Commit 9b87b01fa706c63b94e19ddc690a0dc302f98ebb

Authored by Marcos Ramos
1 parent d74aa7ba

recent_content_plugin: display the last articles published in your blog.

(ActionItem2848)

Signed-off-by: David Carlos <ddavidcarlos1392@gmail.com>
Signed-off-by: Gabriela Navarro <navarro1703@gmail.com>
Signed-off-by: Marcos Ramos <ms.ramos@outlook.com>
Signed-off-by: Valessio Brito <contato@valessiobrito.com.br>
plugins/recent_content/README 0 → 100644
... ... @@ -0,0 +1,69 @@
  1 +README - RecentContent (RecentContent Plugin)
  2 +================================
  3 +
  4 +RecentContent is a plugin that provides a blog which displays the content posted inside a blog choosen by the user.
  5 +
  6 +The RecentContent block will be available for all layout columns of communities, people, enterprises and environments.
  7 +
  8 +The articles posted from the choosen blog are displayed as a list with a link for the title and optionally the abstract/lead content.
  9 +
  10 +If the choosen blog has a cover image, the user can configure the block to show the same image displayed on that blog.
  11 +
  12 +Galleries and folders are not displayed in this block.
  13 +
  14 +INSTALL
  15 +=======
  16 +
  17 +Enable Plugin
  18 +-------------
  19 +
  20 +Also, you need to enable RecentContent Plugin at your Noosfero:
  21 +
  22 +cd <your_noosfero_dir>
  23 +./script/noosfero-plugins enable recent_content
  24 +
  25 +Active Plugin
  26 +-------------
  27 +
  28 +As a Noosfero administrator user, go to administrator panel:
  29 +
  30 +- Click on "Enable/disable plugins" option
  31 +- Click on "Recent Content Plugin" check-box
  32 +
  33 +DEVELOPMENT
  34 +===========
  35 +
  36 +Get the Recent Content (Noosfero with Recent Content Plugin) development repository:
  37 +
  38 +$ git clone https://github.com/fga-unb/noosfero/tree/AI2848-block_recent_articles
  39 +
  40 +Running RecentContent tests
  41 +--------------------
  42 +
  43 +$ rake test:noosfero_plugins:recent_content
  44 +
  45 +
  46 +Get Involved
  47 +============
  48 +
  49 +If you found any bug and/or want to collaborate, please send an e-mail to contato@valessiobrito.com.br
  50 +
  51 +LICENSE
  52 +=======
  53 +
  54 +Copyright (c) The Author developers.
  55 +
  56 +See Noosfero license.
  57 +
  58 +
  59 +AUTHORS
  60 +=======
  61 + David Carlos (ddavidcarlos1392 at gmail.com)
  62 + Gabriela Navarro (navarro1703 at gmail.com)
  63 + Marcos Ramos (ms.ramos at outlook.com)
  64 + Valessio Brito (contato at valessiobrito.com.br)
  65 +
  66 +ACKNOWLEDGMENTS
  67 +===============
  68 +
  69 +The author have been supported by FGA - UnB and Lappis
... ...
plugins/recent_content/features/add_recent_content.feature 0 → 100644
... ... @@ -0,0 +1,91 @@
  1 +Feature:
  2 + As a logged user
  3 + I want to manage a recent content block
  4 +
  5 +Background:
  6 + Given the following users
  7 + | login | name |
  8 + | joaosilva | Joao Silva |
  9 + And the following plugin
  10 + | klass |
  11 + | RecentContent |
  12 + And plugin RecentContent is enabled on environment
  13 + And the following blocks
  14 + | owner | type |
  15 + | joaosilva | RecentContentBlock |
  16 + And the following articles
  17 + | owner | parent | name | body | abstract |
  18 + | joaosilva | JSilva blog | post #1 | Primeiro post do joao silva | Resumo 1 |
  19 + | joaosilva | JSilva blog | post #2 | Segundo post do joao silva | Resumo 2 |
  20 + | joaosilva | JSilva blog | post #3 | Terceiro post do joao silva | Resumo 3 |
  21 + | joaosilva | JSilva blog | post #4 | Quarto post do joao silva | Resumo 4 |
  22 + | joaosilva | JSilva blog | post #5 | Quinto post do joao silva | Resumo 5 |
  23 + | joaosilva | JSilva blog | post #6 | Sexto post do joao silva | Resumo 6 |
  24 + And I am logged in as "joaosilva"
  25 + Given I go to joaosilva's control panel
  26 + And I follow "Edit sideboxes"
  27 + And I follow "Add a block"
  28 + And I choose "Recent content"
  29 + And I press "Add"
  30 +
  31 + Scenario: the block is being displayed
  32 + Then I should see "This is the recent content block. Please edit it to show the content you want."
  33 +
  34 + Scenario: a user should be redirected to the post page when the link is clicked
  35 + When I follow "Edit" within ".recent-content-block"
  36 + And I select "JSilva blog" from "Choose which blog should be displayed"
  37 + And I select "Title only" from "Choose how the content should be displayed"
  38 + And I fill in "Choose how many items will be displayed" with "3"
  39 + And I press "Save"
  40 + And I follow "post #4" within ".recent-content-block"
  41 + Then I should be on /joaosilva/jsilva-blog/post-4
  42 +
  43 + Scenario: a user should be redirected to the blog page when the "view all" is clicked
  44 + When I follow "Edit" within ".recent-content-block"
  45 + And I select "JSilva blog" from "Choose which blog should be displayed"
  46 + And I select "Title only" from "Choose how the content should be displayed"
  47 + And I fill in "Choose how many items will be displayed" with "2"
  48 + And I press "Save"
  49 + And I follow "View All"
  50 + Then I should be on /joaosilva/jsilva-blog
  51 +
  52 + Scenario: a user should see only titles if the block was configured for it
  53 + When I follow "Edit" within ".recent-content-block"
  54 + And I select "JSilva blog" from "Choose which blog should be displayed"
  55 + And I select "Title only" from "Choose how the content should be displayed"
  56 + And I fill in "Choose how many items will be displayed" with "3"
  57 + And I press "Save"
  58 + Then I should see "post #6" within ".recent-content-block"
  59 +
  60 + Scenario: a user should see titles and abstract if the block was configured for it
  61 + When I follow "Edit" within ".recent-content-block"
  62 + And I select "JSilva blog" from "Choose which blog should be displayed"
  63 + And I select "Title and abstract" from "Choose how the content should be displayed"
  64 + And I fill in "Choose how many items will be displayed" with "6"
  65 + And I press "Save"
  66 + Then I should see "Resumo 5" within ".recent-content-block"
  67 +
  68 + Scenario: a user should see full content if the block was configured for it
  69 + When I follow "Edit" within ".recent-content-block"
  70 + And I select "JSilva blog" from "Choose which blog should be displayed"
  71 + And I select "Full content" from "Choose how the content should be displayed"
  72 + And I fill in "Choose how many items will be displayed" with "6"
  73 + And I press "Save"
  74 + Then I should see "Quinto post do joao silva" within ".recent-content-block"
  75 +
  76 + # the step for attaching a file on the input only works with capybara 1.1.2, but it requires rails 1.9.3
  77 + @selenium-fixme
  78 + Scenario: the user should see the blog cover image if configured and the image is available
  79 + Given I go to joaosilva's control panel
  80 + And I follow "Configure blog"
  81 + And I attach the file "public/images/rails.png" to "Uploaded data"
  82 + And I press "Save"
  83 + When I go to joaosilva's control panel
  84 + And I follow "Edit sideboxes"
  85 + And I follow "Edit" within ".recent-content-block"
  86 + And I select "JSilva blog" from "Choose which blog should be displayed"
  87 + And I select "Title only" from "Choose how the content should be displayed"
  88 + And I fill in "Choose how many items will be displayed" with "3"
  89 + And I check "Display blog cover image"
  90 + And I press "Save"
  91 + Then there should be a div with class "recent-content-cover"
... ...
plugins/recent_content/lib/recent_content_block.rb 0 → 100644
... ... @@ -0,0 +1,58 @@
  1 +class RecentContentBlock < Block
  2 +
  3 + settings_items :presentation_mode, :type => String, :default => 'title_only'
  4 + settings_items :total_items, :type => Integer, :default => 5
  5 + settings_items :show_blog_picture, :type => :boolean, :default => false
  6 + settings_items :selected_folder, :type => Integer
  7 +
  8 + VALID_CONTENT = ['RawHTMLArticle', 'TextArticle', 'TextileArticle', 'TinyMceArticle']
  9 +
  10 + def self.description
  11 + _('Recent content')
  12 + end
  13 +
  14 + def help
  15 + _('This block displays all articles inside the blog you choose. You can edit the block to select which of your blogs is going to be displayed in the block.')
  16 + end
  17 +
  18 + def articles_of_folder(folder, limit)
  19 + holder.articles.all(:conditions => {:type => VALID_CONTENT, :parent_id => folder.id},
  20 + :order => 'created_at DESC',
  21 + :limit => limit )
  22 + end
  23 +
  24 + def holder
  25 + return nil if self.box.nil? || self.box.owner.nil?
  26 + if self.box.owner.kind_of?(Environment)
  27 + return nil if self.box.owner.portal_community.nil?
  28 + self.box.owner.portal_community
  29 + else
  30 + self.box.owner
  31 + end
  32 + end
  33 +
  34 + def parents
  35 + selected = self.holder.articles.all(:conditions => {:type => 'Blog'})
  36 + end
  37 +
  38 + def root
  39 + unless self.selected_folder.nil?
  40 + holder.articles.where(:id => self.selected_folder).first
  41 + end
  42 + end
  43 +
  44 + include ActionController::UrlWriter
  45 + include DatesHelper
  46 +
  47 + def content(args={})
  48 + block = self
  49 + lambda do
  50 + render :file => 'blocks/recent_content_block', :locals => {:root => block.root, :block => block}
  51 + end
  52 + end
  53 +
  54 + def mode?(attr)
  55 + attr == self.presentation_mode
  56 + end
  57 +
  58 +end
... ...
plugins/recent_content/lib/recent_content_plugin.rb 0 → 100644
... ... @@ -0,0 +1,27 @@
  1 +require_dependency File.dirname(__FILE__) + '/recent_content_block'
  2 +
  3 +class RecentContentPlugin < Noosfero::Plugin
  4 +
  5 + def self.plugin_name
  6 + "Recent Content Plugin"
  7 + end
  8 +
  9 + def self.plugin_description
  10 + _("A plugin that adds a block where you can display the content of any of your blogs.")
  11 + end
  12 +
  13 + def self.extra_blocks
  14 + {
  15 + RecentContentBlock => {:position => ['1','2','3'] }
  16 + }
  17 + end
  18 +
  19 + def self.has_admin_url?
  20 + false
  21 + end
  22 +
  23 + def stylesheet?
  24 + true
  25 + end
  26 +
  27 +end
... ...
plugins/recent_content/public/images/li-recent.gif 0 → 100644

88 Bytes

plugins/recent_content/public/style.css 0 → 100644
... ... @@ -0,0 +1,35 @@
  1 +#content .recent-content-block {
  2 + padding: 10px 0px 10px 10px;
  3 + overflow: hidden;
  4 +}
  5 +.recent-content-block ul {
  6 + margin: 0px;
  7 + padding: 0px 0px 0px 20px;
  8 +}
  9 +.recent-content-block li {
  10 + margin: 0px;
  11 + padding: 0px;
  12 +}
  13 +.recent-content-block a {
  14 + text-decoration: none;
  15 +}
  16 +.recent-content-block .block-footer-content {
  17 + font-size: 10px;
  18 +}
  19 +.recent-content-block .block-footer-content a:hover {
  20 + text-decoration: underline;
  21 +}
  22 +.recent-content-block li {
  23 + list-style-image: url('images/li-recent.gif');
  24 + padding: 5px 0px;
  25 +}
  26 +.recent-content-cover {
  27 + overflow: hidden;
  28 + display: block;
  29 + width: 100%;
  30 + max-height: 90px;
  31 +}
  32 +.recent-content-cover img {
  33 + width: 100%;
  34 +}
  35 +
... ...
plugins/recent_content/test/test_helper.rb 0 → 100644
... ... @@ -0,0 +1 @@
  1 +require File.dirname(__FILE__) + '/../../../test/test_helper'
... ...
plugins/recent_content/test/unit/recent_content_block_test.rb 0 → 100644
... ... @@ -0,0 +1,75 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +class RecentContentBlockTest < ActiveSupport::TestCase
  3 +
  4 + INVALID_KIND_OF_ARTICLE = [EnterpriseHomepage, RssFeed, UploadedFile, Gallery, Folder, Blog, Forum]
  5 + VALID_KIND_OF_ARTICLE = [RawHTMLArticle, TextArticle, TextileArticle, TinyMceArticle]
  6 +
  7 + should 'describe itself' do
  8 + assert_not_equal Block.description, RecentContentBlock.description
  9 + end
  10 +
  11 + should 'is editable' do
  12 + block = RecentContentBlock.new
  13 + assert block.editable?
  14 + end
  15 +
  16 + should 'blog_picture be false by default' do
  17 + block = RecentContentBlock.new
  18 + assert !block.show_blog_picture
  19 + end
  20 +
  21 + should 'blog_picture is being stored and restored from database as true' do
  22 + block = RecentContentBlock.new
  23 + block.show_blog_picture = true
  24 + block.save
  25 + block.reload
  26 +
  27 + assert block.show_blog_picture
  28 + end
  29 +
  30 + should 'blog_picture is being stored and restored from database as false' do
  31 + block = RecentContentBlock.new
  32 + block.show_blog_picture = false
  33 + block.save
  34 + block.reload
  35 +
  36 + assert !block.show_blog_picture
  37 + end
  38 +
  39 + should 'root be nil for new blocks' do
  40 + block = RecentContentBlock.new
  41 +
  42 + assert block.root.nil?
  43 + end
  44 +
  45 + should 'root be a Blog when it is configured for' do
  46 + profile = create_user('testuser').person
  47 +
  48 + root = fast_create(Blog, :name => 'test-blog', :profile_id => profile.id)
  49 +
  50 + block = RecentContentBlock.new
  51 + block.stubs(:holder).returns(profile)
  52 + block.selected_folder = root.id
  53 +
  54 + assert block.root.id == root.id
  55 + end
  56 +
  57 + should 'return last articles inside a folder' do
  58 + profile = create_user('testuser').person
  59 +
  60 + Article.delete_all
  61 +
  62 + root = fast_create(Blog, :name => 'test-blog', :profile_id => profile.id)
  63 +
  64 + a1 = fast_create(TextileArticle, :name => 'article #1', :profile_id => profile.id, :parent_id => root.id)
  65 + a2 = fast_create(TextileArticle, :name => 'article #2', :profile_id => profile.id, :parent_id => root.id)
  66 + a3 = fast_create(TextileArticle, :name => 'article #3', :profile_id => profile.id, :parent_id => root.id)
  67 +
  68 + block = RecentContentBlock.new
  69 + block.stubs(:holder).returns(profile)
  70 +
  71 + assert block.articles_of_folder(root,2) == [a3, a2]
  72 + assert block.articles_of_folder(root,3) == [a3, a2, a1]
  73 + end
  74 +
  75 +end
... ...
plugins/recent_content/views/blocks/recent_content_block.rhtml 0 → 100644
... ... @@ -0,0 +1,45 @@
  1 +<% unless root.nil? %>
  2 + <div id="recent-content-block">
  3 + <% children = block.articles_of_folder(root, block.total_items)%>
  4 + <div class="recent-content">
  5 + <%= block_title(block.title.blank? ? _("Recent content") : block.title ) %>
  6 + <% if block.show_blog_picture and !root.image.nil? %>
  7 + <div class="recent-content-cover">
  8 + <%= image_tag(root.image.public_filename(:big)) %>
  9 + </div>
  10 + <% end %>
  11 + </div>
  12 + <% if block.mode?('title_only') %>
  13 + <div class="recent-content-title">
  14 + <ul>
  15 + <% childr"A plugin that adds a block where you can display the content of any of your blogs"en.each do |item| %>
  16 + <li> <%= link_to(h(item.title), item.url)%></li>
  17 + <% end %>
  18 + </ul>
  19 + </div>
  20 + <% elsif block.mode?('title_and_abstract') %>
  21 + <div class="recent-content-abstract">
  22 + <% children.each do |item| %>
  23 + <h2><%= link_to(item.title,item.url, :class => 'post-title')%></h2>
  24 + <span class="post-date"><%= show_date(item.published_at, true)%></span>
  25 + <div class="headline"><%=item.lead%></div>
  26 + <p class="highlighted-news-read-more"><%= link_to(_('Read more'), item.url) %></p>
  27 + <% end %>
  28 + </div>
  29 + <% else %>
  30 + <div class="recent-content-full">
  31 + <% children.each do |item| %>
  32 + <h2><%= link_to(item.title,item.url, :class => 'post-title')%></h2>
  33 + <span class="post-date"><%= show_date(item.published_at, true)%></span>
  34 + <div class="headline"><%=item.body%></div>
  35 + <p class="highlighted-news-read-more"><%= link_to(_('Read more'), item.url) %></p>
  36 + <% end %>
  37 + </div>
  38 + <% end %>
  39 + <%= link_to _('View All'), :profile => profile.identifier, :controller => 'content_viewer', :action => 'view_page', :page => block.root.path %>
  40 + </div>
  41 +<% else %>
  42 + <span class="alert-block">
  43 + <%= _('This is the recent content block. Please edit it to show the content you want.') %>
  44 + </span>
  45 +<% end %>
... ...
plugins/recent_content/views/box_organizer/_recent_content_block.rhtml 0 → 100644
... ... @@ -0,0 +1,33 @@
  1 +<% blogs = @block.parents %>
  2 +<% if blogs.empty? %>
  3 + <h3><%= _('No blogs found. Please add a blog in order to configure this block.') %></h3>
  4 +<% end %>
  5 +<%=
  6 +labelled_form_field(_('Choose which blog should be displayed'),
  7 + select_tag(
  8 + 'block[selected_folder]',
  9 + options_for_select(blogs.map {|node| [node.title, node.id]}, @block.selected_folder)
  10 + )
  11 +)
  12 +%>
  13 +<%=
  14 +labelled_form_field(_('Choose how the content should be displayed'),
  15 + select_tag(
  16 + 'block[presentation_mode]',
  17 + options_for_select(
  18 + {
  19 + _("Title only") => "title_only",
  20 + _("Title and abstract") => "title_and_abstract",
  21 + _("Full content") => "full_content"
  22 + },
  23 + @block.presentation_mode
  24 + )
  25 + )
  26 +)
  27 +%>
  28 +<%= labelled_form_field(_('Choose how many items will be displayed'),
  29 + text_field_tag('block[total_items]',
  30 + @block.total_items, :size => 3, :maxlength => 5)
  31 + )
  32 +%>
  33 +<%= labelled_check_box _('Display blog cover image'), 'block[show_blog_picture]', true, @block.show_blog_picture %>
... ...
plugins/recent_content/views/environment_design 0 → 120000
... ... @@ -0,0 +1 @@
  1 +box_organizer/
0 2 \ No newline at end of file
... ...
plugins/recent_content/views/profile_design 0 → 120000
... ... @@ -0,0 +1 @@
  1 +box_organizer/
0 2 \ No newline at end of file
... ...