diff --git a/plugins/context_content/lib/context_content_block.rb b/plugins/context_content/lib/context_content_block.rb new file mode 100644 index 0000000..fe46e3e --- /dev/null +++ b/plugins/context_content/lib/context_content_block.rb @@ -0,0 +1,68 @@ +class ContextContentBlock < Block + + settings_items :show_name, :type => :boolean, :default => true + settings_items :show_image, :type => :boolean, :default => true + settings_items :show_parent_content, :type => :boolean, :default => true + settings_items :types, :type => Array, :default => ['UploadedFile'] + + settings_items :limit, :type => :integer, :default => 6 + + include Noosfero::Plugin::HotSpot + + def self.description + _('Display context content') + end + + def help + _('This block displays content based on context.') + end + + def available_content_types + @available_content_types ||= [TinyMceArticle, TextileArticle, RawHTMLArticle, Event, Folder, Blog, UploadedFile, Forum, Gallery, RssFeed] + plugins.dispatch(:content_types) + end + + def types=(new_types) + settings[:types] = new_types.reject(&:blank?) + end + + def content_image(content) + block = self + lambda do + if content.image? + image_tag(content.public_filename(:thumb)) + else + extra_class = content.kind_of?(UploadedFile) ? "extension-#{content.extension}" : '' + content_tag 'div', '', :class => "context-icon icon-#{content.class.icon_name(content)} #{extra_class}" + end + end + end + + def contents(page) + if page + children = page.children.with_types(types).limit(limit) + (children.blank? && show_parent_content) ? contents(page.parent) : children + else + nil + end + end + +# FIXME +# def footer +# lambda do +# link_to(_('View all'), '') +# end +# end + + def content(args={}) + block = self + lambda do + contents = block.contents(@page) + if !contents.blank? + render :file => 'blocks/context_content', :locals => {:block => block, :contents => contents} + else + '' + end + end + end + +end diff --git a/plugins/context_content/lib/context_content_plugin.rb b/plugins/context_content/lib/context_content_plugin.rb new file mode 100644 index 0000000..c5c16d1 --- /dev/null +++ b/plugins/context_content/lib/context_content_plugin.rb @@ -0,0 +1,21 @@ +class ContextContentPlugin < Noosfero::Plugin + + def self.plugin_name + "Display Context Content" + end + + def self.plugin_description + _("A plugin that display content based on page context.") + end + + def self.extra_blocks + { + ContextContentBlock => { :type => [Person, Community, Enterprise] } + } + end + + def stylesheet? + true + end + +end diff --git a/plugins/context_content/public/style.css b/plugins/context_content/public/style.css new file mode 100644 index 0000000..d9a161e --- /dev/null +++ b/plugins/context_content/public/style.css @@ -0,0 +1,38 @@ +.context-content-block .contents .item img { + width: 100%; +} + +.context-content-block .contents .item .context-icon { + background-size: cover; + background-repeat: no-repeat; + background-position: center; + height: 60px; +} + +.context-content-block .contents .item { + width: 60px; + display: inline-block; + vertical-align: top; + margin: 5px; + list-style-type: none; + border: 1px solid #FFF; + padding: 5px; +} + +.context-content-block .contents .item:hover { + border: 1px solid #CCC; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + background: #EEE; + text-decoration: none; +} + +.context-content-block .contents .item .name { + text-align: center; + font-size: 8pt; + word-wrap: break-word; +} + +.context-content-block .contents .item a { + text-decoration: none; +} diff --git a/plugins/context_content/test/test_helper.rb b/plugins/context_content/test/test_helper.rb new file mode 100644 index 0000000..cca1fd3 --- /dev/null +++ b/plugins/context_content/test/test_helper.rb @@ -0,0 +1 @@ +require File.dirname(__FILE__) + '/../../../test/test_helper' diff --git a/plugins/context_content/test/unit/context_content_block_test.rb b/plugins/context_content/test/unit/context_content_block_test.rb new file mode 100644 index 0000000..c4e55c6 --- /dev/null +++ b/plugins/context_content/test/unit/context_content_block_test.rb @@ -0,0 +1,97 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class ContextContentBlockTest < ActiveSupport::TestCase + + def setup + Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([]) + @block = ContextContentBlock.create! + @block.types = ['TinyMceArticle'] + end + + should 'describe itself' do + assert_not_equal Block.description, ContextContentBlock.description + end + + should 'has a help' do + assert @block.help + end + + should 'return nothing if page is nil' do + assert_equal nil, @block.contents(nil) + end + + should 'render nothing if it has no content to show' do + assert_equal '', instance_eval(&@block.content) + end + + should 'render context content block view' do + @page = fast_create(Folder) + article = fast_create(TinyMceArticle, :parent_id => @page.id) + expects(:render).with(:file => 'blocks/context_content', :locals => {:block => @block, :contents => [article]}) + instance_eval(&@block.content) + end + + should 'return children of page' do + folder = fast_create(Folder) + article = fast_create(TinyMceArticle, :parent_id => folder.id) + assert_equal [article], @block.contents(folder) + end + + should 'limit number of children to display' do + @block.limit = 2 + folder = fast_create(Folder) + article1 = fast_create(TinyMceArticle, :parent_id => folder.id) + article2 = fast_create(TinyMceArticle, :parent_id => folder.id) + article3 = fast_create(TinyMceArticle, :parent_id => folder.id) + assert_equivalent [article1, article2], @block.contents(folder) + end + + should 'return parent children if page has no children' do + folder = fast_create(Folder) + article = fast_create(TinyMceArticle, :parent_id => folder.id) + assert_equal [article], @block.contents(article) + end + + should 'do not return parent children if show_parent_content is false' do + @block.show_parent_content = false + folder = fast_create(Folder) + article = fast_create(TinyMceArticle, :parent_id => folder.id) + assert_equal [], @block.contents(article) + end + + should 'return nil if a page has no parent' do + folder = fast_create(Folder) + assert_equal nil, @block.contents(folder) + end + + should 'return available content types' do + assert_equal [TinyMceArticle, TextileArticle, RawHTMLArticle, Event, Folder, Blog, UploadedFile, Forum, Gallery, RssFeed], @block.available_content_types + end + + should 'include plugin content at available content types' do + class SomePluginContent;end + class SomePlugin; def content_types; SomePluginContent end end + Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([SomePlugin.new]) + + assert_equal [TinyMceArticle, TextileArticle, RawHTMLArticle, Event, Folder, Blog, UploadedFile, Forum, Gallery, RssFeed, SomePluginContent], @block.available_content_types + end + + should 'display thumbnail for image content' do + content = UploadedFile.new(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')) + expects(:image_tag).once + instance_eval(&@block.content_image(content)) + end + + should 'display div as content image for content that is not a image' do + content = fast_create(Folder) + expects(:content_tag).once + instance_eval(&@block.content_image(content)) + end + + should 'display div with extension class for uploaded file that is not a image' do + content = UploadedFile.new(:uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain')) + expects(:content_tag).with('div', '', :class => "context-icon icon-text-plain extension-txt").once + instance_eval(&@block.content_image(content)) + end + +end diff --git a/plugins/context_content/test/unit/context_content_plugin_test.rb b/plugins/context_content/test/unit/context_content_plugin_test.rb new file mode 100644 index 0000000..5c55b41 --- /dev/null +++ b/plugins/context_content/test/unit/context_content_plugin_test.rb @@ -0,0 +1,48 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class ContextContentPluginTest < ActiveSupport::TestCase + + include Noosfero::Plugin::HotSpot + + def setup + @environment = fast_create(Environment) + @environment.enable_plugin(ContextContentPlugin) + end + + attr_reader :environment + + should 'has a name' do + assert_not_equal Noosfero::Plugin.plugin_name, ContextContentPlugin.plugin_name + end + + should 'describe itself' do + assert_not_equal Noosfero::Plugin.plugin_description, ContextContentPlugin.plugin_description + end + + should 'return ContextContentBlock in extra_blocks class method' do + assert ContextContentPlugin.extra_blocks.keys.include?(ContextContentBlock) + end + + should 'return false for class method has_admin_url?' do + assert !ContextContentPlugin.has_admin_url? + end + + should 'ContextContentBlock not available for environment' do + assert_not_includes plugins.dispatch(:extra_blocks, :type => Environment), ContextContentBlock + end + + should 'ContextContentBlock available for community' do + assert_includes plugins.dispatch(:extra_blocks, :type => Community), ContextContentBlock + end + + should 'has stylesheet' do + assert ContextContentPlugin.new.stylesheet? + end + + [Person, Community, Enterprise].each do |klass| + should "ContextContentBlock be available for #{klass.name}" do + assert_includes plugins.dispatch(:extra_blocks, :type => klass), ContextContentBlock + end + end + +end diff --git a/plugins/context_content/views/blocks/context_content.rhtml b/plugins/context_content/views/blocks/context_content.rhtml new file mode 100644 index 0000000..5dbcf74 --- /dev/null +++ b/plugins/context_content/views/blocks/context_content.rhtml @@ -0,0 +1,14 @@ +<%= block_title(block.title) %> + +
Display content types:
+ <% @block.available_content_types.each do |type| %> + <%= labelled_form_field check_box(:block, 'types', {:multiple => true}, type.name, nil) + _(type.short_description), '' %> + <% end %> +