bcms_blog 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/Gemfile +10 -0
  2. data/README.markdown +10 -4
  3. data/app/assets/javascripts/bcms_blog/application.js +15 -0
  4. data/app/assets/stylesheets/bcms_blog/application.css +13 -0
  5. data/app/controllers/bcms_blog/blog_comments_controller.rb +5 -0
  6. data/app/controllers/bcms_blog/blog_posts_controller.rb +37 -0
  7. data/app/controllers/bcms_blog/blogs_controller.rb +13 -0
  8. data/app/controllers/bcms_blog/feeds_controller.rb +10 -0
  9. data/app/helpers/bcms_blog/blog_helper.rb +27 -0
  10. data/app/models/bcms_blog/blog.rb +99 -0
  11. data/app/models/bcms_blog/blog_comment.rb +36 -0
  12. data/app/models/bcms_blog/blog_group_membership.rb +6 -0
  13. data/app/models/bcms_blog/blog_observer.rb +141 -0
  14. data/app/models/bcms_blog/blog_post.rb +108 -0
  15. data/app/portlets/blog_post_portlet.rb +6 -6
  16. data/app/portlets/blog_posts_portlet.rb +4 -4
  17. data/app/views/bcms_blog/blog_comments/_form.html.erb +5 -0
  18. data/app/views/bcms_blog/blog_comments/render.html.erb +2 -0
  19. data/app/views/{cms → bcms_blog}/blog_posts/_form.html.erb +1 -1
  20. data/app/views/{cms → bcms_blog}/blog_posts/no_access.html.erb +0 -0
  21. data/app/views/{cms → bcms_blog}/blog_posts/render.html.erb +0 -0
  22. data/app/views/{cms → bcms_blog}/blogs/_form.html.erb +2 -2
  23. data/app/views/{cms → bcms_blog}/blogs/admin_only.html.erb +0 -0
  24. data/app/views/{cms → bcms_blog}/blogs/render.html.erb +0 -0
  25. data/app/views/{feeds → bcms_blog/feeds}/index.rss.builder +3 -3
  26. data/app/views/portlets/blog_post/_form.html.erb +1 -1
  27. data/app/views/portlets/blog_post/render.html.erb +3 -1
  28. data/app/views/portlets/blog_posts/_form.html.erb +1 -1
  29. data/config/routes.rb +5 -0
  30. data/db/bcms_blog.seeds.rb +4 -0
  31. data/db/migrate/20090415000000_create_blogs.rb +5 -6
  32. data/db/migrate/20090415000001_create_blog_posts.rb +1 -5
  33. data/db/migrate/20090415000002_create_blog_comments.rb +0 -2
  34. data/db/migrate/20120529184028_v130.rb +12 -0
  35. data/lib/bcms_blog/engine.rb +15 -1
  36. data/lib/bcms_blog/route_extensions.rb +8 -0
  37. data/lib/bcms_blog/version.rb +3 -0
  38. data/lib/bcms_blog.rb +5 -2
  39. data/lib/generators/bcms_blog/install/install_generator.rb +11 -11
  40. data/lib/tasks/bcms_blog_tasks.rake +4 -0
  41. data/test/bcms_blog_test.rb +7 -0
  42. data/test/functional/cms/blog_posts_controller_test.rb +47 -0
  43. data/test/functional/cms/blogs_controller_test.rb +27 -0
  44. data/test/integration/blog_controller_test.rb +63 -0
  45. data/test/integration/blog_post_test.rb +31 -0
  46. data/test/support/blog_test_helper.rb +71 -0
  47. data/test/support/factories.rb +54 -0
  48. data/test/support/factory_girl_support.rb +2 -0
  49. data/test/test_helper.rb +15 -0
  50. data/test/test_logging.rb +64 -0
  51. data/test/unit/blog_comment_test.rb +34 -0
  52. data/test/unit/blog_observer_test.rb +84 -0
  53. data/test/unit/blog_post_test.rb +45 -0
  54. data/test/unit/blog_test.rb +42 -0
  55. data/test/unit/helpers/feeds_helper_test.rb +4 -0
  56. metadata +83 -35
  57. data/app/controllers/cms/blog_comments_controller.rb +0 -3
  58. data/app/controllers/cms/blog_posts_controller.rb +0 -35
  59. data/app/controllers/cms/blogs_controller.rb +0 -11
  60. data/app/controllers/feeds_controller.rb +0 -8
  61. data/app/helpers/cms/blog_helper.rb +0 -20
  62. data/app/models/blog.rb +0 -95
  63. data/app/models/blog_comment.rb +0 -34
  64. data/app/models/blog_group_membership.rb +0 -4
  65. data/app/models/blog_observer.rb +0 -140
  66. data/app/models/blog_post.rb +0 -113
  67. data/app/views/cms/blog_comments/_form.html.erb +0 -5
  68. data/app/views/cms/blog_comments/render.html.erb +0 -2
  69. data/app/views/layouts/templates/default.html.erb +0 -17
  70. data/doc/README_FOR_APP +0 -2
  71. data/doc/migrate_to_20100427.rb +0 -77
  72. data/doc/release_notes.txt +0 -48
  73. data/lib/bcms_blog/routes.rb +0 -10
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'sqlite3'
4
+
5
+ group :test do
6
+ gem 'factory_girl_rails'
7
+ gem 'mocha', :require=>false
8
+ end
9
+
10
+ gemspec
data/README.markdown CHANGED
@@ -15,18 +15,21 @@ A simple blog module that lets users create multiple blogs.
15
15
 
16
16
  The blog module installs like most other BrowserCMS modules (http://guides.browsercms.org/installing_modules.html)
17
17
 
18
- gem install bcms_blog
18
+ $ gem install bcms_blog
19
19
 
20
20
  ## Set up your application to use the module
21
21
 
22
22
  ### 1. Install the module
23
23
 
24
- rails g cms:install bcms_blog
24
+ $ rails g cms:install bcms_blog
25
25
 
26
26
  ### 2. Run the following commands
27
27
 
28
- rake db:migrate
29
-
28
+ $ rake db:migrate
29
+ $ rake db:seed
30
+
31
+ For projects with existing databases, you may need to comment out other lines in db/seeds.rb so only the blog seed data runs.
32
+
30
33
  ## Creating a Blog
31
34
 
32
35
  * To get started, go to the Content Library and choose the Blog module in the left hand menu.
@@ -103,3 +106,6 @@ Special thanks to some amazing folks from the BrowserCMS community for their wor
103
106
  * Notifications for Comments - Blogs should have an option to be notified when a new comment is created. This will allow for practical management of comments/spam.
104
107
  * Messaging for Moderated comments - If moderation is turned on, users get no feedback about the comment they just left. Ideally, they would get some sort of javascript notice that their comment is awaiting notification.
105
108
 
109
+ ## 3.5.x Todo
110
+
111
+ * Test and release
@@ -0,0 +1,15 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // the compiled file.
9
+ //
10
+ // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11
+ // GO AFTER THE REQUIRES BELOW.
12
+ //
13
+ //= require jquery
14
+ //= require jquery_ujs
15
+ //= require_tree .
@@ -0,0 +1,13 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ */
@@ -0,0 +1,5 @@
1
+ module BcmsBlog
2
+ class BlogCommentsController < Cms::ContentBlockController
3
+
4
+ end
5
+ end
@@ -0,0 +1,37 @@
1
+ module BcmsBlog
2
+ class BlogPostsController < Cms::ContentBlockController
3
+ before_filter :show_no_access_if_none_editable
4
+
5
+ def build_block
6
+ super
7
+ ensure_blog_editable
8
+ @block.author = current_user
9
+ end
10
+
11
+ def load_block
12
+ super
13
+ ensure_blog_editable
14
+ end
15
+
16
+ def load_blocks
17
+ super
18
+ @blocks.delete_if { |b| !b.editable_by?(current_user) }
19
+ end
20
+
21
+ private
22
+
23
+ # If the current user is not able to edit any blog, just show them a page saying so
24
+ def show_no_access_if_none_editable
25
+ if Blog.editable_by(current_user).empty?
26
+ render :action => "no_access"
27
+ end
28
+ end
29
+
30
+ # Ensure the current user can actually edit the blog this blog post is associated with
31
+ def ensure_blog_editable
32
+ if @block.blog
33
+ raise Cms::Errors::AccessDenied unless @block.blog.editable_by?(current_user)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,13 @@
1
+ module BcmsBlog
2
+ class BlogsController < Cms::ContentBlockController
3
+ check_permissions :administrate, :except => :index
4
+
5
+ def index
6
+ if current_user.able_to?(:administrate)
7
+ super
8
+ else
9
+ render :action => "admin_only"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ module BcmsBlog
2
+ class FeedsController < ApplicationController
3
+
4
+ def index
5
+ @blog = Blog.find(params[:blog_id])
6
+ @blog_posts = @blog.posts.published.all(:limit => 10, :order => "published_at DESC")
7
+ end
8
+
9
+ end
10
+ end
@@ -0,0 +1,27 @@
1
+ module BcmsBlog
2
+ module BlogHelper
3
+ # We can't call it 'blog_path' because that would conflict with the actual named route method if there's a blog named "Blog".
4
+ def _blog_path(blog, route_name, route_params)
5
+ send("#{blog.name_for_path}_#{route_name}_path", route_params)
6
+ end
7
+
8
+ def _blog_post_path(blog_post)
9
+ main_app.send("#{blog_post.route_name}_path", blog_post.route_params)
10
+ end
11
+
12
+ def feeds_link_tag_for(name)
13
+ blog = Blog.find_by_name(name)
14
+ auto_discovery_link_tag(:rss, main_app.blog_feeds_url(:blog_id => blog), :title => "#{blog.name}")
15
+ end
16
+
17
+ def new_comment_params(portlet)
18
+ {:url=> Cms::Engine.routes.url_helpers.portlet_handler_path(:id=>portlet.id, :handler=>'create_comment'),
19
+ :method=>'post'}
20
+ end
21
+
22
+ # Cms::ViewContext doesn't expose this method correctly, so duplicating it here.
23
+ def main_app
24
+ Rails.application.routes.url_helpers
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,99 @@
1
+ module BcmsBlog
2
+ class Blog < ActiveRecord::Base
3
+ acts_as_content_block
4
+
5
+ has_many :posts, :class_name => "BlogPost", :conditions => { :published => true }, :order => "published_at desc"
6
+ has_many :blog_group_memberships
7
+ has_many :groups, :through => :blog_group_memberships, :class_name=>"Cms::Group"
8
+
9
+ attr_accessible :group_ids
10
+
11
+ validates_presence_of :name
12
+ validates_uniqueness_of :name
13
+
14
+ scope :editable_by, lambda { |user|
15
+ if user.able_to?(:administrate)
16
+ { }
17
+ else
18
+ { :include => :groups, :conditions => ["groups.id IN (?)", user.group_ids.join(",")] }
19
+ end
20
+ }
21
+
22
+ def self.default_template
23
+ template_file = ActionController::Base.view_paths.map do |vp|
24
+ path = vp.to_s.first == "/" ? vp.to_s : File.join(Rails.root, vp.to_s)
25
+ File.join(path, "bcms_blog/blogs/render.html.erb")
26
+ end.detect{|f| File.exists? f }
27
+ template_file ? open(template_file){|f| f.read } : ""
28
+ end
29
+
30
+ def self.posts_finder(finder, options)
31
+ if options[:tag]
32
+ finder = finder.tagged_with(options[:tag])
33
+ end
34
+ if options[:exclude_tags]
35
+ finder = finder.not_tagged_with(options[:exclude_tags])
36
+ end
37
+ if options[:category] || options[:category_id]
38
+ category_type = Cms::CategoryType.named("Blog Post").first
39
+ category = category_type.categories.named(options[:category]).first if options[:category]
40
+ category = category_type.categories. find(options[:category_id]) if options[:category_id]
41
+ finder = finder.in_category(category)
42
+ end
43
+ finder
44
+ end
45
+
46
+ def render
47
+ @blog = self
48
+ finder = @blog.posts.published
49
+ finder = Blog.posts_finder(finder, params)
50
+
51
+ if params[:year] && params[:month] && params[:day]
52
+ @date = Date.new(params[:year].to_i, params[:month].to_i, params[:day].to_i)
53
+ finder = posts.published_between(@date, @date + 1.day)
54
+ elsif params[:year] && params[:month]
55
+ @date = Date.new(params[:year].to_i, params[:month].to_i)
56
+ finder = posts.published_between(@date, @date + 1.month)
57
+ elsif params[:year]
58
+ @date = Date.new(params[:year].to_i)
59
+ finder = posts.published_between(@date, @date + 1.year)
60
+ end
61
+
62
+ @blog_posts = finder.all(:limit => 25, :order => "published_at desc")
63
+ raise ActiveRecord::RecordNotFound.new("No posts found") if @blog_posts.empty?
64
+
65
+ if params[:category]
66
+ @page_title = "#{params[:category]}"
67
+ elsif params[:tag]
68
+ @page_title = "Posts tagged with #{params[:tag]}"
69
+ elsif params[:year] && params[:month] && params[:day]
70
+ @page_title = "Posts from #{@date.to_s(:long)}"
71
+ elsif params[:year] && params[:month]
72
+ @page_title = "Posts from #{Date::MONTHNAMES[@date.month]} #{@date.year}"
73
+ elsif params[:year]
74
+ @page_title = "Posts from #{@date.year}"
75
+ end
76
+ end
77
+
78
+ def inline_options
79
+ {:inline => self.template}
80
+ end
81
+
82
+ def self.default_order
83
+ "name"
84
+ end
85
+
86
+ def editable_by?(user)
87
+ user.able_to?(:administrate) || !(group_ids & user.group_ids).empty?
88
+ end
89
+
90
+ def potential_authors
91
+ groups.map(&:users).flatten.uniq
92
+ end
93
+
94
+ def name_for_path
95
+ name.to_slug.gsub('-', '_')
96
+ end
97
+
98
+ end
99
+ end
@@ -0,0 +1,36 @@
1
+ module BcmsBlog
2
+ class BlogComment < ActiveRecord::Base
3
+ acts_as_content_block :is_searachable => "body"
4
+ belongs_to :post, :class_name => "BlogPost", :counter_cache => "comments_count"
5
+
6
+ validates_presence_of :post_id, :author, :body
7
+
8
+ before_create :publish_if_comments_are_enabled
9
+
10
+ def publish_if_comments_are_enabled
11
+ self.published = true unless post.blog.moderate_comments?
12
+ end
13
+
14
+ def self.default_order
15
+ "created_at desc"
16
+ end
17
+
18
+ def self.default_order_for_search
19
+ default_order
20
+ end
21
+
22
+ def self.columns_for_index
23
+ [ {:label => "Comment", :method => :name, :order => "body" },
24
+ {:label => "Created At", :method => :formatted_created_at, :order => "created_at"} ]
25
+ end
26
+
27
+ def name
28
+ body ? body[0..50] : ""
29
+ end
30
+
31
+ def formatted_created_at
32
+ created_at.to_s(:date)
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,6 @@
1
+ module BcmsBlog
2
+ class BlogGroupMembership < ActiveRecord::Base
3
+ belongs_to :blog, :class_name => "BcmsBlog::Blog"
4
+ belongs_to :group, :class_name => "Cms::Group"
5
+ end
6
+ end
@@ -0,0 +1,141 @@
1
+ module BcmsBlog
2
+ class BlogObserver < ActiveRecord::Observer
3
+
4
+ def after_create(blog)
5
+ @blog = blog
6
+ create_section_pages_and_routes
7
+ end
8
+
9
+ def after_save(blog)
10
+ if blog.persisted?
11
+ blog.publish
12
+ end
13
+ end
14
+
15
+ # Can't use before_update since CMS callback stack is altered from normal callbacks.
16
+ def before_save(blog)
17
+ if blog.persisted?
18
+ update_section_pages_and_route(blog)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ # A section, two pages, 6 routes and a portlet are created alongside every blog.
25
+ # This structure provides sensible defaults so users can pretty much start adding
26
+ # posts right after creating a blog without having to worry about where to put
27
+ # their blog and portlets.
28
+ def create_section_pages_and_routes
29
+ create_blog_section
30
+ create_blog_block_page
31
+ create_post_portlet_page
32
+ reload_routes
33
+ end
34
+
35
+ # Every blog is created within a section with the same name.
36
+ # For example, if you create a blog named 'MyBlog', a section 'MyBlog' will be
37
+ # created. This section will hold two pages: one for the blog ContentBlock that
38
+ # will render the list of posts and one for the BlogPost portlet (ie the individual
39
+ # post view)
40
+ def create_blog_section
41
+ @section = Cms::Section.find_by_name(@blog.name) || (
42
+ @section = Cms::Section.create!(
43
+ :name => @blog.name,
44
+ :path => "/#{@blog.name_for_path}",
45
+ :parent => Cms::Section.root.first
46
+ )
47
+ @section.allow_groups = :all
48
+ @section.save!
49
+ @section
50
+ )
51
+ end
52
+
53
+ # Following with the above example, the first page that is created is named 'MyBlog' and
54
+ # holds the Blog ContentBlock directly, not a portlet. Together with the 5 created routes,
55
+ # this page and its ContentBlock handle different post listings (all posts, posts in year,
56
+ # month or day and posts by tag or category).
57
+ def create_blog_block_page
58
+ page = Cms::Page.find_by_name(@blog.name) || Cms::Page.create!(
59
+ :name => @blog.name,
60
+ :path => "/#{@blog.name_for_path}",
61
+ :section => @section,
62
+ :template_file_name => "default.html.erb",
63
+ :hidden => true
64
+ )
65
+ page.create_connector(@blog, 'main')
66
+
67
+ create_route(page, "#{@blog.name}: Posts In Day", "/#{@blog.name_for_path}/:year/:month/:day")
68
+ create_route(page, "#{@blog.name}: Posts In Month", "/#{@blog.name_for_path}/:year/:month")
69
+ create_route(page, "#{@blog.name}: Posts In Year", "/#{@blog.name_for_path}/:year")
70
+ create_route(page, "#{@blog.name}: Posts With Tag", "/#{@blog.name_for_path}/tag/:tag")
71
+ create_route(page, "#{@blog.name}: Posts In Category", "/#{@blog.name_for_path}/category/:category")
72
+ end
73
+
74
+ # The second page that is created holds the BlogPostPortlet and displays the individual
75
+ # post view, along with it's comments.
76
+ def create_post_portlet_page
77
+ page = Cms::Page.find_by_name(portlet_name = "#{@blog.name}: Post") || Cms::Page.create!(
78
+ :name => portlet_name,
79
+ :path => "/#{@blog.name_for_path}/post",
80
+ :section => @section,
81
+ :template_file_name => "default.html.erb",
82
+ :hidden => true)
83
+ page.publish
84
+ create_route(page, portlet_name, "/#{@blog.name_for_path}/:year/:month/:day/:slug")
85
+ create_portlet(page, portlet_name, BlogPostPortlet)
86
+ end
87
+
88
+ # When the name of a Blog block changes, we need to change the Post page route.
89
+ # We also change the *names* of the section and pages that hold the blog block and
90
+ # post portlet because presumably, by changing the name of the blog, the intention
91
+ # was to reflect this name change in breadcrumbs and menus.
92
+ #
93
+ # Note that no other routes or paths are updated. This is intentional to be consistent
94
+ # with how BrowserCMS behaves when a Section or Page names change: paths are not
95
+ # updated automatically.
96
+ def update_section_pages_and_route(blog)
97
+ if blog.name_changed?
98
+ old_blog_name = blog.name_was
99
+
100
+ Cms::Section.find_by_name(old_blog_name).update_attribute(:name, blog.name)
101
+ Cms::PageRoute.find_by_name("#{old_blog_name}: Post").update_attribute(:name, "#{blog.name}: Post")
102
+
103
+ page = Cms::Page.find_by_name("#{old_blog_name}: Post")
104
+ page.update_attribute(:name, "#{blog.name}: Post")
105
+ page.publish
106
+
107
+ page = Cms::Page.find_by_name(old_blog_name)
108
+ page.update_attribute(:name, blog.name)
109
+ page.publish
110
+ end
111
+ end
112
+
113
+ def reload_routes
114
+ Cms::PageRoute.reload_routes
115
+ end
116
+
117
+ def create_route(page, name, pattern)
118
+ route = page.page_routes.build(:name => name, :pattern => pattern, :code => "")
119
+ route.save!
120
+ route.add_condition(:method, "get").save
121
+ route.add_requirement(:year, '\d{4,}') if pattern.include?(":year")
122
+ route.add_requirement(:month, '\d{2,}') if pattern.include?(":month")
123
+ route.add_requirement(:day, '\d{2,}') if pattern.include?(":day")
124
+ route.requirements.each(&:save)
125
+ end
126
+
127
+ def create_portlet(page, name, portlet_class)
128
+ portlet_class.create!(
129
+ :name => "#{name} Portlet",
130
+ :blog_id => @blog.id,
131
+ :template => portlet_class.default_template,
132
+ :connect_to_page_id => page.id,
133
+ :connect_to_container => "main",
134
+ :publish_on_save => true)
135
+ end
136
+ end
137
+ end
138
+
139
+
140
+
141
+
@@ -0,0 +1,108 @@
1
+ module BcmsBlog
2
+ class BlogPost < ActiveRecord::Base
3
+ acts_as_content_block :taggable => true
4
+
5
+ has_attachment :file
6
+
7
+
8
+ before_save :set_published_at
9
+
10
+ belongs_to :blog
11
+ belongs_to_category
12
+ belongs_to :author, :class_name => "Cms::User"
13
+ has_many :comments, :class_name => "BlogComment", :foreign_key => "post_id"
14
+
15
+ before_validation :set_slug
16
+ validates_presence_of :name, :slug, :blog_id, :author_id
17
+
18
+ scope :published_between, lambda { |start, finish|
19
+ { :conditions => [
20
+ "#{table_name}.published_at >= ? AND #{table_name}.published_at < ?",
21
+ start, finish ] }
22
+ }
23
+
24
+ scope :not_tagged_with, lambda { |tag| {
25
+ :conditions => [
26
+ "#{table_name}.id not in (
27
+ SELECT taggings.taggable_id FROM taggings
28
+ JOIN tags ON tags.id = taggings.tag_id
29
+ WHERE taggings.taggable_type = 'BlogPost'
30
+ AND (tags.name = ?)
31
+ )",
32
+ tag
33
+ ]
34
+ } }
35
+
36
+ INCORRECT_PARAMETERS = "Incorrect parameters. This is probably because you are trying to view the " +
37
+ "portlet through the CMS interface, and so we have no way of knowing what " +
38
+ "post(s) to show"
39
+
40
+ delegate :editable_by?, :to => :blog
41
+
42
+ def set_published_at
43
+ if !published_at && publish_on_save
44
+ self.published_at = Time.now
45
+ end
46
+ end
47
+
48
+ # This is necessary because, oddly, the publish! method in the Publishing behaviour sends an update
49
+ # query directly to the database, bypassing callbacks, so published_at does not get set by our
50
+ # set_published_at callback.
51
+ def after_publish_with_set_published_at
52
+ if published_at.nil?
53
+ self.published_at = Time.now
54
+ self.save!
55
+ end
56
+ after_publish_without_set_published_at if respond_to? :after_publish_without_set_published_at
57
+ end
58
+ if instance_methods.map(&:to_s).include? 'after_publish'
59
+ alias_method_chain :after_publish, :set_published_at
60
+ else
61
+ alias_method :after_publish, :after_publish_with_set_published_at
62
+ end
63
+
64
+ def self.default_order
65
+ "created_at desc"
66
+ end
67
+
68
+ def self.columns_for_index
69
+ [ {:label => "Name", :method => :name, :order => "name" },
70
+ {:label => "Published At", :method => :published_label, :order => "published_at" } ]
71
+ end
72
+
73
+ def published_label
74
+ published_at ? published_at.to_s(:date) : nil
75
+ end
76
+
77
+ def set_slug
78
+ self.slug = name.to_slug
79
+ end
80
+
81
+ def path
82
+ send("#{blog.name_for_path}_post_path", route_params)
83
+ end
84
+ def route_name
85
+ "#{blog.name_for_path}_post"
86
+ end
87
+ def route_params
88
+ {:year => year, :month => month, :day => day, :slug => slug}
89
+ end
90
+
91
+ def year
92
+ published_at.strftime("%Y") unless published_at.blank?
93
+ end
94
+
95
+ def month
96
+ published_at.strftime("%m") unless published_at.blank?
97
+ end
98
+
99
+ def day
100
+ published_at.strftime("%d") unless published_at.blank?
101
+ end
102
+
103
+ # Return true if this model has an attachment
104
+ def attachment
105
+ !file.blank?
106
+ end
107
+ end
108
+ end
@@ -1,9 +1,9 @@
1
- class BlogPostPortlet < Portlet
1
+ class BlogPostPortlet < Cms::Portlet
2
2
 
3
3
  enable_template_editor false
4
4
 
5
5
  def render
6
- scope = Blog.find(self.blog_id).posts
6
+ scope = BcmsBlog::Blog.find(self.blog_id).posts
7
7
  if params[:blog_post_id]
8
8
  @blog_post = scope.find(params[:blog_post_id])
9
9
  elsif params[:slug]
@@ -13,7 +13,7 @@ class BlogPostPortlet < Portlet
13
13
  end
14
14
  @blog_post = scope.find_by_slug!(params[:slug])
15
15
  else
16
- raise BlogPost::INCORRECT_PARAMETERS
16
+ raise BcmsBlog::BlogPost::INCORRECT_PARAMETERS
17
17
  end
18
18
 
19
19
  make_page_title_use_blog_post_name(@blog_post)
@@ -29,7 +29,7 @@ class BlogPostPortlet < Portlet
29
29
  work_around_cms_3_3_bug_where_current_user_is_not_correctly_set
30
30
 
31
31
  params[:blog_comment].merge! :ip => request.remote_ip
32
- blog_comment = BlogComment.new(params[:blog_comment])
32
+ blog_comment = BcmsBlog::BlogComment.new(params[:blog_comment])
33
33
  if blog_comment.valid? && blog_comment.save
34
34
  url_for_success
35
35
  else
@@ -42,10 +42,10 @@ class BlogPostPortlet < Portlet
42
42
  private
43
43
 
44
44
  def work_around_cms_3_3_bug_where_current_user_is_not_correctly_set
45
- User.current = current_user
45
+ Cms::User.current = current_user
46
46
  end
47
47
 
48
- # This is a work around for a bug in bcms 3.3 where the Cms::PageHeler#page_title doesnt
48
+ # This is a work around for a bug in bcms 3.3 where the Cms::PageHelper#page_title doesnt
49
49
  # share state between the portlet view and the page view.
50
50
  # When the portlet view (app/views/portlets/blog_post/render) calls 'page_title @post.name'
51
51
  # that instance variable isn't shared back to the page template.
@@ -1,4 +1,4 @@
1
- class BlogPostsPortlet < Portlet
1
+ class BlogPostsPortlet < Cms::Portlet
2
2
 
3
3
  after_initialize :build_permalink_code
4
4
 
@@ -22,9 +22,9 @@ class BlogPostsPortlet < Portlet
22
22
  Rails.logger.debug "... BlogPostsPortlet#render(options=#{@options.inspect} #{@options.class})"
23
23
 
24
24
  if @options[:blog_id]
25
- finder = Blog.find(@options[:blog_id]).posts
25
+ finder = BcmsBlog::Blog.find(@options[:blog_id]).posts
26
26
  elsif @options[:blog_name]
27
- finder = Blog.find_by_name(@options[:blog_name]).posts
27
+ finder = BcmsBlog::Blog.find_by_name(@options[:blog_name]).posts
28
28
  else
29
29
  finder = BlogPost
30
30
  end
@@ -35,7 +35,7 @@ class BlogPostsPortlet < Portlet
35
35
  end
36
36
 
37
37
  finder = finder.published
38
- finder = Blog.posts_finder(finder, @options)
38
+ finder = BcmsBlog::Blog.posts_finder(finder, @options)
39
39
 
40
40
  @blog_posts = finder.all(
41
41
  :limit => @options[:limit] || 25,
@@ -0,0 +1,5 @@
1
+ <%= f.cms_drop_down :post_id, BcmsBlog::BlogPost.all(:order => "name").map{|p| [p.name, p.id]} %>
2
+ <%= f.cms_text_field :author %>
3
+ <%= f.cms_text_field :email %>
4
+ <%= f.cms_text_field :url %>
5
+ <%= f.cms_text_area :body %>
@@ -0,0 +1,2 @@
1
+ <%= link_to h(@content_block.post.name), _blog_post_path(@content_block.post) %>
2
+ <p><%=h @content_block.body.html_safe %></p>
@@ -7,5 +7,5 @@
7
7
  <% end %>
8
8
  <%= f.cms_drop_down :category_id, categories_for('Blog Post').map{|c| [c.path, c.id]}, :include_blank => true %>
9
9
  <%= f.cms_tag_list %>
10
- <%= f.cms_drop_down :blog_id, Blog.editable_by(current_user).map{|b| [b.name, b.id]} %>
10
+ <%= f.cms_drop_down :blog_id, BcmsBlog::Blog.editable_by(current_user).map{|b| [b.name, b.id]} %>
11
11
  <%= f.cms_file_field :attachment_file, :label => "Image" %>