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 |