Commit d08608afec164fe6dd991f8a0bbc487825b94600
Exists in
master
and in
29 other branches
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.
AUTHORS
@@ -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 <alessandro.palmeira@gmail.com> | @@ -38,6 +39,7 @@ Alessandro Palmeira + João M. M. Silva <alessandro.palmeira@gmail.com> | ||
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 <rr.manzo@gmail.com> | @@ -85,6 +87,7 @@ Daniel Alves + Rafael Manzo <rr.manzo@gmail.com> | ||
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 <diegoamc90@gmail.com> | @@ -114,12 +117,16 @@ Diego Martinez <diegoamc90@gmail.com> | ||
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 <jaodsilv@linux.ime.usp.br> | @@ -155,6 +162,7 @@ João M. M. Silva + Rafael Manzo <jaodsilv@linux.ime.usp.br> | ||
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 <renanteruoc@gmail.com> | @@ -202,6 +210,7 @@ Renan Teruo + Diego Araujo <renanteruoc@gmail.com> | ||
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> |
INSTALL.md
@@ -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' |
README.md
1 | +[](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 < BoxOrganizerController | @@ -3,6 +3,8 @@ class EnvironmentDesignController < 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/users_controller.rb
@@ -45,6 +45,20 @@ class UsersController < AdminController | @@ -45,6 +45,20 @@ class UsersController < 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 < MyProfileController | @@ -24,10 +24,16 @@ class CmsController < 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 < MyProfileController | @@ -68,6 +74,9 @@ class CmsController < 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 < MyProfileController | @@ -202,7 +211,7 @@ class CmsController < 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 < MyProfileController | @@ -218,11 +227,10 @@ class CmsController < 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 < BoxOrganizerController | @@ -32,6 +32,7 @@ class ProfileDesignController < 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 < BoxOrganizerController | @@ -54,4 +55,10 @@ class ProfileDesignController < 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 < MyProfileController | @@ -55,11 +55,10 @@ class ProfileEditorController < 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 < MyProfileController | @@ -2,7 +2,7 @@ class ProfileMembersController < 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 |
@@ -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 < ApplicationController | @@ -69,6 +69,8 @@ class AccountController < 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 < ApplicationController | @@ -77,6 +79,7 @@ class AccountController < 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 < ApplicationController | @@ -98,7 +101,7 @@ class AccountController < 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 < ApplicationController | @@ -368,32 +371,29 @@ class AccountController < 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 < ApplicationController | @@ -409,4 +409,22 @@ class AccountController < 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
app/controllers/public/comment_controller.rb
@@ -71,7 +71,9 @@ class CommentController < ApplicationController | @@ -71,7 +71,9 @@ class CommentController < 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 < ApplicationController | @@ -113,6 +115,8 @@ class CommentController < 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 < ApplicationController | @@ -7,6 +9,7 @@ class ContentViewerController < 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 < ApplicationController | @@ -25,27 +28,15 @@ class ContentViewerController < 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 < ApplicationController | @@ -128,6 +119,21 @@ class ContentViewerController < 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 < ApplicationController | @@ -158,6 +164,24 @@ class ContentViewerController < 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 < ApplicationController | @@ -166,5 +190,4 @@ class ContentViewerController < 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 < PublicController | @@ -67,7 +67,7 @@ class ProfileController < 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 < PublicController | @@ -304,14 +304,6 @@ class ProfileController < 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 < PublicController | @@ -80,7 +80,7 @@ class SearchController < 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 |
@@ -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, " → "), | ||
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(' → '), :id => 'breadcrumb') | 24 | content_tag('div', all_items.join(' → '), :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(' → '), 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
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 < ActiveRecord::Base | @@ -201,6 +201,7 @@ class Article < 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 < ActiveRecord::Base | @@ -604,25 +605,49 @@ class Article < 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 < ActiveRecord::Base | @@ -631,7 +656,9 @@ class Article < 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 < ActiveRecord::Base | @@ -23,30 +23,41 @@ class Block < 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 < ActiveRecord::Base | @@ -168,4 +179,14 @@ class Block < 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 < ActiveRecord::Base | @@ -26,6 +26,8 @@ class Box < 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 < ActiveRecord::Base | @@ -52,6 +54,8 @@ class Box < 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 < ActiveRecord::Base | @@ -66,6 +70,7 @@ class Box < 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 < Organization | @@ -10,19 +10,20 @@ class Enterprise < 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 < Organization | @@ -135,8 +136,11 @@ class Enterprise < 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 < ActiveRecord::Base | @@ -26,7 +26,8 @@ class Environment < 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 < ActiveRecord::Base | @@ -144,6 +145,18 @@ class Environment < 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 < ActiveRecord::Base | @@ -160,6 +173,8 @@ class Environment < 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 < ActiveRecord::Base | @@ -680,6 +695,16 @@ class Environment < 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 < ActiveRecord::Base | @@ -695,7 +720,8 @@ class Environment < 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 < ActiveRecord::Base | @@ -703,7 +729,8 @@ class Environment < 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 < ActiveRecord::Base | @@ -711,7 +738,8 @@ class Environment < 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 < ActiveRecord::Base | @@ -719,7 +747,8 @@ class Environment < 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 < ActiveRecord::Base | @@ -801,7 +830,7 @@ class Environment < 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 < Folder | @@ -5,6 +5,7 @@ class Forum < 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 < Folder | @@ -66,4 +67,11 @@ class Forum < 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 < Block | @@ -63,7 +63,7 @@ class LinkListBlock < 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 < Profile | @@ -43,7 +43,12 @@ class Person < 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 < Profile | @@ -129,32 +134,34 @@ class Person < 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 < Profile | @@ -483,6 +490,17 @@ class Person < 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) |
@@ -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 < ActiveRecord::Base | @@ -15,7 +15,11 @@ class Product < 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 < ActiveRecord::Base | @@ -29,7 +33,10 @@ class Product < 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 < ActiveRecord::Base | @@ -81,10 +88,6 @@ class Product < 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 < ActiveRecord::Base | @@ -234,4 +237,10 @@ class Product < 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 |
@@ -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 < Category | @@ -3,6 +3,15 @@ class ProductCategory < 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 < ActiveRecord::Base | @@ -84,7 +84,12 @@ class Profile < 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
app/models/user.rb
@@ -71,7 +71,8 @@ class User < ActiveRecord::Base | @@ -71,7 +71,8 @@ class User < 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 # < ActiveRecord::Observer | @@ -8,6 +8,8 @@ class ProfileSweeper # < 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> |
@@ -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 %>"> |
@@ -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> |
@@ -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> |
@@ -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' %> |
@@ -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 %> |
@@ -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 → %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/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 } %> |
@@ -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> |
@@ -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> |
@@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
1 | +<%= render :partial => 'default_activity', :locals => { :activity => activity } %> |
@@ -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 | +<%= 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,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/> |
@@ -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 |
@@ -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 %> |
@@ -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>--> |
@@ -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' %> |
@@ -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 %> |
@@ -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(' → ') | 21 | :class => 'select-current-category-link')}.join(' → ') |
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 %> | ||
45 | -<% end %> | 32 | +<div class="toplevel-categories"> |
33 | + <%= render :partial => 'shared/select_subcategories', :locals => {:object_name => object_name, :categories => @categories} %> | ||
46 | </div> | 34 | </div> |
@@ -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> |
@@ -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') %> |
@@ -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 | + |
@@ -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 | + |