# 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 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
link_to(' '+content_tag('span', label), url, html_options.merge(:class => the_class, :title => label))
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)
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
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
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
else
if profile
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)
file = (RAILS_ROOT + '/public' + theme_path + '/' + template + '.rhtml')
if File.exists?(file)
render :file => file, :use_full_path => false
end
end
def theme_header
theme_include('header')
end
def theme_footer
theme_include('footer')
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={})
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 )
if profile.image
profile.image.public_filename( size )
else
if profile.organization?
if profile.kind_of?(Community)
'/images/icons-app/users_size-'+ size.to_s() +'.png'
else
'/images/icons-app/enterprise-default-pic-'+ size.to_s() +'.png'
end
else
'/images/icons-app/user_icon_size-'+ size.to_s() +'.png'
end
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 = 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
# 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' )
if profile.class == Person
name = profile.short_name
city = content_tag 'span', content_tag( 'span', profile.city, :class => 'locality' ), :class => 'adr'
else
name = profile.short_name
city = ''
end
content_tag tag,
link_to(
content_tag( 'span', profile_image( profile, size ), :class => 'profile-image' ) +
content_tag( 'span', name, :class => ( profile.class == Person ? 'fn' : 'org' ) ) +
city + 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 = profile.name
content_tag tag,
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 << '