spree_cms 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/Gemfile +4 -0
  2. data/README.markdown +108 -0
  3. data/Rakefile +2 -0
  4. data/app/controllers/admin/cms_settings_controller.rb +11 -0
  5. data/app/controllers/admin/pages_controller.rb +54 -0
  6. data/app/controllers/admin/posts_controller.rb +55 -0
  7. data/app/controllers/pages_controller.rb +4 -0
  8. data/app/controllers/posts_controller.rb +26 -0
  9. data/app/helpers/cms_helper.rb +21 -0
  10. data/app/models/page.rb +38 -0
  11. data/app/models/post.rb +73 -0
  12. data/app/views/admin/cms_settings/edit.html.erb +40 -0
  13. data/app/views/admin/cms_settings/show.html.erb +42 -0
  14. data/app/views/admin/pages/_form.html.erb +51 -0
  15. data/app/views/admin/pages/edit.html.erb +7 -0
  16. data/app/views/admin/pages/index.html.erb +90 -0
  17. data/app/views/admin/pages/new.html.erb +28 -0
  18. data/app/views/admin/posts/_form.html.erb +66 -0
  19. data/app/views/admin/posts/_sub_menu.html.erb +7 -0
  20. data/app/views/admin/posts/edit.html.erb +9 -0
  21. data/app/views/admin/posts/index.html.erb +101 -0
  22. data/app/views/admin/posts/new.html.erb +45 -0
  23. data/app/views/admin/users/_display_name.html.erb +4 -0
  24. data/app/views/pages/show.html.erb +5 -0
  25. data/app/views/posts/_post.html.erb +13 -0
  26. data/app/views/posts/index.html.erb +14 -0
  27. data/app/views/posts/index.rss.builder +19 -0
  28. data/app/views/posts/show.html.erb +10 -0
  29. data/app/views/posts/tags.html.erb +18 -0
  30. data/app/views/shared/_cms_content_for.html.erb +7 -0
  31. data/app/views/shared/_recent_articles.html.erb +7 -0
  32. data/app/views/shared/_store_menu.html.erb +5 -0
  33. data/config/locales/en.yml +48 -0
  34. data/lib/extensions/string.rb +20 -0
  35. data/lib/generators/spree_cms/USAGE +8 -0
  36. data/lib/generators/spree_cms/install/install_generator.rb +40 -0
  37. data/lib/generators/spree_cms/install/templates/db/migrate/add_display_name_to_user.rb +9 -0
  38. data/lib/generators/spree_cms/install/templates/db/migrate/create_pages.rb +23 -0
  39. data/lib/generators/spree_cms/install/templates/db/migrate/create_posts.rb +26 -0
  40. data/lib/generators/spree_cms/install/templates/db/migrate/is_taggable_migration.rb +24 -0
  41. data/lib/generators/spree_cms/install/templates/public/images/icons/feed.gif +0 -0
  42. data/lib/generators/spree_cms/install/templates/public/stylesheets/sass/cms.sass +60 -0
  43. data/lib/spree_cms/version.rb +3 -0
  44. data/lib/spree_cms.rb +66 -0
  45. data/lib/spree_cms_hooks.rb +11 -0
  46. data/spree_cms.gemspec +25 -0
  47. metadata +154 -0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in how_are_we_doing.gemspec
4
+ gemspec
data/README.markdown ADDED
@@ -0,0 +1,108 @@
1
+ Spree on CMS
2
+ =========
3
+
4
+ A blog / static page extension for Spree version 10.x. Spree admin users can create blog posts and static pages. The extension extends the admin interface to allow the adding of display names to users that will be displayed on blog posts.
5
+
6
+ Comments on blog posts are currently powered by [Disqus](http://disqus.com/comments/). The comment system and/or comments on individual blog posts can be disabled, if preferred.
7
+
8
+ The extension provides basic views and a stylesheet that can easily be overridden through your site extension. Also, several helpers exist to allow tags, posts and pages to be accesible in your site views.
9
+
10
+ Installation
11
+ ------------
12
+
13
+ script/extension install git://github.com/jacobwg/spree-cms.git
14
+ rake gems:install
15
+ rake db:migrate
16
+
17
+ All authors for the blog should be given a display name in the admin/users edit form.
18
+
19
+ Edit preferences in cms_extension.rb (Disqus site name if you are using Disqus)
20
+
21
+ All done!
22
+
23
+ Setup
24
+ ------
25
+
26
+ in cms_extension.rb add your disqus account identifier if you plan to use comments.
27
+
28
+ You can edit the preferences in the extension.rb file or in the http://localhost:3000/admin/cms_settings ui.
29
+
30
+ The blog home slug requires a server restart so it can only be edited in the extension file.
31
+
32
+ Posts
33
+ -------
34
+
35
+ New Posts can be created in the admin section http://localhost:3000/admin/posts
36
+
37
+ Posts have unique permalinks created for all new post entries. The permalink can be modified after initial save.
38
+
39
+ RedCloth is used for post formatting.
40
+
41
+ is_taggable gem is used for adding tags to each post. A helper linked_tag_list is provided to display a list of the link tags to filter by.
42
+
43
+
44
+ Comments
45
+ --------
46
+
47
+ Comments can be opened or closed for a post. The comment form displays on the post page when enabled for the specific post.
48
+
49
+ Comments are now managed by Disqus via the disqus gem, http://github.com/norman/disqus/. Management of spam and comment moderation is done through the Disqus UI.
50
+
51
+ Create disqus account at [http://disqus.com/comments/](http://disqus.com/comments/).
52
+
53
+
54
+ Blog
55
+ -----
56
+
57
+ View the blog at http://localhost:3000/blog or the defined slug from the preferences.
58
+
59
+ Use helper post_link_list(limit) to get a list of recent post links.
60
+
61
+ Views are in folder extension/app/views/posts
62
+
63
+
64
+ RSS
65
+ -----
66
+
67
+ http://localhost:3000/blog.rss - All Posts
68
+
69
+ Customize RSS feed in extension/app/views/posts/index.rss.builder
70
+
71
+
72
+ Pages
73
+ -----
74
+
75
+ Under Admin section add pages for static-content (http://localhost:3000/admin/pages).
76
+
77
+ Use helper page_link() to print a link to page, based on ID or Permalink.
78
+
79
+ Pages are displayed by the content route provided by Spree core. Customize the extension/app/views/content/show.html.erb file.
80
+
81
+
82
+
83
+ Tips
84
+ --------
85
+
86
+ You can add a blog link anywhere on your site or include the recent_articles partial.
87
+
88
+ One option is to add the Blog link to the store_menu partial
89
+
90
+ <li><%= link_to t('blog'), posts_path %></li>
91
+
92
+ Use the cms_content_for partial to include the cms css and recent articles partial in the sidebar.
93
+
94
+ <%= render :partial => 'shared/cms_content_for'%>
95
+
96
+
97
+
98
+ TODO
99
+ -----
100
+
101
+ - improve permalinks for posts
102
+ - wysiwyg editor for blog posts and pages.
103
+
104
+
105
+ Credits
106
+ -------
107
+
108
+ Based on spree-wordsmith created by [Matt Anderson](http://tonkapark.com/)
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,11 @@
1
+ class Admin::CmsSettingsController < Admin::BaseController
2
+
3
+ def update
4
+ Spree::Config.set(params[:preferences])
5
+
6
+ respond_to do |wants|
7
+ wants.html { redirect_to admin_cms_settings_path }
8
+ end
9
+ end
10
+
11
+ end
@@ -0,0 +1,54 @@
1
+ class Admin::PagesController < Admin::BaseController
2
+ resource_controller :except => [:show]
3
+
4
+
5
+ index.response do |wants|
6
+ wants.html { render :action => :index }
7
+ wants.json { render :json => @collection.to_json() }
8
+ end
9
+
10
+ new_action.response do |wants|
11
+ wants.html {render :action => :new, :layout => false}
12
+ end
13
+
14
+ create.before :create_before
15
+
16
+ create.response do |wants|
17
+ # go to edit form after creating as new page
18
+ wants.html {redirect_to edit_admin_page_url(Page.find(@page.id)) }
19
+ end
20
+
21
+ update.response do |wants|
22
+ # override the default redirect behavior of r_c
23
+ # need to reload Page in case name / permalink has changed
24
+ wants.html {redirect_to edit_admin_page_url(Page.find(@page.id)) }
25
+ end
26
+
27
+ private
28
+ def collection
29
+
30
+ unless request.xhr?
31
+ # Note: the SL scopes are on/off switches, so we need to select "not_deleted" explicitly if the switch is off
32
+ # QUERY - better as named scope or as SL scope?
33
+ #if params[:search].nil? || params[:search][:deleted_at_not_null].blank?
34
+ # base_scope = base_scope.not_deleted
35
+ #end
36
+
37
+ @search = Page.search(params[:search])
38
+ @search.order ||= "ascend_by_title"
39
+
40
+ @collection = @search.paginate(:page => params[:page])
41
+ else
42
+ @collection = Page.title_contains(params[:q]).all(:include => includes, :limit => 10)
43
+ @collection.uniq!
44
+ end
45
+
46
+ end
47
+
48
+ # set the default published and comment status if applicable
49
+ def create_before
50
+ return unless Spree::Config[:cms_page_status_default]
51
+ @page.is_active = Spree::Config[:cms_page_status_default]
52
+ end
53
+
54
+ end
@@ -0,0 +1,55 @@
1
+ class Admin::PostsController < Admin::BaseController
2
+ resource_controller :except => [:show]
3
+
4
+ index.response do |wants|
5
+ wants.html { render :action => :index }
6
+ wants.json { render :json => @collection.to_json() }
7
+ end
8
+
9
+ new_action.response do |wants|
10
+ wants.html {render :action => :new, :layout => false}
11
+ end
12
+
13
+ create.before :create_before
14
+
15
+ create.response do |wants|
16
+ # go to edit form after creating as new post
17
+ wants.html {redirect_to edit_admin_post_url(Post.find(@post.id)) }
18
+ end
19
+
20
+ update.response do |wants|
21
+ # override the default redirect behavior of r_c
22
+ # need to reload Post in case name / permalink has changed
23
+ wants.html {redirect_to edit_admin_post_url(Post.find(@post.id)) }
24
+ end
25
+
26
+ private
27
+
28
+ def collection
29
+
30
+ unless request.xhr?
31
+ # Note: the SL scopes are on/off switches, so we need to select "not_deleted" explicitly if the switch is off
32
+ # QUERY - better as named scope or as SL scope?
33
+ #if params[:search].nil? || params[:search][:deleted_at_not_null].blank?
34
+ # base_scope = base_scope.not_deleted
35
+ #end
36
+
37
+ @search = Post.search(params[:search])
38
+ @search.order ||= "ascend_by_title"
39
+
40
+ @collection = @search.paginate( :page => params[:page] )
41
+ else
42
+ @collection = Post.title_contains(params[:q]).all(:include => includes, :limit => 10)
43
+ @collection.uniq!
44
+ end
45
+
46
+ end
47
+
48
+ # set the default published and comment status if applicable
49
+ def create_before
50
+ return unless Spree::Config[:cms_post_status_default] || Spree::Config[:cms_post_comment_default]
51
+ @post.is_active = Spree::Config[:cms_post_status_default]
52
+ @post.commentable = Spree::Config[:cms_post_comment_default]
53
+ end
54
+
55
+ end
@@ -0,0 +1,4 @@
1
+ class PagesController < Spree::BaseController
2
+ resource_controller
3
+ actions :show, :index
4
+ end
@@ -0,0 +1,26 @@
1
+ class PostsController < Spree::BaseController
2
+
3
+ resource_controller
4
+ actions :show, :index
5
+
6
+ index.response do |wants|
7
+ wants.html
8
+ wants.rss
9
+ end
10
+
11
+ def tags
12
+ @posts = Post.publish.find_all_tagged_with(params[:tag_name]).paginate :page => params[:page]
13
+ end
14
+
15
+ private
16
+ def collection
17
+ @collection ||= end_of_association_chain.publish.paginate :page => params[:page]
18
+ end
19
+
20
+ #def object
21
+ # @object ||= end_of_association_chain.publish.find(param) unless param.nil?
22
+ # @object
23
+ #end
24
+
25
+
26
+ end
@@ -0,0 +1,21 @@
1
+ module CmsHelper
2
+
3
+ def linked_tag_list(tags)
4
+ tags.collect {|tag| link_to(tag.name, tag_posts_url(:tag_name => tag.name ))}.join(", ")
5
+ end
6
+
7
+ def post_link_list(limit = Spree::Config[:cms_posts_recent])
8
+ link = Struct.new(:name,:url)
9
+ Post.publish.limit(limit).collect { |post| link.new(post.title, post_path(post)) }
10
+ end
11
+
12
+ def page_link(id)
13
+ if id.kind_of?(String)
14
+ page = Page.publish.find_by_permalink(id)
15
+ elsif id.kind_of?(Fixnum)
16
+ page = Page.publish.find(id)
17
+ end
18
+ link_to page.title, page.link unless page.nil?
19
+ end
20
+
21
+ end
@@ -0,0 +1,38 @@
1
+ class Page < ActiveRecord::Base
2
+
3
+ before_validation :format_markup
4
+ before_validation :published
5
+
6
+ validates_presence_of :title, :message => 'required'
7
+ validates_presence_of :body, :message => 'required'
8
+ validates_uniqueness_of :permalink
9
+
10
+ make_permalink :with => :title
11
+
12
+ scope :publish, where('published_at < ? and is_active = ?', Time.zone.now, 1)
13
+
14
+ def to_param
15
+ return permalink unless permalink.blank?
16
+ title.to_url
17
+ end
18
+
19
+ def format_markup
20
+ if not self.body_raw.nil?
21
+ self.body = RedCloth.new(self.body_raw,[:sanitize_html, :filter_html]).to_html
22
+ end
23
+ end
24
+
25
+ def published
26
+ #self.published_at ||= Time.now unless self.is_active == 0
27
+ if self.is_active == 0
28
+ if !self.published_at.blank?
29
+ self.published_at = nil
30
+ end
31
+ else
32
+ if self.published_at.blank?
33
+ self.published_at = Time.now
34
+ end
35
+ end
36
+ end
37
+
38
+ end
@@ -0,0 +1,73 @@
1
+ class Post < ActiveRecord::Base
2
+ cattr_reader :per_page
3
+ @@per_page = Spree::Config[:cms_posts_per_page]
4
+ #attr_accessible :user_id, :title, :body_raw, :published_at, :is_active, :permalink, :tag_list, :excerpt, :commentable, :meta_keywords, :meta_description
5
+
6
+ is_taggable :tags
7
+
8
+ belongs_to :user
9
+
10
+ before_validation :format_markup
11
+ #before_validation :generate_permalink
12
+ before_validation :published
13
+
14
+ make_permalink :with => :title
15
+
16
+ validates_presence_of :title, :message => 'required'
17
+ validates_presence_of :body, :message => 'required'
18
+ validates_uniqueness_of :permalink
19
+
20
+ default_scope order('published_at DESC')
21
+ scope :publish, where('published_at < ? and is_active = ?', Time.zone.now, 1)
22
+
23
+
24
+ #should be part of is_taggable
25
+ #pulled from http://github.com/gnugeek/is_taggable/commit/10b590865f0effeed20f00e3581a7aed8a6bd3b4
26
+ def self.find_all_tagged_with(tag_or_tags, conditions=[])
27
+ return [] if tag_or_tags.nil? || tag_or_tags.empty?
28
+ case tag_or_tags
29
+ when Array, IsTaggable::TagList
30
+ includes('tags', 'taggings').where(conditions).select { |record| tag_or_tags.all? { |tag| record.tags.map(&:name).include?(tag) } } || []
31
+ else
32
+ includes('tags', 'taggings').where(conditions).select { |record| record.tags.map(&:name).include?(tag_or_tags) } || []
33
+ end
34
+ end
35
+
36
+ def to_param
37
+ return permalink unless permalink.blank?
38
+ title.to_url
39
+ end
40
+
41
+ def format_markup
42
+ if not self.body_raw.nil?
43
+ self.body = RedCloth.new(self.body_raw,[:sanitize_html, :filter_html]).to_html
44
+ end
45
+ end
46
+
47
+ #def link
48
+ # ensure_slash_prefix permalink
49
+ #end
50
+
51
+ def published
52
+ #self.published_at ||= Time.now unless self.is_active == 0
53
+ if self.is_active == 0
54
+ if !self.published_at.blank?
55
+ self.published_at = nil
56
+ end
57
+ else
58
+ if self.published_at.blank?
59
+ self.published_at = Time.now
60
+ end
61
+ end
62
+ end
63
+
64
+ def month
65
+ published_at.strftime('%B %Y')
66
+ end
67
+
68
+ #private
69
+
70
+ # def ensure_slash_prefix(str)
71
+ # str.index('/') == 0 ? str : '/' + str
72
+ # end
73
+ end
@@ -0,0 +1,40 @@
1
+ <%= render :partial => 'admin/posts/sub_menu' %>
2
+
3
+ <h1><%= t('cms.settings') %></h1>
4
+
5
+ <% form_tag(admin_cms_settings_path, :method => :put) do -%>
6
+
7
+
8
+
9
+ <p>
10
+ <label><%= t('cms.posts_per_page') %></label>
11
+ <%= text_field_tag('preferences[cms_posts_per_page]', Spree::Config[:cms_posts_per_page]) %>
12
+ </p>
13
+ <p>
14
+ <label><%= t('cms.posts_recent') %></label>
15
+ <%= text_field_tag('preferences[cms_posts_recent]', Spree::Config[:cms_posts_recent])%>
16
+ </p>
17
+
18
+ <p>
19
+ <label><%= t('cms.post_status_default') %></label>
20
+ <%= radio_button_tag('preferences[cms_post_status_default]', 1, Spree::Config[:cms_post_status_default]) %> <%= t("cms.publish") %>
21
+ <%= radio_button_tag('preferences[cms_post_status_default]', 0, Spree::Config[:cms_post_status_default] ) %> <%= t("cms.draft") %>
22
+ </p>
23
+
24
+ <p>
25
+ <label><%= t('cms.page_status_default') %></label>
26
+ <%= radio_button_tag('preferences[cms_page_status_default]', 1, Spree::Config[:cms_page_status_default]) %> <%= t("cms.publish") %>
27
+ <%= radio_button_tag('preferences[cms_page_status_default]', 0, Spree::Config[:cms_page_status_default] ) %> <%= t("cms.draft") %>
28
+ </p>
29
+
30
+ <p>
31
+ <label><%= t('cms.post_comment_default') %></label>
32
+ <%= radio_button_tag('preferences[cms_post_comment_default]', 1, Spree::Config[:cms_post_comment_default]) %> <%= t("cms.open") %>
33
+ <%= radio_button_tag('preferences[cms_post_comment_default]', 0, Spree::Config[:cms_post_comment_default] ) %> <%= t("cms.closed") %>
34
+ </p>
35
+
36
+ <p class="form-buttons">
37
+ <%= button t('update') %>
38
+ <%= t("or") %> <%= link_to t("cancel"), admin_cms_settings_url %>
39
+ </p>
40
+ <% end -%>
@@ -0,0 +1,42 @@
1
+ <%= render :partial => 'admin/posts/sub_menu' %>
2
+
3
+ <h1><%= t("cms.settings") %></h1>
4
+
5
+ <table>
6
+ <tr>
7
+ <th scope="row"><%= t("cms.permalink") %>:</th>
8
+ <td><%= Spree::Config[:cms_permalink] %></td>
9
+ </tr>
10
+ <tr>
11
+ <th scope="row"><%= t("cms.posts_per_page") %>:</th>
12
+ <td><%= Spree::Config[:cms_posts_per_page] %></td>
13
+ </tr>
14
+ <tr>
15
+ <th scope="row"><%= t("cms.posts_recent") %>:</th>
16
+ <td><%= Spree::Config[:cms_posts_recent] %></td>
17
+ </tr>
18
+
19
+ <tr>
20
+ <th scope="row"><%= t("cms.post_status_default") %>:</th>
21
+ <td><%= (Spree::Config[:cms_post_status_default] ? t("cms.publish") : t("cms.draft")) %></td>
22
+ </tr>
23
+
24
+ <tr>
25
+ <th scope="row"><%= t("cms.page_status_default") %>:</th>
26
+ <td><%= (Spree::Config[:cms_page_status_default] ? t("cms.publish") : t("cms.draft")) %></td>
27
+ </tr>
28
+
29
+ <tr>
30
+ <th scope="row"><%= t("cms.post_comment_default") %>:</th>
31
+ <td><%= (Spree::Config[:cms_post_comment_default] ? t("cms.open") : t("cms.closed")) %>
32
+ </td>
33
+ </tr>
34
+
35
+
36
+
37
+
38
+ </table>
39
+
40
+ <p><%= link_to_with_icon 'edit', t("edit"), edit_admin_cms_settings_path %></p>
41
+
42
+
@@ -0,0 +1,51 @@
1
+ <div class="yui-gc">
2
+ <div class="yui-u first">
3
+ <%- locals = {:f => f} -%>
4
+ <% hook :admin_page_form_left, locals do %>
5
+ <% f.field_container :title do %>
6
+ <%= f.label :title, t("cms.title") %> <span class="required">*</span><br />
7
+ <%= f.text_field :title, :class => 'fullwidth title' %>
8
+ <%= f.error_message_on :title %>
9
+ <% end %>
10
+
11
+ <% f.field_container :permalink do %>
12
+ <%= f.label :permalink, t("cms.permalink") %> <span class="required">*</span><br />
13
+ <%= f.text_field :permalink, :class => 'fullwidth title' %>
14
+ <%= f.error_message_on :permalink %>
15
+ <% end %>
16
+
17
+ <% f.field_container :body_raw do %>
18
+ <%= f.label :body_raw, t("cms.body")%><br />
19
+ <%= f.text_area :body_raw, {:cols => 60, :rows => 4, :class => 'fullwidth'} %>
20
+ <%= f.error_message_on :body_raw %>
21
+ <% end %>
22
+ <% end %>
23
+ </div>
24
+ <div class="yui-u">
25
+ <% hook :admin_page_form_right, locals do %>
26
+
27
+ <p>
28
+ <%= f.label :is_active, t("cms.status")%><br />
29
+
30
+ <%= f.radio_button :is_active, 1 %><%= t("cms.publish") %>
31
+ <%= f.radio_button :is_active, 0 %><%= t("cms.draft") %>
32
+ <%= f.error_message_on :is_active%>
33
+ </p>
34
+ <h2><%= t("metadata") %></h2>
35
+ <% hook :admin_page_form_meta, locals do %>
36
+ <p>
37
+ <%= f.label :meta_keywords, t("cms.meta_keywords")%><br />
38
+ <%= f.text_field :meta_keywords, :class => 'fullwidth' %>
39
+ </p>
40
+ <p>
41
+ <%= f.label :meta_description, t("cms.meta_description")%><br />
42
+ <%= f.text_field :meta_description, :class => 'fullwidth' %>
43
+ </p>
44
+ <% end %>
45
+ <% end %>
46
+ </div>
47
+ </div>
48
+
49
+
50
+
51
+
@@ -0,0 +1,7 @@
1
+ <h1><%= t("cms.editing_page") + " &ldquo;#{@page.title}&rdquo;" %></h1>
2
+
3
+ <% form_for(@page, :url => object_url, :html => { :method => :put, :multipart => true }) do |f| %>
4
+ <%= render :partial => 'form', :locals => {:f => f} %>
5
+ <%= render :partial => 'admin/shared/edit_resource_links' %>
6
+ <% end %>
7
+
@@ -0,0 +1,90 @@
1
+ <div class='toolbar'>
2
+ <ul class='actions'>
3
+ <li id="new_ot_link">
4
+ <%= button_link_to_remote t("cms.new_page"),
5
+ {:url => new_object_url,
6
+ :method => :get,
7
+ :update => "new-page"}, :icon => 'add' %>
8
+ </li>
9
+ </ul>
10
+ <br class='clear' />
11
+ </div>
12
+
13
+ <h1><%= "#{t('actions.listing')} #{t('pages')}" %></h1>
14
+
15
+ <%= image_tag "spinner.gif", :plugin=>"spree", :style => "display:none", :id => 'busy_indicator' %>
16
+ <div id="new-page"></div>
17
+
18
+
19
+ <table class="index">
20
+ <tr>
21
+ <% hook :admin_pages_index_headers do %>
22
+ <th><%= order @search, :by => :title, :as => t("cms.title") %></th>
23
+ <th><%= order @search, :by => :date, :as => t("cms.date") %></th>
24
+ <% end %>
25
+ <th>
26
+ <%= hook :admin_pages_index_header_actions %>
27
+ </th>
28
+ </tr>
29
+
30
+ <% @collection.each do |page| %>
31
+ <%- locals = {:page => page} -%>
32
+ <tr>
33
+ <% hook :admin_pages_index_rows, locals do %>
34
+ <td><%= link_to h(page.title), [:edit,:admin,page] %> (<%= page.is_active == 1 ? t("cms.published") : t("cms.draft") %>) </td>
35
+ <td><%= (page.published_at.blank? ? page.updated_at : page.published_at).strftime("%B %d, %Y at %I:%M%p") %></td>
36
+ <% end %>
37
+ <td class="actions">
38
+ <% hook :admin_pages_index_row_actions, locals do %>
39
+ <%= link_to_edit page %>
40
+ &nbsp;
41
+ <%= link_to_delete page %>
42
+ <% end %>
43
+ </td>
44
+ </tr>
45
+ <% end %>
46
+ </table>
47
+ <%= will_paginate(:previous_label => "&#171; #{t('previous')}", :next_label => "#{t('next')} &#187;") %>
48
+
49
+ <% content_for :sidebar do %>
50
+
51
+ <% form_for @search do |f| %>
52
+ <div class="box">
53
+ <h3><%= t(:search) %></h3>
54
+
55
+ <%- locals = {:f => f} -%>
56
+ <% hook :admin_pages_index_search, locals do %>
57
+ <p>
58
+ <label><%= t("cms.title") %></label><br />
59
+ <%= f.text_field :title_contains, :size => 15 %>
60
+ </p>
61
+
62
+ <label><%= t("cms.published_date_range") %></label><br />
63
+ <div class="yui-g date-range-filter">
64
+ <div class="yui-u sub-field first">
65
+ <%= f.unobtrusive_date_text_picker :published_at_after %><br />
66
+ <label class="sub"><%= t("start") %></label>
67
+ </div>
68
+ <div class="yui-u sub-field">
69
+ <%= f.unobtrusive_date_text_picker :published_at_before %><br />
70
+ <label><%= t("stop") %></label>
71
+ </div>
72
+ </div>
73
+
74
+ <p>
75
+ <%= f.check_box :is_active, {:style => "vertical-align:middle;"}, "1", "" %>
76
+ <label>
77
+ <%= t("cms.show_only_published_pages") %>
78
+ </label>
79
+ </p>
80
+ <% end %>
81
+
82
+ <% hook :admin_pages_index_search_buttons, locals do %>
83
+ <p class="form-buttons">
84
+ <%= button t("search") %>
85
+ </p>
86
+ <% end %>
87
+ </div>
88
+ <% end %>
89
+
90
+ <% end %>
@@ -0,0 +1,28 @@
1
+ <%= error_messages_for :page %>
2
+
3
+ <% form_for(:page, :url => collection_url, :html => { :multipart => true }) do |f| %>
4
+ <fieldset>
5
+
6
+ <% f.field_container :title do %>
7
+ <%= f.label :title, t("cms.title") %> <span class="required">*</span><br />
8
+ <%= f.text_field :title, :class => 'fullwidth title' %>
9
+ <%= f.error_message_on :title %>
10
+ <% end %>
11
+
12
+ <div class="yui-gb">
13
+ <div class="yui-u first">
14
+
15
+ <% f.field_container :body_raw do %>
16
+ <%= f.label :body_raw, t("cms.body")%> <span class="required">*</span><br />
17
+ <%= f.text_area :body_raw, {:cols => 120, :rows => 4, :class => 'fullwidth'} %>
18
+ <%= f.error_message_on :body_raw %>
19
+ <% end %>
20
+
21
+ </div>
22
+
23
+ </div>
24
+
25
+ <%= render :partial => 'admin/shared/new_resource_links' %>
26
+
27
+ </fieldset>
28
+ <% end %>