Commit d08608afec164fe6dd991f8a0bbc487825b94600

Authored by Rodrigo Souto
2 parents 62d3dca2 24066ab3

Merge remote-tracking branch 'origin' into stable

Conflicts:
	app/views/content_viewer/view_page.rhtml
	app/views/profile_editor/index.rhtml
	debian/changelog
	lib/noosfero.rb
	plugins/comment_group/test/functional/comment_group_plugin_profile_controller_test.rb
Showing 411 changed files with 25827 additions and 10014 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 411 files displayed.

@@ -7,6 +7,7 @@ Developers @@ -7,6 +7,7 @@ Developers
7 ========== 7 ==========
8 8
9 Alan Freihof Tygel <alantygel@gmail.com> 9 Alan Freihof Tygel <alantygel@gmail.com>
  10 +alcampelo <alcampelo@alcampelo.(none)>
10 Alessandro Palmeira <alessandro.palmeira@gmail.com> 11 Alessandro Palmeira <alessandro.palmeira@gmail.com>
11 Alessandro Palmeira + Caio C. Salgado <alessandro.palmeira@gmail.com> 12 Alessandro Palmeira + Caio C. Salgado <alessandro.palmeira@gmail.com>
12 Alessandro Palmeira + Caio Salgado <alessandro.palmeira@gmail.com> 13 Alessandro Palmeira + Caio Salgado <alessandro.palmeira@gmail.com>
@@ -38,6 +39,7 @@ Alessandro Palmeira + João M. M. Silva &lt;alessandro.palmeira@gmail.com&gt; @@ -38,6 +39,7 @@ Alessandro Palmeira + João M. M. Silva &lt;alessandro.palmeira@gmail.com&gt;
38 Alessandro Palmeira + Paulo Meirelles <alessandro.palmeira@gmail.com> 39 Alessandro Palmeira + Paulo Meirelles <alessandro.palmeira@gmail.com>
39 Alessandro Palmeira + Paulo Meirelles + João M. M. da Silva <alessandro.palmeira@gmail.com> 40 Alessandro Palmeira + Paulo Meirelles + João M. M. da Silva <alessandro.palmeira@gmail.com>
40 Alessandro Palmeira + Rafael Manzo <alessandro.palmeira@gmail.com> 41 Alessandro Palmeira + Rafael Manzo <alessandro.palmeira@gmail.com>
  42 +Ana Losnak <analosnak@gmail.com>
41 Antonio Terceiro + Carlos Morais <terceiro@colivre.coop.br> 43 Antonio Terceiro + Carlos Morais <terceiro@colivre.coop.br>
42 Antonio Terceiro + Paulo Meirelles <terceiro@colivre.coop.br> 44 Antonio Terceiro + Paulo Meirelles <terceiro@colivre.coop.br>
43 Antonio Terceiro <terceiro@colivre.coop.br> 45 Antonio Terceiro <terceiro@colivre.coop.br>
@@ -85,6 +87,7 @@ Daniel Alves + Rafael Manzo &lt;rr.manzo@gmail.com&gt; @@ -85,6 +87,7 @@ Daniel Alves + Rafael Manzo &lt;rr.manzo@gmail.com&gt;
85 Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> 87 Daniela Soares Feitosa <danielafeitosa@colivre.coop.br>
86 Daniel Bucher <daniel.bucher88@gmail.com> 88 Daniel Bucher <daniel.bucher88@gmail.com>
87 Daniel Cunha <daniel@colivre.coop.br> 89 Daniel Cunha <daniel@colivre.coop.br>
  90 +David Carlos <ddavidcarlos1392@gmail.com>
88 diegoamc <diegoamc90@gmail.com> 91 diegoamc <diegoamc90@gmail.com>
89 Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com> 92 Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com>
90 Diego Araújo + Alessandro Palmeira + João M. M. da Silva <diegoamc90@gmail.com> 93 Diego Araújo + Alessandro Palmeira + João M. M. da Silva <diegoamc90@gmail.com>
@@ -114,12 +117,16 @@ Diego Martinez &lt;diegoamc90@gmail.com&gt; @@ -114,12 +117,16 @@ Diego Martinez &lt;diegoamc90@gmail.com&gt;
114 Diego Martinez <diego@diego-K55A.(none)> 117 Diego Martinez <diego@diego-K55A.(none)>
115 Diego + Renan <renanteruoc@gmail.com> 118 Diego + Renan <renanteruoc@gmail.com>
116 Eduardo Tourinho Edington <eduardo.edington@serpro.gov.br> 119 Eduardo Tourinho Edington <eduardo.edington@serpro.gov.br>
  120 +Fabio Teixeira <fabio1079@gmail.com>
117 Fernanda Lopes <nanda.listas+psl@gmail.com> 121 Fernanda Lopes <nanda.listas+psl@gmail.com>
118 Francisco Marcelo A. Lima Júnior <francisco.lima-junior@serpro.gov.br> 122 Francisco Marcelo A. Lima Júnior <francisco.lima-junior@serpro.gov.br>
119 Francisco Marcelo de Araujo Lima Junior <79350259591@serpro-1457614.(none)> 123 Francisco Marcelo de Araujo Lima Junior <79350259591@serpro-1457614.(none)>
120 Francisco Marcelo de Araújo Lima Júnior <francisco.lima-junior@serpro.gov.br> 124 Francisco Marcelo de Araújo Lima Júnior <francisco.lima-junior@serpro.gov.br>
121 Francisco Marcelo de Araújo Lima Júnior <maljunior@gmail.com> 125 Francisco Marcelo de Araújo Lima Júnior <maljunior@gmail.com>
  126 +Gabriela Navarro <navarro1703@gmail.com>
122 Grazieno Pellegrino <grazieno@gmail.com> 127 Grazieno Pellegrino <grazieno@gmail.com>
  128 +Gust <darksshades@hotmail.com>
  129 +Hugo Melo <hugo@riseup.net>
123 Isaac Canan <isaac@intelletto.com.br> 130 Isaac Canan <isaac@intelletto.com.br>
124 Italo Valcy <italo@dcc.ufba.br> 131 Italo Valcy <italo@dcc.ufba.br>
125 Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com> 132 Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com>
@@ -155,6 +162,7 @@ João M. M. Silva + Rafael Manzo &lt;jaodsilv@linux.ime.usp.br&gt; @@ -155,6 +162,7 @@ João M. M. Silva + Rafael Manzo &lt;jaodsilv@linux.ime.usp.br&gt;
155 João M. M. Silva + Renan Teruo <jaodsilv@linux.ime.usp.br> 162 João M. M. Silva + Renan Teruo <jaodsilv@linux.ime.usp.br>
156 Joenio Costa <joenio@colivre.coop.br> 163 Joenio Costa <joenio@colivre.coop.br>
157 Josef Spillner <josef.spillner@tu-dresden.de> 164 Josef Spillner <josef.spillner@tu-dresden.de>
  165 +Junior Silva <junior@bajor.localhost.localdomain>
158 Junior Silva <juniorsilva1001@gmail.com> 166 Junior Silva <juniorsilva1001@gmail.com>
159 Junior Silva <juniorsilva7@juniorsilva-Aspire-5750Z.(none)> 167 Junior Silva <juniorsilva7@juniorsilva-Aspire-5750Z.(none)>
160 Junior Silva <juniorsilva@colivre.coop.br> 168 Junior Silva <juniorsilva@colivre.coop.br>
@@ -202,6 +210,7 @@ Renan Teruo + Diego Araujo &lt;renanteruoc@gmail.com&gt; @@ -202,6 +210,7 @@ Renan Teruo + Diego Araujo &lt;renanteruoc@gmail.com&gt;
202 Renan Teruo + Diego Araújo <renanteruoc@gmail.com> 210 Renan Teruo + Diego Araújo <renanteruoc@gmail.com>
203 Renan Teruo + Paulo Meirelles <renanteruoc@gmail.com> 211 Renan Teruo + Paulo Meirelles <renanteruoc@gmail.com>
204 Renan Teruo + Rafael Manzo <renanteruoc@gmail.com> 212 Renan Teruo + Rafael Manzo <renanteruoc@gmail.com>
  213 +Rodrigo Souto + Ana Losnak + Daniel Bucher + Caio Almeida + Leandro Nunes + Daniela Feitosa + Mariel Zasso <noosfero-br@listas.softwarelivre.org>
205 Rodrigo Souto <diguliu@gmail.com> 214 Rodrigo Souto <diguliu@gmail.com>
206 Rodrigo Souto <rodrigo@colivre.coop.br> 215 Rodrigo Souto <rodrigo@colivre.coop.br>
207 Ronny Kursawe <kursawe.ronny@googlemail.com> 216 Ronny Kursawe <kursawe.ronny@googlemail.com>
@@ -110,7 +110,7 @@ Setup Noosfero log and tmp directories: @@ -110,7 +110,7 @@ Setup Noosfero log and tmp directories:
110 # cd /var/lib/noosfero/current 110 # cd /var/lib/noosfero/current
111 # ./etc/init.d/noosfero setup 111 # ./etc/init.d/noosfero setup
112 112
113 -Now it's time to setup the database. In this example we are using PostgreSQL, so if you are planning to use a different database this steps won't apply. 113 +Now it's time to setup the database. In this example we are using PostgreSQL, so if you are planning to use a different database this steps won't apply. Pay special attention to the default collation defined on your setup by the environment variable LC_COLLATE because it might interfere in some sorting operations on your database. For more information checkout `man locale`.
114 114
115 # apt-get install postgresql libpgsql-ruby 115 # apt-get install postgresql libpgsql-ruby
116 # su postgres -c 'createuser noosfero -S -d -R' 116 # su postgres -c 'createuser noosfero -S -d -R'
  1 +[![Code Climate](https://codeclimate.com/github/Noosfero/noosfero.png)](https://codeclimate.com/github/Noosfero/noosfero)
  2 +
1 Noosfero - a web-based social platform 3 Noosfero - a web-based social platform
2 ====================================== 4 ======================================
3 5
@@ -30,4 +32,4 @@ Authorship and copyright information is available in the files listed below. @@ -30,4 +32,4 @@ Authorship and copyright information is available in the files listed below.
30 -------------------- ----------------------------------------- 32 -------------------- -----------------------------------------
31 AUTHORS.md list of authors (updated at each release) 33 AUTHORS.md list of authors (updated at each release)
32 COPYRIGHT Copyright statement for the project 34 COPYRIGHT Copyright statement for the project
33 - COPYING Full text of the project license 35 - COPYING Full text of the project license
  36 + COPYING Full text of the project license
34 \ No newline at end of file 37 \ No newline at end of file
app/controllers/admin/environment_design_controller.rb
@@ -3,6 +3,8 @@ class EnvironmentDesignController &lt; BoxOrganizerController @@ -3,6 +3,8 @@ class EnvironmentDesignController &lt; BoxOrganizerController
3 protect 'edit_environment_design', :environment 3 protect 'edit_environment_design', :environment
4 4
5 def available_blocks 5 def available_blocks
  6 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  7 + # the Noosfero core soon, see ActionItem3045
6 @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ] 8 @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ]
7 @available_blocks += plugins.dispatch(:extra_blocks, :type => Environment) 9 @available_blocks += plugins.dispatch(:extra_blocks, :type => Environment)
8 end 10 end
app/controllers/admin/environment_themes_controller.rb 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +class EnvironmentThemesController < ThemesController
  2 +
  3 + protect 'edit_appearance', :environment
  4 +
  5 + no_design_blocks
  6 +
  7 + def target
  8 + @target = environment
  9 + end
  10 +
  11 +end
app/controllers/admin/users_controller.rb
@@ -45,6 +45,20 @@ class UsersController &lt; AdminController @@ -45,6 +45,20 @@ class UsersController &lt; AdminController
45 redirect_to :action => :index, :q => params[:q], :filter => params[:filter] 45 redirect_to :action => :index, :q => params[:q], :filter => params[:filter]
46 end 46 end
47 47
  48 +
  49 + def destroy_user
  50 + if request.post?
  51 + person = environment.people.find_by_id(params[:id])
  52 + if person && person.destroy
  53 + session[:notice] = _('The profile was deleted.')
  54 + else
  55 + session[:notice] = _('Could not remove profile')
  56 + end
  57 + end
  58 + redirect_to :action => :index, :q => params[:q], :filter => params[:filter]
  59 + end
  60 +
  61 +
48 def download 62 def download
49 respond_to do |format| 63 respond_to do |format|
50 format.html 64 format.html
app/controllers/my_profile/cms_controller.rb
@@ -24,10 +24,16 @@ class CmsController &lt; MyProfileController @@ -24,10 +24,16 @@ class CmsController &lt; MyProfileController
24 (user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile))) 24 (user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile)))
25 end 25 end
26 26
27 - protect_if :except => [:suggest_an_article, :set_home_page, :edit, :destroy, :publish, :upload_files] do |c, user, profile| 27 + protect_if :except => [:suggest_an_article, :set_home_page, :edit, :destroy, :publish, :upload_files, :new] do |c, user, profile|
28 user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile)) 28 user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile))
29 end 29 end
30 30
  31 + protect_if :only => :new do |c, user, profile|
  32 + article = profile.articles.find_by_id(c.params[:parent_id])
  33 + (!article.nil? && (article.allow_create?(user) || article.parent.allow_create?(user))) ||
  34 + (user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile)))
  35 + end
  36 +
31 protect_if :only => [:destroy, :publish] do |c, user, profile| 37 protect_if :only => [:destroy, :publish] do |c, user, profile|
32 profile.articles.find(c.params[:id]).allow_post_content?(user) 38 profile.articles.find(c.params[:id]).allow_post_content?(user)
33 end 39 end
@@ -68,6 +74,9 @@ class CmsController &lt; MyProfileController @@ -68,6 +74,9 @@ class CmsController &lt; MyProfileController
68 def edit 74 def edit
69 @success_back_to = params[:success_back_to] 75 @success_back_to = params[:success_back_to]
70 @article = profile.articles.find(params[:id]) 76 @article = profile.articles.find(params[:id])
  77 + version = params[:version]
  78 + @article.revert_to(version) if version
  79 +
71 @parent_id = params[:parent_id] 80 @parent_id = params[:parent_id]
72 @type = params[:type] || @article.class.to_s 81 @type = params[:type] || @article.class.to_s
73 translations if @article.translatable? 82 translations if @article.translatable?
@@ -202,7 +211,7 @@ class CmsController &lt; MyProfileController @@ -202,7 +211,7 @@ class CmsController &lt; MyProfileController
202 @article.destroy 211 @article.destroy
203 session[:notice] = _("\"#{@article.name}\" was removed.") 212 session[:notice] = _("\"#{@article.name}\" was removed.")
204 referer = ActionController::Routing::Routes.recognize_path URI.parse(request.referer).path rescue nil 213 referer = ActionController::Routing::Routes.recognize_path URI.parse(request.referer).path rescue nil
205 - if referer and referer[:controller] == 'cms' 214 + if referer and referer[:controller] == 'cms' and referer[:action] != 'edit'
206 redirect_to referer 215 redirect_to referer
207 elsif @article.parent 216 elsif @article.parent
208 redirect_to @article.parent.url 217 redirect_to @article.parent.url
@@ -218,11 +227,10 @@ class CmsController &lt; MyProfileController @@ -218,11 +227,10 @@ class CmsController &lt; MyProfileController
218 227
219 def update_categories 228 def update_categories
220 @object = params[:id] ? @profile.articles.find(params[:id]) : Article.new 229 @object = params[:id] ? @profile.articles.find(params[:id]) : Article.new
  230 + @categories = @toplevel_categories = environment.top_level_categories
221 if params[:category_id] 231 if params[:category_id]
222 @current_category = Category.find(params[:category_id]) 232 @current_category = Category.find(params[:category_id])
223 @categories = @current_category.children 233 @categories = @current_category.children
224 - else  
225 - @categories = environment.top_level_categories.select{|i| !i.children.empty?}  
226 end 234 end
227 render :partial => 'shared/select_categories', :locals => {:object_name => 'article', :multiple => true}, :layout => false 235 render :partial => 'shared/select_categories', :locals => {:object_name => 'article', :multiple => true}, :layout => false
228 end 236 end
app/controllers/my_profile/profile_design_controller.rb
@@ -32,6 +32,7 @@ class ProfileDesignController &lt; BoxOrganizerController @@ -32,6 +32,7 @@ class ProfileDesignController &lt; BoxOrganizerController
32 if profile.enterprise? 32 if profile.enterprise?
33 blocks << DisabledEnterpriseMessageBlock 33 blocks << DisabledEnterpriseMessageBlock
34 blocks << HighlightsBlock 34 blocks << HighlightsBlock
  35 + blocks << ProductCategoriesBlock
35 blocks << FeaturedProductsBlock 36 blocks << FeaturedProductsBlock
36 blocks << FansBlock 37 blocks << FansBlock
37 blocks += plugins.dispatch(:extra_blocks, :type => Enterprise) 38 blocks += plugins.dispatch(:extra_blocks, :type => Enterprise)
@@ -54,4 +55,10 @@ class ProfileDesignController &lt; BoxOrganizerController @@ -54,4 +55,10 @@ class ProfileDesignController &lt; BoxOrganizerController
54 blocks 55 blocks
55 end 56 end
56 57
  58 + def clone
  59 + block = Block.find(params[:id])
  60 + block.duplicate
  61 + redirect_to :action => 'index'
  62 + end
  63 +
57 end 64 end
app/controllers/my_profile/profile_editor_controller.rb
@@ -55,11 +55,10 @@ class ProfileEditorController &lt; MyProfileController @@ -55,11 +55,10 @@ class ProfileEditorController &lt; MyProfileController
55 55
56 def update_categories 56 def update_categories
57 @object = profile 57 @object = profile
  58 + @categories = @toplevel_categories = environment.top_level_categories
58 if params[:category_id] 59 if params[:category_id]
59 @current_category = Category.find(params[:category_id]) 60 @current_category = Category.find(params[:category_id])
60 @categories = @current_category.children 61 @categories = @current_category.children
61 - else  
62 - @categories = environment.top_level_categories.select{|i| !i.children.empty?}  
63 end 62 end
64 render :partial => 'shared/select_categories', :locals => {:object_name => 'profile_data', :multiple => true}, :layout => false 63 render :partial => 'shared/select_categories', :locals => {:object_name => 'profile_data', :multiple => true}, :layout => false
65 end 64 end
app/controllers/my_profile/profile_members_controller.rb
@@ -2,7 +2,7 @@ class ProfileMembersController &lt; MyProfileController @@ -2,7 +2,7 @@ class ProfileMembersController &lt; MyProfileController
2 protect 'manage_memberships', :profile 2 protect 'manage_memberships', :profile
3 3
4 def index 4 def index
5 - @members = profile.members 5 + @members = profile.members_by_name
6 @member_role = environment.roles.find_by_name('member') 6 @member_role = environment.roles.find_by_name('member')
7 end 7 end
8 8
app/controllers/my_profile/profile_themes_controller.rb 0 → 100644
@@ -0,0 +1,75 @@ @@ -0,0 +1,75 @@
  1 +class ProfileThemesController < ThemesController
  2 +
  3 + needs_profile
  4 +
  5 + protect 'edit_appearance', :profile
  6 +
  7 + no_design_blocks
  8 +
  9 + def target
  10 + @target = profile
  11 + end
  12 +
  13 + def new
  14 + if !request.xhr?
  15 + id = params[:name] ? params[:name].to_slug : 'my-theme'
  16 + t = Theme.new(id, :name => params[:name], :owner => profile, :public => false)
  17 + t.save
  18 + redirect_to :action => 'index'
  19 + else
  20 + render :action => 'new', :layout => false
  21 + end
  22 + end
  23 +
  24 + def edit
  25 + @theme = profile.find_theme(params[:id])
  26 + @css_files = @theme.css_files
  27 + @image_files = @theme.image_files
  28 + end
  29 +
  30 + def add_css
  31 + @theme = profile.find_theme(params[:id])
  32 + if request.xhr?
  33 + render :action => 'add_css', :layout => false
  34 + else
  35 + @theme.add_css(params[:css])
  36 + redirect_to :action => 'edit', :id => @theme.id
  37 + end
  38 + end
  39 +
  40 + def css_editor
  41 + @theme = profile.find_theme(params[:id])
  42 + @css = params[:css]
  43 +
  44 + @code = @theme.read_css(@css)
  45 + render :action => 'css_editor', :layout => false
  46 + end
  47 +
  48 + post_only :update_css
  49 + def update_css
  50 + @theme = profile.find_theme(params[:id])
  51 + @theme.update_css(params[:css], params[:csscode])
  52 + redirect_to :action => 'edit', :id => @theme.id
  53 + end
  54 +
  55 + def add_image
  56 + @theme = profile.find_theme(params[:id])
  57 + if request.xhr?
  58 + render :action => 'add_image', :layout => false
  59 + else
  60 + @theme.add_image(params[:image].original_filename, params[:image].read)
  61 + redirect_to :action => 'edit', :id => @theme.id
  62 + end
  63 + end
  64 +
  65 + def start_test
  66 + session[:theme] = params[:id]
  67 + redirect_to :controller => 'content_viewer', :profile => profile.identifier, :action => 'view_page'
  68 + end
  69 +
  70 + def stop_test
  71 + session[:theme] = nil
  72 + redirect_to :action => 'index'
  73 + end
  74 +
  75 +end
app/controllers/my_profile/themes_controller.rb
@@ -1,91 +0,0 @@ @@ -1,91 +0,0 @@
1 -class ThemesController < MyProfileController  
2 -  
3 - protect 'edit_appearance', :profile  
4 - no_design_blocks  
5 -  
6 - def set  
7 - profile.update_theme(params[:id])  
8 - redirect_to :action => 'index'  
9 - end  
10 -  
11 - def unset  
12 - profile.update_theme(nil)  
13 - redirect_to :action => 'index'  
14 - end  
15 -  
16 - def index  
17 - @themes = (profile.environment.themes + Theme.approved_themes(profile)).uniq_by{ |t| t.id }.sort_by{ |t| t.name }  
18 - @current_theme = profile.theme  
19 -  
20 - @layout_templates = LayoutTemplate.all  
21 - @current_template = profile.layout_template  
22 - end  
23 -  
24 - def new  
25 - if !request.xhr?  
26 - id = params[:name] ? params[:name].to_slug : 'my-theme'  
27 - t = Theme.new(id, :name => params[:name], :owner => profile, :public => false)  
28 - t.save  
29 - redirect_to :action => 'index'  
30 - else  
31 - render :action => 'new', :layout => false  
32 - end  
33 - end  
34 -  
35 - def edit  
36 - @theme = profile.find_theme(params[:id])  
37 - @css_files = @theme.css_files  
38 - @image_files = @theme.image_files  
39 - end  
40 -  
41 - def add_css  
42 - @theme = profile.find_theme(params[:id])  
43 - if request.xhr?  
44 - render :action => 'add_css', :layout => false  
45 - else  
46 - @theme.add_css(params[:css])  
47 - redirect_to :action => 'edit', :id => @theme.id  
48 - end  
49 - end  
50 -  
51 - def css_editor  
52 - @theme = profile.find_theme(params[:id])  
53 - @css = params[:css]  
54 -  
55 - @code = @theme.read_css(@css)  
56 - render :action => 'css_editor', :layout => false  
57 - end  
58 -  
59 - post_only :update_css  
60 - def update_css  
61 - @theme = profile.find_theme(params[:id])  
62 - @theme.update_css(params[:css], params[:csscode])  
63 - redirect_to :action => 'edit', :id => @theme.id  
64 - end  
65 -  
66 - def add_image  
67 - @theme = profile.find_theme(params[:id])  
68 - if request.xhr?  
69 - render :action => 'add_image', :layout => false  
70 - else  
71 - @theme.add_image(params[:image].original_filename, params[:image].read)  
72 - redirect_to :action => 'edit', :id => @theme.id  
73 - end  
74 - end  
75 -  
76 - def start_test  
77 - session[:theme] = params[:id]  
78 - redirect_to :controller => 'content_viewer', :profile => profile.identifier, :action => 'view_page'  
79 - end  
80 -  
81 - def stop_test  
82 - session[:theme] = nil  
83 - redirect_to :action => 'index'  
84 - end  
85 -  
86 - def set_layout_template  
87 - profile.update_layout_template(params[:id])  
88 - redirect_to :action => 'index'  
89 - end  
90 -  
91 -end  
app/controllers/public/account_controller.rb
@@ -69,6 +69,8 @@ class AccountController &lt; ApplicationController @@ -69,6 +69,8 @@ class AccountController &lt; ApplicationController
69 session[:notice] = _("This environment doesn't allow user registration.") 69 session[:notice] = _("This environment doesn't allow user registration.")
70 end 70 end
71 71
  72 + store_location(request.referer) unless params[:return_to] or session[:return_to]
  73 +
72 @block_bot = !!session[:may_be_a_bot] 74 @block_bot = !!session[:may_be_a_bot]
73 @invitation_code = params[:invitation_code] 75 @invitation_code = params[:invitation_code]
74 begin 76 begin
@@ -77,6 +79,7 @@ class AccountController &lt; ApplicationController @@ -77,6 +79,7 @@ class AccountController &lt; ApplicationController
77 @user.environment = environment 79 @user.environment = environment
78 @terms_of_use = environment.terms_of_use 80 @terms_of_use = environment.terms_of_use
79 @user.person_data = params[:profile_data] 81 @user.person_data = params[:profile_data]
  82 + @user.return_to = session[:return_to]
80 @person = Person.new(params[:profile_data]) 83 @person = Person.new(params[:profile_data])
81 @person.environment = @user.environment 84 @person.environment = @user.environment
82 if request.post? 85 if request.post?
@@ -98,7 +101,7 @@ class AccountController &lt; ApplicationController @@ -98,7 +101,7 @@ class AccountController &lt; ApplicationController
98 end 101 end
99 if @user.activated? 102 if @user.activated?
100 self.current_user = @user 103 self.current_user = @user
101 - redirect_to '/' 104 + go_to_signup_initial_page
102 else 105 else
103 @register_pending = true 106 @register_pending = true
104 end 107 end
@@ -368,32 +371,29 @@ class AccountController &lt; ApplicationController @@ -368,32 +371,29 @@ class AccountController &lt; ApplicationController
368 end 371 end
369 372
370 def go_to_initial_page 373 def go_to_initial_page
  374 + if params[:redirection]
  375 + session[:return_to] = @user.return_to
  376 + @user.return_to = nil
  377 + @user.save
  378 + end
  379 +
371 if params[:return_to] 380 if params[:return_to]
372 redirect_to params[:return_to] 381 redirect_to params[:return_to]
373 elsif environment.enabled?('allow_change_of_redirection_after_login') 382 elsif environment.enabled?('allow_change_of_redirection_after_login')
374 - case user.preferred_login_redirection  
375 - when 'keep_on_same_page'  
376 - redirect_back_or_default(user.admin_url)  
377 - when 'site_homepage'  
378 - redirect_to :controller => :home  
379 - when 'user_profile_page'  
380 - redirect_to user.public_profile_url  
381 - when 'user_homepage'  
382 - redirect_to user.url  
383 - when 'user_control_panel'  
384 - redirect_to user.admin_url  
385 - else  
386 - redirect_back_or_default(user.admin_url)  
387 - end 383 + check_redirection_options(user, user.preferred_login_redirection, user.admin_url)
388 else 384 else
389 if environment == current_user.environment 385 if environment == current_user.environment
390 - redirect_back_or_default(user.admin_url) 386 + check_redirection_options(user, environment.redirection_after_login, user.admin_url)
391 else 387 else
392 redirect_back_or_default(:controller => 'home') 388 redirect_back_or_default(:controller => 'home')
393 end 389 end
394 end 390 end
395 end 391 end
396 392
  393 + def go_to_signup_initial_page
  394 + check_redirection_options(user, user.environment.redirection_after_signup, user.url)
  395 + end
  396 +
397 def redirect_if_logged_in 397 def redirect_if_logged_in
398 if logged_in? 398 if logged_in?
399 go_to_initial_page 399 go_to_initial_page
@@ -409,4 +409,22 @@ class AccountController &lt; ApplicationController @@ -409,4 +409,22 @@ class AccountController &lt; ApplicationController
409 user 409 user
410 end 410 end
411 411
  412 + protected
  413 +
  414 + def check_redirection_options(user, condition, default)
  415 + case condition
  416 + when 'keep_on_same_page'
  417 + redirect_back_or_default(user.admin_url)
  418 + when 'site_homepage'
  419 + redirect_to :controller => :home
  420 + when 'user_profile_page'
  421 + redirect_to user.public_profile_url
  422 + when 'user_homepage'
  423 + redirect_to user.url
  424 + when 'user_control_panel'
  425 + redirect_to user.admin_url
  426 + else
  427 + redirect_back_or_default(default)
  428 + end
  429 + end
412 end 430 end
app/controllers/public/catalog_controller.rb
1 class CatalogController < PublicController 1 class CatalogController < PublicController
2 needs_profile 2 needs_profile
3 - no_design_blocks  
4 3
5 before_filter :check_enterprise_and_environment 4 before_filter :check_enterprise_and_environment
6 5
app/controllers/public/comment_controller.rb
@@ -71,7 +71,9 @@ class CommentController &lt; ApplicationController @@ -71,7 +71,9 @@ class CommentController &lt; ApplicationController
71 return 71 return
72 end 72 end
73 73
74 - @comment.save 74 + if @comment.save
  75 + @plugins.dispatch(:process_extra_comment_params, [@comment,params])
  76 + end
75 77
76 respond_to do |format| 78 respond_to do |format|
77 format.js do 79 format.js do
@@ -113,6 +115,8 @@ class CommentController &lt; ApplicationController @@ -113,6 +115,8 @@ class CommentController &lt; ApplicationController
113 115
114 def update 116 def update
115 if @comment.update_attributes(params[:comment]) 117 if @comment.update_attributes(params[:comment])
  118 + @plugins.dispatch(:process_extra_comment_params, [@comment,params])
  119 +
116 respond_to do |format| 120 respond_to do |format|
117 format.js do 121 format.js do
118 comment_to_render = @comment.comment_root 122 comment_to_render = @comment.comment_root
app/controllers/public/content_viewer_controller.rb
  1 +require 'diffy'
  2 +
1 class ContentViewerController < ApplicationController 3 class ContentViewerController < ApplicationController
2 4
3 needs_profile 5 needs_profile
@@ -7,6 +9,7 @@ class ContentViewerController &lt; ApplicationController @@ -7,6 +9,7 @@ class ContentViewerController &lt; ApplicationController
7 9
8 def view_page 10 def view_page
9 path = params[:page].join('/') 11 path = params[:page].join('/')
  12 + @version = params[:version].to_i
10 13
11 if path.blank? 14 if path.blank?
12 @page = profile.home_page 15 @page = profile.home_page
@@ -25,27 +28,15 @@ class ContentViewerController &lt; ApplicationController @@ -25,27 +28,15 @@ class ContentViewerController &lt; ApplicationController
25 end 28 end
26 end 29 end
27 30
28 - if !@page.nil? && !@page.display_to?(user)  
29 - if !profile.public?  
30 - private_profile_partial_parameters  
31 - render :template => 'profile/_private_profile.rhtml', :status => 403  
32 - else #if !profile.visible?  
33 - message = _('You are not allowed to view this content.')  
34 - message += ' ' + _('You can contact the owner of this profile to request access then.')  
35 - render_access_denied(message)  
36 - end  
37 - return  
38 - end 31 + return unless allow_access_to_page(path)
39 32
40 - # page not found, give error  
41 - if @page.nil?  
42 - render_not_found(@path)  
43 - return  
44 - end  
45 -  
46 - if request.xhr? && params[:toolbar]  
47 - render :partial => 'article_toolbar'  
48 - return 33 + if @version > 0
  34 + return render_access_denied unless @page.display_versions?
  35 + @versioned_article = @page.versions.find_by_version(@version)
  36 + if @versioned_article && @page.versions.latest.version != @versioned_article.version
  37 + render :template => 'content_viewer/versioned_article.rhtml'
  38 + return
  39 + end
49 end 40 end
50 41
51 redirect_to_translation if @page.profile.redirect_l10n 42 redirect_to_translation if @page.profile.redirect_l10n
@@ -128,6 +119,21 @@ class ContentViewerController &lt; ApplicationController @@ -128,6 +119,21 @@ class ContentViewerController &lt; ApplicationController
128 end 119 end
129 end 120 end
130 121
  122 + def versions_diff
  123 + path = params[:page].join('/')
  124 + @page = profile.articles.find_by_path(path)
  125 + @v1, @v2 = @page.versions.find_by_version(params[:v1]), @page.versions.find_by_version(params[:v2])
  126 + end
  127 +
  128 + def article_versions
  129 + path = params[:page].join('/')
  130 + @page = profile.articles.find_by_path(path)
  131 + return unless allow_access_to_page(path)
  132 +
  133 + render_access_denied unless @page.display_versions?
  134 + @versions = @page.versions.paginate(:per_page => per_page, :page => params[:npage])
  135 + end
  136 +
131 protected 137 protected
132 138
133 def per_page 139 def per_page
@@ -158,6 +164,24 @@ class ContentViewerController &lt; ApplicationController @@ -158,6 +164,24 @@ class ContentViewerController &lt; ApplicationController
158 end 164 end
159 helper_method :pass_without_comment_captcha? 165 helper_method :pass_without_comment_captcha?
160 166
  167 + def allow_access_to_page(path)
  168 + allowed = true
  169 + if @page.nil? # page not found, give error
  170 + render_not_found(path)
  171 + allowed = false
  172 + elsif !@page.display_to?(user)
  173 + if !profile.public?
  174 + private_profile_partial_parameters
  175 + render :template => 'profile/_private_profile.rhtml', :status => 403
  176 + allowed = false
  177 + else #if !profile.visible?
  178 + render_access_denied
  179 + allowed = false
  180 + end
  181 + end
  182 + allowed
  183 + end
  184 +
161 def user_is_a_bot? 185 def user_is_a_bot?
162 user_agent= request.env["HTTP_USER_AGENT"] 186 user_agent= request.env["HTTP_USER_AGENT"]
163 user_agent.blank? || 187 user_agent.blank? ||
@@ -166,5 +190,4 @@ class ContentViewerController &lt; ApplicationController @@ -166,5 +190,4 @@ class ContentViewerController &lt; ApplicationController
166 user_agent.match(/crawler/) || 190 user_agent.match(/crawler/) ||
167 user_agent.match(/\(.*https?:\/\/.*\)/) 191 user_agent.match(/\(.*https?:\/\/.*\)/)
168 end 192 end
169 -  
170 end 193 end
app/controllers/public/profile_controller.rb
@@ -67,7 +67,7 @@ class ProfileController &lt; PublicController @@ -67,7 +67,7 @@ class ProfileController &lt; PublicController
67 67
68 def members 68 def members
69 if is_cache_expired?(profile.members_cache_key(params)) 69 if is_cache_expired?(profile.members_cache_key(params))
70 - @members = profile.members.includes(relations_to_include).paginate(:per_page => members_per_page, :page => params[:npage]) 70 + @members = profile.members_by_name.includes(relations_to_include).paginate(:per_page => members_per_page, :page => params[:npage])
71 end 71 end
72 end 72 end
73 73
@@ -304,14 +304,6 @@ class ProfileController &lt; PublicController @@ -304,14 +304,6 @@ class ProfileController &lt; PublicController
304 end 304 end
305 end 305 end
306 306
307 - def profile_info  
308 - begin  
309 - @block = profile.blocks.find(params[:block_id])  
310 - rescue  
311 - render :text => _('Profile information could not be loaded')  
312 - end  
313 - end  
314 -  
315 def report_abuse 307 def report_abuse
316 @abuse_report = AbuseReport.new 308 @abuse_report = AbuseReport.new
317 render :layout => false 309 render :layout => false
app/controllers/public/search_controller.rb
@@ -80,7 +80,7 @@ class SearchController &lt; PublicController @@ -80,7 +80,7 @@ class SearchController &lt; PublicController
80 end 80 end
81 81
82 def enterprises 82 def enterprises
83 - @scope = visible_profiles(Enterprise, [{:products => :product_category}]) 83 + @scope = visible_profiles(Enterprise)
84 full_text_search 84 full_text_search
85 end 85 end
86 86
app/controllers/themes_controller.rb 0 → 100644
@@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
  1 +class ThemesController < ApplicationController
  2 +
  3 + before_filter :login_required
  4 +
  5 + no_design_blocks
  6 +
  7 + # attr_reader :target
  8 +
  9 + def target
  10 + @target
  11 + end
  12 +
  13 + def index
  14 + @environment = environment
  15 + @themes = (environment.themes + Theme.approved_themes(target)).sort_by { |t| t.name }
  16 +
  17 + @current_theme = target.theme
  18 +
  19 + @layout_templates = LayoutTemplate.all
  20 + @current_template = target.layout_template
  21 + end
  22 +
  23 + def set
  24 + target.update_theme(params[:id])
  25 + redirect_to :action => 'index'
  26 + end
  27 +
  28 + def unset
  29 + if target.kind_of?(Environment)
  30 + target.update_theme('default')
  31 + else
  32 + target.update_theme(nil)
  33 + end
  34 + redirect_to :action => 'index'
  35 + end
  36 +
  37 + def set_layout_template
  38 + target.update_layout_template(params[:id])
  39 + redirect_to :action => 'index'
  40 + end
  41 +
  42 +end
app/helpers/application_helper.rb
@@ -42,6 +42,8 @@ module ApplicationHelper @@ -42,6 +42,8 @@ module ApplicationHelper
42 42
43 include TokenHelper 43 include TokenHelper
44 44
  45 + include CatalogHelper
  46 +
45 def locale 47 def locale
46 (@page && !@page.language.blank?) ? @page.language : FastGettext.locale 48 (@page && !@page.language.blank?) ? @page.language : FastGettext.locale
47 end 49 end
@@ -512,24 +514,25 @@ module ApplicationHelper @@ -512,24 +514,25 @@ module ApplicationHelper
512 514
513 def profile_cat_icons( profile ) 515 def profile_cat_icons( profile )
514 if profile.class == Enterprise 516 if profile.class == Enterprise
515 - icons = profile.product_categories.map{ |c| c.size > 1 ? c[1] : nil }.  
516 - compact.uniq.map do |c|  
517 - cat_name = c.gsub( /[-_\s,.;'"]+/, '_' )  
518 - cat_icon = "/images/icons-cat/#{cat_name}.png"  
519 - if ! File.exists? RAILS_ROOT.to_s() + '/public/' + cat_icon  
520 - cat_icon = '/images/icons-cat/undefined.png'  
521 - end  
522 - content_tag('span',  
523 - content_tag( 'span', c ),  
524 - :title => c,  
525 - :class => 'product-cat-icon cat_icon_' + cat_name,  
526 - :style => "background-image:url(#{cat_icon})"  
527 - )  
528 - end.join("\n").html_safe  
529 - content_tag('div',  
530 - content_tag( 'span', _('Principal Product Categories'), :class => 'header' ) +"\n"+ icons,  
531 - :class => 'product-category-icons' 517 + icons = profile.product_categories.unique_by_level(2).limit(3).map do |c|
  518 + filtered_category = c.filtered_category.blank? ? c.path.split('/').last : c.filtered_category
  519 + category_title = filtered_category.split(/[-_\s,.;'"]+/).map(&:capitalize).join(' ')
  520 + category_name = category_title.gsub(' ', '_' )
  521 + category_icon = "/images/icons-cat/#{category_name}.png"
  522 + if ! File.exists? RAILS_ROOT.to_s() + '/public/' + category_icon
  523 + category_icon = '/images/icons-cat/undefined.png'
  524 + end
  525 + content_tag('span',
  526 + content_tag( 'span', category_title ),
  527 + :title => category_title,
  528 + :class => 'product-cat-icon cat_icon_' + category_name,
  529 + :style => "background-image:url(#{category_icon})"
532 ) 530 )
  531 + end.join("\n").html_safe
  532 + content_tag('div',
  533 + content_tag( 'span', _('Principal Product Categories'), :class => 'header' ) +"\n"+ icons,
  534 + :class => 'product-category-icons'
  535 + )
533 else 536 else
534 '' 537 ''
535 end 538 end
@@ -606,49 +609,18 @@ module ApplicationHelper @@ -606,49 +609,18 @@ module ApplicationHelper
606 end 609 end
607 610
608 attr_reader :environment 611 attr_reader :environment
  612 +
609 def select_categories(object_name, title=nil, title_size=4) 613 def select_categories(object_name, title=nil, title_size=4)
610 return nil if environment.enabled?(:disable_categories) 614 return nil if environment.enabled?(:disable_categories)
611 if title.nil? 615 if title.nil?
612 title = _('Categories') 616 title = _('Categories')
613 end 617 end
614 618
615 - object = instance_variable_get("@#{object_name}")  
616 -  
617 - result = content_tag 'h'+title_size.to_s(), title  
618 - result << javascript_tag( 'function open_close_cat( link ) {  
619 - var div = link.parentNode.getElementsByTagName("div")[0];  
620 - var end = function(){  
621 - if ( div.style.display == "none" ) {  
622 - this.link.className="button icon-button icon-down"  
623 - } else {  
624 - this.link.className="button icon-button icon-up-red"  
625 - }  
626 - }  
627 - Effect.toggle( div, "slide", { link:link, div:div, afterFinish:end } )  
628 - }')  
629 - environment.top_level_categories.select{|i| !i.children.empty?}.each do |toplevel|  
630 - next unless object.accept_category?(toplevel)  
631 - # FIXME  
632 - ([toplevel] + toplevel.children_for_menu).each do |cat|  
633 - if cat.top_level?  
634 - result << '<div class="categorie_box">'.html_safe  
635 - result << icon_button( :down, _('open'), '#', :onclick => 'open_close_cat(this); return false' )  
636 - result << content_tag('h5', toplevel.name)  
637 - result << '<div style="display:none"><ul class="categories">'.html_safe  
638 - else  
639 - checkbox_id = "#{object_name}_#{cat.full_name.downcase.gsub(/\s+|\//, '_')}"  
640 - result << content_tag('li', labelled_check_box(  
641 - cat.full_name_without_leading(1, " &rarr; "),  
642 - "#{object_name}[category_ids][]", cat.id,  
643 - object.category_ids.include?(cat.id), :id => checkbox_id,  
644 - :onchange => 'this.parentNode.className=(this.checked?"cat_checked":"")' ),  
645 - :class => ( object.category_ids.include?(cat.id) ? 'cat_checked' : '' ) ) + "\n"  
646 - end  
647 - end  
648 - result << '</ul></div></div>'.html_safe  
649 - end 619 + @object = instance_variable_get("@#{object_name}")
  620 + @categories = environment.top_level_categories
650 621
651 - content_tag('div', result) 622 + @current_categories = environment.top_level_categories.select{|i| !i.children.empty?}
  623 + render :partial => 'shared/select_categories_top', :locals => {:object_name => object_name, :title => title, :title_size => title_size, :multiple => true, :categories_selected => @object.categories }, :layout => false
652 end 624 end
653 625
654 def theme_option(opt = nil) 626 def theme_option(opt = nil)
@@ -918,12 +890,11 @@ module ApplicationHelper @@ -918,12 +890,11 @@ module ApplicationHelper
918 890
919 def page_title 891 def page_title
920 (@page ? @page.title + ' - ' : '') + 892 (@page ? @page.title + ' - ' : '') +
921 - (profile ? profile.short_name + ' - ' : '') +  
922 (@topic ? @topic.title + ' - ' : '') + 893 (@topic ? @topic.title + ' - ' : '') +
923 (@section ? @section.title + ' - ' : '') + 894 (@section ? @section.title + ' - ' : '') +
924 (@toc ? _('Online Manual') + ' - ' : '') + 895 (@toc ? _('Online Manual') + ' - ' : '') +
925 (@controller.controller_name == 'chat' ? _('Chat') + ' - ' : '') + 896 (@controller.controller_name == 'chat' ? _('Chat') + ' - ' : '') +
926 - environment.name + 897 + (profile ? profile.short_name : environment.name) +
927 (@category ? " - #{@category.full_name}" : '') 898 (@category ? " - #{@category.full_name}" : '')
928 end 899 end
929 900
@@ -1178,6 +1149,7 @@ module ApplicationHelper @@ -1178,6 +1149,7 @@ module ApplicationHelper
1178 #FIXME Use time_ago_in_words instead of this method if you're using Rails 2.2+ 1149 #FIXME Use time_ago_in_words instead of this method if you're using Rails 2.2+
1179 def time_ago_as_sentence(from_time, include_seconds = false) 1150 def time_ago_as_sentence(from_time, include_seconds = false)
1180 to_time = Time.now 1151 to_time = Time.now
  1152 + from_time = Time.parse(from_time.to_s)
1181 from_time = from_time.to_time if from_time.respond_to?(:to_time) 1153 from_time = from_time.to_time if from_time.respond_to?(:to_time)
1182 to_time = to_time.to_time if to_time.respond_to?(:to_time) 1154 to_time = to_time.to_time if to_time.respond_to?(:to_time)
1183 distance_in_minutes = (((to_time - from_time).abs)/60).round 1155 distance_in_minutes = (((to_time - from_time).abs)/60).round
@@ -1402,4 +1374,8 @@ module ApplicationHelper @@ -1402,4 +1374,8 @@ module ApplicationHelper
1402 content.nil? ? '' : content.id.to_s 1374 content.nil? ? '' : content.id.to_s
1403 end 1375 end
1404 1376
  1377 + def display_article_versions(article, version = nil)
  1378 + content_tag('ul', article.versions.map {|v| link_to("r#{v.version}", @page.url.merge(:version => v.version))})
  1379 + end
  1380 +
1405 end 1381 end
app/helpers/article_helper.rb
@@ -28,7 +28,7 @@ module ArticleHelper @@ -28,7 +28,7 @@ module ArticleHelper
28 'div', 28 'div',
29 check_box(:article, :notify_comments) + 29 check_box(:article, :notify_comments) +
30 content_tag('label', _('I want to receive a notification of each comment written by e-mail'), :for => 'article_notify_comments') + 30 content_tag('label', _('I want to receive a notification of each comment written by e-mail'), :for => 'article_notify_comments') +
31 - observe_field(:article_accept_comments, :function => "$('article_notify_comments').disabled = ! $('article_accept_comments').checked;$('article_moderate_comments').disabled = ! $('article_accept_comments').checked") 31 + observe_field(:article_accept_comments, :function => "$('article_notify_comments').disabled = ! $('article_accept_comments').checked;$('article_moderate_comments').disabled = ! $('article_accept_comments').checked")
32 ) + 32 ) +
33 33
34 content_tag( 34 content_tag(
@@ -42,7 +42,21 @@ module ArticleHelper @@ -42,7 +42,21 @@ module ArticleHelper
42 'div', 42 'div',
43 check_box(:article, :display_hits) + 43 check_box(:article, :display_hits) +
44 content_tag('label', _('I want this article to display the number of hits it received'), :for => 'article_display_hits') 44 content_tag('label', _('I want this article to display the number of hits it received'), :for => 'article_display_hits')
45 - ) : '') 45 + ) : '') +
  46 +
  47 + (article.can_display_versions? ?
  48 + content_tag(
  49 + 'div',
  50 + check_box(:article, :display_versions) +
  51 + content_tag('label', _('I want this article to display a link to older versions'), :for => 'article_display_versions')
  52 + ) : '') +
  53 +
  54 + (article.forum? && article.profile.community? ?
  55 + content_tag(
  56 + 'div',
  57 + check_box(:article, :allows_members_to_create_topics) +
  58 + content_tag('label', _('Allow members to create topics'), :for => 'article_allows_members_to_create_topics')
  59 + ) : '')
46 ) 60 )
47 end 61 end
48 62
app/helpers/boxes_helper.rb
@@ -65,7 +65,7 @@ module BoxesHelper @@ -65,7 +65,7 @@ module BoxesHelper
65 end 65 end
66 66
67 def display_box_content(box, main_content) 67 def display_box_content(box, main_content)
68 - context = { :article => @page, :request_path => request.path, :locale => locale } 68 + context = { :article => @page, :request_path => request.path, :locale => locale, :params => request.params }
69 box_decorator.select_blocks(box.blocks.includes(:box), context).map { |item| display_block(item, main_content) }.join("\n") + box_decorator.block_target(box) 69 box_decorator.select_blocks(box.blocks.includes(:box), context).map { |item| display_block(item, main_content) }.join("\n") + box_decorator.block_target(box)
70 end 70 end
71 71
@@ -212,6 +212,7 @@ module BoxesHelper @@ -212,6 +212,7 @@ module BoxesHelper
212 212
213 if !block.main? 213 if !block.main?
214 buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post', :confirm => _('Are you sure you want to remove this block?')}) 214 buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post', :confirm => _('Are you sure you want to remove this block?')})
  215 + buttons << icon_button(:clone, _('Clone'), { :action => 'clone', :id => block.id }, { :method => 'post' })
215 end 216 end
216 217
217 if block.respond_to?(:help) 218 if block.respond_to?(:help)
app/helpers/catalog_helper.rb
@@ -9,7 +9,11 @@ module CatalogHelper @@ -9,7 +9,11 @@ module CatalogHelper
9 @categories = ProductCategory.on_level(params[:level]).order(:name) 9 @categories = ProductCategory.on_level(params[:level]).order(:name)
10 end 10 end
11 11
12 - @products = profile.products.from_category(@category).paginate(:order => 'available desc, highlighted desc, name asc', :per_page => 9, :page => options[:page]) 12 + @products = profile.products.from_category(@category).paginate(
  13 + :order => 'available desc, highlighted desc, name asc',
  14 + :per_page => @profile.products_per_catalog_page,
  15 + :page => options[:page]
  16 + )
13 end 17 end
14 18
15 def breadcrumb(category) 19 def breadcrumb(category)
@@ -20,20 +24,24 @@ module CatalogHelper @@ -20,20 +24,24 @@ module CatalogHelper
20 content_tag('div', all_items.join(' &rarr; '), :id => 'breadcrumb') 24 content_tag('div', all_items.join(' &rarr; '), :id => 'breadcrumb')
21 end 25 end
22 26
23 - def category_link(category, sub = false) 27 + def category_link(category)
24 count = profile.products.from_category(category).count 28 count = profile.products.from_category(category).count
25 name = truncate(category.name, :length => 22 - count.to_s.size) 29 name = truncate(category.name, :length => 22 - count.to_s.size)
26 - link_name = sub ? name : content_tag('strong', name)  
27 - link = link_to(link_name, {:controller => :catalog, :action => 'index', :level => category.id}, :title => category.name)  
28 - content_tag('li', "#{link} (#{count})") if count > 0 30 + link = link_to(name, {:controller => 'catalog', :action => 'index', :level => category.id}, :title => category.name)
  31 + content_tag('div', "#{link} <span class=\"count\">#{count}</span>") if count > 0
29 end 32 end
30 33
31 - def category_sub_links(category) 34 + def category_with_sub_list(category)
  35 + content_tag 'li', "#{category_link(category)}\n#{sub_category_list(category)}"
  36 + end
  37 +
  38 + def sub_category_list(category)
32 sub_categories = [] 39 sub_categories = []
33 category.children.order(:name).each do |sub_category| 40 category.children.order(:name).each do |sub_category|
34 - sub_categories << category_link(sub_category, true) 41 + cat_link = category_link sub_category
  42 + sub_categories << content_tag('li', cat_link) unless cat_link.nil?
35 end 43 end
36 - content_tag('ul', sub_categories) if sub_categories.size > 1 44 + content_tag('ul', sub_categories) if sub_categories.size > 0
37 end 45 end
38 46
39 end 47 end
app/helpers/categories_helper.rb
@@ -48,4 +48,12 @@ module CategoriesHelper @@ -48,4 +48,12 @@ module CategoriesHelper
48 labelled_form_field(_('Type of category'), select_tag('type', options_for_select(TYPES, value))) 48 labelled_form_field(_('Type of category'), select_tag('type', options_for_select(TYPES, value)))
49 end 49 end
50 50
  51 + #FIXME make this test
  52 + def selected_category_link(cat)
  53 + content_tag('div', button_to_function_without_text(:remove, _('Remove'), nil) {|page| page["selected-category-#{cat.id}"].remove} +
  54 + link_to_function(cat.full_name(' &rarr; '), nil, :id => "remove-selected-category-#{cat.id}-button", :class => 'select-subcategory-link') {|page| page["selected-category-#{cat.id}"].remove},
  55 + :class => 'selected-category'
  56 + )
  57 + end
  58 +
51 end 59 end
app/helpers/comment_helper.rb
@@ -21,10 +21,19 @@ module CommentHelper @@ -21,10 +21,19 @@ module CommentHelper
21 title 21 title
22 end 22 end
23 23
  24 + def comment_extra_contents(comment)
  25 + @plugins.dispatch(:comment_extra_contents, comment).collect do |extra_content|
  26 + extra_content.kind_of?(Proc) ? self.instance_eval(&extra_content) : extra_content
  27 + end.join('\n')
  28 + end
  29 +
24 def comment_actions(comment) 30 def comment_actions(comment)
25 url = url_for(:profile => profile.identifier, :controller => :comment, :action => :check_actions, :id => comment.id) 31 url = url_for(:profile => profile.identifier, :controller => :comment, :action => :check_actions, :id => comment.id)
26 links = links_for_comment_actions(comment) 32 links = links_for_comment_actions(comment)
27 - content_tag(:li, link_to(content_tag(:span, _('Contents menu')), '#', :onclick => "toggleSubmenu(this,'',#{links.to_json}); return false", :class => 'menu-submenu-trigger comment-trigger', :url => url), :class=> 'vcard') unless links.empty? 33 + links_submenu = links.select{|link| link[:action_bar].blank?}
  34 + links_action_bar = links - links_submenu
  35 + links_submenu = links_submenu.collect {|link| link.slice(:link)}
  36 + render :partial => 'comment/comment_actions', :locals => {:links_submenu => links_submenu, :links_action_bar => links_action_bar, :url => url, :comment => comment}
28 end 37 end
29 38
30 private 39 private
app/helpers/content_viewer_helper.rb
@@ -51,15 +51,6 @@ module ContentViewerHelper @@ -51,15 +51,6 @@ module ContentViewerHelper
51 end 51 end
52 end 52 end
53 53
54 - def addthis_facebook_url(article)  
55 - "http://www.facebook.com/sharer.php?s=100&p[title]=%{title}&p[summary]=%{summary}&p[url]=%{url}&p[images][0]=%{image}" % {  
56 - :title => CGI.escape(article.title),  
57 - :url => CGI.escape(url_for(article.url)),  
58 - :summary => CGI.escape(truncate(strip_tags(article.body.to_s), :length => 300)),  
59 - :image => CGI.escape(article.body_images_paths.first.to_s)  
60 - }  
61 - end  
62 -  
63 def addthis_image_tag 54 def addthis_image_tag
64 if File.exists?(File.join(Rails.root, 'public', theme_path, 'images', 'addthis.gif')) 55 if File.exists?(File.join(Rails.root, 'public', theme_path, 'images', 'addthis.gif'))
65 image_tag(File.join(theme_path, 'images', 'addthis.gif'), :border => 0, :alt => '') 56 image_tag(File.join(theme_path, 'images', 'addthis.gif'), :border => 0, :alt => '')
app/helpers/layout_helper.rb
@@ -90,5 +90,8 @@ module LayoutHelper @@ -90,5 +90,8 @@ module LayoutHelper
90 end 90 end
91 end 91 end
92 92
  93 + def meta_description_tag(article=nil)
  94 + article ? truncate(strip_tags(article.body.to_s), :length => 200) : environment.name
  95 + end
93 end 96 end
94 97
app/helpers/person_notifier_helper.rb 0 → 100644
@@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
  1 +module PersonNotifierHelper
  2 +
  3 + include ApplicationHelper
  4 +
  5 + private
  6 +
  7 + def path_to_image(source)
  8 + top_url + source
  9 + end
  10 +
  11 + def top_url
  12 + top_url = @profile.environment ? @profile.environment.top_url : ''
  13 + end
  14 +
  15 +end
app/helpers/profile_helper.rb
@@ -16,14 +16,17 @@ module ProfileHelper @@ -16,14 +16,17 @@ module ProfileHelper
16 end 16 end
17 17
18 def display_contact(profile) 18 def display_contact(profile)
19 - address = display_field(_('Address:'), profile, :address)  
20 - zip = display_field(_('ZIP code:'), profile, :zip_code)  
21 - phone = display_field(_('Contact phone:'), profile, :contact_phone)  
22 - email = display_field(_('e-Mail:'), profile, :email) { |email| link_to_email(email) }  
23 - if address.blank? && zip.blank? && phone.blank? && email.blank? 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?
24 '' 27 ''
25 else 28 else
26 - content_tag('tr', content_tag('th', _('Contact'), { :colspan => 2 })) + address + zip + phone + email 29 + content_tag('tr', content_tag('th', _('Contact'), { :colspan => 2 })) + fields.join.html_safe
27 end 30 end
28 end 31 end
29 32
app/models/article.rb
@@ -201,6 +201,7 @@ class Article &lt; ActiveRecord::Base @@ -201,6 +201,7 @@ class Article &lt; ActiveRecord::Base
201 acts_as_filesystem 201 acts_as_filesystem
202 202
203 acts_as_versioned 203 acts_as_versioned
  204 + self.non_versioned_columns << 'setting'
204 205
205 def comment_data 206 def comment_data
206 comments.map {|item| [item.title, item.body].join(' ') }.join(' ') 207 comments.map {|item| [item.title, item.body].join(' ') }.join(' ')
@@ -604,25 +605,49 @@ class Article &lt; ActiveRecord::Base @@ -604,25 +605,49 @@ class Article &lt; ActiveRecord::Base
604 false 605 false
605 end 606 end
606 607
607 - def author  
608 - if versions.empty?  
609 - last_changed_by  
610 - else  
611 - author_id = versions.first.last_changed_by_id 608 + settings_items :display_versions, :type => :boolean, :default => false
  609 +
  610 + def can_display_versions?
  611 + false
  612 + end
  613 +
  614 + def display_versions?
  615 + can_display_versions? && display_versions
  616 + end
  617 +
  618 + def author(version_number = nil)
  619 + if version_number
  620 + version = versions.find_by_version(version_number)
  621 + author_id = version.last_changed_by_id if version
612 Person.exists?(author_id) ? Person.find(author_id) : nil 622 Person.exists?(author_id) ? Person.find(author_id) : nil
  623 + else
  624 + if versions.empty?
  625 + last_changed_by
  626 + else
  627 + author_id = versions.first.last_changed_by_id
  628 + Person.exists?(author_id) ? Person.find(author_id) : nil
  629 + end
613 end 630 end
614 end 631 end
615 632
616 - def author_name  
617 - author ? author.name : (setting[:author_name] || _('Unknown')) 633 + def author_name(version_number = nil)
  634 + person = author(version_number)
  635 + person ? person.name : (setting[:author_name] || _('Unknown'))
618 end 636 end
619 637
620 - def author_url  
621 - author ? author.url : nil 638 + def author_url(version_number = nil)
  639 + person = author(version_number)
  640 + person ? person.url : nil
622 end 641 end
623 642
624 - def author_id  
625 - author ? author.id : nil 643 + def author_id(version_number = nil)
  644 + person = author(version_number)
  645 + person ? person.id : nil
  646 + end
  647 +
  648 + def version_license(version_number = nil)
  649 + return license if version_number.nil?
  650 + profile.environment.licenses.find_by_id(versions.find_by_version(version_number).license_id)
626 end 651 end
627 652
628 alias :active_record_cache_key :cache_key 653 alias :active_record_cache_key :cache_key
@@ -631,7 +656,9 @@ class Article &lt; ActiveRecord::Base @@ -631,7 +656,9 @@ class Article &lt; ActiveRecord::Base
631 (allow_post_content?(the_profile) ? "-owner" : '') + 656 (allow_post_content?(the_profile) ? "-owner" : '') +
632 (params[:npage] ? "-npage-#{params[:npage]}" : '') + 657 (params[:npage] ? "-npage-#{params[:npage]}" : '') +
633 (params[:year] ? "-year-#{params[:year]}" : '') + 658 (params[:year] ? "-year-#{params[:year]}" : '') +
634 - (params[:month] ? "-month-#{params[:month]}" : '') 659 + (params[:month] ? "-month-#{params[:month]}" : '') +
  660 + (params[:version] ? "-version-#{params[:version]}" : '')
  661 +
635 end 662 end
636 663
637 def first_paragraph 664 def first_paragraph
app/models/block.rb
@@ -23,30 +23,41 @@ class Block &lt; ActiveRecord::Base @@ -23,30 +23,41 @@ class Block &lt; ActiveRecord::Base
23 # * <tt>:article</tt>: the article being viewed currently 23 # * <tt>:article</tt>: the article being viewed currently
24 # * <tt>:language</tt>: in which language the block will be displayed 24 # * <tt>:language</tt>: in which language the block will be displayed
25 def visible?(context = nil) 25 def visible?(context = nil)
26 - if display == 'never'  
27 - return false  
28 - end 26 + return false if display == 'never'
  27 +
29 if context 28 if context
30 - if language != 'all' && language != context[:locale]  
31 - return false  
32 - end  
33 - if display == 'home_page_only'  
34 - if context[:article]  
35 - return context[:article] == owner.home_page  
36 - else  
37 - return context[:request_path] == '/'  
38 - end  
39 - elsif display == 'except_home_page'  
40 - if context[:article]  
41 - return context[:article] != owner.home_page  
42 - else  
43 - return context[:request_path] != '/' + (owner.kind_of?(Profile) ? owner.identifier : '')  
44 - end 29 + return false if language != 'all' && language != context[:locale]
  30 +
  31 + begin
  32 + return self.send("display_#{display}", context)
  33 + rescue NoMethodError => exception
  34 + raise "Display '#{display}' is not a valid value."
45 end 35 end
46 end 36 end
  37 +
47 true 38 true
48 end 39 end
49 40
  41 + def display_always(context)
  42 + true
  43 + end
  44 +
  45 + def display_home_page_only(context)
  46 + if context[:article]
  47 + return context[:article] == owner.home_page
  48 + else
  49 + return context[:request_path] == '/'
  50 + end
  51 + end
  52 +
  53 + def display_except_home_page(context)
  54 + if context[:article]
  55 + return context[:article] != owner.home_page
  56 + else
  57 + return context[:request_path] != '/' + (owner.kind_of?(Profile) ? owner.identifier : '')
  58 + end
  59 + end
  60 +
50 # The condition for displaying a block. It can assume the following values: 61 # The condition for displaying a block. It can assume the following values:
51 # 62 #
52 # * <tt>'always'</tt>: the block is always displayed 63 # * <tt>'always'</tt>: the block is always displayed
@@ -168,4 +179,14 @@ class Block &lt; ActiveRecord::Base @@ -168,4 +179,14 @@ class Block &lt; ActiveRecord::Base
168 DISPLAY_OPTIONS[option] 179 DISPLAY_OPTIONS[option]
169 end 180 end
170 181
  182 + def duplicate
  183 + duplicated_block = self.clone
  184 + duplicated_block.display = 'never'
  185 + duplicated_block.created_at = nil
  186 + duplicated_block.updated_at = nil
  187 + duplicated_block.save!
  188 + duplicated_block.insert_at(self.position + 1)
  189 + duplicated_block
  190 + end
  191 +
171 end 192 end
app/models/box.rb
@@ -26,6 +26,8 @@ class Box &lt; ActiveRecord::Base @@ -26,6 +26,8 @@ class Box &lt; ActiveRecord::Base
26 CategoriesBlock, 26 CategoriesBlock,
27 CommunitiesBlock, 27 CommunitiesBlock,
28 EnterprisesBlock, 28 EnterprisesBlock,
  29 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  30 + # the Noosfero core soon, see ActionItem3045
29 EnvironmentStatisticsBlock, 31 EnvironmentStatisticsBlock,
30 FansBlock, 32 FansBlock,
31 FavoriteEnterprisesBlock, 33 FavoriteEnterprisesBlock,
@@ -52,6 +54,8 @@ class Box &lt; ActiveRecord::Base @@ -52,6 +54,8 @@ class Box &lt; ActiveRecord::Base
52 CommunitiesBlock, 54 CommunitiesBlock,
53 DisabledEnterpriseMessageBlock, 55 DisabledEnterpriseMessageBlock,
54 EnterprisesBlock, 56 EnterprisesBlock,
  57 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  58 + # the Noosfero core soon, see ActionItem3045
55 EnvironmentStatisticsBlock, 59 EnvironmentStatisticsBlock,
56 FansBlock, 60 FansBlock,
57 FavoriteEnterprisesBlock, 61 FavoriteEnterprisesBlock,
@@ -66,6 +70,7 @@ class Box &lt; ActiveRecord::Base @@ -66,6 +70,7 @@ class Box &lt; ActiveRecord::Base
66 MyNetworkBlock, 70 MyNetworkBlock,
67 PeopleBlock, 71 PeopleBlock,
68 ProductsBlock, 72 ProductsBlock,
  73 + ProductCategoriesBlock,
69 ProfileImageBlock, 74 ProfileImageBlock,
70 ProfileInfoBlock, 75 ProfileInfoBlock,
71 ProfileSearchBlock, 76 ProfileSearchBlock,
app/models/enterprise.rb
@@ -10,19 +10,20 @@ class Enterprise &lt; Organization @@ -10,19 +10,20 @@ class Enterprise &lt; Organization
10 10
11 N_('Enterprise') 11 N_('Enterprise')
12 12
13 - has_many :products, :dependent => :destroy, :order => 'name ASC' 13 + has_many :products, :foreign_key => :profile_id, :dependent => :destroy, :order => 'name ASC'
14 has_many :inputs, :through => :products 14 has_many :inputs, :through => :products
15 has_many :production_costs, :as => :owner 15 has_many :production_costs, :as => :owner
16 16
17 has_and_belongs_to_many :fans, :class_name => 'Person', :join_table => 'favorite_enteprises_people' 17 has_and_belongs_to_many :fans, :class_name => 'Person', :join_table => 'favorite_enteprises_people'
18 18
19 def product_categories 19 def product_categories
20 - products.includes(:product_category).map{|p| p.category_full_name}.compact 20 + ProductCategory.by_enterprise(self)
21 end 21 end
22 22
23 N_('Organization website'); N_('Historic and current context'); N_('Activities short description'); N_('City'); N_('State'); N_('Country'); N_('ZIP code') 23 N_('Organization website'); N_('Historic and current context'); N_('Activities short description'); N_('City'); N_('State'); N_('Country'); N_('ZIP code')
24 24
25 settings_items :organization_website, :historic_and_current_context, :activities_short_description, :zip_code, :city, :state, :country 25 settings_items :organization_website, :historic_and_current_context, :activities_short_description, :zip_code, :city, :state, :country
  26 + settings_items :products_per_catalog_page, :type => :integer, :default => 6
26 27
27 extend SetProfileRegionFromCityState::ClassMethods 28 extend SetProfileRegionFromCityState::ClassMethods
28 set_profile_region_from_city_state 29 set_profile_region_from_city_state
@@ -135,8 +136,11 @@ class Enterprise &lt; Organization @@ -135,8 +136,11 @@ class Enterprise &lt; Organization
135 ] 136 ]
136 blocks = [ 137 blocks = [
137 [MainBlock.new], 138 [MainBlock.new],
138 - [ProfileImageBlock.new, LinkListBlock.new(:links => links)],  
139 - [] 139 + [ ProfileImageBlock.new,
  140 + LinkListBlock.new(:links => links),
  141 + ProductCategoriesBlock.new
  142 + ],
  143 + [LocationBlock.new]
140 ] 144 ]
141 if environment.enabled?('products_for_enterprises') 145 if environment.enabled?('products_for_enterprises')
142 blocks[2].unshift ProductsBlock.new 146 blocks[2].unshift ProductsBlock.new
app/models/environment.rb
@@ -26,7 +26,8 @@ class Environment &lt; ActiveRecord::Base @@ -26,7 +26,8 @@ class Environment &lt; ActiveRecord::Base
26 'manage_environment_users' => N_('Manage environment users'), 26 'manage_environment_users' => N_('Manage environment users'),
27 'manage_environment_templates' => N_('Manage environment templates'), 27 'manage_environment_templates' => N_('Manage environment templates'),
28 'manage_environment_licenses' => N_('Manage environment licenses'), 28 'manage_environment_licenses' => N_('Manage environment licenses'),
29 - 'manage_environment_trusted_sites' => N_('Manage environment trusted sites') 29 + 'manage_environment_trusted_sites' => N_('Manage environment trusted sites'),
  30 + 'edit_appearance' => N_('Edit appearance'),
30 } 31 }
31 32
32 module Roles 33 module Roles
@@ -144,6 +145,18 @@ class Environment &lt; ActiveRecord::Base @@ -144,6 +145,18 @@ class Environment &lt; ActiveRecord::Base
144 end 145 end
145 validates_inclusion_of :redirection_after_login, :in => Environment.login_redirection_options.keys, :allow_nil => true 146 validates_inclusion_of :redirection_after_login, :in => Environment.login_redirection_options.keys, :allow_nil => true
146 147
  148 + def self.signup_redirection_options
  149 + {
  150 + 'keep_on_same_page' => _('Stays on the same page the user was before signup.'),
  151 + 'site_homepage' => _('Redirects the user to the environment homepage.'),
  152 + 'user_profile_page' => _('Redirects the user to his profile page.'),
  153 + 'user_homepage' => _('Redirects the user to his homepage.'),
  154 + 'user_control_panel' => _('Redirects the user to his control panel.')
  155 + }
  156 + end
  157 + validates_inclusion_of :redirection_after_signup, :in => Environment.signup_redirection_options.keys, :allow_nil => true
  158 +
  159 +
147 # ################################################# 160 # #################################################
148 # Relationships and applied behaviour 161 # Relationships and applied behaviour
149 # ################################################# 162 # #################################################
@@ -160,6 +173,8 @@ class Environment &lt; ActiveRecord::Base @@ -160,6 +173,8 @@ class Environment &lt; ActiveRecord::Base
160 173
161 # "left" area 174 # "left" area
162 env.boxes[1].blocks << LoginBlock.new 175 env.boxes[1].blocks << LoginBlock.new
  176 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  177 + # the Noosfero core soon, see ActionItem3045
163 env.boxes[1].blocks << EnvironmentStatisticsBlock.new 178 env.boxes[1].blocks << EnvironmentStatisticsBlock.new
164 env.boxes[1].blocks << RecentDocumentsBlock.new 179 env.boxes[1].blocks << RecentDocumentsBlock.new
165 180
@@ -680,6 +695,16 @@ class Environment &lt; ActiveRecord::Base @@ -680,6 +695,16 @@ class Environment &lt; ActiveRecord::Base
680 end 695 end
681 end 696 end
682 697
  698 + def update_theme(theme)
  699 + self.theme = theme
  700 + self.save!
  701 + end
  702 +
  703 + def update_layout_template(template)
  704 + self.layout_template = template
  705 + self.save!
  706 + end
  707 +
683 before_create do |env| 708 before_create do |env|
684 env.settings[:themes] ||= %w[ 709 env.settings[:themes] ||= %w[
685 aluminium 710 aluminium
@@ -695,7 +720,8 @@ class Environment &lt; ActiveRecord::Base @@ -695,7 +720,8 @@ class Environment &lt; ActiveRecord::Base
695 end 720 end
696 721
697 def community_template 722 def community_template
698 - Community.find_by_id settings[:community_template_id] 723 + template = Community.find_by_id settings[:community_template_id]
  724 + template if template && template.is_template
699 end 725 end
700 726
701 def community_template=(value) 727 def community_template=(value)
@@ -703,7 +729,8 @@ class Environment &lt; ActiveRecord::Base @@ -703,7 +729,8 @@ class Environment &lt; ActiveRecord::Base
703 end 729 end
704 730
705 def person_template 731 def person_template
706 - Person.find_by_id settings[:person_template_id] 732 + template = Person.find_by_id settings[:person_template_id]
  733 + template if template && template.is_template
707 end 734 end
708 735
709 def person_template=(value) 736 def person_template=(value)
@@ -711,7 +738,8 @@ class Environment &lt; ActiveRecord::Base @@ -711,7 +738,8 @@ class Environment &lt; ActiveRecord::Base
711 end 738 end
712 739
713 def enterprise_template 740 def enterprise_template
714 - Enterprise.find_by_id settings[:enterprise_template_id] 741 + template = Enterprise.find_by_id settings[:enterprise_template_id]
  742 + template if template && template.is_template
715 end 743 end
716 744
717 def enterprise_template=(value) 745 def enterprise_template=(value)
@@ -719,7 +747,8 @@ class Environment &lt; ActiveRecord::Base @@ -719,7 +747,8 @@ class Environment &lt; ActiveRecord::Base
719 end 747 end
720 748
721 def inactive_enterprise_template 749 def inactive_enterprise_template
722 - Enterprise.find_by_id settings[:inactive_enterprise_template_id] 750 + template = Enterprise.find_by_id settings[:inactive_enterprise_template_id]
  751 + template if template && template.is_template
723 end 752 end
724 753
725 def inactive_enterprise_template=(value) 754 def inactive_enterprise_template=(value)
@@ -801,7 +830,7 @@ class Environment &lt; ActiveRecord::Base @@ -801,7 +830,7 @@ class Environment &lt; ActiveRecord::Base
801 end 830 end
802 831
803 def highlighted_products_with_image(options = {}) 832 def highlighted_products_with_image(options = {})
804 - Product.find(:all, {:conditions => {:highlighted => true, :enterprise_id => self.enterprises.find(:all, :select => :id) }, :joins => :image}.merge(options)) 833 + Product.find(:all, {:conditions => {:highlighted => true, :profile_id => self.enterprises.find(:all, :select => :id) }, :joins => :image}.merge(options))
805 end 834 end
806 835
807 settings_items :home_cache_in_minutes, :type => :integer, :default => 5 836 settings_items :home_cache_in_minutes, :type => :integer, :default => 5
app/models/environment_statistics_block.rb
  1 +# TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  2 +# the Noosfero core soon, see ActionItem3045
  3 +
1 class EnvironmentStatisticsBlock < Block 4 class EnvironmentStatisticsBlock < Block
2 5
3 def self.description 6 def self.description
4 - _('Environment stastistics') 7 + _('Environment stastistics (DEPRECATED)')
5 end 8 end
6 9
7 def default_title 10 def default_title
app/models/forum.rb
@@ -5,6 +5,7 @@ class Forum &lt; Folder @@ -5,6 +5,7 @@ class Forum &lt; Folder
5 5
6 settings_items :terms_of_use, :type => :string, :default => "" 6 settings_items :terms_of_use, :type => :string, :default => ""
7 settings_items :has_terms_of_use, :type => :boolean, :default => false 7 settings_items :has_terms_of_use, :type => :boolean, :default => false
  8 + settings_items :allows_members_to_create_topics, :type => :boolean, :default => false
8 has_and_belongs_to_many :users_with_agreement, :class_name => 'Person', :join_table => 'terms_forum_people' 9 has_and_belongs_to_many :users_with_agreement, :class_name => 'Person', :join_table => 'terms_forum_people'
9 10
10 before_save do |forum| 11 before_save do |forum|
@@ -66,4 +67,11 @@ class Forum &lt; Folder @@ -66,4 +67,11 @@ class Forum &lt; Folder
66 self.users_with_agreement.exists? user 67 self.users_with_agreement.exists? user
67 end 68 end
68 69
  70 + def can_create_topic?(user, profile)
  71 + return profile.community? && profile.members.include?(user) && self.allows_members_to_create_topics
  72 + end
  73 +
  74 + def allow_create?(user)
  75 + super || can_create_topic?(user, profile)
  76 + end
69 end 77 end
app/models/link_list_block.rb
@@ -63,7 +63,7 @@ class LinkListBlock &lt; Block @@ -63,7 +63,7 @@ class LinkListBlock &lt; Block
63 def link_html(link) 63 def link_html(link)
64 klass = 'icon-' + link[:icon] if link[:icon] 64 klass = 'icon-' + link[:icon] if link[:icon]
65 sanitize_link( 65 sanitize_link(
66 - link_to(link[:name], expand_address(link[:address]), :target => link[:target], :class => klass) 66 + link_to(link[:name], expand_address(link[:address]), :target => link[:target], :class => klass, :title => link[:title])
67 ) 67 )
68 end 68 end
69 69
app/models/person.rb
@@ -43,7 +43,12 @@ class Person &lt; Profile @@ -43,7 +43,12 @@ class Person &lt; Profile
43 alias_method_chain :has_permission?, :plugins 43 alias_method_chain :has_permission?, :plugins
44 44
45 def memberships 45 def memberships
46 - Profile.memberships_of(self) 46 + scopes = []
  47 + plugins_scopes = plugins.dispatch_scopes(:person_memberships, self)
  48 + scopes = plugins_scopes unless plugins_scopes.first.blank?
  49 + scopes << Profile.memberships_of(self)
  50 + return scopes.first if scopes.size == 1
  51 + ScopeTool.union *scopes
47 end 52 end
48 53
49 def memberships_by_role(role) 54 def memberships_by_role(role)
@@ -129,32 +134,34 @@ class Person &lt; Profile @@ -129,32 +134,34 @@ class Person &lt; Profile
129 end 134 end
130 135
131 FIELDS = %w[ 136 FIELDS = %w[
  137 + description
  138 + image
132 preferred_domain 139 preferred_domain
133 nickname 140 nickname
134 sex 141 sex
135 - address  
136 - zip_code  
137 - city  
138 - state  
139 - country  
140 - nationality  
141 birth_date 142 birth_date
  143 + nationality
  144 + country
  145 + state
  146 + city
  147 + district
  148 + zip_code
  149 + address
  150 + address_reference
142 cell_phone 151 cell_phone
143 comercial_phone 152 comercial_phone
  153 + personal_website
  154 + jabber_id
144 schooling 155 schooling
  156 + formation
  157 + custom_formation
  158 + area_of_study
  159 + custom_area_of_study
145 professional_activity 160 professional_activity
146 organization 161 organization
147 organization_website 162 organization_website
148 - area_of_study  
149 - custom_area_of_study  
150 - formation  
151 - custom_formation  
152 contact_phone 163 contact_phone
153 contact_information 164 contact_information
154 - description  
155 - image  
156 - district  
157 - address_reference  
158 ] 165 ]
159 166
160 validates_multiparameter_assignments 167 validates_multiparameter_assignments
@@ -483,6 +490,17 @@ class Person &lt; Profile @@ -483,6 +490,17 @@ class Person &lt; Profile
483 gravatar_profile_image_url(self.email, :size=>20, :d => gravatar_default) 490 gravatar_profile_image_url(self.email, :size=>20, :d => gravatar_default)
484 end 491 end
485 492
  493 + settings_items :last_notification, :type => DateTime
  494 + settings_items :notification_time, :type => :integer, :default => 0
  495 +
  496 + def notifier
  497 + @notifier ||= PersonNotifier.new(self)
  498 + end
  499 +
  500 + after_update do |person|
  501 + person.notifier.reschedule_next_notification_mail
  502 + end
  503 +
486 protected 504 protected
487 505
488 def followed_by?(profile) 506 def followed_by?(profile)
app/models/person_notifier.rb 0 → 100644
@@ -0,0 +1,89 @@ @@ -0,0 +1,89 @@
  1 +class PersonNotifier
  2 +
  3 + def initialize(person)
  4 + @person = person
  5 + end
  6 +
  7 + def self.schedule_all_next_notification_mail
  8 + Delayed::Job.enqueue(NotifyAllJob.new) unless NotifyAllJob.exists?
  9 + end
  10 +
  11 + def schedule_next_notification_mail
  12 + dispatch_notification_mail if !NotifyJob.exists?(@person.id)
  13 + end
  14 +
  15 + def dispatch_notification_mail
  16 + Delayed::Job.enqueue(NotifyJob.new(@person.id), nil, @person.notification_time.hours.from_now) if @person.notification_time>0
  17 + end
  18 +
  19 + def reschedule_next_notification_mail
  20 + return nil unless @person.setting_changed?(:notification_time) || @person.setting_changed?(:last_notification)
  21 + NotifyJob.find(@person.id).delete_all
  22 + schedule_next_notification_mail
  23 + end
  24 +
  25 + def notify
  26 + if @person.notification_time && @person.notification_time > 0
  27 + from = @person.last_notification || DateTime.now - @person.notification_time.hours
  28 + notifications = @person.tracked_notifications.find(:all, :conditions => ["created_at > ?", from])
  29 + Noosfero.with_locale @person.environment.default_language do
  30 + Mailer::deliver_content_summary(@person, notifications) unless notifications.empty?
  31 + end
  32 + @person.settings[:last_notification] = DateTime.now
  33 + @person.save!
  34 + end
  35 + end
  36 +
  37 + class NotifyAllJob
  38 + def self.exists?
  39 + Delayed::Job.where(:handler => "--- !ruby/object:PersonNotifier::NotifyAllJob {}\n\n").count > 0
  40 + end
  41 +
  42 + def perform
  43 + Person.find_each {|person| person.notifier.schedule_next_notification_mail }
  44 + end
  45 + end
  46 +
  47 + class NotifyJob < Struct.new(:person_id)
  48 +
  49 + def self.exists?(person_id)
  50 + !find(person_id).empty?
  51 + end
  52 +
  53 + def self.find(person_id)
  54 + Delayed::Job.where(:handler => "--- !ruby/struct:PersonNotifier::NotifyJob \nperson_id: #{person_id}\n")
  55 + end
  56 +
  57 + def perform
  58 + Person.find(person_id).notifier.notify
  59 + end
  60 +
  61 + def on_permanent_failure
  62 + person = Person.find(person_id)
  63 + person.notifier.dispatch_notification_mail
  64 + end
  65 +
  66 + end
  67 +
  68 + class Mailer < ActionMailer::Base
  69 +
  70 + add_template_helper(PersonNotifierHelper)
  71 +
  72 + def session
  73 + {:theme => nil}
  74 + end
  75 +
  76 + def content_summary(person, notifications)
  77 + @current_theme = 'default'
  78 + @profile = person
  79 + recipients person.email
  80 + from "#{@profile.environment.name} <#{@profile.environment.contact_email}>"
  81 + subject _("[%s] Network Activity") % [@profile.environment.name]
  82 + body :recipient => @profile.nickname || @profile.name,
  83 + :environment => @profile.environment.name,
  84 + :url => @profile.environment.top_url,
  85 + :notifications => notifications
  86 + content_type "text/html"
  87 + end
  88 + end
  89 +end
app/models/product.rb
@@ -15,7 +15,11 @@ class Product &lt; ActiveRecord::Base @@ -15,7 +15,11 @@ class Product &lt; ActiveRecord::Base
15 'full' 15 'full'
16 end 16 end
17 17
18 - belongs_to :enterprise 18 + belongs_to :enterprise, :foreign_key => :profile_id, :class_name => 'Profile'
  19 + belongs_to :profile
  20 + alias_method :enterprise=, :profile=
  21 + alias_method :enterprise, :profile
  22 +
19 has_one :region, :through => :enterprise 23 has_one :region, :through => :enterprise
20 validates_presence_of :enterprise 24 validates_presence_of :enterprise
21 25
@@ -29,7 +33,10 @@ class Product &lt; ActiveRecord::Base @@ -29,7 +33,10 @@ class Product &lt; ActiveRecord::Base
29 has_many :qualifiers, :through => :product_qualifiers 33 has_many :qualifiers, :through => :product_qualifiers
30 has_many :certifiers, :through => :product_qualifiers 34 has_many :certifiers, :through => :product_qualifiers
31 35
32 - validates_uniqueness_of :name, :scope => :enterprise_id, :allow_nil => true 36 + acts_as_having_settings :field => :data
  37 +
  38 + validates_uniqueness_of :name, :scope => :profile_id, :allow_nil => true, :if => :validate_uniqueness_of_column_name?
  39 +
33 validates_presence_of :product_category_id 40 validates_presence_of :product_category_id
34 validates_associated :product_category 41 validates_associated :product_category
35 42
@@ -81,10 +88,6 @@ class Product &lt; ActiveRecord::Base @@ -81,10 +88,6 @@ class Product &lt; ActiveRecord::Base
81 image ? image.public_filename(size) : '/images/icons-app/product-default-pic-%s.png' % size 88 image ? image.public_filename(size) : '/images/icons-app/product-default-pic-%s.png' % size
82 end 89 end
83 90
84 - def category_full_name  
85 - product_category ? product_category.full_name.split('/') : nil  
86 - end  
87 -  
88 acts_as_having_image 91 acts_as_having_image
89 92
90 def save_image 93 def save_image
@@ -234,4 +237,10 @@ class Product &lt; ActiveRecord::Base @@ -234,4 +237,10 @@ class Product &lt; ActiveRecord::Base
234 237
235 delegate :enabled, :region, :region_id, :environment, :environment_id, :to => :enterprise 238 delegate :enabled, :region, :region_id, :environment, :environment_id, :to => :enterprise
236 239
  240 + protected
  241 +
  242 + def validate_uniqueness_of_column_name?
  243 + true
  244 + end
  245 +
237 end 246 end
app/models/product_categories_block.rb 0 → 100644
@@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
  1 +class ProductCategoriesBlock < Block
  2 +
  3 + def self.description
  4 + _('Product category menu')
  5 + end
  6 +
  7 + # the title of the block. Probably will be overriden in subclasses.
  8 + def default_title
  9 + _('Catalog')
  10 + end
  11 +
  12 + def help
  13 + _('Helps to filter the products catalog.')
  14 + end
  15 +
  16 + def content(args={})
  17 + profile = owner
  18 + lambda do
  19 + if @categories.nil? or @categories.length == 0
  20 + categories = ProductCategory.on_level().order(:name)
  21 + if @categories and @categories.length == 0
  22 + notice = _('There are no sub-categories for %s') % @category.name
  23 + end
  24 + else
  25 + categories = @categories
  26 + end
  27 + render :file => 'blocks/product_categories',
  28 + :locals => {
  29 + :profile => profile,
  30 + :categories => categories,
  31 + :notice => notice
  32 + }
  33 + end
  34 + end
  35 +
  36 + DISPLAY_OPTIONS['catalog_only'] = __('Only on the catalog')
  37 +
  38 + def display
  39 + settings[:display].nil? ? 'catalog_only' : super
  40 + end
  41 +
  42 + def display_catalog_only(context)
  43 + context[:params][:controller] == 'catalog'
  44 + end
  45 +
  46 + def visible?(*args)
  47 + box.environment.enabled?('products_for_enterprises') ? super(*args) : false
  48 + end
  49 +
  50 +end
app/models/product_category.rb
@@ -3,6 +3,15 @@ class ProductCategory &lt; Category @@ -3,6 +3,15 @@ class ProductCategory &lt; Category
3 has_many :products 3 has_many :products
4 has_many :inputs 4 has_many :inputs
5 5
  6 + named_scope :unique, :select => 'DISTINCT ON (path) categories.*'
  7 + named_scope :by_enterprise, lambda { |enterprise| {
  8 + :joins => :products,
  9 + :conditions => ['products.profile_id = ?', enterprise.id]
  10 + }}
  11 + named_scope :unique_by_level, lambda { |level| {
  12 + :select => "DISTINCT ON (filtered_category) split_part(path, '/', #{level}) AS filtered_category, categories.*"
  13 + }}
  14 +
6 def all_products 15 def all_products
7 Product.find(:all, :conditions => { :product_category_id => (all_children << self).map(&:id) }) 16 Product.find(:all, :conditions => { :product_category_id => (all_children << self).map(&:id) })
8 end 17 end
app/models/profile.rb
@@ -84,7 +84,12 @@ class Profile &lt; ActiveRecord::Base @@ -84,7 +84,12 @@ class Profile &lt; ActiveRecord::Base
84 def members 84 def members
85 scopes = plugins.dispatch_scopes(:organization_members, self) 85 scopes = plugins.dispatch_scopes(:organization_members, self)
86 scopes << Person.members_of(self) 86 scopes << Person.members_of(self)
87 - scopes.size == 1 ? scopes.first : Person.or_scope(scopes) 87 + return scopes.first if scopes.size == 1
  88 + ScopeTool.union *scopes
  89 + end
  90 +
  91 + def members_by_name
  92 + members.order(:name)
88 end 93 end
89 94
90 class << self 95 class << self
app/models/text_article.rb
@@ -17,4 +17,7 @@ class TextArticle &lt; Article @@ -17,4 +17,7 @@ class TextArticle &lt; Article
17 end 17 end
18 end 18 end
19 19
  20 + def can_display_versions?
  21 + true
  22 + end
20 end 23 end
app/models/user.rb
@@ -71,7 +71,8 @@ class User &lt; ActiveRecord::Base @@ -71,7 +71,8 @@ class User &lt; ActiveRecord::Base
71 body :recipient => user.name, 71 body :recipient => user.name,
72 :activation_code => user.activation_code, 72 :activation_code => user.activation_code,
73 :environment => user.environment.name, 73 :environment => user.environment.name,
74 - :url => user.environment.top_url 74 + :url => user.environment.top_url,
  75 + :redirection => (true if user.return_to)
75 end 76 end
76 77
77 def signup_welcome_email(user) 78 def signup_welcome_email(user)
app/sweepers/profile_sweeper.rb
@@ -8,6 +8,8 @@ class ProfileSweeper # &lt; ActiveRecord::Observer @@ -8,6 +8,8 @@ class ProfileSweeper # &lt; ActiveRecord::Observer
8 end 8 end
9 9
10 def after_create(profile) 10 def after_create(profile)
  11 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  12 + # the Noosfero core soon, see ActionItem3045
11 expire_statistics_block_cache(profile) 13 expire_statistics_block_cache(profile)
12 end 14 end
13 15
@@ -29,6 +31,8 @@ protected @@ -29,6 +31,8 @@ protected
29 expire_blogs(profile) if profile.organization? 31 expire_blogs(profile) if profile.organization?
30 end 32 end
31 33
  34 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  35 + # the Noosfero core soon, see ActionItem3045
32 def expire_statistics_block_cache(profile) 36 def expire_statistics_block_cache(profile)
33 blocks = profile.environment.blocks.select { |b| b.kind_of?(EnvironmentStatisticsBlock) } 37 blocks = profile.environment.blocks.select { |b| b.kind_of?(EnvironmentStatisticsBlock) }
34 BlockSweeper.expire_blocks(blocks) 38 BlockSweeper.expire_blocks(blocks)
app/views/admin_panel/index.rhtml
@@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
6 <tr><td><%= link_to _('Environment settings'), :action => 'site_info' %></td></tr> 6 <tr><td><%= link_to _('Environment settings'), :action => 'site_info' %></td></tr>
7 <tr><td><%= link_to _('Features'), :controller => 'features' %></td></tr> 7 <tr><td><%= link_to _('Features'), :controller => 'features' %></td></tr>
8 <tr><td><%= link_to _('Plugins'), :controller => 'plugins' %></td></tr> 8 <tr><td><%= link_to _('Plugins'), :controller => 'plugins' %></td></tr>
  9 + <tr><td><%= link_to _('Appearance'), :controller =>'environment_themes' %></td></tr>
9 <tr><td><%= link_to _('Sideboxes'), :controller => 'environment_design'%></td></tr> 10 <tr><td><%= link_to _('Sideboxes'), :controller => 'environment_design'%></td></tr>
10 <tr><td><%= link_to _('Homepage'), :action => 'set_portal_community' %></td></tr> 11 <tr><td><%= link_to _('Homepage'), :action => 'set_portal_community' %></td></tr>
11 <tr><td><%= link_to _('Licenses'), :controller =>'licenses' %></td></tr> 12 <tr><td><%= link_to _('Licenses'), :controller =>'licenses' %></td></tr>
app/views/blocks/product_categories.html.erb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +<%= link_to _('Catalog start'), profile.catalog_url, :class=>'catalog-home-link' %>
  2 +<ul class="catalog-categories-list">
  3 + <% categories.each do |category| %>
  4 + <%= category_with_sub_list(category) %>
  5 + <% end %>
  6 +</ul>
  7 +<% if notice %>
  8 + <div class="catalog-categories-notice"><%= notice %></div>
  9 +<% end %>
app/views/blocks/profile_image.rhtml
@@ -16,11 +16,13 @@ @@ -16,11 +16,13 @@
16 <p><%= h block.owner.short_name %></p> 16 <p><%= h block.owner.short_name %></p>
17 <% end %> 17 <% end %>
18 18
19 -<div style="text-align: center; font-size: 75%; clear: both" id="profile-admin-url-<%= block.id %>"></div>  
20 -  
21 -<div class="profile-info-options" id="profile-info-options-<%= block.id %>"></div> 19 +<% if !user.nil? and user.has_permission?('edit_profile', profile) %>
  20 + <div class='admin-link'>
  21 + <%= link_to _('Control panel'), block.owner.admin_url %>
  22 + </div>
  23 +<% end %>
22 24
  25 +<div class="profile-info-options">
  26 + <%= render :file => view_for_profile_actions(block.owner.class) %>
  27 +</div>
23 </div><!-- end class="vcard" --> 28 </div><!-- end class="vcard" -->
24 -<script type="text/javascript">  
25 - <%= remote_function :url => { :controller => 'profile', :profile => profile.identifier, :action => 'profile_info', :block_id => block.id } %>  
26 -</script>  
app/views/blocks/profile_info.rhtml
@@ -14,13 +14,15 @@ @@ -14,13 +14,15 @@
14 </div> 14 </div>
15 </div> 15 </div>
16 16
17 -<ul class="profile-info-data" id="profile-info-data-<%= block.id %>"> 17 +<ul class="profile-info-data">
18 <li><%= link_to __('Homepage'), block.owner.url, :class => 'url' %></li> 18 <li><%= link_to __('Homepage'), block.owner.url, :class => 'url' %></li>
19 <li><%= link_to _('View profile'), block.owner.public_profile_url %></li> 19 <li><%= link_to _('View profile'), block.owner.public_profile_url %></li>
20 <% if block.owner.enterprise? && block.owner.environment.enabled?('products_for_enterprises') %> 20 <% if block.owner.enterprise? && block.owner.environment.enabled?('products_for_enterprises') %>
21 <li><%= link_to(_('Products/Services'), :controller => 'catalog', :profile => block.owner.identifier) %></li> 21 <li><%= link_to(_('Products/Services'), :controller => 'catalog', :profile => block.owner.identifier) %></li>
22 <% end %> 22 <% end %>
23 - <li id="profile-admin-url-<%= block.id %>"></li> 23 + <% if !user.nil? and user.has_permission?('edit_profile', profile) %>
  24 + <li><%= link_to _('Control panel'), block.owner.admin_url %></li>
  25 + <% end %>
24 <% if profile.person? %> 26 <% if profile.person? %>
25 <li><%= _('Since %{year}/%{month}') % { :year => block.owner.created_at.year, :month => block.owner.created_at.month } %></li> 27 <li><%= _('Since %{year}/%{month}') % { :year => block.owner.created_at.year, :month => block.owner.created_at.month } %></li>
26 <% end %> 28 <% end %>
@@ -37,9 +39,8 @@ @@ -37,9 +39,8 @@
37 </div> 39 </div>
38 <% end %> 40 <% end %>
39 41
40 -<div class="profile-info-options" id="profile-info-options-<%= block.id %>"></div> 42 +<div class="profile-info-options">
  43 + <%= render :file => view_for_profile_actions(block.owner.class) %>
  44 +</div>
41 45
42 </div><!-- end class="vcard" --> 46 </div><!-- end class="vcard" -->
43 -<script type="text/javascript">  
44 - <%= remote_function :url => { :controller => 'profile', :profile => profile.identifier, :action => 'profile_info', :block_id => block.id } %>  
45 -</script>  
app/views/box_organizer/_link_list_block.rhtml
1 <strong><%= _('Links') %></strong> 1 <strong><%= _('Links') %></strong>
2 <div id='edit-link-list-block'> 2 <div id='edit-link-list-block'>
3 <table id='links' class='noborder'> 3 <table id='links' class='noborder'>
4 - <tr><th><%= _('Icon') %></th><th><%= _('Name') %></th><th><%= _('Address') %></th><th><%= _('Target') %></th></tr> 4 + <tr>
  5 + <th><%= _('Icon') %></th>
  6 + <th><%= _('Name') %></th>
  7 + <th><%= _('Address') %></th>
  8 + <th><%= _('Title') %></th>
  9 + <th><%= _('Target') %></th>
  10 + </tr>
5 <% for link in @block.links do %> 11 <% for link in @block.links do %>
6 - <tr>  
7 - <td>  
8 - <%= icon_selector(link['icon']) %>  
9 - </td>  
10 - <td><%= text_field_tag 'block[links][][name]', link[:name], :class => 'link-name', :maxlength => 20 %></td>  
11 - <td class='cel-address'><%= text_field_tag 'block[links][][address]', link[:address], :class => 'link-address' %></td>  
12 - <td>  
13 - <%= select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, link[:target])) %>  
14 - </td>  
15 - </tr> 12 + <tr>
  13 + <td><%= icon_selector(link['icon']) %></td>
  14 + <td><%= text_field_tag 'block[links][][name]', link[:name], :class => 'link-name', :maxlength => 20 %></td>
  15 + <td class='cel-address'><%= text_field_tag 'block[links][][address]', link[:address], :class => 'link-address' %></td>
  16 + <td><%= text_field_tag 'block[links][][title]', link[:title], :class => 'link-title' %></td>
  17 + <td><%= select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, link[:target])) %></td>
  18 + </tr>
16 <% end %> 19 <% end %>
17 </table> 20 </table>
18 </div> 21 </div>
@@ -22,8 +25,8 @@ @@ -22,8 +25,8 @@
22 content_tag('td', icon_selector('ok')) + 25 content_tag('td', icon_selector('ok')) +
23 content_tag('td', text_field_tag('block[links][][name]', '', :maxlength => 20)) + 26 content_tag('td', text_field_tag('block[links][][name]', '', :maxlength => 20)) +
24 content_tag('td', text_field_tag('block[links][][address]', nil, :class => 'link-address'), :class => 'cel-address') + 27 content_tag('td', text_field_tag('block[links][][address]', nil, :class => 'link-address'), :class => 'cel-address') +
25 - content_tag('td', select_tag('block[links][][target]',  
26 -options_for_select(LinkListBlock::TARGET_OPTIONS, '_self'))) 28 + content_tag('td', text_field_tag('block[links][][title]', '', :class => 'link-title')) +
  29 + content_tag('td', select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, '_self')))
27 ) + 30 ) +
28 javascript_tag("$('edit-link-list-block').scrollTop = $('edit-link-list-block').scrollHeight") 31 javascript_tag("$('edit-link-list-block').scrollTop = $('edit-link-list-block').scrollHeight")
29 end %> 32 end %>
app/views/catalog/index.rhtml
1 <% extra_content = [] %> 1 <% extra_content = [] %>
2 <% extra_content_list = [] %> 2 <% extra_content_list = [] %>
3 3
4 -<h1><%= _('Products/Services') %></h1>  
5 -  
6 -<% if @categories %>  
7 - <%= breadcrumb(@category) if params[:level] %>  
8 -  
9 - <div class='l-sidebar-left-bar'>  
10 - <ul>  
11 - <%= content_tag('li', link_to(_('Homepage'), profile.url), :class => 'catalog-categories-link') %>  
12 - <%= content_tag('li', link_to(_('Catalog start'), profile.catalog_url), :class => 'catalog-categories-link') %>  
13 - <% if @categories.present? %>  
14 - <% @categories.each do |category| %>  
15 - <%= category_link(category) %>  
16 - <%= category_sub_links(category) %>  
17 - <% end %>  
18 - <% elsif @category.present? %>  
19 - <%= content_tag('li', _('There are no sub-categories for %s') % @category.name, :id => 'catalog-categories-notice') %>  
20 - <% else %>  
21 - <%= content_tag('li', _('There are no categories available.'), :id => 'catalog-categories-notice') %>  
22 - <% end %>  
23 - </ul> 4 +<div id="product-catalog">
  5 +<% if !user.nil? && ( user.is_admin?(profile.environment) || user.is_admin?(profile) ) %>
  6 + <div class="product-catalog-ctrl">
  7 + <%= button :product, _('Manage Products/Services'), :controller => 'manage_products' %>
24 </div> 8 </div>
25 <% end %> 9 <% end %>
26 10
27 -<ul id="product-list" class="<%="l-sidebar-left-content" if @categories %>"> 11 +<h1><%= _('Products/Services') %></h1>
  12 +
  13 +<%= breadcrumb(@category) if params[:level] %>
  14 +
  15 +<ul id="product-list">
28 <% @products.each do |product| %> 16 <% @products.each do |product| %>
29 <% extra_content = @plugins.dispatch(:catalog_item_extras, product).collect { |content| instance_eval(&content) } %> 17 <% extra_content = @plugins.dispatch(:catalog_item_extras, product).collect { |content| instance_eval(&content) } %>
30 <% extra_content_list = @plugins.dispatch(:catalog_list_item_extras, product).collect { |content| instance_eval(&content) } %> 18 <% extra_content_list = @plugins.dispatch(:catalog_list_item_extras, product).collect { |content| instance_eval(&content) } %>
@@ -132,10 +120,11 @@ @@ -132,10 +120,11 @@
132 </ul> 120 </ul>
133 </li> 121 </li>
134 <% end %> 122 <% end %>
135 -</ul> 123 +</ul><!-- end id="product-list" -->
136 124
137 <%= pagination_links @products, :params => {:controller => :catalog, :action => :index, :profile => profile.identifier} %> 125 <%= pagination_links @products, :params => {:controller => :catalog, :action => :index, :profile => profile.identifier} %>
138 126
139 <%= add_zoom_to_images %> 127 <%= add_zoom_to_images %>
140 128
141 <br style="clear:both"/> 129 <br style="clear:both"/>
  130 +</div><!-- end id="product-catalog" -->
app/views/cms/edit.rhtml
@@ -40,6 +40,7 @@ @@ -40,6 +40,7 @@
40 40
41 <% button_bar do %> 41 <% button_bar do %>
42 <%= submit_button :save, _('Save') %> 42 <%= submit_button :save, _('Save') %>
  43 +
43 <% if @back_to %> 44 <% if @back_to %>
44 <%= button :cancel, _('Cancel'), @back_to %> 45 <%= button :cancel, _('Cancel'), @back_to %>
45 <% elsif @parent_id || @article.parent %> 46 <% elsif @parent_id || @article.parent %>
@@ -47,6 +48,11 @@ @@ -47,6 +48,11 @@
47 <% else %> 48 <% else %>
48 <%= button :cancel, _('Cancel'), :action => 'index' %> 49 <%= button :cancel, _('Cancel'), :action => 'index' %>
49 <% end %> 50 <% end %>
  51 +
  52 + <% unless @article.new_record? %>
  53 + <%= button :delete, _('Delete'), {:controller => :cms, :action => :destroy, :id => @article},
  54 + :method => :post, :confirm => delete_article_message(@article) %>
  55 + <% end %>
50 <% end %> 56 <% end %>
51 <% end %> 57 <% end %>
52 </div> 58 </div>
app/views/comment/_comment.rhtml
@@ -32,19 +32,7 @@ @@ -32,19 +32,7 @@
32 32
33 <div class="comment-details"> 33 <div class="comment-details">
34 <div class="comment-header"> 34 <div class="comment-header">
35 - <ul>  
36 - <div class="comment-actions">  
37 - <%= comment_actions(comment) %>  
38 - </div>  
39 - </ul>  
40 - <% unless comment.spam? %>  
41 - <%= link_to_function '',  
42 - "var f = add_comment_reply_form(this, %s); f.find('comment_title, textarea').val(''); return false" % comment.id,  
43 - :class => 'comment-footer comment-footer-link comment-footer-hide comment-actions-reply button',  
44 - :id => 'comment-reply-to-' + comment.id.to_s,  
45 - :title => _('Reply')  
46 - %>  
47 - <% end %> 35 + <%= comment_actions(comment) %>
48 </div> 36 </div>
49 37
50 <div class="comment-created-at"> 38 <div class="comment-created-at">
@@ -55,6 +43,7 @@ @@ -55,6 +43,7 @@
55 <p/> 43 <p/>
56 <%= txt2html comment.body %> 44 <%= txt2html comment.body %>
57 </div> 45 </div>
  46 + <%= @plugins.dispatch(:comment_extra_contents, local_assigns).collect { |content| instance_eval(&content) }.join("") %>
58 </div> 47 </div>
59 48
60 <div class="comment_reply post_comment_box closed" id="comment_reply_to_<%= comment.id %>"> 49 <div class="comment_reply post_comment_box closed" id="comment_reply_to_<%= comment.id %>">
app/views/comment/_comment_actions.rhtml 0 → 100644
@@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
  1 +<ul>
  2 + <% if !links_submenu.empty? %>
  3 + <div class="comment-actions">
  4 + <li class="vcard">
  5 + <%= link_to(content_tag(:span, _('Contents menu')), '#', :onclick => "toggleSubmenu(this,'',#{links_submenu.to_json}); return false", :class => 'menu-submenu-trigger comment-trigger', :url => url) %>
  6 + </li>
  7 + </div>
  8 + <% end %>
  9 +</ul>
  10 +<div class="comments-action-bar">
  11 + <% unless comment.spam? %>
  12 + <%= link_to_function '',
  13 + "var f = add_comment_reply_form(this, %s); f.find('comment_title, textarea').val(''); return false" % comment.id,
  14 + :class => 'comment-footer comment-footer-link comment-footer-hide comment-actions-reply button',
  15 + :id => 'comment-reply-to-' + comment.id.to_s,
  16 + :title => _('Reply')
  17 + %>
  18 + <% end %>
  19 + <% links_action_bar.collect do |link| %>
  20 + <%= link[:link] %>
  21 + <% end %>
  22 +</div>
app/views/content_viewer/_addthis.rhtml 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +<div id="addThis">
  2 + <script type="text/javascript">
  3 + addthis_pub = '<%= escape_javascript( NOOSFERO_CONF['addthis_pub'] ) %>';
  4 + addthis_logo = '<%= escape_javascript( NOOSFERO_CONF['addthis_logo'] ) %>';
  5 + addthis_options = '<%= escape_javascript( NOOSFERO_CONF['addthis_options'] ) %>';
  6 + </script>
  7 + <a href="http://www.addthis.com/bookmark.php" id="bt_addThis" target="_blank" onmouseover="return addthis_open(this, '', '[URL]')" onmouseout="addthis_close()" onclick="return addthis_sendto()"><%= addthis_image_tag %></a>
  8 +</div>
app/views/content_viewer/_article_toolbar.rhtml
@@ -26,7 +26,7 @@ @@ -26,7 +26,7 @@
26 <%= expirable_button @page, :spread, content, url if url %> 26 <%= expirable_button @page, :spread, content, url if url %>
27 <% end %> 27 <% end %>
28 28
29 - <% if !@page.gallery? && @page.allow_create?(user) %> 29 + <% if !@page.gallery? && (@page.allow_create?(user) || (@page.parent && @page.parent.allow_create?(user))) %>
30 <% if @page.translatable? && !@page.native_translation.language.blank? && !remove_content_button(:locale) %> 30 <% if @page.translatable? && !@page.native_translation.language.blank? && !remove_content_button(:locale) %>
31 <% content = _('Add translation') %> 31 <% content = _('Add translation') %>
32 <% parent_id = (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)) %> 32 <% parent_id = (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)) %>
@@ -48,6 +48,10 @@ @@ -48,6 +48,10 @@
48 <%= expirable_button @page, :suggest, content, url, options %> 48 <%= expirable_button @page, :suggest, content, url, options %>
49 <% end %> 49 <% end %>
50 50
  51 + <% if @page.display_versions? %>
  52 + <%= button(:clock, _('All versions'), {:controller => 'content_viewer', :profile => profile.identifier, :action => 'article_versions'}, :id => 'article-versions-link') %>
  53 + <% end %>
  54 +
51 <%= report_abuse(profile, :link, @page) %> 55 <%= report_abuse(profile, :link, @page) %>
52 56
53 </div> 57 </div>
@@ -56,6 +60,7 @@ @@ -56,6 +60,7 @@
56 <div class="blog-cover"><%= image_tag(@page.image.public_filename())%></div> 60 <div class="blog-cover"><%= image_tag(@page.image.public_filename())%></div>
57 <% end %> 61 <% end %>
58 <%= link_to(image_tag('icons-mime/rss-feed.png'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %> 62 <%= link_to(image_tag('icons-mime/rss-feed.png'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %>
  63 + <%= @plugins.dispatch(:article_header_extra_contents, @page).collect { |content| instance_eval(&content) }.join("") %>
59 <%= article_title(@page, :no_link => true) %> 64 <%= article_title(@page, :no_link => true) %>
60 <%= article_translations(@page) %> 65 <%= article_translations(@page) %>
61 </div> 66 </div>
app/views/content_viewer/article_versions.rhtml 0 → 100644
@@ -0,0 +1,58 @@ @@ -0,0 +1,58 @@
  1 +<div class="article-versions">
  2 + <%= button(:back, _('Go back to latest version'), {:action => 'view_page'}) %>
  3 +</div>
  4 +
  5 +<%= article_title(@page, :no_link => true) %>
  6 +
  7 +<p><%= _('This is the list of all versions of this content. Select a version to see it and then revert to it.') %>.</p>
  8 +
  9 +<% form_tag({:controller => 'content_viewer', :action => 'versions_diff', :profile => profile.identifier, :page => @page.path.split('/')}, :method => 'get') do %>
  10 + <ul id="article-versions">
  11 + <% @versions.each do |v| %>
  12 + <li>
  13 + <%= radio_button_tag 'v1', v.version, false, :onclick => 'versionInputClicked(this)' %>
  14 + <%= radio_button_tag 'v2', v.version, false, :onclick => 'versionInputClicked(this)' %>
  15 + <%= link_to(_("Version #{v.version}"), @page.url.merge(:version => v.version)) %>
  16 + <%= @page.version == v.version ? _('(current)') : '' %>
  17 + <span class='updated-by'><%= _('by %{author}') % {:author => link_to(@page.author_name(v.version), @page.author_url(v.version))} %></span>
  18 + <span class='updated-on'><%= show_time(v.updated_at) %></span>
  19 + </li>
  20 + <% end %>
  21 + </ul>
  22 +
  23 +<script>
  24 + function versionInputClicked(input) {
  25 + var selectedColumn = input.name;
  26 + var sisterColumn = (selectedColumn == 'v1') ? 'v2' : 'v1';
  27 + var li = input.parentNode;
  28 + var checkedBrotherLi = jQuery('#article-versions input[name=' + sisterColumn + ']:checked').parent()[0];
  29 + updateColumn(selectedColumn, li);
  30 + updateColumn(sisterColumn, checkedBrotherLi);
  31 + }
  32 +
  33 + function updateColumn(selectedColumn, startLi){
  34 + var sisterColumn = (selectedColumn == 'v1') ? 'v2' : 'v1';
  35 + var walkMethod = (selectedColumn == 'v1') ? 'prev' : 'next';
  36 + var li = startLi;
  37 + var foundCheckedBrother = false;
  38 + while(li = jQuery(li)[walkMethod]()[0]) {
  39 + li.className = '';
  40 + if (!foundCheckedBrother){
  41 + li.className = 'selected';
  42 + foundCheckedBrother = jQuery('input[name=' + sisterColumn + ']', li)[0].checked;
  43 + }
  44 + jQuery('input[name=' + selectedColumn + ']', li)[0].disabled = foundCheckedBrother;
  45 + }
  46 + }
  47 +
  48 + var penultVersion = jQuery('#article-versions input[name=v1]')[1];
  49 + var lastVersion = jQuery('#article-versions input[name=v2]')[0];
  50 + jQuery('#article-versions input').attr('disabled', false);
  51 + if (penultVersion && lastVersion) {
  52 + penultVersion.checked = lastVersion.checked = true;
  53 + lastVersion.onclick();
  54 + }
  55 +</script>
  56 + <%= submit_button(:clock, _('Show differences between selected versions')) %>
  57 +<% end %>
  58 +<%= pagination_links @versions, :param_name => 'npage' %>
app/views/content_viewer/versioned_article.rhtml 0 → 100644
@@ -0,0 +1,53 @@ @@ -0,0 +1,53 @@
  1 +<div class="article-versions">
  2 + <%= button(:back, _('Back to the versions'), {:action => 'article_versions'}) %>
  3 +</div>
  4 +
  5 +<div id="article" class="<%= @page.css_class_name %>">
  6 +
  7 + <div id="article-actions">
  8 + <%= button(:clock, _('All versions'), {:controller => 'content_viewer', :profile => profile.identifier, :action => 'article_versions'}, :id => 'article-versions-link') %>
  9 +
  10 + <% if @page.allow_edit?(user) && !remove_content_button(:undo) %>
  11 + <% content = content_tag('span', _('Revert to this version')) %>
  12 + <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'edit', :id => @page.id, :version => @version }) %>
  13 + <%= expirable_button @page, :undo, content, url, :id => 'article-revert-version-link' %>
  14 + <% end %>
  15 +
  16 + <%= button(:forward, _('Go to latest version'), {:action => 'view_page'}) %>
  17 +</div>
  18 + <div id="article-header">
  19 + <h1 class='title'><%= @versioned_article.name %></h1>
  20 + <%= _("Version %{version} - %{author} on %{date}") % {:version => @version, :author => @page.author_name(@version), :date => show_time(@versioned_article.updated_at) } %>
  21 + </div>
  22 +
  23 + <p id="no-current-version">
  24 + <%= _('This is not the latest version of this content.') %>
  25 + </p>
  26 +</div>
  27 +
  28 + <% version_license = @page.version_license(@version) %>
  29 + <%# This seemingly doubled verification exists because the article-sub-header
  30 + div must appear only if at least one content inside it will appear.
  31 + Although we have only one content now, we might have others in the future.
  32 + So we're keeping it like that to avoid mistakes. %>
  33 + <% if version_license.present? %>
  34 + <div id='article-sub-header'>
  35 + <% if version_license.present? %>
  36 + <div id="article-license">
  37 + <%= _('Licensed under %s') % (version_license.url.present? ? link_to(version_license.name, version_license.url, :target => '_blank') : version_license.name) %>
  38 + </div>
  39 + <% end %>
  40 + </div>
  41 + <% end %>
  42 +
  43 + <% cache(@page.cache_key(params, user, language)) do %>
  44 + <div class="<%="article-body article-body-" + @page.css_class_name %>">
  45 + <%= @versioned_article.body %>
  46 + <br style="clear:both" />
  47 + </div> <!-- end class="article-body" -->
  48 + <% end %>
  49 +
  50 + <%= display_source_info(@page) %>
  51 +
  52 +</div><!-- end id="article" -->
  53 +<%= add_zoom_to_article_images %>
app/views/content_viewer/versions_diff.html.erb 0 → 100644
@@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
  1 +<div class="article-versions">
  2 +<%= button(:back, _('Back to the versions'), {:action => 'article_versions'}) %>
  3 +</div>
  4 +
  5 +<h1><%= _('Changes on "%s"') % @page.title %></h1>
  6 +
  7 +<p> <%= _('Changes from %s &rarr; %s') % [show_time(@v1.updated_at), show_time(@v2.updated_at)] %> </p>
  8 +
  9 +<% diffContent = Diffy::Diff.new(@v1.body, @v2.body, :context => 1) %>
  10 +<% if diffContent.to_s(:text).blank? %>
  11 + <p id="article-versions-no-diff">
  12 + <%= _('These versions range have no differences.')%>
  13 + </p>
  14 +<% else %>
  15 + <%= diffContent.to_s(:html) %>
  16 +<% end %>
app/views/content_viewer/view_page.rhtml
@@ -15,16 +15,14 @@ @@ -15,16 +15,14 @@
15 </script> 15 </script>
16 16
17 <% if @page.parent && !@page.parent.path.blank? %> 17 <% if @page.parent && !@page.parent.path.blank? %>
18 -<div id="article-parent">  
19 - <%= button(:back, _('Go back to %s') % @page.parent.short_title, @page.parent.url) %>  
20 -</div> 18 + <div id="article-parent">
  19 + <%= button(:back, _('Go back to %s') % @page.parent.short_title, @page.parent.url) %>
  20 + </div>
21 <% end %> 21 <% end %>
22 22
23 -<div id="article-toolbar"></div>  
24 -  
25 -<script type="text/javascript">  
26 - <%= remote_function :update => "article-toolbar", :url => @page.url.merge({ :toolbar => true, :only_path => true }) %>  
27 -</script> 23 +<div id="article-toolbar">
  24 + <%= render :partial => 'article_toolbar' %>
  25 +</div>
28 26
29 <% if @page.display_hits? || @page.license.present? %> 27 <% if @page.display_hits? || @page.license.present? %>
30 <div id='article-sub-header'> 28 <div id='article-sub-header'>
@@ -42,32 +40,10 @@ @@ -42,32 +40,10 @@
42 </div> 40 </div>
43 <% end %> 41 <% end %>
44 42
45 -<% if !@page.tags.empty? %>  
46 - <div id="article-tags">  
47 - <%= _("This article's tags:") %>  
48 - <%= @page.tags.map { |t| link_to(t, :controller => 'profile', :profile => @profile.identifier, :action => 'tags', :id => t.name ) }.join("\n") %>  
49 - </div>  
50 -<% end %>  
51 -  
52 -  
53 <%= render :partial => 'shared/disabled_enterprise' %> 43 <%= render :partial => 'shared/disabled_enterprise' %>
54 44
55 <% if NOOSFERO_CONF['addthis_enabled'] %> 45 <% if NOOSFERO_CONF['addthis_enabled'] %>
56 -<div id="addThis">  
57 -<script type="text/javascript">  
58 - addthis_pub = '<%= escape_javascript( NOOSFERO_CONF['addthis_pub'] ) %>';  
59 - addthis_logo = '<%= escape_javascript( NOOSFERO_CONF['addthis_logo'] ) %>';  
60 - addthis_config = {  
61 - services_custom: {  
62 - name: 'Facebook',  
63 - url: '<%= addthis_facebook_url(@page) %>',  
64 - icon: 'http://cache.addthiscdn.com/icons/v1/thumbs/facebook.gif'  
65 - }  
66 - };  
67 - addthis_options = '<%= escape_javascript( NOOSFERO_CONF['addthis_options'] ) %>';  
68 -</script>  
69 -<a href="https://www.addthis.com/bookmark.php" id="bt_addThis" target="_blank" onmouseover="return addthis_open(this, '', '[URL]')" onmouseout="addthis_close()" onclick="return addthis_sendto()"><%= addthis_image_tag %></a>  
70 -</div> 46 + <%= render :partial => 'addthis' %>
71 <% end %> 47 <% end %>
72 48
73 <% cache(@page.cache_key(params, user, language)) do %> 49 <% cache(@page.cache_key(params, user, language)) do %>
@@ -85,8 +61,17 @@ @@ -85,8 +61,17 @@
85 </div> 61 </div>
86 <% end %> 62 <% end %>
87 63
  64 +<% if !@page.tags.empty? %>
  65 + <div id="article-tags">
  66 + <%= _("This article's tags:") %>
  67 + <%= @page.tags.map { |t| link_to(t, :controller => 'profile', :profile => @profile.identifier, :action => 'tags', :id => t.name ) }.join("\n") %>
  68 + </div>
  69 +<% end %>
  70 +
88 <%= display_source_info(@page) %> 71 <%= display_source_info(@page) %>
89 72
  73 +<%= @plugins.dispatch(:article_extra_contents, @page).collect { |content| instance_eval(&content) }.join("") %>
  74 +
90 <div class="comments" id="comments_list"> 75 <div class="comments" id="comments_list">
91 76
92 <% if @page.accept_comments? || @comments_count > 0 %> 77 <% if @page.accept_comments? || @comments_count > 0 %>
app/views/environment_themes/index.rhtml 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +<%= render :partial => 'themes/select_template' %>
  2 +<%= render :partial => 'themes/select_theme' %>
  3 +
  4 +<br style="clear:both" />
  5 +
  6 +<% button_bar do %>
  7 + <%= button(:back, _('Back'), :controller => 'admin_panel', :action => 'index') %>
  8 +<% end %>
app/views/features/_manage_community_fields.rhtml
1 -<h2><%= __('Manage community fields') %></h2>  
2 -  
3 <% labelled_form_for(:environment, @environment, :url => {:action => 'manage_community_fields'}) do |f| %> 1 <% labelled_form_for(:environment, @environment, :url => {:action => 'manage_community_fields'}) do |f| %>
4 2
5 <table id='community_fields_conf'> 3 <table id='community_fields_conf'>
@@ -9,21 +7,37 @@ @@ -9,21 +7,37 @@
9 <th><%= _('Required') %></th> 7 <th><%= _('Required') %></th>
10 <th><%= _('Display on creation?') %></th> 8 <th><%= _('Display on creation?') %></th>
11 </tr> 9 </tr>
  10 +
  11 + <tr class='manage-fields-batch-actions'>
  12 + <td>
  13 + <%= _("Check/Uncheck All")%>
  14 + </td>
  15 + <td>
  16 + <input type="checkbox" id="community_active" />
  17 + </td>
  18 + <td>
  19 + <input type="checkbox" id="community_required" />
  20 + </td>
  21 + <td>
  22 + <input type="checkbox" id="community_signup" />
  23 + </td>
  24 + </tr>
  25 +
12 <% @community_fields.each do |field| %> 26 <% @community_fields.each do |field| %>
13 <tr> 27 <tr>
14 <td><label for="community_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td> 28 <td><label for="community_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td>
15 29
16 <td> 30 <td>
17 <%= hidden_field_tag "community_fields[#{field}][active]", false %> 31 <%= hidden_field_tag "community_fields[#{field}][active]", false %>
18 - <%= check_box_tag "community_fields[#{field}][active]", true, environment.custom_community_field(field, 'active'), :onclick => "$('community_fields[#{field}][required]').disabled=$('community_fields[#{field}][signup]').disabled=!this.checked;" %> 32 + <%= check_box_tag "community_fields[#{field}][active]", true, environment.custom_community_field(field, 'active'), :onclick => "active_action(this, 'community_fields[#{field}][required]', 'community_fields[#{field}][signup]')" %>
19 </td> 33 </td>
20 <td> 34 <td>
21 <%= hidden_field_tag "community_fields[#{field}][required]", false %> 35 <%= hidden_field_tag "community_fields[#{field}][required]", false %>
22 - <%= check_box_tag "community_fields[#{field}][required]", true, environment.custom_community_field(field, 'required'), :onclick => "if(this.checked) $('community_fields[#{field}][signup]').checked = true;" %> 36 + <%= check_box_tag "community_fields[#{field}][required]", true, environment.custom_community_field(field, 'required'), :onclick => "required_action('community_fields[#{field}][active]','community_fields[#{field}][required]', 'community_fields[#{field}][signup]')" %>
23 </td> 37 </td>
24 <td> 38 <td>
25 <%= hidden_field_tag "community_fields[#{field}][signup]", false %> 39 <%= hidden_field_tag "community_fields[#{field}][signup]", false %>
26 - <%= check_box_tag "community_fields[#{field}][signup]", true, environment.custom_community_field(field, 'signup'), :onclick => "if(!this.checked) $('community_fields[#{field}][required]').checked = false;" %> 40 + <%= check_box_tag "community_fields[#{field}][signup]", true, environment.custom_community_field(field, 'signup'), :onclick => "signup_action('community_fields[#{field}][active]','community_fields[#{field}][required]', 'community_fields[#{field}][signup]')" %>
27 </td> 41 </td>
28 42
29 </tr> 43 </tr>
@@ -31,18 +45,18 @@ @@ -31,18 +45,18 @@
31 </table> 45 </table>
32 46
33 <script type='text/javascript'> 47 <script type='text/javascript'>
34 - var trs = $$('#community_fields_conf tr'); 48 + var trs = jQuery('#community_fields_conf tr');
35 var tr, td2; 49 var tr, td2;
36 - for ( var i=0; tr=trs[i]; i++ ) { 50 + for ( var i=2; tr=trs[i]; i++ ) {
37 if ( td2 = tr.getElementsByTagName('td')[1] ) { 51 if ( td2 = tr.getElementsByTagName('td')[1] ) {
38 - td2.getElementsByTagName('input')[0].onclick(); 52 + td2.getElementsByTagName('input')[1].onclick();
39 } 53 }
40 } 54 }
41 </script> 55 </script>
42 56
43 <div> 57 <div>
44 <% button_bar do %> 58 <% button_bar do %>
45 - <%= submit_button('save', _('Save changes')) %> 59 + <%= submit_button('save', _('Save changes'), :id=>"save_community_fields") %>
46 <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %> 60 <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %>
47 <% end %> 61 <% end %>
48 </div> 62 </div>
app/views/features/_manage_enterprise_fields.rhtml
1 -<h2><%= __('Manage enterprise fields') %></h2>  
2 -  
3 <% labelled_form_for(:environment, @environment, :url => {:action => 'manage_enterprise_fields'}) do |f| %> 1 <% labelled_form_for(:environment, @environment, :url => {:action => 'manage_enterprise_fields'}) do |f| %>
4 2
5 <table id='enterprise_fields_conf'> 3 <table id='enterprise_fields_conf'>
@@ -9,21 +7,37 @@ @@ -9,21 +7,37 @@
9 <th><%= _('Required') %></th> 7 <th><%= _('Required') %></th>
10 <th><%= _('Display on registration?') %></th> 8 <th><%= _('Display on registration?') %></th>
11 </tr> 9 </tr>
  10 +
  11 + <tr class='manage-fields-batch-actions'>
  12 + <td>
  13 + <%= _("Check/Uncheck All")%>
  14 + </td>
  15 + <td>
  16 + <input type="checkbox" id="enterprise_active" />
  17 + </td>
  18 + <td>
  19 + <input type="checkbox" id="enterprise_required" />
  20 + </td>
  21 + <td>
  22 + <input type="checkbox" id="enterprise_signup" />
  23 + </td>
  24 + </tr>
  25 +
12 <% @enterprise_fields.each do |field| %> 26 <% @enterprise_fields.each do |field| %>
13 <tr> 27 <tr>
14 28
15 <td><label for="enterprise_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td> 29 <td><label for="enterprise_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td>
16 <td> 30 <td>
17 <%= hidden_field_tag "enterprise_fields[#{field}][active]", false %> 31 <%= hidden_field_tag "enterprise_fields[#{field}][active]", false %>
18 - <%= check_box_tag "enterprise_fields[#{field}][active]", true, environment.custom_enterprise_field(field, 'active'), :onclick => "$('enterprise_fields[#{field}][required]').disabled=$('enterprise_fields[#{field}][signup]').disabled=!this.checked;" %> 32 + <%= check_box_tag "enterprise_fields[#{field}][active]", true, environment.custom_enterprise_field(field, 'active'), :onclick => "active_action(this, 'enterprise_fields[#{field}][required]', 'enterprise_fields[#{field}][signup]')" %>
19 </td> 33 </td>
20 <td> 34 <td>
21 <%= hidden_field_tag "enterprise_fields[#{field}][required]", false %> 35 <%= hidden_field_tag "enterprise_fields[#{field}][required]", false %>
22 - <%= check_box_tag "enterprise_fields[#{field}][required]", true, environment.custom_enterprise_field(field, 'required'), :onclick => "if(this.checked) $('enterprise_fields[#{field}][signup]').checked = true;" %> 36 + <%= check_box_tag "enterprise_fields[#{field}][required]", true, environment.custom_enterprise_field(field, 'required'), :onclick => "required_action('enterprise_fields[#{field}][active]','enterprise_fields[#{field}][required]', 'enterprise_fields[#{field}][signup]')" %>
23 </td> 37 </td>
24 <td> 38 <td>
25 <%= hidden_field_tag "enterprise_fields[#{field}][signup]", false %> 39 <%= hidden_field_tag "enterprise_fields[#{field}][signup]", false %>
26 - <%= check_box_tag "enterprise_fields[#{field}][signup]", true, environment.custom_enterprise_field(field, 'signup'), :onclick => "if(!this.checked) $('enterprise_fields[#{field}][required]').checked = false;" %> 40 + <%= check_box_tag "enterprise_fields[#{field}][signup]", true, environment.custom_enterprise_field(field, 'signup'), :onclick => "signup_action('enterprise_fields[#{field}][active]','enterprise_fields[#{field}][required]', 'enterprise_fields[#{field}][signup]')" %>
27 </td> 41 </td>
28 42
29 </tr> 43 </tr>
@@ -31,18 +45,18 @@ @@ -31,18 +45,18 @@
31 </table> 45 </table>
32 46
33 <script type='text/javascript'> 47 <script type='text/javascript'>
34 - var trs = $$('#enterprise_fields_conf tr'); 48 + var trs = jQuery('#enterprise_fields_conf tr');
35 var tr, td2; 49 var tr, td2;
36 - for ( var i=0; tr=trs[i]; i++ ) { 50 + for ( var i=2; tr=trs[i]; i++ ) {
37 if ( td2 = tr.getElementsByTagName('td')[1] ) { 51 if ( td2 = tr.getElementsByTagName('td')[1] ) {
38 - td2.getElementsByTagName('input')[0].onclick(); 52 + td2.getElementsByTagName('input')[1].onclick();
39 } 53 }
40 } 54 }
41 </script> 55 </script>
42 56
43 <div> 57 <div>
44 <% button_bar do %> 58 <% button_bar do %>
45 - <%= submit_button('save', _('Save changes')) %> 59 + <%= submit_button('save', _('Save changes'), :id=>"save_enterprise_fields") %>
46 <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %> 60 <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %>
47 <% end %> 61 <% end %>
48 </div> 62 </div>
app/views/features/_manage_person_fields.rhtml
1 -<h2><%= _('Manage person fields') %></h2>  
2 -  
3 <% labelled_form_for(:environment, @environment, :url => {:action => 'manage_person_fields'}) do |f| %> 1 <% labelled_form_for(:environment, @environment, :url => {:action => 'manage_person_fields'}) do |f| %>
4 2
5 <table id='person_fields_conf'> 3 <table id='person_fields_conf'>
@@ -9,31 +7,48 @@ @@ -9,31 +7,48 @@
9 <th><%= _('Required') %></th> 7 <th><%= _('Required') %></th>
10 <th><%= _('Display on signup?') %></th> 8 <th><%= _('Display on signup?') %></th>
11 </tr> 9 </tr>
  10 +
  11 + <tr class='manage-fields-batch-actions'>
  12 + <td>
  13 + <%= _("Check/Uncheck All")%>
  14 + </td>
  15 + <td>
  16 + <input type="checkbox" id="person_active" />
  17 + </td>
  18 + <td>
  19 + <input type="checkbox" id="person_required" />
  20 + </td>
  21 + <td>
  22 + <input type="checkbox" id="person_signup" />
  23 + </td>
  24 + </tr>
  25 +
12 <% @person_fields.each do |field| %> 26 <% @person_fields.each do |field| %>
13 <tr> 27 <tr>
14 <td><label for="person_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td> 28 <td><label for="person_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td>
15 <td> 29 <td>
16 <%= hidden_field_tag "person_fields[#{field}][active]", false %> 30 <%= hidden_field_tag "person_fields[#{field}][active]", false %>
17 - <%= check_box_tag "person_fields[#{field}][active]", true, environment.custom_person_field(field, 'active'), :onclick => "$('person_fields[#{field}][required]').disabled=$('person_fields[#{field}][signup]').disabled=!this.checked;" %> 31 + <%= check_box_tag "person_fields[#{field}][active]", true, environment.custom_person_field(field, 'active'), :onclick => "active_action(this, 'person_fields[#{field}][required]', 'person_fields[#{field}][signup]')" %>
18 </td> 32 </td>
19 <td> 33 <td>
20 <%= hidden_field_tag "person_fields[#{field}][required]", false %> 34 <%= hidden_field_tag "person_fields[#{field}][required]", false %>
21 - <%= check_box_tag "person_fields[#{field}][required]", true, environment.custom_person_field(field, 'required'), :onclick => "if(this.checked) $('person_fields[#{field}][signup]').checked = true;" %> 35 + <%= check_box_tag "person_fields[#{field}][required]", true, environment.custom_person_field(field, 'required'), :onclick => "required_action('person_fields[#{field}][active]','person_fields[#{field}][required]', 'person_fields[#{field}][signup]')" %>
22 </td> 36 </td>
23 <td> 37 <td>
24 <%= hidden_field_tag "person_fields[#{field}][signup]", false %> 38 <%= hidden_field_tag "person_fields[#{field}][signup]", false %>
25 - <%= check_box_tag "person_fields[#{field}][signup]", true, environment.custom_person_field(field, 'signup'), :onclick => "if(!this.checked) $('person_fields[#{field}][required]').checked = false;" %> 39 + <%= check_box_tag "person_fields[#{field}][signup]", true, environment.custom_person_field(field, 'signup'), :onclick => "signup_action('person_fields[#{field}][active]','person_fields[#{field}][required]', 'person_fields[#{field}][signup]')" %>
26 </td> 40 </td>
27 </tr> 41 </tr>
28 <% end %> 42 <% end %>
29 </table> 43 </table>
30 44
31 <script type='text/javascript'>// <!-- 45 <script type='text/javascript'>// <!--
32 - var trs = $$('#person_fields_conf tr'); 46 + var trs = jQuery('#person_fields_conf tr');
  47 +
33 var tr, td2; 48 var tr, td2;
34 - for ( var i=0; tr=trs[i]; i++ ) { 49 + for ( var i=2; tr=trs[i]; i++ ) {
35 if ( td2 = tr.getElementsByTagName('td')[1] ) { 50 if ( td2 = tr.getElementsByTagName('td')[1] ) {
36 - td2.getElementsByTagName('input')[0].onclick(); 51 + td2.getElementsByTagName('input')[1].onclick();
37 } 52 }
38 } 53 }
39 // --> 54 // -->
@@ -41,7 +56,7 @@ @@ -41,7 +56,7 @@
41 56
42 <div> 57 <div>
43 <% button_bar do %> 58 <% button_bar do %>
44 - <%= submit_button('save', _('Save changes')) %> 59 + <%= submit_button('save', _('Save changes'), :id=>"save_person_fields") %>
45 <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %> 60 <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %>
46 <% end %> 61 <% end %>
47 </div> 62 </div>
app/views/features/index.rhtml
@@ -26,9 +26,13 @@ Check all the features you want to enable for your environment, uncheck all the @@ -26,9 +26,13 @@ Check all the features you want to enable for your environment, uncheck all the
26 26
27 <h2><%= _('Configure features') %></h2> 27 <h2><%= _('Configure features') %></h2>
28 28
  29 +<h3><%= _('Page to redirect after signup') %></h3>
  30 + <%= select 'environment', 'redirection_after_signup', Environment.signup_redirection_options.map{|key,value|[value,key]} %>
  31 +<hr/>
29 <h3><%= _('Page to redirect after login') %></h3> 32 <h3><%= _('Page to redirect after login') %></h3>
30 <%= select 'environment', 'redirection_after_login', Environment.login_redirection_options.map{|key,value|[value,key]} %> 33 <%= select 'environment', 'redirection_after_login', Environment.login_redirection_options.map{|key,value|[value,key]} %>
31 <hr/> 34 <hr/>
  35 +
32 <h3><%= _('Organization Approval Method') %></h3> 36 <h3><%= _('Organization Approval Method') %></h3>
33 <%= select_organization_approval_method('environment', 'organization_approval_method') %> 37 <%= select_organization_approval_method('environment', 'organization_approval_method') %>
34 <hr/> 38 <hr/>
app/views/features/manage_fields.rhtml
1 -<%= render :partial => 'manage_person_fields' %> 1 +<h1><%= _('Manage fields displayed for profiles') %></h1>
2 2
3 -<% if !environment.enabled?('disable_asset_enterprises') %>  
4 - <%= render :partial => 'manage_enterprise_fields' %> 3 +<% tabs = [] %>
  4 +<% tabs << {:title => _("Person's fields"), :id => 'person-fields',
  5 + :content => (render :partial => 'manage_person_fields')} %>
  6 +<% tabs << {:title => _("Community's fields"), :id => 'community-fields',
  7 + :content => (render :partial => 'manage_community_fields')} %>
  8 +<% unless environment.enabled?('disable_asset_enterprises') %>
  9 + <% tabs << {:title => _("Enterprise's fields"), :id => 'enterprise-fields',
  10 + :content => (render :partial => 'manage_enterprise_fields')} %>
5 <% end %> 11 <% end %>
6 12
7 -<%= render :partial => 'manage_community_fields' %> 13 +<%= render_tabs(tabs) %>
  14 +
  15 +<%= javascript_include_tag "manage-fields.js" %>
app/views/layouts/application-ng.rhtml
@@ -6,6 +6,27 @@ @@ -6,6 +6,27 @@
6 <!--<meta http-equiv="refresh" content="1"/>--> 6 <!--<meta http-equiv="refresh" content="1"/>-->
7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
8 <meta name="description" content="<%= @environment.name %>" /> 8 <meta name="description" content="<%= @environment.name %>" />
  9 +
  10 + <!-- Twitter Card -->
  11 + <meta name="twitter:card" value="summary">
  12 + <meta name="twitter:title" content="<%= h page_title %>">
  13 + <meta name="twitter:description" content="<%= meta_description_tag(@page) %>">
  14 +
  15 + <!-- Open Graph -->
  16 + <meta property="og:type" content="<%= @page ? 'article' : 'website' %>">
  17 + <meta property="og:url" content="<%= @page ? url_for(@page.url) : @environment.top_url %>">
  18 + <meta property="og:title" content="<%= h page_title %>">
  19 + <meta property="og:site_name" content="<%= profile ? profile.name : @environment.name %>">
  20 + <meta property="og:description" content="<%= @page ? truncate(strip_tags(@page.body.to_s), :length => 200) : @environment.name %>">
  21 +
  22 + <% if @page %>
  23 + <meta property="article:published_time" content="<%= show_date(@page.published_at) %>">
  24 + <% @page.body_images_paths.each do |img| %>
  25 + <meta name="twitter:image" content="<%= img.to_s %>">
  26 + <meta property="og:image" content="<%= img.to_s %>">
  27 + <% end %>
  28 + <% end %>
  29 +
9 <link rel="shortcut icon" href="<%= image_path(theme_favicon) %>" type="image/x-icon" /> 30 <link rel="shortcut icon" href="<%= image_path(theme_favicon) %>" type="image/x-icon" />
10 <%= noosfero_javascript %> 31 <%= noosfero_javascript %>
11 <%= noosfero_stylesheets %> 32 <%= noosfero_stylesheets %>
app/views/person_notifier/mailer/_add_member_in_community.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= render :partial => 'default_activity', :locals => { :activity => activity } %>
app/views/person_notifier/mailer/_comment.rhtml 0 → 100644
@@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
  1 +<% Comment %>
  2 +<% Profile %>
  3 +<% Person %>
  4 +
  5 +<table style="background: #f0f0f1;border-bottom: 1px solid #d2d2d2 !important;border-top: 1px solid #fff;margin-bottom: 0;">
  6 +<tr>
  7 + <td>
  8 + <% if comment.author %>
  9 + <%= link_to profile_image(comment.author, :minor),
  10 + comment.author_url,
  11 + :class => 'comment-picture',
  12 + :title => comment.author_name
  13 + %>
  14 + <% end %>
  15 + </td>
  16 + <td>
  17 + <%= comment.author.present? ? link_to(comment.author_name, comment.author.url, :style => "font-size: 12px; color: #333; font-weight: bold; text-decoration: none;") : content_tag('strong', comment.author_name) %>
  18 + <% unless comment.title.blank? %>
  19 + <span style="font-size: 12px;"><%= comment.title %></span><br/>
  20 + <% end %>
  21 + <span style="font-size: 10px;"><%= txt2html comment.body %></span><br/>
  22 + <span style="font-size: 8px; color: #444444"><%= time_ago_as_sentence(comment.created_at) %></span>
  23 + <br style="clear: both;" />
  24 +
  25 + <% unless comment.replies.blank? %>
  26 + <ul class="comment-replies">
  27 + <% comment.replies.each do |reply| %>
  28 + <%= render :partial => 'comment', :locals => { :comment => reply } %>
  29 + <% end %>
  30 + </ul>
  31 + <% end %>
  32 + </td>
  33 +</table>
app/views/person_notifier/mailer/_create_article.rhtml 0 → 100644
@@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
  1 +<table>
  2 +<tr>
  3 + <td>
  4 + <%= link_to(profile_image(activity.user, :minor), activity.user.url) %>
  5 + </td>
  6 + <td>
  7 + <p style="width:550px">
  8 + <span style="font-size: 14px;"><%= link_to activity.user.short_name(20), activity.user.url %></span>
  9 + <span style="font-size: 14px;"><%= _("has published on community %s") % link_to(activity.target.profile.short_name(20), activity.target.profile.url, :style => "color: #333; font-weight: bold; text-decoration: none;") if activity.target.profile.is_a?(Community) %></span>
  10 + <span style="font-size: 10px; color: #444444; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span>
  11 + </p>
  12 + <p>
  13 + <span style="font-size: 14px;"><%= link_to(activity.params['name'], activity.params['url'], :style => "color: #333; font-weight: bold; text-decoration: none;") %></span>
  14 + <br/>
  15 + <span title='<%= activity.target.class.short_description %>' class='profile-activity-icon icon-new icon-new<%= activity.target.class.icon_name %>'></span>
  16 + <%= image_tag(activity.params['first_image']) unless activity.params['first_image'].blank? %><%= strip_tags(truncate(activity.params['lead'], :length => 1000, :ommision => '...')).gsub(/(\xC2\xA0|\s)+/, ' ').gsub(/^\s+/, '') %>
  17 + </p>
  18 + <p><%= content_tag(:p, link_to(_('See complete forum'), activity.get_url), :class => 'see-forum') if activity.target.is_a?(Forum) %></p>
  19 + </td>
  20 +</tr>
  21 +<tr>
  22 + <td></td>
  23 + <td>
  24 + <%= render :partial => 'profile_comments', :locals => { :activity => activity } %>
  25 + </td>
  26 +</tr>
  27 +</table>
app/views/person_notifier/mailer/_default_activity.rhtml 0 → 100644
@@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
  1 +<table>
  2 +<tr>
  3 + <td>
  4 + <%= link_to(profile_image(activity.user, :minor), activity.user.url) %>
  5 + </td>
  6 + <td>
  7 + <p style="width:550px">
  8 + <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span>
  9 + <span style="font-size: 10px; color: #444444; float: right;"><%= time_ago_as_sentence(activity.created_at) %></span>
  10 + </p>
  11 + </td>
  12 +</tr>
  13 +<tr>
  14 + <td></td>
  15 + <td>
  16 + <%= render :partial => 'profile_comments', :locals => { :activity => activity } %>
  17 + </td>
  18 +</tr>
  19 +</table>
app/views/person_notifier/mailer/_join_community.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= render :partial => 'default_activity', :locals => { :activity => activity } %>
app/views/person_notifier/mailer/_leave_scrap.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= render :partial => 'default_activity', :locals => { :activity => activity } %>
app/views/person_notifier/mailer/_leave_scrap_to_self.rhtml 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +_leave_scrap.rhtml
0 \ No newline at end of file 2 \ No newline at end of file
app/views/person_notifier/mailer/_new_friendship.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= render :partial => 'default_activity', :locals => { :activity => activity } %>
app/views/person_notifier/mailer/_profile_comments.rhtml 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +<% if activity.comments_count > 2 %>
  2 + <div style="font-size: 10px;">
  3 + <% if activity.params['url'].blank? %>
  4 + <%= _("%s comments") % activity.comments_count %>
  5 + <% else %>
  6 + <%= link_to(_("View all %s comments") % activity.comments_count, activity.params['url']) %>
  7 + <% end %>
  8 + </div>
  9 +<% else %>
  10 + <ul>
  11 + <%= render :partial => 'comment', :collection => activity.comments %>
  12 + </ul>
  13 +<% end %>
app/views/person_notifier/mailer/_reply_scrap_on_self.rhtml 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +_leave_scrap.rhtml
0 \ No newline at end of file 2 \ No newline at end of file
app/views/person_notifier/mailer/_upload_image.rhtml 0 → 100644
@@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
  1 +<table>
  2 + <tr>
  3 + <td>
  4 + <%= link_to(profile_image(activity.user, :minor), activity.user.url) %>
  5 + </td>
  6 + <td>
  7 + <p style="width:550px">
  8 + <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span>
  9 + <span style="font-size: 10px; color: #444444; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span>
  10 + </p>
  11 + </td>
  12 +</tr>
  13 +</table>
  14 +<div title='<%= activity.target.class.short_description %>' class='profile-activity-icon icon-new icon-newgallery'></div>
  15 +<br/>
app/views/person_notifier/mailer/content_summary.rhtml 0 → 100644
@@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
  1 +<h3><%= _("%s's network activity") % @profile.name %></h3>
  2 +<br/>
  3 +<div>
  4 +<% @notifications.each do |activity| %>
  5 + <div style="border-left:none;border-right:none;border-top:1px solid #ccc;border-bottom:none;padding:10px;width:600px">
  6 + <%= render :partial => activity.verb, :locals => { :activity => activity } rescue "cannot render notification for #{activity.verb}" %>
  7 + </div>
  8 +<% end %>
  9 +</div>
  10 +
  11 +<div style="color:#444444;font-size:11px;">
  12 +<p><%= _("Greetings,") %></p>
  13 +<br/>
  14 +<p>--</p>
  15 +<p><%= _('%s team.') % @environment %></p>
  16 +<p><%= url_for @url %></p>
  17 +</div>
  18 +<br/>
app/views/profile/_create_article.rhtml
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 <div class='profile-activity-description profile-activity-article-<%= activity.target.class.icon_name %>'> 4 <div class='profile-activity-description profile-activity-article-<%= activity.target.class.icon_name %>'>
5 <p class='profile-activity-text'> 5 <p class='profile-activity-text'>
6 <%= link_to activity.user.short_name(20), activity.user.url %> 6 <%= link_to activity.user.short_name(20), activity.user.url %>
7 - <%= _("on community %s") % link_to(activity.target.profile.short_name(20), activity.target.profile.url) if activity.target.profile.is_a?(Community) %> 7 + <%= _("has published on community %s") % link_to(activity.target.profile.short_name(20), activity.target.profile.url) if activity.target.profile.is_a?(Community) %>
8 </p> 8 </p>
9 <div class='profile-activity-lead'> 9 <div class='profile-activity-lead'>
10 <div class='article-name'><%= link_to(activity.params['name'], activity.params['url']) %></div> 10 <div class='article-name'><%= link_to(activity.params['name'], activity.params['url']) %></div>
app/views/profile/index.rhtml
@@ -19,22 +19,21 @@ @@ -19,22 +19,21 @@
19 <table class='profile'> 19 <table class='profile'>
20 <tr> 20 <tr>
21 <td colspan='2'> 21 <td colspan='2'>
22 - <% plugins_tabs = @plugins.dispatch(:profile_tabs).  
23 - map { |tab| {:title => tab[:title], :id => tab[:id], :content => instance_eval(&tab[:content]), :start => tab[:title]} }%> 22 + <% plugins_tabs = @plugins.dispatch(:profile_tabs).map { |tab| {:title => tab[:title], :id => tab[:id], :content => instance_eval(&tab[:content]), :start => tab[:title]} }%>
24 23
25 <% tabs = plugins_tabs.select { |tab| tab[:start] } %> 24 <% tabs = plugins_tabs.select { |tab| tab[:start] } %>
26 25
27 <% if @profile.organization? %> 26 <% if @profile.organization? %>
28 - <% tabs << {:title => _('Profile'), :id => 'organization-profile', :content => (render :partial => 'organization_profile')} %>  
29 <% if logged_in? && current_person.follows?(@profile) %> 27 <% if logged_in? && current_person.follows?(@profile) %>
30 <% tabs << {:title => _('Wall'), :id => 'profile-wall', :content => (render :partial => 'profile_wall')} %> 28 <% tabs << {:title => _('Wall'), :id => 'profile-wall', :content => (render :partial => 'profile_wall')} %>
31 <% end %> 29 <% end %>
  30 + <% tabs << {:title => _('Profile'), :id => 'organization-profile', :content => (render :partial => 'organization_profile')} %>
32 <% elsif @profile.person? %> 31 <% elsif @profile.person? %>
33 - <% tabs << {:title => _('Profile'), :id => 'person-profile', :content => (render :partial => 'person_profile')} %>  
34 <% if logged_in? && current_person.follows?(@profile) %> 32 <% if logged_in? && current_person.follows?(@profile) %>
35 <% tabs << {:title => _('Wall'), :id => 'profile-wall', :content => (render :partial => 'profile_wall')} %> 33 <% tabs << {:title => _('Wall'), :id => 'profile-wall', :content => (render :partial => 'profile_wall')} %>
36 <% tabs << {:title => _('Network'), :id => 'profile-network', :content => (render :partial => 'profile_network')} %> 34 <% tabs << {:title => _('Network'), :id => 'profile-network', :content => (render :partial => 'profile_network')} %>
37 <% end %> 35 <% end %>
  36 + <% tabs << {:title => _('Profile'), :id => 'person-profile', :content => (render :partial => 'person_profile')} %>
38 <% end %> 37 <% end %>
39 38
40 <% tabs += plugins_tabs.select { |tab| !tab[:start] } %> 39 <% tabs += plugins_tabs.select { |tab| !tab[:start] } %>
app/views/profile/profile_info.rjs
@@ -1,6 +0,0 @@ @@ -1,6 +0,0 @@
1 -if !user.nil? and user.has_permission?('edit_profile', profile)  
2 - page.replace_html "profile-admin-url-#{@block.id}", link_to(_('Control panel'), @block.owner.admin_url)  
3 -else  
4 - page.hide "profile-admin-url-#{@block.id}"  
5 -end  
6 -page.replace_html "profile-info-options-#{@block.id}", :file => view_for_profile_actions(@block.owner.class)  
app/views/profile_editor/_organization.rhtml
@@ -65,3 +65,8 @@ @@ -65,3 +65,8 @@
65 <%= labelled_check_box(_('Enable "contact us"'), 'profile_data[enable_contact_us]', "1", @profile.enable_contact_us) if @profile.enterprise? %> 65 <%= labelled_check_box(_('Enable "contact us"'), 'profile_data[enable_contact_us]', "1", @profile.enable_contact_us) if @profile.enterprise? %>
66 66
67 <%= render :partial => 'moderation', :locals => { :profile => @profile } %> 67 <%= render :partial => 'moderation', :locals => { :profile => @profile } %>
  68 +
  69 +<% if profile.enterprise? && profile.environment.enabled?('products_for_enterprises') %>
  70 + <h2><%=_('Products/Services catalog')%></h2>
  71 + <%= labelled_form_field(_('Number of products/services displayed per page on catalog'), text_field(:profile_data, :products_per_catalog_page, :size => 3)) %>
  72 +<% end %>
app/views/profile_editor/_person.rhtml
@@ -19,3 +19,8 @@ @@ -19,3 +19,8 @@
19 <%= @plugins.dispatch(:profile_info_extra_contents).collect { |content| instance_eval(&content) }.join("") %> 19 <%= @plugins.dispatch(:profile_info_extra_contents).collect { |content| instance_eval(&content) }.join("") %>
20 20
21 <%= render :partial => 'person_form', :locals => {:f => f} %> 21 <%= render :partial => 'person_form', :locals => {:f => f} %>
  22 +
  23 + <h2><%= _('Notification options') %></h2>
  24 + <div>
  25 + <%= select_tag 'profile_data[notification_time]', options_for_select([[_('Disabled'), 0], [_('Hourly'), 1], [_('Half Day'), 12], [_('Daily'), 24]], @profile.notification_time) %>
  26 + </div>
app/views/profile_editor/_person_form.rhtml
@@ -13,6 +13,8 @@ @@ -13,6 +13,8 @@
13 <%= optional_field(@person, 'contact_phone', labelled_form_field(_('Home phone'), text_field(:profile_data, :contact_phone, :rel => _('Contact phone')))) %> 13 <%= optional_field(@person, 'contact_phone', labelled_form_field(_('Home phone'), text_field(:profile_data, :contact_phone, :rel => _('Contact phone')))) %>
14 <%= optional_field(@person, 'cell_phone', f.text_field(:cell_phone, :rel => _('Cell phone'))) %> 14 <%= optional_field(@person, 'cell_phone', f.text_field(:cell_phone, :rel => _('Cell phone'))) %>
15 <%= optional_field(@person, 'comercial_phone', f.text_field(:comercial_phone, :rel => _('Comercial phone'))) %> 15 <%= optional_field(@person, 'comercial_phone', f.text_field(:comercial_phone, :rel => _('Comercial phone'))) %>
  16 +<%= optional_field(@person, 'jabber_id', f.text_field(:jabber_id, :rel => _('Jabber'))) %>
  17 +<%= optional_field(@person, 'personal_website', f.text_field(:personal_website, :rel => _('Personal website'))) %>
16 <%= optional_field(@person, 'sex', f.radio_group(:profile_data, :sex, [ ['male',_('Male')], ['female',_('Female')] ])) %> 18 <%= optional_field(@person, 'sex', f.radio_group(:profile_data, :sex, [ ['male',_('Male')], ['female',_('Female')] ])) %>
17 <%= optional_field(@person, 'birth_date', labelled_form_field(_('Birth date'), '<div class="select-birth-date">' + pick_date(:profile_data, :birth_date, {:start_year => (Date.today.year - 100), :end_year => (Date.today.year - 5)}) + '</div>')) %> 19 <%= optional_field(@person, 'birth_date', labelled_form_field(_('Birth date'), '<div class="select-birth-date">' + pick_date(:profile_data, :birth_date, {:start_year => (Date.today.year - 100), :end_year => (Date.today.year - 5)}) + '</div>')) %>
18 <%= optional_field(@person, 'nationality', f.text_field(:nationality, :rel => _('Nationality'))) %> 20 <%= optional_field(@person, 'nationality', f.text_field(:nationality, :rel => _('Nationality'))) %>
app/views/profile_editor/index.rhtml
@@ -22,7 +22,7 @@ @@ -22,7 +22,7 @@
22 22
23 <%= control_panel_button(_('Edit sideboxes'), 'blocks', :controller => 'profile_design', :action => 'index') %> 23 <%= control_panel_button(_('Edit sideboxes'), 'blocks', :controller => 'profile_design', :action => 'index') %>
24 24
25 - <%= control_panel_button(_('Edit Appearance'), 'design-editor', :controller => 'themes', :action => 'index') %> 25 + <%= control_panel_button(_('Edit Appearance'), 'design-editor', :controller => 'profile_themes', :action => 'index') %>
26 26
27 <%= control_panel_button(_('Edit Header and Footer'), 'header-and-footer', :controller => 'profile_editor', :action => 'header_footer') unless profile.enterprise? && environment.enabled?('disable_header_and_footer') && !user.is_admin?(environment) %> 27 <%= control_panel_button(_('Edit Header and Footer'), 'header-and-footer', :controller => 'profile_editor', :action => 'header_footer') unless profile.enterprise? && environment.enabled?('disable_header_and_footer') && !user.is_admin?(environment) %>
28 28
app/views/profile_members/_members_list.rhtml
1 -<% collection = @collection == :profile_admins ? profile.admins : profile.members %> 1 +<% collection = @collection == :profile_admins ? profile.admins : profile.members_by_name %>
2 <% title = @title ? @title : _('Current members') %> 2 <% title = @title ? @title : _('Current members') %>
3 <% remove_action = @remove_action ? @remove_action : {:action => 'unassociate'} %> 3 <% remove_action = @remove_action ? @remove_action : {:action => 'unassociate'} %>
4 4
app/views/profile_themes/add_css.rhtml 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +<h2><%= _('Add a CSS file') %></h2>
  2 +
  3 +<% form_tag do %>
  4 + <%= labelled_form_field(_('File name'), text_field_tag('css')) %>
  5 +
  6 + <% button_bar do %>
  7 + <%= submit_button(:add, _('Add')) %>
  8 + <%= lightbox_close_button(_('Cancel')) %>
  9 + <% end %>
  10 +
  11 +<% end %>
app/views/profile_themes/add_image.rhtml 0 → 100644
@@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
  1 +<% form_tag({:action => 'add_image', :id => @theme.id}, :multipart => true) do %>
  2 + <%= labelled_form_field(_('Choose the image file'), file_field_tag(:image)) %>
  3 + <% button_bar do %>
  4 + <%= submit_button(:add, _('Add image')) %>
  5 + <% end %>
  6 +<% end %>
app/views/profile_themes/css_editor.rhtml 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +<h2><%= _('CSS code: "%s"') % @css %></h2>
  2 +
  3 +<% form_tag({:action => 'update_css', :id => @theme.id }, :name => 'csscode_form') do %>
  4 + <%= hidden_field_tag('css', @css) %>
  5 + <%= text_area_tag('csscode', @code, :id => "codepressWindow", :class => 'codepress css') %>
  6 + <% button_bar do %>
  7 + <%= submit_button(:save, _('Save')) %>
  8 + <% end %>
  9 +<% end %>
  10 +
  11 +<!--<script type='text/javascript'>-->
  12 + <!--CodePress.run();-->
  13 +<!--</script>-->
app/views/profile_themes/edit.rhtml 0 → 100644
@@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
  1 +<form>
  2 + <%# FIXME %>
  3 + <h1 id='theme-name'>
  4 + <%= _('Editing theme "%s"') % @theme.name %>
  5 + <%= button(:eyes, _('Preview this theme'), :action => 'start_test', :id => @theme.id) %>
  6 + <%= button(:back, _('Back'), :action => 'index') %>
  7 + </h1>
  8 +</form>
  9 +
  10 +
  11 +<div id='css-files-list'>
  12 + <h2><%= _('CSS files') %></h2>
  13 + <ul>
  14 + <% for css in @css_files %>
  15 + <li><%= link_to_remote(css, :url => { :action => 'css_editor', :id => @theme.id, :css => css }, :update => { :success => 'css-code' }) %></li>
  16 + <% end %>
  17 + </ul>
  18 + <% button_bar do %>
  19 + <%= lightbox_button(:add, _('New CSS'), :action => 'add_css', :id => @theme.id) %>
  20 + <% end %>
  21 +</div>
  22 +
  23 +<div id='image-files-list'>
  24 + <h2><%= _('Images') %></h2>
  25 + <ul>
  26 + <% for image in @image_files %>
  27 + <li><%= image_tag("/user_themes/#{@theme.id}/images/#{image}") %></li>
  28 + <% end %>
  29 + </ul>
  30 + <% button_bar do %>
  31 + <%= lightbox_button(:add, _('Add image'), :action => 'add_image', :id => @theme.id) %>
  32 + <% end %>
  33 +</div>
  34 +
  35 +<div id='css-code'>
  36 + <center style='padding-top: 5em;'>
  37 + <em><%= _('Select a CSS file to edit') %></em>
  38 + </center>
  39 +</div>
  40 +
  41 +<%# javascript_include_tag 'codepress/codepress' %>
app/views/profile_themes/index.rhtml 0 → 100644
@@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
  1 +<%= render :partial => 'themes/select_template' %>
  2 +<%= render :partial => 'themes/select_theme' %>
  3 +
  4 +<% if environment.enabled?('user_themes') %>
  5 + <div id="user-themes" class="list-options">
  6 +
  7 + <h2><%= _('My themes') %></h2>
  8 +
  9 + <% for themes in profile.themes.in_groups_of(3) %>
  10 + <div class="list-group">
  11 + <% for theme in themes %><%=
  12 + if theme
  13 +
  14 + selected = theme.id == @current_theme
  15 + sel_html = selected ?
  16 + content_tag('big', _('(current)') ) :
  17 + link_to(_('Use this theme'), :action => 'set', :id => theme.id)
  18 +
  19 + content_tag( 'div',
  20 + image_tag(
  21 + '/images/icons-app/design-editor.png',
  22 + :alt => (_('The "%s" theme.') % theme.name)) +
  23 + '<div class="opt-info">' +
  24 + content_tag('strong', theme.name, :class => 'name') +
  25 + ' <br/> '+ sel_html +' <br/> ' +
  26 + link_to(_('Edit this theme'), :action => 'edit', :id => theme.id) +
  27 + ' <br/> ' +
  28 + link_to(_('Test this theme'), :action => 'start_test', :id => theme.id) +
  29 + '</div>',
  30 + :class => 'theme-opt list-opt' + (selected ? ' selected' : '')
  31 + )
  32 +
  33 + end
  34 + %><% end %>
  35 + </div>
  36 + <% end %>
  37 +
  38 + </div><!-- end id="user-themes" -->
  39 +<% end %>
  40 +
  41 +<br style="clear:both" />
  42 +
  43 +<% button_bar do %>
  44 + <% if environment.enabled?('user_themes') %>
  45 + <%= lightbox_button(:add, _('New theme ...'), :action => 'new') %>
  46 + <% end %>
  47 + <%= button(:back, _('Back'), :controller => 'profile_editor', :action => 'index') %>
  48 +<% end %>
app/views/profile_themes/new.rhtml 0 → 100644
@@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
  1 +<h2><%= _('Create new theme') %></h2>
  2 +
  3 +<% form_tag(:action => 'new') do %>
  4 +
  5 + <%= labelled_form_field(_('Name of the new theme:'), text_field_tag(:name)) %>
  6 +
  7 + <% button_bar do %>
  8 + <%= submit_button(:save, _('Create')) %>
  9 + <% end %>
  10 +<% end %>
app/views/shared/_select_categories.rhtml
1 -<div id="category-ajax-selector"> 1 +<% extend CategoriesHelper %>
  2 +
2 <% if !@current_category.nil? %> 3 <% if !@current_category.nil? %>
3 - <h3 class="box-title"><%= _('Current category:') %></h3>  
4 <%= hidden_field_tag "#{object_name}[#{object_name}_category_id]", @current_category.id unless multiple %> 4 <%= hidden_field_tag "#{object_name}[#{object_name}_category_id]", @current_category.id unless multiple %>
  5 + <%= hidden_field_tag "#{object_name}[category_ids][]", @current_category.id if multiple %>
  6 + <%= button_to_remote_without_text(:back, _('Back'),
  7 + { :update => "select-categories",
  8 + :url => { :action => 'update_categories', :id => @object },
  9 + :loaded => visual_effect(:highlight, "select-categories")
  10 + },
  11 + :id => 'cancel-category-button') %>
5 <% 12 <%
6 categories = [@current_category] 13 categories = [@current_category]
7 categories.push(@current_category) while @current_category = @current_category.parent 14 categories.push(@current_category) while @current_category = @current_category.parent
8 %> 15 %>
9 <%= categories.compact.reverse.map{|i| 16 <%= categories.compact.reverse.map{|i|
10 - link_to_remote(i.name, 17 + link_to_remote(i.name,
11 :update => "select-categories", 18 :update => "select-categories",
12 :url => { :action => 'update_categories', :category_id => i.id, :id => @object }, 19 :url => { :action => 'update_categories', :category_id => i.id, :id => @object },
13 :loaded => visual_effect(:highlight, "select-categories"), 20 :loaded => visual_effect(:highlight, "select-categories"),
14 :class => 'select-current-category-link')}.join(' &rarr; ') 21 :class => 'select-current-category-link')}.join(' &rarr; ')
15 %> 22 %>
16 - <strong>  
17 - <%= button_to_function_without_text(:save, _('Save'), nil, :id => 'save-category-button') do |page|  
18 - page.insert_html :bottom, 'selected-categories', content_tag('li', categories.first.full_name + 23 + <%= button_to_function_without_text(:add, _('Add'), nil, :id => 'save-category-button') do |page|
  24 + page.insert_html :bottom, 'selected-categories', content_tag('div',
19 hidden_field_tag("#{object_name}[category_ids][]", categories.first.id) + 25 hidden_field_tag("#{object_name}[category_ids][]", categories.first.id) +
20 - button_to_function_without_text(:cancel, _('Remove'), nil, :id => "remove-selected-category-#{categories.first.id}-button") {|page| page["selected-category-#{categories.first.id}"].remove}, :id => "selected-category-#{categories.first.id}") 26 + selected_category_link(categories.first), :id => "selected-category-#{categories.first.id}")
  27 + page.replace_html 'select-categories', :partial => 'shared/select_subcategories',
  28 + :locals => {:object_name => object_name, :categories => @toplevel_categories}
21 end if multiple %> 29 end if multiple %>
22 - <%= button_to_remote_without_text(:cancel, _('Cancel'),  
23 - { :update => "select-categories",  
24 - :url => { :action => 'update_categories', :id => @object },  
25 - :loaded => visual_effect(:highlight, "select-categories")  
26 - },  
27 - :id => 'cancel-category-button') %>  
28 - </strong>  
29 -<% else %>  
30 - <h3 class="box-title"><%= _('Select a category:') %></h3>  
31 <% end %> 30 <% end %>
32 31
33 -<% if !@categories.empty? %>  
34 - <h3><%= _('Categories:') %></h3>  
35 - <% @categories.select{|i| !@object.respond_to?(:accept_category?) || @object.accept_category?(i)}.each do |category| %>  
36 - <%= link_to_remote category.name,  
37 - { :update => "select-categories",  
38 - :url => { :action => "update_categories", :category_id => category.id, :id => @object},  
39 - :loaded => visual_effect(:highlight, "select-categories")  
40 - },  
41 - :class => 'select-subcategory-link',  
42 - :id => "select-category-#{category.id}-link"  
43 - %>  
44 - <% end %> &nbsp;  
45 -<% end %> 32 +<div class="toplevel-categories">
  33 + <%= render :partial => 'shared/select_subcategories', :locals => {:object_name => object_name, :categories => @categories} %>
46 </div> 34 </div>
app/views/shared/_select_categories_top.rhtml 0 → 100644
@@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
  1 +<% categories_selected ||= nil %>
  2 +<% title ||= nil %>
  3 +
  4 +<% extend CategoriesHelper %>
  5 +
  6 +<%= content_tag "h#{title_size}", title, :class => "box-title" %>
  7 +
  8 +<%= hidden_field_tag "#{object_name}[category_ids][]", nil %>
  9 +
  10 +<div id="category-ajax-selector">
  11 +<% unless categories_selected.nil? %>
  12 +<div id="selected-categories">
  13 + <div class="label"><%= _('Selected categories:') %></div>
  14 + <% categories_selected.each do |cat| %>
  15 + <div id="selected-category-<%= cat.id %>">
  16 + <%= hidden_field_tag("#{object_name}[category_ids][]", cat.id) %>
  17 + <%= selected_category_link(cat) %>
  18 + </div>
  19 + <% end %>
  20 +</div>
  21 +<% end %>
  22 +<div id="select-categories">
  23 + <%= render :partial => 'shared/select_categories', :locals => {:object_name => object_name, :multiple => true, :categories_selected => categories_selected }, :layout => false %>
  24 +</div>
  25 +
  26 +</div>
app/views/shared/_select_subcategories.rhtml 0 → 100644
@@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
  1 +<% if !categories.nil? && !categories.empty? && !@object.nil? %>
  2 + <hr>
  3 + <div class="category-helper-label"><%= _('Click to select a category') %></div>
  4 +
  5 + <% categories.select{|i| @object.accept_category?(i)}.each do |category| %>
  6 +
  7 + <%= link_to_remote category.name,
  8 + { :update => "select-categories",
  9 + :url => { :action => "update_categories", :category_id => category.id, :id => @object},
  10 + :loaded => visual_effect(:highlight, "select-categories")
  11 + },
  12 + :class => 'select-subcategory-link',
  13 + :id => "select-category-#{category.id}-link"
  14 + %>
  15 + <% end %>
  16 +<% end %>
app/views/shared/theme_test_panel.rhtml
@@ -6,8 +6,8 @@ @@ -6,8 +6,8 @@
6 <p><small><em><%= _('You can move this window away to have a better visualization of specific parts of screen.') %></em></small></p> 6 <p><small><em><%= _('You can move this window away to have a better visualization of specific parts of screen.') %></em></small></p>
7 7
8 <% button_bar do %> 8 <% button_bar do %>
9 - <%= button(:ok, _('Finished testing'), :controller => 'themes', :profile => theme_owner, :action => 'stop_test', :id => current_theme) %>  
10 - <%= button(:edit, _('Edit theme'), :controller => 'themes', :profile => theme_owner, :action => 'edit', :id => current_theme) %> 9 + <%= button(:ok, _('Finished testing'), :controller => 'profile_themes', :profile => theme_owner, :action => 'stop_test', :id => current_theme) %>
  10 + <%= button(:edit, _('Edit theme'), :controller => 'profile_themes', :profile => theme_owner, :action => 'edit', :id => current_theme) %>
11 <% end %> 11 <% end %>
12 </div> 12 </div>
13 <%= draggable_element('theme-test-panel') %> 13 <%= draggable_element('theme-test-panel') %>
app/views/themes/_select_template.rhtml 0 → 100644
@@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
  1 +<h1><%= _('Editing Appearance') %></h1>
  2 +
  3 +<div id="template-options" class="list-options">
  4 +
  5 +<h2><%= _('Select template') %></h2>
  6 +
  7 +<% for templates in @layout_templates.in_groups_of(3) %>
  8 + <div class="list-group">
  9 + <% for template in templates %><%=
  10 + if template
  11 + base_content = image_tag(
  12 + "/designs/templates/#{template.id}/thumbnail.png",
  13 + :alt => _('The "%s" template')) +
  14 + '<div class="opt-info">'.html_safe +
  15 + content_tag('strong', template.name, :title => template.title, :class => 'name') +
  16 + ' <br/> '.html_safe
  17 +
  18 + if @current_template == template.id # selected
  19 + content_tag( 'div',
  20 + base_content + content_tag('big', _('(current)') ) +'</div>'.html_safe,
  21 + :class => 'template-opt list-opt selected')
  22 + else # Not selected
  23 + link_to(
  24 + base_content +'</div>'.html_safe,
  25 + { :action => 'set_layout_template', :id => template.id },
  26 + :class => 'template-opt list-opt')
  27 + end
  28 +
  29 + end
  30 + %><% end %>
  31 + </div>
  32 +<% end %>
  33 +
  34 +</div><!-- end id="template-options" -->
  35 +
app/views/themes/_select_theme.rhtml 0 → 100644
@@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
  1 +<% if !@themes.empty? %>
  2 +<div id="theme-options" class="list-options">
  3 +
  4 +<h2><%= _('Select theme') %></h2>
  5 +<%= button :home, _('Use the default theme'), { :action => 'unset'}, :method => 'post', :confirm => _('Are you sure you want to use the environment default theme?') %>
  6 +
  7 +<% for themes in @themes.in_groups_of(3) %>
  8 + <div class="list-group">
  9 + <% for theme in themes %><%=
  10 + if theme
  11 +
  12 + base_content = image_tag(
  13 + "/designs/themes/#{theme.id}/preview.png",
  14 + :alt => (_('The "%s" theme.') % theme.name)) +
  15 + '<div class="opt-info">'.html_safe +
  16 + content_tag('strong', theme.name, :class => 'name') +
  17 + ' <br/> '.html_safe
  18 +
  19 + if theme.id == @current_theme # selected
  20 + content_tag( 'div',
  21 + base_content + content_tag('big', _('(current)') ) +'</div>'.html_safe,
  22 + :class => 'theme-opt list-opt selected')
  23 + else # Not selected
  24 + link_to(
  25 + base_content + '</div>'.html_safe,
  26 + { :action => 'set', :id => theme.id },
  27 + :class => 'theme-opt list-opt')
  28 + end
  29 +
  30 + end
  31 + %><% end %>
  32 + </div>
  33 +<% end %>
  34 +
  35 +</div><!-- end id="theme-options" -->
  36 +<% end %>
  37 +