Commit cb67a972189432ac6d5d0b1e9b3ef13f9d3cff40
Committed by
Antonio Terceiro
1 parent
d2c9927d
Exists in
master
and in
29 other branches
ActionItem904: removing unpublished posts from blogs and feeds
* For blog owner, unpublished articles are listed with hachures and opacity
Showing
15 changed files
with
153 additions
and
46 deletions
Show diff stats
app/helpers/blog_helper.rb
... | ... | @@ -14,4 +14,25 @@ module BlogHelper |
14 | 14 | _('Edit blog') |
15 | 15 | end |
16 | 16 | |
17 | + def list_posts(user, articles) | |
18 | + pagination = will_paginate(articles, { | |
19 | + :param_name => 'npage', | |
20 | + :prev_label => _('« Newer posts'), | |
21 | + :next_label => _('Older posts »') | |
22 | + }) | |
23 | + content = [] | |
24 | + articles.map{ |i| | |
25 | + css_add = '' | |
26 | + if i.published? || (user==i.profile) | |
27 | + css_add = '-not-published' if !i.published? | |
28 | + content << content_tag('div', display_post(i), :class => 'blog-post' + css_add, :id => "post-#{i.id}") | |
29 | + end | |
30 | + } | |
31 | + content.join("\n") + (pagination or '') | |
32 | + end | |
33 | + | |
34 | + def display_post(article) | |
35 | + article_title(article) + content_tag('p', article.to_html) + | |
36 | + content_tag('p', link_to( number_of_comments(article), article.url.merge(:form => 'opened', :anchor => 'comment_form') ), :class => 'metadata') | |
37 | + end | |
17 | 38 | end | ... | ... |
app/helpers/content_viewer_helper.rb
1 | 1 | module ContentViewerHelper |
2 | 2 | |
3 | 3 | include GetText |
4 | + include BlogHelper | |
4 | 5 | |
5 | 6 | def number_of_comments(article) |
6 | 7 | n = article.comments.size |
... | ... | @@ -24,37 +25,10 @@ module ContentViewerHelper |
24 | 25 | title |
25 | 26 | end |
26 | 27 | |
27 | - def list_posts(articles) | |
28 | - pagination = will_paginate(articles, { | |
29 | - :param_name => 'npage', | |
30 | - :page_links => false, | |
31 | - :prev_label => _('Newer posts »'), | |
32 | - :next_label => _('« Older posts') | |
33 | - }) | |
34 | - articles.map{ |i| content_tag('div', display_post(i), :class => 'blog-post', :id => "post-#{i.id}") }.join("\n") + | |
35 | - (pagination or '') | |
36 | - end | |
37 | - | |
38 | - def display_post(article) | |
39 | - article_title(article) + content_tag('p', article.to_html) + | |
40 | - content_tag('p', link_to( number_of_comments(article), article.url.merge(:form => 'opened', :anchor => 'comment_form') ), :class => 'metadata') | |
41 | - end | |
42 | - | |
43 | 28 | def article_to_html(article) |
44 | - content = article.to_html | |
29 | + content = article.to_html(:page => params[:npage]) | |
45 | 30 | return self.instance_eval(&content) if content.kind_of?(Proc) |
46 | - | |
47 | - if article.blog? | |
48 | - children = if article.filter and article.filter[:year] and article.filter[:month] | |
49 | - filter_date = DateTime.parse("#{article.filter[:year]}-#{article.filter[:month]}-01") | |
50 | - article.posts.paginate :page => params[:npage], :per_page => article.posts_per_page, :conditions => [ 'created_at between ? and ?', filter_date, filter_date + 1.month - 1.day ] | |
51 | - else | |
52 | - article.posts.paginate :page => params[:npage], :per_page => article.posts_per_page | |
53 | - end | |
54 | - content + (children.compact.empty? ? content_tag('em', _('(no posts)')) : list_posts(children)) | |
55 | - else | |
56 | - content | |
57 | - end | |
31 | + content | |
58 | 32 | end |
59 | 33 | |
60 | 34 | end | ... | ... |
app/models/article.rb
... | ... | @@ -127,7 +127,7 @@ class Article < ActiveRecord::Base |
127 | 127 | # The implementation in this class just provides the +body+ attribute as the |
128 | 128 | # HTML. Other article types can override this method to provide customized |
129 | 129 | # views of themselves. |
130 | - def to_html | |
130 | + def to_html(options = {}) | |
131 | 131 | body |
132 | 132 | end |
133 | 133 | ... | ... |
app/models/blog.rb
... | ... | @@ -28,8 +28,8 @@ class Blog < Folder |
28 | 28 | |
29 | 29 | # FIXME isn't this too much including just to be able to generate some HTML? |
30 | 30 | include ActionView::Helpers::TagHelper |
31 | - def to_html | |
32 | - content_tag('div', body) + tag('hr') | |
31 | + def to_html(options = {}) | |
32 | + posts_list(options[:page]) | |
33 | 33 | end |
34 | 34 | |
35 | 35 | def folder? |
... | ... | @@ -52,4 +52,16 @@ class Blog < Folder |
52 | 52 | end |
53 | 53 | end |
54 | 54 | |
55 | + def posts_list(npage) | |
56 | + article = self | |
57 | + children = if filter and filter[:year] and filter[:month] | |
58 | + filter_date = DateTime.parse("#{filter[:year]}-#{filter[:month]}-01") | |
59 | + posts.paginate :page => npage, :per_page => posts_per_page, :conditions => [ 'created_at between ? and ?', filter_date, filter_date + 1.month - 1.day ] | |
60 | + else | |
61 | + posts.paginate :page => npage, :per_page => posts_per_page | |
62 | + end | |
63 | + lambda do | |
64 | + render :file => 'content_viewer/blog_page', :locals => {:article => article, :children => children} | |
65 | + end | |
66 | + end | |
55 | 67 | end | ... | ... |
app/models/enterprise_homepage.rb
... | ... | @@ -20,7 +20,7 @@ class EnterpriseHomepage < Article |
20 | 20 | include EnterpriseHomepageHelper |
21 | 21 | include CatalogHelper |
22 | 22 | |
23 | - def to_html | |
23 | + def to_html(options ={}) | |
24 | 24 | products = self.profile.products |
25 | 25 | display_profile_info(self.profile) + content_tag('div', self.body || '') + |
26 | 26 | (self.profile.environment.enabled?('disable_products_for_enterprises') ? '' : display_products_list(self.profile, products)) | ... | ... |
app/models/event.rb
app/models/folder.rb
app/models/rss_feed.rb
... | ... | @@ -50,7 +50,7 @@ class RssFeed < Article |
50 | 50 | validates_inclusion_of :feed_item_description, :in => [ 'body', 'abstract' ], :if => :feed_item_description |
51 | 51 | |
52 | 52 | # TODO |
53 | - def to_html | |
53 | + def to_html(options = {}) | |
54 | 54 | end |
55 | 55 | |
56 | 56 | # RSS feeds have type =text/xml=. |
... | ... | @@ -61,7 +61,7 @@ class RssFeed < Article |
61 | 61 | include ActionController::UrlWriter |
62 | 62 | def fetch_articles |
63 | 63 | if parent && parent.blog? |
64 | - return parent.posts.find(:all, :limit => self.limit, :order => 'id desc') | |
64 | + return parent.posts.find(:all, :conditions => ['published = ?', true], :limit => self.limit, :order => 'id desc') | |
65 | 65 | end |
66 | 66 | |
67 | 67 | articles = | ... | ... |
app/models/textile_article.rb
app/models/uploaded_file.rb
... | ... | @@ -50,7 +50,7 @@ class UploadedFile < Article |
50 | 50 | # FIXME isn't this too much including just to be able to generate some HTML? |
51 | 51 | include ActionView::Helpers::TagHelper |
52 | 52 | |
53 | - def to_html | |
53 | + def to_html(options = {}) | |
54 | 54 | tag('img', :src => public_filename, :class => css_class_name, :style => 'max-width: 100%') if image? |
55 | 55 | end |
56 | 56 | ... | ... |
public/stylesheets/article.css
... | ... | @@ -202,10 +202,38 @@ |
202 | 202 | |
203 | 203 | #content #article .pagination .prev_page { |
204 | 204 | position: absolute; |
205 | - right: 0; | |
205 | + left: 0; | |
206 | 206 | } |
207 | 207 | |
208 | 208 | #content #article .pagination .next_page { |
209 | 209 | position: absolute; |
210 | - left: 0; | |
210 | + right: 0; | |
211 | +} | |
212 | +.msie6 #content #article .pagination .prev_page, | |
213 | +.msie6 #content #article .pagination .next_page { | |
214 | + position: relative; | |
215 | + display: inline; | |
216 | +} | |
217 | + | |
218 | +/* NOT PUBLISHED BLOG POSTS */ | |
219 | + | |
220 | +.blog-post-not-published { | |
221 | + background: url(/images/hachure.png); | |
222 | + opacity: 0.25; | |
223 | + filter: alpha(opacity=25); | |
224 | + zoom: 1; | |
225 | +} | |
226 | + | |
227 | +.blog-post-not-published a { | |
228 | + text-decoration: none; | |
229 | +} | |
230 | + | |
231 | +#content .blog-post-not-published .created-at { | |
232 | + text-align: left; | |
233 | +} | |
234 | + | |
235 | +.blog-post-not-published .metadata { | |
236 | + display: block; | |
237 | + text-align: center; | |
238 | + font-size: small; | |
211 | 239 | } | ... | ... |
test/unit/blog_helper_test.rb
... | ... | @@ -6,12 +6,64 @@ class BlogHelperTest < Test::Unit::TestCase |
6 | 6 | |
7 | 7 | def setup |
8 | 8 | stubs(:show_date).returns('') |
9 | + @environment = Environment.default | |
9 | 10 | @profile = create_user('blog_helper_test').person |
11 | + @blog = Blog.create!(:profile => profile, :name => 'Blog test') | |
10 | 12 | end |
13 | + | |
11 | 14 | attr :profile |
15 | + attr :blog | |
16 | + | |
17 | + def _(s); s; end | |
18 | + | |
19 | + should 'list published posts with class blog-post' do | |
20 | + blog.children << published_post = TextileArticle.create!(:name => 'Post', :profile => profile, :parent => blog, :published => true) | |
12 | 21 | |
13 | - should 'add real tests' do | |
14 | - assert true | |
22 | + expects(:display_post).with(anything).returns('POST') | |
23 | + expects(:content_tag).with('div', 'POST', :class => 'blog-post', :id => "post-#{published_post.id}").returns('RESULT') | |
24 | + | |
25 | + assert_equal 'RESULT', list_posts(profile, blog.posts) | |
15 | 26 | end |
16 | 27 | |
28 | + should 'list unpublished posts to owner with a different class' do | |
29 | + blog.children << unpublished_post = TextileArticle.create!(:name => 'Post', :profile => profile, :parent => blog, :published => false) | |
30 | + | |
31 | + expects(:display_post).with(anything).returns('POST') | |
32 | + expects(:content_tag).with('div', 'POST', :class => 'blog-post-not-published', :id => "post-#{unpublished_post.id}").returns('RESULT') | |
33 | + | |
34 | + assert_equal 'RESULT', list_posts(profile, blog.posts) | |
35 | + end | |
36 | + | |
37 | + should 'not list unpublished posts to not owner' do | |
38 | + blog.children << unpublished_post = TextileArticle.create!(:name => 'First post', :profile => profile, :parent => blog, :published => false) | |
39 | + | |
40 | + blog.children << published_post = TextileArticle.create!(:name => 'Second post', :profile => profile, :parent => blog, :published => true) | |
41 | + | |
42 | + expects(:display_post).with(anything).returns('POST') | |
43 | + expects(:content_tag).with('div', 'POST', :class => 'blog-post', :id => "post-#{published_post.id}").returns('RESULT') | |
44 | + expects(:content_tag).with('div', 'POST', :class => 'blog-post-not-published', :id => "post-#{unpublished_post.id}").never | |
45 | + | |
46 | + assert_equal 'RESULT', list_posts(nil, blog.posts) | |
47 | + end | |
48 | + | |
49 | + should 'display post' do | |
50 | + blog.children << article = TextileArticle.create!(:name => 'Second post', :profile => profile, :parent => blog, :published => true) | |
51 | + expects(:article_title).with(article).returns('TITLE') | |
52 | + expects(:content_tag).with('p', article.to_html).returns(' TO_HTML') | |
53 | + expects(:number_of_comments).with(article).returns('NUMBER OF COMMENTS') | |
54 | + expects(:content_tag).with('p', 'NUMBER OF COMMENTS', anything).returns(' COMMENTS').at_least_once | |
55 | + | |
56 | + assert_equal 'TITLE TO_HTML COMMENTS', display_post(article) | |
57 | + end | |
58 | + | |
59 | + def will_paginate(arg1, arg2) | |
60 | + end | |
61 | + | |
62 | + def link_to(content, url) | |
63 | + content | |
64 | + end | |
65 | + | |
66 | + def content_tag(tag, content, options = {}) | |
67 | + "<#{tag}>#{content}</#{tag}>" | |
68 | + end | |
17 | 69 | end | ... | ... |
test/unit/content_viewer_helper_test.rb
... | ... | @@ -56,7 +56,7 @@ class ContentViewerHelperTest < Test::Unit::TestCase |
56 | 56 | should 'not list feed article' do |
57 | 57 | profile.articles << Blog.new(:name => 'Blog test') |
58 | 58 | assert_includes profile.blog.children.map{|i| i.class}, RssFeed |
59 | - result = list_posts(profile.blog.posts) | |
59 | + result = list_posts(nil, profile.blog.posts) | |
60 | 60 | assert_no_match /feed/, result |
61 | 61 | end |
62 | 62 | |
... | ... | @@ -75,10 +75,11 @@ class ContentViewerHelperTest < Test::Unit::TestCase |
75 | 75 | |
76 | 76 | self.stubs(:params).returns({:npage => nil}) |
77 | 77 | |
78 | + expects(:render).with(:file => 'content_viewer/blog_page', :locals => {:article => blog, :children => [nov]}).returns("BLI") | |
79 | + | |
78 | 80 | result = article_to_html(blog) |
79 | 81 | |
80 | - assert_match /November post/, result | |
81 | - assert_no_match /September post/, result | |
82 | + assert_equal 'BLI', result | |
82 | 83 | end |
83 | 84 | |
84 | 85 | end | ... | ... |
test/unit/rss_feed_test.rb
... | ... | @@ -121,6 +121,20 @@ class RssFeedTest < Test::Unit::TestCase |
121 | 121 | assert_equal [posts[5], posts[4], posts[3], posts[2], posts[1]], feed.fetch_articles |
122 | 122 | end |
123 | 123 | |
124 | + should 'list only published posts from blog' do | |
125 | + profile = create_user('testuser').person | |
126 | + blog = Blog.create(:name => 'blog', :profile => profile) | |
127 | + posts = [] | |
128 | + 5.times do |i| | |
129 | + posts << TextArticle.create!(:name => "post #{i}", :profile => profile, :parent => blog) | |
130 | + end | |
131 | + posts[0].published = false | |
132 | + posts[0].save! | |
133 | + | |
134 | + assert_equal [posts[4], posts[3], posts[2], posts[1]], blog.feed.fetch_articles | |
135 | + end | |
136 | + | |
137 | + | |
124 | 138 | should 'provide link to profile' do |
125 | 139 | profile = create_user('testuser').person |
126 | 140 | feed = RssFeed.new(:name => 'testfeed') | ... | ... |