tylerrick-bcms_blog 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +63 -0
- data/app/controllers/application_controller.rb +10 -0
- data/app/controllers/cms/blog_comments_controller.rb +3 -0
- data/app/controllers/cms/blog_posts_controller.rb +35 -0
- data/app/controllers/cms/blogs_controller.rb +11 -0
- data/app/helpers/application_helper.rb +3 -0
- data/app/helpers/cms/blog_helper.rb +11 -0
- data/app/models/blog.rb +143 -0
- data/app/models/blog_comment.rb +28 -0
- data/app/models/blog_group_membership.rb +4 -0
- data/app/models/blog_post.rb +101 -0
- data/app/portlets/blog_post_portlet.rb +38 -0
- data/app/views/cms/blog_comments/_form.html.erb +5 -0
- data/app/views/cms/blog_comments/render.html.erb +2 -0
- data/app/views/cms/blog_posts/_form.html.erb +11 -0
- data/app/views/cms/blog_posts/no_access.html.erb +9 -0
- data/app/views/cms/blog_posts/render.html.erb +1 -0
- data/app/views/cms/blogs/_form.html.erb +23 -0
- data/app/views/cms/blogs/admin_only.html.erb +9 -0
- data/app/views/cms/blogs/render.html.erb +2 -0
- data/app/views/partials/_blog_post.html.erb +106 -0
- data/app/views/partials/_blog_post.html.haml +91 -0
- data/app/views/portlets/blog_post/_form.html.erb +3 -0
- data/app/views/portlets/blog_post/render.html.erb +33 -0
- data/db/migrate/20090415000000_create_blogs.rb +45 -0
- data/db/migrate/20090415000001_create_blog_posts.rb +25 -0
- data/db/migrate/20090415000002_create_blog_comments.rb +19 -0
- data/db/migrate/20090415000003_add_attachment_to_blog_posts.rb +23 -0
- data/doc/README_FOR_APP +2 -0
- data/doc/migrate_to_20100427.rb +68 -0
- data/lib/bcms_blog/routes.rb +9 -0
- data/lib/bcms_blog.rb +1 -0
- data/rails/init.rb +4 -0
- data/test/factories.rb +31 -0
- data/test/functional/blog_post_test.rb +41 -0
- data/test/functional/blog_test.rb +69 -0
- data/test/functional/cms/blog_posts_controller_test.rb +43 -0
- data/test/functional/cms/blogs_controller_test.rb +12 -0
- data/test/performance/browsing_test.rb +9 -0
- data/test/test_helper.rb +104 -0
- data/test/test_logging.rb +64 -0
- data/test/unit/blog_post_test.rb +16 -0
- data/test/unit/blog_test.rb +23 -0
- metadata +96 -0
data/README.markdown
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# Blog Module for BrowserCMS
|
2
|
+
|
3
|
+
A simple blog module that lets you create one or more blogs. It features:
|
4
|
+
|
5
|
+
* Blog posts can be tagged and categorized
|
6
|
+
* The ability for users to leave comments on a blog post (stores the user name, email, url and comment)
|
7
|
+
* Support for multiple blogs
|
8
|
+
* Blog block can be added to any container in any page
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
To install this module, do the following:
|
12
|
+
|
13
|
+
### A. Build and install the gem from source
|
14
|
+
This assumes you have the latest copy of the code from github on your machine.
|
15
|
+
|
16
|
+
gem build bcms_blog.gemspec
|
17
|
+
sudo gem install bcms_blog-1.x.x.gem
|
18
|
+
|
19
|
+
At this point, the Page Comments gem should be installed as a gem on your system, and can be added to your projects.
|
20
|
+
|
21
|
+
### B. Adding the Page Comments to your project
|
22
|
+
In your BrowserCMS application, do the following steps.
|
23
|
+
|
24
|
+
#### 1. Edit the confing/environment.rb file
|
25
|
+
|
26
|
+
config.gem 'browsercms'
|
27
|
+
|
28
|
+
# Add this next line after the browsercms gem
|
29
|
+
config.gem "bcms_page_comments"
|
30
|
+
|
31
|
+
#### 2. Edit the routes.rb file
|
32
|
+
|
33
|
+
# Add this route. It must be before the core browser_cms route.
|
34
|
+
map.routes_for_bcms_page_comments
|
35
|
+
map.routes_for_browser_cms
|
36
|
+
|
37
|
+
#### 3. Install the new module code
|
38
|
+
From the root directory of your cms project, run:
|
39
|
+
|
40
|
+
script/generate browser_cms
|
41
|
+
|
42
|
+
This will copy all the necessary views and migrations from the gems into your local project. You should messages checking to see if files already exist or were created.
|
43
|
+
|
44
|
+
#### 4. Run migrations and start the server
|
45
|
+
Modules will often add new data types, like content blocks, so you need to run the migrations to add them to your project.
|
46
|
+
|
47
|
+
rake db:migrate
|
48
|
+
script/server
|
49
|
+
|
50
|
+
#### 5. Create a Comments portlet and embed into your templates
|
51
|
+
* Open your browser to localhost:3000/cms/portlets and login
|
52
|
+
* Click 'Add New Content', and select 'Page Comments Portlet'
|
53
|
+
* Set the name to 'Page Comments' and click save.
|
54
|
+
* Now go to Administration -> Page Templates -> Sub Page -> Edit
|
55
|
+
* Add the following line to your template, somewhere in the body (preferably after your main content area)
|
56
|
+
|
57
|
+
<%= render_portlet "Page Comments" %>
|
58
|
+
|
59
|
+
This will render embed the portlet named "Page Comments" into any page which uses the Sub Page template.
|
60
|
+
|
61
|
+
* Now add a new page using the "Sub Page" template and you should see the comments form. Adding a new comment will display on that page.
|
62
|
+
|
63
|
+
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Filters added to this controller apply to all controllers in the application.
|
2
|
+
# Likewise, all the methods added will be available for all controllers.
|
3
|
+
|
4
|
+
class ApplicationController < ActionController::Base
|
5
|
+
helper :all # include all helpers, all the time
|
6
|
+
protect_from_forgery # See ActionController::RequestForgeryProtection for details
|
7
|
+
|
8
|
+
# Scrub sensitive parameters from your log
|
9
|
+
# filter_parameter_logging :password
|
10
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class Cms::BlogPostsController < Cms::ContentBlockController
|
2
|
+
before_filter :show_no_access_if_none_editable
|
3
|
+
|
4
|
+
def build_block
|
5
|
+
super
|
6
|
+
ensure_blog_editable
|
7
|
+
@block.author = current_user
|
8
|
+
end
|
9
|
+
|
10
|
+
def load_block
|
11
|
+
super
|
12
|
+
ensure_blog_editable
|
13
|
+
end
|
14
|
+
|
15
|
+
def load_blocks
|
16
|
+
super
|
17
|
+
@blocks.delete_if { |b| !b.editable_by?(current_user) }
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
# If the current user is not able to edit any blog, just show them a page saying so
|
23
|
+
def show_no_access_if_none_editable
|
24
|
+
if Blog.editable_by(current_user).empty?
|
25
|
+
render :action => "no_access"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Ensure the current user can actually edit the blog this blog post is associated with
|
30
|
+
def ensure_blog_editable
|
31
|
+
if @block.blog
|
32
|
+
raise Cms::Errors::AccessDenied unless @block.blog.editable_by?(current_user)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Cms::BlogHelper
|
2
|
+
# We can't call it 'blog_path' because that would conflict with the actual named route method if there's a blog named "Blog".
|
3
|
+
def _blog_path(blog, route_name, route_params)
|
4
|
+
send("#{blog.name_for_path}_#{route_name}_path", route_params)
|
5
|
+
end
|
6
|
+
|
7
|
+
def _blog_post_path(blog_post)
|
8
|
+
send("#{blog_post.route_name}_path", blog_post.route_params)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
data/app/models/blog.rb
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
class Blog < ActiveRecord::Base
|
2
|
+
acts_as_content_block
|
3
|
+
has_many :posts, :class_name => "BlogPost", :conditions => { :published => true }, :order => "published_at desc"
|
4
|
+
|
5
|
+
has_many :blog_group_memberships
|
6
|
+
has_many :groups, :through => :blog_group_memberships
|
7
|
+
|
8
|
+
validates_presence_of :name
|
9
|
+
validates_uniqueness_of :name
|
10
|
+
|
11
|
+
named_scope :editable_by, lambda { |user|
|
12
|
+
if user.able_to?(:administrate)
|
13
|
+
{ }
|
14
|
+
else
|
15
|
+
{ :include => :groups, :conditions => ["groups.id IN (?)", user.group_ids.join(",")] }
|
16
|
+
end
|
17
|
+
}
|
18
|
+
|
19
|
+
def self.default_template
|
20
|
+
template_file = ActionController::Base.view_paths.map do |vp|
|
21
|
+
path = vp.to_s.first == "/" ? vp.to_s : File.join(Rails.root, vp.to_s)
|
22
|
+
File.join(path, "cms/blogs/render.html.erb")
|
23
|
+
end.detect{|f| File.exists? f }
|
24
|
+
template_file ? open(template_file){|f| f.read } : ""
|
25
|
+
end
|
26
|
+
|
27
|
+
def render
|
28
|
+
@blog = self
|
29
|
+
finder = @blog.posts.published
|
30
|
+
|
31
|
+
if params[:category]
|
32
|
+
@category_type = CategoryType.named("Blog Post").first
|
33
|
+
@category = @category_type.categories.named(params[:category]).first
|
34
|
+
finder = finder.in_category(@category)
|
35
|
+
@page_title = "Posts in category #{params[:category]}"
|
36
|
+
elsif params[:tag]
|
37
|
+
finder = finder.tagged_with(params[:tag])
|
38
|
+
@page_title = "Posts tagged with #{params[:tag]}"
|
39
|
+
elsif params[:year] && params[:month] && params[:day]
|
40
|
+
@date = Date.new(params[:year].to_i, params[:month].to_i, params[:day].to_i)
|
41
|
+
finder = posts.published_between(@date, @date + 1.day)
|
42
|
+
@page_title = "Blog posts from #{@date.to_s(:long)}"
|
43
|
+
elsif params[:year] && params[:month]
|
44
|
+
@date = Date.new(params[:year].to_i, params[:month].to_i)
|
45
|
+
finder = posts.published_between(@date, @date + 1.month)
|
46
|
+
@page_title = "Blog posts from #{Date::MONTHNAMES[@date.month]} #{@date.year}"
|
47
|
+
elsif params[:year]
|
48
|
+
@date = Date.new(params[:year].to_i)
|
49
|
+
finder = posts.published_between(@date, @date + 1.year)
|
50
|
+
@page_title = "Blog posts from #{@date.year}"
|
51
|
+
end
|
52
|
+
|
53
|
+
@blog_posts = finder.all(:limit => 25, :order => "published_at desc")
|
54
|
+
raise ActiveRecord::RecordNotFound.new("No posts found") if @blog_posts.empty?
|
55
|
+
end
|
56
|
+
|
57
|
+
def inline_options
|
58
|
+
{:inline => self.template}
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.default_order
|
62
|
+
"name"
|
63
|
+
end
|
64
|
+
|
65
|
+
def editable_by?(user)
|
66
|
+
user.able_to?(:administrate) || !(group_ids & user.group_ids).empty?
|
67
|
+
end
|
68
|
+
|
69
|
+
def potential_authors
|
70
|
+
groups.map(&:users).flatten.uniq
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
#-------------------------------------------------------------------------------------------------
|
75
|
+
|
76
|
+
def name_for_path
|
77
|
+
name.to_slug.gsub('-', '_')
|
78
|
+
end
|
79
|
+
|
80
|
+
protected
|
81
|
+
def after_create
|
82
|
+
section = Section.find_by_name(name) || (
|
83
|
+
section = Section.create!(
|
84
|
+
:name => name,
|
85
|
+
:path => "/#{name_for_path}",
|
86
|
+
:parent_id => 1
|
87
|
+
)
|
88
|
+
section.groups << Group.find_by_code("cms-admin")
|
89
|
+
section.groups << Group.find_by_code("guest")
|
90
|
+
section.groups << Group.find_by_code("content-editor")
|
91
|
+
section.save!
|
92
|
+
section
|
93
|
+
)
|
94
|
+
|
95
|
+
page = Page.find_by_name(name) || Page.create!(
|
96
|
+
:name => name,
|
97
|
+
:path => "/#{name_for_path}",
|
98
|
+
:section => section,
|
99
|
+
:template_file_name => "default.html.erb",
|
100
|
+
:hidden => true
|
101
|
+
)
|
102
|
+
page.create_connector(self, 'main')
|
103
|
+
create_route(page, "#{name}: Posts In Day", "/#{name_for_path}/:year/:month/:day")
|
104
|
+
create_route(page, "#{name}: Posts In Month", "/#{name_for_path}/:year/:month")
|
105
|
+
create_route(page, "#{name}: Posts In Year", "/#{name_for_path}/:year")
|
106
|
+
create_route(page, "#{name}: Posts With Tag", "/#{name_for_path}/tag/:tag")
|
107
|
+
create_route(page, "#{name}: Posts In Category", "/#{name_for_path}/category/:category")
|
108
|
+
|
109
|
+
page = Page.find_by_name(portlet_name = "#{name}: Post") || Page.create!(
|
110
|
+
:name => portlet_name,
|
111
|
+
:path => "/#{name_for_path}/post",
|
112
|
+
:section => section,
|
113
|
+
:template_file_name => "default.html.erb",
|
114
|
+
:hidden => true)
|
115
|
+
page.publish
|
116
|
+
create_route( page, portlet_name, "/#{name_for_path}/:year/:month/:day/:slug")
|
117
|
+
create_portlet(page, portlet_name, BlogPostPortlet)
|
118
|
+
|
119
|
+
# FIXME: This takes about 5 seconds to run, which is probably too long.
|
120
|
+
# Solution: Disable PageRoute's after_save :reload_routes and add this to the end here:
|
121
|
+
# ActionController::Routing::Routes.load!
|
122
|
+
end
|
123
|
+
|
124
|
+
def create_route(page, name, pattern)
|
125
|
+
route = page.page_routes.build(:name => name, :pattern => pattern, :code => "")
|
126
|
+
route.add_condition(:method, "get")
|
127
|
+
route.add_requirement(:year, '\d{4,}') if pattern.include?(":year")
|
128
|
+
route.add_requirement(:month, '\d{2,}') if pattern.include?(":month")
|
129
|
+
route.add_requirement(:day, '\d{2,}') if pattern.include?(":day")
|
130
|
+
route.save!
|
131
|
+
end
|
132
|
+
|
133
|
+
def create_portlet(page, name, portlet_class)
|
134
|
+
portlet_class.create!(
|
135
|
+
:name => "#{name} Portlet",
|
136
|
+
:blog_id => self.id,
|
137
|
+
:template => portlet_class.default_template,
|
138
|
+
:connect_to_page_id => page.id,
|
139
|
+
:connect_to_container => "main",
|
140
|
+
:publish_on_save => true)
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class BlogComment < ActiveRecord::Base
|
2
|
+
acts_as_content_block :is_searachable => "body"
|
3
|
+
belongs_to :post, :class_name => "BlogPost", :counter_cache => "comments_count"
|
4
|
+
|
5
|
+
validates_presence_of :post_id, :author, :body
|
6
|
+
|
7
|
+
def self.default_order
|
8
|
+
"blog_comments.created_at desc"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.default_order_for_search
|
12
|
+
default_order
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.columns_for_index
|
16
|
+
[ {:label => "Comment", :method => :name, :order => "blog_comments.body" },
|
17
|
+
{:label => "Created At", :method => :formatted_created_at, :order => "blog_comments.created_at"} ]
|
18
|
+
end
|
19
|
+
|
20
|
+
def name
|
21
|
+
body ? body[0..50] : ""
|
22
|
+
end
|
23
|
+
|
24
|
+
def formatted_created_at
|
25
|
+
created_at.to_s(:date)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,101 @@
|
|
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
|
+
named_scope :published_between, lambda { |start, finish|
|
30
|
+
{ :conditions => [
|
31
|
+
"blog_posts.published_at >= ? AND blog_posts.published_at < ?",
|
32
|
+
start, finish ] }
|
33
|
+
}
|
34
|
+
|
35
|
+
INCORRECT_PARAMETERS = "Incorrect parameters. This is probably because you are trying to view the " +
|
36
|
+
"portlet through the CMS interface, and so we have no way of knowing what " +
|
37
|
+
"post(s) to show"
|
38
|
+
|
39
|
+
delegate :editable_by?, :to => :blog
|
40
|
+
|
41
|
+
def set_published_at
|
42
|
+
if !published_at && publish_on_save
|
43
|
+
self.published_at = Time.now
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# This is necessary because, oddly, the publish! method in the Publishing behaviour sends an update
|
48
|
+
# query directly to the database, bypassing callbacks, so published_at does not get set by our
|
49
|
+
# set_published_at callback.
|
50
|
+
def after_publish_with_set_published_at
|
51
|
+
if published_at.nil?
|
52
|
+
self.published_at = Time.now
|
53
|
+
self.save!
|
54
|
+
end
|
55
|
+
after_publish_without_set_published_at if respond_to? :after_publish_without_set_published_at
|
56
|
+
end
|
57
|
+
if instance_methods.map(&:to_s).include? 'after_publish'
|
58
|
+
alias_method_chain :after_publish, :set_published_at
|
59
|
+
else
|
60
|
+
alias_method :after_publish, :after_publish_with_set_published_at
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.default_order
|
64
|
+
"created_at desc"
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.columns_for_index
|
68
|
+
[ {:label => "Name", :method => :name, :order => "name" },
|
69
|
+
{:label => "Published", :method => :published_label, :order => "published" } ]
|
70
|
+
end
|
71
|
+
|
72
|
+
def published_label
|
73
|
+
published_at ? published_at.to_s(:date) : nil
|
74
|
+
end
|
75
|
+
|
76
|
+
def set_slug
|
77
|
+
self.slug = name.to_slug
|
78
|
+
end
|
79
|
+
|
80
|
+
def path
|
81
|
+
send("#{blog.name_for_path}_post_path", route_params)
|
82
|
+
end
|
83
|
+
def route_name
|
84
|
+
"#{blog.name_for_path}_post"
|
85
|
+
end
|
86
|
+
def route_params
|
87
|
+
{:year => year, :month => month, :day => day, :slug => slug}
|
88
|
+
end
|
89
|
+
|
90
|
+
def year
|
91
|
+
published_at.strftime("%Y") unless published_at.blank?
|
92
|
+
end
|
93
|
+
|
94
|
+
def month
|
95
|
+
published_at.strftime("%m") unless published_at.blank?
|
96
|
+
end
|
97
|
+
|
98
|
+
def day
|
99
|
+
published_at.strftime("%d") unless published_at.blank?
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class BlogPostPortlet < Portlet
|
2
|
+
render_inline false
|
3
|
+
enable_template_editor false
|
4
|
+
|
5
|
+
def render
|
6
|
+
scope = Blog.find(self.blog_id).posts
|
7
|
+
if params[:blog_post_id]
|
8
|
+
@blog_post = scope.find(params[:blog_post_id])
|
9
|
+
elsif params[:slug]
|
10
|
+
if params[:year]
|
11
|
+
date = Date.new(params[:year].to_i, params[:month].to_i, params[:day].to_i)
|
12
|
+
scope = scope.published_between(date, date + 1.day)
|
13
|
+
end
|
14
|
+
@blog_post = scope.find_by_slug!(params[:slug])
|
15
|
+
else
|
16
|
+
raise BlogPost::INCORRECT_PARAMETERS
|
17
|
+
end
|
18
|
+
|
19
|
+
pmap = flash[instance_name] || params
|
20
|
+
pmap[:blog_comment] ||= {}
|
21
|
+
|
22
|
+
@blog_comment = @blog_post.comments.build pmap[:blog_comment]
|
23
|
+
@blog_comment.errors.add_from_hash flash["#{instance_name}_errors"]
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_comment
|
27
|
+
params[:blog_comment].merge! :ip => request.remote_ip
|
28
|
+
blog_comment = BlogComment.new(params[:blog_comment])
|
29
|
+
if blog_comment.valid? && blog_comment.save
|
30
|
+
url_for_success
|
31
|
+
else
|
32
|
+
store_params_in_flash
|
33
|
+
store_errors_in_flash(blog_comment.errors)
|
34
|
+
url_for_failure
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<%= f.cms_drop_down :blog_id, Blog.editable_by(current_user).map{|b| [b.name, b.id]} %>
|
2
|
+
<% unless @block.new_record? %>
|
3
|
+
<%= f.cms_drop_down :author_id, @block.blog.potential_authors.map { |u| ["#{u.full_name} (#{u.login})", u.id] } %>
|
4
|
+
<% end %>
|
5
|
+
<%= f.cms_drop_down :category_id, categories_for('Blog Post').map{|c| [c.path, c.id]}, :include_blank => true %>
|
6
|
+
<%= f.cms_text_field :name, :label => 'Title' %>
|
7
|
+
<%= f.cms_tag_list %>
|
8
|
+
<%= f.cms_datetime_select :published_at, :label => "Date" %>
|
9
|
+
<%= f.cms_text_area :summary, :style => "height: 200px", :instructions => 'This will be displayed on the list page with a Read More link if present' %>
|
10
|
+
<%= f.cms_text_editor :body %>
|
11
|
+
<%= f.cms_file_field :attachment_file, :label => "Image" %>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<% content_for(:html_head) do %>
|
2
|
+
<%= stylesheet_link_tag "cms/content_library" %>
|
3
|
+
<% end %>
|
4
|
+
<% page_title "Content Library / List #{content_type.display_name_plural}" %>
|
5
|
+
<% @toolbar_title = "List #{content_type.display_name_plural}" %>
|
6
|
+
|
7
|
+
<div class="roundedcorners">
|
8
|
+
<p>Sorry, you don't have the permissions to write blog posts.</p>
|
9
|
+
</div>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render :partial => "partials/blog_post", :object => @content_block %>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<%= f.cms_text_field :name %>
|
2
|
+
|
3
|
+
<div class="checkbox_group fields" style="float: left; width: 100%">
|
4
|
+
<label>Permissions</label>
|
5
|
+
<%= hidden_field_tag "blog[group_ids][]", "", :id => nil %>
|
6
|
+
<div class="checkboxes">
|
7
|
+
<% for group in Group.cms_access.all(:order => "groups.name") %>
|
8
|
+
<div class="checkbox_fields">
|
9
|
+
<%= check_box_tag "blog[group_ids][]", group.id,
|
10
|
+
@block.groups.include?(group), :class => "cms_group_ids", :id => "cms_group_ids_#{group.id}", :tabindex => next_tabindex %>
|
11
|
+
<label for="cms_group_ids_<%= group.id %>"><%= group.name %></label>
|
12
|
+
</div>
|
13
|
+
<% end %>
|
14
|
+
<div class="instructions">Which “CMS” groups can edit and publish the blog?</div>
|
15
|
+
<div class="check_uncheck">
|
16
|
+
<%= link_to_check_all 'input.cms_group_ids' %>,
|
17
|
+
<%= link_to_uncheck_all 'input.cms_group_ids' %>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
<br clear="all" />
|
22
|
+
|
23
|
+
<%= f.cms_text_area :template, :default_value => Blog.default_template %>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<% content_for(:html_head) do %>
|
2
|
+
<%= stylesheet_link_tag "cms/content_library" %>
|
3
|
+
<% end %>
|
4
|
+
<% page_title "Content Library / List #{content_type.display_name_plural}" %>
|
5
|
+
<% @toolbar_title = "List #{content_type.display_name_plural}" %>
|
6
|
+
|
7
|
+
<div class="roundedcorners">
|
8
|
+
<p>Sorry, this section is restricted to administrators.</p>
|
9
|
+
</div>
|
@@ -0,0 +1,106 @@
|
|
1
|
+
<style>
|
2
|
+
.blog_post {
|
3
|
+
border-bottom: 1px solid #ccc;
|
4
|
+
margin-bottom: 20px;
|
5
|
+
}
|
6
|
+
|
7
|
+
.blog_post h2 {
|
8
|
+
margin-bottom: 0
|
9
|
+
}
|
10
|
+
|
11
|
+
.blog_post h2,
|
12
|
+
.blog_post h2 a {
|
13
|
+
font: normal 30px/28px 'arial black', arial, sans-serif !important;
|
14
|
+
text-decoration: none !important;
|
15
|
+
}
|
16
|
+
.blog_post h2 a:hover {
|
17
|
+
text-decoration: underline !important;
|
18
|
+
}
|
19
|
+
|
20
|
+
.blog_post .image {
|
21
|
+
float: left;
|
22
|
+
border: 1px solid #ccc;
|
23
|
+
margin: 10px;
|
24
|
+
margin-top: 0;
|
25
|
+
}
|
26
|
+
.blog_post .date {
|
27
|
+
color: #666;
|
28
|
+
}
|
29
|
+
.blog_post .read_more {
|
30
|
+
font-weight: bold;
|
31
|
+
}
|
32
|
+
|
33
|
+
.blog_post .comment + .comment {
|
34
|
+
border-top: 1px dashed #ccc;
|
35
|
+
}
|
36
|
+
|
37
|
+
.clear {
|
38
|
+
clear: both;
|
39
|
+
}
|
40
|
+
</style>
|
41
|
+
|
42
|
+
<%
|
43
|
+
# _counter is defined only if we pass :collection to the partial
|
44
|
+
if defined?(blog_post_counter)
|
45
|
+
showing_individual_post = false
|
46
|
+
else
|
47
|
+
showing_individual_post = true
|
48
|
+
blog_post_counter = 0
|
49
|
+
end
|
50
|
+
%>
|
51
|
+
|
52
|
+
<div id="blog_post_<%= blog_post.id %>" class="blog_post clear">
|
53
|
+
<% if blog_post.attachment %>
|
54
|
+
<div class="image">
|
55
|
+
<%# image_tag_with_max_size blog_post.attachment.file_path, blog_post.attachment.full_file_location, :width => max_width %>
|
56
|
+
<%= image_tag blog_post.attachment.file_path %>
|
57
|
+
</div>
|
58
|
+
<% end %>
|
59
|
+
|
60
|
+
<h2><%= link_to h(blog_post.name), href = _blog_post_path(blog_post) %></h2>
|
61
|
+
|
62
|
+
<div class="date"><%= blog_post.published_at.to_s(:long) %></div>
|
63
|
+
|
64
|
+
<div class="body">
|
65
|
+
<% if showing_individual_post or blog_post.summary.blank? %>
|
66
|
+
<%= blog_post.body %>
|
67
|
+
<% else %>
|
68
|
+
<%= blog_post.summary %>
|
69
|
+
<p class="read_more">
|
70
|
+
<%= link_to 'Read More »', href %>
|
71
|
+
</p>
|
72
|
+
<% end %>
|
73
|
+
</div>
|
74
|
+
|
75
|
+
<div class="meta">
|
76
|
+
<% unless blog_post.category_id.blank? %>
|
77
|
+
Posted in <%= link_to h(blog_post.category_name), _blog_path(blog_post.blog, 'posts_in_category', :category => blog_post.category_name) %>
|
78
|
+
<strong>|</strong>
|
79
|
+
<% end %>
|
80
|
+
|
81
|
+
<% if blog_post.tags.any? %>
|
82
|
+
Tags:
|
83
|
+
<span class="tags">
|
84
|
+
<%= blog_post.tags.map{|t| link_to(h(t.name), _blog_path(blog_post.blog, 'posts_with_tag', :tag => t.name)) }.join(", ") %>
|
85
|
+
</span>
|
86
|
+
<strong>|</strong>
|
87
|
+
<% end %>
|
88
|
+
|
89
|
+
<%= link_to h(pluralize(blog_post.comments_count, "Comment")), "#{_blog_post_path(blog_post)}#comments" %>
|
90
|
+
</div>
|
91
|
+
<br class="clear" />
|
92
|
+
|
93
|
+
|
94
|
+
<% comments = blog_post.comments.reject(&:new_record?) %>
|
95
|
+
<% if showing_individual_post and comments.any? -%>
|
96
|
+
<h2>Comments</h2>
|
97
|
+
<% comments.each_with_index do |comment, i| %>
|
98
|
+
<div class="comment <%= 'first' if i == 0 %>">
|
99
|
+
<%= h comment.body %>
|
100
|
+
<p>—<%= comment.url.present? ? link_to(h(comment.author), comment.url) : h(comment.author) %></p>
|
101
|
+
</div>
|
102
|
+
<% end %>
|
103
|
+
<% end %>
|
104
|
+
|
105
|
+
|
106
|
+
</div>
|