bcms_blog 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE.txt +165 -0
- data/README.markdown +113 -2
- data/app/controllers/application_controller.rb +10 -0
- data/app/controllers/cms/blog_comments_controller.rb +1 -1
- data/app/controllers/cms/blog_posts_controller.rb +34 -1
- data/app/controllers/cms/blogs_controller.rb +10 -1
- data/app/controllers/feeds_controller.rb +8 -0
- data/app/helpers/application_helper.rb +3 -0
- data/app/helpers/cms/blog_helper.rb +17 -0
- data/app/helpers/feeds_helper.rb +2 -0
- data/app/models/blog.rb +70 -14
- data/app/models/blog_comment.rb +15 -9
- data/app/models/blog_group_membership.rb +4 -0
- data/app/models/blog_observer.rb +135 -0
- data/app/models/blog_post.rb +76 -32
- data/app/portlets/blog_post_portlet.rb +23 -9
- data/app/portlets/blog_posts_portlet.rb +50 -0
- data/app/views/cms/blog_posts/_form.html.erb +9 -4
- data/app/views/cms/blog_posts/no_access.html.erb +9 -0
- data/app/views/cms/blog_posts/render.html.erb +1 -5
- data/app/views/cms/blogs/_form.html.erb +27 -1
- data/app/views/cms/blogs/admin_only.html.erb +9 -0
- data/app/views/cms/blogs/render.html.erb +2 -3
- data/app/views/feeds/index.rss.builder +18 -0
- data/app/views/partials/_blog_post.html.erb +102 -0
- data/app/views/partials/_blog_post.html.haml +91 -0
- data/app/views/portlets/blog_post/_form.html.erb +2 -1
- data/app/views/portlets/blog_post/render.html.erb +33 -36
- data/app/views/portlets/blog_posts/_form.html.erb +13 -0
- data/app/views/portlets/blog_posts/render.html.haml +9 -0
- data/db/migrate/20090415000000_create_blogs.rb +31 -18
- data/db/migrate/20090415000001_create_blog_posts.rb +5 -30
- data/db/migrate/20090415000002_create_blog_comments.rb +2 -1
- data/db/migrate/20090415000003_add_attachment_to_blog_posts.rb +23 -0
- data/db/migrate/20100521042244_add_moderate_comments_to_blog.rb +10 -0
- data/doc/README_FOR_APP +2 -0
- data/doc/migrate_to_20100427.rb +77 -0
- data/doc/release_notes.txt +40 -0
- data/lib/bcms_blog/routes.rb +3 -0
- data/rails/init.rb +6 -1
- data/test/factories.rb +47 -1
- data/test/functional/blog_post_test.rb +19 -17
- data/test/functional/blog_test.rb +47 -25
- data/test/functional/cms/blog_posts_controller_test.rb +44 -0
- data/test/functional/cms/blogs_controller_test.rb +25 -0
- data/test/functional/feeds_controller_test.rb +8 -0
- data/test/test_helper.rb +64 -120
- data/test/unit/blog_comment_test.rb +34 -0
- data/test/unit/blog_observer_test.rb +61 -0
- data/test/unit/blog_post_test.rb +43 -0
- data/test/unit/blog_test.rb +42 -0
- data/test/unit/helpers/feeds_helper_test.rb +4 -0
- metadata +64 -7
- data/app/views/portlets/blog_post/_blog_post.html.erb +0 -29
data/app/models/blog_post.rb
CHANGED
@@ -1,69 +1,113 @@
|
|
1
1
|
class BlogPost < ActiveRecord::Base
|
2
2
|
acts_as_content_block :taggable => true
|
3
|
-
|
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
|
+
|
4
19
|
before_save :set_published_at
|
5
|
-
|
20
|
+
|
6
21
|
belongs_to :blog
|
7
22
|
belongs_to_category
|
8
23
|
belongs_to :author, :class_name => "User"
|
9
24
|
has_many :comments, :class_name => "BlogComment", :foreign_key => "post_id"
|
10
|
-
|
25
|
+
|
11
26
|
before_validation :set_slug
|
12
|
-
validates_presence_of :name, :slug
|
27
|
+
validates_presence_of :name, :slug, :blog_id, :author_id
|
13
28
|
|
14
|
-
named_scope :
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
date
|
19
|
-
end
|
20
|
-
|
21
|
-
{:conditions => [
|
22
|
-
"blog_posts.published_at >= ? AND blog_posts.published_at < ?",
|
23
|
-
d.beginning_of_day,
|
24
|
-
(d.beginning_of_day + 1.day)
|
25
|
-
]}
|
29
|
+
named_scope :published_between, lambda { |start, finish|
|
30
|
+
{ :conditions => [
|
31
|
+
"blog_posts.published_at >= ? AND blog_posts.published_at < ?",
|
32
|
+
start, finish ] }
|
26
33
|
}
|
27
|
-
|
28
|
-
named_scope :
|
29
|
-
|
34
|
+
|
35
|
+
named_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
|
+
|
30
53
|
def set_published_at
|
31
54
|
if !published_at && publish_on_save
|
32
55
|
self.published_at = Time.now
|
33
56
|
end
|
34
57
|
end
|
35
|
-
|
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
|
+
|
36
75
|
def self.default_order
|
37
76
|
"created_at desc"
|
38
77
|
end
|
39
|
-
|
78
|
+
|
40
79
|
def self.columns_for_index
|
41
80
|
[ {:label => "Name", :method => :name, :order => "name" },
|
42
|
-
{:label => "Published", :method => :published_label, :order => "
|
43
|
-
end
|
44
|
-
|
81
|
+
{:label => "Published At", :method => :published_label, :order => "published_at" } ]
|
82
|
+
end
|
83
|
+
|
45
84
|
def published_label
|
46
85
|
published_at ? published_at.to_s(:date) : nil
|
47
86
|
end
|
48
|
-
|
87
|
+
|
49
88
|
def set_slug
|
50
89
|
self.slug = name.to_slug
|
51
90
|
end
|
52
|
-
|
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
|
53
98
|
def route_params
|
54
99
|
{:year => year, :month => month, :day => day, :slug => slug}
|
55
|
-
end
|
56
|
-
|
100
|
+
end
|
101
|
+
|
57
102
|
def year
|
58
103
|
published_at.strftime("%Y") unless published_at.blank?
|
59
104
|
end
|
60
|
-
|
105
|
+
|
61
106
|
def month
|
62
107
|
published_at.strftime("%m") unless published_at.blank?
|
63
108
|
end
|
64
|
-
|
109
|
+
|
65
110
|
def day
|
66
111
|
published_at.strftime("%d") unless published_at.blank?
|
67
112
|
end
|
68
|
-
|
69
|
-
end
|
113
|
+
end
|
@@ -1,24 +1,38 @@
|
|
1
1
|
class BlogPostPortlet < Portlet
|
2
|
-
|
2
|
+
#render_inline false
|
3
|
+
#enable_template_editor false
|
4
|
+
|
3
5
|
def render
|
4
|
-
|
5
|
-
if
|
6
|
-
@blog_post =
|
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
|
7
17
|
end
|
18
|
+
|
8
19
|
pmap = flash[instance_name] || params
|
20
|
+
pmap[:blog_comment] ||= {}
|
21
|
+
|
9
22
|
@blog_comment = @blog_post.comments.build pmap[:blog_comment]
|
10
23
|
@blog_comment.errors.add_from_hash flash["#{instance_name}_errors"]
|
11
24
|
end
|
12
|
-
|
25
|
+
|
13
26
|
def create_comment
|
27
|
+
params[:blog_comment].merge! :ip => request.remote_ip
|
14
28
|
blog_comment = BlogComment.new(params[:blog_comment])
|
15
|
-
if blog_comment.save
|
29
|
+
if blog_comment.valid? && blog_comment.save
|
16
30
|
url_for_success
|
17
31
|
else
|
18
32
|
store_params_in_flash
|
19
33
|
store_errors_in_flash(blog_comment.errors)
|
20
34
|
url_for_failure
|
21
35
|
end
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
class BlogPostsPortlet < Portlet
|
2
|
+
def after_initialize
|
3
|
+
self.render_blog_post_code ||= 'truncate(blog_post.name, 30)'
|
4
|
+
end
|
5
|
+
|
6
|
+
# Mark this as 'true' to allow the portlet's template to be editable via the CMS admin UI.
|
7
|
+
enable_template_editor false
|
8
|
+
|
9
|
+
def render(_options = {})
|
10
|
+
# Since we can't pass any options to render_portlet, you can use $blog_posts_portlet_options if you want to pass in/override some options
|
11
|
+
# This is an ugly workaround for https://browsermedia.lighthouseapp.com/projects/28481-browsercms-30/tickets/350-make-it-possible-to-pass-options-to-render_portletrender_connectable in case we want to call render_portlet with some options
|
12
|
+
_options = $blog_posts_portlet_options || {}
|
13
|
+
_options.symbolize_keys!
|
14
|
+
|
15
|
+
portlet_attributes = self.portlet_attributes.inject({}) {|hash, a| hash[a.name] = a.value; hash}.reject {|k,v| v.blank?}.symbolize_keys
|
16
|
+
|
17
|
+
#options.reverse_merge!(params.slice(:tags)).symbolize_keys!
|
18
|
+
@options = portlet_attributes.merge(_options)
|
19
|
+
Rails.logger.debug "... BlogPostsPortlet#render(options=#{@options.inspect} #{@options.class})"
|
20
|
+
|
21
|
+
if @options[:blog_id]
|
22
|
+
finder = Blog.find(@options[:blog_id]).posts
|
23
|
+
elsif @options[:blog_name]
|
24
|
+
finder = Blog.find_by_name(@options[:blog_name]).posts
|
25
|
+
else
|
26
|
+
finder = BlogPost
|
27
|
+
end
|
28
|
+
|
29
|
+
if @options[:tags].is_a?(Array) && @options[:tags].size > 1
|
30
|
+
other_tags = @options[:tags][1..-1]
|
31
|
+
@options[:tags] = @options[:tags][0]
|
32
|
+
end
|
33
|
+
|
34
|
+
finder = finder.published
|
35
|
+
finder = Blog.posts_finder(finder, @options)
|
36
|
+
|
37
|
+
@blog_posts = finder.all(
|
38
|
+
:limit => @options[:limit] || 25,
|
39
|
+
:order => "published_at desc"
|
40
|
+
)
|
41
|
+
|
42
|
+
if other_tags
|
43
|
+
@blog_posts.select! {|p| (p.tags.map(&:name).map(&:downcase) & other_tags.map(&:downcase)).size == other_tags.size }
|
44
|
+
end
|
45
|
+
|
46
|
+
raise ActiveRecord::RecordNotFound.new("No articles found") if @blog_posts.empty?
|
47
|
+
|
48
|
+
@portlet = self
|
49
|
+
end
|
50
|
+
end
|
@@ -1,6 +1,11 @@
|
|
1
|
-
<%= f.
|
1
|
+
<%= f.cms_text_field :name, :label => 'Title' %>
|
2
|
+
<%= f.cms_text_area :summary, :style => "height: 200px", :instructions => 'This will be displayed on the list page with a Read More link if present' %>
|
3
|
+
<%= f.cms_text_editor :body %>
|
4
|
+
<%= f.cms_datetime_select :published_at, :label => "Date", :instructions=>"The 'published' date/time for the post which is displayed publically." %>
|
5
|
+
<% unless @block.new_record? %>
|
6
|
+
<%= f.cms_drop_down :author_id, @block.blog.potential_authors.map { |u| ["#{u.full_name} (#{u.login})", u.id] } %>
|
7
|
+
<% end %>
|
2
8
|
<%= f.cms_drop_down :category_id, categories_for('Blog Post').map{|c| [c.path, c.id]}, :include_blank => true %>
|
3
|
-
<%= f.cms_text_field :name %>
|
4
9
|
<%= f.cms_tag_list %>
|
5
|
-
<%= f.
|
6
|
-
<%= f.
|
10
|
+
<%= f.cms_drop_down :blog_id, Blog.editable_by(current_user).map{|b| [b.name, b.id]} %>
|
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>
|
@@ -1,2 +1,28 @@
|
|
1
1
|
<%= f.cms_text_field :name %>
|
2
|
-
<%= f.
|
2
|
+
<%= f.cms_check_box :moderate_comments %>
|
3
|
+
|
4
|
+
<div class="checkbox_group fields" style="float: left; width: 100%">
|
5
|
+
<label>Permissions</label>
|
6
|
+
<%= hidden_field_tag "blog[group_ids][]", "", :id => nil %>
|
7
|
+
<div class="checkboxes">
|
8
|
+
<% for group in Group.cms_access.all(:order => "groups.name") %>
|
9
|
+
<div class="checkbox_fields">
|
10
|
+
<%= check_box_tag "blog[group_ids][]", group.id,
|
11
|
+
@block.groups.include?(group), :class => "cms_group_ids", :id => "cms_group_ids_#{group.id}", :tabindex => next_tabindex %>
|
12
|
+
<label for="cms_group_ids_<%= group.id %>"><%= group.name %></label>
|
13
|
+
</div>
|
14
|
+
<% end %>
|
15
|
+
<div class="instructions">Which “CMS” groups can edit and publish the blog?</div>
|
16
|
+
<div class="check_uncheck">
|
17
|
+
<%= link_to_check_all 'input.cms_group_ids' %>,
|
18
|
+
<%= link_to_uncheck_all 'input.cms_group_ids' %>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
<br clear="all" />
|
23
|
+
|
24
|
+
<%= f.cms_text_area :template, :default_value => Blog.default_template %>
|
25
|
+
|
26
|
+
<div class="instructions" style="float:none">
|
27
|
+
Saving your blog might take a couple of seconds while everything is set up.
|
28
|
+
</div>
|
@@ -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>
|
@@ -1,3 +1,2 @@
|
|
1
|
-
<% page_title @blog.name %>
|
2
|
-
|
3
|
-
<%= render :partial => "portlets/blog_post/blog_post", :collection => @blog_posts %>
|
1
|
+
<% page_title @page_title || @blog.name %>
|
2
|
+
<%= render :partial => "partials/blog_post", :collection => @blog_posts %>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
xml.instruct! :xml, :version=>"1.0"
|
2
|
+
xml.rss(:version=>"2.0") do
|
3
|
+
xml.channel do
|
4
|
+
xml.title("#{@blog.name} Posts Feed")
|
5
|
+
xml.link(blog_feeds_url(:id => @blog.id, :format => "rss"))
|
6
|
+
xml.description("")
|
7
|
+
xml.language('en-us')
|
8
|
+
for post in @blog_posts
|
9
|
+
xml.item do
|
10
|
+
xml.title(post.name)
|
11
|
+
xml.description(post.summary) unless post.summary.blank?
|
12
|
+
xml.pubDate(post.published_at.strftime("%a, %d %b %Y %H:%M:%S %z")) unless post.published_at.blank?
|
13
|
+
xml.link(send("#{@blog.name_for_path}_post_url", post.route_params))
|
14
|
+
xml.guid(send("#{@blog.name_for_path}_post_url", post.route_params))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,102 @@
|
|
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 blog_post.attachment.file_path %>
|
56
|
+
</div>
|
57
|
+
<% end %>
|
58
|
+
|
59
|
+
<h2><%= link_to h(blog_post.name), href = _blog_post_path(blog_post) %></h2>
|
60
|
+
|
61
|
+
<div class="date"><%= blog_post.published_at.to_s(:long) %></div>
|
62
|
+
|
63
|
+
<div class="body">
|
64
|
+
<% if showing_individual_post or blog_post.summary.blank? %>
|
65
|
+
<%= blog_post.body %>
|
66
|
+
<% else %>
|
67
|
+
<%= blog_post.summary %>
|
68
|
+
<p class="read_more">
|
69
|
+
<%= link_to 'Read More »', href %>
|
70
|
+
</p>
|
71
|
+
<% end %>
|
72
|
+
</div>
|
73
|
+
|
74
|
+
<div class="meta">
|
75
|
+
<% unless blog_post.category_id.blank? %>
|
76
|
+
Posted in <%= link_to h(blog_post.category_name), _blog_path(blog_post.blog, 'posts_in_category', :category => blog_post.category_name) %>
|
77
|
+
<strong>|</strong>
|
78
|
+
<% end %>
|
79
|
+
|
80
|
+
<% if blog_post.tags.any? %>
|
81
|
+
Tags:
|
82
|
+
<span class="tags">
|
83
|
+
<%= blog_post.tags.map{|t| link_to(h(t.name), _blog_path(blog_post.blog, 'posts_with_tag', :tag => t.name)) }.join(", ") %>
|
84
|
+
</span>
|
85
|
+
<strong>|</strong>
|
86
|
+
<% end %>
|
87
|
+
|
88
|
+
<%= link_to h(pluralize(blog_post.comments.published.count, "Comment")), "#{_blog_post_path(blog_post)}#comments" %>
|
89
|
+
</div>
|
90
|
+
<br class="clear" />
|
91
|
+
|
92
|
+
<% comments = blog_post.comments.published.reject(&:new_record?) %>
|
93
|
+
<% if showing_individual_post and comments.any? -%>
|
94
|
+
<h2>Comments</h2>
|
95
|
+
<% comments.each_with_index do |comment, i| %>
|
96
|
+
<div class="comment <%= 'first' if i == 0 %>">
|
97
|
+
<%= h comment.body %>
|
98
|
+
<p>—<%= comment.url.present? ? link_to(h(comment.author), comment.url) : h(comment.author) %></p>
|
99
|
+
</div>
|
100
|
+
<% end %>
|
101
|
+
<% end %>
|
102
|
+
</div>
|
@@ -0,0 +1,91 @@
|
|
1
|
+
%style
|
2
|
+
:sass
|
3
|
+
.blog_post.first
|
4
|
+
h2, h2 a
|
5
|
+
font: normal 30px/28px 'arial black', arial, sans-serif !important
|
6
|
+
border-bottom: 1px solid #ccc
|
7
|
+
|
8
|
+
.blog_post
|
9
|
+
border: 0px solid gray
|
10
|
+
margin-bottom: 20px
|
11
|
+
|
12
|
+
h2
|
13
|
+
margin-bottom: 0
|
14
|
+
h2, h2 a
|
15
|
+
font: normal 20px/23px 'arial black', arial, sans-serif !important
|
16
|
+
text-decoration: none !important
|
17
|
+
h2 a:hover
|
18
|
+
text-decoration: underline !important
|
19
|
+
|
20
|
+
.image
|
21
|
+
float: left
|
22
|
+
border: 1px solid #ccc
|
23
|
+
margin: 10px
|
24
|
+
margin-top: 0
|
25
|
+
|
26
|
+
.date
|
27
|
+
color: #666
|
28
|
+
.read_more
|
29
|
+
font-weight: bold
|
30
|
+
|
31
|
+
.comment + .comment
|
32
|
+
border-top: 1px dashed #ccc
|
33
|
+
|
34
|
+
.clear
|
35
|
+
clear: both
|
36
|
+
|
37
|
+
:ruby
|
38
|
+
# _counter is defined only if we pass :collection to the partial
|
39
|
+
if defined?(blog_post_counter)
|
40
|
+
showing_individual_post = false
|
41
|
+
else
|
42
|
+
showing_individual_post = true
|
43
|
+
blog_post_counter = 0
|
44
|
+
end
|
45
|
+
|
46
|
+
if blog_post_counter == 0
|
47
|
+
max_width = 250
|
48
|
+
css_class = 'first'
|
49
|
+
else
|
50
|
+
max_width = 75
|
51
|
+
css_class = ''
|
52
|
+
end
|
53
|
+
|
54
|
+
.blog_post.clear{:id => "blog_post_#{blog_post.id}", :class => css_class}
|
55
|
+
- if blog_post.attachment
|
56
|
+
-# .image= image_tag_with_max_size blog_post.attachment.file_path, blog_post.attachment.full_file_location, :width => max_width
|
57
|
+
.image= image_tag blog_post.attachment.file_path
|
58
|
+
|
59
|
+
%h2= link_to h(blog_post.name), href = _blog_post_path(blog_post)
|
60
|
+
|
61
|
+
.date= blog_post.published_at.to_s(:long)
|
62
|
+
|
63
|
+
.body
|
64
|
+
- if showing_individual_post or blog_post.summary.blank?
|
65
|
+
= blog_post.body
|
66
|
+
- else
|
67
|
+
= blog_post.summary
|
68
|
+
%p.read_more= link_to 'Read More »', href
|
69
|
+
|
70
|
+
- if showing_individual_post || blog_post_counter == 0
|
71
|
+
.meta
|
72
|
+
- unless blog_post.category_id.blank?
|
73
|
+
Posted in #{link_to h(blog_post.category_name), _blog_path(blog_post.blog, 'posts_in_category', :category => blog_post.category_name)}
|
74
|
+
%strong |
|
75
|
+
- if blog_post.tags.any?
|
76
|
+
Tags:
|
77
|
+
%span.tags
|
78
|
+
= blog_post.tags.map{|t| link_to(h(t.name), _blog_path(blog_post.blog, 'posts_with_tag', :tag => t.name)) }.join(", ")
|
79
|
+
%strong |
|
80
|
+
= link_to h(pluralize(blog_post.comments_count, "Comment")), "#{_blog_post_path(blog_post)}#comments"
|
81
|
+
%br.clear/
|
82
|
+
|
83
|
+
- comments = blog_post.comments.reject(&:new_record?)
|
84
|
+
- if showing_individual_post and comments.any?
|
85
|
+
%h2 Comments
|
86
|
+
- comments.each_with_index do |comment, i|
|
87
|
+
%div{:class => "comment #{'first' if i == 0}"}
|
88
|
+
= h comment.body
|
89
|
+
%p
|
90
|
+
\—#{comment.url.present? ? link_to(h(comment.author), comment.url) : h(comment.author)}
|
91
|
+
|
@@ -1,36 +1,33 @@
|
|
1
|
-
<%
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
<b>Missing required parameter</b><br/>
|
35
|
-
This portlet expects a request parameter 'blog_post_id'. Be sure the calling page provides it.
|
36
|
-
<% end -%>
|
1
|
+
<% page_title @blog_post.name %>
|
2
|
+
<%= render :partial => "partials/blog_post", :object => @blog_post %>
|
3
|
+
|
4
|
+
<style>
|
5
|
+
@import url('/stylesheets/cms/form_layout.css');
|
6
|
+
</style>
|
7
|
+
|
8
|
+
<div class="blog_comment_form">
|
9
|
+
<% form_for @blog_comment, :url => cms_handler_path(@portlet, "create_comment") do |f| %>
|
10
|
+
<%= f.hidden_field :post_id %>
|
11
|
+
<%= f.error_messages %>
|
12
|
+
<div class="fields text_fields">
|
13
|
+
<%= f.label :author, 'Name *' %>
|
14
|
+
<%= f.text_field :author %>
|
15
|
+
</div>
|
16
|
+
<div class="fields text_fields clear">
|
17
|
+
<%= f.label :email, 'E-mail address' %>
|
18
|
+
<%= f.text_field :email %>
|
19
|
+
</div>
|
20
|
+
<div class="fields text_fields clear">
|
21
|
+
<%= f.label :url, 'Web site' %>
|
22
|
+
<%= f.text_field :url %>
|
23
|
+
</div>
|
24
|
+
<div class="fields text_editor_fields clear">
|
25
|
+
<%= f.label :body, 'Body *' %>
|
26
|
+
<br/>
|
27
|
+
<%= f.text_area :body, :size => "50x5", :style => 'height: auto' %>
|
28
|
+
</div>
|
29
|
+
<div class="buttons clear">
|
30
|
+
<%= submit_tag "Submit comment" %>
|
31
|
+
</div>
|
32
|
+
<% end %>
|
33
|
+
</div>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<%= f.cms_text_field :name, :label => 'Portlet Name', :instructions => 'Since we may have many Articles portlets, each with different parameters, give each portlet a descriptive name.' %>
|
2
|
+
|
3
|
+
<%= f.cms_drop_down :blog_id, Blog.all.map{|b| [b.name, b.id.to_s]}, :include_blank => true, :label => "Show posts from", :instructions => 'Leave blank to include posts from all blogs' %>
|
4
|
+
<%# f.cms_drop_down :show_posts_as, [['First post as full post, the rest as Summary + Read More link', 'first_full_post_others_summary'], ['Summary + Read More link', 'summary'], ['Full post', 'full_post'], ['Title (links to post)', 'link']] %>
|
5
|
+
<%= f.cms_drop_down :show_posts_as, [['Title (links to post)', 'link'], ['Post', 'post']] %>
|
6
|
+
<%= f.cms_check_box :show_full_posts %>
|
7
|
+
<%= f.cms_drop_down :category_id, categories_for('Blog Post').map{|c| [c.path, c.id]}, :include_blank => true, :label => "Only posts in category" %>
|
8
|
+
<%= f.cms_tag_list :label => "Only posts with tags", :instructions => 'Separate tags with spaces' %>
|
9
|
+
<%= f.cms_text_field :exclude_tags, :label => 'Exclude posts with tags' %>
|
10
|
+
<%= f.cms_text_field :limit, :label => 'Limit' %>
|
11
|
+
<%= f.cms_text_area :render_blog_post_code, :label => 'Code to turn blog_post into link text' %>
|
12
|
+
|
13
|
+
<%= f.cms_template_editor :template %>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
- if @portlet.show_posts_as == 'post'
|
2
|
+
= render :partial => '/partials/blog_post', :collection => @blog_posts, :locals => {:show_full_posts => @options[:show_full_posts]}
|
3
|
+
- elsif @portlet.show_posts_as == 'link'
|
4
|
+
%ul.blog_posts
|
5
|
+
- for blog_post in @blog_posts
|
6
|
+
- text = @portlet.render_blog_post_code.present? ? eval(@portlet.render_blog_post_code) : text = truncate(blog_post.name, 30)
|
7
|
+
%li= link_to text, _blog_post_path(blog_post)
|
8
|
+
- else
|
9
|
+
Unrecognized option '#{@portlet.show_posts_as}' for @portlet.show_posts_as
|