# Methods added to this helper will be available to all templates in the
# application.
module ApplicationHelper
include PermissionName
include LightboxHelper
include ThickboxHelper
include BoxesHelper
include FormsHelper
include AssetsHelper
include BlockHelper
include DatesHelper
include FolderHelper
include ProfileEditorHelper
include DisplayHelper
include AccountHelper
def locale
FastGettext.locale
end
def load_web2_conf
if File.exists?( RAILS_ROOT + '/config/web2.0.yml')
YAML.load_file( RAILS_ROOT + '/config/web2.0.yml' )
else
{}
end
end
def web2_conf
@web_conf ||= load_web2_conf
end
# Displays context help. You can pass the content of the help message as the
# first parameter or using template code inside a block passed to this
# method. *Note*: the block is ignored if content is not
# nil
#
# The method returns the text generated, so you can also use it inside a
# <%= ... %>
#
# Follow some examples ...
#
# Passing the text as argument:
#
# <% help 'This your help message' %>
#
# Using a block:
#
# <% help do %>
# This is the help message to be displayed. It can contain any HTML you
# want: bold, italic. It can also contain calls
# to any Rails helper, like <%= link_to 'home', :controller => 'home' %>.
# <% end %>
#
# You can also pass an optional argument to force the use of textile in your
# help message:
#
# <% help nil, :textile do %>
# You can also use *textile*!
# <% end %>
#
# or, using the return of the method:
#
# <%= help 'this is your help message' %>
#
# Formally, the type argument can be :html (i.e. no
# conversion of the input) or :textile (converts the message, in
# textile, into HTML). It defaults to :html.
#
# TODO: implement correcly the 'Help' button click
def help(content = nil, link_name = nil, options = {}, &block)
link_name ||= _('Help')
@help_message_id ||= 1
help_id = "help_message_#{@help_message_id}"
if content.nil?
return '' if block.nil?
content = capture(&block)
end
if options[:type] == :textile
content = RedCloth.new(content).to_html
end
options[:class] = '' if ! options[:class]
options[:class] += ' button icon-help' # with-text
# TODO: implement this button, and add style='display: none' to the help
# message DIV
button = link_to_function(content_tag('span', link_name), "Element.show('#{help_id}')", options )
close_button = content_tag("div", link_to_function(_("Close"), "Element.hide('#{help_id}')", :class => 'close_help_button'))
text = content_tag('div', button + content_tag('div', content_tag('div', content) + close_button, :class => 'help_message', :id => help_id, :style => 'display: none;'), :class => 'help_box')
unless block.nil?
concat(text, block.binding)
end
text
end
# alias for help(content, :textile). You can pass a block in the
# same way you would do if you called help directly.
def help_textile(content = nil, link_name = nil, options = {}, &block)
options[:type] = :textile
help(content, link_name, options, &block)
end
# TODO: do something more useful here
# TODO: test this helper
# TODO: add an icon?
# TODO: the command rake test:rcov didn't works because of this method. See what it's the problem
def environment_identification
content_tag('div', @environment.name, :id => 'environment_identification')
end
def link_to_cms(text, profile = nil, options = {})
profile ||= current_user.login
link_to text, myprofile_path(:controller => 'cms', :profile => profile), options
end
def link_to_profile(text, profile = nil, options = {})
profile ||= current_user.login
link_to text, profile_path(:profile => profile) , options
end
def link_to_homepage(text, profile = nil, options = {})
p = if profile
Profile[profile]
else
user
end
link_to text, p.url, options
end
def link_if_permitted(link, permission = nil, target = nil)
if permission.nil? || current_user.person.has_permission?(permission, target)
link
else
nil
end
end
def footer
# FIXME: add some information from the environment
[
content_tag('div', _('This is %s, version %s') % [ link_to(Noosfero::PROJECT, 'http://www.noosfero.com.br/'), Noosfero::VERSION]),
].join("\n")
end
# returns the current profile beign viewed.
#
# Make sure that you use this helper method only in contexts where there
# should be a current profile (i.e. while viewing some profile's pages, or the
# profile info, etc), because if there is no profile an exception is thrown.
def profile
@controller.send(:profile)
end
def category_color
if @category.nil?
""
else
@category.top_ancestor.display_color
end
end
def text_editor(object, method, filter_type_method = nil, options = {})
text_area(object, method, { :rows => 10, :cols => 64 }.merge(options))
end
def hide(id)
"Element.hide(#{id.inspect});"
end
def show(id)
"Element.show(#{id.inspect});"
end
def toggle_panel(hide_label, show_label, id)
hide_button_id = id + "-hide"
show_button_id = id + "-show"
result = ""
result << button_to_function('open', show_label, show(id) + show(hide_button_id) + hide(show_button_id), :id => show_button_id, :class => 'show-button with-text', :style => 'display: none;' )
result < " "
result << button_to_function('close', hide_label, hide(id) + hide(hide_button_id) + show(show_button_id), :id => hide_button_id, :class => 'hide-button with-text')
result
end
def button(type, label, url, html_options = {})
the_class = 'with-text'
if html_options.has_key?(:class)
the_class << ' ' << html_options[:class]
end
button_without_text type, label, url, html_options.merge(:class => the_class)
end
def button_without_text(type, label, url, html_options = {})
the_class = "button icon-#{type}"
if html_options.has_key?(:class)
the_class << ' ' << html_options[:class]
end
the_title = html_options[:title] || label
link_to(' '+content_tag('span', label), url, html_options.merge(:class => the_class, :title => the_title))
end
def button_to_function(type, label, js_code, html_options = {}, &block)
html_options[:class] = "button with-text" unless html_options[:class]
html_options[:class] << " icon-#{type}"
link_to_function(label, js_code, html_options, &block)
end
def button_to_function_without_text(type, label, js_code, html_options = {}, &block)
html_options[:class] = "" unless html_options[:class]
html_options[:class] << " button icon-#{type}"
link_to_function(content_tag('span', label), js_code, html_options, &block)
end
def button_to_remote(type, label, options, html_options = {})
html_options[:class] = "button with-text" unless html_options[:class]
html_options[:class] << " icon-#{type}"
link_to_remote(label, options, html_options)
end
def button_to_remote_without_text(type, label, options, html_options = {})
html_options[:class] = "" unless html_options[:class]
html_options[:class] << " button icon-#{type}"
link_to_remote(content_tag('span', label), options, html_options.merge(:title => label))
end
def icon(icon_name, html_options = {})
the_class = "button #{icon_name}"
if html_options.has_key?(:class)
the_class << ' ' << html_options[:class]
end
content_tag('div', '', html_options.merge(:class => the_class))
end
def icon_button(type, text, url, html_options = {})
the_class = "button icon-button icon-#{type}"
if html_options.has_key?(:class)
the_class << ' ' << html_options[:class]
end
link_to(content_tag('span', text), url, html_options.merge(:class => the_class, :title => text))
end
def button_bar(options = {}, &block)
concat(content_tag('div', capture(&block) + tag('br', :style => 'clear: left;'), { :class => 'button-bar' }.merge(options)), block.binding)
end
def partial_for_class(klass)
if klass.nil?
raise ArgumentError, 'No partial for object. Is there a partial for any class in the inheritance hierarchy?'
end
name = klass.name.underscore
if File.exists?(File.join(RAILS_ROOT, 'app', 'views', params[:controller], "_#{name}.rhtml"))
name
else
partial_for_class(klass.superclass)
end
end
def user
@controller.send(:user)
end
# DEPRECATED. Do not use this.
def stylesheet_import(*sources)
options = sources.last.is_a?(Hash) ? sources.pop : { }
themed_source = options.delete(:themed_source)
content_tag(
'style',
"\n" +
sources.flatten.map do |source|
filename = filename_for_stylesheet(source.to_s, themed_source)
if File.exists?(File.join(RAILS_ROOT, 'public', filename))
"@import url(#{filename});\n"
else
"/* Not included: url(#{filename}) */\n"
end
end.join(),
{ "type" => "text/css" }.merge(options)
)
end
# DEPRECATED. Do not use this.
def filename_for_stylesheet(name, in_theme)
result = ''
if in_theme
result << theme_path
end
name += '.css' if ( name[-4..-1] != '.css' )
if ( name[0..0] == '/' )
result << name
else
result << '/stylesheets/' << name
end
end
def theme_path
if session[:theme]
'/user_themes/' + current_theme
else
'/designs/themes/' + current_theme
end
end
def theme_stylesheet_path
theme_path + '/style.css'
end
def current_theme
@current_theme ||=
begin
if (session[:theme])
session[:theme]
else
# utility for developers: set the theme to 'random' in development mode and
# you will get a different theme every request. This is interesting for
# testing
if ENV['RAILS_ENV'] == 'development' && environment.theme == 'random'
@random_theme ||= Dir.glob('public/designs/themes/*').map { |f| File.basename(f) }.rand
@random_theme
elsif ENV['RAILS_ENV'] == 'development' && params[:theme]
params[:theme]
else
if profile && !profile.theme.nil?
profile.theme
elsif environment
environment.theme
else
if logger
logger.warn("No environment found. This is weird.")
logger.warn("Request environment: %s" % request.env.inspect)
logger.warn("Request parameters: %s" % params.inspect)
end
# could not determine the theme, so return the default one
'default'
end
end
end
end
end
def theme_include(template)
['.rhtml', '.html.erb'].each do |ext|
file = (RAILS_ROOT + '/public' + theme_path + '/' + template + ext)
if File.exists?(file)
return render :file => file, :use_full_path => false
end
end
nil
end
def theme_favicon
return '/designs/themes/' + current_theme + '/favicon.ico' if profile.nil? || profile.theme.nil?
if File.exists?(File.join(RAILS_ROOT, 'public', theme_path, 'favicon.ico'))
'/designs/themes/' + profile.theme + '/favicon.ico'
else
favicon = profile.articles.find_by_path('favicon.ico')
if favicon
favicon.public_filename
else
'/designs/themes/' + environment.theme + '/favicon.ico'
end
end
end
def theme_site_title
theme_include('site_title')
end
def theme_header
theme_include('header')
end
def theme_footer
theme_include('footer')
end
def theme_extra_navigation
theme_include('navigation')
end
def is_testing_theme
!@controller.session[:theme].nil?
end
def theme_owner
Theme.find(current_theme).owner.identifier
end
# generates a image tag for the profile.
#
# If the profile has no image set yet, then a default image is used.
def profile_image(profile, size=:portrait, opt={})
return '' if profile.nil?
opt[:alt] ||= profile.name()
opt[:title] ||= ''
opt[:class] ||= ''
opt[:class] += ( profile.class == Person ? ' photo' : ' logo' )
image_tag(profile_icon(profile, size), opt )
end
def profile_icon( profile, size=:portrait, return_mimetype=false )
filename, mimetype = '', 'image/png'
if profile.image
filename = profile.image.public_filename( size )
mimetype = profile.image.content_type
else
icon =
if profile.organization?
if profile.kind_of?(Community)
'/images/icons-app/community-'+ size.to_s() +'.png'
else
'/images/icons-app/enterprise-'+ size.to_s() +'.png'
end
else
'/images/icons-app/person-'+ size.to_s() +'.png'
end
filename = default_or_themed_icon(icon)
end
return_mimetype ? [filename, mimetype] : filename
end
def default_or_themed_icon(icon)
if File.exists?(File.join(Rails.root, 'public', theme_path, icon))
theme_path + icon
else
icon
end
end
def profile_sex_icon( profile )
return '' unless profile.is_a?(Person)
return '' unless !environment.enabled?('disable_gender_icon')
sex = ( profile.sex ? profile.sex.to_s() : 'undef' )
title = ( sex == 'undef' ? _('non registered gender') : ( sex == 'male' ? _('Male') : _('Female') ) )
sex = content_tag 'span',
content_tag( 'span', sex ),
:class => 'sex-'+sex,
:title => title
sex
end
def profile_cat_icons( profile )
if profile.class == Enterprise
icons =
profile.product_categories.map{ |c| c.size > 1 ? c[1] : nil }.
compact.uniq.map{ |c|
cat_name = c.gsub( /[-_\s,.;'"]+/, '_' )
cat_icon = "/images/icons-cat/#{cat_name}.png"
if ! File.exists? RAILS_ROOT.to_s() + '/public/' + cat_icon
cat_icon = '/images/icons-cat/undefined.png'
end
content_tag 'span',
content_tag( 'span', c ),
:title => c,
:class => 'product-cat-icon cat_icon_' + cat_name,
:style => "background-image:url(#{cat_icon})"
}.join "\n"
content_tag 'div',
content_tag( 'span', _('Principal Product Categories'), :class => 'header' ) +"\n"+ icons,
:class => 'product-category-icons'
else
''
end
end
# displays a link to add the profile with its image (as generated by
# #profile_image) or only its name below.
def profile_add_link( profile, image=false, size=:portrait, tag='li')
the_class = profile.members.include?(user) ? 'profile_member' : ''
name = h(profile.short_name)
if image
display = content_tag( 'span', profile_image( profile, size ), :class => 'profile-image' ) +
content_tag( 'span', name, :class => 'org' ) +
profile_cat_icons( profile )
the_class << ' vcard'
else
display = content_tag( 'span', name, :class => 'org' )
end
content_tag tag,
link_to_remote( display,
:update => 'search-results-and-pages',
:url => {:controller => 'account', :action => 'profile_details', :profile => profile.identifier},
:onclick => 'document.location.href = this.href', # work-arround for ie.
:class => 'profile_link url',
:help => _('Click on this icon to add %s to your network') % profile.name,
:title => profile.name ),
:class => the_class
end
def links_for_balloon(profile)
if environment.enabled?(:show_balloon_with_profile_links_when_clicked)
if profile.kind_of?(Person)
[
{_('Wall') => {:href => url_for(profile.public_profile_url)}},
{_('Friends') => {:href => url_for(:controller => :profile, :action => :friends, :profile => profile.identifier)}},
{_('Communities') => {:href => url_for(:controller => :profile, :action => :communities, :profile => profile.identifier)}},
{_('Send an e-mail') => {:href => url_for(:profile => profile.identifier, :controller => 'contact', :action => 'new'), :class => 'send-an-email', :style => 'display: none'}},
{_('Add') => {:href => url_for(profile.add_url), :class => 'add-friend', :style => 'display: none'}}
]
elsif profile.kind_of?(Community)
[
{_('Wall') => {:href => url_for(profile.public_profile_url)}},
{_('Members') => {:href => url_for(:controller => :profile, :action => :members, :profile => profile.identifier)}},
{_('Agenda') => {:href => url_for(:controller => :profile, :action => :events, :profile => profile.identifier)}},
{_('Join') => {:href => url_for(profile.join_url), :class => 'join-community', :style => 'display: none'}},
{_('Leave') => {:href => url_for(profile.leave_url), :class => 'leave-community', :style => 'display: none'}},
{_('Send an e-mail') => {:href => url_for(:profile => profile.identifier, :controller => 'contact', :action => 'new'), :class => 'send-an-email', :style => 'display: none'}}
]
elsif profile.kind_of?(Enterprise)
[
{_('Products') => {:href => catalog_path(profile.identifier)}},
{_('Members') => {:href => url_for(:controller => :profile, :action => :members, :profile => profile.identifier)}},
{_('Agenda') => {:href => url_for(:controller => :profile, :action => :events, :profile => profile.identifier)}},
{_('Send an e-mail') => {:href => url_for(:profile => profile.identifier, :controller => 'contact', :action => 'new'), :class => 'send-an-email', :style => 'display: none'}},
]
else
[]
end
end
end
# displays a link to the profile homepage with its image (as generated by
# #profile_image) and its name below it.
def profile_image_link( profile, size=:portrait, tag='li', extra_info = nil )
name = profile.short_name
if profile.person?
city = content_tag 'span', content_tag( 'span', profile.city, :class => 'locality' ), :class => 'adr'
url = url_for(profile.check_friendship_url)
trigger_class = 'person-trigger'
else
city = ''
url = url_for(profile.check_membership_url)
if profile.community?
trigger_class = 'community-trigger'
elsif profile.enterprise?
trigger_class = 'enterprise-trigger'
end
end
extra_info = extra_info.nil? ? '' : content_tag( 'span', extra_info, :class => 'extra_info' )
links = links_for_balloon(profile)
content_tag tag,
(environment.enabled?(:show_balloon_with_profile_links_when_clicked) ? link_to( content_tag( 'span', _('Profile links')), '#', :onclick => "toggleSubmenu(this, '#{profile.short_name}', #{links.to_json}); return false", :class => "menu-submenu-trigger #{trigger_class}", :url => url) : "") +
link_to(
content_tag( 'span', profile_image( profile, size ), :class => 'profile-image' ) +
content_tag( 'span', h(name), :class => ( profile.class == Person ? 'fn' : 'org' ) ) +
city + extra_info + profile_sex_icon( profile ) + profile_cat_icons( profile ),
profile.url,
:onclick => 'document.location.href = this.href', # work-arround for ie.
:class => 'profile_link url',
:help => _('Click on this icon to go to the %s\'s home page') % profile.name,
:title => profile.name ),
:class => 'vcard'
end
# displays a link to the community homepage with its image (as generated by
# #profile_image) and its name and number of members beside it.
def community_image_link( profile, size=:portrait, tag='li' )
name = h(profile.name)
links = links_for_balloon(profile)
url = url_for(profile.check_membership_url)
content_tag tag,
(environment.enabled?(:show_balloon_with_profile_links_when_clicked) ? link_to( content_tag( 'span', _('Profile links')), '#', :onclick => "toggleSubmenu(this, '#{profile.short_name}', #{links.to_json}); return false", :class => 'menu-submenu-trigger community-trigger', :url => url) : "") +
link_to(
content_tag( 'span', profile_image( profile, size ), :class => 'profile-image' ) +
content_tag( 'span', name, :class => 'org' ) +
content_tag( 'span', n_('1 member', '%s members', profile.members.count) % profile.members.count, :class => 'community-member-count' ),
profile.url,
:onclick => 'document.location.href = this.href', # work-arround for ie.
:class => 'profile_link url',
:help => _('Click on this icon to go to the %s\'s home page') % profile.name,
:title => profile.name ) +
'
',
:class => 'vcard'
end
def gravatar_url_for(email, options = {})
# Ta dando erro de roteamento
url_for( { :gravatar_id => Digest::MD5.hexdigest(email),
:host => 'www.gravatar.com',
:protocol => 'http://',
:only_path => false,
:controller => 'avatar.php',
:d => web2_conf['gravatar'] ? web2_conf['gravatar']['default'] : nil
}.merge(options) )
end
def str_gravatar_url_for(email, options = {})
default = web2_conf['gravatar'] ? web2_conf['gravatar']['default'] : nil
url = 'http://www.gravatar.com/avatar.php?gravatar_id=' +
Digest::MD5.hexdigest(email)
{
:only_path => false,
:d => default
}.merge(options).each { |k,v|
url += ( '&%s=%s' % [ k,v ] )
}
url
end
attr_reader :environment
def select_categories(object_name, title=nil, title_size=4)
return nil if environment.enabled?(:disable_categories)
if title.nil?
title = _('Categories')
end
object = instance_variable_get("@#{object_name}")
result = content_tag 'h'+title_size.to_s(), title
result << javascript_tag( 'function open_close_cat( link ) {
var div = link.parentNode.getElementsByTagName("div")[0];
var end = function(){
if ( div.style.display == "none" ) {
this.link.className="button icon-button icon-down"
} else {
this.link.className="button icon-button icon-up-red"
}
}
Effect.toggle( div, "slide", { link:link, div:div, afterFinish:end } )
}')
environment.top_level_categories.select{|i| !i.children.empty?}.each do |toplevel|
next unless object.accept_category?(toplevel)
# FIXME
([toplevel] + toplevel.children_for_menu).each do |cat|
if cat.top_level?
result << '