Commit 9be859d42aea93e04ea8f520ee5258021abf3c05

Authored by Rodrigo Souto
1 parent f323c51d

profile: refactor profile fields display process

Also displays every field that is not defined in any category in the
last category called "General". Fields are now easily moved between
categories and categories a easily created.

Fields html generation centered in only one method and the field name
and value are customizable through methods.

Fix #14
app/helpers/profile_helper.rb
1 1 module ProfileHelper
2 2  
3   - def display_field(title, profile, field, force = false)
  3 + COMMON_CATEGORIES = ActiveSupport::OrderedHash.new
  4 + COMMON_CATEGORIES[:content] = [:blogs, :image_galleries, :events, :tags]
  5 + COMMON_CATEGORIES[:interests] = [:interests]
  6 + COMMON_CATEGORIES[:general] = nil
  7 +
  8 + PERSON_CATEGORIES = ActiveSupport::OrderedHash.new
  9 + PERSON_CATEGORIES[:basic_information] = [:nickname, :sex, :birth_date, :location, :privacy_setting, :created_at]
  10 + PERSON_CATEGORIES[:contact] = [:contact_phone, :cell_phone, :comercial_phone, :contact_information, :email, :personal_website, :jabber_id]
  11 + PERSON_CATEGORIES[:location] = [:address, :address_reference, :zip_code, :city, :state, :district, :country, :nationality]
  12 + PERSON_CATEGORIES[:work] = [:organization, :organization_website, :professional_activity]
  13 + PERSON_CATEGORIES[:study] = [:schooling, :formation, :area_of_study]
  14 + PERSON_CATEGORIES[:network] = [:friends, :communities, :enterprises]
  15 + PERSON_CATEGORIES.merge!(COMMON_CATEGORIES)
  16 +
  17 + ORGANIZATION_CATEGORIES = ActiveSupport::OrderedHash.new
  18 + ORGANIZATION_CATEGORIES[:basic_information] = [:display_name, :created_at, :foundation_year, :type, :language, :members_count, :location, :address_reference, :historic_and_current_context, :admins]
  19 + ORGANIZATION_CATEGORIES[:contact] = [:contact_person, :contact_phone, :contact_email, :organization_website, :jabber_id]
  20 + ORGANIZATION_CATEGORIES[:economic] = [:business_name, :acronym, :economic_activity, :legal_form, :products, :activities_short_description, :management_information]
  21 + ORGANIZATION_CATEGORIES.merge!(COMMON_CATEGORIES)
  22 +
  23 + CATEGORY_MAP = ActiveSupport::OrderedHash.new
  24 + CATEGORY_MAP[:person] = PERSON_CATEGORIES
  25 + CATEGORY_MAP[:organization] = ORGANIZATION_CATEGORIES
  26 +
  27 + FORCE = {
  28 + :person => [:privacy_setting],
  29 + :organization => [:privacy_setting, :location],
  30 + }
  31 +
  32 + MULTIPLE = {
  33 + :person => [:blogs, :image_galleries, :interests],
  34 + :organization => [:blogs, :image_galleries, :interests],
  35 + }
  36 +
  37 + CUSTOM_LABELS = {
  38 + :zip_code => _('ZIP code'),
  39 + :email => _('e-Mail'),
  40 + :jabber_id => _('Jabber'),
  41 + :birth_date => _('Date of birth'),
  42 + :created_at => _('Profile created at'),
  43 + :members_count => _('Members'),
  44 + }
  45 +
  46 + EXCEPTION = {
  47 + :person => [:image, :preferred_domain, :description, :tag_list],
  48 + :organization => [:image, :preferred_domain, :description, :tag_list, :address, :zip_code, :city, :state, :country, :district]
  49 + }
  50 +
  51 + def general_fields
  52 + categorized_fields = CATEGORY_MAP[kind].values.flatten
  53 + profile.class.fields.map(&:to_sym) - categorized_fields - EXCEPTION[kind]
  54 + end
  55 +
  56 + def kind
  57 + if profile.kind_of?(Person)
  58 + :person
  59 + else
  60 + :organization
  61 + end
  62 + end
  63 +
  64 + def title(field, entry = nil)
  65 + return self.send("#{field}_title", entry) if MULTIPLE[kind].include?(field) && entry.present?
  66 + CUSTOM_LABELS[field.to_sym] || field.to_s.humanize
  67 + end
  68 +
  69 + def display_field(field)
  70 + force = FORCE[kind].include?(field)
  71 + multiple = MULTIPLE[kind].include?(field)
4 72 unless force || profile.may_display_field_to?(field, user)
5 73 return ''
6 74 end
7   - value = profile.send(field)
  75 + value = begin profile.send(field) rescue nil end
  76 + p field
8 77 if !value.blank?
9   - if block_given?
10   - value = yield(value)
11   - end
12   - content_tag('tr', content_tag('td', title, :class => 'field-name') + content_tag('td', value))
  78 + entries = multiple ? value : [] << value
  79 + entries.map do |entry|
  80 + content = self.send("treat_#{field}", entry)
  81 + content_tag('tr', content_tag('td', title(field, entry), :class => 'field-name') + content_tag('td', content))
  82 + end.join("\n")
13 83 else
14 84 ''
15 85 end
16 86 end
17 87  
18   - def display_contact(profile)
19   - fields = []
20   - fields << display_field(_('Address:'), profile, :address).html_safe
21   - fields << display_field(_('ZIP code:'), profile, :zip_code).html_safe
22   - fields << display_field(_('Contact phone:'), profile, :contact_phone).html_safe
23   - fields << display_field(_('e-Mail:'), profile, :email) { |email| link_to_email(email) }.html_safe
24   - fields << display_field(_('Personal website:'), profile, :personal_website).html_safe
25   - fields << display_field(_('Jabber:'), profile, :jabber_id).html_safe
26   - if fields.reject!(&:blank?).empty?
27   - ''
28   - else
29   - content_tag('tr', content_tag('th', _('Contact'), { :colspan => 2 })) + fields.join.html_safe
  88 + def treat_email(email)
  89 + link_to_email(email)
  90 + end
  91 +
  92 + def treat_organization_website(url)
  93 + link_to(url, url)
  94 + end
  95 +
  96 + def treat_sex(gender)
  97 + { 'male' => _('Male'), 'female' => _('Female') }[gender]
  98 + end
  99 +
  100 + def treat_date(date)
  101 + puts date.inspect
  102 + show_date(date.to_date)
  103 + end
  104 + alias :treat_birth_date :treat_date
  105 + alias :treat_created_at :treat_date
  106 +
  107 + def treat_friends(friends)
  108 + link_to friends.count, :controller => 'profile', :action => 'friends'
  109 + end
  110 +
  111 + def treat_communities(communities)
  112 + link_to communities.count, :controller => "profile", :action => 'communities'
  113 + end
  114 +
  115 + def treat_enterprises(enterprises)
  116 + if environment.disabled?('disable_asset_enterprises')
  117 + link_to enterprises.count, :controller => "profile", :action => 'enterprises'
30 118 end
31 119 end
32 120  
33   - def display_work_info(profile)
34   - organization = display_field(_('Organization:'), profile, :organization)
35   - organization_site = display_field(_('Organization website:'), profile, :organization_website) { |url| link_to(url, url) }
36   - if organization.blank? && organization_site.blank?
37   - ''
  121 + def treat_members_count(count)
  122 + link_to count, :controller => 'profile', :action => 'members'
  123 + end
  124 +
  125 + def treat_products(products)
  126 + if profile.kind_of?(Enterprise) && profile.environment.enabled?('products_for_enterprises')
  127 + link_to _('Products/Services'), :controller => 'catalog', :action => 'index'
  128 + end
  129 + end
  130 +
  131 + def treat_admins(admins)
  132 + profile.admins.map { |admin| link_to(admin.short_name, admin.url)}.join(', ')
  133 + end
  134 +
  135 + def treat_blogs(blog)
  136 + p blog
  137 + link_to(n_('One post', '%{num} posts', blog.posts.published.count) % { :num => blog.posts.published.count }, blog.url)
  138 + end
  139 +
  140 + def treat_image_galleries(gallery)
  141 + p gallery
  142 + link_to(n_('One picture', '%{num} pictures', gallery.images.published.count) % { :num => gallery.images.published.count }, gallery.url)
  143 + end
  144 +
  145 + def treat_events(events)
  146 + link_to events.published.count, :controller => 'events', :action => 'events'
  147 + end
  148 +
  149 + def treat_tags(tags)
  150 + tag_cloud @tags, :id, { :action => 'tags' }, :max_size => 18, :min_size => 10
  151 + end
  152 +
  153 + def treat_interests(interest)
  154 + link_to interest.name, :controller => 'search', :action => 'category_index', :category_path => interest.explode_path
  155 + end
  156 +
  157 + def article_title(article)
  158 + article.name
  159 + end
  160 + alias :blogs_title :article_title
  161 + alias :image_galleries_title :article_title
  162 +
  163 + def interests_title(interest)
  164 + ''
  165 + end
  166 +
  167 + def method_missing(method, *args, &block)
  168 + if method.to_s =~ /^treat_(.+)$/
  169 + args[0]
  170 + elsif method.to_s =~ /^display_(.+)$/ && CATEGORY_MAP[kind].has_key?($1.to_sym)
  171 + category = $1.to_sym
  172 + fields = category == :general ? general_fields : CATEGORY_MAP[kind][category]
  173 + contents = []
  174 +
  175 + fields.each do |field|
  176 + contents << display_field(field).html_safe
  177 + end
  178 +
  179 + contents = contents.delete_if(&:blank?)
  180 +
  181 + unless contents.empty?
  182 + content_tag('tr', content_tag('th', title(category), { :colspan => 2 })) + contents.join.html_safe
  183 + else
  184 + ''
  185 + end
38 186 else
39   - content_tag('tr', content_tag('th', _('Work'), { :colspan => 2 })) + organization + organization_site
  187 + super
40 188 end
41 189 end
42 190  
... ...
app/views/profile/_common.html.erb
1 1 <% unless @action %>
2 2 <% cache_timeout(profile.cache_key + '-profile-general-info', 4.hours) do %>
3   - <tr>
4   - <th colspan='2'>
5   - <%= _('Content') %>
6   - </th>
7   - </tr>
8   -
9   - <% profile.blogs.each do |blog| %>
10   - <tr>
11   - <td><%= blog.name + ':' %></td>
12   - <td>
13   - <%= link_to(n_('One post', '%{num} posts', blog.posts.published.count) % { :num => blog.posts.published.count }, blog.url) %>
14   - </td>
15   - </tr>
16   - <% end %>
17   - <% profile.image_galleries.each do |gallery| %>
18   - <tr>
19   - <td><%= gallery.name + ':' %></td>
20   - <td>
21   - <%= link_to(n_('One picture', '%{num} pictures', gallery.images.published.count) % { :num => gallery.images.published.count }, gallery.url) %>
22   - </td>
23   - </tr>
24   - <% end %>
25   -
26   - <tr>
27   - <td><%= _('Events:') %></td>
28   - <td>
29   - <%= link_to profile.events.published.count, :controller => 'events', :action => 'events' %>
30   - </td>
31   - </tr>
32   - <tr>
33   - <td>
34   - <%= _('Tags:') %>
35   - </td>
36   - <td>
37   - <%= tag_cloud @tags, :id, { :action => 'tags' }, :max_size => 18, :min_size => 10%>
38   - </td>
39   - </tr>
  3 + <%= display_content %>
40 4  
41 5 <% if !environment.enabled?('disable_categories') && !profile.interests.empty? %>
42   - <tr>
43   - <th colspan='2'><%= _('Interests') %></th>
44   - </tr>
45   - <% profile.interests.each do |item| %>
46   - <tr>
47   - <td></td>
48   - <td><%= link_to item.name, :controller => 'search', :action => 'category_index', :category_path => item.explode_path %></td>
49   - </tr>
50   - <% end %>
  6 + <%= display_interests %>
51 7 <% end %>
  8 +
  9 + <%= display_general %>
52 10 <% end %>
53 11 <% end %>
... ...
app/views/profile/_organization_profile.html.erb
1 1 <table>
2   - <tr>
3   - <th colspan='2'><%= _('Basic information')%></th>
4   - </tr>
5   -
6   - <tr>
7   - <td class='field-name'><%= _('Members') %></td>
8   - <td>
9   - <%= link_to profile.members_count, :controller => 'profile', :action => 'members' %>
10   - </td>
11   - </tr>
12   -
13   - <%= display_field(_('Type:'), profile, :privacy_setting, true) %>
14   -
15   - <%= display_field(_('Location:'), profile, :location, true) %>
16   -
17   - <tr>
18   - <td class='field-name'><%= _('Profile created at:') %></td>
19   - <td><%= show_date(profile.created_at) %></td>
20   - </tr>
21   -
22   - <% if profile.kind_of?(Enterprise) && profile.environment.enabled?('products_for_enterprises') %>
23   - <tr>
24   - <td></td>
25   - <td>
26   - <%= link_to _('Products/Services'), :controller => 'catalog', :action => 'index' %>
27   - </td>
28   - </tr>
29   - <% end %>
30   -
31   - <tr>
32   - <td class='field-name'><%= _('Administrators:') %></td>
33   - <td>
34   - <%= profile.admins.map { |admin| link_to(admin.short_name, admin.url)}.join(', ') %>
35   - </td>
36   - </tr>
37   -
  2 + <%= display_basic_information %>
  3 + <%= display_contact %>
  4 + <%= display_economic %>
38 5 <%= render :partial => 'common' %>
39 6 </table>
... ...
app/views/profile/_person_profile.html.erb
1 1 <table>
2   - <tr>
3   - <th colspan='2'><%= _('Basic information')%></th>
4   - </tr>
5   - <%= display_field(_('Sex:'), profile, :sex) { |gender| { 'male' => _('Male'), 'female' => _('Female') }[gender] } %>
6   - <%= display_field(_('Date of birth:'), profile, :birth_date) { |date| show_date(date) }%>
7   - <%= display_field _('Location:'), profile, :location %>
8   -
9   - <%= display_field(_('Type:'), profile, :privacy_setting, true) %>
10   -
11   - <tr>
12   - <td class='field-name'><%= _('Profile created at:') %></td>
13   - <td><%= show_date(profile.created_at) %></td>
14   - </tr>
15   -
16   - <%= display_contact profile %>
  2 + <%= display_basic_information %>
  3 + <%= display_contact %>
  4 + <%= display_location %>
17 5  
18 6 <% cache_timeout(profile.relationships_cache_key, 4.hours) do %>
19   - <%= display_work_info profile %>
20   -
21   - <tr>
22   - <th colspan='2'><%= _('Network')%></th>
23   - </tr>
24   - <tr>
25   - <td><%= _('Friends') + ':' %></td>
26   - <td><%= link_to profile.friends.count, { :controller => 'profile', :action => 'friends' } %></td>
27   - </tr>
28   - <tr>
29   - <td><%= _('Communities') + ':' %></td>
30   - <td><%= link_to profile.communities.count, :controller => "profile", :action => 'communities' %></td>
31   - </tr>
32   - <% if environment.disabled?('disable_asset_enterprises') %>
33   - <tr id="person-profile-network-enterprises">
34   - <td><%= _('Enterprises') + ':' %></td>
35   - <td><%= link_to profile.enterprises.count, :controller => "profile", :action => 'enterprises' %></td>
36   - </tr>
37   - <% end %>
  7 + <%= display_work %>
  8 + <%= display_study %>
  9 + <%= display_network %>
38 10  
39 11 <%= render :partial => 'common' %>
40   -
41 12 <% end %>
42 13 </table>
43 14  
... ...
public/stylesheets/application.css
... ... @@ -242,10 +242,11 @@ table.noborder:hover td.selected, td.selected {
242 242 td .button {
243 243 background-color: transparent;
244 244 }
245   -td.field-name {
  245 +table.profile td.field-name {
246 246 width: 150px;
247 247 text-align: left;
248   - vertical-align: top;
  248 + vertical-align: middle;
  249 + padding-right: 5px;
249 250 }
250 251  
251 252 table.profile .ui-tabs .ui-tabs-panel {
... ...