Commit 7018c3d23b4667fac37cc34ad706eac182c57f37

Authored by Leandro Santos
2 parents 91109fe3 d2220530

Merge branches 'master' and 'hide_license' into hide_license

INSTALL.https.md
1 -Setup Noosfero to use HTTPS  
2 -=========================== 1 +# Setup Noosfero to use HTTPS
3 2
4 This document assumes that you have a fully and clean Noosfero 3 This document assumes that you have a fully and clean Noosfero
5 installation as explained at the `INSTALL.md` file. 4 installation as explained at the `INSTALL.md` file.
6 5
7 -SSL certificate  
8 -+++++++++++++++ 6 +## Creating a self-signed SSL certificate
9 7
10 You should get a valid SSL certificate, but if you want to test 8 You should get a valid SSL certificate, but if you want to test
11 your setup before, you could generate a self-signed certificate 9 your setup before, you could generate a self-signed certificate
@@ -17,99 +15,106 @@ as below: @@ -17,99 +15,106 @@ as below:
17 # openssl req -new -x509 -nodes -sha1 -days $[10*365] -key noosfero.key > noosfero.cert 15 # openssl req -new -x509 -nodes -sha1 -days $[10*365] -key noosfero.key > noosfero.cert
18 # cat noosfero.key noosfero.cert > noosfero.pem 16 # cat noosfero.key noosfero.cert > noosfero.pem
19 17
  18 +## Web server configuration
  19 +
20 There are two ways of using SSL with Noosfero: 1) If you are not using 20 There are two ways of using SSL with Noosfero: 1) If you are not using
21 Varnish; and 2) If you are using Varnish. 21 Varnish; and 2) If you are using Varnish.
22 22
23 -1) If you are are not using Varnish  
24 -+++++++++++++++++++++++++++++++++++ 23 +### 1) If you are are not using Varnish
25 24
26 Simply do a redirect in apache to force all connections with SSL: 25 Simply do a redirect in apache to force all connections with SSL:
27 26
28 - <VirtualHost *:8080>  
29 - ServerName test.stoa.usp.br  
30 -  
31 - Redirect / https://example.com/  
32 - </VirtualHost> 27 +```
  28 +<VirtualHost *:8080>
  29 + ServerName test.stoa.usp.br
  30 + Redirect / https://example.com/
  31 +</VirtualHost>
  32 +```
33 33
34 And set a vhost to receive then: 34 And set a vhost to receive then:
35 35
36 - <VirtualHost *:443>  
37 - ServerName example.com  
38 -  
39 - SSLEngine On  
40 - SSLCertificateFile /etc/ssl/certs/cert.pem  
41 - SSLCertificateKeyFile /etc/ssl/private/cert.key  
42 -  
43 - Include /etc/noosfero/apache/virtualhost.conf  
44 - </VirtualHost> 36 +```
  37 +<VirtualHost *:443>
  38 + ServerName example.com
  39 + SSLEngine On
  40 + SSLCertificateFile /etc/ssl/certs/cert.pem
  41 + SSLCertificateKeyFile /etc/ssl/private/cert.key
  42 + Include /etc/noosfero/apache/virtualhost.conf
  43 +</VirtualHost>
  44 +```
45 45
46 Be aware that if you had configured varnish, the requests won't reach 46 Be aware that if you had configured varnish, the requests won't reach
47 it with this configuration. 47 it with this configuration.
48 48
49 -2) If you are using Varnish  
50 -+++++++++++++++++++++++++++  
51 -  
52 -Varnish isn't able to communicate with the SSL protocol, so we will  
53 -need some one who do this and Pound[1] can do the job. In order to  
54 -install it in Debian based systems: 49 +### 2) If you are using Varnish
55 50
56 - $ sudo apt-get install pound 51 +Varnish isn't able to communicate with the SSL protocol, so we will need some
  52 +one else who do this and [Pound](http://www.apsis.ch/pound) can do the job. In
  53 +order to install it in Debian based systems:
57 54
58 -Set Varnish to listen in other port than 80: 55 +```
  56 +$ sudo apt-get install pound
  57 +```
59 58
60 -/etc/defaults/varnish  
61 ---------------------- 59 +Set Varnish to listen in other port than 80 in `/etc/defaults/varnish`:
62 60
63 - DAEMON_OPTS="-a localhost:6081 \  
64 - -T localhost:6082 \  
65 - -f /etc/varnish/default.vcl \  
66 - -S /etc/varnish/secret \  
67 - -s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G" 61 +```
  62 +DAEMON_OPTS="-a localhost:6081 \
  63 + -T localhost:6082 \
  64 + -f /etc/varnish/default.vcl \
  65 + -S /etc/varnish/secret \
  66 + -s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G"
  67 +```
68 68
69 Configure Pound: 69 Configure Pound:
70 70
71 - # cp /usr/share/noosfero/etc/pound.cfg /etc/pound/  
72 -  
73 -Edit /etc/pound.cfg and set the IP and domain of your server. 71 +```
  72 +# cp /usr/share/noosfero/etc/pound.cfg /etc/pound/
  73 +```
74 74
75 -Configure Pound to start at system initialization: 75 +Edit `/etc/pound.cfg` and set the IP and domain of your server.
76 76
77 -/etc/default/pound 77 +Configure Pound to start at system initialization. At `/etc/default/pound`:
78 ------------------ 78 ------------------
79 79
80 - startup=1 80 +```
  81 +startup=1
  82 +```
81 83
82 -Set Apache to only listen to localhost: 84 +Set Apache to only listen to localhost, at `/etc/apache2/ports.conf`:
83 85
84 -/etc/apache2/ports.conf  
85 ------------------------  
86 -  
87 - Listen 127.0.0.1:8080 86 +```
  87 +Listen 127.0.0.1:8080
  88 +```
88 89
89 Restart the services: 90 Restart the services:
90 91
91 - $ sudo service apache2 restart  
92 - $ sudo service varnish restart 92 +```
  93 +$ sudo service apache2 restart
  94 +$ sudo service varnish restart
  95 +```
93 96
94 Start pound: 97 Start pound:
95 98
96 - $ sudo service pound start  
97 -  
98 -[1] http://www.apsis.ch/pound 99 +```
  100 +$ sudo service pound start
  101 +```
99 102
100 -Noosfero XMPP chat  
101 -++++++++++++++++++ 103 +## Noosfero XMPP chat
102 104
103 If you want to use chat over HTTPS, then you should add the domain 105 If you want to use chat over HTTPS, then you should add the domain
104 -and IP of your server in the /etc/hosts file, example: 106 +and IP of your server in the /etc/hosts file, example
105 107
106 -/etc/hosts  
107 ----------- 108 +`/etc/hosts:`
108 109
109 - 192.168.1.86 mydomain.example.com 110 +```
  111 +192.168.1.86 mydomain.example.com
  112 +```
110 113
111 -Also, it's recomended that you remove lines above from the file 114 +Also, it's recomended that you remove the lines below from the file
112 `/etc/apache2/sites-enabled/noosfero`: 115 `/etc/apache2/sites-enabled/noosfero`:
113 116
114 - RewriteEngine On  
115 - Include /usr/share/noosfero/util/chat/apache/xmpp.conf 117 +```
  118 +RewriteEngine On
  119 +Include /usr/share/noosfero/util/chat/apache/xmpp.conf
  120 +```
INSTALL.locales.md 0 → 100644
@@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
  1 +Using custom locales
  2 +====================
  3 +
  4 +Personalized translations go into the `config/custom_locales/` directory.
  5 +Custom locales can be identified by the rails environment, schema name in a
  6 +multitenancy setup or domain name until the first dot (e.g env1.coop.br for the
  7 +example below).
  8 +
  9 +Currently, the only filename prefix for the localization file which is
  10 +processed is "environment". For instance, a POT file would be called
  11 +"environment.pot".
  12 +
  13 +The structure of an environment named env1 with custom translations for both
  14 +Portuguese and Spanish and an environment named env2 with custom Russian
  15 +translation would be:
  16 +
  17 + config/
  18 + custom_locales/
  19 + env1/
  20 + environment.pot
  21 + pt/
  22 + environment.po
  23 + es/
  24 + environment.po
  25 + env2/
  26 + environment.pot
  27 + ru/
  28 + environment.po
  29 +
app/controllers/application_controller.rb
@@ -127,6 +127,9 @@ class ApplicationController &lt; ActionController::Base @@ -127,6 +127,9 @@ class ApplicationController &lt; ActionController::Base
127 127
128 # TODO: move this logic somewhere else (Domain class?) 128 # TODO: move this logic somewhere else (Domain class?)
129 def detect_stuff_by_domain 129 def detect_stuff_by_domain
  130 + # Sets text domain based on request host for custom internationalization
  131 + FastGettext.text_domain = Domain.custom_locale(request.host)
  132 +
130 @domain = Domain.find_by_name(request.host) 133 @domain = Domain.find_by_name(request.host)
131 if @domain.nil? 134 if @domain.nil?
132 @environment = Environment.default 135 @environment = Environment.default
app/helpers/layout_helper.rb
@@ -9,6 +9,24 @@ module LayoutHelper @@ -9,6 +9,24 @@ module LayoutHelper
9 (!profile.nil? && profile.is_on_homepage?(request.path,@page) ? " profile-homepage" : "") 9 (!profile.nil? && profile.is_on_homepage?(request.path,@page) ? " profile-homepage" : "")
10 end 10 end
11 11
  12 + def html_tag_classes
  13 + [
  14 + body_classes, (
  15 + profile.blank? ? nil : [
  16 + 'profile-type-is-' + profile.class.name.downcase,
  17 + 'profile-name-is-' + profile.identifier,
  18 + ]
  19 + ), 'theme-' + current_theme,
  20 + @plugins.dispatch(:html_tag_classes).map do |content|
  21 + if content.respond_to?(:call)
  22 + instance_exec(&content)
  23 + else
  24 + content.html_safe
  25 + end
  26 + end
  27 + ].flatten.compact.join(' ')
  28 + end
  29 +
12 def noosfero_javascript 30 def noosfero_javascript
13 plugins_javascripts = @plugins.map { |plugin| [plugin.js_files].flatten.map { |js| plugin.class.public_path(js) } }.flatten 31 plugins_javascripts = @plugins.map { |plugin| [plugin.js_files].flatten.map { |js| plugin.class.public_path(js) } }.flatten
14 32
app/models/domain.rb
@@ -92,4 +92,11 @@ class Domain &lt; ActiveRecord::Base @@ -92,4 +92,11 @@ class Domain &lt; ActiveRecord::Base
92 @hosting = {} 92 @hosting = {}
93 end 93 end
94 94
  95 + # Detects a domain's custom text domain chain if available based on a domain
  96 + # served on multitenancy configuration or a registered domain.
  97 + def self.custom_locale(domainname)
  98 + domain = Noosfero::MultiTenancy.mapping[domainname] || domainname[/(.*?)\./,1]
  99 + FastGettext.translation_repositories.keys.include?(domain) ? domain : FastGettext.default_text_domain
  100 + end
  101 +
95 end 102 end
app/views/content_viewer/view_page.html.erb
@@ -70,37 +70,36 @@ @@ -70,37 +70,36 @@
70 70
71 <%= @plugins.dispatch(:article_extra_contents, @page).collect { |content| instance_exec(&content) }.join("") %> 71 <%= @plugins.dispatch(:article_extra_contents, @page).collect { |content| instance_exec(&content) }.join("") %>
72 72
73 -<div class="comments" id="comments_list">  
74 -  
75 - <% if @page.accept_comments? || @comments_count > 0 %> 73 +<% if @page.accept_comments? || @comments_count > 0 %>
  74 + <div class="comments" id="comments_list">
76 <h3 <%= 'class="no-comments-yet"' if @comments_count == 0 %>> 75 <h3 <%= 'class="no-comments-yet"' if @comments_count == 0 %>>
77 <%= display_number_of_comments(@comments_count) %> 76 <%= display_number_of_comments(@comments_count) %>
78 </h3> 77 </h3>
79 - <% end %>  
80 78
81 - <% if @comments.present? && @comments.count > 1 %>  
82 - <%= link_to(_('Post a comment'), '#', :class => 'display-comment-form', :id => 'top-post-comment-button', :onclick => "jQuery('#page-comment-form .display-comment-form').first().click();") if @page.accept_comments? %> 79 + <% if @comments.present? && @comments.count > 1 %>
  80 + <%= link_to(_('Post a comment'), '#', :class => 'display-comment-form', :id => 'top-post-comment-button', :onclick => "jQuery('#page-comment-form .display-comment-form').first().click();") if @page.accept_comments? %>
  81 +
  82 + <%= hidden_field_tag("page_url", url_for(:controller=>'content_viewer', :action=>'view_page', :profile=>profile.identifier, :page => @page.explode_path)) %>
  83 + <%= javascript_include_tag "comment_order.js" %>
  84 + <div class="comment-order">
  85 + <%= form_tag({:controller=>'content_viewer' , :action=>'view_page'}, {:method=>'get', :id=>"form_order"}) do %>
  86 + <%= select_tag 'comment_order', options_for_select({_('Oldest first')=>'oldest', _('Newest first')=>'newest'}, @comment_order) %>
  87 + <% end %>
  88 + </div>
  89 + <% end %>
83 90
84 - <%= hidden_field_tag("page_url", url_for(:controller=>'content_viewer', :action=>'view_page', :profile=>profile.identifier, :page => @page.explode_path)) %>  
85 - <%= javascript_include_tag "comment_order.js" %>  
86 - <div class="comment-order">  
87 - <%= form_tag({:controller=>'content_viewer' , :action=>'view_page'}, {:method=>'get', :id=>"form_order"}) do %>  
88 - <%= select_tag 'comment_order', options_for_select({_('Oldest first')=>'oldest', _('Newest first')=>'newest'}, @comment_order) %> 91 + <ul class="article-comments-list">
  92 + <% if @comments.present? %>
  93 + <%= render :partial => 'comment/comment', :collection => @comments %>
  94 + <%= pagination_links @comments, :param_name => 'comment_page' %>
89 <% end %> 95 <% end %>
90 - </div>  
91 - <% end %> 96 + </ul>
92 97
93 - <ul class="article-comments-list">  
94 - <% if @comments.present? %>  
95 - <%= render :partial => 'comment/comment', :collection => @comments %>  
96 - <%= pagination_links @comments, :param_name => 'comment_page' %> 98 + <% if @page.accept_comments? %>
  99 + <div id='page-comment-form' class='page-comment-form'><%= render :partial => 'comment/comment_form', :locals =>{:url => {:controller => :comment, :action => :create}, :display_link => true, :cancel_triggers_hide => true}%></div>
97 <% end %> 100 <% end %>
98 - </ul>  
99 -  
100 - <% if @page.accept_comments? %>  
101 - <div id='page-comment-form' class='page-comment-form'><%= render :partial => 'comment/comment_form', :locals =>{:url => {:controller => :comment, :action => :create}, :display_link => true, :cancel_triggers_hide => true}%></div>  
102 - <% end %>  
103 -</div><!-- end class="comments" --> 101 + </div><!-- end class="comments" -->
  102 +<% end %>
104 103
105 </div><!-- end id="article" --> 104 </div><!-- end id="article" -->
106 <%= add_zoom_to_article_images %> 105 <%= add_zoom_to_article_images %>
app/views/layouts/application-ng.html.erb
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2 -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%= html_language %>" lang="<%= html_language %>"> 2 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%= html_language %>" lang="<%= html_language %>" class="<%= h html_tag_classes %>">
3 <head> 3 <head>
4 <title><%= h page_title %></title> 4 <title><%= h page_title %></title>
5 <%= yield(:feeds) %> 5 <%= yield(:feeds) %>
app/views/layouts/application.html.erb
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2 -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%= html_language %>" lang="<%= html_language %>"> 2 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%= html_language %>" lang="<%= html_language %>" class="<%= h html_tag_classes %>">
3 <head> 3 <head>
4 <title><%= h page_title %></title> 4 <title><%= h page_title %></title>
5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
config/initializers/passenger.rb
@@ -3,7 +3,7 @@ if defined? PhusionPassenger @@ -3,7 +3,7 @@ if defined? PhusionPassenger
3 # from http://russbrooks.com/2010/10/20/rails-cache-memcache-on-passenger-with-smart-spawning 3 # from http://russbrooks.com/2010/10/20/rails-cache-memcache-on-passenger-with-smart-spawning
4 PhusionPassenger.on_event :starting_worker_process do |forked| 4 PhusionPassenger.on_event :starting_worker_process do |forked|
5 if forked 5 if forked
6 - Rails.cache.instance_variable_get(:@data).reset if Rails.cache.class == ActiveSupport::Cache::MemCacheStore 6 + Rails.cache.instance_variable_get(:@data).reset if Rails.cache.class.name == 'ActiveSupport::Cache::MemCacheStore'
7 end 7 end
8 end 8 end
9 end 9 end
db/migrate/20150122165042_change_address_type_to_text_in_external_feed.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +class ChangeAddressTypeToTextInExternalFeed < ActiveRecord::Migration
  2 + def up
  3 + change_column :external_feeds, :address, :text
  4 + end
  5 +
  6 + def down
  7 + change_column :external_feeds, :address, :string
  8 + end
  9 +end
@@ -316,7 +316,7 @@ ActiveRecord::Schema.define(:version =&gt; 20150113131617) do @@ -316,7 +316,7 @@ ActiveRecord::Schema.define(:version =&gt; 20150113131617) do
316 create_table "external_feeds", :force => true do |t| 316 create_table "external_feeds", :force => true do |t|
317 t.string "feed_title" 317 t.string "feed_title"
318 t.datetime "fetched_at" 318 t.datetime "fetched_at"
319 - t.string "address" 319 + t.text "address"
320 t.integer "blog_id", :null => false 320 t.integer "blog_id", :null => false
321 t.boolean "enabled", :default => true, :null => false 321 t.boolean "enabled", :default => true, :null => false
322 t.boolean "only_once", :default => true, :null => false 322 t.boolean "only_once", :default => true, :null => false
@@ -5,7 +5,7 @@ TimeOut 300 @@ -5,7 +5,7 @@ TimeOut 300
5 Control "/var/run/pound/poundctl.socket" 5 Control "/var/run/pound/poundctl.socket"
6 6
7 ListenHTTP 7 ListenHTTP
8 - Address 192.168.1.86 8 + Address 0.0.0.0
9 Port 80 9 Port 80
10 xHTTP 1 10 xHTTP 1
11 # uncomment code above if you are using chat 11 # uncomment code above if you are using chat
@@ -22,7 +22,7 @@ ListenHTTP @@ -22,7 +22,7 @@ ListenHTTP
22 End 22 End
23 23
24 ListenHTTPS 24 ListenHTTPS
25 - Address 192.168.1.86 25 + Address 0.0.0.0
26 Port 443 26 Port 443
27 Cert "/etc/noosfero/ssl/noosfero.pem" 27 Cert "/etc/noosfero/ssl/noosfero.pem"
28 Ciphers "ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM" 28 Ciphers "ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM"
lib/noosfero/i18n.rb
@@ -9,7 +9,8 @@ class Object @@ -9,7 +9,8 @@ class Object
9 end 9 end
10 10
11 11
12 -custom_locale_dir = Rails.root.join('custom_locales', Rails.env) 12 +# Adds custom locales for a whole environment
  13 +custom_locale_dir = Rails.root.join('config', 'custom_locales', Rails.env)
13 repos = [] 14 repos = []
14 if File.exists?(custom_locale_dir) 15 if File.exists?(custom_locale_dir)
15 repos << FastGettext::TranslationRepository.build('environment', :type => 'po', :path => custom_locale_dir) 16 repos << FastGettext::TranslationRepository.build('environment', :type => 'po', :path => custom_locale_dir)
@@ -29,3 +30,15 @@ end @@ -29,3 +30,15 @@ end
29 30
30 FastGettext.add_text_domain 'noosfero', :type => :chain, :chain => repos 31 FastGettext.add_text_domain 'noosfero', :type => :chain, :chain => repos
31 FastGettext.default_text_domain = 'noosfero' 32 FastGettext.default_text_domain = 'noosfero'
  33 +
  34 +# Adds custom locales for specific domains; Domains are identified by the
  35 +# sequence before the first dot, while tenants are identified by schema name
  36 +hosted_environments = Noosfero::MultiTenancy.mapping.values
  37 +hosted_environments += Domain.all.map { |domain| domain.name[/(.*?)\./,1] } if Domain.table_exists?
  38 +
  39 +hosted_environments.uniq.each do |env|
  40 + custom_locale_dir = Rails.root.join('config', 'custom_locales', env)
  41 + if File.exists?(custom_locale_dir)
  42 + FastGettext.add_text_domain(env, :type => :chain, :chain => [FastGettext::TranslationRepository.build('environment', :type => 'po', :path => custom_locale_dir)] + repos)
  43 + end
  44 +end
lib/noosfero/plugin.rb
@@ -560,6 +560,12 @@ class Noosfero::Plugin @@ -560,6 +560,12 @@ class Noosfero::Plugin
560 [] 560 []
561 end 561 end
562 562
  563 + # -> Adds css class to <html> tag
  564 + # returns = ['class1', 'class2']
  565 + def html_tag_classes
  566 + nil
  567 + end
  568 +
563 # -> Adds additional blocks to profiles and environments. 569 # -> Adds additional blocks to profiles and environments.
564 # Your plugin must implements a class method called 'extra_blocks' 570 # Your plugin must implements a class method called 'extra_blocks'
565 # that returns a hash with the following syntax. 571 # that returns a hash with the following syntax.
plugins/classify_members/README 0 → 100644
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +Classify Members
  2 +Plugin that allows the association of communities with types of user profiles to classify and highlight them within the environment.
  3 +
  4 + * In a school env we want to visit a profile and know it is a teacher or a student.
  5 + * In a enterprise env we want to view a forum comment and know it comes from a director or a lawyer.
  6 +
  7 +This plugin will allow the admin to select communities for classification. When the user enter in one of these communities, its profile pages comes with a community related class allowing the theme to adapt it. Also the picture block and other places where the user picture is displayed will have labels like "Teacher" or "Lawyer", also themable with css.
plugins/classify_members/controllers/classify_members_plugin_admin_controller.rb 0 → 100644
@@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
  1 +class ClassifyMembersPluginAdminController < PluginsController
  2 + def index
  3 + @settings ||= Noosfero::Plugin::Settings.new(
  4 + environment, ClassifyMembersPlugin, params[:settings]
  5 + )
  6 +
  7 + if request.post?
  8 + @settings.save!
  9 + redirect_to :controller => 'plugins', :action => 'index'
  10 + end
  11 + end
  12 +end
plugins/classify_members/lib/classify_members_plugin.rb 0 → 100644
@@ -0,0 +1,78 @@ @@ -0,0 +1,78 @@
  1 +class ClassifyMembersPlugin < Noosfero::Plugin
  2 + def self.plugin_name
  3 + _("Classify Members")
  4 + end
  5 +
  6 + def self.plugin_description
  7 + _("Allows the association of communities with types of user profiles to classify and highlight them within the environment.")
  8 + end
  9 +
  10 + def html_tag_classes
  11 + plugin = self
  12 + lambda do
  13 + if profile && profile.person?
  14 + plugin.find_community(profile).map do |community, community_label|
  15 + 'member-of-' + community.identifier
  16 + end
  17 + end
  18 + end
  19 + end
  20 +
  21 + def body_beginning
  22 + plugin = self
  23 + lambda do
  24 + if profile && profile.person?
  25 + javascript_tag("
  26 + jQuery(function(){
  27 + jQuery('<div class=\"cmm-member-tags\"><ul class=\"cmm-member-list\"></ul></div>').insertBefore(
  28 + '.profile-image-block .vcard .profile-info-options'
  29 + );
  30 + });\n" +
  31 + plugin.find_community(profile).map do |community, community_label|
  32 + "jQuery(function(){
  33 + jQuery('.cmm-member-list').prepend(
  34 + '<li>' + '#{link_to '<i></i>' + community_label,
  35 + {:profile => community.identifier, :controller => 'profile', :action => 'members'},
  36 + :class => 'member-of-' + community.identifier}' + '</li>'
  37 + );
  38 + });"
  39 + end.join("\n")
  40 + )
  41 + else
  42 + '<!-- ClassCommunityPlugin not in a profile -->'
  43 + end
  44 + end
  45 + end
  46 +
  47 + def settings
  48 + @settings ||= Noosfero::Plugin::Settings.new(
  49 + context.environment, ClassifyMembersPlugin
  50 + )
  51 + end
  52 +
  53 + def communities
  54 + communities = settings.communities
  55 +
  56 + return [] if communities.blank?
  57 +
  58 + communities.split(/\s*\n\s*/).map do |community|
  59 + community = community.split(/\s*:\s*/)
  60 + community[0] = Profile[community[0].to_s.strip]
  61 + community[1] = community[1].to_s.strip
  62 +
  63 + if community[0].blank?
  64 + nil
  65 + else
  66 + community[1] = community[0].name if community[1].blank?
  67 + community
  68 + end
  69 + end.compact
  70 + end
  71 +
  72 + def find_community(profile)
  73 + communities.map do |community|
  74 + profile.is_member_of?(community[0]) ? community : nil
  75 + end.compact
  76 + end
  77 +
  78 +end
plugins/classify_members/test/functional/classify_members_plugin_test.rb 0 → 100644
@@ -0,0 +1,45 @@ @@ -0,0 +1,45 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +
  3 +# Re-raise errors caught by the controller.
  4 +class HomeController
  5 + def rescue_action(e)
  6 + raise e
  7 + end
  8 +end
  9 +
  10 +class ProfileControllerTest < ActionController::TestCase
  11 + def setup
  12 + @env = Environment.default
  13 + @env.enable_plugin('ClassifyMembersPlugin')
  14 +
  15 + @p1 = fast_create(Person, :environment_id => @env.id)
  16 + @p2 = fast_create(Person, :environment_id => @env.id)
  17 + @c1 = fast_create(Community, :environment_id => @env.id)
  18 + @c2 = fast_create(Community, :environment_id => @env.id)
  19 +
  20 + # Register cassification communities:
  21 + ClassifyMembersPlugin.new(self).settings.communities = "#{@c1.identifier}: Test-Tag"
  22 + @env.save!
  23 +
  24 + @c1.add_member @p1
  25 + @c2.add_member @p1
  26 + @c2.add_member @p2
  27 + end
  28 +
  29 + def environment
  30 + @env
  31 + end
  32 +
  33 + should 'add classification to the <html>' do
  34 + get :index, :profile => @p1.identifier
  35 +
  36 + assert_select 'html.member-of-' + @c1.identifier
  37 + assert_select 'html.member-of-' + @c2.identifier, false
  38 + end
  39 +
  40 + should 'not add classification to a non member' do
  41 + get :index, :profile=>@p2.identifier
  42 +
  43 + assert_select 'html.member-of-' + @c1.identifier, false
  44 + end
  45 +end
plugins/classify_members/test/unit/classify_members_plugin_test.rb 0 → 100644
@@ -0,0 +1,46 @@ @@ -0,0 +1,46 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +
  3 +class ClassifyMembersPluginTest < ActiveSupport::TestCase
  4 + def setup
  5 + @env = fast_create(Environment)
  6 + @p1 = fast_create(Person, :environment_id => @env.id)
  7 + @c1 = fast_create(Community, :environment_id => @env.id)
  8 + @c2 = fast_create(Community, :environment_id => @env.id)
  9 + @c3 = fast_create(Community, :environment_id => @env.id)
  10 + @plugin = ClassifyMembersPlugin.new self
  11 + end
  12 +
  13 + def environment
  14 + @env
  15 + end
  16 +
  17 + should 'not crash for nil setting' do
  18 + assert_equal [], @plugin.find_community(@p1)
  19 + end
  20 +
  21 + should 'list all classification communities' do
  22 + @plugin.settings.communities = "
  23 + #{@c1.identifier}: Tag1
  24 + #{@c2.identifier}
  25 + "
  26 + @env.save!
  27 +
  28 + assert_equal [[@c1, 'Tag1'], [@c2, @c2.name]], @plugin.communities
  29 + end
  30 +
  31 + should 'list the classification communities for a person' do
  32 + @c1.add_member @p1
  33 + @c2.add_member @p1
  34 + @p1.stubs(:is_member_of?).returns(false)
  35 + @p1.stubs(:is_member_of?).with(@c1).returns(true)
  36 + @p1.stubs(:is_member_of?).with(@c2).returns(true)
  37 + @plugin.settings.communities = "
  38 + #{@c1.identifier}: Tag1
  39 + #{@c2.identifier}: Tag2
  40 + #{@c3.identifier}: Tag3
  41 + "
  42 + @env.save!
  43 +
  44 + assert_equal [[@c1, 'Tag1'], [@c2, 'Tag2']], @plugin.find_community(@p1)
  45 + end
  46 +end
plugins/classify_members/views/classify_members_plugin_admin/index.html.erb 0 → 100644
@@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
  1 +<h1><%= _("Classify Members Plugin's config") %></h1>
  2 +
  3 +<%= form_for(:settings) do |f| %>
  4 +
  5 + <%= labelled_form_field _('Communities to classify people:'), f.text_area(:communities) %>
  6 +
  7 + <p><%=
  8 + _('List of community identifiers and the applicable person label, line by line.')
  9 + %></p>
  10 +
  11 + <fieldset>
  12 + <legend><%=_('Example:')%></legend>
  13 + <%=_('teachers: Teacher')%> <br>
  14 + <%=_('office-lawyers: Lawyer')%> <br>
  15 + <%=_('salvador-ba: Soteropolitano')%>
  16 + </fieldset>
  17 +
  18 + <% button_bar do %>
  19 + <%= submit_button(:save, _('Save'), :cancel => {:controller => 'plugins', :action => 'index'}) %>
  20 + <% end %>
  21 +
  22 +<% end %>
script/noosfero-plugins
@@ -177,7 +177,7 @@ _new(){ @@ -177,7 +177,7 @@ _new(){
177 mkdir "$target" 177 mkdir "$target"
178 178
179 plugin_name=$(echo "$plugin" | sed -e 's/^./\u&/; s/_\(.\)/\u\1/g') 179 plugin_name=$(echo "$plugin" | sed -e 's/^./\u&/; s/_\(.\)/\u\1/g')
180 - for source_file in $(find "$template" -type f); do 180 + for source_file in $(find "$template" -type f -and '(' -not -name '*.po' -and -not -name '*.mo' ')'); do
181 target_file=$(echo "$source_file" | sed -e "s/template/$plugin/g") 181 target_file=$(echo "$source_file" | sed -e "s/template/$plugin/g")
182 mkdir -p $(dirname "$target_file") 182 mkdir -p $(dirname "$target_file")
183 sed "s/TemplatePlugin/${plugin_name}Plugin/g" "$source_file" > "$target_file" 183 sed "s/TemplatePlugin/${plugin_name}Plugin/g" "$source_file" > "$target_file"
test/functional/application_controller_test.rb
@@ -498,51 +498,6 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -498,51 +498,6 @@ class ApplicationControllerTest &lt; ActionController::TestCase
498 498
499 end 499 end
500 500
501 - should 'do not duplicate plugin filters' do  
502 -  
503 - class FilterPlugin < Noosfero::Plugin  
504 - def test_controller_filters  
505 - { :type => 'before_filter',  
506 - :method_name => 'filter_plugin',  
507 - :options => {:only => 'some_method'},  
508 - :block => lambda {} }  
509 - end  
510 - end  
511 - Noosfero::Plugin.stubs(:all).returns([FilterPlugin.name])  
512 -  
513 - Noosfero::Plugin.load_plugin_filters(FilterPlugin)  
514 - Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([FilterPlugin.new])  
515 -  
516 - get :index  
517 - get :index  
518 - assert_equal 1, @controller.class._process_action_callbacks.select{|c| c.filter == :application_controller_test_filter_plugin_filter_plugin}.count  
519 - end  
520 -  
521 - should 'do not call plugin filter block on a environment that this plugin is not enabled' do  
522 -  
523 - class OtherFilterPlugin < Noosfero::Plugin  
524 - def test_controller_filters  
525 - { :type => 'before_filter',  
526 - :method_name => 'filter_plugin',  
527 - :options => {:only => 'some_method'},  
528 - :block => proc {'plugin block called'} }  
529 - end  
530 - end  
531 - Noosfero::Plugin.stubs(:all).returns([OtherFilterPlugin.name])  
532 -  
533 - Noosfero::Plugin.load_plugin_filters(OtherFilterPlugin)  
534 - environment1 = fast_create(Environment, :name => 'test environment')  
535 - environment1.enable_plugin(OtherFilterPlugin.name)  
536 - environment2 = fast_create(Environment, :name => 'other test environment')  
537 -  
538 - @controller.stubs(:environment).returns(environment1)  
539 - get :index  
540 - assert_equal 'plugin block called', @controller.application_controller_test_other_filter_plugin_filter_plugin  
541 -  
542 - @controller.stubs(:environment).returns(environment2)  
543 - assert_equal nil, @controller.application_controller_test_other_filter_plugin_filter_plugin  
544 - end  
545 -  
546 should 'display meta tags for social media' do 501 should 'display meta tags for social media' do
547 get :index 502 get :index
548 assert_tag :tag => 'meta', :attributes => { :name => 'twitter:card', :value => 'summary' } 503 assert_tag :tag => 'meta', :attributes => { :name => 'twitter:card', :value => 'summary' }
test/functional/home_controller_test.rb
@@ -130,4 +130,36 @@ class HomeControllerTest &lt; ActionController::TestCase @@ -130,4 +130,36 @@ class HomeControllerTest &lt; ActionController::TestCase
130 assert_no_tag :tag => 'a', :attributes => {:href => '/account/signup'} 130 assert_no_tag :tag => 'a', :attributes => {:href => '/account/signup'}
131 end 131 end
132 132
  133 + should 'add class to the <html>' do
  134 + get :index
  135 +
  136 + # Where am i?
  137 + assert_select 'html.controller-home.action-home-index'
  138 + # What is the current layout?
  139 + assert_select 'html.template-default.theme-noosfero'
  140 + end
  141 +
  142 + should 'plugins add class to the <html>' do
  143 + class Plugin1 < Noosfero::Plugin
  144 + def html_tag_classes
  145 + lambda { ['t1', 't2'] }
  146 + end
  147 + end
  148 +
  149 + class Plugin2 < Noosfero::Plugin
  150 + def html_tag_classes
  151 + 'test'
  152 + end
  153 + end
  154 +
  155 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
  156 + Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new])
  157 +
  158 + get :index
  159 +
  160 + # Where am i?
  161 + assert_select 'html.controller-home.action-home-index'
  162 + # There are plugin classes?
  163 + assert_select 'html.t1.t2.test'
  164 + end
133 end 165 end