bcms_blog 1.2.0 → 1.3.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.
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
@@ -1,140 +0,0 @@
1
- class BlogObserver < ActiveRecord::Observer
2
-
3
- def after_create(blog)
4
- @blog = blog
5
- create_section_pages_and_routes
6
- end
7
-
8
- def after_save(blog)
9
- if blog.persisted?
10
- blog.publish
11
- end
12
- end
13
-
14
- # Can't use before_update since CMS callback stack is altered from normal callbacks.
15
- def before_save(blog)
16
- if blog.persisted?
17
- update_section_pages_and_route(blog)
18
- end
19
- end
20
-
21
- private
22
-
23
- # A section, two pages, 6 routes and a portlet are created alongside every blog.
24
- # This structure provides sensible defaults so users can pretty much start adding
25
- # posts right after creating a blog without having to worry about where to put
26
- # their blog and portlets.
27
- def create_section_pages_and_routes
28
- create_blog_section
29
- create_blog_block_page
30
- create_post_portlet_page
31
- reload_routes
32
- end
33
-
34
- # Every blog is created within a section with the same name.
35
- # For example, if you create a blog named 'MyBlog', a section 'MyBlog' will be
36
- # created. This section will hold two pages: one for the blog ContentBlock that
37
- # will render the list of posts and one for the BlogPost portlet (ie the individual
38
- # post view)
39
- def create_blog_section
40
- @section = Section.find_by_name(@blog.name) || (
41
- @section = Section.create!(
42
- :name => @blog.name,
43
- :path => "/#{@blog.name_for_path}",
44
- :parent_id => 1
45
- )
46
- @section.allow_groups = :all
47
- @section.save!
48
- @section
49
- )
50
- end
51
-
52
- # Following with the above example, the first page that is created is named 'MyBlog' and
53
- # holds the Blog ContentBlock directly, not a portlet. Together with the 5 created routes,
54
- # this page and its ContentBlock handle different post listings (all posts, posts in year,
55
- # month or day and posts by tag or category).
56
- def create_blog_block_page
57
- page = Page.find_by_name(@blog.name) || Page.create!(
58
- :name => @blog.name,
59
- :path => "/#{@blog.name_for_path}",
60
- :section => @section,
61
- :template_file_name => "default.html.erb",
62
- :hidden => true
63
- )
64
- page.create_connector(@blog, 'main')
65
-
66
- create_route(page, "#{@blog.name}: Posts In Day", "/#{@blog.name_for_path}/:year/:month/:day")
67
- create_route(page, "#{@blog.name}: Posts In Month", "/#{@blog.name_for_path}/:year/:month")
68
- create_route(page, "#{@blog.name}: Posts In Year", "/#{@blog.name_for_path}/:year")
69
- create_route(page, "#{@blog.name}: Posts With Tag", "/#{@blog.name_for_path}/tag/:tag")
70
- create_route(page, "#{@blog.name}: Posts In Category", "/#{@blog.name_for_path}/category/:category")
71
- end
72
-
73
- # The second page that is created holds the BlogPostPortlet and displays the individual
74
- # post view, along with it's comments.
75
- def create_post_portlet_page
76
- page = Page.find_by_name(portlet_name = "#{@blog.name}: Post") || Page.create!(
77
- :name => portlet_name,
78
- :path => "/#{@blog.name_for_path}/post",
79
- :section => @section,
80
- :template_file_name => "default.html.erb",
81
- :hidden => true)
82
- page.publish
83
- create_route(page, portlet_name, "/#{@blog.name_for_path}/:year/:month/:day/:slug")
84
- create_portlet(page, portlet_name, BlogPostPortlet)
85
- end
86
-
87
- # When the name of a Blog block changes, we need to change the Post page route.
88
- # We also change the *names* of the section and pages that hold the blog block and
89
- # post portlet because presumably, by changing the name of the blog, the intention
90
- # was to reflect this name change in breadcrumbs and menus.
91
- #
92
- # Note that no other routes or paths are updated. This is intentional to be consistent
93
- # with how BrowserCMS behaves when a Section or Page names change: paths are not
94
- # updated automatically.
95
- def update_section_pages_and_route(blog)
96
- if blog.name_changed?
97
- old_blog_name = blog.name_was
98
-
99
- Section.find_by_name(old_blog_name).update_attribute(:name, blog.name)
100
- PageRoute.find_by_name("#{old_blog_name}: Post").update_attribute(:name, "#{blog.name}: Post")
101
-
102
- page = Page.find_by_name("#{old_blog_name}: Post")
103
- page.update_attribute(:name, "#{blog.name}: Post")
104
- page.publish
105
-
106
- page = Page.find_by_name(old_blog_name)
107
- page.update_attribute(:name, blog.name)
108
- page.publish
109
- end
110
- end
111
-
112
- def reload_routes
113
- PageRoute.reload_routes
114
- end
115
-
116
- def create_route(page, name, pattern)
117
- route = page.page_routes.build(:name => name, :pattern => pattern, :code => "")
118
- route.save!
119
- route.add_condition(:method, "get").save
120
- route.add_requirement(:year, '\d{4,}') if pattern.include?(":year")
121
- route.add_requirement(:month, '\d{2,}') if pattern.include?(":month")
122
- route.add_requirement(:day, '\d{2,}') if pattern.include?(":day")
123
- route.requirements.each(&:save)
124
- end
125
-
126
- def create_portlet(page, name, portlet_class)
127
- portlet_class.create!(
128
- :name => "#{name} Portlet",
129
- :blog_id => @blog.id,
130
- :template => portlet_class.default_template,
131
- :connect_to_page_id => page.id,
132
- :connect_to_container => "main",
133
- :publish_on_save => true)
134
- end
135
- end
136
-
137
-
138
-
139
-
140
-
@@ -1,113 +0,0 @@
1
- class BlogPost < ActiveRecord::Base
2
- acts_as_content_block :taggable => true
3
-
4
- belongs_to_attachment
5
- def set_attachment_file_path
6
- # The default behavior is use /attachments/file.txt for the attachment path,
7
- # assuming file.txt was the name of the file the user uploaded
8
- # You should override this with your own strategy for setting the attachment path
9
- super
10
- end
11
-
12
- def set_attachment_section
13
- # The default behavior is to put all attachments in the root section
14
- # Override this method if you would like to change that
15
- super
16
- end
17
-
18
-
19
- before_save :set_published_at
20
-
21
- belongs_to :blog
22
- belongs_to_category
23
- belongs_to :author, :class_name => "User"
24
- has_many :comments, :class_name => "BlogComment", :foreign_key => "post_id"
25
-
26
- before_validation :set_slug
27
- validates_presence_of :name, :slug, :blog_id, :author_id
28
-
29
- scope :published_between, lambda { |start, finish|
30
- { :conditions => [
31
- "blog_posts.published_at >= ? AND blog_posts.published_at < ?",
32
- start, finish ] }
33
- }
34
-
35
- scope :not_tagged_with, lambda { |tag| {
36
- :conditions => [
37
- "blog_posts.id not in (
38
- SELECT taggings.taggable_id FROM taggings
39
- JOIN tags ON tags.id = taggings.tag_id
40
- WHERE taggings.taggable_type = 'BlogPost'
41
- AND (tags.name = ?)
42
- )",
43
- tag
44
- ]
45
- } }
46
-
47
- INCORRECT_PARAMETERS = "Incorrect parameters. This is probably because you are trying to view the " +
48
- "portlet through the CMS interface, and so we have no way of knowing what " +
49
- "post(s) to show"
50
-
51
- delegate :editable_by?, :to => :blog
52
-
53
- def set_published_at
54
- if !published_at && publish_on_save
55
- self.published_at = Time.now
56
- end
57
- end
58
-
59
- # This is necessary because, oddly, the publish! method in the Publishing behaviour sends an update
60
- # query directly to the database, bypassing callbacks, so published_at does not get set by our
61
- # set_published_at callback.
62
- def after_publish_with_set_published_at
63
- if published_at.nil?
64
- self.published_at = Time.now
65
- self.save!
66
- end
67
- after_publish_without_set_published_at if respond_to? :after_publish_without_set_published_at
68
- end
69
- if instance_methods.map(&:to_s).include? 'after_publish'
70
- alias_method_chain :after_publish, :set_published_at
71
- else
72
- alias_method :after_publish, :after_publish_with_set_published_at
73
- end
74
-
75
- def self.default_order
76
- "created_at desc"
77
- end
78
-
79
- def self.columns_for_index
80
- [ {:label => "Name", :method => :name, :order => "name" },
81
- {:label => "Published At", :method => :published_label, :order => "published_at" } ]
82
- end
83
-
84
- def published_label
85
- published_at ? published_at.to_s(:date) : nil
86
- end
87
-
88
- def set_slug
89
- self.slug = name.to_slug
90
- end
91
-
92
- def path
93
- send("#{blog.name_for_path}_post_path", route_params)
94
- end
95
- def route_name
96
- "#{blog.name_for_path}_post"
97
- end
98
- def route_params
99
- {:year => year, :month => month, :day => day, :slug => slug}
100
- end
101
-
102
- def year
103
- published_at.strftime("%Y") unless published_at.blank?
104
- end
105
-
106
- def month
107
- published_at.strftime("%m") unless published_at.blank?
108
- end
109
-
110
- def day
111
- published_at.strftime("%d") unless published_at.blank?
112
- end
113
- end
@@ -1,5 +0,0 @@
1
- <%= f.cms_drop_down :post_id, 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 %>
@@ -1,2 +0,0 @@
1
- <%= link_to h(@content_block.post.name), cms_blog_post_path(@content_block.post) %>
2
- <p><%=h @content_block.body.html_safe %></p>
@@ -1,17 +0,0 @@
1
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
3
- <head>
4
- <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
5
- <title><%= page_title %></title>
6
- <%= yield :html_head %>
7
- </head>
8
- <body style="margin: 0; padding: 0; text-align: center;">
9
- <%= cms_toolbar %>
10
- <div id="wrapper" style="width: 700px; margin: 0 auto; text-align: left; padding: 30px">
11
- Breadcrumbs: <%= render_breadcrumbs %>
12
- Main Menu: <%= render_menu %>
13
- <h1><%= page_title %></h1>
14
- <%= container :main %>
15
- </div>
16
- </body>
17
- </html>
data/doc/README_FOR_APP DELETED
@@ -1,2 +0,0 @@
1
- Use this README file to introduce your application and point to useful places in the API for learning more.
2
- Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries.
@@ -1,77 +0,0 @@
1
- # Ideally, we would create a new migration whenever we wanted to make changes to an existing
2
- # migration that is already in circulation, instead of simply editing the existing migrations
3
- # and publishing the new version, because doing rake db:migrate:redo VERSION=20090415000000,
4
- # etc. on each updated migration is not only a pain but will probably result in more data being
5
- # lost than is strictly necessary -- assuming the migrations work correctly at all.
6
- #
7
- # On the other hand, there's something pretty compelling about "fixing" the migration so that
8
- # it doesn't have any useless steps that are just going to get reverted by the next migration.
9
- #
10
- # There is also the problem of model dependencies: you can't safely remove a model in the same
11
- # commit that you use that model in a migration (f.e., Model.destroy_all). Even if you remove it
12
- # in the following commit, it's only safe if people check out every intermediate version and run
13
- # db:migrate at each version, instead of simply checking out the tip version and then running
14
- # db:migrate. And people don't do that.
15
- #
16
- # Anyway, I guess we assume that there are only a few brave souls out there who are already
17
- # using bcms_blog and hope for the best. Here is the "missing migration"; hopefully it will be
18
- # helpful to you.
19
- #
20
- # Run this script instead of re-running the changed migrations with rake db:migrate:redo so that
21
- # your blog data is not destroyed.
22
- #
23
- # Usage: ./script/runner 'require "/path/to/bcms_blog/doc/migrate_to_20100427.rb"'
24
-
25
- require 'pp'
26
-
27
- Page # trigger auto-loading
28
- # At the time of this writing, these associations are missing :dependent => :destroy
29
- class Page
30
- has_many :page_routes, :dependent => :destroy
31
- end
32
- class PageRoute
33
- has_many :requirements, :class_name => "PageRouteRequirement", :dependent => :destroy
34
- has_many :conditions, :class_name => "PageRouteCondition", :dependent => :destroy
35
- end
36
-
37
- # Added these here because these classes will be removed by the next commit, so if anyone tried to run this script in future versions it would have a missing constant error unless we keep these class definitions around
38
- class BlogPostsInCategoryPortlet < Portlet; end
39
- class BlogPostsWithTagPortlet < Portlet; end
40
- class BlogPostPortlet < Portlet; end
41
- class BlogPostsInDayPortlet < Portlet; end
42
- class BlogPostsInMonthPortlet < Portlet; end
43
- class BlogPostsInYearPortlet < Portlet; end
44
-
45
- class MigrateTo20100427 < ActiveRecord::Migration
46
- def self.up
47
- drop_table :blog_group_membership_versions
48
-
49
- PageRouteOption.all.each {|a| a.destroy unless a.page_route }
50
-
51
- puts "Destroying portlets, pages, page_routes left over from old version of bcms_blog..."
52
- puts "(*Not* destroying any existing Blogs, pages on which Blogs are connected, or BlogPosts)"
53
- portlets = [BlogPostPortlet, BlogPostsInCategoryPortlet, BlogPostsWithTagPortlet, BlogPostsInDayPortlet, BlogPostsInMonthPortlet, BlogPostsInYearPortlet]
54
- #pp portlets.map(&:all).flatten.map(&:connected_pages).flatten.map(&:page_routes).flatten.each(&:destroy)
55
- pp portlets.map(&:all).flatten.map(&:connected_pages).flatten.each(&:destroy)
56
- pp portlets.map(&:all).flatten.each(&:destroy)
57
-
58
- # Something like this might not work if they have moved their Blog page to a different section or to no section, so we better let users resolve this manually...
59
- #Blog.all.map(&:connected_pages).flatten.each do |page|
60
- # page.hidden = true
61
- # page.save!
62
- # page.section.hidden = false
63
- # page.section.save!
64
- #end
65
-
66
- puts "Calling after_create on each Blog in the system..."
67
- Blog.all.each do |blog|
68
- puts "#{blog}..."
69
- blog.send :after_create
70
- end
71
- end
72
-
73
- def self.down
74
- end
75
- end
76
-
77
- MigrateTo20100427.up
@@ -1,48 +0,0 @@
1
- v1.2.0
2
- - Upgrade to be compatible with BrowserCMS 3.3 (aka Rails 3)
3
-
4
- v1.1.1
5
-
6
- - Blog partials and templates no longer include any css style declarations
7
- - Fixed browsing by tags, categories and dates
8
- - Fixed bug on page route conditions and requirements when creating a blog
9
- - Tests refactoring. Tests now depend on bcms_support gem
10
-
11
- v1.1.0
12
-
13
- This version introduces significant changes and improvements over version 1.0.0
14
- and lays the groundwork for a more sophisticated blogging platform for BrowserCMS.
15
-
16
- Notable Features:
17
- =================
18
-
19
- 1. A Blog and supporting structure (sections, pages, page routes, etc.) and data are no longer
20
- created as part of the modules's installation process. When running the module's migrations,
21
- only the following items are created:
22
-
23
- * blogs, blog_posts and blog_comment tables (and corresponding tables to hold versioning data)
24
- * blog_group_memberships table
25
- * Blog, BlogPost and BlogComment content types
26
- * Blog Post category type
27
-
28
- 2. It is only until a Blog is created when a corresponding section, pages, page routes and portlets are created.
29
- Each blog has its own section, pages and page routes, which allows for multiple blogs to be created.
30
-
31
- 3. It is now possible to add attachments to blog posts.
32
-
33
- 4. Comments are moderated by default using BrowserCMS' default behaviors. However, when creating a Blog,
34
- users can specify whether comments should be published automatically.
35
-
36
- 5. The module now uses BrowserCMS' permissions framework to specify if a particular user is able to
37
- create or edit Blogs and BlogPosts.
38
-
39
- 6. Portlets have been improved to match common standard blog publishing templates.
40
-
41
- For a complete rundown and rationale behind the changes introduced, please refer to:
42
- https://browsermedia.lighthouseapp.com/projects/28481/tickets/163-review-and-integrate-changes-to-the-blog-module
43
-
44
- Contributors:
45
- =============
46
- Tyler Rick
47
- Jon Leighton
48
- Juan Alvarez
@@ -1,10 +0,0 @@
1
- module Cms::Routes
2
- def routes_for_bcms_blog
3
- match '/blog/feeds', :to=>"feeds#index", :defaults=>{:format => "rss"}, :as=>'blog_feeds'
4
- namespace(:cms) do
5
- content_blocks :blogs
6
- content_blocks :blog_posts
7
- content_blocks :blog_comments
8
- end
9
- end
10
- end