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.
Files changed (54) hide show
  1. data/LICENSE.txt +165 -0
  2. data/README.markdown +113 -2
  3. data/app/controllers/application_controller.rb +10 -0
  4. data/app/controllers/cms/blog_comments_controller.rb +1 -1
  5. data/app/controllers/cms/blog_posts_controller.rb +34 -1
  6. data/app/controllers/cms/blogs_controller.rb +10 -1
  7. data/app/controllers/feeds_controller.rb +8 -0
  8. data/app/helpers/application_helper.rb +3 -0
  9. data/app/helpers/cms/blog_helper.rb +17 -0
  10. data/app/helpers/feeds_helper.rb +2 -0
  11. data/app/models/blog.rb +70 -14
  12. data/app/models/blog_comment.rb +15 -9
  13. data/app/models/blog_group_membership.rb +4 -0
  14. data/app/models/blog_observer.rb +135 -0
  15. data/app/models/blog_post.rb +76 -32
  16. data/app/portlets/blog_post_portlet.rb +23 -9
  17. data/app/portlets/blog_posts_portlet.rb +50 -0
  18. data/app/views/cms/blog_posts/_form.html.erb +9 -4
  19. data/app/views/cms/blog_posts/no_access.html.erb +9 -0
  20. data/app/views/cms/blog_posts/render.html.erb +1 -5
  21. data/app/views/cms/blogs/_form.html.erb +27 -1
  22. data/app/views/cms/blogs/admin_only.html.erb +9 -0
  23. data/app/views/cms/blogs/render.html.erb +2 -3
  24. data/app/views/feeds/index.rss.builder +18 -0
  25. data/app/views/partials/_blog_post.html.erb +102 -0
  26. data/app/views/partials/_blog_post.html.haml +91 -0
  27. data/app/views/portlets/blog_post/_form.html.erb +2 -1
  28. data/app/views/portlets/blog_post/render.html.erb +33 -36
  29. data/app/views/portlets/blog_posts/_form.html.erb +13 -0
  30. data/app/views/portlets/blog_posts/render.html.haml +9 -0
  31. data/db/migrate/20090415000000_create_blogs.rb +31 -18
  32. data/db/migrate/20090415000001_create_blog_posts.rb +5 -30
  33. data/db/migrate/20090415000002_create_blog_comments.rb +2 -1
  34. data/db/migrate/20090415000003_add_attachment_to_blog_posts.rb +23 -0
  35. data/db/migrate/20100521042244_add_moderate_comments_to_blog.rb +10 -0
  36. data/doc/README_FOR_APP +2 -0
  37. data/doc/migrate_to_20100427.rb +77 -0
  38. data/doc/release_notes.txt +40 -0
  39. data/lib/bcms_blog/routes.rb +3 -0
  40. data/rails/init.rb +6 -1
  41. data/test/factories.rb +47 -1
  42. data/test/functional/blog_post_test.rb +19 -17
  43. data/test/functional/blog_test.rb +47 -25
  44. data/test/functional/cms/blog_posts_controller_test.rb +44 -0
  45. data/test/functional/cms/blogs_controller_test.rb +25 -0
  46. data/test/functional/feeds_controller_test.rb +8 -0
  47. data/test/test_helper.rb +64 -120
  48. data/test/unit/blog_comment_test.rb +34 -0
  49. data/test/unit/blog_observer_test.rb +61 -0
  50. data/test/unit/blog_post_test.rb +43 -0
  51. data/test/unit/blog_test.rb +42 -0
  52. data/test/unit/helpers/feeds_helper_test.rb +4 -0
  53. metadata +64 -7
  54. data/app/views/portlets/blog_post/_blog_post.html.erb +0 -29
@@ -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 :published_on, lambda {|date|
15
- d = if date.kind_of?(Hash)
16
- Date.new(date[:year].to_i, date[:month].to_i, date[:day].to_i)
17
- else
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 :with_slug, lambda{|slug| {:conditions => ["blog_posts.slug = ?",slug]}}
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 => "published" } ]
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
- # @blog_post should already be set by the page route
5
- if !@blog_post && params[:blog_post_id]
6
- @blog_post = BlogPost.find(params[:blog_post_id])
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.cms_drop_down :blog_id, Blog.all.map{|b| [b.name, b.id]} %>
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.cms_text_area :summary, :style => "height: 200px" %>
6
- <%= f.cms_text_editor :body %>
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,5 +1 @@
1
- <%= render :partial => "portlets/blog_post/blog_post", :object => @content_block %>
2
- <h2>Comments</h2>
3
- <% for comment in @content_block.comments %>
4
- <p><%=h comment.body %></p>
5
- <% end %>
1
+ <%= render :partial => "partials/blog_post", :object => @content_block %>
@@ -1,2 +1,28 @@
1
1
  <%= f.cms_text_field :name %>
2
- <%= f.cms_text_area :template, :default_value => Blog.default_template %>
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 &ldquo;CMS&rdquo; 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
- <h1><%=h page_title %></h1>
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>&mdash;<%= 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
+ \&mdash;#{comment.url.present? ? link_to(h(comment.author), comment.url) : h(comment.author)}
91
+
@@ -1,2 +1,3 @@
1
1
  <%= f.cms_text_field :name %>
2
- <%= f.cms_text_area :template, :default_value => @block.class.default_template %>
2
+ <%= f.cms_drop_down :blog_id, Blog.all.map{|b| [b.name, b.id.to_s]} %>
3
+ <%# f.cms_text_area :template, :default_value => @block.class.default_template %>
@@ -1,36 +1,33 @@
1
- <% if @blog_post -%>
2
- <% page_title @blog_post.name %>
3
- <%= render :partial => "portlets/blog_post/blog_post", :object => @blog_post %>
4
- <h2>Comments</h2>
5
- <% for comment in @blog_post.comments %>
6
- <p><%=h comment.body %></p>
7
- <% end %>
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
- <p>
13
- <%= f.label :author %>
14
- <%= f.text_field :author %>
15
- </p>
16
- <p>
17
- <%= f.label :email %>
18
- <%= f.text_field :email %>
19
- </p>
20
- <p>
21
- <%= f.label :url %>
22
- <%= f.text_field :url %>
23
- </p>
24
- <p>
25
- <%= f.label :body %>
26
- <%= f.text_area :body, :size => "50x3" %>
27
- </p>
28
- <p>
29
- <%= submit_tag "Submit" %>
30
- </p>
31
- <% end %>
32
- </div>
33
- <% else -%>
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