beef-pages 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Steve England
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,7 @@
1
+ = pages
2
+
3
+ Description goes here.
4
+
5
+ == Copyright
6
+
7
+ Copyright (c) 2009 Steve England. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,56 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "pages"
8
+ gem.summary = %Q{Pages engine}
9
+ gem.email = "steve@wearebeef.co.uk"
10
+ gem.homepage = "http://github.com/stengland/pages"
11
+ gem.authors = ["Steve England"]
12
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
13
+ end
14
+
15
+ rescue LoadError
16
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
17
+ end
18
+
19
+ require 'rake/testtask'
20
+ Rake::TestTask.new(:test) do |test|
21
+ test.libs << 'lib' << 'test'
22
+ test.pattern = 'test/**/*_test.rb'
23
+ test.verbose = true
24
+ end
25
+
26
+ begin
27
+ require 'rcov/rcovtask'
28
+ Rcov::RcovTask.new do |test|
29
+ test.libs << 'test'
30
+ test.pattern = 'test/**/*_test.rb'
31
+ test.verbose = true
32
+ end
33
+ rescue LoadError
34
+ task :rcov do
35
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
36
+ end
37
+ end
38
+
39
+
40
+ task :default => :test
41
+
42
+ require 'rake/rdoctask'
43
+ Rake::RDocTask.new do |rdoc|
44
+ if File.exist?('VERSION.yml')
45
+ config = YAML.load(File.read('VERSION.yml'))
46
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
47
+ else
48
+ version = ""
49
+ end
50
+
51
+ rdoc.rdoc_dir = 'rdoc'
52
+ rdoc.title = "pages #{version}"
53
+ rdoc.rdoc_files.include('README*')
54
+ rdoc.rdoc_files.include('lib/**/*.rb')
55
+ end
56
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,113 @@
1
+ class Admin::PagesController < Admin::BaseController
2
+
3
+ def index
4
+ @pages = Page.top
5
+
6
+ respond_to do |format|
7
+ format.html # index.html.erb
8
+ format.xml { render :xml => @pages }
9
+ end
10
+ end
11
+
12
+ def show
13
+ @page = Page.find(params[:id])
14
+
15
+ respond_to do |format|
16
+ format.html # show.html.erb
17
+ format.xml { render :xml => @page }
18
+ end
19
+ end
20
+
21
+ def new
22
+ @page = Page.new( :parent_id => params[:page_id] )
23
+
24
+ render :action => 'show'
25
+ end
26
+
27
+ def edit
28
+ @page = Page.find(params[:id])
29
+ end
30
+
31
+ def create
32
+ @page = Page.new(params[:page])
33
+ @page.updated_by = current_user
34
+
35
+ respond_to do |format|
36
+ if @page.save
37
+ flash[:notice] = 'Page was successfully created.'
38
+ format.html { redirect_to(admin_pages_url) }
39
+ format.xml { render :xml => @page, :status => :created, :location => @page }
40
+ else
41
+ format.html { render :action => "show" }
42
+ format.xml { render :xml => @page.errors, :status => :unprocessable_entity }
43
+ end
44
+ end
45
+ end
46
+
47
+ def update
48
+ @page = Page.find(params[:id])
49
+ @page.updated_by = current_user
50
+
51
+ respond_to do |format|
52
+ if @page.update_attributes(params[:page])
53
+ flash[:notice] = 'Page was successfully updated.'
54
+ format.html { redirect_to(admin_pages_url) }
55
+ format.xml { head :ok }
56
+ else
57
+ format.html { render :action => "show" }
58
+ format.xml { render :xml => @page.errors, :status => :unprocessable_entity }
59
+ end
60
+ end
61
+ end
62
+
63
+ def destroy
64
+ @page = Page.find(params[:id])
65
+ @page.destroy
66
+
67
+ respond_to do |format|
68
+ format.html { redirect_to(admin_pages_url) }
69
+ format.xml { head :ok }
70
+ end
71
+ end
72
+
73
+ def preview
74
+ session[:page_preview] = params[:page]
75
+ end
76
+
77
+ def feature
78
+ @page = Page.find(params[:id])
79
+ if request.put?
80
+ if params[:spot] == 'remove'
81
+ @page.features.delete_all
82
+ else
83
+ @page.feature_at! params[:spot]
84
+ end
85
+ flash[:notice] = 'Page has been featured'
86
+ redirect_to admin_pages_path
87
+ end
88
+ end
89
+
90
+ def move_up
91
+ Page.find(params[:id]).move_higher
92
+ redirect_to :back
93
+ end
94
+
95
+ def move_down
96
+ Page.find(params[:id]).move_lower
97
+ redirect_to :back
98
+ end
99
+
100
+ protected
101
+
102
+ def get_template_names
103
+ templates = []
104
+ Dir.glob("#{RAILS_ROOT}/app/views/pages/templates/*"){|f| match = /\/([^\/]+)\.html\.erb$/.match(f); templates << match[1] unless match.nil? }
105
+ # Move default to top if it exists
106
+ if default = templates.delete('default')
107
+ templates.insert(0, default)
108
+ end
109
+ templates.sort
110
+ end
111
+ helper_method :get_template_names
112
+
113
+ end
@@ -0,0 +1,19 @@
1
+ class PagesController < ApplicationController
2
+
3
+ def show
4
+ @page = Page.published.find_by_permalink(params[:id])
5
+
6
+ @page_title = @page.title
7
+ @page_description = @page.description
8
+ @page_keywords = @page.tag_list
9
+
10
+ render :template => "pages/templates/#{(@page.template || get_template_names.first)}"
11
+ end
12
+
13
+ def preview
14
+ @page = Page.new(session[:page_preview])
15
+ session[:page_preview] = nil
16
+ render :action => "show"
17
+ end
18
+
19
+ end
@@ -0,0 +1,2 @@
1
+ module PagesHelper
2
+ end
@@ -0,0 +1,74 @@
1
+ class Page < ActiveRecord::Base
2
+ # http://ramblings.gibberishcode.net/archives/one-activerecord-model-acting-as-a-list-and-tree
3
+
4
+ named_scope :top, :conditions => {:parent_id => nil}, :order => :position
5
+ named_scope :ordered, :order => 'position ASC'
6
+
7
+ has_assets
8
+ acts_as_content_node
9
+ acts_as_tree
10
+ acts_as_list :scope => :parent_id
11
+ acts_as_textiled :body
12
+ acts_as_taggable_on :tags
13
+
14
+ before_save :keep_position_sane
15
+
16
+ validates_presence_of :title
17
+ validates_presence_of :body, :tag_list, :description, :if => :publish
18
+
19
+ def first_child?
20
+ self == self.self_and_siblings.first
21
+ end
22
+
23
+ def last_child?
24
+ self == self.self_and_siblings.last
25
+ end
26
+
27
+ def self.reindex_top_level_pages(recurse = true, departing_child = nil)
28
+ reindex_pages(self.top, recurse, departing_child)
29
+ end
30
+
31
+ def reindex_children(recurse = true, departing_child = nil)
32
+ Page.reindex_pages(children, recurse, departing_child)
33
+ end
34
+
35
+ def root?
36
+ parent_id.nil?
37
+ end
38
+
39
+ def featured?
40
+ !features.empty?
41
+ end
42
+
43
+ private
44
+
45
+ # takes a given array of pages and recursively (or not) reindexes
46
+ # if departing_child is supplied, it is removed from the array so
47
+ # that former siblings are reindexed as though it was already
48
+ # removed from the collection.
49
+ def self.reindex_pages(pages, recurse, departing_child)
50
+ pages.select{|r| r != departing_child}.each_with_index do |page, index|
51
+ page.reindex_children(true) if recurse
52
+ page.update_attributes(:position => index + 1)
53
+ end
54
+ true
55
+ end
56
+
57
+ # When the parent id of a node changes, the acts_as_list gets lost, so
58
+ # we need to reindex the affected nodes to keep things sane
59
+ def keep_position_sane
60
+ return unless self.parent_id_changed?
61
+
62
+ # reindex the group this page is being removed from
63
+ if self.parent_id_was.nil? then
64
+ Page.reindex_top_level_pages(false, self)
65
+ else
66
+ Page.find(self.parent_id_was).reindex_children(false, self)
67
+ end
68
+
69
+ # make this page the last sibling of the new parent group of pages
70
+ last_page = (self.parent_id.nil? ? Page.top.last : Page.find(self.parent_id).children.last)
71
+ self.position = (last_page.nil? ? 1 : last_page.position + 1)
72
+ true
73
+ end
74
+ end
@@ -0,0 +1,16 @@
1
+ <tr class="level-<%= level %>" id="pages:<%= page.id %>">
2
+ <td class="title"><% level.times{|i| %><span>-</span><%} %><%= link_to page.title, [:admin, page] %></td>
3
+ <td><%= content_status(page) %></td>
4
+ <td><%= page.author %></td>
5
+ <td><%= page.editor %></td>
6
+ <td class="date"><%= page.created_at.to_formatted_s(:short) %></td>
7
+ <td class="date"><%= page.updated_at.to_formatted_s(:short) %></td>
8
+ <td><%= link_to 'Show', page_path(page.permalink), :class => 'show' if page.published? %></td>
9
+ <td><%= link_to 'Add page', new_admin_page_page_path(page), :class => 'add', :title => 'Add a sub page' %></td>
10
+ <td><%= link_to 'Edit', [:admin, page], :class => 'edit' %></td>
11
+ <td><%= link_to('Destroy', admin_page_path(page), :confirm => 'Are you sure?', :method => :delete, :class => 'delete') unless page.parent_id.nil? || !current_user.admin? %></td>
12
+ <% if page.parent %>
13
+ <td><%= link_to 'up', move_up_admin_page_path(page), { :class => "page_up" } if current_user.admin? && !page.first_child? %><%= link_to 'down', move_down_admin_page_path(page), { :class => 'page_down' } if current_user.admin? && !page.last_child? %></td>
14
+ <% end %>
15
+ </tr>
16
+ <%= render :partial => page.children, :locals => { :level => level+1 } %>
@@ -0,0 +1,10 @@
1
+ <h1>Feature a page</h1>
2
+
3
+ <% form_for([:feature, :admin, @page]) do %>
4
+ <p>
5
+ <%= label_tag :spot, "Please select where to feture the page '#{h(@page.title)}'" %><br/>
6
+ <%= select_tag :spot, options_for_select({'Home page left' => :home_page_left, 'Home page centre' => :home_page_centre, 'Home page right' => :home_page_right, "Remove from feature" => :remove }) %></p>
7
+ <p>
8
+ <%= submit_tag "Feature", :disable_with => 'Featureing...' %> or <%= link_to 'Cancel', admin_pages_path %>
9
+ </p>
10
+ <% end -%>
@@ -0,0 +1,36 @@
1
+ <h1>Listing pages</h1>
2
+
3
+ <ul class="choices">
4
+ <li><%= link_to 'New page', new_admin_page_path, :class => "button" %></li>
5
+ </ul>
6
+
7
+ <%= hidden_field_tag 'form_authenticity_token', "#{form_authenticity_token}" %>
8
+
9
+ <table class="featurable">
10
+ <thead>
11
+ <tr>
12
+ <th>Title</th>
13
+ <th>Status</th>
14
+ <th>Author</th>
15
+ <th>Updated</th>
16
+ <th>Published At</th>
17
+ <th>Published To</th>
18
+ <th colspan="4">Actions</th>
19
+ </tr>
20
+ </thead>
21
+ <tbody>
22
+ <%= render :partial => @pages, :locals => { :level => 0 } %>
23
+ </tbody>
24
+ <tfoot>
25
+ <tr>
26
+ <th>Title</th>
27
+ <th>Status</th>
28
+ <th>Author</th>
29
+ <th>Updated</th>
30
+ <th>Published At</th>
31
+ <th>Published To</th>
32
+ <th colspan="4">Actions</th>
33
+ </tr>
34
+ </tfoot>
35
+ </table>
36
+
@@ -0,0 +1 @@
1
+ page << "myLightWindow.activateWindow({href: '#{pages_preview_path}', title: 'This is only a preview'});"
@@ -0,0 +1,60 @@
1
+ <h1><%= @page.new_record? ? 'New' : 'Editing' %> page</h1>
2
+
3
+ <% form_for([:admin, @page], :html => { :id => 'content-node-form' }) do |f| %>
4
+ <%= f.error_messages %>
5
+
6
+ <%= f.hidden_field :parent_id %>
7
+ <p>
8
+ <%= f.label :title %><br/>
9
+ <%= f.text_field :title, :class => 'title' %>
10
+ </p>
11
+
12
+ <p>
13
+ <%= f.label :permalink, "URL" %><br/>
14
+ <%= root_url %><%= f.text_field :permalink %>
15
+ <p>URLs are most efficient if they closely reflect the title or main subject of this content. Changing the permalink will make search engines think it is a different page resulting in a loss of page rank, only change if very necessary. Leave blank to use the title.</p>
16
+ </p>
17
+
18
+ <p>
19
+ <%= f.label :description, "Description for search engines" %><br/>
20
+ <%= f.text_area :description, "rows" => 4 %>
21
+ </p>
22
+
23
+ <p>
24
+ <%= f.label :tag_list, "Keywords (comma seperated) - used by search engines" %><br/>
25
+ <%= f.text_field :tag_list, :class => 'long' %>
26
+ </p>
27
+
28
+
29
+ <p>
30
+ <%= f.label :template %>
31
+ <%= f.select :template, get_template_names.collect{|t| [ t.titleize, t ] } %>
32
+ </p>
33
+
34
+ <p>
35
+ <%= f.label :body %><br/>
36
+ <%= f.text_area 'body', :class => 'editor' %>
37
+ </p>
38
+
39
+ <%= publish_select(f) %>
40
+
41
+ <p class="submission">
42
+ <%= preview_link(@page) %>
43
+ <%= f.submit 'Publish', :name => 'page[publish]' %>
44
+ <%= f.submit 'Save as draft', :name => 'page[hide]' %>
45
+ or <%= link_to 'Cancel', admin_articles_path %>
46
+ </p>
47
+
48
+ <% end %>
49
+
50
+ <% content_for :sub_content do %>
51
+
52
+ <%= asset_list(@page) %>
53
+
54
+ <h2>Asset Library</h2>
55
+ <%= asset_browser(true) %>
56
+
57
+ <h2>Asset Upload</h2>
58
+ <%= asset_upload_form %>
59
+
60
+ <% end %>
data/config/routes.rb ADDED
@@ -0,0 +1,6 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+ map.resources :pages, :only => :show, :collection => {:preview => :get}
3
+ map.namespace(:admin) do |admin|
4
+ admin.resources :pages, :has_many => :pages, :collection => {:preview => :post}, :member => {:preview => :put, :feature => [:get, :put], :move_up => :get, :move_down => :get}
5
+ end
6
+ end
@@ -0,0 +1,11 @@
1
+ class PageTemplateGenerator < Rails::Generator::NamedBase
2
+
3
+ def manifest
4
+ record do |m|
5
+ m.directory(File.join('app', 'views', 'pages', 'templates'))
6
+
7
+ m.file('default.html.erb', File.join('app', 'views', 'pages', 'templates', "#{name}.html.erb"))
8
+ end
9
+ end
10
+
11
+ end
@@ -0,0 +1,11 @@
1
+ <div id="main-content">
2
+ <h1><%= @page.title %></h1>
3
+
4
+ <%= @page.body %>
5
+ </div><!-- eo: main -->
6
+
7
+ <ul class="page-nav">
8
+ <% for page in @page.root? ? @page.children : @page.self_and_siblings %>
9
+ <li><%= link_to_unless_current h(page.title), page_path(page.permalink) %></li>
10
+ <% end -%>
11
+ </ul>
@@ -0,0 +1,11 @@
1
+ class PagesMigrationGenerator < Rails::Generator::Base
2
+
3
+ def manifest
4
+ record do |m|
5
+ m.migration_template "migration.rb",
6
+ 'db/migrate',
7
+ :migration_file_name => "create_pages"
8
+ end
9
+ end
10
+
11
+ end
@@ -0,0 +1,24 @@
1
+ class CreatePages < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :pages do |t|
4
+ t.string :title
5
+ t.string :permalink
6
+ t.datetime :published_at
7
+ t.datetime :published_to
8
+ t.text :body
9
+ t.string :description
10
+ t.string :template, :limit => 20
11
+ t.integer :position, :default => 0
12
+ t.references :created_by, :updated_by, :parent
13
+
14
+ t.timestamps
15
+ end
16
+
17
+ add_index :pages, :permalink
18
+
19
+ end
20
+
21
+ def self.down
22
+ drop_table :pages
23
+ end
24
+ end
data/lib/pages.rb ADDED
File without changes
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class PagesTest < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'pages'
8
+
9
+ class Test::Unit::TestCase
10
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: beef-pages
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Steve England
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-24 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: steve@wearebeef.co.uk
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.rdoc
25
+ files:
26
+ - .document
27
+ - .gitignore
28
+ - LICENSE
29
+ - README.rdoc
30
+ - Rakefile
31
+ - VERSION
32
+ - app/controllers/admin/pages_controller.rb
33
+ - app/controllers/pages_controller.rb
34
+ - app/helpers/pages_helper.rb
35
+ - app/models/page.rb
36
+ - app/views/admin/pages/_page.html.erb
37
+ - app/views/admin/pages/feature.html.erb
38
+ - app/views/admin/pages/index.html.erb
39
+ - app/views/admin/pages/preview.rjs
40
+ - app/views/admin/pages/show.html.erb
41
+ - config/routes.rb
42
+ - generators/page_tempate/page_template_generator.rb
43
+ - generators/page_tempate/templates/default.html.erb
44
+ - generators/pages_migration/pages_migration_generator.rb
45
+ - generators/pages_migration/templates/migration.rb
46
+ - lib/pages.rb
47
+ - test/pages_test.rb
48
+ - test/test_helper.rb
49
+ has_rdoc: false
50
+ homepage: http://github.com/stengland/pages
51
+ post_install_message:
52
+ rdoc_options:
53
+ - --charset=UTF-8
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ version:
68
+ requirements: []
69
+
70
+ rubyforge_project:
71
+ rubygems_version: 1.2.0
72
+ signing_key:
73
+ specification_version: 3
74
+ summary: Pages engine
75
+ test_files:
76
+ - test/pages_test.rb
77
+ - test/test_helper.rb