Commit 1f0194be42835a51ee86741bb9f56a1a0f297c5d

Authored by Rodrigo Souto
2 parents e9fea38f adc4f4fd

Merge branch 'master' into rails3-merge

Conflicts:
	app/views/profile_themes/add_css.rhtml
	app/views/profile_themes/add_image.rhtml
	app/views/profile_themes/css_editor.rhtml
	app/views/profile_themes/edit.rhtml
	app/views/profile_themes/new.rhtml
	app/views/themes/add_css.html.erb
	app/views/themes/add_css.rhtml
	app/views/themes/add_image.html.erb
	app/views/themes/add_image.rhtml
	app/views/themes/css_editor.html.erb
	app/views/themes/css_editor.rhtml
	app/views/themes/edit.html.erb
	app/views/themes/edit.rhtml
	app/views/themes/index.html.erb
	app/views/themes/new.html.erb
	app/views/themes/new.rhtml
	test/factories.rb
	test/functional/profile_themes_controller_test.rb
Showing 40 changed files with 1132 additions and 642 deletions   Show diff stats
AUTHORS 0 → 100644
... ... @@ -0,0 +1,231 @@
  1 +If you are not listed here, but should be, please write to the noosfero mailing
  2 +list: http://listas.softwarelivre.org/cgi-bin/mailman/listinfo/noosfero-dev
  3 +(this list requires subscription to post, but since you are an author of
  4 +noosfero, that's not a problem).
  5 +
  6 +Developers
  7 +==========
  8 +
  9 +Alan Freihof Tygel <alantygel@gmail.com>
  10 +Alessandro Palmeira <alessandro.palmeira@gmail.com>
  11 +Alessandro Palmeira + Caio C. Salgado <alessandro.palmeira@gmail.com>
  12 +Alessandro Palmeira + Caio Salgado <alessandro.palmeira@gmail.com>
  13 +Alessandro Palmeira + Caio Salgado <caio.csalgado@gmail.com>
  14 +Alessandro Palmeira + Caio Salgado + Diego Araújo + João M. M. da Silva <diegoamc90@gmail.com>
  15 +Alessandro Palmeira + Carlos Morais <alessandro.palmeira@gmail.com>
  16 +Alessandro Palmeira + Daniel Alves <alessandro.palmeira@gmail.com>
  17 +Alessandro Palmeira + Daniel Alves + Diego Araújo <diegoamc90@gmail.com>
  18 +Alessandro Palmeira + Daniel Alves + Diego Araújo + Guilherme Rojas <danpaulalves@gmail.com>
  19 +Alessandro Palmeira + Diego Araujo <alessandro.palmeira@gmail.com>
  20 +Alessandro Palmeira + Diego Araújo <alessandro.palmeira@gmail.com>
  21 +Alessandro Palmeira + Diego Araujo + Daniela Feitosa <alessandro.palmeira@gmail.com>
  22 +Alessandro Palmeira + Diego Araujo <diegoamc90@gmail.com>
  23 +Alessandro Palmeira + Diego Araújo <diegoamc90@gmail.com>
  24 +Alessandro Palmeira + Diego Araujo + Eduardo Morais <alessandro.palmeira@gmail.com>
  25 +Alessandro Palmeira + Diego Araújo + João M. M. da Silva <alessandro.palmeira@gmail.com>
  26 +Alessandro Palmeira + Diego Araújo + João M. M. da Silva <diegoamc90@gmail.com>
  27 +Alessandro Palmeira + Diego Araujo + João M. M. da Silva + Paulo Meirelles <alessandro.palmeira@gmail.com>
  28 +Alessandro Palmeira + Diego Araújo + Pedro Leal <diegoamc90@gmail.com>
  29 +Alessandro Palmeira + Diego Araújo + Pedro Leal + João M. M. da Silva <diegoamc90@gmail.com>
  30 +Alessandro Palmeira + Diego Araujo + Rafael Manzo <alessandro.palmeira@gmail.com>
  31 +Alessandro Palmeira + Eduardo Morais <alessandro.palmeira@gmail.com>
  32 +Alessandro Palmeira + Guilherme Rojas <alessandro.palmeira@gmail.com>
  33 +Alessandro Palmeira + Jefferson Fernandes <alessandro.palmeira@gmail.com>
  34 +Alessandro Palmeira + João M. M. da Silva <alessandro.palmeira@gmail.com>
  35 +Alessandro Palmeira + Joao M. M. da Silva + Diego Araujo <alessandro.palmeira@gmail.com>
  36 +Alessandro Palmeira + João M. M. da Silva + Renan Teruo <alessandro.palmeira@gmail.com>
  37 +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 + João M. M. da Silva <alessandro.palmeira@gmail.com>
  40 +Alessandro Palmeira + Rafael Manzo <alessandro.palmeira@gmail.com>
  41 +Antonio Terceiro + Carlos Morais <terceiro@colivre.coop.br>
  42 +Antonio Terceiro + Paulo Meirelles <terceiro@colivre.coop.br>
  43 +Antonio Terceiro <terceiro@colivre.coop.br>
  44 +Arthur Del Esposte <arthurmde@yahoo.com.br>
  45 +Aurelio A. Heckert <aurelio@colivre.coop.br>
  46 +Braulio Bhavamitra <brauliobo@gmail.com>
  47 +Bráulio Bhavamitra <brauliobo@gmail.com>
  48 +Braulio Bhavamitra <braulio@eita.org.br>
  49 +Caio <caio.csalgado@gmail.com>
  50 +Caio + Diego + Pedro + João <caio.csalgado@gmail.com>
  51 +Caio Formiga <caio.formiga@gmail.com>
  52 +Caio, Pedro <caio.csalgado@gmail.com>
  53 +Caio Salgado + Alessandro Palmeira <caio.csalgado@gmail.com>
  54 +Caio Salgado <caio.csalgado@gmail.com>
  55 +Caio Salgado + Carlos Morais + Diego Araújo + Pedro Leal <diegoamc90@gmail.com>
  56 +Caio Salgado + Diego Araujo <caio.csalgado@gmail.com>
  57 +Caio Salgado + Diego Araújo <caio.csalgado@gmail.com>
  58 +Caio Salgado + Diego Araújo <diegoamc90@gmail.com>
  59 +Caio Salgado + Diego Araújo + Jefferson Fernandes <caio.csalgado@gmail.com>
  60 +Caio Salgado + Diego Araújo + João M. M. da Silva <caio.csalgado@gmail.com>
  61 +Caio Salgado + Diego Araújo + Pedro Leal <caio.csalgado@gmail.com>
  62 +Caio Salgado + Diego Araújo + Pedro Leal <diegoamc90@gmail.com>
  63 +Caio Salgado + Diego Araújo + Rafael Manzo <diegoamc90@gmail.com>
  64 +Caio Salgado + Jefferson Fernandes <caio.csalgado@gmail.com>
  65 +Caio Salgado + Jefferson Fernandes <jeffs.fernandes@gmail.com>
  66 +Caio Salgado + Rafael Manzo <caio.csalgado@gmail.com>
  67 +Caio Salgado + Renan Teruo <caio.csalgado@gmail.com>
  68 +Caio Salgado + Renan Teruo <caio.salgado@gmail.com>
  69 +Caio Salgado + Renan Teruo + Jefferson Fernandes <jeffs.fernandes@gmail.com>
  70 +Caio Salgado + Renan Teruo <renanteruoc@gmail.com>
  71 +Caio SBA <caio@colivre.coop.br>
  72 +Carlos Andre de Souza <carlos.andre.souza@msn.com>
  73 +Carlos Morais <carlos88morais@gmail.com>
  74 +Carlos Morais + Diego Araújo <diegoamc90@gmail.com>
  75 +Carlos Morais + Eduardo Morais <carlos88morais@gmail.com>
  76 +Carlos Morais + Paulo Meirelles <carlos88morais@gmail.com>
  77 +Carlos Morais + Pedro Leal <carlos88morais@gmail.com>
  78 +Daniel Alves + Diego Araújo <danpaulalves@gmail.com>
  79 +Daniel Alves + Diego Araújo <diegoamc90@gmail.com>
  80 +Daniel Alves + Diego Araújo + Guilherme Rojas <danpaulalves@gmail.com>
  81 +Daniel Alves + Diego Araújo + Guilherme Rojas <diegoamc90@gmail.com>
  82 +Daniel Alves + Diego Araújo + Guilherme Rojas <guilhermehrojas@gmail.com>
  83 +Daniel Alves + Guilherme Rojas <danpaulalves@gmail.com>
  84 +Daniel Alves + Rafael Manzo <rr.manzo@gmail.com>
  85 +Daniela Soares Feitosa <danielafeitosa@colivre.coop.br>
  86 +Daniel Bucher <daniel.bucher88@gmail.com>
  87 +Daniel Cunha <daniel@colivre.coop.br>
  88 +diegoamc <diegoamc90@gmail.com>
  89 +Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com>
  90 +Diego Araújo + Alessandro Palmeira + João M. M. da Silva <diegoamc90@gmail.com>
  91 +Diego Araújo + Alessandro Palmeira + Rafael Manzo <rr.manzo@gmail.com>
  92 +Diego Araujo + Caio Salgado <diegoamc90@gmail.com>
  93 +Diego Araújo + Daniel Alves + Rafael Manzo <rr.manzo@gmail.com>
  94 +Diego Araújo <diegoamc90@gmail.com>
  95 +Diego Araújo + Eduardo Morais + Paulo Meirelles <diegoamc90@gmail.com>
  96 +Diego Araújo + Guilherme Rojas <diegoamc90@gmail.com>
  97 +Diego Araújo + Jefferson Fernandes <diegoamc90@gmail.com>
  98 +Diego Araujo + Jefferson Fernandes <jeffs.fernandes@gmail.com>
  99 +Diego Araújo + João Machini <diegoamc90@gmail.com>
  100 +Diego Araújo + João Machini <digoamc90@gmail.com>
  101 +Diego Araújo + João M. M. da Silva + Alessandro Palmeira <jaodsilv@linux.ime.usp.br>
  102 +Diego Araújo + João M. M. da Silva <diegoamc90@gmail.com>
  103 +Diego Araújo + João M. M. da Silva + João Machini <diegoamc90@gmail.com>
  104 +Diego Araújo + João M. M. da Silva + Pedro Leal <diegoamc90@gmail.com>
  105 +Diego Araújo + Paulo Meirelles <diegoamc90@gmail.com>
  106 +Diego Araújo + Pedro Leal <diegoamc90@gmail.com>
  107 +Diego Araujo + Rafael Manzo <diegoamc90@gmail.com>
  108 +Diego Araújo + Rafael Manzo <diegoamc90@gmail.com>
  109 +Diego Araújo + Renan Teruo + Alessandro Palmeira <diegoamc90@gmail.com>
  110 +Diego Araújo + Renan Teruo <diegoamc90@gmail.com>
  111 +Diego Araujo + Rodrigo Souto + Rafael Manzo <rr.manzo@gmail.com>
  112 +Diego + Jefferson <diegoamc90@gmail.com>
  113 +Diego Martinez <diegoamc90@gmail.com>
  114 +Diego Martinez <diego@diego-K55A.(none)>
  115 +Diego + Renan <renanteruoc@gmail.com>
  116 +Eduardo Tourinho Edington <eduardo.edington@serpro.gov.br>
  117 +Fernanda Lopes <nanda.listas+psl@gmail.com>
  118 +Francisco Marcelo A. Lima Júnior <francisco.lima-junior@serpro.gov.br>
  119 +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>
  121 +Francisco Marcelo de Araújo Lima Júnior <maljunior@gmail.com>
  122 +Grazieno Pellegrino <grazieno@gmail.com>
  123 +Isaac Canan <isaac@intelletto.com.br>
  124 +Italo Valcy <italo@dcc.ufba.br>
  125 +Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com>
  126 +Jefferson Fernandes + Joao M. M. da Silva <jeffs.fernandes@gmail.com>
  127 +Jefferson Fernandes + Joao M. M. Silva <jeffs.fernandes@gmail.com>
  128 +João da Silva <jaodsilv@linux.ime.usp.br>
  129 +João Marco Maciel da Silva + Rafael Manzo + Renan Teruo <jaodsilv@linux.ime.usp.br>
  130 +João M. M. da Silva + Alessandro Palmeira + Diego Araújo + Caio Salgado <jaodsilv@linux.ime.usp.br>
  131 +João M. M. da Silva + Alessandro Palmeira + Diego Araújo <jaodsilv@linux.ime.usp.br>
  132 +Joao M. M. da Silva + Alessandro Palmeira <jaodsilv@linux.ime.usp.br>
  133 +João M. M. da Silva + Alessandro Palmeira <jaodsilv@linux.ime.usp.br>
  134 +João M. M. da Silva + Alessandro Palmeira + João Machini <jaodsilv@linux.ime.usp.br>
  135 +João M. M. da Silva + Caio Salgado + Alessandro Palmeira <jaodsilv@linux.ime.usp.br>
  136 +João M. M. da Silva + Caio Salgado <jaodsilv@linux.ime.usp.br>
  137 +João M. M. da Silva + Carlos Morais <jaodsilv@linux.ime.usp.br>
  138 +João M. M. da Silva + Diego Araújo <diegoamc90@gmail.com>
  139 +João M. M. da Silva + Diego Araújo <jaodsilv@linux.ime.usp.br>
  140 +João M. M. da Silva + Diego Araújo + Pedro Leal <jaodsilv@linux.ime.usp.br>
  141 +João M. M. da Silva <jaodsilv@linux.ime.usp.br>
  142 +Joao M. M. da Silva + Jefferson Fernandes <jaodsilv@linux.ime.usp.br>
  143 +João M. M. da Silva + Jefferson Fernandes <jaodsilv@linux.ime.usp.br>
  144 +João M. M. da Silva + João M. Miranda <jaodsilv@linux.ime.usp.br>
  145 +João M. M. da Silva + Paulo Meirelles <jaodsilv@linux.ime.usp.br>
  146 +João M. M. da Silva + Pedro Leal <jaodsilv@linux.ime.usp.br>
  147 +João M. M. da Silva + Rafael Manzo + Diego Araújo <jaodsilv@linux.ime.usp.br>
  148 +João M. M. da Silva + Rafael Manzo <jaodsilv@linux.ime.usp.br>
  149 +João M. M. da Silva + Renan Teruo <jaodsilv@linux.ime.usp.br>
  150 +João M. M. Silva + Caio Salgado <jaodsilv@linux.ime.usp.br>
  151 +João M. M. Silva + Diego Araújo <jaodsilv@linux.ime.usp.br>
  152 +Joao M. M. Silva + Jefferson Fernandes <jaodsilv@linux.ime.usp.br>
  153 +João M. M. Silva + Paulo Meirelles <jaodsilv@linux.ime.usp.br>
  154 +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>
  156 +Joenio Costa <joenio@colivre.coop.br>
  157 +Josef Spillner <josef.spillner@tu-dresden.de>
  158 +Junior Silva <juniorsilva1001@gmail.com>
  159 +Junior Silva <juniorsilva7@juniorsilva-Aspire-5750Z.(none)>
  160 +Junior Silva <juniorsilva@colivre.coop.br>
  161 +Keilla Menezes <keilla@colivre.coop.br>
  162 +Larissa Reis <larissa@colivre.coop.br>
  163 +Larissa Reis <reiss.larissa@gmail.com>
  164 +Leandro Nunes dos Santos <81665687568@serpro-1541727.Home>
  165 +Leandro Nunes dos Santos <81665687568@serpro-1541727.(none)>
  166 +Leandro Nunes dos Santos <leandronunes@gmail.com>
  167 +Leandro Nunes dos Santos <leandro.santos@serpro.gov.br>
  168 +LinguÁgil 2010 <linguagil.bahia@gmail.com>
  169 +Lucas Melo <lucas@colivre.coop.br>
  170 +Lucas Melo <lucaspradomelo@gmail.com>
  171 +Luis David Aguilar Carlos <ludwig9003@gmail.com>
  172 +Marcos Ramos <ms.ramos@outlook.com>
  173 +Martín Olivera <molivera@solar.org.ar>
  174 +Moises Machado <moises@colivre.coop.br>
  175 +Naíla Alves <naila@colivre.coop.br>
  176 +Nanda Lopes <nanda.listas+psl@gmail.com>
  177 +Paulo Meirelles + Alessandro Palmeira + João M. M. da Silva <paulo@softwarelivre.org>
  178 +Paulo Meirelles + Alessandro Palmeira <paulo@softwarelivre.org>
  179 +Paulo Meirelles + Carlos Morais <paulo@softwarelivre.org>
  180 +Paulo Meirelles + Diego Araújo <paulo@softwarelivre.org>
  181 +Paulo Meirelles + João M. M. da Silva <paulo@softwarelivre.org>
  182 +Paulo Meirelles <paulo@softwarelivre.org>
  183 +Paulo Meirelles + Rafael Manzo <paulo@softwarelivre.org>
  184 +Rafael Gomes <rafaelgomes@techfree.com.br>
  185 +Rafael Manzo + Alessandro Palmeira <rr.manzo@gmail.com>
  186 +Rafael Manzo + Daniel Alves <danpaulalves@gmail.com>
  187 +Rafael Manzo + Diego Araújo <rr.manzo@gmail.com>
  188 +Rafael Manzo + João M. M. Silva <rr.manzo@gmail.com>
  189 +Rafael Manzo + Paulo Meirelles <rr.manzo@gmail.com>
  190 +Rafael Martins <rmmartins@gmail.com>
  191 +Rafael Reggiani Manzo + Caio Salgado + Jefferson Fernandes <rr.manzo@gmail.com>
  192 +Rafael Reggiani Manzo + Diego Araujo <diegoamc90@gmail.com>
  193 +Rafael Reggiani Manzo + Diego Araujo <rr.manzo@gmail.com>
  194 +Rafael Reggiani Manzo + Diego Araújo <rr.manzo@gmail.com>
  195 +Rafael Reggiani Manzo + João M. M. da Silva <rr.manzo@gmail.com>
  196 +Rafael Reggiani Manzo <rr.manzo@gmail.com>
  197 +Raphaël Rousseau <raph@r4f.org>
  198 +Raquel Lira <raquel.lira@gmail.com>
  199 +Renan Teruo + Caio Salgado <renanteruoc@gmail.com>
  200 +Renan Teruoc + Diego Araujo <renanteruoc@gmail.com>
  201 +Renan Teruo + Diego Araujo <renanteruoc@gmail.com>
  202 +Renan Teruo + Diego Araújo <renanteruoc@gmail.com>
  203 +Renan Teruo + Paulo Meirelles <renanteruoc@gmail.com>
  204 +Renan Teruo + Rafael Manzo <renanteruoc@gmail.com>
  205 +Rodrigo Souto <diguliu@gmail.com>
  206 +Rodrigo Souto <rodrigo@colivre.coop.br>
  207 +Ronny Kursawe <kursawe.ronny@googlemail.com>
  208 +root <root@debian.sdr.serpro>
  209 +Samuel R. C. Vale <srcvale@holoscopio.com>
  210 +Valessio Brito <contato@valessiobrito.com.br>
  211 +Valessio Brito <contato@valessiobrito.info>
  212 +Valessio Brito <valessio@gmail.com>
  213 +vfcosta <vfcosta@gmail.com>
  214 +Victor Carvalho <victorhugodf.ac@gmail.com>
  215 +Victor Costa <vfcosta@gmail.com>
  216 +Victor Hugo Alves de Carvalho <victorhugodf.ac@gmail.com>
  217 +Vinicius Cubas Brand <viniciuscb@gmail.com>
  218 +Visita <visita@debian.(none)>
  219 +Yann Lugrin <yann.lugrin@liquid-concept.ch>
  220 +
  221 +Ideas, specifications and incentive
  222 +===================================
  223 +Daniel Tygel <dtygel@fbes.org.br>
  224 +Guilherme Rocha <guilherme@gf7.com.br>
  225 +Raphael Rousseau <raph@r4f.org>
  226 +Théo Bondolfi <move@cooperation.net>
  227 +Vicente Aguiar <vicenteaguiar@colivre.coop.br>
  228 +
  229 +Arts
  230 +===================================
  231 +Nara Oliveira <narananet@gmail.com>
... ...
app/controllers/admin/environment_themes_controller.rb 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +class EnvironmentThemesController < ThemesController
  2 +
  3 + protect 'edit_appearance', :environment
  4 +
  5 + no_design_blocks
  6 +
  7 + def target
  8 + @target = environment
  9 + end
  10 +
  11 +end
... ...
app/controllers/my_profile/profile_themes_controller.rb 0 → 100644
... ... @@ -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   -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)
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/comment_controller.rb
... ... @@ -71,7 +71,9 @@ class CommentController &lt; ApplicationController
71 71 return
72 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 78 respond_to do |format|
77 79 format.js do
... ... @@ -113,6 +115,8 @@ class CommentController &lt; ApplicationController
113 115  
114 116 def update
115 117 if @comment.update_attributes(params[:comment])
  118 + @plugins.dispatch(:process_extra_comment_params, [@comment,params])
  119 +
116 120 respond_to do |format|
117 121 format.js do
118 122 comment_to_render = @comment.comment_root
... ...
app/controllers/themes_controller.rb 0 → 100644
... ... @@ -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)
  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/models/box.rb
... ... @@ -10,7 +10,7 @@ class Box &lt; ActiveRecord::Base
10 10 end
11 11  
12 12 def acceptable_blocks
13   - blocks_classes = central? ? Box.acceptable_center_blocks + plugins.dispatch(:extra_blocks, :position => 1) : Box.acceptable_side_blocks + plugins.dispatch(:extra_blocks, :position => [2, 3])
  13 + blocks_classes = central? ? Box.acceptable_center_blocks + plugins.dispatch(:extra_blocks, :type => owner.class, :position => 1) : Box.acceptable_side_blocks + plugins.dispatch(:extra_blocks, :type => owner.class, :position => [2, 3])
14 14 to_css_class_name(blocks_classes)
15 15 end
16 16  
... ...
app/models/environment.rb
... ... @@ -28,7 +28,8 @@ class Environment &lt; ActiveRecord::Base
28 28 'manage_environment_users' => N_('Manage environment users'),
29 29 'manage_environment_templates' => N_('Manage environment templates'),
30 30 'manage_environment_licenses' => N_('Manage environment licenses'),
31   - 'manage_environment_trusted_sites' => N_('Manage environment trusted sites')
  31 + 'manage_environment_trusted_sites' => N_('Manage environment trusted sites'),
  32 + 'edit_appearance' => N_('Edit appearance'),
32 33 }
33 34  
34 35 module Roles
... ... @@ -666,6 +667,16 @@ class Environment &lt; ActiveRecord::Base
666 667 end
667 668 end
668 669  
  670 + def update_theme(theme)
  671 + self.theme = theme
  672 + self.save!
  673 + end
  674 +
  675 + def update_layout_template(template)
  676 + self.layout_template = template
  677 + self.save!
  678 + end
  679 +
669 680 before_create do |env|
670 681 env.settings[:themes] ||= %w[
671 682 aluminium
... ...
app/views/admin_panel/index.html.erb
... ... @@ -6,6 +6,7 @@
6 6 <tr><td><%= link_to _('Environment settings'), :action => 'site_info' %></td></tr>
7 7 <tr><td><%= link_to _('Features'), :controller => 'features' %></td></tr>
8 8 <tr><td><%= link_to _('Plugins'), :controller => 'plugins' %></td></tr>
  9 + <tr><td><%= link_to _('Appearance'), :controller =>'environment_themes' %></td></tr>
9 10 <tr><td><%= link_to _('Sideboxes'), :controller => 'environment_design'%></td></tr>
10 11 <tr><td><%= link_to _('Homepage'), :action => 'set_portal_community' %></td></tr>
11 12 <tr><td><%= link_to _('Licenses'), :controller =>'licenses' %></td></tr>
... ...
app/views/cms/edit.html.erb
1 1 <%= error_messages_for 'article' %>
2   -<%= javascript_include_tag "article.js" %>
3 2  
4 3 <div class='<%= (environment.enabled?('media_panel') ? 'with_media_panel' : 'no_media_panel') %>'>
5 4 <%= labelled_form_for 'article', @article, :html => { :multipart => true, :class => @type } do |f| %>
... ... @@ -63,3 +62,5 @@
63 62 <% end %>
64 63  
65 64 <br style='clear: both'/>
  65 +
  66 +<%= javascript_include_tag "article.js" %>
... ...
app/views/comment/_comment.html.erb
... ... @@ -43,6 +43,7 @@
43 43 <p/>
44 44 <%= txt2html comment.body %>
45 45 </div>
  46 + <%= @plugins.dispatch(:comment_extra_contents, local_assigns).collect { |content| instance_eval(&content) }.join("") %>
46 47 </div>
47 48  
48 49 <div class="comment_reply post_comment_box closed" id="comment_reply_to_<%= comment.id %>">
... ...
app/views/environment_themes/index.html.erb 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +<%= render :partial => 'themes/select_template' %>
  2 +<%= render :partial => 'themes/select_theme' %>
  3 +
  4 +<br style="clear:both" />
  5 +
  6 +<% button_bar do %>
  7 + <%= button(:back, _('Back'), :controller => 'admin_panel', :action => 'index') %>
  8 +<% end %>
... ...
app/views/profile_editor/index.html.erb
... ... @@ -22,7 +22,7 @@
22 22  
23 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 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_themes/add_css.html.erb 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +<h2><%= _('Add a CSS file') %></h2>
  2 +
  3 +<%= form_tag do %>
  4 + <%= labelled_form_field(_('File name'), text_field_tag('css')) %>
  5 +
  6 + <% button_bar do %>
  7 + <%= submit_button(:add, _('Add')) %>
  8 + <%= lightbox_close_button(_('Cancel')) %>
  9 + <% end %>
  10 +
  11 +<% end %>
... ...
app/views/profile_themes/add_image.html.erb 0 → 100644
... ... @@ -0,0 +1,6 @@
  1 +<%= form_tag({:action => 'add_image', :id => @theme.id}, :multipart => true) do %>
  2 + <%= labelled_form_field(_('Choose the image file'), file_field_tag(:image)) %>
  3 + <% button_bar do %>
  4 + <%= submit_button(:add, _('Add image')) %>
  5 + <% end %>
  6 +<% end %>
... ...
app/views/profile_themes/css_editor.html.erb 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +<h2><%= _('CSS code: "%s"') % @css %></h2>
  2 +
  3 +<%= form_tag({:action => 'update_css', :id => @theme.id }, :name => 'csscode_form') do %>
  4 + <%= hidden_field_tag('css', @css) %>
  5 + <%= text_area_tag('csscode', @code, :id => "codepressWindow", :class => 'codepress css') %>
  6 + <% button_bar do %>
  7 + <%= submit_button(:save, _('Save')) %>
  8 + <% end %>
  9 +<% end %>
  10 +
  11 +<!--<script type='text/javascript'>-->
  12 + <!--CodePress.run();-->
  13 +<!--</script>-->
... ...
app/views/profile_themes/edit.html.erb 0 → 100644
... ... @@ -0,0 +1,41 @@
  1 +<form>
  2 + <%# FIXME %>
  3 + <h1 id='theme-name'>
  4 + <%= _('Editing theme "%s"') % @theme.name %>
  5 + <%= button(:eyes, _('Preview this theme'), :action => 'start_test', :id => @theme.id) %>
  6 + <%= button(:back, _('Back'), :action => 'index') %>
  7 + </h1>
  8 +</form>
  9 +
  10 +
  11 +<div id='css-files-list'>
  12 + <h2><%= _('CSS files') %></h2>
  13 + <ul>
  14 + <% for css in @css_files %>
  15 + <li><%= link_to_remote(css, :url => { :action => 'css_editor', :id => @theme.id, :css => css }, :update => { :success => 'css-code' }) %></li>
  16 + <% end %>
  17 + </ul>
  18 + <% button_bar do %>
  19 + <%= lightbox_button(:add, _('New CSS'), :action => 'add_css', :id => @theme.id) %>
  20 + <% end %>
  21 +</div>
  22 +
  23 +<div id='image-files-list'>
  24 + <h2><%= _('Images') %></h2>
  25 + <ul>
  26 + <% for image in @image_files %>
  27 + <li><%= image_tag("/user_themes/#{@theme.id}/images/#{image}") %></li>
  28 + <% end %>
  29 + </ul>
  30 + <% button_bar do %>
  31 + <%= lightbox_button(:add, _('Add image'), :action => 'add_image', :id => @theme.id) %>
  32 + <% end %>
  33 +</div>
  34 +
  35 +<div id='css-code'>
  36 + <center style='padding-top: 5em;'>
  37 + <em><%= _('Select a CSS file to edit') %></em>
  38 + </center>
  39 +</div>
  40 +
  41 +<%# javascript_include_tag 'codepress/codepress' %>
... ...
app/views/profile_themes/index.html.erb 0 → 100644
... ... @@ -0,0 +1,48 @@
  1 +<%= render :partial => 'themes/select_template' %>
  2 +<%= render :partial => 'themes/select_theme' %>
  3 +
  4 +<% if environment.enabled?('user_themes') %>
  5 + <div id="user-themes" class="list-options">
  6 +
  7 + <h2><%= _('My themes') %></h2>
  8 +
  9 + <% for themes in profile.themes.in_groups_of(3) %>
  10 + <div class="list-group">
  11 + <% for theme in themes %><%=
  12 + if theme
  13 +
  14 + selected = theme.id == @current_theme
  15 + sel_html = selected ?
  16 + content_tag('big', _('(current)') ) :
  17 + link_to(_('Use this theme'), :action => 'set', :id => theme.id)
  18 +
  19 + content_tag( 'div',
  20 + image_tag(
  21 + '/images/icons-app/design-editor.png',
  22 + :alt => (_('The "%s" theme.') % theme.name)) +
  23 + '<div class="opt-info">' +
  24 + content_tag('strong', theme.name, :class => 'name') +
  25 + ' <br/> '+ sel_html +' <br/> ' +
  26 + link_to(_('Edit this theme'), :action => 'edit', :id => theme.id) +
  27 + ' <br/> ' +
  28 + link_to(_('Test this theme'), :action => 'start_test', :id => theme.id) +
  29 + '</div>',
  30 + :class => 'theme-opt list-opt' + (selected ? ' selected' : '')
  31 + )
  32 +
  33 + end
  34 + %><% end %>
  35 + </div>
  36 + <% end %>
  37 +
  38 + </div><!-- end id="user-themes" -->
  39 +<% end %>
  40 +
  41 +<br style="clear:both" />
  42 +
  43 +<% button_bar do %>
  44 + <% if environment.enabled?('user_themes') %>
  45 + <%= lightbox_button(:add, _('New theme ...'), :action => 'new') %>
  46 + <% end %>
  47 + <%= button(:back, _('Back'), :controller => 'profile_editor', :action => 'index') %>
  48 +<% end %>
... ...
app/views/profile_themes/new.html.erb 0 → 100644
... ... @@ -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/_lead_and_body.html.erb
... ... @@ -33,4 +33,4 @@
33 33 <% end %>
34 34 </div>
35 35  
36   -<%= javascript_include_tag 'article'%>
  36 +<%= javascript_include_tag 'article-lead-and-body'%>
... ...
app/views/shared/theme_test_panel.html.erb
... ... @@ -6,8 +6,8 @@
6 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 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 11 <% end %>
12 12 </div>
13 13 <%= draggable_element('theme-test-panel') %>
... ...
app/views/themes/_select_template.html.erb 0 → 100644
... ... @@ -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, :class => 'name') +
  16 + ' <br/> '.html_safe
  17 +
  18 + if @current_template == template.id # selected
  19 + content_tag( 'div',
  20 + base_content + content_tag('big', _('(current)') ) +'</div>'.html_safe,
  21 + :class => 'template-opt list-opt selected')
  22 + else # Not selected
  23 + link_to(
  24 + base_content +'</div>'.html_safe,
  25 + { :action => 'set_layout_template', :id => template.id },
  26 + :class => 'template-opt list-opt')
  27 + end
  28 +
  29 + end
  30 + %><% end %>
  31 + </div>
  32 +<% end %>
  33 +
  34 +</div><!-- end id="template-options" -->
  35 +
... ...
app/views/themes/_select_theme.html.erb 0 → 100644
... ... @@ -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 +
... ...
app/views/themes/add_css.html.erb
... ... @@ -1,11 +0,0 @@
1   -<h2><%= _('Add a CSS file') %></h2>
2   -
3   -<%= form_tag do %>
4   - <%= labelled_form_field(_('File name'), text_field_tag('css')) %>
5   -
6   - <% button_bar do %>
7   - <%= submit_button(:add, _('Add')) %>
8   - <%= lightbox_close_button(_('Cancel')) %>
9   - <% end %>
10   -
11   -<% end %>
app/views/themes/add_image.html.erb
... ... @@ -1,6 +0,0 @@
1   -<%= form_tag({:action => 'add_image', :id => @theme.id}, :multipart => true) do %>
2   - <%= labelled_form_field(_('Choose the image file'), file_field_tag(:image)) %>
3   - <% button_bar do %>
4   - <%= submit_button(:add, _('Add image')) %>
5   - <% end %>
6   -<% end %>
app/views/themes/css_editor.html.erb
... ... @@ -1,13 +0,0 @@
1   -<h2><%= _('CSS code: "%s"') % @css %></h2>
2   -
3   -<%= form_tag({:action => 'update_css', :id => @theme.id }, :name => 'csscode_form') do %>
4   - <%= hidden_field_tag('css', @css) %>
5   - <%= text_area_tag('csscode', @code, :id => "codepressWindow", :class => 'codepress css') %>
6   - <% button_bar do %>
7   - <%= submit_button(:save, _('Save')) %>
8   - <% end %>
9   -<% end %>
10   -
11   -<!--<script type='text/javascript'>-->
12   - <!--CodePress.run();-->
13   -<!--</script>-->
app/views/themes/edit.html.erb
... ... @@ -1,41 +0,0 @@
1   -<form>
2   - <%# FIXME %>
3   - <h1 id='theme-name'>
4   - <%= _('Editing theme "%s"') % @theme.name %>
5   - <%= button(:eyes, _('Preview this theme'), :action => 'start_test', :id => @theme.id) %>
6   - <%= button(:back, _('Back'), :action => 'index') %>
7   - </h1>
8   -</form>
9   -
10   -
11   -<div id='css-files-list'>
12   - <h2><%= _('CSS files') %></h2>
13   - <ul>
14   - <% for css in @css_files %>
15   - <li><%= link_to_remote(css, :url => { :action => 'css_editor', :id => @theme.id, :css => css }, :update => { :success => 'css-code' }) %></li>
16   - <% end %>
17   - </ul>
18   - <% button_bar do %>
19   - <%= lightbox_button(:add, _('New CSS'), :action => 'add_css', :id => @theme.id) %>
20   - <% end %>
21   -</div>
22   -
23   -<div id='image-files-list'>
24   - <h2><%= _('Images') %></h2>
25   - <ul>
26   - <% for image in @image_files %>
27   - <li><%= image_tag("/user_themes/#{@theme.id}/images/#{image}") %></li>
28   - <% end %>
29   - </ul>
30   - <% button_bar do %>
31   - <%= lightbox_button(:add, _('Add image'), :action => 'add_image', :id => @theme.id) %>
32   - <% end %>
33   -</div>
34   -
35   -<div id='css-code'>
36   - <center style='padding-top: 5em;'>
37   - <em><%= _('Select a CSS file to edit') %></em>
38   - </center>
39   -</div>
40   -
41   -<%# javascript_include_tag 'codepress/codepress' %>
app/views/themes/index.html.erb
... ... @@ -1,120 +0,0 @@
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, :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   -
36   -
37   -<% if !@themes.empty? %>
38   -<div id="theme-options" class="list-options">
39   -
40   -<h2><%= _('Select theme') %></h2>
41   -<%= button :home, _('Use the default theme'), { :action => 'unset'}, :method => 'post', :confirm => _('Are you sure you want to use the environment default theme?') %>
42   -
43   -<% for themes in @themes.in_groups_of(3) %>
44   - <div class="list-group">
45   - <% for theme in themes %><%=
46   - if theme
47   -
48   - base_content = image_tag(
49   - "/designs/themes/#{theme.id}/preview.png",
50   - :alt => (_('The "%s" theme.') % theme.name)) +
51   - '<div class="opt-info">'.html_safe +
52   - content_tag('strong', theme.name, :class => 'name') +
53   - ' <br/> '.html_safe
54   -
55   - if theme.id == @current_theme # selected
56   - content_tag( 'div',
57   - base_content + content_tag('big', _('(current)') ) +'</div>'.html_safe,
58   - :class => 'theme-opt list-opt selected')
59   - else # Not selected
60   - link_to(
61   - base_content + '</div>'.html_safe,
62   - { :action => 'set', :id => theme.id },
63   - :class => 'theme-opt list-opt')
64   - end
65   -
66   - end
67   - %><% end %>
68   - </div>
69   -<% end %>
70   -
71   -</div><!-- end id="theme-options" -->
72   -<% end %>
73   -
74   -
75   -
76   -<% if environment.enabled?('user_themes') %>
77   - <div id="user-themes" class="list-options">
78   -
79   - <h2><%= _('My themes') %></h2>
80   -
81   - <% for themes in profile.themes.in_groups_of(3) %>
82   - <div class="list-group">
83   - <% for theme in themes %><%=
84   - if theme
85   -
86   - selected = theme.id == @current_theme
87   - sel_html = selected ?
88   - content_tag('big', _('(current)') ) :
89   - link_to(_('Use this theme'), :action => 'set', :id => theme.id)
90   -
91   - content_tag( 'div',
92   - image_tag(
93   - '/images/icons-app/design-editor.png',
94   - :alt => (_('The "%s" theme.') % theme.name)) +
95   - '<div class="opt-info">' +
96   - content_tag('strong', theme.name, :class => 'name') +
97   - ' <br/> '+ sel_html +' <br/> ' +
98   - link_to(_('Edit this theme'), :action => 'edit', :id => theme.id) +
99   - ' <br/> ' +
100   - link_to(_('Test this theme'), :action => 'start_test', :id => theme.id) +
101   - '</div>',
102   - :class => 'theme-opt list-opt' + (selected ? ' selected' : '')
103   - )
104   -
105   - end
106   - %><% end %>
107   - </div>
108   - <% end %>
109   -
110   - </div><!-- end id="user-themes" -->
111   -<% end %>
112   -
113   -<br style="clear:both" />
114   -
115   -<% button_bar do %>
116   - <% if environment.enabled?('user_themes') %>
117   - <%= lightbox_button(:add, _('New theme ...'), :action => 'new') %>
118   - <% end %>
119   - <%= button(:back, _('Back'), :controller => 'profile_editor', :action => 'index') %>
120   -<% end %>
app/views/themes/new.html.erb
... ... @@ -1,10 +0,0 @@
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 %>
debian/changelog
  1 +noosfero (0.46.0) unstable; urgency=low
  2 +
  3 + * New features release
  4 +
  5 + -- Rodrigo Souto <rodrigo@colivre.coop.br> Thu, 20 Feb 2014 17:56:14 -0300
  6 +
  7 +noosfero (0.46.0~rc20140120171635) squeeze-test; urgency=low
  8 +
  9 + * 0.46.0 RC1
  10 +
  11 + -- Rodrigo Souto <rodrigo@colivre.coop.br> Mon, 20 Jan 2014 17:16:45 +0000
  12 +
1 13 noosfero (0.45.2) unstable; urgency=low
2 14  
3 15 * Small release with a critical bugfix
... ...
lib/noosfero.rb
... ... @@ -4,7 +4,7 @@ require &#39;fast_gettext&#39;
4 4  
5 5 module Noosfero
6 6 PROJECT = 'noosfero'
7   - VERSION = '0.45.2'
  7 + VERSION = '0.46.0'
8 8  
9 9 def self.pattern_for_controllers_in_directory(dir)
10 10 disjunction = controllers_in_directory(dir).join('|')
... ...
lib/noosfero/plugin.rb
... ... @@ -462,6 +462,25 @@ class Noosfero::Plugin
462 462 nil
463 463 end
464 464  
  465 + # -> Adds adittional content to comment visualization
  466 + # returns = lambda block that creates html code
  467 + def comment_extra_contents(args)
  468 + nil
  469 + end
  470 +
  471 + # This method is called when the user clicks to send a comment.
  472 + # A plugin can add new content to comment form and this method can process the params sent to avoid creating field on core tables.
  473 + # returns = params after processed by plugins
  474 + # example:
  475 + #
  476 + # def process_extra_comment_params(params)
  477 + # params.delete(:extra_field)
  478 + # end
  479 + #
  480 + def process_extra_comment_params(params)
  481 + params
  482 + end
  483 +
465 484 # -> Finds objects by their contents
466 485 # returns = {:results => [a, b, c, ...], ...}
467 486 # P.S.: The plugin might add other informations on the return hash for its
... ...
public/javascripts/article-lead-and-body.js 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +jQuery(function($) {
  2 + $(".lead-button").live('click', function(){
  3 + article_id = this.getAttribute("article_id");
  4 + $(this).toggleClass('icon-add').toggleClass('icon-remove');
  5 + $(article_id).slideToggle();
  6 + return false;
  7 + })
  8 +});
... ...
public/javascripts/article.js
1 1 jQuery(function($) {
2   - $(".lead-button").live('click', function(){
3   - article_id = this.getAttribute("article_id");
4   - $(this).toggleClass('icon-add').toggleClass('icon-remove');
5   - $(article_id).slideToggle();
6   - return false;
7   - })
8 2 $("#body-button").click(function(){
9 3 $(this).toggleClass('icon-add').toggleClass('icon-remove');
10 4 $('#article-body-field').slideToggle();
... ...
public/stylesheets/application.css
... ... @@ -4323,7 +4323,7 @@ h1#agenda-title {
4323 4323 padding-left: 0px;
4324 4324 list-style-type: none;
4325 4325 }
4326   -/* ==> public/stylesheets/controller_themes.css <== */
  4326 +/* ==> public/stylesheets/profile_controller_themes.css <== */
4327 4327  
4328 4328 .action-themes-index .button-bar {
4329 4329 padding-top: 20px;
... ... @@ -4397,23 +4397,23 @@ h1#agenda-title {
4397 4397 #user-themes a:hover {
4398 4398 text-decoration: underline;
4399 4399 }
4400   -.controller-themes .template-preview-cell {
  4400 +.controller-profile_themes .template-preview-cell {
4401 4401 text-align: center;
4402 4402 }
4403   -.controller-themes .theme-preview {
  4403 +.controller-profile_themes .theme-preview {
4404 4404 border: 1px solid #BBB;
4405 4405 }
4406   -.controller-themes #css-files-list h2, .controller-themes #image-files-list h2 {
  4406 +.controller-profile_themes #css-files-list h2, .controller-profile_themes #image-files-list h2 {
4407 4407 margin-top: 0px;
4408 4408 }
4409   -.controller-themes #css-files-list ul, .controller-themes #image-files-list ul, .controller-themes #css-code textarea {
  4409 +.controller-profile_themes #css-files-list ul, .controller-profile_themes #image-files-list ul, .controller-profile_themes #css-code textarea {
4410 4410 height: 280px;
4411 4411 }
4412   -.controller-themes #css-files-list ul, .controller-themes #image-files-list ul {
  4412 +.controller-profile_themes #css-files-list ul, .controller-profile_themes #image-files-list ul {
4413 4413 overflow: auto;
4414 4414 }
4415 4415 /* header stuff */
4416   -.controller-themes #theme-name input {
  4416 +.controller-profile_themes #theme-name input {
4417 4417 font-size: 18px;
4418 4418 border: 1px solid black;
4419 4419 background: white;
... ... @@ -4422,78 +4422,78 @@ h1#agenda-title {
4422 4422 }
4423 4423 /* files list */
4424 4424  
4425   -.controller-themes #css-files-list {
  4425 +.controller-profile_themes #css-files-list {
4426 4426 width: 200px;
4427 4427 float: left;
4428 4428 margin-left: 10px;
4429 4429 }
4430   -.controller-themes #css-files-list ul {
  4430 +.controller-profile_themes #css-files-list ul {
4431 4431 margin: 0px;
4432 4432 padding-left: 0px;
4433 4433 background: white;
4434 4434 border: 1px solid #bbb;
4435 4435 }
4436   -.controller-themes #css-files-list li {
  4436 +.controller-profile_themes #css-files-list li {
4437 4437 list-style: none;
4438 4438 margin-bottom: 5px;
4439 4439 border-bottom: 1px solid #bbb;
4440 4440 }
4441   -.controller-themes #css-files-list li a {
  4441 +.controller-profile_themes #css-files-list li a {
4442 4442 display: block;
4443 4443 padding: 1px 5px;
4444 4444 }
4445   -.controller-themes #css-files-list a:hover {
  4445 +.controller-profile_themes #css-files-list a:hover {
4446 4446 color: red;
4447 4447 }
4448 4448 /* images list */
4449 4449  
4450   -.controller-themes #image-files-list {
  4450 +.controller-profile_themes #image-files-list {
4451 4451 width: 200px;
4452 4452 float: right;
4453 4453 margin-right: 10px;
4454 4454 }
4455   -.controller-themes #image-files-list ul {
  4455 +.controller-profile_themes #image-files-list ul {
4456 4456 background: white;
4457 4457 border: 1px solid #bbb;
4458 4458 }
4459   -.controller-themes #image-files-list ul, .controller-themes #image-files-list li {
  4459 +.controller-profile_themes #image-files-list ul, .controller-profile_themes #image-files-list li {
4460 4460 padding: 0px;
4461 4461 margin: 0px;
4462 4462 list-style: none;
4463 4463 }
4464   -.controller-themes #image-files-list li {
  4464 +.controller-profile_themes #image-files-list li {
4465 4465 border-bottom: 1px solid #bbb;
4466 4466 padding: 5px 0px;
4467 4467 text-align: center;
4468 4468 }
4469   -.controller-themes #image-files-list img {
  4469 +.controller-profile_themes #image-files-list img {
4470 4470 max-width: 98%;
4471 4471 max-height: 40px;
4472 4472 }
4473   -.controller-themes .msie6 #image-files-list img {
  4473 +.controller-profile_themes .msie6 #image-files-list img {
4474 4474 width: 50%;
4475 4475 height: 40px;
4476 4476 }
4477   -.controller-themes #image-files-list li span {
  4477 +.controller-profile_themes #image-files-list li span {
4478 4478 display: block;
4479 4479 width: 100%;
4480 4480 overflow: hidden;
4481 4481 }
4482 4482 /* textbox */
4483 4483  
4484   -.controller-themes #css-code {
  4484 +.controller-profile_themes #css-code {
4485 4485 margin-left: 220px;
4486 4486 margin-right: 220px;
4487 4487 }
4488   -.controller-themes .msie6 #css-code {
  4488 +.controller-profile_themes .msie6 #css-code {
4489 4489 float: left;
4490 4490 margin-left: 20px;
4491 4491 margin-right: 240px;
4492 4492 }
4493   -.controller-themes #css-code textarea {
  4493 +.controller-profile_themes #css-code textarea {
4494 4494 width: 100%;
4495 4495 }
4496   -.controller-themes .msie6 #css-code textarea {
  4496 +.controller-profile_themes .msie6 #css-code textarea {
4497 4497 width: 500px;
4498 4498 }
4499 4499 /* highlights block stuff */
... ...
test/factories.rb
... ... @@ -61,7 +61,7 @@ module Noosfero::Factory
61 61 ###### old stuff to be rearranged
62 62 def create_admin_user(env)
63 63 admin_user = User.find_by_login('adminuser') || create_user('adminuser', :email => 'adminuser@noosfero.org', :password => 'adminuser', :password_confirmation => 'adminuser', :environment => env)
64   - admin_role = Role.find_by_name('admin_role') || create(Role, :name => 'admin_role', :permissions => ['view_environment_admin_panel','edit_environment_features', 'edit_environment_design', 'manage_environment_categories', 'manage_environment_roles', 'manage_environment_trusted_sites', 'manage_environment_validators', 'manage_environment_users', 'manage_environment_templates', 'manage_environment_licenses'])
  64 + admin_role = Role.find_by_name('admin_role') || Role.create!(:name => 'admin_role', :permissions => ['view_environment_admin_panel','edit_environment_features', 'edit_environment_design', 'manage_environment_categories', 'manage_environment_roles', 'manage_environment_trusted_sites', 'manage_environment_validators', 'manage_environment_users', 'manage_environment_templates', 'manage_environment_licenses', 'edit_appearance'])
65 65 create(RoleAssignment, :accessor => admin_user.person, :role => admin_role, :resource => env) unless admin_user.person.role_assignments.map{|ra|[ra.role, ra.accessor, ra.resource]}.include?([admin_role, admin_user, env])
66 66 admin_user.login
67 67 end
... ...
test/functional/environment_themes_controller_test.rb 0 → 100644
... ... @@ -0,0 +1,140 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class EnvironmentThemesController; def rescue_action(e) raise e end; end
  4 +
  5 +class EnvironmentThemesControllerTest < ActionController::TestCase
  6 +
  7 + def setup
  8 + @controller = EnvironmentThemesController.new
  9 + @request = ActionController::TestRequest.new
  10 + @response = ActionController::TestResponse.new
  11 +
  12 + Theme.stubs(:user_themes_dir).returns(TMP_THEMES_DIR)
  13 +
  14 + @env = Environment.default
  15 + login = create_admin_user(@env)
  16 + login_as(login)
  17 + @profile = User.find_by_login(login).person
  18 + end
  19 +
  20 + def teardown
  21 + FileUtils.rm_rf(TMP_THEMES_DIR)
  22 + end
  23 +
  24 + TMP_THEMES_DIR = Rails.root.join("test", "tmp", "environment_themes_controller")
  25 +
  26 + should 'display themes that can be applied' do
  27 + env = Environment.default
  28 + Theme.stubs(:approved_themes).with(@env).returns([])
  29 + t1 = 't1'
  30 + t2 = 't2'
  31 + t3 = 't3'
  32 + env.themes = [t1, t2]
  33 + env.save
  34 +
  35 + Theme.stubs(:system_themes).returns([Theme.new(t1), Theme.new(t2), Theme.new(t3)])
  36 + get :index
  37 +
  38 + %w[ t1 t2 ].each do |item|
  39 + assert_tag :tag => 'a', :attributes => { :href => "/admin/environment_themes/set/#{item}" }
  40 + end
  41 +
  42 + assert_no_tag :tag => 'a', :attributes => { :href => "/admin/environment_themes/set/t3" }
  43 + end
  44 +
  45 + should 'highlight current theme' do
  46 + env = Environment.default
  47 + t1 = 'one'
  48 + t2 = 'two'
  49 + env.themes = [t1, t2]
  50 + env.save
  51 +
  52 + Theme.stubs(:system_themes).returns([Theme.new(t1), Theme.new(t2)])
  53 + env.update_theme(t1)
  54 + get :index
  55 +
  56 + assert_tag :attributes => { :class => 'theme-opt list-opt selected' }
  57 + assert_no_tag :tag => 'a', :attributes => { :href => "/admin/environment_themes/set/one" }
  58 + end
  59 +
  60 + should 'save selection of theme' do
  61 + get :set, :id => 'onetheme'
  62 + env = Environment.default
  63 + assert_equal 'onetheme', env.theme
  64 + end
  65 +
  66 +
  67 + should 'unset selection of theme' do
  68 + get :unset
  69 + env = Environment.default
  70 + assert_equal 'default', env.theme
  71 + end
  72 +
  73 + should 'display link to use the default theme' do
  74 + env = Environment.default
  75 + env.themes = ['new-theme']
  76 + env.save
  77 +
  78 + Theme.stubs(:system_themes).returns([Theme.new('new-theme')])
  79 +
  80 + get :index
  81 + assert_tag :tag => 'a', :attributes => { :href => "/admin/environment_themes/unset" }
  82 + end
  83 +
  84 + should 'point back to admin panel' do
  85 + get :index
  86 + assert_tag :tag => 'a', :attributes => { :href => '/admin' }, :content => 'Back'
  87 + end
  88 +
  89 + should 'list templates' do
  90 + all = LayoutTemplate.all
  91 +
  92 + LayoutTemplate.expects(:all).returns(all)
  93 + get :index
  94 + assert_same all, assigns(:layout_templates)
  95 + end
  96 +
  97 + should 'display links to set template' do
  98 + env = Environment.default
  99 + env.layout_template = 'rightbar'
  100 + env.save!
  101 + t1 = LayoutTemplate.find('default')
  102 + t2 = LayoutTemplate.find('leftbar')
  103 + LayoutTemplate.expects(:all).returns([t1, t2])
  104 +
  105 + get :index
  106 + assert_tag :tag => 'a', :attributes => { :href => "/admin/environment_themes/set_layout_template/default"}
  107 + assert_tag :tag => 'a', :attributes => { :href => "/admin/environment_themes/set_layout_template/leftbar"}
  108 + end
  109 +
  110 + should 'highlight current template' do
  111 + env = Environment.default
  112 + env.update_attributes!(:layout_template => 'default')
  113 + env.layout_template = 'default'
  114 +
  115 + t1 = LayoutTemplate.find('default')
  116 + t2 = LayoutTemplate.find('leftbar')
  117 + LayoutTemplate.expects(:all).returns([t1, t2])
  118 +
  119 + get :index
  120 + assert_tag :attributes => { :class => 'template-opt list-opt selected' }
  121 + assert_no_tag :tag => 'a', :attributes => { :href => "/admin/environment_themes/set_layout_template/default"}
  122 + end
  123 +
  124 + should 'set template' do
  125 + env = Environment.default
  126 + post :set_layout_template, :id => 'leftbar'
  127 + env.reload
  128 + assert_equal 'leftbar', env.layout_template
  129 + assert_redirected_to :action => 'index'
  130 + end
  131 +
  132 + should 'not display the "Select themes" section if there are no themes to choose from' do
  133 + env = Environment.default
  134 + env.themes = []; env.save!
  135 + Theme.stubs(:system_themes_dir).returns(TMP_THEMES_DIR) # an empty dir
  136 + get :index
  137 + assert_no_tag :content => "Select theme"
  138 + end
  139 +
  140 +end
... ...
test/functional/profile_themes_controller_test.rb 0 → 100644
... ... @@ -0,0 +1,313 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +# require 'profile_themes_controller'
  3 +
  4 +class ProfileThemesController; def rescue_action(e) raise e end; end
  5 +
  6 +class ProfileThemesControllerTest < ActionController::TestCase
  7 +
  8 + def setup
  9 + @controller = ProfileThemesController.new
  10 + @request = ActionController::TestRequest.new
  11 + @response = ActionController::TestResponse.new
  12 +
  13 + Theme.stubs(:user_themes_dir).returns(TMP_THEMES_DIR)
  14 +
  15 + @profile = create_user('testinguser').person
  16 + login_as('testinguser')
  17 +
  18 + @env = Environment.default
  19 + @env.enable('user_themes')
  20 + @env.save!
  21 + end
  22 + attr_reader :profile, :env
  23 +
  24 + def teardown
  25 + FileUtils.rm_rf(TMP_THEMES_DIR)
  26 + end
  27 +
  28 + TMP_THEMES_DIR = Rails.root.join("test", "tmp", "profile_themes_controller")
  29 +
  30 + should 'display themes that can be applied' do
  31 + env = Environment.default
  32 + Theme.stubs(:approved_themes).with(@profile).returns([Theme.new('t1', :name => 't1')])
  33 + t2 = 't2'
  34 + t3 = 't3'
  35 + env.themes = [t2]
  36 + env.save
  37 +
  38 + Theme.stubs(:system_themes).returns([Theme.new(t2), Theme.new(t3)])
  39 + get :index, :profile => 'testinguser'
  40 +
  41 + %w[ t1 t2 ].each do |item|
  42 + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/testinguser/profile_themes/set/#{item}" }
  43 + end
  44 +
  45 + assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/testinguser/profile_themes/set/t3" }
  46 + end
  47 +
  48 + should 'highlight current theme' do
  49 + env = Environment.default
  50 + t1 = 'one'
  51 + t2 = 'two'
  52 + env.themes = [t1, t2]
  53 + env.save
  54 +
  55 + Theme.stubs(:system_themes).returns([Theme.new(t1), Theme.new(t2)])
  56 + profile.update_theme(t1)
  57 + get :index, :profile => 'testinguser'
  58 +
  59 + assert_tag :attributes => { :class => 'theme-opt list-opt selected' }
  60 + assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/testinguser/profile_themes/set/one" }
  61 + end
  62 +
  63 + should 'display list of my themes for edition' do
  64 + Theme.create('three', :owner => profile)
  65 + Theme.create('four', :owner => profile)
  66 +
  67 + get :index, :profile => 'testinguser'
  68 +
  69 + %w[ three four ].each do |item|
  70 + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/testinguser/profile_themes/edit/#{item}" }
  71 + end
  72 + end
  73 +
  74 + should 'save selection of theme' do
  75 + get :set, :profile => 'testinguser', :id => 'onetheme'
  76 + profile = Profile.find(@profile.id)
  77 + assert_equal 'onetheme', profile.theme
  78 + end
  79 +
  80 + should 'save selection of theme even if model is invalid' do
  81 + @profile.sex = nil
  82 + @profile.save!
  83 + @profile.environment.custom_person_fields = { 'sex' => {'required' => 'true', 'active' => 'true'} }; @profile.environment.save!
  84 +
  85 + get :set, :profile => 'testinguser', :id => 'onetheme'
  86 + profile = Profile.find(@profile.id)
  87 + assert_equal 'onetheme', profile.theme
  88 + end
  89 +
  90 + should 'unset selection of theme' do
  91 + get :unset, :profile => 'testinguser'
  92 + assert_equal nil, profile.theme
  93 + end
  94 +
  95 + should 'display link to use the default theme' do
  96 + env = Environment.default
  97 + env.themes = ['new-theme']
  98 + env.save
  99 +
  100 + Theme.stubs(:system_themes).returns([Theme.new('new-theme')])
  101 +
  102 + get :index, :profile => 'testinguser'
  103 + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/testinguser/profile_themes/unset" }
  104 + end
  105 +
  106 + should 'point back to control panel' do
  107 + get :index, :profile => 'testinguser'
  108 + assert_tag :tag => 'a', :attributes => { :href => '/myprofile/testinguser' }, :content => 'Back'
  109 + end
  110 +
  111 + should 'display screen for creating new theme' do
  112 + @request.expects(:xhr?).returns(true).at_least_once
  113 + get :new, :profile => 'testinguser'
  114 + assert_tag :tag => 'form', :attributes => { :action => '/myprofile/testinguser/profile_themes/new', :method => /post/i }, :descendant => { :tag => 'input', :attributes => { :type => 'text', :name => 'name' } }
  115 + end
  116 +
  117 + should 'create a new theme' do
  118 + post :new, :profile => 'testinguser', :name => 'My theme'
  119 +
  120 + ok('theme should be created') do
  121 + profile.themes.first.id == 'my-theme'
  122 + end
  123 + end
  124 +
  125 + should 'edit a theme' do
  126 + theme = Theme.create('mytheme', :owner => profile)
  127 + get :edit, :profile => 'testinguser', :id => 'mytheme'
  128 +
  129 + assert_equal theme, assigns(:theme)
  130 + end
  131 +
  132 + should 'list CSS files in theme' do
  133 + theme = Theme.create('mytheme', :owner => profile)
  134 + theme.add_css('one.css')
  135 + theme.add_css('two.css')
  136 +
  137 + get :edit, :profile => 'testinguser', :id => 'mytheme'
  138 +
  139 + %w[ one.css two.css ].each do |item|
  140 + assert_includes assigns(:css_files), item
  141 + assert_tag :tag => 'li', :descendant => { :tag => 'a', :content => item}
  142 + end
  143 + end
  144 +
  145 + should 'display dialog for creating new CSS' do
  146 + theme = Theme.create('mytheme', :owner => profile)
  147 + @request.stubs(:xhr?).returns(true)
  148 + get :add_css, :profile => 'testinguser', :id => 'mytheme'
  149 +
  150 + assert_tag :tag => 'form', :attributes => { :action => '/myprofile/testinguser/profile_themes/add_css/mytheme', :method => /post/i}
  151 + assert_tag :tag => 'input', :attributes => { :name => 'css', :type => 'text' }
  152 + assert_tag :tag => 'input', :attributes => { :type => 'submit' }
  153 + end
  154 +
  155 + should 'be able to add new CSS to theme' do
  156 + theme = Theme.create('mytheme', :owner => profile)
  157 + post :add_css, :profile => 'testinguser', :id => 'mytheme', :css => 'test.css'
  158 +
  159 + assert_response :redirect
  160 +
  161 + reloaded_theme = Theme.find('mytheme')
  162 + assert_includes reloaded_theme.css_files, 'test.css'
  163 + end
  164 +
  165 + should 'load code from a given CSS file' do
  166 + theme = Theme.create('mytheme', :owner => profile); theme.update_css('test.css', '/* sample code */')
  167 + get :css_editor, :profile => 'testinguser', :id => 'mytheme', :css => 'test.css'
  168 +
  169 + assert_tag :tag => 'form', :attributes => { :action => '/myprofile/testinguser/profile_themes/update_css/mytheme' }, :descendant => { :tag => 'textarea', :content => /\/\* sample code \*\// }
  170 + end
  171 +
  172 + should 'be able to save CSS code' do
  173 + theme = Theme.create('mytheme', :owner => profile); theme.update_css('test.css', '/* sample code */')
  174 + get :css_editor, :profile => 'testinguser', :id => 'mytheme', :css => 'test.css'
  175 +
  176 + assert_tag :tag => 'form', :attributes => { :action => '/myprofile/testinguser/profile_themes/update_css/mytheme' }, :descendant => { :tag => 'input', :attributes => { :type => 'submit' } }
  177 + assert_tag :tag => 'form', :attributes => { :action => '/myprofile/testinguser/profile_themes/update_css/mytheme' }, :descendant => { :tag => 'input', :attributes => { :type => 'hidden', :name => 'css', :value => 'test.css' } }
  178 + end
  179 +
  180 + should 'update css code when saving' do
  181 + theme = Theme.create('mytheme', :owner => profile); theme.update_css('test.css', '/* sample code */')
  182 + post :update_css, :profile => 'testinguser', :id => 'mytheme', :css => 'test.css', :csscode => 'body { background: white; }'
  183 + assert_equal 'body { background: white; }', theme.read_css('test.css')
  184 + end
  185 +
  186 + should 'list image files in theme' do
  187 + theme = Theme.create('mytheme', :owner => profile)
  188 + theme.add_image('one.png', 'FAKE IMAGE DATA 1')
  189 + theme.add_image('two.png', 'FAKE IMAGE DATA 2')
  190 +
  191 + get :edit, :profile => 'testinguser', :id => 'mytheme'
  192 +
  193 + assert_tag :tag => 'img', :attributes => { :src => '/user_themes/mytheme/images/one.png' }
  194 + assert_tag :tag => 'img', :attributes => { :src => '/user_themes/mytheme/images/two.png' }
  195 + end
  196 +
  197 + should 'display "add image" button' do
  198 + theme = Theme.create('mytheme', :owner => profile)
  199 + get :edit, :profile => 'testinguser', :id => 'mytheme'
  200 +
  201 + assert_tag :tag => 'a', :attributes => { :href => '/myprofile/testinguser/profile_themes/add_image/mytheme' }
  202 + end
  203 +
  204 + should 'display the "add image" dialog' do
  205 + theme = Theme.create('mytheme', :owner => profile)
  206 + @request.stubs(:xhr?).returns(true)
  207 +
  208 + get :add_image, :profile => 'testinguser', :id => 'mytheme'
  209 + assert_tag :tag => 'form', :attributes => { :action => '/myprofile/testinguser/profile_themes/add_image/mytheme', :method => /post/i, :enctype => 'multipart/form-data' }, :descendant => { :tag => 'input', :attributes => { :name => 'image', :type => 'file' } }
  210 + end
  211 +
  212 + should 'be able to add new image to theme' do
  213 + theme = Theme.create('mytheme', :owner => profile)
  214 + @request.stubs(:xhr?).returns(false)
  215 +
  216 + post :add_image, :profile => 'testinguser', :id => 'mytheme', :image => fixture_file_upload('/files/rails.png', 'image/png', :binary)
  217 + assert_redirected_to :action => "edit", :id => 'mytheme'
  218 + assert theme.image_files.include?('rails.png')
  219 + assert(system('diff', Rails.root.join('test', 'fixtures', 'files','rails.png').to_s, TMP_THEMES_DIR.join('mytheme/images/rails.png').to_s), 'should put the correct uploaded file in the right place')
  220 + end
  221 +
  222 + should 'link to "test theme"' do
  223 + Theme.create('one', :owner => profile)
  224 + Theme.create('two', :owner => profile)
  225 + get :index, :profile => 'testinguser'
  226 +
  227 + %w[ one two ].each do |item|
  228 + assert_tag :tag => 'a', :attributes => { :href => '/myprofile/testinguser/profile_themes/start_test/' + item }
  229 + end
  230 + end
  231 +
  232 + should 'start testing theme' do
  233 + theme = Theme.create('theme-under-test', :owner => profile)
  234 + post :start_test, :profile => 'testinguser', :id => 'theme-under-test'
  235 +
  236 + assert_equal 'theme-under-test', session[:theme]
  237 + assert_redirected_to :controller => 'content_viewer', :profile => 'testinguser', :action => 'view_page'
  238 + end
  239 +
  240 + should 'stop testing theme' do
  241 + theme = Theme.create('theme-under-test', :owner => profile)
  242 + post :stop_test, :profile => 'testinguser', :id => 'theme-under-test'
  243 +
  244 + assert_nil session[:theme]
  245 + assert_redirected_to :action => 'index'
  246 + end
  247 +
  248 + should 'list templates' do
  249 + all = LayoutTemplate.all
  250 +
  251 + LayoutTemplate.expects(:all).returns(all)
  252 + get :index, :profile => 'testinguser'
  253 + assert_equal all, assigns(:layout_templates)
  254 + end
  255 +
  256 + should 'display links to set template' do
  257 + profile.layout_template = 'rightbar'
  258 + profile.save!
  259 + t1 = LayoutTemplate.find('default')
  260 + t2 = LayoutTemplate.find('leftbar')
  261 + LayoutTemplate.expects(:all).returns([t1, t2])
  262 +
  263 + get :index, :profile => 'testinguser'
  264 + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/testinguser/profile_themes/set_layout_template/default"}
  265 + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/testinguser/profile_themes/set_layout_template/leftbar"}
  266 + end
  267 +
  268 + should 'highlight current template' do
  269 + profile.layout_template = 'default'
  270 + profile.save!
  271 +
  272 + t1 = LayoutTemplate.find('default')
  273 + t2 = LayoutTemplate.find('leftbar')
  274 + LayoutTemplate.expects(:all).returns([t1, t2])
  275 +
  276 + get :index, :profile => 'testinguser'
  277 + assert_tag :attributes => { :class => 'template-opt list-opt selected' }
  278 + assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/testinguser/profile_themes/set_layout_template/default"}
  279 + end
  280 +
  281 + should 'set template' do
  282 + post :set_layout_template, :profile => 'testinguser', :id => 'leftbar'
  283 + profile = Profile.find(@profile.id)
  284 + assert_equal 'leftbar', profile.layout_template
  285 + assert_redirected_to :action => 'index'
  286 + end
  287 +
  288 + should 'set template even if the model is invalid' do
  289 + @profile.sex = nil
  290 + @profile.save!
  291 + @profile.environment.custom_person_fields = { 'sex' => {'required' => 'true', 'active' => 'true'} }; @profile.environment.save!
  292 +
  293 + post :set_layout_template, :profile => 'testinguser', :id => 'leftbar'
  294 + profile = Profile.find(@profile.id)
  295 + assert_equal 'leftbar', profile.layout_template
  296 + assert_redirected_to :action => 'index'
  297 + end
  298 +
  299 + should 'not display "new theme" button when user themes are disabled' do
  300 + env.disable('user_themes')
  301 + env.save!
  302 + get :index, :profile => 'testinguser'
  303 + assert_no_tag :tag => 'a', :attributes => { :href => '/myprofile/testinguser/profile_themes/new' }
  304 + end
  305 +
  306 + should 'not display the "Select themes" section if there are no themes to choose from' do
  307 + env.themes = []; env.save!
  308 + Theme.stubs(:system_themes_dir).returns(TMP_THEMES_DIR) # an empty dir
  309 + get :index, :profile => "testinguser"
  310 + assert_no_tag :content => "Select theme"
  311 + end
  312 +
  313 +end
... ...
test/functional/themes_controller_test.rb
... ... @@ -1,311 +0,0 @@
1   -require File.dirname(__FILE__) + '/../test_helper'
2   -require 'themes_controller'
3   -
4   -class ThemesController; def rescue_action(e) raise e end; end
5   -
6   -class ThemesControllerTest < ActionController::TestCase
7   -
8   - def setup
9   - @controller = ThemesController.new
10   - @request = ActionController::TestRequest.new
11   - @response = ActionController::TestResponse.new
12   -
13   - Theme.stubs(:user_themes_dir).returns(TMP_THEMES_DIR)
14   -
15   - @profile = create_user('testinguser').person
16   - login_as('testinguser')
17   -
18   - @env = Environment.default
19   - @env.enable('user_themes')
20   - @env.save!
21   - end
22   - attr_reader :profile, :env
23   -
24   - def teardown
25   - FileUtils.rm_rf(TMP_THEMES_DIR)
26   - end
27   -
28   - TMP_THEMES_DIR = Rails.root.join("test", "tmp", "themes_controller")
29   -
30   - should 'display themes that can be applied' do
31   - env = Environment.default
32   - Theme.stubs(:approved_themes).with(@profile).returns([Theme.new('t1', :name => 't1')])
33   - t2 = 't2'
34   - t3 = 't3'
35   - env.themes = [t2]
36   - env.save
37   -
38   - Theme.stubs(:system_themes).returns([Theme.new(t2), Theme.new(t3)])
39   - get :index, :profile => 'testinguser'
40   -
41   - %w[ t1 t2 ].each do |item|
42   - assert_tag :tag => 'a', :attributes => { :href => "/myprofile/testinguser/themes/set/#{item}" }
43   - end
44   -
45   - assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/testinguser/themes/set/t3" }
46   - end
47   -
48   - should 'highlight current theme' do
49   - env = Environment.default
50   - t1 = 'one'
51   - t2 = 'two'
52   - env.themes = [t1, t2]
53   - env.save
54   -
55   - Theme.stubs(:system_themes).returns([Theme.new(t1), Theme.new(t2)])
56   - profile.update_theme(t1)
57   - get :index, :profile => 'testinguser'
58   -
59   - assert_tag :attributes => { :class => 'theme-opt list-opt selected' }
60   - assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/testinguser/themes/set/one" }
61   - end
62   -
63   - should 'display list of my themes for edition' do
64   - Theme.create('three', :owner => profile)
65   - Theme.create('four', :owner => profile)
66   -
67   - get :index, :profile => 'testinguser'
68   -
69   - %w[ three four ].each do |item|
70   - assert_tag :tag => 'a', :attributes => { :href => "/myprofile/testinguser/themes/edit/#{item}" }
71   - end
72   - end
73   -
74   - should 'save selection of theme' do
75   - get :set, :profile => 'testinguser', :id => 'onetheme'
76   - profile = Profile.find(@profile.id)
77   - assert_equal 'onetheme', profile.theme
78   - end
79   -
80   - should 'save selection of theme even if model is invalid' do
81   - @profile.sex = nil
82   - @profile.save!
83   - @profile.environment.custom_person_fields = { 'sex' => {'required' => 'true', 'active' => 'true'} }; @profile.environment.save!
84   -
85   - get :set, :profile => 'testinguser', :id => 'onetheme'
86   - profile = Profile.find(@profile.id)
87   - assert_equal 'onetheme', profile.theme
88   - end
89   -
90   - should 'unset selection of theme' do
91   - get :unset, :profile => 'testinguser'
92   - assert_equal nil, profile.theme
93   - end
94   -
95   - should 'display link to use the default theme' do
96   - env = Environment.default
97   - env.themes = ['new-theme']
98   - env.save
99   -
100   - Theme.stubs(:system_themes).returns([Theme.new('new-theme')])
101   -
102   - get :index, :profile => 'testinguser'
103   - assert_tag :tag => 'a', :attributes => { :href => "/myprofile/testinguser/themes/unset" }
104   - end
105   -
106   - should 'point back to control panel' do
107   - get :index, :profile => 'testinguser'
108   - assert_tag :tag => 'a', :attributes => { :href => '/myprofile/testinguser' }, :content => 'Back'
109   - end
110   -
111   - should 'display screen for creating new theme' do
112   - @request.expects(:xhr?).returns(true).at_least_once
113   - get :new, :profile => 'testinguser'
114   - assert_tag :tag => 'form', :attributes => { :action => '/myprofile/testinguser/themes/new', :method => /post/i }, :descendant => { :tag => 'input', :attributes => { :type => 'text', :name => 'name' } }
115   - end
116   -
117   - should 'create a new theme' do
118   - post :new, :profile => 'testinguser', :name => 'My theme'
119   -
120   - ok('theme should be created') do
121   - profile.themes.first.id == 'my-theme'
122   - end
123   - end
124   -
125   - should 'edit a theme' do
126   - theme = Theme.create('mytheme', :owner => profile)
127   - get :edit, :profile => 'testinguser', :id => 'mytheme'
128   -
129   - assert_equal theme, assigns(:theme)
130   - end
131   -
132   - should 'list CSS files in theme' do
133   - theme = Theme.create('mytheme', :owner => profile)
134   - theme.add_css('one.css')
135   - theme.add_css('two.css')
136   -
137   - get :edit, :profile => 'testinguser', :id => 'mytheme'
138   -
139   - %w[ one.css two.css ].each do |item|
140   - assert_includes assigns(:css_files), item
141   - assert_tag :tag => 'li', :descendant => { :tag => 'a', :content => item}
142   - end
143   - end
144   -
145   - should 'display dialog for creating new CSS' do
146   - theme = Theme.create('mytheme', :owner => profile)
147   - @request.stubs(:xhr?).returns(true)
148   - get :add_css, :profile => 'testinguser', :id => 'mytheme'
149   -
150   - assert_tag :tag => 'form', :attributes => { :action => '/myprofile/testinguser/themes/add_css/mytheme', :method => /post/i}
151   - assert_tag :tag => 'input', :attributes => { :name => 'css', :type => 'text' }
152   - assert_tag :tag => 'input', :attributes => { :type => 'submit' }
153   - end
154   -
155   - should 'be able to add new CSS to theme' do
156   - theme = Theme.create('mytheme', :owner => profile)
157   - post :add_css, :profile => 'testinguser', :id => 'mytheme', :css => 'test.css'
158   -
159   - assert_response :redirect
160   -
161   - reloaded_theme = Theme.find('mytheme')
162   - assert_includes reloaded_theme.css_files, 'test.css'
163   - end
164   -
165   - should 'load code from a given CSS file' do
166   - theme = Theme.create('mytheme', :owner => profile); theme.update_css('test.css', '/* sample code */')
167   - get :css_editor, :profile => 'testinguser', :id => 'mytheme', :css => 'test.css'
168   -
169   - assert_tag :tag => 'form', :attributes => { :action => '/myprofile/testinguser/themes/update_css/mytheme' }, :descendant => { :tag => 'textarea', :content => /\/\* sample code \*\// }
170   - end
171   -
172   - should 'be able to save CSS code' do
173   - theme = Theme.create('mytheme', :owner => profile); theme.update_css('test.css', '/* sample code */')
174   - get :css_editor, :profile => 'testinguser', :id => 'mytheme', :css => 'test.css'
175   -
176   - assert_tag :tag => 'form', :attributes => { :action => '/myprofile/testinguser/themes/update_css/mytheme' }, :descendant => { :tag => 'input', :attributes => { :type => 'submit' } }
177   - assert_tag :tag => 'form', :attributes => { :action => '/myprofile/testinguser/themes/update_css/mytheme' }, :descendant => { :tag => 'input', :attributes => { :type => 'hidden', :name => 'css', :value => 'test.css' } }
178   - end
179   -
180   - should 'update css code when saving' do
181   - theme = Theme.create('mytheme', :owner => profile); theme.update_css('test.css', '/* sample code */')
182   - post :update_css, :profile => 'testinguser', :id => 'mytheme', :css => 'test.css', :csscode => 'body { background: white; }'
183   - assert_equal 'body { background: white; }', theme.read_css('test.css')
184   - end
185   -
186   - should 'list image files in theme' do
187   - theme = Theme.create('mytheme', :owner => profile)
188   - theme.add_image('one.png', 'FAKE IMAGE DATA 1')
189   - theme.add_image('two.png', 'FAKE IMAGE DATA 2')
190   -
191   - get :edit, :profile => 'testinguser', :id => 'mytheme'
192   -
193   - assert_tag :tag => 'img', :attributes => { :src => '/user_themes/mytheme/images/one.png' }
194   - assert_tag :tag => 'img', :attributes => { :src => '/user_themes/mytheme/images/two.png' }
195   - end
196   -
197   - should 'display "add image" button' do
198   - theme = Theme.create('mytheme', :owner => profile)
199   - get :edit, :profile => 'testinguser', :id => 'mytheme'
200   -
201   - assert_tag :tag => 'a', :attributes => { :href => '/myprofile/testinguser/themes/add_image/mytheme' }
202   - end
203   -
204   - should 'display the "add image" dialog' do
205   - theme = Theme.create('mytheme', :owner => profile)
206   - @request.stubs(:xhr?).returns(true)
207   -
208   - get :add_image, :profile => 'testinguser', :id => 'mytheme'
209   - assert_tag :tag => 'form', :attributes => { :action => '/myprofile/testinguser/themes/add_image/mytheme', :method => /post/i, :enctype => 'multipart/form-data' }, :descendant => { :tag => 'input', :attributes => { :name => 'image', :type => 'file' } }
210   - end
211   -
212   - should 'be able to add new image to theme' do
213   - theme = Theme.create('mytheme', :owner => profile)
214   - @request.stubs(:xhr?).returns(false)
215   -
216   - post :add_image, :profile => 'testinguser', :id => 'mytheme', :image => fixture_file_upload('/files/rails.png', 'image/png', :binary)
217   - assert_redirected_to :action => "edit", :id => 'mytheme'
218   - assert theme.image_files.include?('rails.png')
219   - assert(system('diff', Rails.root.join('test', 'fixtures', 'files','rails.png').to_s, TMP_THEMES_DIR.join('mytheme/images/rails.png').to_s), 'should put the correct uploaded file in the right place')
220   - end
221   -
222   - should 'link to "test theme"' do
223   - Theme.create('one', :owner => profile)
224   - Theme.create('two', :owner => profile)
225   - get :index, :profile => 'testinguser'
226   -
227   - %w[ one two ].each do |item|
228   - assert_tag :tag => 'a', :attributes => { :href => '/myprofile/testinguser/themes/start_test/' + item }
229   - end
230   - end
231   -
232   - should 'start testing theme' do
233   - theme = Theme.create('theme-under-test', :owner => profile)
234   - post :start_test, :profile => 'testinguser', :id => 'theme-under-test'
235   -
236   - assert_equal 'theme-under-test', session[:theme]
237   - assert_redirected_to :controller => 'content_viewer', :profile => 'testinguser', :action => 'view_page'
238   - end
239   -
240   - should 'stop testing theme' do
241   - theme = Theme.create('theme-under-test', :owner => profile)
242   - post :stop_test, :profile => 'testinguser', :id => 'theme-under-test'
243   -
244   - assert_nil session[:theme]
245   - assert_redirected_to :action => 'index'
246   - end
247   -
248   - should 'list templates' do
249   - all = LayoutTemplate.all
250   -
251   - LayoutTemplate.expects(:all).returns(all)
252   - get :index, :profile => 'testinguser'
253   - assert_equal all, assigns(:layout_templates)
254   - end
255   -
256   - should 'display links to set template' do
257   - profile.update_attributes!({:layout_template => 'rightbar'}, :without_protection => true)
258   - t1 = LayoutTemplate.find('default')
259   - t2 = LayoutTemplate.find('leftbar')
260   - LayoutTemplate.expects(:all).returns([t1, t2])
261   -
262   - get :index, :profile => 'testinguser'
263   - assert_tag :tag => 'a', :attributes => { :href => "/myprofile/testinguser/themes/set_layout_template/default"}
264   - assert_tag :tag => 'a', :attributes => { :href => "/myprofile/testinguser/themes/set_layout_template/leftbar"}
265   - end
266   -
267   - should 'highlight current template' do
268   - profile.update_attributes!({:layout_template => 'default'}, :without_protection => true)
269   -
270   - t1 = LayoutTemplate.find('default')
271   - t2 = LayoutTemplate.find('leftbar')
272   - LayoutTemplate.expects(:all).returns([t1, t2])
273   -
274   - get :index, :profile => 'testinguser'
275   - assert_tag :attributes => { :class => 'template-opt list-opt selected' }
276   - assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/testinguser/themes/set_layout_template/default"}
277   - end
278   -
279   - should 'set template' do
280   - post :set_layout_template, :profile => 'testinguser', :id => 'leftbar'
281   - profile = Profile.find(@profile.id)
282   - assert_equal 'leftbar', profile.layout_template
283   - assert_redirected_to :action => 'index'
284   - end
285   -
286   - should 'set template even if the model is invalid' do
287   - @profile.sex = nil
288   - @profile.save!
289   - @profile.environment.custom_person_fields = { 'sex' => {'required' => 'true', 'active' => 'true'} }; @profile.environment.save!
290   -
291   - post :set_layout_template, :profile => 'testinguser', :id => 'leftbar'
292   - profile = Profile.find(@profile.id)
293   - assert_equal 'leftbar', profile.layout_template
294   - assert_redirected_to :action => 'index'
295   - end
296   -
297   - should 'not display "new theme" button when user themes are disabled' do
298   - env.disable('user_themes')
299   - env.save!
300   - get :index, :profile => 'testinguser'
301   - assert_no_tag :tag => 'a', :attributes => { :href => '/myprofile/testinguser/themes/new' }
302   - end
303   -
304   - should 'not display the "Select themes" section if there are no themes to choose from' do
305   - env.themes = []; env.save!
306   - Theme.stubs(:system_themes_dir).returns(TMP_THEMES_DIR) # an empty dir
307   - get :index, :profile => "testinguser"
308   - assert_no_tag :content => "Select theme"
309   - end
310   -
311   -end
test/unit/box_test.rb
... ... @@ -119,4 +119,25 @@ class BoxTest &lt; ActiveSupport::TestCase
119 119 assert blocks.include?('box-test_plugin-block')
120 120 end
121 121  
  122 + should 'list plugin block as allowed for the right holder' do
  123 + class SomePlugin < Noosfero::Plugin
  124 + def self.extra_blocks
  125 + { PluginBlock => {:position => 1, :type => [Person, Enterprise]} }
  126 + end
  127 + end
  128 + class PluginBlock < Block
  129 + def self.to_s; 'plugin-block'; end
  130 + end
  131 + Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([SomePlugin.new])
  132 +
  133 + blocks = Box.new(:position => 1, :owner => Person.new).acceptable_blocks
  134 + assert blocks.include?('box-test_plugin-block')
  135 +
  136 + blocks = Box.new(:position => 1, :owner => Enterprise.new).acceptable_blocks
  137 + assert blocks.include?('box-test_plugin-block')
  138 +
  139 + blocks = Box.new(:position => 1, :owner => Community.new).acceptable_blocks
  140 + assert !blocks.include?('box-test_plugin-block')
  141 + end
  142 +
122 143 end
... ...