Commit f7c784e9e6bec5b1a4a4f3490aa578fa448824f5

Authored by Daniela Feitosa
Committed by Joenio Costa
1 parent 45521292

Adding option to choose how posts will be displayed

A blog can display the full content of posts or only the first paragraph

(ActionItem1515)
app/helpers/blog_helper.rb
@@ -14,7 +14,7 @@ module BlogHelper @@ -14,7 +14,7 @@ module BlogHelper
14 _('Edit blog') 14 _('Edit blog')
15 end 15 end
16 16
17 - def list_posts(user, articles) 17 + def list_posts(user, articles, format = 'full')
18 pagination = will_paginate(articles, { 18 pagination = will_paginate(articles, {
19 :param_name => 'npage', 19 :param_name => 'npage',
20 :prev_label => _('« Newer posts'), 20 :prev_label => _('« Newer posts'),
@@ -32,7 +32,7 @@ module BlogHelper @@ -32,7 +32,7 @@ module BlogHelper
32 css_add << position + '-inner' 32 css_add << position + '-inner'
33 content << content_tag('div', 33 content << content_tag('div',
34 content_tag('div', 34 content_tag('div',
35 - display_post(art) + '<br style="clear:both"/>', 35 + display_post(art, format) + '<br style="clear:both"/>',
36 :class => 'blog-post ' + css_add.join(' '), 36 :class => 'blog-post ' + css_add.join(' '),
37 :id => "post-#{art.id}"), :class => position 37 :id => "post-#{art.id}"), :class => position
38 ) 38 )
@@ -41,10 +41,29 @@ module BlogHelper @@ -41,10 +41,29 @@ module BlogHelper
41 content.join("\n<hr class='sep-posts'/>\n") + (pagination or '') 41 content.join("\n<hr class='sep-posts'/>\n") + (pagination or '')
42 end 42 end
43 43
44 - def display_post(article) 44 + def display_post(article, format = 'full')
  45 + no_comments = (format == 'full') ? false : true
  46 + html = send("display_#{format}_format", article)
  47 +
  48 + article_title(article, :no_comments => no_comments) + html
  49 + end
  50 +
  51 + def display_short_format(article)
  52 + html = content_tag('div',
  53 + article.first_paragraph +
  54 + content_tag('div',
  55 + link_to_comments(article) +
  56 + link_to( _('Read more'), article.url),
  57 + :class => 'read-more'),
  58 + :class => 'short-post'
  59 + )
  60 + html
  61 + end
  62 +
  63 + def display_full_format(article)
45 html = article_to_html(article) 64 html = article_to_html(article)
46 html = content_tag('p', html) if ! html.include?('</p>') 65 html = content_tag('p', html) if ! html.include?('</p>')
47 - article_title(article) + html 66 + html
48 end 67 end
49 68
50 end 69 end
app/helpers/content_viewer_helper.rb
@@ -19,12 +19,13 @@ module ContentViewerHelper @@ -19,12 +19,13 @@ module ContentViewerHelper
19 unless args[:no_link] 19 unless args[:no_link]
20 title = content_tag('h1', link_to(article.name, article.url), :class => 'title') 20 title = content_tag('h1', link_to(article.name, article.url), :class => 'title')
21 end 21 end
22 - title << content_tag('span', _("%s, by %s - %s") % [show_date(article.published_at), link_to(article.author.name, article.author.url), link_to_comments(article)], :class => 'created-at') 22 + comments = args[:no_comments] ? '' : (("- %s") % link_to_comments(article))
  23 + title << content_tag('span', _("%s, by %s %s") % [show_date(article.published_at), link_to(article.author.name, article.author.url), comments], :class => 'created-at')
23 end 24 end
24 title 25 title
25 end 26 end
26 27
27 - def link_to_comments(article) 28 + def link_to_comments(article, args = {})
28 link_to( number_of_comments(article), article.url.merge(:anchor => 'comments_list') ) 29 link_to( number_of_comments(article), article.url.merge(:anchor => 'comments_list') )
29 end 30 end
30 31
app/models/article.rb
@@ -332,7 +332,7 @@ class Article &lt; ActiveRecord::Base @@ -332,7 +332,7 @@ class Article &lt; ActiveRecord::Base
332 332
333 def first_paragraph 333 def first_paragraph
334 to_html =~ /(.*<\/p>)/ 334 to_html =~ /(.*<\/p>)/
335 - $1 335 + $1 || ''
336 end 336 end
337 337
338 def self.find_tagged_with(tag) 338 def self.find_tagged_with(tag)
app/models/blog.rb
@@ -99,4 +99,8 @@ class Blog &lt; Folder @@ -99,4 +99,8 @@ class Blog &lt; Folder
99 end 99 end
100 end 100 end
101 101
  102 + settings_items :visualization_format, :type => :string, :default => 'full'
  103 + validates_inclusion_of :visualization_format, :in => [ 'full', 'short' ], :if => :visualization_format
  104 +
  105 +
102 end 106 end
app/views/cms/_blog.rhtml
@@ -52,6 +52,8 @@ @@ -52,6 +52,8 @@
52 52
53 <%= labelled_form_field(_('Description:'), text_area(:article, :body, :cols => 64, :rows => 10)) %> 53 <%= labelled_form_field(_('Description:'), text_area(:article, :body, :cols => 64, :rows => 10)) %>
54 54
  55 +<%= labelled_form_field(_('How to display posts:'), f.select(:visualization_format, [ [ _('Full post'), 'full'], [ _('First paragraph'), 'short'] ])) %>
  56 +
55 <%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, [5, 10, 20, 50, 100])) %> 57 <%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, [5, 10, 20, 50, 100])) %>
56 58
57 <% f.fields_for 'feed', @article.feed do |feed| %> 59 <% f.fields_for 'feed', @article.feed do |feed| %>
app/views/content_viewer/blog_page.rhtml
@@ -10,5 +10,5 @@ @@ -10,5 +10,5 @@
10 </div> 10 </div>
11 <hr class="pre-posts"/> 11 <hr class="pre-posts"/>
12 <div class="blog-posts"> 12 <div class="blog-posts">
13 - <%= (children.compact.empty? ? content_tag('em', _('(no posts)')) : list_posts(user, children)) %> 13 + <%= (children.compact.empty? ? content_tag('em', _('(no posts)')) : list_posts(user, children, article.visualization_format)) %>
14 </div> 14 </div>
public/stylesheets/application.css
@@ -1171,6 +1171,14 @@ a.comment-picture { @@ -1171,6 +1171,14 @@ a.comment-picture {
1171 max-width: 100%; 1171 max-width: 100%;
1172 } 1172 }
1173 1173
  1174 +#content .blog-post .read-more {
  1175 + text-align: right;
  1176 + clear: both;
  1177 +}
  1178 +#content .blog-post .read-more a {
  1179 + margin: 0 10px;
  1180 +}
  1181 +
1174 /* NOT PUBLISHED BLOG POSTS */ 1182 /* NOT PUBLISHED BLOG POSTS */
1175 1183
1176 .blog-post.not-published { 1184 .blog-post.not-published {
test/functional/cms_controller_test.rb
@@ -736,6 +736,12 @@ class CmsControllerTest &lt; Test::Unit::TestCase @@ -736,6 +736,12 @@ class CmsControllerTest &lt; Test::Unit::TestCase
736 assert_tag :tag => 'select', :attributes => { :name => 'article[posts_per_page]' }, :child => { :tag => 'option', :attributes => {:value => n, :selected => 'selected'} } 736 assert_tag :tag => 'select', :attributes => { :name => 'article[posts_per_page]' }, :child => { :tag => 'option', :attributes => {:value => n, :selected => 'selected'} }
737 end 737 end
738 738
  739 + should 'display options for blog visualization with default value on edit blog' do
  740 + format = Blog.new.visualization_format
  741 + get :new, :profile => profile.identifier, :type => 'Blog'
  742 + assert_tag :tag => 'select', :attributes => { :name => 'article[visualization_format]' }, :child => { :tag => 'option', :attributes => {:value => 'full', :selected => 'selected'} }
  743 + end
  744 +
739 should 'not offer to create special article types' do 745 should 'not offer to create special article types' do
740 get :new, :profile => profile.identifier 746 get :new, :profile => profile.identifier
741 assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/new?type=Blog"} 747 assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/new?type=Blog"}
test/functional/content_viewer_controller_test.rb
@@ -857,4 +857,17 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase @@ -857,4 +857,17 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase
857 assert_tag :tag => 'div', :attributes => { :class => 'post_comment_box opened' } 857 assert_tag :tag => 'div', :attributes => { :class => 'post_comment_box opened' }
858 end 858 end
859 859
  860 + should 'show only first paragraph of blog posts if visualization_format is short' do
  861 + login_as(profile.identifier)
  862 +
  863 + blog = Blog.create!(:name => 'A blog test', :profile => profile, :visualization_format => 'short')
  864 +
  865 + blog.posts << TinyMceArticle.create!(:name => 'first post', :parent => blog, :profile => profile, :body => '<p>Content to be displayed.</p> Anything')
  866 +
  867 + get :view_page, :profile => profile.identifier, :page => blog.explode_path
  868 +
  869 + assert_tag :tag => 'div', :attributes => { :class => 'short-post'}, :content => /Content to be displayed./
  870 + assert_no_tag :tag => 'div', :attributes => { :class => 'short-post'}, :content => /Anything/
  871 + end
  872 +
860 end 873 end
test/unit/blog_helper_test.rb
@@ -23,7 +23,7 @@ class BlogHelperTest &lt; Test::Unit::TestCase @@ -23,7 +23,7 @@ class BlogHelperTest &lt; Test::Unit::TestCase
23 should 'list published posts with class blog-post' do 23 should 'list published posts with class blog-post' do
24 blog.children << published_post = TextileArticle.create!(:name => 'Post', :profile => profile, :parent => blog, :published => true) 24 blog.children << published_post = TextileArticle.create!(:name => 'Post', :profile => profile, :parent => blog, :published => true)
25 25
26 - expects(:display_post).with(anything).returns('POST') 26 + expects(:display_post).with(anything, anything).returns('POST')
27 expects(:content_tag).with('div', "POST<br style=\"clear:both\"/>", :class => 'blog-post position-1 first last odd-post-inner', :id => "post-#{published_post.id}").returns('POST') 27 expects(:content_tag).with('div', "POST<br style=\"clear:both\"/>", :class => 'blog-post position-1 first last odd-post-inner', :id => "post-#{published_post.id}").returns('POST')
28 expects(:content_tag).with('div', 'POST', {:class => 'odd-post'}).returns('RESULT') 28 expects(:content_tag).with('div', 'POST', {:class => 'odd-post'}).returns('RESULT')
29 29
@@ -33,7 +33,7 @@ class BlogHelperTest &lt; Test::Unit::TestCase @@ -33,7 +33,7 @@ class BlogHelperTest &lt; Test::Unit::TestCase
33 should 'list unpublished posts to owner with a different class' do 33 should 'list unpublished posts to owner with a different class' do
34 blog.children << unpublished_post = TextileArticle.create!(:name => 'Post', :profile => profile, :parent => blog, :published => false) 34 blog.children << unpublished_post = TextileArticle.create!(:name => 'Post', :profile => profile, :parent => blog, :published => false)
35 35
36 - expects(:display_post).with(anything).returns('POST') 36 + expects(:display_post).with(anything, anything).returns('POST')
37 expects(:content_tag).with('div', "POST<br style=\"clear:both\"/>", :class => 'blog-post position-1 first last not-published odd-post-inner', :id => "post-#{unpublished_post.id}").returns('POST') 37 expects(:content_tag).with('div', "POST<br style=\"clear:both\"/>", :class => 'blog-post position-1 first last not-published odd-post-inner', :id => "post-#{unpublished_post.id}").returns('POST')
38 expects(:content_tag).with('div', 'POST', {:class => 'odd-post'}).returns('RESULT') 38 expects(:content_tag).with('div', 'POST', {:class => 'odd-post'}).returns('RESULT')
39 assert_equal 'RESULT', list_posts(profile, blog.posts) 39 assert_equal 'RESULT', list_posts(profile, blog.posts)
@@ -44,7 +44,7 @@ class BlogHelperTest &lt; Test::Unit::TestCase @@ -44,7 +44,7 @@ class BlogHelperTest &lt; Test::Unit::TestCase
44 44
45 blog.children << published_post = TextileArticle.create!(:name => 'Second post', :profile => profile, :parent => blog, :published => true) 45 blog.children << published_post = TextileArticle.create!(:name => 'Second post', :profile => profile, :parent => blog, :published => true)
46 46
47 - expects(:display_post).with(anything).returns('POST') 47 + expects(:display_post).with(anything, anything).returns('POST')
48 expects(:content_tag).with('div', "POST<br style=\"clear:both\"/>", has_entries(:id => "post-#{unpublished_post.id}")).never 48 expects(:content_tag).with('div', "POST<br style=\"clear:both\"/>", has_entries(:id => "post-#{unpublished_post.id}")).never
49 expects(:content_tag).with('div', "POST<br style=\"clear:both\"/>", has_entries(:id => "post-#{published_post.id}")).returns('POST') 49 expects(:content_tag).with('div', "POST<br style=\"clear:both\"/>", has_entries(:id => "post-#{published_post.id}")).returns('POST')
50 expects(:content_tag).with('div', 'POST', {:class => 'odd-post'}).returns('RESULT') 50 expects(:content_tag).with('div', 'POST', {:class => 'odd-post'}).returns('RESULT')
@@ -56,7 +56,7 @@ class BlogHelperTest &lt; Test::Unit::TestCase @@ -56,7 +56,7 @@ class BlogHelperTest &lt; Test::Unit::TestCase
56 56
57 blog.children << newer_post = TextileArticle.create!(:name => 'Second post', :profile => profile, :parent => blog, :published => true) 57 blog.children << newer_post = TextileArticle.create!(:name => 'Second post', :profile => profile, :parent => blog, :published => true)
58 58
59 - expects(:display_post).with(anything).returns('POST').times(2) 59 + expects(:display_post).with(anything, anything).returns('POST').times(2)
60 60
61 expects(:content_tag).with('div', "POST<br style=\"clear:both\"/>", :class => 'blog-post position-1 first odd-post-inner', :id => "post-#{newer_post.id}").returns('POST 1') 61 expects(:content_tag).with('div', "POST<br style=\"clear:both\"/>", :class => 'blog-post position-1 first odd-post-inner', :id => "post-#{newer_post.id}").returns('POST 1')
62 expects(:content_tag).with('div', "POST 1", :class => 'odd-post').returns('ODD-POST') 62 expects(:content_tag).with('div', "POST 1", :class => 'odd-post').returns('ODD-POST')
@@ -70,7 +70,7 @@ class BlogHelperTest &lt; Test::Unit::TestCase @@ -70,7 +70,7 @@ class BlogHelperTest &lt; Test::Unit::TestCase
70 70
71 should 'display post' do 71 should 'display post' do
72 blog.children << article = TextileArticle.create!(:name => 'Second post', :profile => profile, :parent => blog, :published => true) 72 blog.children << article = TextileArticle.create!(:name => 'Second post', :profile => profile, :parent => blog, :published => true)
73 - expects(:article_title).with(article).returns('TITLE') 73 + expects(:article_title).with(article, anything).returns('TITLE')
74 expects(:content_tag).with('p', article.to_html).returns(' TO_HTML') 74 expects(:content_tag).with('p', article.to_html).returns(' TO_HTML')
75 self.stubs(:params).returns({:npage => nil}) 75 self.stubs(:params).returns({:npage => nil})
76 76
@@ -79,13 +79,39 @@ class BlogHelperTest &lt; Test::Unit::TestCase @@ -79,13 +79,39 @@ class BlogHelperTest &lt; Test::Unit::TestCase
79 79
80 should 'display empty post if body is nil' do 80 should 'display empty post if body is nil' do
81 blog.children << article = fast_create(Article, :profile_id => profile.id, :parent_id => blog.id, :body => nil) 81 blog.children << article = fast_create(Article, :profile_id => profile.id, :parent_id => blog.id, :body => nil)
82 - expects(:article_title).with(article).returns('TITLE') 82 + expects(:article_title).with(article, anything).returns('TITLE')
83 expects(:content_tag).with('p', '').returns('') 83 expects(:content_tag).with('p', '').returns('')
84 self.stubs(:params).returns({:npage => nil}) 84 self.stubs(:params).returns({:npage => nil})
85 85
86 assert_equal 'TITLE', display_post(article) 86 assert_equal 'TITLE', display_post(article)
87 end 87 end
88 88
  89 + should 'display full post by default' do
  90 + blog.children << article = fast_create(Article, :profile_id => profile.id, :parent_id => blog.id, :body => nil)
  91 + expects(:article_title).with(article, anything).returns('')
  92 + expects(:display_full_format).with(article).returns('FULL POST')
  93 +
  94 + assert_equal 'FULL POST', display_post(article)
  95 + end
  96 +
  97 + should 'no_comments is false if blog displays full post' do
  98 + blog.children << article = fast_create(Article, :profile_id => profile.id, :parent_id => blog.id, :body => nil)
  99 + expects(:article_title).with(article, :no_comments => false).returns('')
  100 + expects(:display_full_format).with(article).returns('FULL POST')
  101 +
  102 + assert_equal 'FULL POST', display_post(article, 'full')
  103 + end
  104 +
  105 + should 'no_comments is true if blog displays short post' do
  106 + blog.update_attribute(:visualization_format, 'short')
  107 + blog.children << article = fast_create(Article, :profile_id => profile.id, :parent_id => blog.id, :body => nil)
  108 + expects(:article_title).with(article, :no_comments => true).returns('')
  109 + expects(:display_short_format).with(article).returns('SHORT POST')
  110 +
  111 + assert_equal 'SHORT POST', display_post(article, 'short')
  112 + end
  113 +
  114 +
89 should 'display link to file if post is an uploaded_file' do 115 should 'display link to file if post is an uploaded_file' do
90 file = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain'), :profile => profile, :published => true, :parent => blog) 116 file = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain'), :profile => profile, :published => true, :parent => blog)
91 117
test/unit/blog_test.rb
@@ -149,4 +149,33 @@ class BlogTest &lt; ActiveSupport::TestCase @@ -149,4 +149,33 @@ class BlogTest &lt; ActiveSupport::TestCase
149 assert_not_equal 'changed-name', blog.slug 149 assert_not_equal 'changed-name', blog.slug
150 end 150 end
151 151
  152 + should 'display full posts by default' do
  153 + blog = Blog.new
  154 + assert_equal 'full', blog.visualization_format
  155 + end
  156 +
  157 + should 'update visualization_format setting' do
  158 + p = create_user('testuser').person
  159 + p.articles << Blog.new(:profile => p, :name => 'Blog test')
  160 + blog = p.blog
  161 + blog.visualization_format = 'short'
  162 + assert blog.save!
  163 + assert_equal 'short', p.blog.visualization_format
  164 + end
  165 +
  166 + should 'allow only full and short as visualization_format' do
  167 + blog = Blog.new(:name => 'blog')
  168 + blog.visualization_format = 'wrong_format'
  169 + blog.valid?
  170 + assert blog.errors.invalid?(:visualization_format)
  171 +
  172 + blog.visualization_format = 'short'
  173 + blog.valid?
  174 + assert !blog.errors.invalid?(:visualization_format)
  175 +
  176 + blog.visualization_format = 'full'
  177 + blog.valid?
  178 + assert !blog.errors.invalid?(:visualization_format)
  179 + end
  180 +
152 end 181 end