From 3e7250494a6552a03f6924fc3f22fcb4627f8b23 Mon Sep 17 00:00:00 2001 From: AurĂ©lio A. Heckert Date: Tue, 14 Apr 2015 21:11:47 +0000 Subject: [PATCH] Improve blog posts listing --- app/helpers/blog_helper.rb | 31 ++++++++++++++++++++----------- app/models/article.rb | 4 +++- app/models/blog.rb | 2 +- app/views/cms/_blog.html.erb | 6 +++++- app/views/content_viewer/blog_page.html.erb | 5 ++++- public/stylesheets/application.css | 8 ++++++++ test/functional/content_viewer_controller_test.rb | 14 ++++++++++++++ test/unit/article_test.rb | 12 ++++++++++++ test/unit/blog_helper_test.rb | 54 ++++++++++++++++++++++++++++++------------------------ 9 files changed, 97 insertions(+), 39 deletions(-) diff --git a/app/helpers/blog_helper.rb b/app/helpers/blog_helper.rb index 69e2a2a..5c87253 100644 --- a/app/helpers/blog_helper.rb +++ b/app/helpers/blog_helper.rb @@ -17,28 +17,28 @@ module BlogHelper _('Configure blog') end - def list_posts(articles, format = 'full', paginate = true) + def list_posts(articles, conf = { format: 'full', paginate: true }) pagination = will_paginate(articles, { :param_name => 'npage', :previous_label => _('« Newer posts'), :next_label => _('Older posts »'), :params => {:action=>"view_page", :page=>articles.first.parent.path.split('/'), :controller=>"content_viewer"} - }) if articles.present? && paginate + }) if articles.present? && conf[:paginate] content = [] artic_len = articles.length articles.each_with_index{ |art,i| - css_add = [ 'position-'+(i+1).to_s() ] + css_add = [ 'blog-post', 'position-'+(i+1).to_s() ] position = (i%2 == 0) ? 'odd-post' : 'even-post' css_add << 'first' if i == 0 css_add << 'last' if i == (artic_len-1) css_add << 'not-published' if !art.published? - css_add << position + '-inner' - content << content_tag('div', - content_tag('div', - display_post(art, format).html_safe + '
'.html_safe, - :class => 'blog-post ' + css_add.join(' '), - :id => "post-#{art.id}"), :class => position - ) + css_add << position + content << (content_tag 'div', id: "post-#{art.id}", class: css_add do + content_tag 'div', class: position + '-inner blog-post-inner' do + display_post(art, conf[:format]).html_safe + + '
'.html_safe + end + end) } content.join("\n
\n") + (pagination or '') end @@ -46,7 +46,16 @@ module BlogHelper def display_post(article, format = 'full') no_comments = (format == 'full') ? false : true title = article_title(article, :no_comments => no_comments) - html = send("display_#{format}_format", FilePresenter.for(article)).html_safe + method = "display_#{format.split('+')[0]}_format" + html = send(method, FilePresenter.for(article)).html_safe + if format.split('+')[1] == 'pic' + img = article.first_image + if img.blank? + '
' + else + '
' + end + end.to_s + title + html end diff --git a/app/models/article.rb b/app/models/article.rb index 3e6e43f..95939a8 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -769,7 +769,9 @@ class Article < ActiveRecord::Base end def first_image - img = Nokogiri::HTML.fragment(self.lead.to_s).css('img[src]').first || Nokogiri::HTML.fragment(self.body.to_s).search('img').first + img = ( image.present? && { 'src' => image.public_filename } ) || + Nokogiri::HTML.fragment(self.lead.to_s).css('img[src]').first || + Nokogiri::HTML.fragment(self.body.to_s).search('img').first img.nil? ? '' : img['src'] end diff --git a/app/models/blog.rb b/app/models/blog.rb index 7ce092a..edee58e 100644 --- a/app/models/blog.rb +++ b/app/models/blog.rb @@ -76,7 +76,7 @@ class Blog < Folder end settings_items :visualization_format, :type => :string, :default => 'full' - validates_inclusion_of :visualization_format, :in => [ 'full', 'short' ], :if => :visualization_format + validates_inclusion_of :visualization_format, :in => [ 'full', 'short', 'short+pic' ], :if => :visualization_format settings_items :display_posts_in_current_language, :type => :boolean, :default => false diff --git a/app/views/cms/_blog.html.erb b/app/views/cms/_blog.html.erb index c30f77b..3a8c5be 100644 --- a/app/views/cms/_blog.html.erb +++ b/app/views/cms/_blog.html.erb @@ -64,7 +64,11 @@ <%= labelled_check_box(_('Remove cover image'),'remove_image',true,false)%> <% end %> -<%= labelled_form_field(_('How to display posts:'), f.select(:visualization_format, [ [ _('Full post'), 'full'], [ _('First paragraph'), 'short'] ])) %> +<%= labelled_form_field(_('How to display posts:'), f.select(:visualization_format, [ + [ _('Full post'), 'full'], + [ _('First paragraph'), 'short'], + [ _('First paragraph, with post picture'), 'short+pic'] +])) %> <%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, Blog.posts_per_page_options)) %> diff --git a/app/views/content_viewer/blog_page.html.erb b/app/views/content_viewer/blog_page.html.erb index 8645ec3..b4a9621 100644 --- a/app/views/content_viewer/blog_page.html.erb +++ b/app/views/content_viewer/blog_page.html.erb @@ -18,6 +18,9 @@ format = inside_block.visualization_format paginate = false end - (blog.empty? ? content_tag('em', _('(no posts)')) : list_posts(posts, format, paginate)) + (blog.empty? ? + content_tag('em', _('(no posts)')) : + list_posts(posts, format: format, paginate: paginate) + ) %> diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css index 79ea613..7c82998 100644 --- a/public/stylesheets/application.css +++ b/public/stylesheets/application.css @@ -1483,6 +1483,14 @@ a.comment-picture { #content .title { margin-bottom: 2px; } +.blog-post .post-pic { + background-position: 50% 40%; + background-size: cover; + height: 150px; +} +.blog-post .post-pic.empty { + display: none; +} .metadata, .blog-post .metadata { display: block; text-align: center; diff --git a/test/functional/content_viewer_controller_test.rb b/test/functional/content_viewer_controller_test.rb index bf8fb9d..5d6210f 100644 --- a/test/functional/content_viewer_controller_test.rb +++ b/test/functional/content_viewer_controller_test.rb @@ -780,6 +780,20 @@ class ContentViewerControllerTest < ActionController::TestCase assert_no_tag :tag => 'div', :attributes => { :class => 'short-post'}, :content => /Anything/ end + should 'show only first paragraph with picture of posts if visualization_format is short+pic' do + login_as(profile.identifier) + + blog = Blog.create!(:name => 'A blog test', :profile => profile, :visualization_format => 'short+pic') + + blog.posts << TinyMceArticle.create!(:name => 'first post', :parent => blog, :profile => profile, :body => '

Content to be displayed.

') + + get :view_page, :profile => profile.identifier, :page => blog.path + + assert_select '.blog-post .post-pic' do |el| + assert_match /background-image:url\(pic.jpg\)/, el.to_s + end + end + should 'display link to edit blog for allowed' do blog = fast_create(Blog, :profile_id => profile.id, :path => 'blog') login_as(profile.identifier) diff --git a/test/unit/article_test.rb b/test/unit/article_test.rb index b956dfc..d2334ad 100644 --- a/test/unit/article_test.rb +++ b/test/unit/article_test.rb @@ -1715,6 +1715,18 @@ class ArticleTest < ActiveSupport::TestCase assert_equal 'bar.png', a.first_image end + should 'get first image from having_image' do + a = fast_create(Article, + :body => '

Foo

', + :abstract => '

Lead

' + ) + img = {} + img.expects(:present?).returns true + img.expects(:public_filename).returns 'pic.jpg' + a.expects(:image).at_least_once.returns img + assert_equal 'pic.jpg', a.first_image + end + should 'not get first image from anywhere' do a = fast_create(Article, :body => '

Foo

Bar

') assert_equal '', a.first_image diff --git a/test/unit/blog_helper_test.rb b/test/unit/blog_helper_test.rb index b49e37e..474703b 100644 --- a/test/unit/blog_helper_test.rb +++ b/test/unit/blog_helper_test.rb @@ -20,30 +20,36 @@ class BlogHelperTest < ActionView::TestCase def _(s); s; end def h(s); s; end - should 'list published posts with class blog-post' do - blog.children << published_post = create(TextileArticle, :name => 'Post', :profile => profile, :parent => blog, :published => true) - - expects(:display_post).with(anything, anything).returns('POST') - expects(:content_tag).with('div', "POST
", :class => 'blog-post position-1 first last odd-post-inner', :id => "post-#{published_post.id}").returns('POST') - expects(:content_tag).with('div', 'POST', {:class => 'odd-post'}).returns('RESULT') - - assert_equal 'RESULT', list_posts(blog.posts) - end - - should 'list even/odd posts with a different class' do - blog.children << older_post = create(TextileArticle, :name => 'First post', :profile => profile, :parent => blog, :published => true) - - blog.children << newer_post = create(TextileArticle, :name => 'Second post', :profile => profile, :parent => blog, :published => true) - - expects(:display_post).with(anything, anything).returns('POST').times(2) - - expects(:content_tag).with('div', "POST
", :class => 'blog-post position-1 first odd-post-inner', :id => "post-#{newer_post.id}").returns('POST 1') - expects(:content_tag).with('div', "POST 1", :class => 'odd-post').returns('ODD-POST') - - expects(:content_tag).with('div', "POST
", :class => 'blog-post position-2 last even-post-inner', :id => "post-#{older_post.id}").returns('POST 2') - expects(:content_tag).with('div', "POST 2", :class => 'even-post').returns('EVEN-POST') - - assert_equal "ODD-POST\n
\nEVEN-POST", list_posts(blog.posts) + should 'list blog posts with identifiers and classes' do + blog.children << older_post = create(TextileArticle, :name => 'First post', + :profile => profile, :parent => blog, :published => true) + blog.children << some_post = create(TextileArticle, :name => 'Some post', + :profile => profile, :parent => blog, :published => true) + blog.children << hidden_post = create(TextileArticle, :name => 'Hidden post', + :profile => profile, :parent => blog, :published => false) + blog.children << newer_post = create(TextileArticle, :name => 'Last post', + :profile => profile, :parent => blog, :published => true) + + def content_tag(tag, content_or_options_with_block = nil, options = nil, &block) + if block_given? + options = content_or_options_with_block + content = block.call + else + content = content_or_options_with_block + end + options ||= {} + "<#{tag}#{options.map{|k,v| " #{k}=\"#{[v].flatten.join(' ')}\""}.join}>#{content}" + end + + html = HTML::Document.new(list_posts(blog.posts)).root + assert_select html, "div#post-#{newer_post.id}.blog-post.position-1.first.odd-post" + + " > div.odd-post-inner.blog-post-inner > .title", 'Last post' + assert_select html, "div#post-#{hidden_post.id}.blog-post.position-2.not-published.even-post" + + " > div.even-post-inner.blog-post-inner > .title", 'Hidden post' + assert_select html, "div#post-#{some_post.id}.blog-post.position-3.odd-post" + + " > div.odd-post-inner.blog-post-inner > .title", 'Some post' + assert_select html, "div#post-#{older_post.id}.blog-post.position-4.last.even-post" + + " > div.even-post-inner.blog-post-inner > .title", 'First post' end -- libgit2 0.21.2