bcms_blog 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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