Commit f7c784e9e6bec5b1a4a4f3490aa578fa448824f5
Committed by
Joenio Costa
1 parent
45521292
Exists in
master
and in
29 other branches
Adding option to choose how posts will be displayed
A blog can display the full content of posts or only the first paragraph (ActionItem1515)
Showing
11 changed files
with
122 additions
and
14 deletions
Show diff stats
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 < ActiveRecord::Base | @@ -332,7 +332,7 @@ class Article < 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 < Folder | @@ -99,4 +99,8 @@ class Blog < 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 < Test::Unit::TestCase | @@ -736,6 +736,12 @@ class CmsControllerTest < 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 < Test::Unit::TestCase | @@ -857,4 +857,17 @@ class ContentViewerControllerTest < 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 < Test::Unit::TestCase | @@ -23,7 +23,7 @@ class BlogHelperTest < 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 < Test::Unit::TestCase | @@ -33,7 +33,7 @@ class BlogHelperTest < 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 < Test::Unit::TestCase | @@ -44,7 +44,7 @@ class BlogHelperTest < 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 < Test::Unit::TestCase | @@ -56,7 +56,7 @@ class BlogHelperTest < 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 < Test::Unit::TestCase | @@ -70,7 +70,7 @@ class BlogHelperTest < 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 < Test::Unit::TestCase | @@ -79,13 +79,39 @@ class BlogHelperTest < 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 < ActiveSupport::TestCase | @@ -149,4 +149,33 @@ class BlogTest < 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 |