diff --git a/app/controllers/application.rb b/app/controllers/application.rb
index bb49a27..212c008 100644
--- a/app/controllers/application.rb
+++ b/app/controllers/application.rb
@@ -53,7 +53,7 @@ class ApplicationController < ActionController::Base
def render_not_found(path = nil)
@path ||= request.path
# raise "#{@path} not found"
- render(:file => File.join(RAILS_ROOT, 'app', 'views', 'shared', 'not_found.rhtml'), :layout => 'not_found', :status => 404) && fal
+ render(:file => File.join(RAILS_ROOT, 'app', 'views', 'shared', 'not_found.rhtml'), :layout => 'not_found', :status => 404)
end
def user
diff --git a/app/controllers/my_profile/profile_design_controller.rb b/app/controllers/my_profile/profile_design_controller.rb
index 366a8fb..6bb60ab 100644
--- a/app/controllers/my_profile/profile_design_controller.rb
+++ b/app/controllers/my_profile/profile_design_controller.rb
@@ -3,7 +3,7 @@ class ProfileDesignController < BoxOrganizerController
needs_profile
def available_blocks
- @available_blocks ||= [ Block, ArticleBlock ]
+ @available_blocks ||= [ Block, ArticleBlock, TagsBlock ]
end
end
diff --git a/app/controllers/public/profile_controller.rb b/app/controllers/public/profile_controller.rb
index 4e05b9d..e741ea5 100644
--- a/app/controllers/public/profile_controller.rb
+++ b/app/controllers/public/profile_controller.rb
@@ -1,3 +1,14 @@
class ProfileController < ApplicationController
needs_profile
+
+ helper TagsHelper
+
+ def index
+ @tags = profile.tags
+ end
+
+ def tag
+ @tag = profile.content_tagged_with(params[:id])
+ end
+
end
diff --git a/app/controllers/public/search_controller.rb b/app/controllers/public/search_controller.rb
index b626975..1a17c1e 100644
--- a/app/controllers/public/search_controller.rb
+++ b/app/controllers/public/search_controller.rb
@@ -1,5 +1,7 @@
class SearchController < ApplicationController
+ helper TagsHelper
+
SEARCHES = []
def self.search(&block)
@@ -44,7 +46,10 @@ class SearchController < ApplicationController
end
def tags
- @tags = Tag.find(:all)
+ @tags = Tag.find(:all).inject({}) do |memo,tag|
+ memo[tag.name] = tag.taggings.count
+ memo
+ end
end
def tag
diff --git a/app/helpers/tags_helper.rb b/app/helpers/tags_helper.rb
new file mode 100644
index 0000000..2829131
--- /dev/null
+++ b/app/helpers/tags_helper.rb
@@ -0,0 +1,51 @@
+module TagsHelper
+
+ module Cloud
+ MAX_SIZE = 32
+ MIN_SIZE = 12
+ end
+
+ # tags must be a hash where the keys are tag names and the values
+ # the count of elements tagged with the tag, as returned by
+ # Profile#find_tagged_with. If not tags were returned, just returns
+ # _('No tags yet.')
+ #
+ # must be a symbol representing the key to be inserted in
+ # url with the tag name as value, if url is a Hash. If
+ # url_options is a String, then the tag name is just appended to it.
+ #
+ # Example:
+ #
+ # tag_cloud({ 'first-tag' => 10, 'second-tag' => 2, 'third-tag' => 1 }, :id, { :action => 'show_tag' })
+ #
+ # options can include one or more of the following:
+ #
+ # * :max_size: font size for the tag with largest count
+ # * :min_size: font size for the tag with smallest count
+ #
+ # The algorithm for generating the different sizes and positions is a
+ # courtesy of Aurelio: http://www.colivre.coop.br/Aurium/Nuvem
+ # (pt_BR only).
+ def tag_cloud(tags, tagname_option, url, options = {})
+
+ return _('No tags yet.') if tags.empty?
+
+ max_size = options[:max_size] || Cloud::MAX_SIZE
+ min_size = options[:min_size] || Cloud::MIN_SIZE
+
+ delta = max_size - min_size
+ max = tags.values.max.to_f
+
+ tags.map do |tag,count|
+ v = count.to_f / max
+ style = <<-EOS
+ font-size: #{ (v * delta).round + min_size }px;
+ top: #{ -4 - (v * 4).round }px;
+ EOS
+ destination = url.kind_of?(Hash) ? url_for(url.merge(tagname_option => tag)) : (url.to_s + tag)
+
+ link_to "#{tag} (#{count})", destination, :style => style
+ end.join("\n")
+ end
+
+end
diff --git a/app/models/block.rb b/app/models/block.rb
index eee9e24..05bb50d 100644
--- a/app/models/block.rb
+++ b/app/models/block.rb
@@ -1,4 +1,8 @@
class Block < ActiveRecord::Base
+
+ # to be able to generate HTML
+ include ActionView::Helpers::TagHelper
+
acts_as_list :scope => :box
belongs_to :box
diff --git a/app/models/profile.rb b/app/models/profile.rb
index 5c0b7f2..48cb783 100644
--- a/app/models/profile.rb
+++ b/app/models/profile.rb
@@ -187,4 +187,23 @@ class Profile < ActiveRecord::Base
options
end
+ def tags(public_only = false)
+ totals = {}
+ articles.each do |article|
+ article.tags.each do |tag|
+ if totals[tag.name]
+ totals[tag.name] += 1
+ else
+ totals[tag.name] = 1
+ end
+ end
+ end
+ totals
+ end
+
+ def find_tagged_with(tag)
+ # FIXME: this can be SLOW
+ articles.select {|item| item.tags.map(&:name).include?(tag) }
+ end
+
end
diff --git a/app/models/tags_block.rb b/app/models/tags_block.rb
new file mode 100644
index 0000000..8927ce9
--- /dev/null
+++ b/app/models/tags_block.rb
@@ -0,0 +1,15 @@
+class TagsBlock < Block
+
+ include TagsHelper
+ include ActionView::Helpers::UrlHelper
+
+ def self.description
+ _('List count of contents by tag')
+ end
+
+ def content(main_content = nil)
+ content_tag('h3', _('Tags'), :class => 'block-title') +
+ tag_cloud(owner.tags, :id, owner.generate_url(:controller => 'profile', :action => 'tag') + '/', :max_size => 20, :min_size => 10)
+ end
+
+end
diff --git a/app/views/profile/index.rhtml b/app/views/profile/index.rhtml
index 0991704..42c3a3b 100644
--- a/app/views/profile/index.rhtml
+++ b/app/views/profile/index.rhtml
@@ -13,4 +13,9 @@
<%# FIXME %>
<%= link_to_function _('Friends'), 'alert("not yet")' %>
<%= link_to_function _('Communities'), 'alert("not yet")' %>
+
+
+ <%= _('Tags:') %>
+ <%= tag_cloud @tags, :id, { :action => 'tag' }, :max_size => 18, :min_size => 10%>
+
diff --git a/app/views/search/tags.rhtml b/app/views/search/tags.rhtml
index 7915fc0..938320c 100644
--- a/app/views/search/tags.rhtml
+++ b/app/views/search/tags.rhtml
@@ -1,5 +1,4 @@
<%= _('Tag cloud') %>
-<% @tags.each do |t| %>
- <%= link_to("#{t.name} (#{t.taggings.count})", { :action => 'tag', :tag => t.name }, :style => "font-size: #{14 + 2 * t.taggings.count}px;") %>
-<% end %>
+<%= tag_cloud(@tags, :tag, :action => 'tag') %>
+
diff --git a/config/routes.rb b/config/routes.rb
index c9920b9..98adf7a 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -44,7 +44,7 @@ ActionController::Routing::Routes.draw do |map|
map.controllers 'block/:profile/:controller/:action/:id', :controller => Noosfero.pattern_for_controllers_from_design_blocks
# public profile information
- map.profile 'profile/:profile/:action', :controller => 'profile', :action => 'index'
+ map.profile 'profile/:profile/:action/:id', :controller => 'profile', :action => 'index'
######################################################
## Controllers that are profile-specific (for profile admins )
diff --git a/test/test_helper.rb b/test/test_helper.rb
index 7b09edd..a208b89 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -56,6 +56,13 @@ class Test::Unit::TestCase
admin_user.login
end
+ def create_environment(domainname)
+ env = Environment.create!(:name => domainname)
+ env.domains << Domain.new(:name => domainname)
+ env.save!
+ env
+ end
+
def create_user(name)
User.create!(:login => name,
:email => name + '@noosfero.org',
diff --git a/test/unit/profile_test.rb b/test/unit/profile_test.rb
index a7889be..4285eee 100644
--- a/test/unit/profile_test.rb
+++ b/test/unit/profile_test.rb
@@ -231,21 +231,43 @@ class ProfileTest < Test::Unit::TestCase
end
should 'provide url to itself' do
- profile = Profile.create!(:name => "Test Profile", :identifier => 'testprofile', :environment_id => create_environment('colivre.net').id)
+ profile = Profile.create!(:name => "Test Profile", :identifier => 'testprofile', :environment_id => create_environment('mycolivre.net').id)
- assert_equal 'http://colivre.net/testprofile', profile.url
+ assert_equal 'http://mycolivre.net/testprofile', profile.url
end
should 'generate URL' do
- profile = Profile.create!(:name => "Test Profile", :identifier => 'testprofile', :environment_id => create_environment('colivre.net').id)
+ profile = Profile.create!(:name => "Test Profile", :identifier => 'testprofile', :environment_id => create_environment('mycolivre.net').id)
- assert_equal 'http://colivre.net/profile/testprofile/friends', profile.generate_url(:controller => 'profile', :action => 'friends')
+ assert_equal 'http://mycolivre.net/profile/testprofile/friends', profile.generate_url(:controller => 'profile', :action => 'friends')
end
should 'provide URL options' do
- profile = Profile.create!(:name => "Test Profile", :identifier => 'testprofile', :environment_id => create_environment('colivre.net').id)
+ profile = Profile.create!(:name => "Test Profile", :identifier => 'testprofile', :environment_id => create_environment('mycolivre.net').id)
- assert_equal({:host => 'colivre.net', :profile => 'testprofile'}, profile.url_options)
+ assert_equal({:host => 'mycolivre.net', :profile => 'testprofile'}, profile.url_options)
+ end
+
+ should 'list tags for profile' do
+ profile = Profile.create!(:name => "Test Profile", :identifier => 'testprofile')
+ profile.articles.build(:name => 'first', :tag_list => 'first-tag').save!
+ profile.articles.build(:name => 'second', :tag_list => 'first-tag, second-tag').save!
+ profile.articles.build(:name => 'third', :tag_list => 'first-tag, second-tag, third-tag').save!
+
+ assert_equal({ 'first-tag' => 3, 'second-tag' => 2, 'third-tag' => 1 }, profile.tags)
+
+ end
+
+ should 'find content tagged with given tag' do
+ profile = Profile.create!(:name => "Test Profile", :identifier => 'testprofile')
+ first = profile.articles.build(:name => 'first', :tag_list => 'first-tag'); first.save!
+ second = profile.articles.build(:name => 'second', :tag_list => 'first-tag, second-tag'); second.save!
+ third = profile.articles.build(:name => 'third', :tag_list => 'first-tag, second-tag, third-tag'); third.save!
+ profile.reload
+
+ assert_equivalent [ first, second, third], profile.find_tagged_with('first-tag')
+ assert_equivalent [ second, third ], profile.find_tagged_with('second-tag')
+ assert_equivalent [ third], profile.find_tagged_with('third-tag')
end
private
diff --git a/test/unit/tags_block_test.rb b/test/unit/tags_block_test.rb
new file mode 100644
index 0000000..2b9d334
--- /dev/null
+++ b/test/unit/tags_block_test.rb
@@ -0,0 +1,26 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class TagsBlockTest < Test::Unit::TestCase
+
+ def setup
+ user = create_user('testinguser').person
+ user.articles.build(:name => 'article 1', :tag_list => 'first-tag').save!
+ user.articles.build(:name => 'article 2', :tag_list => 'first-tag, second-tag').save!
+ user.articles.build(:name => 'article 3', :tag_list => 'first-tag, second-tag, third-tag').save!
+
+ box = Box.create!(:owner => user)
+ @block = TagsBlock.create!(:box => box)
+ end
+ attr_reader :block
+
+ should 'describe itself' do
+ assert_not_equal Block.description, TagsBlock.description
+ end
+
+ should 'generate links to tags' do
+ assert_match /profile\/testinguser\/tag\/first-tag/, block.content
+ assert_match /profile\/testinguser\/tag\/second-tag/, block.content
+ assert_match /profile\/testinguser\/tag\/third-tag/, block.content
+ end
+
+end
--
libgit2 0.21.2