Commit 8f42e790ed5d0191e62237e24a6e0a68514ff087

Authored by Leandro Nunes dos Santos
1 parent e22e8356

merging with stable

Showing 1039 changed files with 144546 additions and 114933 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 1039 files displayed.

@@ -13,16 +13,30 @@ Alessandro Palmeira + Caio Salgado <alessandro.palmeira@gmail.com> @@ -13,16 +13,30 @@ Alessandro Palmeira + Caio Salgado <alessandro.palmeira@gmail.com>
13 Alessandro Palmeira + Caio Salgado <caio.csalgado@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> 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> 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>
16 Alessandro Palmeira + Diego Araújo <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>
17 Alessandro Palmeira + Diego Araújo <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>
18 Alessandro Palmeira + Diego Araújo + Pedro Leal <diegoamc90@gmail.com> 28 Alessandro Palmeira + Diego Araújo + Pedro Leal <diegoamc90@gmail.com>
19 Alessandro Palmeira + Diego Araújo + Pedro Leal + João M. M. da Silva <diegoamc90@gmail.com> 29 Alessandro Palmeira + Diego Araújo + Pedro Leal + João M. M. da Silva <diegoamc90@gmail.com>
20 Alessandro Palmeira + Diego Araujo + Rafael Manzo <alessandro.palmeira@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>
21 Alessandro Palmeira + Jefferson Fernandes <alessandro.palmeira@gmail.com> 33 Alessandro Palmeira + Jefferson Fernandes <alessandro.palmeira@gmail.com>
22 Alessandro Palmeira + João M. M. da Silva <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>
23 Alessandro Palmeira + João M. M. da Silva + Renan Teruo <alessandro.palmeira@gmail.com> 36 Alessandro Palmeira + João M. M. da Silva + Renan Teruo <alessandro.palmeira@gmail.com>
24 Alessandro Palmeira + João M. M. Silva <alessandro.palmeira@gmail.com> 37 Alessandro Palmeira + João M. M. Silva <alessandro.palmeira@gmail.com>
25 Alessandro Palmeira + Paulo Meirelles <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>
26 Alessandro Palmeira + Rafael Manzo <alessandro.palmeira@gmail.com> 40 Alessandro Palmeira + Rafael Manzo <alessandro.palmeira@gmail.com>
27 Antonio Terceiro + Carlos Morais <terceiro@colivre.coop.br> 41 Antonio Terceiro + Carlos Morais <terceiro@colivre.coop.br>
28 Antonio Terceiro + Paulo Meirelles <terceiro@colivre.coop.br> 42 Antonio Terceiro + Paulo Meirelles <terceiro@colivre.coop.br>
@@ -32,6 +46,7 @@ Braulio Bhavamitra &lt;brauliobo@gmail.com&gt; @@ -32,6 +46,7 @@ Braulio Bhavamitra &lt;brauliobo@gmail.com&gt;
32 Bráulio Bhavamitra <brauliobo@gmail.com> 46 Bráulio Bhavamitra <brauliobo@gmail.com>
33 Caio <caio.csalgado@gmail.com> 47 Caio <caio.csalgado@gmail.com>
34 Caio + Diego + Pedro + João <caio.csalgado@gmail.com> 48 Caio + Diego + Pedro + João <caio.csalgado@gmail.com>
  49 +Caio Formiga <caio.formiga@gmail.com>
35 Caio, Pedro <caio.csalgado@gmail.com> 50 Caio, Pedro <caio.csalgado@gmail.com>
36 Caio Salgado + Alessandro Palmeira <caio.csalgado@gmail.com> 51 Caio Salgado + Alessandro Palmeira <caio.csalgado@gmail.com>
37 Caio Salgado <caio.csalgado@gmail.com> 52 Caio Salgado <caio.csalgado@gmail.com>
@@ -57,26 +72,42 @@ Carlos Morais + Diego Araújo &lt;diegoamc90@gmail.com&gt; @@ -57,26 +72,42 @@ Carlos Morais + Diego Araújo &lt;diegoamc90@gmail.com&gt;
57 Carlos Morais + Eduardo Morais <carlos88morais@gmail.com> 72 Carlos Morais + Eduardo Morais <carlos88morais@gmail.com>
58 Carlos Morais + Paulo Meirelles <carlos88morais@gmail.com> 73 Carlos Morais + Paulo Meirelles <carlos88morais@gmail.com>
59 Carlos Morais + Pedro Leal <carlos88morais@gmail.com> 74 Carlos Morais + Pedro Leal <carlos88morais@gmail.com>
  75 +Daniel Alves + Diego Araújo <danpaulalves@gmail.com>
  76 +Daniel Alves + Diego Araújo <diegoamc90@gmail.com>
  77 +Daniel Alves + Diego Araújo + Guilherme Rojas <danpaulalves@gmail.com>
  78 +Daniel Alves + Diego Araújo + Guilherme Rojas <diegoamc90@gmail.com>
  79 +Daniel Alves + Diego Araújo + Guilherme Rojas <guilhermehrojas@gmail.com>
  80 +Daniel Alves + Guilherme Rojas <danpaulalves@gmail.com>
  81 +Daniel Alves + Rafael Manzo <rr.manzo@gmail.com>
60 Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> 82 Daniela Soares Feitosa <danielafeitosa@colivre.coop.br>
61 Daniel Cunha <daniel@colivre.coop.br> 83 Daniel Cunha <daniel@colivre.coop.br>
62 diegoamc <diegoamc90@gmail.com> 84 diegoamc <diegoamc90@gmail.com>
63 Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com> 85 Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com>
  86 +Diego Araújo + Alessandro Palmeira + João M. M. da Silva <diegoamc90@gmail.com>
  87 +Diego Araújo + Alessandro Palmeira + Rafael Manzo <rr.manzo@gmail.com>
64 Diego Araujo + Caio Salgado <diegoamc90@gmail.com> 88 Diego Araujo + Caio Salgado <diegoamc90@gmail.com>
  89 +Diego Araújo + Daniel Alves + Rafael Manzo <rr.manzo@gmail.com>
65 Diego Araújo <diegoamc90@gmail.com> 90 Diego Araújo <diegoamc90@gmail.com>
  91 +Diego Araújo + Eduardo Morais + Paulo Meirelles <diegoamc90@gmail.com>
  92 +Diego Araújo + Guilherme Rojas <diegoamc90@gmail.com>
66 Diego Araújo + Jefferson Fernandes <diegoamc90@gmail.com> 93 Diego Araújo + Jefferson Fernandes <diegoamc90@gmail.com>
67 Diego Araujo + Jefferson Fernandes <jeffs.fernandes@gmail.com> 94 Diego Araujo + Jefferson Fernandes <jeffs.fernandes@gmail.com>
68 Diego Araújo + João Machini <diegoamc90@gmail.com> 95 Diego Araújo + João Machini <diegoamc90@gmail.com>
69 Diego Araújo + João Machini <digoamc90@gmail.com> 96 Diego Araújo + João Machini <digoamc90@gmail.com>
  97 +Diego Araújo + João M. M. da Silva + Alessandro Palmeira <jaodsilv@linux.ime.usp.br>
70 Diego Araújo + João M. M. da Silva <diegoamc90@gmail.com> 98 Diego Araújo + João M. M. da Silva <diegoamc90@gmail.com>
71 Diego Araújo + João M. M. da Silva + João Machini <diegoamc90@gmail.com> 99 Diego Araújo + João M. M. da Silva + João Machini <diegoamc90@gmail.com>
72 Diego Araújo + João M. M. da Silva + Pedro Leal <diegoamc90@gmail.com> 100 Diego Araújo + João M. M. da Silva + Pedro Leal <diegoamc90@gmail.com>
73 Diego Araújo + Paulo Meirelles <diegoamc90@gmail.com> 101 Diego Araújo + Paulo Meirelles <diegoamc90@gmail.com>
74 Diego Araújo + Pedro Leal <diegoamc90@gmail.com> 102 Diego Araújo + Pedro Leal <diegoamc90@gmail.com>
  103 +Diego Araujo + Rafael Manzo <diegoamc90@gmail.com>
75 Diego Araújo + Rafael Manzo <diegoamc90@gmail.com> 104 Diego Araújo + Rafael Manzo <diegoamc90@gmail.com>
76 Diego Araújo + Renan Teruo + Alessandro Palmeira <diegoamc90@gmail.com> 105 Diego Araújo + Renan Teruo + Alessandro Palmeira <diegoamc90@gmail.com>
77 Diego Araújo + Renan Teruo <diegoamc90@gmail.com> 106 Diego Araújo + Renan Teruo <diegoamc90@gmail.com>
  107 +Diego Araujo + Rodrigo Souto + Rafael Manzo <rr.manzo@gmail.com>
78 Diego + Jefferson <diegoamc90@gmail.com> 108 Diego + Jefferson <diegoamc90@gmail.com>
79 Diego Martinez <diegoamc90@gmail.com> 109 Diego Martinez <diegoamc90@gmail.com>
  110 +Diego Martinez <diego@diego-K55A.(none)>
80 Diego + Renan <renanteruoc@gmail.com> 111 Diego + Renan <renanteruoc@gmail.com>
81 Fernanda Lopes <nanda.listas+psl@gmail.com> 112 Fernanda Lopes <nanda.listas+psl@gmail.com>
82 Grazieno Pellegrino <grazieno@gmail.com> 113 Grazieno Pellegrino <grazieno@gmail.com>
@@ -89,6 +120,7 @@ João da Silva &lt;jaodsilv@linux.ime.usp.br&gt; @@ -89,6 +120,7 @@ João da Silva &lt;jaodsilv@linux.ime.usp.br&gt;
89 João Marco Maciel da Silva + Rafael Manzo + Renan Teruo <jaodsilv@linux.ime.usp.br> 120 João Marco Maciel da Silva + Rafael Manzo + Renan Teruo <jaodsilv@linux.ime.usp.br>
90 João M. M. da Silva + Alessandro Palmeira + Diego Araújo + Caio Salgado <jaodsilv@linux.ime.usp.br> 121 João M. M. da Silva + Alessandro Palmeira + Diego Araújo + Caio Salgado <jaodsilv@linux.ime.usp.br>
91 João M. M. da Silva + Alessandro Palmeira + Diego Araújo <jaodsilv@linux.ime.usp.br> 122 João M. M. da Silva + Alessandro Palmeira + Diego Araújo <jaodsilv@linux.ime.usp.br>
  123 +Joao M. M. da Silva + Alessandro Palmeira <jaodsilv@linux.ime.usp.br>
92 João M. M. da Silva + Alessandro Palmeira <jaodsilv@linux.ime.usp.br> 124 João M. M. da Silva + Alessandro Palmeira <jaodsilv@linux.ime.usp.br>
93 João M. M. da Silva + Alessandro Palmeira + João Machini <jaodsilv@linux.ime.usp.br> 125 João M. M. da Silva + Alessandro Palmeira + João Machini <jaodsilv@linux.ime.usp.br>
94 João M. M. da Silva + Caio Salgado + Alessandro Palmeira <jaodsilv@linux.ime.usp.br> 126 João M. M. da Silva + Caio Salgado + Alessandro Palmeira <jaodsilv@linux.ime.usp.br>
@@ -120,21 +152,30 @@ Larissa Reis &lt;reiss.larissa@gmail.com&gt; @@ -120,21 +152,30 @@ Larissa Reis &lt;reiss.larissa@gmail.com&gt;
120 Leandro Nunes dos Santos <leandronunes@gmail.com> 152 Leandro Nunes dos Santos <leandronunes@gmail.com>
121 Leandro Nunes dos Santos <leandro.santos@serpro.gov.br> 153 Leandro Nunes dos Santos <leandro.santos@serpro.gov.br>
122 LinguÁgil 2010 <linguagil.bahia@gmail.com> 154 LinguÁgil 2010 <linguagil.bahia@gmail.com>
  155 +Lucas Melo <lucas@colivre.coop.br>
123 Luis David Aguilar Carlos <ludwig9003@gmail.com> 156 Luis David Aguilar Carlos <ludwig9003@gmail.com>
124 Martín Olivera <molivera@solar.org.ar> 157 Martín Olivera <molivera@solar.org.ar>
125 Moises Machado <moises@colivre.coop.br> 158 Moises Machado <moises@colivre.coop.br>
126 Nanda Lopes <nanda.listas+psl@gmail.com> 159 Nanda Lopes <nanda.listas+psl@gmail.com>
  160 +Paulo Meirelles + Alessandro Palmeira + João M. M. da Silva <paulo@softwarelivre.org>
127 Paulo Meirelles + Alessandro Palmeira <paulo@softwarelivre.org> 161 Paulo Meirelles + Alessandro Palmeira <paulo@softwarelivre.org>
128 Paulo Meirelles + Carlos Morais <paulo@softwarelivre.org> 162 Paulo Meirelles + Carlos Morais <paulo@softwarelivre.org>
129 Paulo Meirelles + Diego Araújo <paulo@softwarelivre.org> 163 Paulo Meirelles + Diego Araújo <paulo@softwarelivre.org>
130 Paulo Meirelles + João M. M. da Silva <paulo@softwarelivre.org> 164 Paulo Meirelles + João M. M. da Silva <paulo@softwarelivre.org>
131 Paulo Meirelles <paulo@softwarelivre.org> 165 Paulo Meirelles <paulo@softwarelivre.org>
  166 +Paulo Meirelles + Rafael Manzo <paulo@softwarelivre.org>
132 Rafael Gomes <rafaelgomes@techfree.com.br> 167 Rafael Gomes <rafaelgomes@techfree.com.br>
  168 +Rafael Manzo + Alessandro Palmeira <rr.manzo@gmail.com>
  169 +Rafael Manzo + Daniel Alves <danpaulalves@gmail.com>
  170 +Rafael Manzo + Diego Araújo <rr.manzo@gmail.com>
133 Rafael Manzo + João M. M. Silva <rr.manzo@gmail.com> 171 Rafael Manzo + João M. M. Silva <rr.manzo@gmail.com>
  172 +Rafael Manzo + Paulo Meirelles <rr.manzo@gmail.com>
134 Rafael Martins <rmmartins@gmail.com> 173 Rafael Martins <rmmartins@gmail.com>
135 Rafael Reggiani Manzo + Caio Salgado + Jefferson Fernandes <rr.manzo@gmail.com> 174 Rafael Reggiani Manzo + Caio Salgado + Jefferson Fernandes <rr.manzo@gmail.com>
136 Rafael Reggiani Manzo + Diego Araujo <diegoamc90@gmail.com> 175 Rafael Reggiani Manzo + Diego Araujo <diegoamc90@gmail.com>
137 Rafael Reggiani Manzo + Diego Araujo <rr.manzo@gmail.com> 176 Rafael Reggiani Manzo + Diego Araujo <rr.manzo@gmail.com>
  177 +Rafael Reggiani Manzo + Diego Araújo <rr.manzo@gmail.com>
  178 +Rafael Reggiani Manzo + João M. M. da Silva <rr.manzo@gmail.com>
138 Rafael Reggiani Manzo <rr.manzo@gmail.com> 179 Rafael Reggiani Manzo <rr.manzo@gmail.com>
139 Raphaël Rousseau <raph@r4f.org> 180 Raphaël Rousseau <raph@r4f.org>
140 Raquel Lira <raquel.lira@gmail.com> 181 Raquel Lira <raquel.lira@gmail.com>
@@ -146,8 +187,11 @@ Renan Teruo + Paulo Meirelles &lt;renanteruoc@gmail.com&gt; @@ -146,8 +187,11 @@ Renan Teruo + Paulo Meirelles &lt;renanteruoc@gmail.com&gt;
146 Renan Teruo + Rafael Manzo <renanteruoc@gmail.com> 187 Renan Teruo + Rafael Manzo <renanteruoc@gmail.com>
147 Rodrigo Souto <rodrigo@colivre.coop.br> 188 Rodrigo Souto <rodrigo@colivre.coop.br>
148 Ronny Kursawe <kursawe.ronny@googlemail.com> 189 Ronny Kursawe <kursawe.ronny@googlemail.com>
  190 +root <root@debian.sdr.serpro>
149 Samuel R. C. Vale <srcvale@holoscopio.com> 191 Samuel R. C. Vale <srcvale@holoscopio.com>
150 Valessio Brito <valessio@gmail.com> 192 Valessio Brito <valessio@gmail.com>
  193 +vfcosta <vfcosta@gmail.com>
  194 +Visita <visita@debian.(none)>
151 Yann Lugrin <yann.lugrin@liquid-concept.ch> 195 Yann Lugrin <yann.lugrin@liquid-concept.ch>
152 196
153 Ideas, specifications and incentive 197 Ideas, specifications and incentive
1 -source :rubygems  
2 -gem 'cucumber', '0.4.0'  
3 -gem 'webrat', '0.5.1'  
4 -gem 'rspec', '1.2.9'  
5 -gem 'rspec-rails', '1.2.9'  
6 -gem 'Selenium', '>= 1.1.14'  
7 -gem 'selenium-client', '>= 1.2.17'  
8 -gem 'database_cleaner' 1 +source "https://rubygems.org"
  2 +
9 gem 'exception_notification', '1.0.20090728' 3 gem 'exception_notification', '1.0.20090728'
10 gem 'system_timer' 4 gem 'system_timer'
11 5
  6 +group :test do
  7 + gem 'rspec', '1.2.9'
  8 + gem 'rspec-rails', '1.2.9'
  9 +end
  10 +
  11 +group :cucumber do
  12 + gem 'rake', '0.8.7'
  13 + gem 'cucumber-rails', '0.3.2'
  14 + gem 'capybara', '1.1.1'
  15 + gem 'cucumber', '1.1.0'
  16 + gem 'database_cleaner'
  17 +end
  18 +
12 def program(name) 19 def program(name)
13 unless system("which #{name} > /dev/null") 20 unless system("which #{name} > /dev/null")
14 puts "W: Program #{name} is needed, but was not found in your PATH" 21 puts "W: Program #{name} is needed, but was not found in your PATH"
1 GEM 1 GEM
2 - remote: http://rubygems.org/ 2 + remote: https://rubygems.org/
3 specs: 3 specs:
4 - Selenium (1.1.14)  
5 - builder (3.0.0)  
6 - cucumber (0.4.0) 4 + builder (3.1.4)
  5 + capybara (1.1.1)
  6 + mime-types (>= 1.16)
  7 + nokogiri (>= 1.3.3)
  8 + rack (>= 1.0.0)
  9 + rack-test (>= 0.5.4)
  10 + selenium-webdriver (~> 2.0)
  11 + xpath (~> 0.1.4)
  12 + childprocess (0.3.6)
  13 + ffi (~> 1.0, >= 1.0.6)
  14 + cucumber (1.1.0)
7 builder (>= 2.1.2) 15 builder (>= 2.1.2)
8 diff-lcs (>= 1.1.2) 16 diff-lcs (>= 1.1.2)
9 - polyglot (>= 0.2.9)  
10 - term-ansicolor (>= 1.0.3)  
11 - treetop (>= 1.4.2)  
12 - database_cleaner (0.7.0) 17 + gherkin (~> 2.5.0)
  18 + json (>= 1.4.6)
  19 + term-ansicolor (>= 1.0.6)
  20 + cucumber-rails (0.3.2)
  21 + cucumber (>= 0.8.0)
  22 + database_cleaner (0.9.1)
13 diff-lcs (1.1.3) 23 diff-lcs (1.1.3)
14 exception_notification (1.0.20090728) 24 exception_notification (1.0.20090728)
15 - nokogiri (1.5.0)  
16 - polyglot (0.3.3)  
17 - rack (1.3.5) 25 + ffi (1.2.0)
  26 + gherkin (2.5.4)
  27 + json (>= 1.4.6)
  28 + json (1.7.5)
  29 + libwebsocket (0.1.6.1)
  30 + websocket
  31 + mime-types (1.19)
  32 + multi_json (1.3.7)
  33 + nokogiri (1.5.5)
  34 + rack (1.1.0)
  35 + rack-test (0.6.2)
  36 + rack (>= 1.0)
  37 + rake (0.8.7)
18 rspec (1.2.9) 38 rspec (1.2.9)
19 rspec-rails (1.2.9) 39 rspec-rails (1.2.9)
20 rack (>= 1.0.0) 40 rack (>= 1.0.0)
21 rspec (>= 1.2.9) 41 rspec (>= 1.2.9)
22 - selenium-client (1.2.18) 42 + rubyzip (0.9.9)
  43 + selenium-webdriver (2.26.0)
  44 + childprocess (>= 0.2.5)
  45 + libwebsocket (~> 0.1.3)
  46 + multi_json (~> 1.0)
  47 + rubyzip
23 system_timer (1.2.4) 48 system_timer (1.2.4)
24 term-ansicolor (1.0.7) 49 term-ansicolor (1.0.7)
25 - treetop (1.4.10)  
26 - polyglot  
27 - polyglot (>= 0.3.1)  
28 - webrat (0.5.1)  
29 - nokogiri (>= 1.2.0)  
30 - rack (>= 1.0) 50 + websocket (1.0.4)
  51 + xpath (0.1.4)
  52 + nokogiri (~> 1.3)
31 53
32 PLATFORMS 54 PLATFORMS
33 ruby 55 ruby
34 56
35 DEPENDENCIES 57 DEPENDENCIES
36 - Selenium (>= 1.1.14)  
37 - cucumber (= 0.4.0) 58 + capybara (= 1.1.1)
  59 + cucumber (= 1.1.0)
  60 + cucumber-rails (= 0.3.2)
38 database_cleaner 61 database_cleaner
39 exception_notification (= 1.0.20090728) 62 exception_notification (= 1.0.20090728)
  63 + rake (= 0.8.7)
40 rspec (= 1.2.9) 64 rspec (= 1.2.9)
41 rspec-rails (= 1.2.9) 65 rspec-rails (= 1.2.9)
42 - selenium-client (>= 1.2.17)  
43 system_timer 66 system_timer
44 - webrat (= 0.5.1)  
@@ -33,7 +33,7 @@ You need to install some packages Noosfero depends on. On Debian GNU/Linux or @@ -33,7 +33,7 @@ You need to install some packages Noosfero depends on. On Debian GNU/Linux or
33 Debian-based systems, all of these packages are available through the Debian 33 Debian-based systems, all of these packages are available through the Debian
34 archive. You can install them with the following command: 34 archive. You can install them with the following command:
35 35
36 - # apt-get install ruby rake po4a libgettext-ruby-util libgettext-ruby1.8 libsqlite3-ruby rcov librmagick-ruby libredcloth-ruby libwill-paginate-ruby iso-codes libfeedparser-ruby openjdk-6-jre libdaemons-ruby thin tango-icon-theme libhpricot-ruby 36 + # apt-get install ruby rake po4a libgettext-ruby-util libgettext-ruby1.8 libsqlite3-ruby rcov librmagick-ruby libredcloth-ruby libwill-paginate-ruby iso-codes libfeedparser-ruby libdaemons-ruby thin tango-icon-theme libhpricot-ruby
37 37
38 On other systems, they may or may not be available through your regular package 38 On other systems, they may or may not be available through your regular package
39 management system. Below are the links to their homepages. 39 management system. Below are the links to their homepages.
@@ -43,7 +43,6 @@ management system. Below are the links to their homepages. @@ -43,7 +43,6 @@ management system. Below are the links to their homepages.
43 * po4a: http://po4a.alioth.debian.org/ 43 * po4a: http://po4a.alioth.debian.org/
44 * Ruby-sqlite3: http://rubyforge.org/projects/sqlite-ruby 44 * Ruby-sqlite3: http://rubyforge.org/projects/sqlite-ruby
45 * rcov: http://eigenclass.org/hiki/rcov 45 * rcov: http://eigenclass.org/hiki/rcov
46 -* Solr: http://lucene.apache.org/solr  
47 * RMagick: http://rmagick.rubyforge.org/ 46 * RMagick: http://rmagick.rubyforge.org/
48 * RedCloth: http://redcloth.org/ 47 * RedCloth: http://redcloth.org/
49 * will_paginate: http://github.com/mislav/will_paginate/wikis 48 * will_paginate: http://github.com/mislav/will_paginate/wikis
@@ -111,9 +110,6 @@ $ tar -zxvf noosfero-0.39.0.tar.gz @@ -111,9 +110,6 @@ $ tar -zxvf noosfero-0.39.0.tar.gz
111 $ ln -s noosfero-0.39.0 current 110 $ ln -s noosfero-0.39.0 current
112 $ cd current 111 $ cd current
113 112
114 -Copy config/solr.yml.dist to config/solr.yml. You will  
115 -probably not need to customize this configuration, but have a look at it.  
116 -  
117 Create the thin configuration file: 113 Create the thin configuration file:
118 114
119 $ thin -C config/thin.yml -e production config 115 $ thin -C config/thin.yml -e production config
@@ -195,10 +191,6 @@ Compile the translations: @@ -195,10 +191,6 @@ Compile the translations:
195 191
196 $ RAILS_ENV=production rake noosfero:translations:compile 192 $ RAILS_ENV=production rake noosfero:translations:compile
197 193
198 -Run Solr:  
199 -  
200 -$ rake solr:start  
201 -  
202 Now we must create some initial data. To create your default environment 194 Now we must create some initial data. To create your default environment
203 (the first one), run the command below: 195 (the first one), run the command below:
204 196
@@ -6,15 +6,13 @@ To configure XMPP/BOSH in Noosfero you need: @@ -6,15 +6,13 @@ To configure XMPP/BOSH in Noosfero you need:
6 * SystemTimer - http://ph7spot.com/musings/system-timer 6 * SystemTimer - http://ph7spot.com/musings/system-timer
7 * Pidgin data files - http://www.pidgin.im/ 7 * Pidgin data files - http://www.pidgin.im/
8 8
9 -If you use Debian Lenny: 9 +If you use Debian Wheezy:
10 10
11 -# apt-get install librestclient-ruby (from backports)  
12 -# apt-get install pidgin-data  
13 -# apt-get install ruby1.8-dev 11 +# apt-get install librestclient-ruby pidgin-data ruby1.8-dev
14 # gem install SystemTimer 12 # gem install SystemTimer
15 13
16 -Take a look at util/chat directory to see samples of config file to configure a  
17 -XMPP/BOSH server with ejabberd, postgresql and apache2. 14 +The samples of config file to configure a XMPP/BOSH server with
  15 +ejabberd, postgresql and apache2 can be found at util/chat directory.
18 16
19 == XMPP/Chat Server Setup 17 == XMPP/Chat Server Setup
20 18
@@ -22,8 +20,7 @@ This is a step-by-step guide to get a XMPP service working, in a Debian system. @@ -22,8 +20,7 @@ This is a step-by-step guide to get a XMPP service working, in a Debian system.
22 20
23 1. Install the required packages 21 1. Install the required packages
24 22
25 -# apt-get -t lenny-backports install ejabberd  
26 -# apt-get install odbc-postgresql 23 +# apt-get install ejabberd odbc-postgresql
27 24
28 2. Ejabberd configuration 25 2. Ejabberd configuration
29 26
@@ -108,7 +105,7 @@ Unused modules can be disabled, for example: @@ -108,7 +105,7 @@ Unused modules can be disabled, for example:
108 * web_admin 105 * web_admin
109 * mod_pubsub 106 * mod_pubsub
110 * mod_irc 107 * mod_irc
111 - * mod_offine 108 + * mod_offline
112 * mod_admin_extra 109 * mod_admin_extra
113 * mod_register 110 * mod_register
114 111
@@ -132,7 +129,7 @@ This will create a new schema inside the noosfero database, called &#39;ejabberd&#39;. @@ -132,7 +129,7 @@ This will create a new schema inside the noosfero database, called &#39;ejabberd&#39;.
132 129
133 Note 'noosfero' user should have permission to create Postgresql schemas. Also, 130 Note 'noosfero' user should have permission to create Postgresql schemas. Also,
134 there should be at least one domain with 'is_default = true' in 'domains' 131 there should be at least one domain with 'is_default = true' in 'domains'
135 -table, otherwise people couldn't see your friends online. 132 +table, otherwise people won't be able to see their friends online.
136 133
137 134
138 4. ODBC configuration 135 4. ODBC configuration
@@ -168,9 +165,12 @@ Debug = 0 @@ -168,9 +165,12 @@ Debug = 0
168 CommLog = 1 165 CommLog = 1
169 UsageCount = 3 166 UsageCount = 3
170 167
171 - * testing all: 168 + 4.1 testing all:
172 169
173 -# isql 'PostgreSQLEjabberdNoosfero' DBUSER 170 +# isql 'PostgreSQLEjabberdNoosfero'
  171 +
  172 +If the configuration was done right, the message "Connected!"
  173 +will be displayed.
174 174
175 175
176 5. Enabling kernel polling and SMP in /etc/default/ejabberd 176 5. Enabling kernel polling and SMP in /etc/default/ejabberd
@@ -19,11 +19,12 @@ To prepare a release of noosfero, you must follow the steps below: @@ -19,11 +19,12 @@ To prepare a release of noosfero, you must follow the steps below:
19 19
20 * Finish all requirements and bugs assigned to the to-be-released version 20 * Finish all requirements and bugs assigned to the to-be-released version
21 * Make sure all tests pass 21 * Make sure all tests pass
22 -* Change the version in lib/noosfero.rb and debian/changelog to the  
23 - to-be-released version (e.g. 0.2.0, 0.3.1)  
24 * Write release notes at the version's wiki topic 22 * Write release notes at the version's wiki topic
25 -* Generate packages with <tt>rake noosfero:release</tt>. Your tarball and deb  
26 - pkg will be under the pkg/ directory. This task will create a git tag too. 23 +* Generate packages with <tt>rake noosfero:release[(stable|test)]</tt>. This task will:
  24 + * Update the version in lib/noosfero.rb and debian/changelog.
  25 + * Create the tarbal and the deb pkg under pkg/ directory.
  26 + * Create a git tag and push it.
  27 + * Upload the pkg to the configured repository (if configured) on ~/.dput.cf.
27 * Test that the tarball and deb package are ok 28 * Test that the tarball and deb package are ok
28 * Go to the version's wiki topic and edit it to reflect the new reality 29 * Go to the version's wiki topic and edit it to reflect the new reality
29 * Edit the topic WebPreferences and update DEBIAN_REPOSITORY_TOPICS setting 30 * Edit the topic WebPreferences and update DEBIAN_REPOSITORY_TOPICS setting
@@ -7,6 +7,10 @@ require &#39;rake&#39; @@ -7,6 +7,10 @@ require &#39;rake&#39;
7 require 'rake/testtask' 7 require 'rake/testtask'
8 require 'rake/rdoctask' 8 require 'rake/rdoctask'
9 9
10 -ACTS_AS_SEARCHABLE_ENABLED = false if Rake.application.top_level_tasks.detect{|t| t == 'db:data:minimal'}  
11 - 10 +# rails tasks
12 require 'tasks/rails' 11 require 'tasks/rails'
  12 +
  13 +# plugins' tasks
  14 +plugins_tasks = Dir.glob("config/plugins/*/{tasks,lib/tasks,rails/tasks}/**/*.rake").sort +
  15 + Dir.glob("config/plugins/*/vendor/plugins/*/{tasks,lib/tasks,rails/tasks}/**/*.rake").sort
  16 +plugins_tasks.each{ |ext| load ext }
app/controllers/admin/environment_design_controller.rb
@@ -3,7 +3,8 @@ class EnvironmentDesignController &lt; BoxOrganizerController @@ -3,7 +3,8 @@ class EnvironmentDesignController &lt; BoxOrganizerController
3 protect 'edit_environment_design', :environment 3 protect 'edit_environment_design', :environment
4 4
5 def available_blocks 5 def available_blocks
6 - @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock ] 6 + @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)
7 end 8 end
8 9
9 end 10 end
app/controllers/admin/region_validators_controller.rb
@@ -33,7 +33,7 @@ class RegionValidatorsController &lt; AdminController @@ -33,7 +33,7 @@ class RegionValidatorsController &lt; AdminController
33 def load_region_and_search 33 def load_region_and_search
34 @region = environment.regions.find(params[:id]) 34 @region = environment.regions.find(params[:id])
35 if params[:search] 35 if params[:search]
36 - @search = @region.search_possible_validators(params[:search]) 36 + @search = find_by_contents(:organizations, Organization, params[:search])[:results].reject {|item| @region.validator_ids.include?(item.id) }
37 end 37 end
38 end 38 end
39 39
app/controllers/admin/users_controller.rb
  1 +require 'csv'
  2 +
1 class UsersController < AdminController 3 class UsersController < AdminController
2 4
3 protect 'manage_environment_users', :environment 5 protect 'manage_environment_users', :environment
@@ -15,8 +17,16 @@ class UsersController &lt; AdminController @@ -15,8 +17,16 @@ class UsersController &lt; AdminController
15 :disposition => "attachment; filename=users.xml" 17 :disposition => "attachment; filename=users.xml"
16 end 18 end
17 format.csv do 19 format.csv do
18 - @users = User.find(:all, :conditions => {:environment_id => environment.id}, :include => [:person])  
19 - render :template => "users/index_csv.rhtml", :content_type => 'text/csv', :layout => false 20 + # using a direct connection with the dbms to optimize
  21 + command = User.send(:sanitize_sql, ["SELECT profiles.name, users.email FROM profiles
  22 + INNER JOIN users ON profiles.user_id=users.id
  23 + WHERE profiles.environment_id = ?", environment.id])
  24 + users = User.connection.execute(command)
  25 + csv_content = "name;email\n"
  26 + users.each { |u|
  27 + CSV.generate_row([u['name'], u['email']], 2, csv_content, fs=';')
  28 + }
  29 + render :text => csv_content, :content_type => 'text/csv', :layout => false
20 end 30 end
21 end 31 end
22 end 32 end
app/controllers/application_controller.rb
@@ -154,4 +154,18 @@ class ApplicationController &lt; ActionController::Base @@ -154,4 +154,18 @@ class ApplicationController &lt; ActionController::Base
154 end 154 end
155 end 155 end
156 156
  157 + def find_by_contents(asset, scope, query, paginate_options={:page => 1}, options={})
  158 + scope = scope.send(options[:filter]) if options[:filter]
  159 +
  160 + @plugins.first(:find_by_contents, asset, scope, query, paginate_options, options) ||
  161 + fallback_find_by_contents(asset, scope, query, paginate_options, options)
  162 + end
  163 +
  164 + private
  165 +
  166 + def fallback_find_by_contents(asset, scope, query, paginate_options, options)
  167 + return {:results => scope.paginate(paginate_options)} if query.blank?
  168 + {:results => scope.like_search(query).paginate(paginate_options)}
  169 + end
  170 +
157 end 171 end
app/controllers/box_organizer_controller.rb
@@ -68,8 +68,8 @@ class BoxOrganizerController &lt; ApplicationController @@ -68,8 +68,8 @@ class BoxOrganizerController &lt; ApplicationController
68 raise ArgumentError.new("Type %s is not allowed. Go away." % type) 68 raise ArgumentError.new("Type %s is not allowed. Go away." % type)
69 end 69 end
70 else 70 else
71 - @center_block_types = Box.acceptable_center_blocks & available_blocks  
72 - @side_block_types = Box.acceptable_side_blocks & available_blocks 71 + @center_block_types = (Box.acceptable_center_blocks & available_blocks) + plugins.dispatch(:extra_blocks, :type => boxes_holder.class, :position => 1)
  72 + @side_block_types = (Box.acceptable_side_blocks & available_blocks) + plugins.dispatch(:extra_blocks, :type => boxes_holder.class, :position => [2,3])
73 @boxes = boxes_holder.boxes 73 @boxes = boxes_holder.boxes
74 render :action => 'add_block', :layout => false 74 render :action => 'add_block', :layout => false
75 end 75 end
app/controllers/my_profile/cms_controller.rb
@@ -270,7 +270,7 @@ class CmsController &lt; MyProfileController @@ -270,7 +270,7 @@ class CmsController &lt; MyProfileController
270 270
271 def search 271 def search
272 query = params[:q] 272 query = params[:q]
273 - results = profile.files.published.find_by_contents(query)[:results] 273 + results = find_by_contents(:uploaded_files, profile.files.published, query)[:results]
274 render :text => article_list_to_json(results), :content_type => 'application/json' 274 render :text => article_list_to_json(results), :content_type => 'application/json'
275 end 275 end
276 276
app/controllers/my_profile/profile_design_controller.rb
@@ -7,17 +7,25 @@ class ProfileDesignController &lt; BoxOrganizerController @@ -7,17 +7,25 @@ class ProfileDesignController &lt; BoxOrganizerController
7 def available_blocks 7 def available_blocks
8 blocks = [ ArticleBlock, TagsBlock, RecentDocumentsBlock, ProfileInfoBlock, LinkListBlock, MyNetworkBlock, FeedReaderBlock, ProfileImageBlock, LocationBlock, SlideshowBlock, ProfileSearchBlock, HighlightsBlock ] 8 blocks = [ ArticleBlock, TagsBlock, RecentDocumentsBlock, ProfileInfoBlock, LinkListBlock, MyNetworkBlock, FeedReaderBlock, ProfileImageBlock, LocationBlock, SlideshowBlock, ProfileSearchBlock, HighlightsBlock ]
9 9
  10 + blocks += plugins.dispatch(:extra_blocks)
  11 +
10 # blocks exclusive for organizations 12 # blocks exclusive for organizations
11 if profile.has_members? 13 if profile.has_members?
12 blocks << MembersBlock 14 blocks << MembersBlock
13 end 15 end
14 16
15 - # blocks exclusive to person 17 + # blocks exclusive to people
16 if profile.person? 18 if profile.person?
17 blocks << FriendsBlock 19 blocks << FriendsBlock
18 blocks << FavoriteEnterprisesBlock 20 blocks << FavoriteEnterprisesBlock
19 blocks << CommunitiesBlock 21 blocks << CommunitiesBlock
20 blocks << EnterprisesBlock 22 blocks << EnterprisesBlock
  23 + blocks += plugins.dispatch(:extra_blocks, :type => Person)
  24 + end
  25 +
  26 + # blocks exclusive to communities
  27 + if profile.community?
  28 + blocks += plugins.dispatch(:extra_blocks, :type => Community)
21 end 29 end
22 30
23 # blocks exclusive for enterprises 31 # blocks exclusive for enterprises
@@ -26,6 +34,7 @@ class ProfileDesignController &lt; BoxOrganizerController @@ -26,6 +34,7 @@ class ProfileDesignController &lt; BoxOrganizerController
26 blocks << HighlightsBlock 34 blocks << HighlightsBlock
27 blocks << FeaturedProductsBlock 35 blocks << FeaturedProductsBlock
28 blocks << FansBlock 36 blocks << FansBlock
  37 + blocks += plugins.dispatch(:extra_blocks, :type => Enterprise)
29 end 38 end
30 39
31 # product block exclusive for enterprises in environments that permits it 40 # product block exclusive for enterprises in environments that permits it
@@ -33,7 +42,7 @@ class ProfileDesignController &lt; BoxOrganizerController @@ -33,7 +42,7 @@ class ProfileDesignController &lt; BoxOrganizerController
33 blocks << ProductsBlock 42 blocks << ProductsBlock
34 end 43 end
35 44
36 - # block exclusive to profile has blog 45 + # block exclusive to profiles that have blog
37 if profile.has_blog? 46 if profile.has_blog?
38 blocks << BlogArchivesBlock 47 blocks << BlogArchivesBlock
39 end 48 end
app/controllers/my_profile/profile_members_controller.rb
@@ -32,7 +32,6 @@ class ProfileMembersController &lt; MyProfileController @@ -32,7 +32,6 @@ class ProfileMembersController &lt; MyProfileController
32 32
33 def last_admin 33 def last_admin
34 @roles = [Profile::Roles.admin(environment.id)] 34 @roles = [Profile::Roles.admin(environment.id)]
35 - @pre_population = [].to_json  
36 end 35 end
37 36
38 def add_role 37 def add_role
app/controllers/public/account_controller.rb
@@ -71,10 +71,6 @@ class AccountController &lt; ApplicationController @@ -71,10 +71,6 @@ class AccountController &lt; ApplicationController
71 @block_bot = !!session[:may_be_a_bot] 71 @block_bot = !!session[:may_be_a_bot]
72 @invitation_code = params[:invitation_code] 72 @invitation_code = params[:invitation_code]
73 begin 73 begin
74 - if params[:user]  
75 - params[:user].delete(:password_confirmation_clear)  
76 - params[:user].delete(:password_clear)  
77 - end  
78 @user = User.new(params[:user]) 74 @user = User.new(params[:user])
79 @user.terms_of_use = environment.terms_of_use 75 @user.terms_of_use = environment.terms_of_use
80 @user.environment = environment 76 @user.environment = environment
app/controllers/public/catalog_controller.rb
@@ -7,7 +7,7 @@ class CatalogController &lt; PublicController @@ -7,7 +7,7 @@ class CatalogController &lt; PublicController
7 def index 7 def index
8 @category = params[:level] ? ProductCategory.find(params[:level]) : nil 8 @category = params[:level] ? ProductCategory.find(params[:level]) : nil
9 @products = @profile.products.from_category(@category).paginate(:order => 'available desc, highlighted desc, name asc', :per_page => 9, :page => params[:page]) 9 @products = @profile.products.from_category(@category).paginate(:order => 'available desc, highlighted desc, name asc', :per_page => 9, :page => params[:page])
10 - @categories = ProductCategory.on_level(params[:level]) 10 + @categories = ProductCategory.on_level(params[:level]).order(:name)
11 end 11 end
12 12
13 protected 13 protected
app/controllers/public/profile_search_controller.rb
@@ -11,7 +11,7 @@ class ProfileSearchController &lt; PublicController @@ -11,7 +11,7 @@ class ProfileSearchController &lt; PublicController
11 if params[:where] == 'environment' 11 if params[:where] == 'environment'
12 redirect_to :controller => 'search', :query => @q 12 redirect_to :controller => 'search', :query => @q
13 else 13 else
14 - @results = profile.articles.published.find_by_contents(@q, {:per_page => 10, :page => params[:page]})[:results] 14 + @results = find_by_contents(:articles, profile.articles.published, @q, {:per_page => 10, :page => params[:page]})[:results]
15 end 15 end
16 end 16 end
17 end 17 end
app/controllers/public/search_controller.rb
@@ -4,10 +4,11 @@ class SearchController &lt; PublicController @@ -4,10 +4,11 @@ class SearchController &lt; PublicController
4 include SearchHelper 4 include SearchHelper
5 include ActionView::Helpers::NumberHelper 5 include ActionView::Helpers::NumberHelper
6 6
7 - before_filter :redirect_asset_param, :except => [:facets_browse, :assets] 7 + before_filter :redirect_asset_param, :except => :assets
8 before_filter :load_category 8 before_filter :load_category
9 before_filter :load_search_assets 9 before_filter :load_search_assets
10 before_filter :load_query 10 before_filter :load_query
  11 + before_filter :load_filter
11 12
12 # Backwards compatibility with old URLs 13 # Backwards compatibility with old URLs
13 def redirect_asset_param 14 def redirect_asset_param
@@ -17,25 +18,51 @@ class SearchController &lt; PublicController @@ -17,25 +18,51 @@ class SearchController &lt; PublicController
17 18
18 no_design_blocks 19 no_design_blocks
19 20
20 - def facets_browse  
21 - @asset = params[:asset]  
22 - @asset_class = asset_class(@asset) 21 + def index
  22 + @searches = {}
  23 + @order = []
  24 + @names = {}
  25 + @results_only = true
23 26
24 - @facets_only = true  
25 - send(@asset) 27 + @enabled_searches.select { |key,description| @searching[key] }.each do |key, description|
  28 + load_query
  29 + @asset = key
  30 + send(key)
  31 + @order << key
  32 + @names[key] = getterm(description)
  33 + end
  34 + @asset = nil
26 35
27 - @facet = @asset_class.map_facets_for(environment).find { |facet| facet[:id] == params[:facet_id] }  
28 - raise 'Facet not found' if @facet.nil? 36 + if @searches.keys.size == 1
  37 + @asset = @searches.keys.first
  38 + render :action => @asset
  39 + end
  40 + end
29 41
30 - render :layout => false 42 + # view the summary of one category
  43 + def category_index
  44 + @searches = {}
  45 + @order = []
  46 + @names = {}
  47 + limit = MULTIPLE_SEARCH_LIMIT
  48 + [
  49 + [ :people, _('People'), :recent_people ],
  50 + [ :enterprises, _('Enterprises'), :recent_enterprises ],
  51 + [ :products, _('Products'), :recent_products ],
  52 + [ :events, _('Upcoming events'), :upcoming_events ],
  53 + [ :communities, _('Communities'), :recent_communities ],
  54 + [ :articles, _('Contents'), :recent_articles ]
  55 + ].each do |asset, name, filter|
  56 + @order << asset
  57 + @searches[asset]= {:results => @category.send(filter, limit)}
  58 + raise "No total_entries for: #{asset}" unless @searches[asset][:results].respond_to?(:total_entries)
  59 + @names[asset] = name
  60 + end
31 end 61 end
32 62
33 def articles 63 def articles
34 - if !@empty_query  
35 - full_text_search ['public:true']  
36 - else  
37 - @results[@asset] = @environment.articles.public.send(@filter).paginate(paginate_options)  
38 - end 64 + @scope = @environment.articles.public
  65 + full_text_search
39 end 66 end
40 67
41 def contents 68 def contents
@@ -43,49 +70,23 @@ class SearchController &lt; PublicController @@ -43,49 +70,23 @@ class SearchController &lt; PublicController
43 end 70 end
44 71
45 def people 72 def people
46 - if !@empty_query  
47 - full_text_search ['public:true']  
48 - else  
49 - @results[@asset] = visible_profiles(Person).send(@filter).paginate(paginate_options)  
50 - end 73 + @scope = visible_profiles(Person)
  74 + full_text_search
51 end 75 end
52 76
53 def products 77 def products
54 - public_filters = ['public:true', 'enabled:true']  
55 - if !@empty_query  
56 - full_text_search public_filters  
57 - else  
58 - @one_page = true  
59 - @geosearch = logged_in? && current_user.person.lat && current_user.person.lng  
60 -  
61 - extra_limit = LIST_SEARCH_LIMIT*5  
62 - sql_options = {:limit => LIST_SEARCH_LIMIT, :order => 'random()'}  
63 - if @geosearch  
64 - full_text_search public_filters, :sql_options => sql_options, :extra_limit => extra_limit,  
65 - :alternate_query => "{!boost b=recip(geodist(),#{"%e" % (1.to_f/DistBoost)},1,1)}",  
66 - :radius => DistFilt, :latitude => current_user.person.lat, :longitude => current_user.person.lng  
67 - else  
68 - full_text_search public_filters, :sql_options => sql_options, :extra_limit => extra_limit,  
69 - :boost_functions => ['recip(ms(NOW/HOUR,updated_at),1.3e-10,1,1)']  
70 - end  
71 - end 78 + @scope = @environment.products
  79 + full_text_search
72 end 80 end
73 81
74 def enterprises 82 def enterprises
75 - if !@empty_query  
76 - full_text_search ['public:true']  
77 - else  
78 - @filter_title = _('Enterprises from network')  
79 - @results[@asset] = visible_profiles(Enterprise, [{:products => :product_category}]).paginate(paginate_options)  
80 - end 83 + @scope = visible_profiles(Enterprise, [{:products => :product_category}])
  84 + full_text_search
81 end 85 end
82 86
83 def communities 87 def communities
84 - if !@empty_query  
85 - full_text_search ['public:true']  
86 - else  
87 - @results[@asset] = visible_profiles(Community).send(@filter).paginate(paginate_options)  
88 - end 88 + @scope = visible_profiles(Community)
  89 + full_text_search
89 end 90 end
90 91
91 def events 92 def events
@@ -93,7 +94,7 @@ class SearchController &lt; PublicController @@ -93,7 +94,7 @@ class SearchController &lt; PublicController
93 month = (params[:month] ? params[:month].to_i : Date.today.month) 94 month = (params[:month] ? params[:month].to_i : Date.today.month)
94 day = (params[:day] ? params[:day].to_i : Date.today.day) 95 day = (params[:day] ? params[:day].to_i : Date.today.day)
95 date = build_date(params[:year], params[:month], params[:day]) 96 date = build_date(params[:year], params[:month], params[:day])
96 - date_range = (date - 1.month)..(date + 1.month).at_end_of_month 97 + date_range = (date - 1.month).at_beginning_of_month..(date + 1.month).at_end_of_month
97 98
98 @selected_day = nil 99 @selected_day = nil
99 @events_of_the_day = [] 100 @events_of_the_day = []
@@ -104,64 +105,21 @@ class SearchController &lt; PublicController @@ -104,64 +105,21 @@ class SearchController &lt; PublicController
104 environment.events.by_day(@selected_day) 105 environment.events.by_day(@selected_day)
105 end 106 end
106 107
107 - if !@empty_query  
108 - full_text_search  
109 - else  
110 - @results[@asset] = date_range ? environment.events.by_range(date_range) : environment.events  
111 - end 108 + @scope = date_range && params[:action] == 'events' ? environment.events.by_range(date_range) : environment.events
  109 + full_text_search
112 110
113 - events = @results[@asset] 111 + events = @searches[@asset][:results]
114 @calendar = populate_calendar(date, events) 112 @calendar = populate_calendar(date, events)
115 @previous_calendar = populate_calendar(date - 1.month, events) 113 @previous_calendar = populate_calendar(date - 1.month, events)
116 @next_calendar = populate_calendar(date + 1.month, events) 114 @next_calendar = populate_calendar(date + 1.month, events)
117 end 115 end
118 116
119 - def index  
120 - @results = {}  
121 - @order = []  
122 - @names = {}  
123 - @results_only = true  
124 -  
125 - @enabled_searches.select { |key,description| @searching[key] }.each do |key, description|  
126 - load_query  
127 - @asset = key  
128 - send(key)  
129 - @order << key  
130 - @names[key] = getterm(description)  
131 - end  
132 - @asset = nil  
133 - @facets = {}  
134 -  
135 - render :action => @results.keys.first if @results.keys.size == 1  
136 - end  
137 -  
138 # keep old URLs workings 117 # keep old URLs workings
139 def assets 118 def assets
140 params[:action] = params[:asset].is_a?(Array) ? :index : params.delete(:asset) 119 params[:action] = params[:asset].is_a?(Array) ? :index : params.delete(:asset)
141 redirect_to params 120 redirect_to params
142 end 121 end
143 122
144 - # view the summary of one category  
145 - def category_index  
146 - @results = {}  
147 - @order = []  
148 - @names = {}  
149 - limit = MULTIPLE_SEARCH_LIMIT  
150 - [  
151 - [ :people, _('People'), :recent_people ],  
152 - [ :enterprises, _('Enterprises'), :recent_enterprises ],  
153 - [ :products, _('Products'), :recent_products ],  
154 - [ :events, _('Upcoming events'), :upcoming_events ],  
155 - [ :communities, _('Communities'), :recent_communities ],  
156 - [ :articles, _('Contents'), :recent_articles ]  
157 - ].each do |asset, name, filter|  
158 - @order << asset  
159 - @results[asset] = @category.send(filter, limit)  
160 - raise "No total_entries for: #{asset}" unless @results[asset].respond_to?(:total_entries)  
161 - @names[asset] = name  
162 - end  
163 - end  
164 -  
165 def tags 123 def tags
166 @tags_cache_key = "tags_env_#{environment.id.to_s}" 124 @tags_cache_key = "tags_env_#{environment.id.to_s}"
167 if is_cache_expired?(@tags_cache_key) 125 if is_cache_expired?(@tags_cache_key)
@@ -173,7 +131,7 @@ class SearchController &lt; PublicController @@ -173,7 +131,7 @@ class SearchController &lt; PublicController
173 @tag = params[:tag] 131 @tag = params[:tag]
174 @tag_cache_key = "tag_#{CGI.escape(@tag.to_s)}_env_#{environment.id.to_s}_page_#{params[:npage]}" 132 @tag_cache_key = "tag_#{CGI.escape(@tag.to_s)}_env_#{environment.id.to_s}_page_#{params[:npage]}"
175 if is_cache_expired?(@tag_cache_key) 133 if is_cache_expired?(@tag_cache_key)
176 - @results[@asset] = environment.articles.find_tagged_with(@tag).paginate(paginate_options) 134 + @searches[@asset] = {:results => environment.articles.find_tagged_with(@tag).paginate(paginate_options)}
177 end 135 end
178 end 136 end
179 137
@@ -187,11 +145,9 @@ class SearchController &lt; PublicController @@ -187,11 +145,9 @@ class SearchController &lt; PublicController
187 protected 145 protected
188 146
189 def load_query 147 def load_query
190 - @asset = params[:action].to_sym 148 + @asset = (params[:asset] || params[:action]).to_sym
191 @order ||= [@asset] 149 @order ||= [@asset]
192 - @results ||= {}  
193 - @filter = filter  
194 - @filter_title = filter_description(@asset, @filter) 150 + @searches ||= {}
195 151
196 @query = params[:query] || '' 152 @query = params[:query] || ''
197 @empty_query = @category.nil? && @query.blank? 153 @empty_query = @category.nil? && @query.blank?
@@ -211,42 +167,13 @@ class SearchController &lt; PublicController @@ -211,42 +167,13 @@ class SearchController &lt; PublicController
211 end 167 end
212 end 168 end
213 169
214 - FILTERS = %w(  
215 - more_recent  
216 - more_active  
217 - more_popular  
218 - more_comments  
219 - )  
220 - def filter  
221 - if FILTERS.include?(params[:filter])  
222 - params[:filter]  
223 - else  
224 - 'more_recent'  
225 - end  
226 - end  
227 -  
228 - def filter_description(asset, filter)  
229 - {  
230 - 'articles_more_recent' => _('More recent contents from network'),  
231 - 'articles_more_popular' => _('More viewed contents from network'),  
232 - 'articles_more_comments' => _('Most commented contents from network'),  
233 - 'people_more_recent' => _('More recent people from network'),  
234 - 'people_more_active' => _('More active people from network'),  
235 - 'people_more_popular' => _('More popular people from network'),  
236 - 'communities_more_recent' => _('More recent communities from network'),  
237 - 'communities_more_active' => _('More active communities from network'),  
238 - 'communities_more_popular' => _('More popular communities from network'),  
239 - 'products_more_recent' => _('Highlights'),  
240 - }[asset.to_s + '_' + filter]  
241 - end  
242 -  
243 def load_search_assets 170 def load_search_assets
244 - if Searches.keys.include?(params[:action].to_sym) and environment.enabled?("disable_asset_#{params[:action]}") 171 + if SEARCHES.keys.include?(params[:action].to_sym) && environment.enabled?("disable_asset_#{params[:action]}")
245 render_not_found 172 render_not_found
246 return 173 return
247 end 174 end
248 175
249 - @enabled_searches = Searches.select {|key, name| environment.disabled?("disable_asset_#{params[:action]}") } 176 + @enabled_searches = SEARCHES.select {|key, name| environment.disabled?("disable_asset_#{key}") }
250 @searching = {} 177 @searching = {}
251 @titles = {} 178 @titles = {}
252 @enabled_searches.each do |key, name| 179 @enabled_searches.each do |key, name|
@@ -256,13 +183,19 @@ class SearchController &lt; PublicController @@ -256,13 +183,19 @@ class SearchController &lt; PublicController
256 @names = @titles if @names.nil? 183 @names = @titles if @names.nil?
257 end 184 end
258 185
  186 + def load_filter
  187 + @filter = 'more_recent'
  188 + if SEARCHES.keys.include?(@asset.to_sym)
  189 + available_filters = asset_class(@asset)::SEARCH_FILTERS
  190 + @filter = params[:filter] if available_filters.include?(params[:filter])
  191 + end
  192 + end
  193 +
259 def limit 194 def limit
260 - if map_search? 195 + if map_search?(@searches)
261 MAP_SEARCH_LIMIT 196 MAP_SEARCH_LIMIT
262 elsif !multiple_search? 197 elsif !multiple_search?
263 - if [:people, :communities].include? @asset  
264 - BLOCKS_SEARCH_LIMIT  
265 - elsif @asset == :enterprises and @empty_query 198 + if [:people, :communities, :enterprises].include? @asset
266 BLOCKS_SEARCH_LIMIT 199 BLOCKS_SEARCH_LIMIT
267 else 200 else
268 LIST_SEARCH_LIMIT 201 LIST_SEARCH_LIMIT
@@ -273,41 +206,12 @@ class SearchController &lt; PublicController @@ -273,41 +206,12 @@ class SearchController &lt; PublicController
273 end 206 end
274 207
275 def paginate_options(page = params[:page]) 208 def paginate_options(page = params[:page])
276 - page = 1 if multiple_search? or params[:display] == 'map' 209 + page = 1 if multiple_search?(@searches) || params[:display] == 'map'
277 { :per_page => limit, :page => page } 210 { :per_page => limit, :page => page }
278 end 211 end
279 212
280 - def full_text_search(filters = [], options = {})  
281 - paginate_options = paginate_options(params[:page])  
282 - asset_class = asset_class(@asset)  
283 - solr_options = options  
284 - pg_options = paginate_options(params[:page])  
285 -  
286 - if !multiple_search?  
287 - if !@results_only and asset_class.respond_to? :facets  
288 - solr_options.merge! asset_class.facets_find_options(params[:facet])  
289 - solr_options[:all_facets] = true  
290 - end  
291 - solr_options[:filter_queries] ||= []  
292 - solr_options[:filter_queries] += filters  
293 - solr_options[:filter_queries] << "environment_id:#{environment.id}"  
294 - solr_options[:filter_queries] << asset_class.facet_category_query.call(@category) if @category  
295 -  
296 - solr_options[:boost_functions] ||= []  
297 - params[:order_by] = nil if params[:order_by] == 'none'  
298 - if params[:order_by]  
299 - order = SortOptions[@asset][params[:order_by].to_sym]  
300 - raise "Unknown order by" if order.nil?  
301 - order[:solr_opts].each do |opt, value|  
302 - solr_options[opt] = value.is_a?(Proc) ? instance_eval(&value) : value  
303 - end  
304 - end  
305 - end  
306 -  
307 - ret = asset_class.find_by_contents(@query, paginate_options, solr_options)  
308 - @results[@asset] = ret[:results]  
309 - @facets = ret[:facets]  
310 - @all_facets = ret[:all_facets] 213 + def full_text_search
  214 + @searches[@asset] = find_by_contents(@asset, @scope, @query, paginate_options, {:category => @category, :filter => @filter})
311 end 215 end
312 216
313 private 217 private
app/helpers/application_helper.rb
@@ -30,6 +30,12 @@ module ApplicationHelper @@ -30,6 +30,12 @@ module ApplicationHelper
30 30
31 include AccountHelper 31 include AccountHelper
32 32
  33 + include BlogHelper
  34 +
  35 + include ContentViewerHelper
  36 +
  37 + include LayoutHelper
  38 +
33 def locale 39 def locale
34 (@page && !@page.language.blank?) ? @page.language : FastGettext.locale 40 (@page && !@page.language.blank?) ? @page.language : FastGettext.locale
35 end 41 end
@@ -260,14 +266,17 @@ module ApplicationHelper @@ -260,14 +266,17 @@ module ApplicationHelper
260 end 266 end
261 267
262 def button_bar(options = {}, &block) 268 def button_bar(options = {}, &block)
263 - concat(content_tag('div', capture(&block) + tag('br', :style => 'clear: left;'), { :class => 'button-bar' }.merge(options))) 269 + options[:class].nil? ?
  270 + options[:class]='button-bar' :
  271 + options[:class]+=' button-bar'
  272 + concat(content_tag('div', capture(&block) + tag('br', :style => 'clear: left;'), options))
264 end 273 end
265 274
266 VIEW_EXTENSIONS = %w[.rhtml .html.erb] 275 VIEW_EXTENSIONS = %w[.rhtml .html.erb]
267 276
268 - def partial_for_class_in_view_path(klass, view_path, suffix = nil) 277 + def partial_for_class_in_view_path(klass, view_path, prefix = nil, suffix = nil)
269 return nil if klass.nil? 278 return nil if klass.nil?
270 - name = [klass.name.underscore, suffix].compact.map(&:to_s).join('_') 279 + name = [prefix, klass.name.underscore, suffix].compact.map(&:to_s).join('_')
271 280
272 search_name = String.new(name) 281 search_name = String.new(name)
273 if search_name.include?("/") 282 if search_name.include?("/")
@@ -282,14 +291,14 @@ module ApplicationHelper @@ -282,14 +291,14 @@ module ApplicationHelper
282 return name if File.exists?(File.join(path)) 291 return name if File.exists?(File.join(path))
283 end 292 end
284 293
285 - partial_for_class_in_view_path(klass.superclass, view_path, suffix) 294 + partial_for_class_in_view_path(klass.superclass, view_path, prefix, suffix)
286 end 295 end
287 296
288 - def partial_for_class(klass, suffix=nil) 297 + def partial_for_class(klass, prefix=nil, suffix=nil)
289 raise ArgumentError, 'No partial for object. Is there a partial for any class in the inheritance hierarchy?' if klass.nil? 298 raise ArgumentError, 'No partial for object. Is there a partial for any class in the inheritance hierarchy?' if klass.nil?
290 name = klass.name.underscore 299 name = klass.name.underscore
291 @controller.view_paths.each do |view_path| 300 @controller.view_paths.each do |view_path|
292 - partial = partial_for_class_in_view_path(klass, view_path, suffix) 301 + partial = partial_for_class_in_view_path(klass, view_path, prefix, suffix)
293 return partial if partial 302 return partial if partial
294 end 303 end
295 304
@@ -352,10 +361,6 @@ module ApplicationHelper @@ -352,10 +361,6 @@ module ApplicationHelper
352 end 361 end
353 end 362 end
354 363
355 - def theme_stylesheet_path  
356 - theme_path + '/style.css'  
357 - end  
358 -  
359 def current_theme 364 def current_theme
360 @current_theme ||= 365 @current_theme ||=
361 begin 366 begin
@@ -493,23 +498,24 @@ module ApplicationHelper @@ -493,23 +498,24 @@ module ApplicationHelper
493 498
494 def profile_cat_icons( profile ) 499 def profile_cat_icons( profile )
495 if profile.class == Enterprise 500 if profile.class == Enterprise
496 - icons =  
497 - profile.product_categories.map{ |c| c.size > 1 ? c[1] : nil }.  
498 - compact.uniq.map{ |c|  
499 - cat_name = c.gsub( /[-_\s,.;'"]+/, '_' )  
500 - cat_icon = "/images/icons-cat/#{cat_name}.png"  
501 - if ! File.exists? RAILS_ROOT.to_s() + '/public/' + cat_icon  
502 - cat_icon = '/images/icons-cat/undefined.png'  
503 - end  
504 - content_tag 'span',  
505 - content_tag( 'span', c ),  
506 - :title => c,  
507 - :class => 'product-cat-icon cat_icon_' + cat_name,  
508 - :style => "background-image:url(#{cat_icon})"  
509 - }.join "\n"  
510 - content_tag 'div',  
511 - content_tag( 'span', _('Principal Product Categories'), :class => 'header' ) +"\n"+ icons,  
512 - :class => 'product-category-icons' 501 + icons = profile.product_categories.map{ |c| c.size > 1 ? c[1] : nil }.
  502 + compact.uniq.map do |c|
  503 + cat_name = c.gsub( /[-_\s,.;'"]+/, '_' )
  504 + cat_icon = "/images/icons-cat/#{cat_name}.png"
  505 + if ! File.exists? RAILS_ROOT.to_s() + '/public/' + cat_icon
  506 + cat_icon = '/images/icons-cat/undefined.png'
  507 + end
  508 + content_tag('span',
  509 + content_tag( 'span', c ),
  510 + :title => c,
  511 + :class => 'product-cat-icon cat_icon_' + cat_name,
  512 + :style => "background-image:url(#{cat_icon})"
  513 + )
  514 + end.join("\n").html_safe
  515 + content_tag('div',
  516 + content_tag( 'span', _('Principal Product Categories'), :class => 'header' ) +"\n"+ icons,
  517 + :class => 'product-category-icons'
  518 + )
513 else 519 else
514 '' 520 ''
515 end 521 end
@@ -633,10 +639,10 @@ module ApplicationHelper @@ -633,10 +639,10 @@ module ApplicationHelper
633 # FIXME 639 # FIXME
634 ([toplevel] + toplevel.children_for_menu).each do |cat| 640 ([toplevel] + toplevel.children_for_menu).each do |cat|
635 if cat.top_level? 641 if cat.top_level?
636 - result << '<div class="categorie_box">' 642 + result << '<div class="categorie_box">'.html_safe
637 result << icon_button( :down, _('open'), '#', :onclick => 'open_close_cat(this); return false' ) 643 result << icon_button( :down, _('open'), '#', :onclick => 'open_close_cat(this); return false' )
638 result << content_tag('h5', toplevel.name) 644 result << content_tag('h5', toplevel.name)
639 - result << '<div style="display:none"><ul class="categories">' 645 + result << '<div style="display:none"><ul class="categories">'.html_safe
640 else 646 else
641 checkbox_id = "#{object_name}_#{cat.full_name.downcase.gsub(/\s+|\//, '_')}" 647 checkbox_id = "#{object_name}_#{cat.full_name.downcase.gsub(/\s+|\//, '_')}"
642 result << content_tag('li', labelled_check_box( 648 result << content_tag('li', labelled_check_box(
@@ -647,7 +653,7 @@ module ApplicationHelper @@ -647,7 +653,7 @@ module ApplicationHelper
647 :class => ( object.category_ids.include?(cat.id) ? 'cat_checked' : '' ) ) + "\n" 653 :class => ( object.category_ids.include?(cat.id) ? 'cat_checked' : '' ) ) + "\n"
648 end 654 end
649 end 655 end
650 - result << '</ul></div></div>' 656 + result << '</ul></div></div>'.html_safe
651 end 657 end
652 658
653 content_tag('div', result) 659 content_tag('div', result)
@@ -787,10 +793,10 @@ module ApplicationHelper @@ -787,10 +793,10 @@ module ApplicationHelper
787 :class => 'lineitem' + (line_item+=1).to_s() ) +"\n" 793 :class => 'lineitem' + (line_item+=1).to_s() ) +"\n"
788 if line_item == line_size 794 if line_item == line_size
789 line_item = 0 795 line_item = 0
790 - html += "<br />\n" 796 + html += "<br />\n".html_safe
791 end 797 end
792 } 798 }
793 - html += "<br />\n" if line_size == 0 || ( values.size % line_size ) > 0 799 + html += "<br />\n".html_safe if line_size == 0 || ( values.size % line_size ) > 0
794 column = object.class.columns_hash[method.to_s] 800 column = object.class.columns_hash[method.to_s]
795 text = 801 text =
796 ( column ? 802 ( column ?
@@ -873,14 +879,6 @@ module ApplicationHelper @@ -873,14 +879,6 @@ module ApplicationHelper
873 content_tag('div', labelled_check_box(_('Public'), 'profile_data[fields_privacy]['+name+']', 'public', profile.public_fields.include?(name)), :class => 'field-privacy-selector') 879 content_tag('div', labelled_check_box(_('Public'), 'profile_data[fields_privacy]['+name+']', 'public', profile.public_fields.include?(name)), :class => 'field-privacy-selector')
874 end 880 end
875 881
876 - def template_stylesheet_path  
877 - if profile.nil?  
878 - "/designs/templates/#{environment.layout_template}/stylesheets/style.css"  
879 - else  
880 - "/designs/templates/#{profile.layout_template}/stylesheets/style.css"  
881 - end  
882 - end  
883 -  
884 def login_url 882 def login_url
885 options = Noosfero.url_options.merge({ :controller => 'account', :action => 'login' }) 883 options = Noosfero.url_options.merge({ :controller => 'account', :action => 'login' })
886 url_for(options) 884 url_for(options)
@@ -919,18 +917,6 @@ module ApplicationHelper @@ -919,18 +917,6 @@ module ApplicationHelper
919 end 917 end
920 end 918 end
921 919
922 - def icon_theme_stylesheet_path  
923 - icon_themes = []  
924 - theme_icon_themes = theme_option(:icon_theme) || []  
925 - for icon_theme in theme_icon_themes do  
926 - theme_path = "/designs/icons/#{icon_theme}/style.css"  
927 - if File.exists?(File.join(RAILS_ROOT, 'public', theme_path))  
928 - icon_themes << theme_path  
929 - end  
930 - end  
931 - icon_themes  
932 - end  
933 -  
934 def page_title 920 def page_title
935 (@page ? @page.title + ' - ' : '') + 921 (@page ? @page.title + ' - ' : '') +
936 (profile ? profile.short_name + ' - ' : '') + 922 (profile ? profile.short_name + ' - ' : '') +
@@ -942,42 +928,13 @@ module ApplicationHelper @@ -942,42 +928,13 @@ module ApplicationHelper
942 (@category ? " - #{@category.full_name}" : '') 928 (@category ? " - #{@category.full_name}" : '')
943 end 929 end
944 930
945 - def noosfero_javascript  
946 - render :file => 'layouts/_javascript'  
947 - end  
948 -  
949 - def noosfero_stylesheets  
950 - [  
951 - 'application',  
952 - 'search',  
953 - 'thickbox',  
954 - 'lightbox',  
955 - 'colorpicker',  
956 - 'colorbox',  
957 - pngfix_stylesheet_path,  
958 - ] +  
959 - tokeninput_stylesheets  
960 - end  
961 -  
962 # DEPRECATED. Do not use this· 931 # DEPRECATED. Do not use this·
963 def import_controller_stylesheets(options = {}) 932 def import_controller_stylesheets(options = {})
964 stylesheet_import( "controller_"+ @controller.controller_name(), options ) 933 stylesheet_import( "controller_"+ @controller.controller_name(), options )
965 end 934 end
966 935
967 - def pngfix_stylesheet_path  
968 - 'iepngfix/iepngfix.css'  
969 - end  
970 -  
971 - def tokeninput_stylesheets  
972 - ['token-input', 'token-input-facebook', 'token-input-mac', 'token-input-facet']  
973 - end  
974 -  
975 - def noosfero_layout_features  
976 - render :file => 'shared/noosfero_layout_features'  
977 - end  
978 -  
979 def link_to_email(email) 936 def link_to_email(email)
980 - javascript_tag('var array = ' + email.split('@').to_json + '; document.write("<a href=\'mailto:" + array.join("@") + "\'>" + array.join("@") + "</a>")') 937 + javascript_tag('var array = ' + email.split('@').to_json + '; document.write("<a href=\'mailto:" + array.join("@") + "\'>" + array.join("@") + "</a>")'.html_safe)
981 end 938 end
982 939
983 def stylesheet(*args) 940 def stylesheet(*args)
@@ -987,13 +944,43 @@ module ApplicationHelper @@ -987,13 +944,43 @@ module ApplicationHelper
987 def article_to_html(article, options = {}) 944 def article_to_html(article, options = {})
988 options.merge!(:page => params[:npage]) 945 options.merge!(:page => params[:npage])
989 content = article.to_html(options) 946 content = article.to_html(options)
990 - content = content.kind_of?(Proc) ? self.instance_eval(&content) : content 947 + content = content.kind_of?(Proc) ? self.instance_eval(&content).html_safe : content.html_safe
991 @plugins && @plugins.each do |plugin| 948 @plugins && @plugins.each do |plugin|
992 content = plugin.parse_content(content) 949 content = plugin.parse_content(content)
993 end 950 end
994 content 951 content
995 end 952 end
996 953
  954 + # Please, use link_to by default!
  955 + # This method was created to work around to inexplicable
  956 + # chain of problems when display_short_format was called
  957 + # from Article model for an ArticleBlock.
  958 + def reference_to_article(text, article, anchor=nil)
  959 + if article.profile.domains.empty?
  960 + href = "/#{article.url[:profile]}/"
  961 + else
  962 + href = "http://#{article.profile.domains.first.name}/"
  963 + end
  964 + href += article.url[:page].join('/')
  965 + href += '#' + anchor if anchor
  966 + content_tag('a', text, :href => href)
  967 + end
  968 +
  969 + def display_short_format(article, options={})
  970 + options[:comments_link] ||= true
  971 + options[:read_more_link] ||= true
  972 + html = content_tag('div',
  973 + article.lead +
  974 + content_tag('div',
  975 + (options[:comments_link] ? link_to_comments(article) : '') +
  976 + (options[:read_more_link] ? reference_to_article( _('Read more'), article) : ''),
  977 + :class => 'read-more'
  978 + ),
  979 + :class => 'short-post'
  980 + )
  981 + html
  982 + end
  983 +
997 def colorpicker_field(object_name, method, options = {}) 984 def colorpicker_field(object_name, method, options = {})
998 text_field(object_name, method, options.merge(:class => 'colorpicker_field')) 985 text_field(object_name, method, options.merge(:class => 'colorpicker_field'))
999 end 986 end
@@ -1003,7 +990,7 @@ module ApplicationHelper @@ -1003,7 +990,7 @@ module ApplicationHelper
1003 end 990 end
1004 991
1005 def ui_icon(icon_class, extra_class = '') 992 def ui_icon(icon_class, extra_class = '')
1006 - "<span class='ui-icon #{icon_class} #{extra_class}' style='float:left; margin-right:7px;'></span>" 993 + "<span class='ui-icon #{icon_class} #{extra_class}' style='float:left; margin-right:7px;'></span>".html_safe
1007 end 994 end
1008 995
1009 def ui_button(label, url, html_options = {}) 996 def ui_button(label, url, html_options = {})
@@ -1018,10 +1005,6 @@ module ApplicationHelper @@ -1018,10 +1005,6 @@ module ApplicationHelper
1018 theme_option(:jquery_theme) || 'smoothness_mod' 1005 theme_option(:jquery_theme) || 'smoothness_mod'
1019 end 1006 end
1020 1007
1021 - def jquery_ui_theme_stylesheet_path  
1022 - 'jquery.ui/' + jquery_theme + '/jquery-ui-1.8.2.custom'  
1023 - end  
1024 -  
1025 def ui_error(message) 1008 def ui_error(message)
1026 content_tag('div', ui_icon('ui-icon-alert') + message, :class => 'alert fg-state-error ui-state-error') 1009 content_tag('div', ui_icon('ui-icon-alert') + message, :class => 'alert fg-state-error ui-state-error')
1027 end 1010 end
@@ -1035,13 +1018,13 @@ module ApplicationHelper @@ -1035,13 +1018,13 @@ module ApplicationHelper
1035 end 1018 end
1036 1019
1037 def collapsed_item_icon 1020 def collapsed_item_icon
1038 - "<span class='ui-icon ui-icon-circlesmall-plus' style='float:left;'></span>" 1021 + "<span class='ui-icon ui-icon-circlesmall-plus' style='float:left;'></span>".html_safe
1039 end 1022 end
1040 def expanded_item_icon 1023 def expanded_item_icon
1041 - "<span class='ui-icon ui-icon-circlesmall-minus' style='float:left;'></span>" 1024 + "<span class='ui-icon ui-icon-circlesmall-minus' style='float:left;'></span>".html_safe
1042 end 1025 end
1043 def leaf_item_icon 1026 def leaf_item_icon
1044 - "<span class='ui-icon ui-icon-arrow-1-e' style='float:left;'></span>" 1027 + "<span class='ui-icon ui-icon-arrow-1-e' style='float:left;'></span>".html_safe
1045 end 1028 end
1046 1029
1047 def display_category_menu(block, categories, root = true) 1030 def display_category_menu(block, categories, root = true)
@@ -1300,9 +1283,7 @@ module ApplicationHelper @@ -1300,9 +1283,7 @@ module ApplicationHelper
1300 titles = tabs.inject(''){ |result, tab| result << content_tag(:li, link_to(tab[:title], '#'+tab[:id]), :class => 'tab') } 1283 titles = tabs.inject(''){ |result, tab| result << content_tag(:li, link_to(tab[:title], '#'+tab[:id]), :class => 'tab') }
1301 contents = tabs.inject(''){ |result, tab| result << content_tag(:div, tab[:content], :id => tab[:id]) } 1284 contents = tabs.inject(''){ |result, tab| result << content_tag(:div, tab[:content], :id => tab[:id]) }
1302 1285
1303 - content_tag :div, :class => 'ui-tabs' do  
1304 - content_tag(:ul, titles) + contents  
1305 - end 1286 + content_tag(:div, content_tag(:ul, titles) + raw(contents), :class => 'ui-tabs')
1306 end 1287 end
1307 1288
1308 def jquery_token_input_messages_json(hintText = _('Type in an keyword'), noResultsText = _('No results'), searchingText = _('Searching...')) 1289 def jquery_token_input_messages_json(hintText = _('Type in an keyword'), noResultsText = _('No results'), searchingText = _('Searching...'))
@@ -1331,11 +1312,12 @@ module ApplicationHelper @@ -1331,11 +1312,12 @@ module ApplicationHelper
1331 end 1312 end
1332 1313
1333 def template_options(klass, field_name) 1314 def template_options(klass, field_name)
1334 - return '' if klass.templates.count == 0  
1335 - return hidden_field_tag("#{field_name}[template_id]", klass.templates.first.id) if klass.templates.count == 1 1315 + templates = klass.templates(environment)
  1316 + return '' if templates.count == 0
  1317 + return hidden_field_tag("#{field_name}[template_id]", templates.first.id) if templates.count == 1
1336 1318
1337 counter = 0 1319 counter = 0
1338 - radios = klass.templates.map do |template| 1320 + radios = templates.map do |template|
1339 counter += 1 1321 counter += 1
1340 content_tag('li', labelled_radio_button(link_to(template.name, template.url, :target => '_blank'), "#{field_name}[template_id]", template.id, counter==1)) 1322 content_tag('li', labelled_radio_button(link_to(template.name, template.url, :target => '_blank'), "#{field_name}[template_id]", template.id, counter==1))
1341 end.join("\n") 1323 end.join("\n")
@@ -1425,4 +1407,14 @@ module ApplicationHelper @@ -1425,4 +1407,14 @@ module ApplicationHelper
1425 @no_design_blocks = true 1407 @no_design_blocks = true
1426 end 1408 end
1427 1409
  1410 + def default_folder_for_image_upload(profile)
  1411 + default_folder = profile.folders.find_by_type('Gallery')
  1412 + default_folder = profile.folders.find_by_type('Folder') if default_folder.nil?
  1413 + default_folder
  1414 + end
  1415 +
  1416 + def content_id_to_str(content)
  1417 + content.nil? ? '' : content.id.to_s
  1418 + end
  1419 +
1428 end 1420 end
app/helpers/block_helper.rb
@@ -3,7 +3,24 @@ module BlockHelper @@ -3,7 +3,24 @@ module BlockHelper
3 def block_title(title) 3 def block_title(title)
4 tag_class = 'block-title' 4 tag_class = 'block-title'
5 tag_class += ' empty' if title.empty? 5 tag_class += ' empty' if title.empty?
6 - content_tag 'h3', content_tag('span', title), :class => tag_class 6 + content_tag 'h3', content_tag('span', h(title)), :class => tag_class
  7 + end
  8 +
  9 + def highlights_block_config_image_fields(block, image={})
  10 + "
  11 + <tr class=\"image-data-line\">
  12 + <td>
  13 + #{select_tag 'block[images][][image_id]', content_tag(:option) + option_groups_from_collection_for_select(block.folder_choices, :images, :name, :id, :name, image[:image_id].to_i).html_safe}
  14 + </td>
  15 + <td>#{text_field_tag 'block[images][][address]', image[:address], :class => 'highlight-address', :size => 20}</td>
  16 + <td>#{text_field_tag 'block[images][][position]', image[:position], :class => 'highlight-position', :size => 1}</td>
  17 + </tr><tr class=\"image-title\">
  18 + <td colspan=\"3\"><label>#{
  19 + content_tag('span', _('Title')) +
  20 + text_field_tag('block[images][][title]', image[:title], :class => 'highlight-title', :size => 45)
  21 + }</label></td>
  22 + </tr>
  23 + "
7 end 24 end
8 25
9 end 26 end
app/helpers/blog_helper.rb
@@ -18,8 +18,9 @@ module BlogHelper @@ -18,8 +18,9 @@ module BlogHelper
18 pagination = will_paginate(articles, { 18 pagination = will_paginate(articles, {
19 :param_name => 'npage', 19 :param_name => 'npage',
20 :previous_label => _('&laquo; Newer posts'), 20 :previous_label => _('&laquo; Newer posts'),
21 - :next_label => _('Older posts &raquo;')  
22 - }) 21 + :next_label => _('Older posts &raquo;'),
  22 + :params => {:action=>"view_page", :page=>articles.first.parent.path.split('/'), :controller=>"content_viewer"}
  23 + }) if articles.present?
23 content = [] 24 content = []
24 artic_len = articles.length 25 artic_len = articles.length
25 articles.each_with_index{ |art,i| 26 articles.each_with_index{ |art,i|
@@ -31,7 +32,7 @@ module BlogHelper @@ -31,7 +32,7 @@ module BlogHelper
31 css_add << position + '-inner' 32 css_add << position + '-inner'
32 content << content_tag('div', 33 content << content_tag('div',
33 content_tag('div', 34 content_tag('div',
34 - display_post(art, format) + '<br style="clear:both"/>', 35 + display_post(art, format).html_safe + '<br style="clear:both"/>'.html_safe,
35 :class => 'blog-post ' + css_add.join(' '), 36 :class => 'blog-post ' + css_add.join(' '),
36 :id => "post-#{art.id}"), :class => position 37 :id => "post-#{art.id}"), :class => position
37 ) 38 )
@@ -46,18 +47,6 @@ module BlogHelper @@ -46,18 +47,6 @@ module BlogHelper
46 article_title(article, :no_comments => no_comments) + html 47 article_title(article, :no_comments => no_comments) + html
47 end 48 end
48 49
49 - def display_short_format(article)  
50 - html = content_tag('div',  
51 - article.lead +  
52 - content_tag('div',  
53 - link_to_comments(article) +  
54 - link_to( _('Read more'), article.url),  
55 - :class => 'read-more'),  
56 - :class => 'short-post'  
57 - )  
58 - html  
59 - end  
60 -  
61 def display_full_format(article) 50 def display_full_format(article)
62 html = article_to_html(article) 51 html = article_to_html(article)
63 html = content_tag('p', html) if ! html.include?('</p>') 52 html = content_tag('p', html) if ! html.include?('</p>')
app/helpers/catalog_helper.rb
@@ -21,7 +21,7 @@ module CatalogHelper @@ -21,7 +21,7 @@ module CatalogHelper
21 21
22 def category_sub_links(category) 22 def category_sub_links(category)
23 sub_categories = [] 23 sub_categories = []
24 - category.children.each do |sub_category| 24 + category.children.order(:name).each do |sub_category|
25 sub_categories << category_link(sub_category, true) 25 sub_categories << category_link(sub_category, true)
26 end 26 end
27 content_tag('ul', sub_categories) if sub_categories.size > 1 27 content_tag('ul', sub_categories) if sub_categories.size > 1
app/helpers/content_viewer_helper.rb
@@ -39,7 +39,7 @@ module ContentViewerHelper @@ -39,7 +39,7 @@ module ContentViewerHelper
39 39
40 def link_to_comments(article, args = {}) 40 def link_to_comments(article, args = {})
41 return '' unless article.accept_comments? 41 return '' unless article.accept_comments?
42 - link_to(number_of_comments(article), article.url.merge(:anchor => 'comments_list') ) 42 + reference_to_article number_of_comments(article), article, 'comments_list'
43 end 43 end
44 44
45 def article_translations(article) 45 def article_translations(article)
@@ -48,7 +48,7 @@ module ContentViewerHelper @@ -48,7 +48,7 @@ module ContentViewerHelper
48 { article.environment.locales[translation.language] => { :href => url_for(translation.url) } } 48 { article.environment.locales[translation.language] => { :href => url_for(translation.url) } }
49 end 49 end
50 content_tag(:div, link_to(_('Translations'), '#', 50 content_tag(:div, link_to(_('Translations'), '#',
51 - :onclick => "toggleSubmenu(this, '#{_('Translations')}', #{links.to_json}); return false", 51 + :onmouseover => "toggleSubmenu(this, '#{_('Translations')}', #{links.to_json}); return false",
52 :class => 'article-translations-menu simplemenu-trigger up'), 52 :class => 'article-translations-menu simplemenu-trigger up'),
53 :class => 'article-translations') 53 :class => 'article-translations')
54 end 54 end
app/helpers/dates_helper.rb
@@ -23,11 +23,13 @@ module DatesHelper @@ -23,11 +23,13 @@ module DatesHelper
23 end 23 end
24 24
25 # formats a date for displaying. 25 # formats a date for displaying.
26 - def show_date(date, use_numbers = false) 26 + def show_date(date, use_numbers = false, year=true)
27 if date && use_numbers 27 if date && use_numbers
28 - _('%{month}/%{day}/%{year}') % { :day => date.day, :month => date.month, :year => date.year } 28 + date_format = year ? _('%{month}/%{day}/%{year}') : _('%{month}/%{day}')
  29 + date_format % { :day => date.day, :month => date.month, :year => date.year }
29 elsif date 30 elsif date
30 - _('%{month} %{day}, %{year}') % { :day => date.day, :month => month_name(date.month), :year => date.year } 31 + date_format = year ? _('%{month_name} %{day}, %{year}') : _('%{month_name} %{day}')
  32 + date_format % { :day => date.day, :month_name => month_name(date.month), :year => date.year }
31 else 33 else
32 '' 34 ''
33 end 35 end
@@ -46,7 +48,27 @@ module DatesHelper @@ -46,7 +48,27 @@ module DatesHelper
46 if (date1 == date2) || (date2.nil?) 48 if (date1 == date2) || (date2.nil?)
47 show_date(date1, use_numbers) 49 show_date(date1, use_numbers)
48 else 50 else
49 - _('from %{date1} to %{date2}') % {:date1 => show_date(date1, use_numbers), :date2 => show_date(date2, use_numbers)} 51 + if date1.year == date2.year
  52 + if date1.month == date2.month
  53 + _('from %{month} %{day1} to %{day2}, %{year}') % {
  54 + :day1 => date1.day,
  55 + :day2 => date2.day,
  56 + :month => use_numbers ? date1.month : month_name(date1.month),
  57 + :year => date1.year
  58 + }
  59 + else
  60 + _('from %{date1} to %{date2}, %{year}') % {
  61 + :date1 => show_date(date1, use_numbers, false),
  62 + :date2 => show_date(date2, use_numbers, false),
  63 + :year => date1.year
  64 + }
  65 + end
  66 + else
  67 + _('from %{date1} to %{date2}') % {
  68 + :date1 => show_date(date1, use_numbers),
  69 + :date2 => show_date(date2, use_numbers)
  70 + }
  71 + end
50 end 72 end
51 end 73 end
52 74
app/helpers/forms_helper.rb
@@ -142,38 +142,6 @@ module FormsHelper @@ -142,38 +142,6 @@ module FormsHelper
142 content_tag('table',rows.join("\n")) 142 content_tag('table',rows.join("\n"))
143 end 143 end
144 144
145 - def select_folder(label_text, field_id, collection, default_value=nil, html_options = {}, js_options = {})  
146 - root = profile ? profile.identifier : _("root")  
147 - labelled_form_field(  
148 - label_text,  
149 - select_tag(  
150 - field_id,  
151 - options_for_select(  
152 - [[root, '']] +  
153 - collection.collect {|f| [ root + '/' + f.full_name, f.id ] },  
154 - default_value  
155 - ),  
156 - html_options.merge(js_options)  
157 - )  
158 - )  
159 - end  
160 -  
161 - def select_profile_folder(label_text, field_id, profile, default_value='', html_options = {}, js_options = {})  
162 - result = labelled_form_field(  
163 - label_text,  
164 - select_tag(  
165 - field_id,  
166 - options_for_select(  
167 - [[profile.identifier, '']] +  
168 - profile.folders.collect {|f| [ profile.identifier + '/' + f.full_name, f.id ] },  
169 - default_value  
170 - ),  
171 - html_options.merge(js_options)  
172 - )  
173 - )  
174 - return result  
175 - end  
176 -  
177 def date_field(name, value, format = '%Y-%m-%d', datepicker_options = {}, html_options = {}) 145 def date_field(name, value, format = '%Y-%m-%d', datepicker_options = {}, html_options = {})
178 datepicker_options[:disabled] ||= false 146 datepicker_options[:disabled] ||= false
179 datepicker_options[:alt_field] ||= '' 147 datepicker_options[:alt_field] ||= ''
@@ -276,7 +244,7 @@ module FormsHelper @@ -276,7 +244,7 @@ module FormsHelper
276 yearSuffix: #{datepicker_options[:year_suffix].to_json} 244 yearSuffix: #{datepicker_options[:year_suffix].to_json}
277 }) 245 })
278 </script> 246 </script>
279 - " 247 + ".html_safe
280 result 248 result
281 end 249 end
282 250
@@ -295,23 +263,28 @@ module FormsHelper @@ -295,23 +263,28 @@ module FormsHelper
295 field_id, 263 field_id,
296 options_for_select( 264 options_for_select(
297 [[root, '']] + 265 [[root, '']] +
298 - collection.collect {|f| [ root + '/' + f.full_name, f.id ] },  
299 - default_value 266 + collection.collect {|f| [ root + '/' + f.full_name, f.id.to_s ] },
  267 + default_value.to_s
300 ), 268 ),
301 html_options.merge(js_options) 269 html_options.merge(js_options)
302 ) 270 )
303 ) 271 )
304 end 272 end
305 273
306 - def select_profile_folder(label_text, field_id, profile, default_value='', html_options = {}, js_options = {}) 274 + def select_profile_folder(label_text, field_id, profile, default_value='', html_options = {}, js_options = {}, find_options = {})
  275 + if find_options.empty?
  276 + folders = profile.folders
  277 + else
  278 + folders = profile.folders.where(find_options)
  279 + end
307 result = labelled_form_field( 280 result = labelled_form_field(
308 label_text, 281 label_text,
309 select_tag( 282 select_tag(
310 field_id, 283 field_id,
311 options_for_select( 284 options_for_select(
312 [[profile.identifier, '']] + 285 [[profile.identifier, '']] +
313 - profile.folders.collect {|f| [ profile.identifier + '/' + f.full_name, f.id ] },  
314 - default_value 286 + folders.collect {|f| [ profile.identifier + '/' + f.full_name, f.id.to_s ] },
  287 + default_value.to_s
315 ), 288 ),
316 html_options.merge(js_options) 289 html_options.merge(js_options)
317 ) 290 )
app/helpers/layout_helper.rb 0 → 100644
@@ -0,0 +1,94 @@ @@ -0,0 +1,94 @@
  1 +module LayoutHelper
  2 +
  3 + def body_classes
  4 + # Identify the current controller and action for the CSS:
  5 + " controller-#{@controller.controller_name}" +
  6 + " action-#{@controller.controller_name}-#{@controller.action_name}" +
  7 + " template-#{profile.nil? ? "default" : profile.layout_template}" +
  8 + (!profile.nil? && profile.is_on_homepage?(request.path,@page) ? " profile-homepage" : "")
  9 + end
  10 +
  11 + def noosfero_javascript
  12 + plugins_javascripts = @plugins.map { |plugin| plugin.js_files.map { |js| plugin.class.public_path(js) } }.flatten
  13 +
  14 + output = ''
  15 + output += render :file => 'layouts/_javascript'
  16 + output += javascript_tag 'render_all_jquery_ui_widgets()'
  17 + unless plugins_javascripts.empty?
  18 + output += javascript_include_tag plugins_javascripts, :cache => "cache/plugins-#{Digest::MD5.hexdigest plugins_javascripts.to_s}"
  19 + end
  20 + output
  21 + end
  22 +
  23 + def noosfero_stylesheets
  24 + standard_stylesheets = [
  25 + 'application',
  26 + 'search',
  27 + 'thickbox',
  28 + 'lightbox',
  29 + 'colorpicker',
  30 + 'colorbox',
  31 + pngfix_stylesheet_path,
  32 + ] + tokeninput_stylesheets
  33 + plugins_stylesheets = @plugins.select(&:stylesheet?).map { |plugin| plugin.class.public_path('style.css') }
  34 +
  35 + output = ''
  36 + output += stylesheet_link_tag standard_stylesheets, :cache => 'cache'
  37 + output += stylesheet_link_tag template_stylesheet_path
  38 + output += stylesheet_link_tag icon_theme_stylesheet_path
  39 + output += stylesheet_link_tag jquery_ui_theme_stylesheet_path
  40 + unless plugins_stylesheets.empty?
  41 + output += stylesheet_link_tag plugins_stylesheets, :cache => "cache/plugins-#{Digest::MD5.hexdigest plugins_stylesheets.to_s}"
  42 + end
  43 + output += stylesheet_link_tag theme_stylesheet_path
  44 + output
  45 + end
  46 +
  47 + def pngfix_stylesheet_path
  48 + 'iepngfix/iepngfix.css'
  49 + end
  50 +
  51 + def tokeninput_stylesheets
  52 + ['token-input', 'token-input-facebook', 'token-input-mac', 'token-input-facet']
  53 + end
  54 +
  55 + def noosfero_layout_features
  56 + render :file => 'shared/noosfero_layout_features'
  57 + end
  58 +
  59 + def template_stylesheet_path
  60 + if profile.nil?
  61 + "/designs/templates/#{environment.layout_template}/stylesheets/style.css"
  62 + else
  63 + "/designs/templates/#{profile.layout_template}/stylesheets/style.css"
  64 + end
  65 + end
  66 +
  67 + def icon_theme_stylesheet_path
  68 + icon_themes = []
  69 + theme_icon_themes = theme_option(:icon_theme) || []
  70 + for icon_theme in theme_icon_themes do
  71 + theme_path = "/designs/icons/#{icon_theme}/style.css"
  72 + if File.exists?(File.join(RAILS_ROOT, 'public', theme_path))
  73 + icon_themes << theme_path
  74 + end
  75 + end
  76 + icon_themes
  77 + end
  78 +
  79 + def jquery_ui_theme_stylesheet_path
  80 + 'jquery.ui/' + jquery_theme + '/jquery-ui-1.8.2.custom'
  81 + end
  82 +
  83 + def theme_stylesheet_path
  84 + theme_path + '/style.css'
  85 + end
  86 +
  87 + def addthis_javascript
  88 + if NOOSFERO_CONF['addthis_enabled']
  89 + '<script src="http://s7.addthis.com/js/152/addthis_widget.js"></script>'
  90 + end
  91 + end
  92 +
  93 +end
  94 +
app/helpers/profile_editor_helper.rb
@@ -136,7 +136,7 @@ module ProfileEditorHelper @@ -136,7 +136,7 @@ module ProfileEditorHelper
136 concat( 136 concat(
137 content_tag( 137 content_tag(
138 'div', 138 'div',
139 - capture(&block) + '<br style="clear:left;"/>&nbsp;', 139 + capture(&block) + content_tag('br', '', :style => 'clear: left'),
140 :class => 'control-panel') 140 :class => 'control-panel')
141 ) 141 )
142 end 142 end
app/helpers/search_helper.rb
@@ -2,12 +2,10 @@ module SearchHelper @@ -2,12 +2,10 @@ module SearchHelper
2 2
3 MAP_SEARCH_LIMIT = 2000 3 MAP_SEARCH_LIMIT = 2000
4 LIST_SEARCH_LIMIT = 20 4 LIST_SEARCH_LIMIT = 20
5 - BLOCKS_SEARCH_LIMIT = 18 5 + BLOCKS_SEARCH_LIMIT = 24
6 MULTIPLE_SEARCH_LIMIT = 8 6 MULTIPLE_SEARCH_LIMIT = 8
7 - DistFilt = 200  
8 - DistBoost = 50  
9 7
10 - Searches = ActiveSupport::OrderedHash[ 8 + SEARCHES = ActiveSupport::OrderedHash[
11 :articles, _('Contents'), 9 :articles, _('Contents'),
12 :enterprises, _('Enterprises'), 10 :enterprises, _('Enterprises'),
13 :people, _('People'), 11 :people, _('People'),
@@ -16,46 +14,31 @@ module SearchHelper @@ -16,46 +14,31 @@ module SearchHelper
16 :events, _('Events'), 14 :events, _('Events'),
17 ] 15 ]
18 16
19 - SortOptions = {  
20 - :products => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},  
21 - :more_recent, {:label => _('More recent'), :solr_opts => {:sort => 'updated_at desc, score desc'}},  
22 - :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}},  
23 - :closest, {:label => _('Closest to me'), :if => proc{ logged_in? && (profile=current_user.person).lat && profile.lng },  
24 - :solr_opts => {:sort => "geodist() asc",  
25 - :latitude => proc{ current_user.person.lat }, :longitude => proc{ current_user.person.lng }}},  
26 - ],  
27 - :events => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},  
28 - :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}},  
29 - ],  
30 - :articles => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},  
31 - :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}},  
32 - :more_recent, {:label => _('More recent'), :solr_opts => {:sort => 'updated_at desc, score desc'}},  
33 - ],  
34 - :enterprises => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},  
35 - :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}},  
36 - ],  
37 - :people => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},  
38 - :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}},  
39 - ],  
40 - :communities => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},  
41 - :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}},  
42 - ], 17 + FILTER_TRANSLATION = {
  18 + 'more_popular' => _('More popular'),
  19 + 'more_active' => _('More active'),
  20 + 'more_recent' => _('More recent'),
  21 + 'more_comments' => _('More comments')
43 } 22 }
44 23
45 # FIXME remove it after search_controler refactored 24 # FIXME remove it after search_controler refactored
46 include EventsHelper 25 include EventsHelper
47 26
48 - def multiple_search?  
49 - ['index', 'category_index'].include?(params[:action]) or @results.size > 1 27 + def multiple_search?(searches=nil)
  28 + ['index', 'category_index'].include?(params[:action]) || (searches && searches.size > 1)
50 end 29 end
51 30
52 - def map_search?  
53 - !@empty_query and !multiple_search? and params[:display] == 'map' 31 + def map_search?(searches=nil)
  32 + !multiple_search?(searches) && params[:display] == 'map'
  33 + end
  34 +
  35 + def asset_class(asset)
  36 + asset.to_s.singularize.camelize.constantize
54 end 37 end
55 38
56 def search_page_title(title, category = nil) 39 def search_page_title(title, category = nil)
57 title = "<h1>" + title 40 title = "<h1>" + title
58 - title += '<small>' + category.name + '</small>' if category 41 + title += ' - <small>' + category.name + '</small>' if category
59 title + "</h1>" 42 title + "</h1>"
60 end 43 end
61 44
@@ -66,8 +49,12 @@ module SearchHelper @@ -66,8 +49,12 @@ module SearchHelper
66 :align => 'center', :class => 'search-category-context') if category 49 :align => 'center', :class => 'search-category-context') if category
67 end 50 end
68 51
69 - def display_results(map_capable = false)  
70 - if map_capable and map_search? 52 + def display?(asset, mode)
  53 + defined?(asset_class(asset)::SEARCH_DISPLAYS) && asset_class(asset)::SEARCH_DISPLAYS.include?(mode.to_s)
  54 + end
  55 +
  56 + def display_results(searches=nil, asset=nil)
  57 + if display?(asset, :map) && map_search?(searches)
71 partial = 'google_maps' 58 partial = 'google_maps'
72 klass = 'map' 59 klass = 'map'
73 else 60 else
@@ -78,10 +65,13 @@ module SearchHelper @@ -78,10 +65,13 @@ module SearchHelper
78 content_tag('div', render(:partial => partial), :class => "map-or-list-search-results #{klass}") 65 content_tag('div', render(:partial => partial), :class => "map-or-list-search-results #{klass}")
79 end 66 end
80 67
81 - def display_map_list_button  
82 - button(:search, params[:display] == 'map' ? _('Display in list') : _('Display in map'),  
83 - params.merge(:display => (params[:display] == 'map' ? 'list' : 'map')),  
84 - :class => "map-toggle-button" ) 68 + def display_filter(asset, display)
  69 + asset = :articles if asset == :tag
  70 + if display?(asset, display)
  71 + display
  72 + else
  73 + asset_class(asset).default_search_display
  74 + end
85 end 75 end
86 76
87 def city_with_state(city) 77 def city_with_state(city)
@@ -97,120 +87,50 @@ module SearchHelper @@ -97,120 +87,50 @@ module SearchHelper
97 end 87 end
98 end 88 end
99 89
100 - def facets_menu(asset, _facets)  
101 - @asset_class = asset_class(asset)  
102 - @facets = _facets  
103 - render(:partial => 'facets_menu')  
104 - end  
105 -  
106 - def facets_unselect_menu(asset)  
107 - @asset_class = asset_class(asset)  
108 - render(:partial => 'facets_unselect_menu')  
109 - end  
110 -  
111 - def facet_javascript(input_id, facet, array)  
112 - array = [] if array.nil?  
113 - hintText = _('Type in an option')  
114 - text_field_tag('facet['+input_id+']', '', :id => input_id) +  
115 - javascript_tag("jQuery.TokenList(jQuery('##{input_id}'), #{array.to_json},  
116 - {searchDelay: 0, permanentDropdown: true, theme: 'facet', dontAdd: true, preventDuplicates: true,  
117 - #{jquery_token_input_messages_json(hintText)}});")  
118 - end  
119 -  
120 - def facet_link_html(facet, params, value, label, count)  
121 - params = params ? params.dup : {}  
122 - has_extra = label.kind_of?(Array)  
123 - link_label = has_extra ? label[0] : label  
124 - id = facet[:solr_field].to_s  
125 - params[:facet] ||= {}  
126 - params[:facet][id] ||= {}  
127 - params[:page] = {} if params[:page]  
128 -  
129 - selected = facet[:label_id].nil? ? params[:facet][id] == value : params[:facet][id][facet[:label_id]].to_a.include?(value)  
130 -  
131 - if count > 0  
132 - url = params.merge(:facet => params[:facet].merge(  
133 - id => facet[:label_id].nil? ? value : params[:facet][id].merge( facet[:label_id] => params[:facet][id][facet[:label_id]].to_a | [value] )  
134 - ))  
135 - else  
136 - # preserve others filters and change this filter  
137 - url = params.merge(:facet => params[:facet].merge(  
138 - id => facet[:label_id].nil? ? value : { facet[:label_id] => value }  
139 - )) 90 + def display_selector(asset, display, float = 'right')
  91 + display = nil if display.blank?
  92 + display ||= asset_class(asset).default_search_display
  93 + if [display?(asset, :map), display?(asset, :compact), display?(asset, :full)].select {|option| option}.count > 1
  94 + compact_link = display?(asset, :compact) ? (display == 'compact' ? _('Compact') : link_to(_('Compact'), params.merge(:display => 'compact'))) : nil
  95 + map_link = display?(asset, :map) ? (display == 'map' ? _('Map') : link_to(_('Map'), params.merge(:display => 'map'))) : nil
  96 + full_link = display?(asset, :full) ? (display == 'full' ? _('Full') : link_to(_('Full'), params.merge(:display => 'full'))) : nil
  97 + content_tag('div',
  98 + content_tag('strong', _('Display')) + ': ' + [compact_link, map_link, full_link].compact.join(' | ').html_safe,
  99 + :class => 'search-customize-options'
  100 + )
140 end 101 end
141 -  
142 - content_tag 'div', link_to(link_label, url, :class => 'facet-result-link-label') +  
143 - content_tag('span', (has_extra ? label[1] : ''), :class => 'facet-result-extra-label') +  
144 - (count > 0 ? content_tag('span', " (#{count})", :class => 'facet-result-count') : ''),  
145 - :class => 'facet-menu-item' + (selected ? ' facet-result-link-selected' : '')  
146 end 102 end
147 103
148 - def facet_selecteds_html_for(environment, klass, params)  
149 - def name_with_extra(klass, facet, value)  
150 - name = klass.facet_result_name(facet, value)  
151 - name = name[0] + name[1] if name.kind_of?(Array)  
152 - name  
153 - end  
154 -  
155 - ret = []  
156 - params = params.dup  
157 - params[:facet].each do |id, value|  
158 - facet = klass.facet_by_id(id.to_sym)  
159 - next unless facet  
160 - if value.kind_of?(Hash)  
161 - label_hash = facet[:label].call(environment)  
162 - value.each do |label_id, value|  
163 - facet[:label_id] = label_id  
164 - facet[:label] = label_hash[label_id]  
165 - value.to_a.each do |value|  
166 - ret << [facet[:label], name_with_extra(klass, facet, value),  
167 - params.merge(:facet => params[:facet].merge(id => params[:facet][id].merge(label_id => params[:facet][id][label_id].to_a.reject{ |v| v == value })))]  
168 - end  
169 - end  
170 - else  
171 - ret << [klass.facet_label(facet), name_with_extra(klass, facet, value),  
172 - params.merge(:facet => params[:facet].reject{ |k,v| k == id })]  
173 - end 104 + def filter_selector(asset, filter, float = 'right')
  105 + klass = asset_class(asset)
  106 + if klass::SEARCH_FILTERS.count > 1
  107 + options = options_for_select(klass::SEARCH_FILTERS.map {|f| [FILTER_TRANSLATION[f], f]}, filter)
  108 + url_params = url_for(params.merge(:filter => 'FILTER'))
  109 + onchange = "document.location.href = '#{url_params}'.replace('FILTER', this.value)"
  110 + select_field = select_tag(:filter, options, :onchange => onchange)
  111 + content_tag('div',
  112 + content_tag('strong', _('Filter')) + ': ' + select_field,
  113 + :class => "search-customize-options"
  114 + )
174 end 115 end
175 -  
176 - ret.map do |label, name, url|  
177 - content_tag('div', content_tag('span', label, :class => 'facet-selected-label') +  
178 - content_tag('span', name, :class => 'facet-selected-name') +  
179 - link_to('', url, :class => 'facet-selected-remove', :title => 'remove facet'), :class => 'facet-selected')  
180 - end.join  
181 - end  
182 -  
183 - def order_by(asset)  
184 - options = SortOptions[asset].map do |name, options|  
185 - next if options[:if] and ! instance_eval(&options[:if])  
186 - [_(options[:label]), name.to_s]  
187 - end.compact  
188 -  
189 - content_tag('div', _('Sort results by ') +  
190 - select_tag(asset.to_s + '[order]', options_for_select(options, params[:order_by] || 'none'),  
191 - {:onchange => "window.location = jQuery.param.querystring(window.location.href, { 'order_by' : this.options[this.selectedIndex].value})"}),  
192 - :class => "search-ordering")  
193 - end  
194 -  
195 - def label_total_found(asset, total_found)  
196 - labels = {  
197 - :products => _("%s products offers found"),  
198 - :articles => _("%s articles found"),  
199 - :events => _("%s events found"),  
200 - :people => _("%s people found"),  
201 - :enterprises => _("%s enterprises found"),  
202 - :communities => _("%s communities found"),  
203 - }  
204 - content_tag('span', labels[asset] % total_found,  
205 - :class => "total-pages-found") if labels[asset]  
206 - end  
207 -  
208 - def asset_class(asset)  
209 - asset.to_s.singularize.camelize.constantize  
210 end 116 end
211 117
212 - def asset_table(asset)  
213 - asset_class(asset).table_name 118 + def filter_title(asset, filter)
  119 + {
  120 + 'articles_more_recent' => _('More recent contents from network'),
  121 + 'articles_more_popular' => _('More viewed contents from network'),
  122 + 'articles_more_comments' => _('Most commented contents from network'),
  123 + 'people_more_recent' => _('More recent people from network'),
  124 + 'people_more_active' => _('More active people from network'),
  125 + 'people_more_popular' => _('More popular people from network'),
  126 + 'communities_more_recent' => _('More recent communities from network'),
  127 + 'communities_more_active' => _('More active communities from network'),
  128 + 'communities_more_popular' => _('More popular communities from network'),
  129 + 'enterprises_more_recent' => _('More recent enterprises from network'),
  130 + 'enterprises_more_active' => _('More active enterprises from network'),
  131 + 'enterprises_more_popular' => _('More popular enterprises from network'),
  132 + 'products_more_recent' => _('Highlights'),
  133 + }[asset.to_s + '_' + filter].to_s
214 end 134 end
215 135
216 end 136 end
app/helpers/tags_helper.rb
@@ -29,10 +29,8 @@ module TagsHelper @@ -29,10 +29,8 @@ module TagsHelper
29 # (pt_BR only). 29 # (pt_BR only).
30 def tag_cloud(tags, tagname_option, url, options = {}) 30 def tag_cloud(tags, tagname_option, url, options = {})
31 31
32 - return content_tag('em', _('No tags yet.')) +  
33 - ' <a href="' + _('http://en.wikipedia.org/wiki/Tag_%28metadata%29') +  
34 - '" target="wptags"><span>(' +  
35 - _('What are tags?') + ')</span></a>' if tags.empty? 32 + return content_tag('em', _('No tags yet.') + ' ') +
  33 + link_to(content_tag(:span, _('What are tags?')),_('http://en.wikipedia.org/wiki/Tag_%28metadata%29')) if tags.empty?
36 34
37 max_size = options[:max_size] || Cloud::MAX_SIZE 35 max_size = options[:max_size] || Cloud::MAX_SIZE
38 min_size = options[:min_size] || Cloud::MIN_SIZE 36 min_size = options[:min_size] || Cloud::MIN_SIZE
@@ -68,7 +66,7 @@ module TagsHelper @@ -68,7 +66,7 @@ module TagsHelper
68 :title => n_( 'one item', '%d items', count ) % count 66 :title => n_( 'one item', '%d items', count ) % count
69 end 67 end
70 68
71 - end.join("\n") 69 + end.join("\n").html_safe
72 end 70 end
73 71
74 end 72 end
app/models/approve_comment.rb
@@ -43,7 +43,7 @@ class ApproveComment &lt; Task @@ -43,7 +43,7 @@ class ApproveComment &lt; Task
43 43
44 def information 44 def information
45 if article 45 if article
46 - {:message => _('%{requestor} commented on the the article: %{linked_subject}.') % {:requestor => requestor_name} } 46 + {:message => _('%{requestor} commented on the the article: %{linked_subject}.') % {:requestor => requestor_name, :linked_subject => linked_subject} }
47 else 47 else
48 {:message => _("The article was removed.")} 48 {:message => _("The article was removed.")}
49 end 49 end
app/models/article.rb
@@ -2,7 +2,28 @@ require &#39;hpricot&#39; @@ -2,7 +2,28 @@ require &#39;hpricot&#39;
2 2
3 class Article < ActiveRecord::Base 3 class Article < ActiveRecord::Base
4 4
5 -include ActionController::UrlWriter 5 + SEARCHABLE_FIELDS = {
  6 + :name => 10,
  7 + :abstract => 3,
  8 + :body => 2,
  9 + :slug => 1,
  10 + :filename => 1,
  11 + }
  12 +
  13 + SEARCH_FILTERS = %w[
  14 + more_recent
  15 + more_popular
  16 + more_comments
  17 + ]
  18 +
  19 + SEARCH_DISPLAYS = %w[full]
  20 +
  21 + def self.default_search_display
  22 + 'full'
  23 + end
  24 +
  25 + #FIXME This is necessary because html is being generated on the model...
  26 + include ActionView::Helpers::TagHelper
6 27
7 # use for internationalizable human type names in search facets 28 # use for internationalizable human type names in search facets
8 # reimplement on subclasses 29 # reimplement on subclasses
@@ -147,7 +168,6 @@ include ActionController::UrlWriter @@ -147,7 +168,6 @@ include ActionController::UrlWriter
147 else 168 else
148 ArticleCategorization.add_category_to_article(c, self) 169 ArticleCategorization.add_category_to_article(c, self)
149 self.categories(reload) 170 self.categories(reload)
150 - self.solr_save  
151 end 171 end
152 end 172 end
153 173
@@ -165,7 +185,6 @@ include ActionController::UrlWriter @@ -165,7 +185,6 @@ include ActionController::UrlWriter
165 ArticleCategorization.add_category_to_article(item, self) 185 ArticleCategorization.add_category_to_article(item, self)
166 end 186 end
167 self.categories(true) 187 self.categories(true)
168 - self.solr_save  
169 pending_categorizations.clear 188 pending_categorizations.clear
170 end 189 end
171 190
@@ -201,20 +220,12 @@ include ActionController::UrlWriter @@ -201,20 +220,12 @@ include ActionController::UrlWriter
201 named_scope :public, 220 named_scope :public,
202 :conditions => [ "advertise = ? AND published = ? AND profiles.visible = ? AND profiles.public_profile = ?", true, true, true, true ] 221 :conditions => [ "advertise = ? AND published = ? AND profiles.visible = ? AND profiles.public_profile = ?", true, true, true, true ]
203 222
204 - named_scope :more_recent,  
205 - :conditions => [ "advertise = ? AND published = ? AND profiles.visible = ? AND profiles.public_profile = ? AND  
206 - ((articles.type != ?) OR articles.type is NULL)",  
207 - true, true, true, true, 'RssFeed'  
208 - ],  
209 - :order => 'articles.published_at desc, articles.id desc'  
210 -  
211 # retrives the most commented articles, sorted by the comment count (largest 223 # retrives the most commented articles, sorted by the comment count (largest
212 # first) 224 # first)
213 def self.most_commented(limit) 225 def self.most_commented(limit)
214 paginate(:order => 'comments_count DESC', :page => 1, :per_page => limit) 226 paginate(:order => 'comments_count DESC', :page => 1, :per_page => limit)
215 end 227 end
216 228
217 - named_scope :more_popular, :order => 'hits DESC'  
218 named_scope :relevant_as_recent, :conditions => ["(articles.type != 'UploadedFile' and articles.type != 'RssFeed' and articles.type != 'Blog') OR articles.type is NULL"] 229 named_scope :relevant_as_recent, :conditions => ["(articles.type != 'UploadedFile' and articles.type != 'RssFeed' and articles.type != 'Blog') OR articles.type is NULL"]
219 230
220 def self.recent(limit = nil, extra_conditions = {}, pagination = true) 231 def self.recent(limit = nil, extra_conditions = {}, pagination = true)
@@ -239,8 +250,13 @@ include ActionController::UrlWriter @@ -239,8 +250,13 @@ include ActionController::UrlWriter
239 # The implementation in this class just provides the +body+ attribute as the 250 # The implementation in this class just provides the +body+ attribute as the
240 # HTML. Other article types can override this method to provide customized 251 # HTML. Other article types can override this method to provide customized
241 # views of themselves. 252 # views of themselves.
  253 + # (To override short format representation, override the lead method)
242 def to_html(options = {}) 254 def to_html(options = {})
243 - body || '' 255 + if options[:format] == 'short'
  256 + display_short_format(self)
  257 + else
  258 + body || ''
  259 + end
244 end 260 end
245 261
246 include ApplicationHelper 262 include ApplicationHelper
@@ -429,8 +445,8 @@ include ActionController::UrlWriter @@ -429,8 +445,8 @@ include ActionController::UrlWriter
429 named_scope :images, :conditions => { :is_image => true } 445 named_scope :images, :conditions => { :is_image => true }
430 named_scope :text_articles, :conditions => [ 'articles.type IN (?)', text_article_types ] 446 named_scope :text_articles, :conditions => [ 'articles.type IN (?)', text_article_types ]
431 447
  448 + named_scope :more_popular, :order => 'hits DESC'
432 named_scope :more_comments, :order => "comments_count DESC" 449 named_scope :more_comments, :order => "comments_count DESC"
433 - named_scope :more_views, :order => "hits DESC"  
434 named_scope :more_recent, :order => "created_at DESC" 450 named_scope :more_recent, :order => "created_at DESC"
435 451
436 def self.display_filter(user, profile) 452 def self.display_filter(user, profile)
@@ -596,7 +612,7 @@ include ActionController::UrlWriter @@ -596,7 +612,7 @@ include ActionController::UrlWriter
596 end 612 end
597 613
598 def lead 614 def lead
599 - abstract.blank? ? first_paragraph : abstract 615 + abstract.blank? ? first_paragraph.html_safe : abstract.html_safe
600 end 616 end
601 617
602 def short_lead 618 def short_lead
@@ -627,7 +643,7 @@ include ActionController::UrlWriter @@ -627,7 +643,7 @@ include ActionController::UrlWriter
627 643
628 end 644 end
629 645
630 - def more_views_label 646 + def more_popular_label
631 amount = self.hits 647 amount = self.hits
632 { 648 {
633 0 => _('no views'), 649 0 => _('no views'),
@@ -655,98 +671,7 @@ include ActionController::UrlWriter @@ -655,98 +671,7 @@ include ActionController::UrlWriter
655 img.nil? ? '' : img.attributes['src'] 671 img.nil? ? '' : img.attributes['src']
656 end 672 end
657 673
658 - private  
659 -  
660 - # FIXME: workaround for development env.  
661 - # Subclasses aren't (re)loaded, and acts_as_solr  
662 - # depends on subclasses method to search  
663 - # see http://stackoverflow.com/questions/4138957/activerecordsubclassnotfound-error-when-using-sti-in-rails/4139245  
664 - UploadedFile  
665 - TextArticle  
666 - TinyMceArticle  
667 - TextileArticle  
668 - Folder  
669 - EnterpriseHomepage  
670 - Gallery  
671 - Blog  
672 - Forum  
673 - Event  
674 -  
675 - def self.f_type_proc(klass)  
676 - klass.constantize.type_name  
677 - end  
678 -  
679 - def self.f_profile_type_proc(klass)  
680 - klass.constantize.type_name  
681 - end  
682 -  
683 - def f_type  
684 - #join common types  
685 - case self.class.name  
686 - when 'TinyMceArticle', 'TextileArticle'  
687 - TextArticle.name  
688 - else  
689 - self.class.name  
690 - end  
691 - end  
692 -  
693 - def f_profile_type  
694 - self.profile.class.name  
695 - end  
696 -  
697 - def f_published_at  
698 - self.published_at  
699 - end  
700 -  
701 - def f_category  
702 - self.categories.collect(&:name)  
703 - end  
704 -  
705 delegate :region, :region_id, :environment, :environment_id, :to => :profile, :allow_nil => true 674 delegate :region, :region_id, :environment, :environment_id, :to => :profile, :allow_nil => true
706 - def name_sortable # give a different name for solr  
707 - name  
708 - end  
709 -  
710 - def public  
711 - self.public?  
712 - end  
713 -  
714 - def category_filter  
715 - categories_including_virtual_ids  
716 - end  
717 -  
718 - public  
719 -  
720 - acts_as_faceted :fields => {  
721 - :f_type => {:label => _('Type'), :proc => proc{|klass| f_type_proc(klass)}},  
722 - :f_published_at => {:type => :date, :label => _('Published date'), :queries => {'[* TO NOW-1YEARS/DAY]' => _("Older than one year"),  
723 - '[NOW-1YEARS TO NOW/DAY]' => _("In the last year"), '[NOW-1MONTHS TO NOW/DAY]' => _("In the last month"), '[NOW-7DAYS TO NOW/DAY]' => _("In the last week"), '[NOW-1DAYS TO NOW/DAY]' => _("In the last day")},  
724 - :queries_order => ['[NOW-1DAYS TO NOW/DAY]', '[NOW-7DAYS TO NOW/DAY]', '[NOW-1MONTHS TO NOW/DAY]', '[NOW-1YEARS TO NOW/DAY]', '[* TO NOW-1YEARS/DAY]']},  
725 - :f_profile_type => {:label => _('Profile'), :proc => proc{|klass| f_profile_type_proc(klass)}},  
726 - :f_category => {:label => _('Categories')},  
727 - }, :category_query => proc { |c| "category_filter:\"#{c.id}\"" },  
728 - :order => [:f_type, :f_published_at, :f_profile_type, :f_category]  
729 -  
730 - acts_as_searchable :fields => facets_fields_for_solr + [  
731 - # searched fields  
732 - {:name => {:type => :text, :boost => 2.0}},  
733 - {:slug => :text}, {:body => :text},  
734 - {:abstract => :text}, {:filename => :text},  
735 - # filtered fields  
736 - {:public => :boolean}, {:environment_id => :integer},  
737 - {:profile_id => :integer}, :language,  
738 - {:category_filter => :integer},  
739 - # ordered/query-boosted fields  
740 - {:name_sortable => :string}, :last_changed_by_id, :published_at, :is_image,  
741 - :updated_at, :created_at,  
742 - ], :include => [  
743 - {:profile => {:fields => [:name, :identifier, :address, :nickname, :region_id, :lat, :lng]}},  
744 - {:comments => {:fields => [:title, :body, :author_name, :author_email]}},  
745 - {:categories => {:fields => [:name, :path, :slug, :lat, :lng, :acronym, :abbreviation]}},  
746 - ], :facets => facets_option_for_solr,  
747 - :boost => proc { |a| 10 if a.profile && a.profile.enabled },  
748 - :if => proc{ |a| ! ['RssFeed'].include?(a.class.name) }  
749 - handle_asynchronously :solr_save  
750 675
751 private 676 private
752 677
app/models/article_block.rb
@@ -12,7 +12,11 @@ class ArticleBlock &lt; Block @@ -12,7 +12,11 @@ class ArticleBlock &lt; Block
12 block = self 12 block = self
13 lambda do 13 lambda do
14 block_title(block.title) + 14 block_title(block.title) +
15 - (block.article ? article_to_html(block.article, :gallery_view => false) : _('Article not selected yet.')) 15 + (block.article ? article_to_html(block.article,
  16 + :gallery_view => false,
  17 + :inside_block => block, # For Blogs and folders
  18 + :format => block.visualization_format # For Articles and contents
  19 + ).html_safe : _('Article not selected yet.'))
16 end 20 end
17 end 21 end
18 22
@@ -49,4 +53,14 @@ class ArticleBlock &lt; Block @@ -49,4 +53,14 @@ class ArticleBlock &lt; Block
49 self.box.owner.kind_of?(Environment) ? self.box.owner.portal_community.articles : self.box.owner.articles 53 self.box.owner.kind_of?(Environment) ? self.box.owner.portal_community.articles : self.box.owner.articles
50 end 54 end
51 55
  56 + def posts_per_page
  57 + self.settings[:posts_per_page] or 1
  58 + end
  59 +
  60 + def posts_per_page= value
  61 + value = value.to_i
  62 + self.settings[:posts_per_page] = value if value > 0
  63 + end
  64 +
  65 + settings_items :visualization_format, :type => :string, :default => 'short'
52 end 66 end
app/models/blog.rb
@@ -24,8 +24,9 @@ class Blog &lt; Folder @@ -24,8 +24,9 @@ class Blog &lt; Folder
24 # FIXME isn't this too much including just to be able to generate some HTML? 24 # FIXME isn't this too much including just to be able to generate some HTML?
25 include ActionView::Helpers::TagHelper 25 include ActionView::Helpers::TagHelper
26 def to_html(options = {}) 26 def to_html(options = {})
  27 + me = self
27 lambda do 28 lambda do
28 - render :file => 'content_viewer/blog_page' 29 + render :file => 'content_viewer/blog_page', :locals => { :blog=>me, :inside_block=>options[:inside_block] }
29 end 30 end
30 end 31 end
31 32
app/models/category.rb
1 class Category < ActiveRecord::Base 1 class Category < ActiveRecord::Base
2 2
  3 + SEARCHABLE_FIELDS = {
  4 + :name => 10,
  5 + :acronym => 5,
  6 + :abbreviation => 5,
  7 + :slug => 1,
  8 + }
  9 +
3 validates_exclusion_of :slug, :in => [ 'index' ], :message => N_('%{fn} cannot be like that.').fix_i18n 10 validates_exclusion_of :slug, :in => [ 'index' ], :message => N_('%{fn} cannot be like that.').fix_i18n
4 validates_presence_of :name, :environment_id 11 validates_presence_of :name, :environment_id
5 validates_uniqueness_of :slug,:scope => [ :environment_id, :parent_id ], :message => N_('%{fn} is already being used by another category.').fix_i18n 12 validates_uniqueness_of :slug,:scope => [ :environment_id, :parent_id ], :message => N_('%{fn} is already being used by another category.').fix_i18n
@@ -100,23 +107,4 @@ class Category &lt; ActiveRecord::Base @@ -100,23 +107,4 @@ class Category &lt; ActiveRecord::Base
100 self.children.find(:all, :conditions => {:display_in_menu => true}).empty? 107 self.children.find(:all, :conditions => {:display_in_menu => true}).empty?
101 end 108 end
102 109
103 - private  
104 - def name_sortable # give a different name for solr  
105 - name  
106 - end  
107 - public  
108 -  
109 - acts_as_searchable :fields => [  
110 - # searched fields  
111 - {:name => {:type => :text, :boost => 2.0}},  
112 - {:path => :text}, {:slug => :text},  
113 - {:abbreviation => :text}, {:acronym => :text},  
114 - # filtered fields  
115 - :parent_id,  
116 - # ordered/query-boosted fields  
117 - {:name_sortable => :string},  
118 - ]  
119 - after_save_reindex [:articles, :profiles], :with => :delayed_job  
120 - handle_asynchronously :solr_save  
121 -  
122 end 110 end
app/models/certifier.rb
1 class Certifier < ActiveRecord::Base 1 class Certifier < ActiveRecord::Base
2 2
  3 + SEARCHABLE_FIELDS = {
  4 + :name => 10,
  5 + :description => 3,
  6 + :link => 1,
  7 + }
  8 +
3 belongs_to :environment 9 belongs_to :environment
4 10
5 has_many :qualifier_certifiers, :dependent => :destroy 11 has_many :qualifier_certifiers, :dependent => :destroy
@@ -24,6 +30,4 @@ class Certifier &lt; ActiveRecord::Base @@ -24,6 +30,4 @@ class Certifier &lt; ActiveRecord::Base
24 self.name.downcase.transliterate <=> b.name.downcase.transliterate 30 self.name.downcase.transliterate <=> b.name.downcase.transliterate
25 end 31 end
26 32
27 - after_save_reindex [:products], :with => :delayed_job  
28 -  
29 end 33 end
app/models/comment.rb
1 class Comment < ActiveRecord::Base 1 class Comment < ActiveRecord::Base
2 2
  3 + SEARCHABLE_FIELDS = {
  4 + :title => 10,
  5 + :name => 4,
  6 + :body => 2,
  7 + }
  8 +
3 validates_presence_of :body 9 validates_presence_of :body
4 10
5 belongs_to :source, :counter_cache => true, :polymorphic => true 11 belongs_to :source, :counter_cache => true, :polymorphic => true
@@ -85,12 +91,6 @@ class Comment &lt; ActiveRecord::Base @@ -85,12 +91,6 @@ class Comment &lt; ActiveRecord::Base
85 self.article.profile.notification_emails - [self.author_email || self.email] 91 self.article.profile.notification_emails - [self.author_email || self.email]
86 end 92 end
87 93
88 - after_save :notify_article  
89 - after_destroy :notify_article  
90 - def notify_article  
91 - article.comments_updated if article.kind_of?(Article)  
92 - end  
93 -  
94 after_create :new_follower 94 after_create :new_follower
95 def new_follower 95 def new_follower
96 if source.kind_of?(Article) 96 if source.kind_of?(Article)
app/models/enterprise.rb
@@ -2,6 +2,8 @@ @@ -2,6 +2,8 @@
2 # only enterprises can offer products and services. 2 # only enterprises can offer products and services.
3 class Enterprise < Organization 3 class Enterprise < Organization
4 4
  5 + SEARCH_DISPLAYS += %w[map full]
  6 +
5 def self.type_name 7 def self.type_name
6 _('Enterprise') 8 _('Enterprise')
7 end 9 end
@@ -14,8 +16,6 @@ class Enterprise &lt; Organization @@ -14,8 +16,6 @@ class Enterprise &lt; Organization
14 16
15 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'
16 18
17 - after_save_reindex [:products], :with => :delayed_job  
18 - extra_data_for_index :product_categories  
19 def product_categories 19 def product_categories
20 products.includes(:product_category).map{|p| p.category_full_name}.compact 20 products.includes(:product_category).map{|p| p.category_full_name}.compact
21 end 21 end
@@ -182,7 +182,15 @@ class Enterprise &lt; Organization @@ -182,7 +182,15 @@ class Enterprise &lt; Organization
182 end 182 end
183 183
184 def activities 184 def activities
185 - Scrap.find_by_sql("SELECT id, updated_at, 'Scrap' AS klass FROM scraps WHERE scraps.receiver_id = #{self.id} AND scraps.scrap_id IS NULL UNION SELECT id, updated_at, 'ActionTracker::Record' AS klass FROM action_tracker WHERE action_tracker.target_id = #{self.id} UNION SELECT action_tracker.id, action_tracker.updated_at, 'ActionTracker::Record' AS klass FROM action_tracker INNER JOIN articles ON action_tracker.target_id = articles.id WHERE articles.profile_id = #{self.id} AND action_tracker.target_type = 'Article' ORDER BY action_tracker.updated_at DESC") 185 + Scrap.find_by_sql("SELECT id, updated_at, 'Scrap' AS klass FROM scraps WHERE scraps.receiver_id = #{self.id} AND scraps.scrap_id IS NULL UNION SELECT id, updated_at, 'ActionTracker::Record' AS klass FROM action_tracker WHERE action_tracker.target_id = #{self.id} UNION SELECT action_tracker.id, action_tracker.updated_at, 'ActionTracker::Record' AS klass FROM action_tracker INNER JOIN articles ON action_tracker.target_id = articles.id WHERE articles.profile_id = #{self.id} AND action_tracker.target_type = 'Article' ORDER BY updated_at DESC")
  186 + end
  187 +
  188 + def catalog_url
  189 + { :profile => identifier, :controller => 'catalog'}
  190 + end
  191 +
  192 + def more_recent_label
  193 + ''
186 end 194 end
187 195
188 end 196 end
app/models/environment.rb
@@ -268,8 +268,6 @@ class Environment &lt; ActiveRecord::Base @@ -268,8 +268,6 @@ class Environment &lt; ActiveRecord::Base
268 268
269 settings_items :search_hints, :type => Hash, :default => {} 269 settings_items :search_hints, :type => Hash, :default => {}
270 270
271 - settings_items :top_level_category_as_facet_ids, :type => Array, :default => []  
272 -  
273 def news_amount_by_folder=(amount) 271 def news_amount_by_folder=(amount)
274 settings[:news_amount_by_folder] = amount.to_i 272 settings[:news_amount_by_folder] = amount.to_i
275 end 273 end
@@ -618,12 +616,10 @@ class Environment &lt; ActiveRecord::Base @@ -618,12 +616,10 @@ class Environment &lt; ActiveRecord::Base
618 end 616 end
619 617
620 def top_url 618 def top_url
621 - protocol = 'http'  
622 - result = "#{protocol}://#{default_hostname}"  
623 - if Noosfero.url_options.has_key?(:port)  
624 - result << ':' << Noosfero.url_options[:port].to_s  
625 - end  
626 - result 619 + url = 'http://'
  620 + url << (Noosfero.url_options.key?(:host) ? Noosfero.url_options[:host] : default_hostname)
  621 + url << ':' << Noosfero.url_options[:port].to_s if Noosfero.url_options.key?(:port)
  622 + url
627 end 623 end
628 624
629 def to_s 625 def to_s
app/models/event.rb
@@ -14,7 +14,6 @@ class Event &lt; Article @@ -14,7 +14,6 @@ class Event &lt; Article
14 maybe_add_http(self.setting[:link]) 14 maybe_add_http(self.setting[:link])
15 end 15 end
16 16
17 - xss_terminate :only => [ :link ], :on => 'validation'  
18 xss_terminate :only => [ :body, :link, :address ], :with => 'white_list', :on => 'validation' 17 xss_terminate :only => [ :body, :link, :address ], :with => 'white_list', :on => 'validation'
19 18
20 def initialize(*args) 19 def initialize(*args)
@@ -104,18 +103,30 @@ class Event &lt; Article @@ -104,18 +103,30 @@ class Event &lt; Article
104 } 103 }
105 } 104 }
106 105
  106 + # TODO: some good soul, please clean this ugly hack:
107 if self.body 107 if self.body
108 html.div('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', :class => 'event-description') 108 html.div('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', :class => 'event-description')
109 end 109 end
110 } 110 }
111 111
112 if self.body 112 if self.body
113 - result.sub!('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', self.body) 113 + if options[:format] == 'short'
  114 + result.sub!('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', display_short_format(self))
  115 + else
  116 + result.sub!('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', self.body)
  117 + end
114 end 118 end
115 119
116 result 120 result
117 end 121 end
118 122
  123 + def lead
  124 + content_tag('div',
  125 + show_period(start_date, end_date),
  126 + :class => 'event-dates'
  127 + ) + super
  128 + end
  129 +
119 def event? 130 def event?
120 true 131 true
121 end 132 end
app/models/external_feed.rb
@@ -11,6 +11,15 @@ class ExternalFeed &lt; ActiveRecord::Base @@ -11,6 +11,15 @@ class ExternalFeed &lt; ActiveRecord::Base
11 } 11 }
12 12
13 def add_item(title, link, date, content) 13 def add_item(title, link, date, content)
  14 + doc = Hpricot(content)
  15 + doc.search('*').each do |p|
  16 + if p.instance_of? Hpricot::Elem
  17 + p.remove_attribute 'style'
  18 + p.remove_attribute 'class'
  19 + end
  20 + end
  21 + content = doc.to_s
  22 +
14 article = TinyMceArticle.new(:name => title, :profile => blog.profile, :body => content, :published_at => date, :source => link, :profile => blog.profile, :parent => blog) 23 article = TinyMceArticle.new(:name => title, :profile => blog.profile, :body => content, :published_at => date, :source => link, :profile => blog.profile, :parent => blog)
15 unless blog.children.exists?(:slug => article.slug) 24 unless blog.children.exists?(:slug => article.slug)
16 article.save! 25 article.save!
app/models/feed_reader_block.rb
@@ -47,11 +47,11 @@ class FeedReaderBlock &lt; Block @@ -47,11 +47,11 @@ class FeedReaderBlock &lt; Block
47 47
48 def formatted_feed_content 48 def formatted_feed_content
49 if error_message.blank? 49 if error_message.blank?
50 - "<ul>\n" +  
51 - self.feed_items[0..(limit-1)].map{ |item| "<li><a href='#{item[:link]}'>#{item[:title]}</a></li>" }.join("\n") +  
52 - "</ul>" 50 + "<ul>\n".html_safe +
  51 + self.feed_items[0..(limit-1)].map{ |item| "<li><a href='#{item[:link]}'>#{item[:title]}</a></li>" }.join("\n").html_safe +
  52 + "</ul>".html_safe
53 else 53 else
54 - '<p>' + error_message + '</p>' 54 + "<p>#{error_message}</p>".html_safe
55 end 55 end
56 end 56 end
57 57
app/models/license.rb
1 class License < ActiveRecord::Base 1 class License < ActiveRecord::Base
  2 +
  3 + SEARCHABLE_FIELDS = {
  4 + :name => 10,
  5 + :url => 5,
  6 + }
  7 +
2 belongs_to :environment 8 belongs_to :environment
3 has_many :content, :class_name => 'Article', :foreign_key => 'license_id' 9 has_many :content, :class_name => 'Article', :foreign_key => 'license_id'
4 10
app/models/link_list_block.rb
@@ -80,7 +80,7 @@ class LinkListBlock &lt; Block @@ -80,7 +80,7 @@ class LinkListBlock &lt; Block
80 80
81 def icons_options 81 def icons_options
82 ICONS.map do |i| 82 ICONS.map do |i|
83 - "<span title=\"#{i[1]}\" class=\"icon-#{i[0]}\" onclick=\"changeIcon(this, '#{i[0]}')\"></span>" 83 + "<span title=\"#{i[1]}\" class=\"icon-#{i[0]}\" onclick=\"changeIcon(this, '#{i[0]}')\"></span>".html_safe
84 end 84 end
85 end 85 end
86 86
app/models/national_region.rb
1 class NationalRegion < ActiveRecord::Base 1 class NationalRegion < ActiveRecord::Base
2 2
  3 + SEARCHABLE_FIELDS = {
  4 + :name => 1,
  5 + :national_region_code => 1,
  6 + }
  7 +
3 def self.search_city(city_name, like = false, state = nil) 8 def self.search_city(city_name, like = false, state = nil)
4 9
5 operator = "=" 10 operator = "="
app/models/organization.rb
1 # Represents any organization of the system 1 # Represents any organization of the system
2 class Organization < Profile 2 class Organization < Profile
3 3
  4 + SEARCH_FILTERS += %w[
  5 + more_popular
  6 + more_active
  7 + ]
  8 +
4 settings_items :closed, :type => :boolean, :default => false 9 settings_items :closed, :type => :boolean, :default => false
5 def closed? 10 def closed?
6 closed 11 closed
app/models/organization_mailing.rb
@@ -5,7 +5,7 @@ class OrganizationMailing &lt; Mailing @@ -5,7 +5,7 @@ class OrganizationMailing &lt; Mailing
5 end 5 end
6 6
7 def recipients(offset=0, limit=100) 7 def recipients(offset=0, limit=100)
8 - source.members.all(:order => self.id, :offset => offset, :limit => limit, :joins => "LEFT OUTER JOIN mailing_sents m ON (m.mailing_id = #{id} AND m.person_id = profiles.id)", :conditions => { "m.person_id" => nil }) 8 + source.members.all(:order => :id, :offset => offset, :limit => limit, :joins => "LEFT OUTER JOIN mailing_sents m ON (m.mailing_id = #{id} AND m.person_id = profiles.id)", :conditions => { "m.person_id" => nil })
9 end 9 end
10 10
11 def each_recipient 11 def each_recipient
app/models/person.rb
1 # A person is the profile of an user holding all relationships with the rest of the system 1 # A person is the profile of an user holding all relationships with the rest of the system
2 class Person < Profile 2 class Person < Profile
3 3
  4 + SEARCH_FILTERS += %w[
  5 + more_popular
  6 + more_active
  7 + ]
  8 +
4 def self.type_name 9 def self.type_name
5 _('Person') 10 _('Person')
6 end 11 end
app/models/product.rb
1 class Product < ActiveRecord::Base 1 class Product < ActiveRecord::Base
2 2
  3 + SEARCHABLE_FIELDS = {
  4 + :name => 10,
  5 + :description => 1,
  6 + }
  7 +
  8 + SEARCH_FILTERS = %w[
  9 + more_recent
  10 + ]
  11 +
  12 + SEARCH_DISPLAYS = %w[map full]
  13 +
  14 + def self.default_search_display
  15 + 'full'
  16 + end
  17 +
3 belongs_to :enterprise 18 belongs_to :enterprise
4 has_one :region, :through => :enterprise 19 has_one :region, :through => :enterprise
5 validates_presence_of :enterprise 20 validates_presence_of :enterprise
@@ -173,7 +188,7 @@ class Product &lt; ActiveRecord::Base @@ -173,7 +188,7 @@ class Product &lt; ActiveRecord::Base
173 188
174 def price_described? 189 def price_described?
175 return false if price.blank? or price == 0 190 return false if price.blank? or price == 0
176 - (price - total_production_cost).zero? 191 + (price - total_production_cost.to_f).zero?
177 end 192 end
178 193
179 def update_price_details(price_details) 194 def update_price_details(price_details)
@@ -215,89 +230,6 @@ class Product &lt; ActiveRecord::Base @@ -215,89 +230,6 @@ class Product &lt; ActiveRecord::Base
215 end 230 end
216 end 231 end
217 232
218 - private  
219 - def f_category  
220 - self.product_category.name  
221 - end  
222 - def f_region  
223 - self.enterprise.region.id if self.enterprise.region  
224 - end  
225 - def self.f_region_proc(id)  
226 - c = Region.find(id)  
227 - s = c.parent  
228 - if c and c.kind_of?(City) and s and s.kind_of?(State) and s.acronym  
229 - [c.name, ', ' + s.acronym]  
230 - else  
231 - c.name  
232 - end  
233 - end  
234 - def self.f_qualifier_proc(ids)  
235 - array = ids.split  
236 - qualifier = Qualifier.find_by_id array[0]  
237 - certifier = Certifier.find_by_id array[1]  
238 - certifier ? [qualifier.name, _(' cert. ') + certifier.name] : qualifier.name  
239 - end  
240 - def f_qualifier  
241 - product_qualifiers.map do |pq|  
242 - "#{pq.qualifier_id} #{pq.certifier_id}"  
243 - end  
244 - end  
245 -  
246 - alias_method :name_sortable, :name  
247 delegate :enabled, :region, :region_id, :environment, :environment_id, :to => :enterprise 233 delegate :enabled, :region, :region_id, :environment, :environment_id, :to => :enterprise
248 - def name_sortable # give a different name for solr  
249 - name  
250 - end  
251 - def public  
252 - self.public?  
253 - end  
254 - def price_sortable  
255 - (price.nil? or price.zero?) ? nil : price  
256 - end  
257 - def category_filter  
258 - enterprise.categories_including_virtual_ids << product_category_id  
259 - end  
260 - public  
261 -  
262 - acts_as_faceted :fields => {  
263 - :f_category => {:label => _('Related products')},  
264 - :f_region => {:label => _('City'), :proc => proc { |id| f_region_proc(id) }},  
265 - :f_qualifier => {:label => _('Qualifiers'), :proc => proc { |id| f_qualifier_proc(id) }},  
266 - }, :category_query => proc { |c| "category_filter:#{c.id}" },  
267 - :order => [:f_category, :f_region, :f_qualifier]  
268 -  
269 - Boosts = [  
270 - [:image, 0.55, proc{ |p| p.image ? 1 : 0}],  
271 - [:qualifiers, 0.45, proc{ |p| p.product_qualifiers.count > 0 ? 1 : 0}],  
272 - [:open_price, 0.45, proc{ |p| p.price_described? ? 1 : 0}],  
273 - [:solidarity, 0.45, proc{ |p| p.percentage_from_solidarity_economy[0].to_f/100 }],  
274 - [:available, 0.35, proc{ |p| p.available ? 1 : 0}],  
275 - [:price, 0.35, proc{ |p| (!p.price.nil? and p.price > 0) ? 1 : 0}],  
276 - [:new_product, 0.35, proc{ |p| (p.updated_at.to_i - p.created_at.to_i) < 24*3600 ? 1 : 0}],  
277 - [:description, 0.3, proc{ |p| !p.description.blank? ? 1 : 0}],  
278 - [:enabled, 0.2, proc{ |p| p.enterprise.enabled ? 1 : 0}],  
279 - ]  
280 -  
281 - acts_as_searchable :fields => facets_fields_for_solr + [  
282 - # searched fields  
283 - {:name => {:type => :text, :boost => 2.0}},  
284 - {:description => :text}, {:category_full_name => :text},  
285 - # filtered fields  
286 - {:public => :boolean}, {:environment_id => :integer},  
287 - {:enabled => :boolean}, {:category_filter => :integer},  
288 - # ordered/query-boosted fields  
289 - {:price_sortable => :decimal}, {:name_sortable => :string},  
290 - {:lat => :float}, {:lng => :float},  
291 - :updated_at, :created_at,  
292 - ], :include => [  
293 - {:product_category => {:fields => [:name, :path, :slug, :lat, :lng, :acronym, :abbreviation]}},  
294 - {:region => {:fields => [:name, :path, :slug, :lat, :lng]}},  
295 - {:enterprise => {:fields => [:name, :identifier, :address, :nickname, :lat, :lng]}},  
296 - {:qualifiers => {:fields => [:name]}},  
297 - {:certifiers => {:fields => [:name]}},  
298 - ], :facets => facets_option_for_solr,  
299 - :boost => proc{ |p| boost = 1; Boosts.each{ |b| boost = boost * (1 - ((1 - b[2].call(p)) * b[1])) }; boost}  
300 - handle_asynchronously :solr_save  
301 - after_save_reindex [:enterprise], :with => :delayed_job  
302 234
303 end 235 end
app/models/product_category.rb
@@ -11,6 +11,4 @@ class ProductCategory &lt; Category @@ -11,6 +11,4 @@ class ProductCategory &lt; Category
11 top_category ? top_category.children : top_level_for(env).select{|c|c.kind_of?(ProductCategory)} 11 top_category ? top_category.children : top_level_for(env).select{|c|c.kind_of?(ProductCategory)}
12 end 12 end
13 13
14 - after_save_reindex [:products], :with => :delayed_job  
15 -  
16 end 14 end
app/models/profile.rb
@@ -3,10 +3,20 @@ @@ -3,10 +3,20 @@
3 # which by default is the one returned by Environment:default. 3 # which by default is the one returned by Environment:default.
4 class Profile < ActiveRecord::Base 4 class Profile < ActiveRecord::Base
5 5
6 - # use for internationalizable human type names in search facets  
7 - # reimplement on subclasses  
8 - def self.type_name  
9 - _('Profile') 6 + SEARCHABLE_FIELDS = {
  7 + :name => 10,
  8 + :identifier => 5,
  9 + :nickname => 2,
  10 + }
  11 +
  12 + SEARCH_FILTERS = %w[
  13 + more_recent
  14 + ]
  15 +
  16 + SEARCH_DISPLAYS = %w[compact]
  17 +
  18 + def self.default_search_display
  19 + 'compact'
10 end 20 end
11 21
12 module Roles 22 module Roles
@@ -68,7 +78,7 @@ class Profile &lt; ActiveRecord::Base @@ -68,7 +78,7 @@ class Profile &lt; ActiveRecord::Base
68 #FIXME: these will work only if the subclass is already loaded 78 #FIXME: these will work only if the subclass is already loaded
69 named_scope :enterprises, lambda { {:conditions => (Enterprise.send(:subclasses).map(&:name) << 'Enterprise').map { |klass| "profiles.type = '#{klass}'"}.join(" OR ")} } 79 named_scope :enterprises, lambda { {:conditions => (Enterprise.send(:subclasses).map(&:name) << 'Enterprise').map { |klass| "profiles.type = '#{klass}'"}.join(" OR ")} }
70 named_scope :communities, lambda { {:conditions => (Community.send(:subclasses).map(&:name) << 'Community').map { |klass| "profiles.type = '#{klass}'"}.join(" OR ")} } 80 named_scope :communities, lambda { {:conditions => (Community.send(:subclasses).map(&:name) << 'Community').map { |klass| "profiles.type = '#{klass}'"}.join(" OR ")} }
71 - named_scope :templates, :conditions => {:is_template => true} 81 + named_scope :templates, lambda { |environment| { :conditions => {:is_template => true, :environment_id => environment.id} } }
72 82
73 def members 83 def members
74 scopes = plugins.dispatch_scopes(:organization_members, self) 84 scopes = plugins.dispatch_scopes(:organization_members, self)
@@ -127,18 +137,6 @@ class Profile &lt; ActiveRecord::Base @@ -127,18 +137,6 @@ class Profile &lt; ActiveRecord::Base
127 scrap.nil? ? Scrap.all_scraps(self) : Scrap.all_scraps(self).find(scrap) 137 scrap.nil? ? Scrap.all_scraps(self) : Scrap.all_scraps(self).find(scrap)
128 end 138 end
129 139
130 - class_inheritable_accessor :extra_index_methods  
131 - self.extra_index_methods = []  
132 -  
133 - def extra_data_for_index  
134 - self.class.extra_index_methods.map { |meth| meth.to_proc.call(self) }.flatten  
135 - end  
136 -  
137 - def self.extra_data_for_index(sym = nil, &block)  
138 - self.extra_index_methods.push(sym) if sym  
139 - self.extra_index_methods.push(block) if block_given?  
140 - end  
141 -  
142 acts_as_having_settings :field => :data 140 acts_as_having_settings :field => :data
143 141
144 def settings 142 def settings
@@ -211,7 +209,7 @@ class Profile &lt; ActiveRecord::Base @@ -211,7 +209,7 @@ class Profile &lt; ActiveRecord::Base
211 has_many :profile_categorizations_including_virtual, :class_name => 'ProfileCategorization' 209 has_many :profile_categorizations_including_virtual, :class_name => 'ProfileCategorization'
212 has_many :categories_including_virtual, :through => :profile_categorizations_including_virtual, :source => :category 210 has_many :categories_including_virtual, :through => :profile_categorizations_including_virtual, :source => :category
213 211
214 - has_many :abuse_complaints, :foreign_key => 'requestor_id' 212 + has_many :abuse_complaints, :foreign_key => 'requestor_id', :dependent => :destroy
215 213
216 def top_level_categorization 214 def top_level_categorization
217 ret = {} 215 ret = {}
@@ -262,7 +260,6 @@ class Profile &lt; ActiveRecord::Base @@ -262,7 +260,6 @@ class Profile &lt; ActiveRecord::Base
262 else 260 else
263 ProfileCategorization.add_category_to_profile(c, self) 261 ProfileCategorization.add_category_to_profile(c, self)
264 self.categories(true) 262 self.categories(true)
265 - self.solr_save  
266 end 263 end
267 self.categories(reload) 264 self.categories(reload)
268 end 265 end
@@ -894,86 +891,6 @@ private :generate_url, :url_options @@ -894,86 +891,6 @@ private :generate_url, :url_options
894 self.active_fields 891 self.active_fields
895 end 892 end
896 893
897 - private  
898 - def self.f_categories_label_proc(environment)  
899 - ids = environment.top_level_category_as_facet_ids  
900 - r = Category.find(ids)  
901 - map = {}  
902 - ids.map{ |id| map[id.to_s] = r.detect{|c| c.id == id}.name }  
903 - map  
904 - end  
905 - def self.f_categories_proc(facet, id)  
906 - id = id.to_i  
907 - return if id.zero?  
908 - c = Category.find(id)  
909 - c.name if c.top_ancestor.id == facet[:label_id].to_i or facet[:label_id] == 0  
910 - end  
911 - def f_categories  
912 - category_ids - [region_id]  
913 - end  
914 -  
915 - def f_region  
916 - self.region_id  
917 - end  
918 - def self.f_region_proc(id)  
919 - c = Region.find(id)  
920 - s = c.parent  
921 - if c and c.kind_of?(City) and s and s.kind_of?(State) and s.acronym  
922 - [c.name, ', ' + s.acronym]  
923 - else  
924 - c.name  
925 - end  
926 - end  
927 -  
928 - def self.f_enabled_proc(enabled)  
929 - enabled = enabled == "true" ? true : false  
930 - enabled ? s_('facets|Enabled') : s_('facets|Not enabled')  
931 - end  
932 - def f_enabled  
933 - self.enabled  
934 - end  
935 -  
936 - def name_sortable # give a different name for solr  
937 - name  
938 - end  
939 - def public  
940 - self.public?  
941 - end  
942 - def category_filter  
943 - categories_including_virtual_ids  
944 - end  
945 - public  
946 -  
947 - acts_as_faceted :fields => {  
948 - :f_enabled => {:label => _('Situation'), :type_if => proc { |klass| klass.kind_of?(Enterprise) },  
949 - :proc => proc { |id| f_enabled_proc(id) }},  
950 - :f_region => {:label => _('City'), :proc => proc { |id| f_region_proc(id) }},  
951 - :f_categories => {:multi => true, :proc => proc {|facet, id| f_categories_proc(facet, id)},  
952 - :label => proc { |env| f_categories_label_proc(env) }, :label_abbrev => proc{ |env| f_categories_label_abbrev_proc(env) }},  
953 - }, :category_query => proc { |c| "category_filter:#{c.id}" },  
954 - :order => [:f_region, :f_categories, :f_enabled]  
955 -  
956 - acts_as_searchable :fields => facets_fields_for_solr + [:extra_data_for_index,  
957 - # searched fields  
958 - {:name => {:type => :text, :boost => 2.0}},  
959 - {:identifier => :text}, {:nickname => :text},  
960 - # filtered fields  
961 - {:public => :boolean}, {:environment_id => :integer},  
962 - {:category_filter => :integer},  
963 - # ordered/query-boosted fields  
964 - {:name_sortable => :string}, {:user_id => :integer},  
965 - :enabled, :active, :validated, :public_profile,  
966 - {:lat => :float}, {:lng => :float},  
967 - :updated_at, :created_at,  
968 - ],  
969 - :include => [  
970 - {:region => {:fields => [:name, :path, :slug, :lat, :lng]}},  
971 - {:categories => {:fields => [:name, :path, :slug, :lat, :lng, :acronym, :abbreviation]}},  
972 - ], :facets => facets_option_for_solr,  
973 - :boost => proc{ |p| 10 if p.enabled }  
974 - after_save_reindex [:articles], :with => :delayed_job  
975 - handle_asynchronously :solr_save  
976 -  
977 def control_panel_settings_button 894 def control_panel_settings_button
978 {:title => _('Profile Info and settings'), :icon => 'edit-profile'} 895 {:title => _('Profile Info and settings'), :icon => 'edit-profile'}
979 end 896 end
app/models/profile_list_block.rb
@@ -49,13 +49,12 @@ class ProfileListBlock &lt; Block @@ -49,13 +49,12 @@ class ProfileListBlock &lt; Block
49 send(:profile_image_link, item, :minor ) 49 send(:profile_image_link, item, :minor )
50 }.join("\n ") 50 }.join("\n ")
51 if list.empty? 51 if list.empty?
52 - list = '<div class="common-profile-list-block-none">'+ _('None') +'</div>' 52 + list = content_tag 'div', _('None'), :class => 'common-profile-list-block-none'
53 else 53 else
54 list = content_tag 'ul', nl +' '+ list + nl 54 list = content_tag 'ul', nl +' '+ list + nl
55 end 55 end
56 block_title(title) + nl + 56 block_title(title) + nl +
57 - '<div class="common-profile-list-block">' +  
58 - nl + list + nl + '<br style="clear:both" /></div>' 57 + content_tag('div', nl + list + nl + content_tag('br', '', :style => 'clear:both'))
59 end 58 end
60 end 59 end
61 60
app/models/qualifier.rb
1 class Qualifier < ActiveRecord::Base 1 class Qualifier < ActiveRecord::Base
2 2
  3 + SEARCHABLE_FIELDS = {
  4 + :name => 1,
  5 + }
  6 +
3 belongs_to :environment 7 belongs_to :environment
4 8
5 has_many :qualifier_certifiers, :dependent => :destroy 9 has_many :qualifier_certifiers, :dependent => :destroy
@@ -15,6 +19,4 @@ class Qualifier &lt; ActiveRecord::Base @@ -15,6 +19,4 @@ class Qualifier &lt; ActiveRecord::Base
15 self.name.downcase.transliterate <=> b.name.downcase.transliterate 19 self.name.downcase.transliterate <=> b.name.downcase.transliterate
16 end 20 end
17 21
18 - after_save_reindex [:products], :with => :delayed_job  
19 -  
20 end 22 end
app/models/raw_html_block.rb
@@ -7,7 +7,7 @@ class RawHTMLBlock &lt; Block @@ -7,7 +7,7 @@ class RawHTMLBlock &lt; Block
7 settings_items :html, :type => :text 7 settings_items :html, :type => :text
8 8
9 def content(args={}) 9 def content(args={})
10 - (title.blank? ? '' : block_title(title)) + html.to_s 10 + (title.blank? ? '' : block_title(title)).html_safe + html.to_s.html_safe
11 end 11 end
12 12
13 end 13 end
app/models/region.rb
@@ -4,12 +4,6 @@ class Region &lt; Category @@ -4,12 +4,6 @@ class Region &lt; Category
4 4
5 require_dependency 'enterprise' # enterprises can also be validators 5 require_dependency 'enterprise' # enterprises can also be validators
6 6
7 - # searches for organizations that could become validators for this region.  
8 - # <tt>search</tt> is passed as is to find_by_contents on Organization.  
9 - def search_possible_validators(search)  
10 - Organization.find_by_contents(search)[:results].docs.reject {|item| self.validator_ids.include?(item.id) }  
11 - end  
12 -  
13 def has_validator? 7 def has_validator?
14 validators.count > 0 8 validators.count > 0
15 end 9 end
app/models/scrap.rb
1 class Scrap < ActiveRecord::Base 1 class Scrap < ActiveRecord::Base
  2 + SEARCHABLE_FIELDS = {
  3 + :content => 1,
  4 + }
2 validates_presence_of :content 5 validates_presence_of :content
3 validates_presence_of :sender_id, :receiver_id 6 validates_presence_of :sender_id, :receiver_id
4 7
app/models/spammer_logger.rb
@@ -5,10 +5,10 @@ class SpammerLogger &lt; Logger @@ -5,10 +5,10 @@ class SpammerLogger &lt; Logger
5 def self.log(spammer_ip, object=nil) 5 def self.log(spammer_ip, object=nil)
6 if object 6 if object
7 if object.kind_of?(Comment) 7 if object.kind_of?(Comment)
8 - @logger << "[#{Time.now.strftime("%F %T %z")}] Comment-id: #{object.id} IP: #{spammer_ip}\n" 8 + @logger << "[#{Time.now.strftime('%F %T %z')}] Comment-id: #{object.id} IP: #{spammer_ip}\n"
9 end 9 end
10 else 10 else
11 - @logger << "[#{Time.now.strftime("%F %T %z")}] IP: #{spammer_ip}\n" 11 + @logger << "[#{Time.now.strftime('%F %T %z')}] IP: #{spammer_ip}\n"
12 end 12 end
13 end 13 end
14 14
app/models/tags_block.rb
@@ -20,7 +20,8 @@ class TagsBlock &lt; Block @@ -20,7 +20,8 @@ class TagsBlock &lt; Block
20 end 20 end
21 21
22 def content(args={}) 22 def content(args={})
23 - tags = owner.article_tags 23 + is_env = owner.class == Environment
  24 + tags = is_env ? owner.tag_counts : owner.article_tags
24 return '' if tags.empty? 25 return '' if tags.empty?
25 26
26 if limit 27 if limit
@@ -29,18 +30,28 @@ class TagsBlock &lt; Block @@ -29,18 +30,28 @@ class TagsBlock &lt; Block
29 tags_tmp.map{ |k,v| tags[k] = v } 30 tags_tmp.map{ |k,v| tags[k] = v }
30 end 31 end
31 32
  33 + url = is_env ? {:host=>owner.default_hostname, :controller=>'search', :action => 'tag'} :
  34 + owner.public_profile_url.merge(:controller => 'profile', :action => 'tags')
  35 + tagname_option = is_env ? :tag : :id
  36 +
32 block_title(title) + 37 block_title(title) +
33 - "\n<div class='tag_cloud'>\n"+  
34 - tag_cloud( tags, :id,  
35 - owner.public_profile_url.merge(:controller => 'profile', :action => 'tags'),  
36 - :max_size => 16, :min_size => 9 ) +  
37 - "\n</div><!-- end class='tag_cloud' -->\n"; 38 + "\n<div class='tag_cloud'>\n".html_safe+
  39 + tag_cloud( tags, tagname_option, url, :max_size => 16, :min_size => 9 ) +
  40 + "\n</div><!-- end class='tag_cloud' -->\n".html_safe
38 end 41 end
39 42
40 def footer 43 def footer
41 - owner_id = owner.identifier  
42 - lambda do  
43 - link_to s_('tags|View all'), :profile => owner_id, :controller => 'profile', :action => 'tags' 44 + if owner.class == Environment
  45 + lambda do
  46 + link_to s_('tags|View all'),
  47 + :controller => 'search', :action => 'tags'
  48 + end
  49 + else
  50 + owner_id = owner.identifier
  51 + lambda do
  52 + link_to s_('tags|View all'),
  53 + :profile => owner_id, :controller => 'profile', :action => 'tags'
  54 + end
44 end 55 end
45 end 56 end
46 57
app/models/uploaded_file.rb
@@ -113,7 +113,7 @@ class UploadedFile &lt; Article @@ -113,7 +113,7 @@ class UploadedFile &lt; Article
113 113
114 content_tag( 114 content_tag(
115 'div', 115 'div',
116 - link_to_previous + content_tag('span', _('image %d of %d'), :class => 'total-of-images') % [current_index + 1, total_of_images] + link_to_next, 116 + link_to_previous + (content_tag('span', _('image %d of %d'), :class => 'total-of-images') % [current_index + 1, total_of_images]).html_safe + link_to_next,
117 :class => 'gallery-navigation' 117 :class => 'gallery-navigation'
118 ) 118 )
119 end.to_s + 119 end.to_s +
app/models/user.rb
@@ -15,7 +15,7 @@ class User &lt; ActiveRecord::Base @@ -15,7 +15,7 @@ class User &lt; ActiveRecord::Base
15 # FIXME ugly workaround 15 # FIXME ugly workaround
16 def self.human_attribute_name(attrib) 16 def self.human_attribute_name(attrib)
17 case attrib.to_sym 17 case attrib.to_sym
18 - when :login: return _('Username') 18 + when :login: return [_('Username'), _('Email')].join(' / ')
19 when :email: return _('e-Mail') 19 when :email: return _('e-Mail')
20 else _(self.superclass.human_attribute_name(attrib)) 20 else _(self.superclass.human_attribute_name(attrib))
21 end 21 end
@@ -116,10 +116,11 @@ class User &lt; ActiveRecord::Base @@ -116,10 +116,11 @@ class User &lt; ActiveRecord::Base
116 116
117 validates_inclusion_of :terms_accepted, :in => [ '1' ], :if => lambda { |u| ! u.terms_of_use.blank? }, :message => N_('%{fn} must be checked in order to signup.').fix_i18n 117 validates_inclusion_of :terms_accepted, :in => [ '1' ], :if => lambda { |u| ! u.terms_of_use.blank? }, :message => N_('%{fn} must be checked in order to signup.').fix_i18n
118 118
119 - # Authenticates a user by their login name and unencrypted password. Returns the user or nil. 119 + # Authenticates a user by their login name or email and unencrypted password. Returns the user or nil.
120 def self.authenticate(login, password, environment = nil) 120 def self.authenticate(login, password, environment = nil)
121 environment ||= Environment.default 121 environment ||= Environment.default
122 - u = first :conditions => ['login = ? AND environment_id = ? AND activated_at IS NOT NULL', login, environment.id] # need to get the salt 122 + u = self.first :conditions => ['(login = ? OR email = ?) AND environment_id = ? AND activated_at IS NOT NULL',
  123 + login, login, environment.id] # need to get the salt
123 u && u.authenticated?(password) ? u : nil 124 u && u.authenticated?(password) ? u : nil
124 end 125 end
125 126
@@ -293,7 +294,8 @@ class User &lt; ActiveRecord::Base @@ -293,7 +294,8 @@ class User &lt; ActiveRecord::Base
293 'email_domain' => self.enable_email ? self.email_domain : nil, 294 'email_domain' => self.enable_email ? self.email_domain : nil,
294 'friends_list' => friends_list, 295 'friends_list' => friends_list,
295 'enterprises' => enterprises, 296 'enterprises' => enterprises,
296 - 'amount_of_friends' => friends_list.count 297 + 'amount_of_friends' => friends_list.count,
  298 + 'chat_enabled' => person.environment.enabled?('xmpp_chat')
297 } 299 }
298 end 300 end
299 301
app/views/account/_signup_form.rhtml
@@ -32,7 +32,8 @@ @@ -32,7 +32,8 @@
32 <span id="signup-domain"><%= environment.default_hostname %>/</span> 32 <span id="signup-domain"><%= environment.default_hostname %>/</span>
33 <div id='signup-login'> 33 <div id='signup-login'>
34 <div id='signup-login-field' class='formfield'> 34 <div id='signup-login-field' class='formfield'>
35 - <%= required text_field(:user, :login, :id => 'user_login', :onchange => 'this.value = convToValidLogin(this.value);') %> 35 + <%= required text_field(:user, :login, :id => 'user_login',
  36 + :onchange => 'this.value = convToValidUsername(this.value);') %>
36 <div id='url-check'><p>&nbsp;</p></div> 37 <div id='url-check'><p>&nbsp;</p></div>
37 </div> 38 </div>
38 <%= content_tag(:small, _('Choose your login name carefully! It will be your network access and you will not be able to change it later.'), :id => 'signup-balloon') %> 39 <%= content_tag(:small, _('Choose your login name carefully! It will be your network access and you will not be able to change it later.'), :id => 'signup-balloon') %>
app/views/account/forgot_password.rhtml
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <% labelled_form_for :change_password, @change_password, :url => { :action => 'forgot_password' } do |f| %> 5 <% labelled_form_for :change_password, @change_password, :url => { :action => 'forgot_password' } do |f| %>
6 6
7 <%= f.text_field :login, 7 <%= f.text_field :login,
8 - :onchange => 'this.value = convToValidLogin( this.value )' %> 8 + :onchange => 'this.value = convToValidUsername( this.value )' %>
9 9
10 <%= f.text_field :email %> 10 <%= f.text_field :email %>
11 11
app/views/admin_panel/site_info.rhtml
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 4
5 <%= render :file => 'shared/tiny_mce' %> 5 <%= render :file => 'shared/tiny_mce' %>
6 6
7 -<% labelled_form_for :environment, @environment, :url => {:host => @environment.default_hostname, :port => request.port} do |f| %> 7 +<% labelled_form_for :environment, @environment do |f| %>
8 <% tabs = [] %> 8 <% tabs = [] %>
9 <% tabs << {:title => _('Site info'), :id => 'site-info', 9 <% tabs << {:title => _('Site info'), :id => 'site-info',
10 :content => (render :partial => 'site_info', :locals => {:f => f})} %> 10 :content => (render :partial => 'site_info', :locals => {:f => f})} %>
app/views/box_organizer/_article_block.rhtml
1 -<div class='article-block-edition'> 1 +<div class="article-block-edition">
2 <% if @block.box.owner.kind_of?(Environment) and @block.box.owner.portal_community.nil? %> 2 <% if @block.box.owner.kind_of?(Environment) and @block.box.owner.portal_community.nil? %>
3 - <p id='no_portal_community'> 3 + <p id="no_portal_community">
4 <%= _("You don't have an community defined as the portal community. Define it before use this block properly.") %> 4 <%= _("You don't have an community defined as the portal community. Define it before use this block properly.") %>
5 </p> 5 </p>
6 <% else %> 6 <% else %>
7 - <% articles = @block.available_articles.select {|article| !article.folder? } %>  
8 - <%= select_tag('block[article_id]', options_for_select_with_title(articles.map {|item| [item.path, item.id]}, @block.article ? @block.article.id : nil)) %> 7 + <%
  8 + articles = @block.available_articles.select {|a| !a.folder? || a.blog? }
  9 + first_text = articles[articles.find_index{|a| a.kind_of? TextArticle}||-1]
  10 + selected = @block.article || first_text
  11 + %>
  12 + <%= select_tag(
  13 + 'block[article_id]',
  14 + options_for_select_with_title(articles.map {|item| [item.path, item.id]}, selected.id),
  15 + :onchange => 'this.changedTo(this.value)'
  16 + )%>
  17 + <div id="block_blog_options" style="display:none">
  18 + <%= labelled_form_field(
  19 + _('Number of posts:'),
  20 + text_field_tag('block[posts_per_page]', @block.posts_per_page)
  21 + )%>
  22 + </div>
  23 + <%= labelled_form_field(
  24 + _('How to display this content:'),
  25 + select_tag(
  26 + 'block[visualization_format]',
  27 + options_for_select([[_('Lead'), 'short'], [_('Full post'), 'full']], @block.visualization_format)
  28 + )
  29 + )%>
  30 + <% blogs = @block.available_articles.select{|a|a.blog?} %>
  31 + <script>
  32 + var select = jQuery("#block_article_id")[0];
  33 + select.blogs = <%= blogs.map{|b| b.id.to_s }.to_json %>;
  34 + select.changedTo = function(articleId) {
  35 + var blogSelected = this.blogs.indexOf(articleId) != -1;
  36 + jQuery("#block_blog_options").toggle(blogSelected);
  37 + }
  38 + select.changedTo('<%= selected.id %>');
  39 + </script>
9 <% end %> 40 <% end %>
10 </div> 41 </div>
app/views/box_organizer/_block_types.rhtml
@@ -1,10 +0,0 @@ @@ -1,10 +0,0 @@
1 -<% block_types.in_groups_of(2) do |block1, block2| %>  
2 - <div style='float: left; width: 48%; padding-top: 2px;'>  
3 - <%= labelled_radio_button(block1.description, :type, block1.name) %>  
4 - </div>  
5 - <% if block2 %>  
6 - <div style='float: left; width: 48%; padding-top: 2px;'>  
7 - <%= labelled_radio_button(block2.description, :type, block2.name) %>  
8 - </div>  
9 - <% end %>  
10 -<% end %>  
app/views/box_organizer/_highlights_block.rhtml
1 <strong><%= _('Highlights') %></strong> 1 <strong><%= _('Highlights') %></strong>
2 -<div id='edit-highlights-block' style='width:450px'>  
3 -<table id='highlights' class='noborder'>  
4 - <tr><th><%= _('Image') %></th><th><%= _('Address') %></th><th><%= _('Position') %></th><th><%= _('Title') %></th></tr> 2 +
  3 +<table class="noborder"><tbody id="highlights-data-table">
  4 + <tr><th><%= _('Image') %></th><th><%= _('Address') %></th><th><%= _('Position') %></th></tr>
5 <% for image in @block.images do %> 5 <% for image in @block.images do %>
6 - <tr>  
7 - <td>  
8 - <%= select_tag 'block[images][][image_id]', content_tag(:option) + option_groups_from_collection_for_select(@block.folder_choices, :images, :name, :id, :name, image[:image_id].to_i), :style => "width: 100px" %></p>  
9 - </td>  
10 - <td><%= text_field_tag 'block[images][][address]', image[:address], :class => 'highlight-address', :size => 10 %></td>  
11 - <td><%= text_field_tag 'block[images][][position]', image[:position], :class => 'highlight-position', :size => 3 %></td>  
12 - <td><%= text_field_tag 'block[images][][title]', image[:title], :class => 'highlight-title', :size => 10 %></td>  
13 - </tr> 6 + <%= highlights_block_config_image_fields @block, image %>
14 <% end %> 7 <% end %>
15 -</table>  
16 -</div> 8 +</tbody></table>
17 9
18 <%= link_to_function(_('New highlight'), nil, :class => 'button icon-add with-text') do |page| 10 <%= link_to_function(_('New highlight'), nil, :class => 'button icon-add with-text') do |page|
19 - page.insert_html :bottom, 'highlights', content_tag('tr',  
20 - content_tag('td', select_tag('block[images][][image_id]', content_tag(:option) + option_groups_from_collection_for_select(@block.folder_choices, :images, :name, :id, :name), :style => "width: 100px")) +  
21 - content_tag('td', text_field_tag('block[images][][address]', nil, :class => 'highlight-address', :size => 10)) +  
22 - content_tag('td', text_field_tag('block[images][][position]', nil, :class => 'highlight-position', :size => 3)) +  
23 - content_tag('td', text_field_tag('block[images][][title]', nil, :class => 'highlight-position', :size => 10))  
24 - ) +  
25 - javascript_tag("$('edit-link-list-block').scrollTop = $('edit-link-list-block').scrollHeight") 11 + page.insert_html :bottom, 'highlights-data-table', highlights_block_config_image_fields(@block)
26 end %> 12 end %>
27 13
28 <%= labelled_form_field _('Image transition:'), select('block', 'interval', [[_('No automatic transition'), 0]] + [1, 2, 3, 4, 5, 10, 20, 30, 60].map {|item| [n_('Every 1 second', 'Every %d seconds', item) % item, item]}) %> 14 <%= labelled_form_field _('Image transition:'), select('block', 'interval', [[_('No automatic transition'), 0]] + [1, 2, 3, 4, 5, 10, 20, 30, 60].map {|item| [n_('Every 1 second', 'Every %d seconds', item) % item, item]}) %>
app/views/box_organizer/add_block.rhtml
1 -<div style='height:350px'> 1 +<div id="add-block-dialog">
2 <% form_tag do %> 2 <% form_tag do %>
3 3
4 <p><%= _('In what area do you want to put your new block?') %></p> 4 <p><%= _('In what area do you want to put your new block?') %></p>
5 5
  6 + <div id="box-position">
6 <% @boxes.each do |box| %> 7 <% @boxes.each do |box| %>
7 - <%= labelled_radio_button(_("Area %d") % box.position, :box_id, box.id, box.central?, { :class => 'box-position', 'data-position' => box.position }) %> 8 + <% name = box.central? ? _('Main area') : _('Area %d') % box.position %>
  9 + <%= labelled_radio_button(name, :box_id, box.id, box.central?, { 'data-position' => box.position }) %>
8 <% end %> 10 <% end %>
  11 + </div>
9 12
10 <script type="text/javascript"> 13 <script type="text/javascript">
11 - (function ($) {  
12 - $(document).ready(function () {  
13 - $(".box-position").live('change', function () {  
14 - if ($(this).attr('data-position') == '1') {  
15 - $('#center-block-types').show();  
16 - $('#side-block-types').hide();  
17 - } else {  
18 - $('#center-block-types').hide();  
19 - $('#side-block-types').show();  
20 - };  
21 - });  
22 - })})(jQuery); 14 + jQuery('#box-position input').bind('change',
  15 + function () {
  16 + showCenter = jQuery(this).attr('data-position') == '1';
  17 + jQuery('#center-block-types').toggle(showCenter);
  18 + jQuery('#side-block-types').toggle(!showCenter);
  19 + }
  20 + );
23 </script> 21 </script>
24 22
25 <p><%= _('Select the type of block you want to add to your page.') %></p> 23 <p><%= _('Select the type of block you want to add to your page.') %></p>
26 24
27 - <div id='center-block-types'>  
28 - <%= render :partial => 'block_types', :locals => { :block_types => @center_block_types } %> 25 + <div id="center-block-types" class="block-types">
  26 + <% @center_block_types.each do |block| %>
  27 + <div class='block-type'>
  28 + <%= labelled_radio_button(block.description, :type, block.name) %>
  29 + </div>
  30 + <% end %>
29 </div> 31 </div>
30 32
31 - <div id='side-block-types' style='display:none'>  
32 - <%= render :partial => 'block_types', :locals => { :block_types => @side_block_types } %> 33 + <div id="side-block-types" class="block-types" style="display:none">
  34 + <% @side_block_types.each do |block| %>
  35 + <div class='block-type'>
  36 + <%= labelled_radio_button(block.description, :type, block.name) %>
  37 + </div>
  38 + <% end %>
33 </div> 39 </div>
34 40
35 <br style='clear: both'/> 41 <br style='clear: both'/>
app/views/box_organizer/edit.rhtml
1 -<div style='width: 500px;'>  
2 - <h2><%= _('Editing block') %></h2> 1 +<div class="block-config-options <%= @block.class.name %>-options">
  2 + <h2 class="title"><%= _('Editing block') %></h2>
3 3
4 <% form_tag(:action => 'save', :id => @block.id) do %> 4 <% form_tag(:action => 'save', :id => @block.id) do %>
5 5
app/views/box_organizer/index.rhtml
1 <h1><%= _('Editing sideboxes')%></h1> 1 <h1><%= _('Editing sideboxes')%></h1>
2 2
3 -<% button_bar do %> 3 +<% button_bar :class=>'design-menu' do %>
4 <%= colorbox_button('add', _('Add a block'), { :action => 'add_block' }) %> 4 <%= colorbox_button('add', _('Add a block'), { :action => 'add_block' }) %>
5 <%= button(:back, _('Back to control panel'), :controller => (profile.nil? ? 'admin_panel': 'profile_editor')) %> 5 <%= button(:back, _('Back to control panel'), :controller => (profile.nil? ? 'admin_panel': 'profile_editor')) %>
6 <% end %> 6 <% end %>
app/views/catalog/index.rhtml
@@ -7,13 +7,17 @@ @@ -7,13 +7,17 @@
7 7
8 <div class='l-sidebar-left-bar'> 8 <div class='l-sidebar-left-bar'>
9 <ul> 9 <ul>
10 - <% if @categories.size > 0 %> 10 + <%= content_tag('li', link_to(_('Homepage'), profile.url), :class => 'catalog-categories-link') %>
  11 + <%= content_tag('li', link_to(_('Catalog start'), profile.catalog_url), :class => 'catalog-categories-link') %>
  12 + <% if @categories.present? %>
11 <% @categories.each do |category| %> 13 <% @categories.each do |category| %>
12 <%= category_link(category) %> 14 <%= category_link(category) %>
13 <%= category_sub_links(category) %> 15 <%= category_sub_links(category) %>
14 <% end %> 16 <% end %>
  17 + <% elsif @category.present? %>
  18 + <%= content_tag('li', _('There are no sub-categories for %s') % @category.name, :id => 'catalog-categories-notice') %>
15 <% else %> 19 <% else %>
16 - <%= content_tag('li', _('There are no sub-categories for %s') % @category.name, :style => 'color: #555753; padding-bottom: 0.5em;') %> 20 + <%= content_tag('li', _('There are no categories available.'), :id => 'catalog-categories-notice') %>
17 <% end %> 21 <% end %>
18 </ul> 22 </ul>
19 </div> 23 </div>
@@ -64,20 +68,20 @@ @@ -64,20 +68,20 @@
64 68
65 <% if product.description %> 69 <% if product.description %>
66 <li class="product-description expand-box"> 70 <li class="product-description expand-box">
67 - <span id="product-description-button"><%= _('description') %></span>  
68 - <div> 71 + <span class="product-description-button"><%= _('description') %></span>
  72 + <div class="float-box">
69 <div class="arrow"></div> 73 <div class="arrow"></div>
70 - <div class="content" id="product-description"><%= txt2html(product.description || '') %></div> 74 + <div class="content"><%= product.description %></div>
71 </div> 75 </div>
72 </li> 76 </li>
73 <% end %> 77 <% end %>
74 78
75 <% if product.price_described? %> 79 <% if product.price_described? %>
76 <li class="product-price-composition expand-box"> 80 <li class="product-price-composition expand-box">
77 - <span id="product-price-composition-button"><%= _('price composition') %></span>  
78 - <div> 81 + <span class="product-price-composition-button"><%= _('price composition') %></span>
  82 + <div class="float-box">
79 <div class="arrow"></div> 83 <div class="arrow"></div>
80 - <div class="content" id="product-price-composition"> 84 + <div class="content">
81 <% product.inputs.relevant_to_price.each do |i| %> 85 <% product.inputs.relevant_to_price.each do |i| %>
82 <div class="search-product-input-dots-to-price"> 86 <div class="search-product-input-dots-to-price">
83 <div class="search-product-input-name"><%= i.product_category.name %></div> 87 <div class="search-product-input-name"><%= i.product_category.name %></div>
@@ -98,9 +102,9 @@ @@ -98,9 +102,9 @@
98 <% if product.inputs.count > 0 %> 102 <% if product.inputs.count > 0 %>
99 <li class="product-inputs expand-box"> 103 <li class="product-inputs expand-box">
100 <span id="inputs-button"><%= _('inputs and raw materials') %></span> 104 <span id="inputs-button"><%= _('inputs and raw materials') %></span>
101 - <div> 105 + <div class="float-box">
102 <div class="arrow"></div> 106 <div class="arrow"></div>
103 - <div class="content" id="inputs-description"> 107 + <div class="content">
104 <% product.inputs.each do |i| %> 108 <% product.inputs.each do |i| %>
105 <div> 109 <div>
106 <%= _('%{amount_used} %{unit} of') % {:amount_used => i.amount_used, :unit => i.unit.singular} + ' ' if i.has_all_price_details? %> 110 <%= _('%{amount_used} %{unit} of') % {:amount_used => i.amount_used, :unit => i.unit.singular} + ' ' if i.has_all_price_details? %>
app/views/cms/_text_editor_sidebar.rhtml
@@ -9,7 +9,12 @@ @@ -9,7 +9,12 @@
9 <div id='media-upload-form'> 9 <div id='media-upload-form'>
10 <% form_tag({ :action => 'media_upload' }, :multipart => true) do %> 10 <% form_tag({ :action => 'media_upload' }, :multipart => true) do %>
11 <div class='formfield'> 11 <div class='formfield'>
12 - <%= select_profile_folder(_('Choose folder to upload files:'), :parent_id, profile) %> 12 + <% default_folder = content_id_to_str default_folder_for_image_upload(profile) %>
  13 + <%= select_profile_folder(
  14 + _('Choose folder to upload files:'),
  15 + :parent_id, profile, default_folder, {}, {},
  16 + "type='Folder' or type='Gallery'"
  17 + ) %>
13 </div> 18 </div>
14 <p><%= file_field_tag('file1') %></p> 19 <p><%= file_field_tag('file1') %></p>
15 <p><%= file_field_tag('file2') %></p> 20 <p><%= file_field_tag('file2') %></p>
app/views/cms/select_article_type.rhtml
  1 +<div class="select-article-type">
  2 +
1 <h2> <%= _('Choose the type of content:') %> </h2> 3 <h2> <%= _('Choose the type of content:') %> </h2>
2 4
3 -<ul id="article_types"> 5 +<ul class="article-types">
4 <% for type in @article_types %> 6 <% for type in @article_types %>
5 <% action = type[:class].name == 'UploadedFile' ? {:action => 'upload_files'} : {:action => 'new', :type => type[:class].name} %> 7 <% action = type[:class].name == 'UploadedFile' ? {:action => 'upload_files'} : {:action => 'new', :type => type[:class].name} %>
6 <% content_tag('a', :href => url_for(action.merge(:parent_id => @parent_id, :back_to => @back_to))) do %> 8 <% content_tag('a', :href => url_for(action.merge(:parent_id => @parent_id, :back_to => @back_to))) do %>
@@ -14,3 +16,5 @@ @@ -14,3 +16,5 @@
14 <br style="clear:both" /> 16 <br style="clear:both" />
15 17
16 <%= colorbox_close_button(_('Cancel')) %> 18 <%= colorbox_close_button(_('Cancel')) %>
  19 +
  20 +</div>
app/views/content_viewer/blog_page.rhtml
1 -<% add_rss_feed_to_head(@page.name, @page.feed.url) if @page.blog? && @page.feed %> 1 +<% add_rss_feed_to_head(blog.name, blog.feed.url) if blog.blog? && blog.feed %>
2 2
3 -<%= content_tag('em', _('(external feed was not loaded yet)'), :id => 'external-feed-info', :class => 'metadata') if @page.blog? && @page.external_feed && @page.external_feed.enabled && @page.external_feed.fetched_at.nil? %> 3 +<%= content_tag('em', _('(external feed was not loaded yet)'), :id => 'external-feed-info', :class => 'metadata') if blog.blog? && blog.external_feed && blog.external_feed.enabled && blog.external_feed.fetched_at.nil? %>
4 4
5 <div> 5 <div>
6 <div class='blog-description'> 6 <div class='blog-description'>
7 - <%= @page.body %> 7 + <%= blog.body %>
8 </div> 8 </div>
9 </div> 9 </div>
10 <hr class="pre-posts"/> 10 <hr class="pre-posts"/>
11 <div class="blog-posts"> 11 <div class="blog-posts">
12 - <%= (@page.empty? ? content_tag('em', _('(no posts)')) : list_posts(@posts, @page.visualization_format)) %> 12 + <%=
  13 + posts = @posts
  14 + format = blog.visualization_format
  15 + if inside_block
  16 + posts = blog.posts.paginate(:page=>1, :per_page=>inside_block.posts_per_page)
  17 + format = inside_block.visualization_format
  18 + end
  19 + (blog.empty? ? content_tag('em', _('(no posts)')) : list_posts(posts, format))
  20 + %>
13 </div> 21 </div>
app/views/content_viewer/view_page.rhtml
@@ -66,7 +66,6 @@ @@ -66,7 +66,6 @@
66 addthis_options = '<%= escape_javascript( NOOSFERO_CONF['addthis_options'] ) %>'; 66 addthis_options = '<%= escape_javascript( NOOSFERO_CONF['addthis_options'] ) %>';
67 </script> 67 </script>
68 <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> 68 <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>
69 -<script type="text/javascript" src="http://s7.addthis.com/js/152/addthis_widget.js"></script>  
70 </div> 69 </div>
71 <% end %> 70 <% end %>
72 71
@@ -96,7 +95,7 @@ @@ -96,7 +95,7 @@
96 <% end %> 95 <% end %>
97 96
98 <% if @page.accept_comments? && @comments_count > 1 %> 97 <% if @page.accept_comments? && @comments_count > 1 %>
99 - <p class="post-comment-button"><a href="#comment_form" onclick="jQuery('#page-comment-form h4').first().trigger('click')"><%= _('Post a comment') %></a></p> 98 + <%= link_to(_('Post a comment'), '#', :class => 'display-comment-form', :id => 'top-post-comment-button') %>
100 <% end %> 99 <% end %>
101 100
102 <ul class="article-comments-list"> 101 <ul class="article-comments-list">
app/views/favorite_enterprises/index.rhtml
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <ul class="profile-list"> 5 <ul class="profile-list">
6 <% @favorite_enterprises.each do |enterprise| %> 6 <% @favorite_enterprises.each do |enterprise| %>
7 <li> 7 <li>
8 - <%= link_to_profile profile_image(enterprise) + '<br/>' + enterprise.name, 8 + <%= link_to_profile profile_image(enterprise) + '<br/>'.html_safe + enterprise.name,
9 enterprise.identifier, :class => 'profile-link' %> 9 enterprise.identifier, :class => 'profile-link' %>
10 <%# profile_image_link enterprise, :portrait, 'div' %> 10 <%# profile_image_link enterprise, :portrait, 'div' %>
11 <div class="controll"> 11 <div class="controll">
app/views/layouts/_user.html.erb 0 → 100644
@@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
  1 +<div id="user">
  2 + <span class='logged-in' style='display: none;'>
  3 + <%= usermenu_logged_in %>
  4 + </span>
  5 + <span class='not-logged-in' style='display: none'>
  6 +
  7 + <%= _("<span class='login'>%s</span>") % thickbox_inline_popup_link('<i class="icon-menu-login"></i><strong>' + _('Login') + '</strong>', login_url, 'inlineLoginBox', :id => 'link_login') %>
  8 + <%= @plugins.dispatch(:alternative_authentication_link).collect { |content| instance_eval(&content) }.join("") %>
  9 +
  10 + <div id='inlineLoginBox' style='display: none;'>
  11 + <%= render :file => 'account/login', :locals => { :is_thickbox => true } %>
  12 + </div>
  13 +
  14 + <% unless @plugins.dispatch(:allow_user_registration).include?(false) %>
  15 + <%= _("<span class='or'>or</span> <span class='signup'>%s</span>") % link_to('<strong>' + _('Sign up') + '</strong>', :controller => 'account', :action => 'signup')%>
  16 + <% end %>
  17 +
  18 + </span>
  19 + <form action="/search" id="top-search" class="search_form clean" method="get">
  20 + <input name="query" size="15" title="<%=_('Search...')%>" onfocus="this.form.className='focused';" onblur="this.form.className=''" />
  21 + <div><%=_('Press <strong>Enter</strong> to send the search query.')%></div>
  22 + <%= javascript_tag 'jQuery("#user form input").hint();' %>
  23 + </form>
  24 +</div><!-- end id="user" -->
app/views/layouts/application-ng.rhtml
@@ -8,23 +8,10 @@ @@ -8,23 +8,10 @@
8 <meta name="description" content="<%= @environment.name %>" /> 8 <meta name="description" content="<%= @environment.name %>" />
9 <link rel="shortcut icon" href="<%= image_path(theme_favicon) %>" type="image/x-icon" /> 9 <link rel="shortcut icon" href="<%= image_path(theme_favicon) %>" type="image/x-icon" />
10 <%= noosfero_javascript %> 10 <%= noosfero_javascript %>
11 - <%= stylesheet_link_tag noosfero_stylesheets, :cache => 'cache' %>  
12 - <%= stylesheet_link_tag template_stylesheet_path %>  
13 - <%= stylesheet_link_tag icon_theme_stylesheet_path %>  
14 - <%= stylesheet_link_tag jquery_ui_theme_stylesheet_path %>  
15 - <%  
16 - plugins_stylesheets = @plugins.select(&:stylesheet?).map { |plugin| plugin.class.public_path('style.css') }  
17 - %>  
18 - <%= stylesheet_link_tag(plugins_stylesheets, :cache => 'cache/plugins-' + Digest::MD5.hexdigest(plugins_stylesheets.to_s)) unless plugins_stylesheets.empty? %>  
19 - <%= stylesheet_link_tag theme_stylesheet_path %> 11 + <%= noosfero_stylesheets %>
20 12
21 <%# Add custom tags/styles/etc via content_for %> 13 <%# Add custom tags/styles/etc via content_for %>
22 <%= yield :head %> 14 <%= yield :head %>
23 - <%= javascript_tag('render_all_jquery_ui_widgets()') %>  
24 - <%  
25 - plugins_javascripts = @plugins.map { |plugin| plugin.js_files.map { |js| plugin.class.public_path(js) } }.flatten  
26 - %>  
27 - <%= javascript_include_tag(plugins_javascripts, :cache => 'cache/plugins-' + Digest::MD5.hexdigest(plugins_javascripts.to_s)) unless plugins_javascripts.empty? %>  
28 <%= 15 <%=
29 @plugins.dispatch(:head_ending).collect do |content| 16 @plugins.dispatch(:head_ending).collect do |content|
30 content.respond_to?(:call) ? content.call : content 17 content.respond_to?(:call) ? content.call : content
@@ -35,15 +22,9 @@ @@ -35,15 +22,9 @@
35 DEFAULT_LOADING_MESSAGE = <%="'#{ _('loading...') }'" %>; 22 DEFAULT_LOADING_MESSAGE = <%="'#{ _('loading...') }'" %>;
36 </script> 23 </script>
37 </head> 24 </head>
38 - <body class="<%=  
39 - # Identify the current controller and action for the CSS:  
40 - " controller-"+ @controller.controller_name() +  
41 - " action-"+ @controller.controller_name() +"-"+ @controller.action_name() +  
42 - " template-"+ ( profile.nil? ? "default" : profile.layout_template ) +  
43 - (!profile.nil? && profile.is_on_homepage?(request.path,@page) ? " profile-homepage" : "")  
44 - %>" >  
45 - 25 + <body class="<%= body_classes %>">
46 <a href="#content" id="link-go-content"><span><%= _("Go to the content") %></span></a> 26 <a href="#content" id="link-go-content"><span><%= _("Go to the content") %></span></a>
  27 +
47 <%= 28 <%=
48 @plugins.dispatch(:body_beginning).collect do |content| 29 @plugins.dispatch(:body_beginning).collect do |content|
49 content.respond_to?(:call) ? content.call : content 30 content.respond_to?(:call) ? content.call : content
@@ -55,31 +36,7 @@ @@ -55,31 +36,7 @@
55 <%= theme_header %> 36 <%= theme_header %>
56 </div> 37 </div>
57 <div id="wrap-2"> 38 <div id="wrap-2">
58 - <div id="user">  
59 - <span class='logged-in' style='display: none;'>  
60 - <%= usermenu_logged_in %>  
61 - </span>  
62 - <span class='not-logged-in' style='display: none'>  
63 -  
64 - <%= _("<span class='login'>%s</span>") % thickbox_inline_popup_link('<i class="icon-menu-login"></i><strong>' + _('Login') + '</strong>', login_url, 'inlineLoginBox', :id => 'link_login') %>  
65 - <%= @plugins.dispatch(:alternative_authentication_link).collect { |content| instance_eval(&content) }.join("") %>  
66 -  
67 - <div id='inlineLoginBox' style='display: none;'>  
68 - <%= render :file => 'account/login', :locals => { :is_thickbox => true } %>  
69 - </div>  
70 -  
71 - <% unless @plugins.dispatch(:allow_user_registration).include?(false) %>  
72 - <%= _("<span class='or'>or</span> <span class='signup'>%s</span>") % link_to('<strong>' + _('Sign up') + '</strong>', :controller => 'account', :action => 'signup')%>  
73 - <% end %>  
74 -  
75 - </span>  
76 - <form action="/search" class="search_form" method="get" class="clean">  
77 - <input name="query" size="15" title="<%=_('Search...')%>" onfocus="this.form.className='focused';" onblur="this.form.className=''" />  
78 - <div><%=_('Press <strong>Enter</strong> to send the search query.')%></div>  
79 - <%= javascript_tag 'jQuery("#user form input").hint();' %>  
80 - </form>  
81 - </div><!-- end id="user" -->  
82 - 39 + <%= render :partial => 'layouts/user' %>
83 <h1 id="site-title"> 40 <h1 id="site-title">
84 <%= theme_site_title %> 41 <%= theme_site_title %>
85 </h1> 42 </h1>
@@ -103,5 +60,6 @@ @@ -103,5 +60,6 @@
103 </div><!-- end id="theme-footer" --> 60 </div><!-- end id="theme-footer" -->
104 <%= noosfero_layout_features %> 61 <%= noosfero_layout_features %>
105 <%= theme_javascript_ng %> 62 <%= theme_javascript_ng %>
  63 + <%= addthis_javascript %>
106 </body> 64 </body>
107 </html> 65 </html>
app/views/map_balloon/product.rhtml
1 <div id="balloon"> 1 <div id="balloon">
2 - <%= render :partial => 'search/product', :locals => {:product => @product} %> 2 + <%= render :partial => 'search/full_product', :locals => {:product => @product} %>
3 </div> 3 </div>
app/views/profile/_profile_wall.rhtml
1 <h3><%= _("%s's wall") % @profile.name %></h3> 1 <h3><%= _("%s's wall") % @profile.name %></h3>
2 <div id='leave_scrap'> 2 <div id='leave_scrap'>
3 <%= flash[:error] %> 3 <%= flash[:error] %>
4 - <% form_remote_tag :url => {:controller => 'profile', :action => 'leave_scrap', :tab_action => 'wall' }, :update => 'profile_activities', :success => "$('leave_scrap_content').value=''" do %> 4 + <% form_remote_tag :url => {:controller => 'profile', :action => 'leave_scrap', :tab_action => 'wall' }, :update => 'profile_activities', :success => "$('leave_scrap_content').value=''", :complete => "jQuery('#leave_scrap_form').removeClass('loading').find('*').attr('disabled', false)", :loading => "jQuery('#leave_scrap_form').addClass('loading').find('*').attr('disabled', true)", :html => {:id => 'leave_scrap_form' } do %>
5 <%= limited_text_area :scrap, :content, 420, 'leave_scrap_content', :cols => 50, :rows => 2 %> 5 <%= limited_text_area :scrap, :content, 420, 'leave_scrap_content', :cols => 50, :rows => 2 %>
6 <%= submit_button :new, _('Share') %> 6 <%= submit_button :new, _('Share') %>
7 <% end %> 7 <% end %>
app/views/profile_members/_manage_roles.html.erb
@@ -13,11 +13,11 @@ @@ -13,11 +13,11 @@
13 13
14 <% @roles.each do |role| %> 14 <% @roles.each do |role| %>
15 <% search_url = url_for(:action => 'search_user', :profile => profile.identifier, :role => role.id) %> 15 <% search_url = url_for(:action => 'search_user', :profile => profile.identifier, :role => role.id) %>
16 - <% @pre_population ||= profile.members_by_role_to_json(role) %> 16 + <% pre_population = params[:action] == 'last_admin' ? [].to_json : profile.members_by_role_to_json(role) %>
17 <script type="text/javascript"> 17 <script type="text/javascript">
18 jQuery(<%= ('#search_' + role.key).to_json %>) 18 jQuery(<%= ('#search_' + role.key).to_json %>)
19 .tokenInput("<%= search_url %>", { 19 .tokenInput("<%= search_url %>", {
20 - prePopulate: <%= @pre_population %>, 20 + prePopulate: <%= pre_population %>,
21 hintText: <%= _('Type in a search term for users').to_json %>, 21 hintText: <%= _('Type in a search term for users').to_json %>,
22 noResultsText: <%= _('No results').to_json %>, 22 noResultsText: <%= _('No results').to_json %>,
23 searchingText: <%= _('Searching...').to_json %>, 23 searchingText: <%= _('Searching...').to_json %>,
app/views/search/_article.rhtml
@@ -1,12 +0,0 @@ @@ -1,12 +0,0 @@
1 -<li class="search-article-item article-item">  
2 - <%= link_to(article.title, article.url, :class => "search-result-title") %>  
3 - <div class="search-content-first-column">  
4 - <%= render :partial => 'image', :object => article %>  
5 - </div>  
6 - <table class="noborder search-content-second-column">  
7 - <%= render :partial => 'article_common', :object => article %>  
8 - </table>  
9 - <%= render :partial => 'article_last_change', :object => article %>  
10 -  
11 - <div style="clear:both"></div>  
12 -</li>  
app/views/search/_blog.rhtml
@@ -1,24 +0,0 @@ @@ -1,24 +0,0 @@
1 -<li class="search-blog article-item">  
2 - <%= link_to blog.title, blog.view_url, :class => 'search-result-title' %>  
3 - <div class="search-content-first-column">  
4 - <%= render :partial => 'image', :object => blog %>  
5 - </div>  
6 - <table class="noborder search-content-second-column">  
7 - <tr class="search-blog-items">  
8 - <td class="search-field-label"><%= _("Last posts") %></td>  
9 -  
10 - <% r = blog.children.find(:all, :order => :updated_at, :conditions => ['type != ?', 'RssFeed']).last(3) %>  
11 - <td class="<%= "search-field-none" if r.empty? %>">  
12 - <% r.each do |a| %>  
13 - <%= link_to a.title, a.view_url, :class => 'search-blog-sample-item '+icon_for_article(a) %>  
14 - <% end %>  
15 - <%= _('None') if r.empty? %>  
16 - </td>  
17 - </tr>  
18 -  
19 - <%= render :partial => 'article_common', :object => blog %>  
20 - </table>  
21 - <%= render :partial => 'article_last_change', :object => blog %>  
22 -  
23 - <div style="clear: both;"/></div>  
24 -</li>  
app/views/search/_compact_profile.html.erb 0 → 100644
@@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
  1 +<% filter_label = profile.send(@filter + '_label') %>
  2 +<% filter_label += show_date(profile.created_at) if @filter == 'more_recent' %>
  3 +<li class="search-profile-item">
  4 + <%= profile_image_link profile, :portrait, 'div', filter_label %>
  5 +</li>
app/views/search/_content.rhtml
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -_article.rhtml  
2 \ No newline at end of file 0 \ No newline at end of file
app/views/search/_display_results.rhtml
1 <div id="search-results" class="<%= !multiple_search? ? 'only-one-result-box' : 'multiple-results-boxes' %>"> 1 <div id="search-results" class="<%= !multiple_search? ? 'only-one-result-box' : 'multiple-results-boxes' %>">
2 <% @order.each do |name| %> 2 <% @order.each do |name| %>
3 - <% results = @results[name] %>  
4 - <% empty = results.nil? || results.empty? %> 3 + <% search = @searches[name] %>
5 4
6 - <div class="search-results-<%= name %> search-results-box <%= "search-results-empty" if empty %>">  
7 - <% if not empty %>  
8 - <% partial = partial_for_class(results.first.class.class_name.constantize) %> 5 + <div class="search-results-<%= name %> search-results-box <%= "search-results-empty" if search[:results].blank? %>">
  6 + <% if !search[:results].blank? %>
9 7
10 - <% if multiple_search? %> 8 + <% if multiple_search?(@searches) %>
11 <h3><%= @names[name] %></h3> 9 <h3><%= @names[name] %></h3>
12 - <% if results.total_entries > SearchController::MULTIPLE_SEARCH_LIMIT %>  
13 - <%= link_to(_('see all (%d)') % results.total_entries, params.merge(:action => name), :class => 'see-more' ) %> 10 + <% if search[:results].total_entries > SearchController::MULTIPLE_SEARCH_LIMIT %>
  11 + <%= link_to(_('see all (%d)') % search[:results].total_entries, params.merge(:action => name), :class => 'see-more' ) %>
14 <% end %> 12 <% end %>
15 <% end %> 13 <% end %>
16 14
17 - <div class="search-results-innerbox search-results-type-<%= partial %> <%= 'common-profile-list-block' if partial == 'profile' %>"> 15 + <% display = display_filter(name, params[:display]) %>
  16 +
  17 + <div class="search-results-innerbox search-results-type-<%= name.to_s.singularize %> <%= 'common-profile-list-block' if [:enterprises, :people, :communities].include?(name) %>">
18 <ul> 18 <ul>
19 - <% results.each do |hit| %>  
20 - <%= render :partial => partial_for_class(hit.class), :object => hit %>  
21 - <% end %> 19 + <% search[:results].each do |hit| %>
  20 + <% partial = partial_for_class(hit.class, display) %>
  21 + <% variable_name = partial.gsub("#{display}_", '').to_sym %>
  22 + <%= render :partial => partial, :locals => {variable_name => hit} %>
  23 + <% end %>
22 </ul> 24 </ul>
23 </div> 25 </div>
24 <% else %> 26 <% else %>
app/views/search/_event.rhtml
@@ -1,25 +0,0 @@ @@ -1,25 +0,0 @@
1 -<li class="search-event-item article-item">  
2 -<%= link_to(event.title, event.url, :class => "search-result-title") %>  
3 -<div class="search-content-first-column">  
4 - <%= render :partial => 'image', :object => event %>  
5 -</div>  
6 -<table class="noborder search-content-second-column">  
7 - <% if event.start_date %>  
8 - <tr class="search-article-event-date">  
9 - <td class="search-field-label"><%= _('Start date') %></td>  
10 - <td class="article-item-date"><%= event.start_date %></td>  
11 - </tr>  
12 - <% end %>  
13 - <% if event.end_date %>  
14 - <tr class="search-article-event-date">  
15 - <td class="search-field-label"><%= _('End date') %></td>  
16 - <td class="article-item-date"><%= event.end_date %></td>  
17 - </tr>  
18 - <% end %>  
19 -  
20 - <%= render :partial => 'article_common', :object => event %>  
21 -</table>  
22 -<%= render :partial => 'article_last_change', :object => event %>  
23 -  
24 -<div style="clear: both"></div>  
25 -</li>  
app/views/search/_facets_menu.rhtml
@@ -1,36 +0,0 @@ @@ -1,36 +0,0 @@
1 -<% less_options_limit = 8 %>  
2 -  
3 -<div id="facets-menu">  
4 - <% @asset_class.map_facets_for(environment).each do |facet| %>  
5 -  
6 - <div id="facet-menu-<%= facet[:id].to_s %>" class="facet-menu">  
7 - <div class="facet-menu-label">  
8 - <%= @asset_class.facet_label(facet) %>  
9 - </div>  
10 -  
11 - <% results = @asset_class.map_facet_results(facet, params[:facet], @facets, @all_facets, :limit => less_options_limit) %>  
12 - <% facet_count = results.total_entries %>  
13 -  
14 - <% if facet_count > 0 %>  
15 - <div class="facet-menu-options facet-menu-more-options" style="display: none">  
16 - </div>  
17 -  
18 - <div class="facet-menu-options facet-menu-less-options">  
19 - <% results.each do |id, label, count| %>  
20 - <%= facet_link_html(facet, params, id, label, count) %><br />  
21 - <% end %>  
22 - </div> <br />  
23 -  
24 - <% if facet_count > less_options_limit %>  
25 - <%= link_to_function _("Options"),  
26 - "facet_options_toggle('#{facet[:id].to_s}', '#{url_for(params.merge(:action => 'facets_browse', :facet_id => facet[:id], :asset => @asset, :escape => false))}'); " +  
27 - "jQuery(this).toggleClass('facet-less-options')", :class => "facet-options-toggle" %>  
28 - <br />  
29 - <% end %>  
30 -  
31 - <% else %>  
32 - <span class="facet-any-result-found"><%= _("No filter available") %></span>  
33 - <% end %>  
34 - </div>  
35 - <% end %>  
36 -</div>  
app/views/search/_facets_unselect_menu.rhtml
@@ -1,6 +0,0 @@ @@ -1,6 +0,0 @@
1 -<div class="facets-applied">  
2 - <% if params[:facet] and params[:facet].count > 0 %>  
3 - <span class="facets-applied-label"><%= _("Applied filters") %> </span>  
4 - <%= facet_selecteds_html_for(environment, asset_class(@asset), params) %>  
5 - <% end %>  
6 -</div>  
app/views/search/_folder.rhtml
@@ -1,24 +0,0 @@ @@ -1,24 +0,0 @@
1 -<li class="search-folder-item article-item">  
2 - <%= link_to folder.title, folder.view_url, :class => 'search-result-title' %>  
3 - <div class="search-content-first-column">  
4 - <%= render :partial => 'image', :object => folder %>  
5 - </div>  
6 - <table class="noborder search-content-second-column">  
7 - <tr class="search-folder-items">  
8 - <td class="search-field-label"><%= _("Last items") %></td>  
9 -  
10 - <% r = folder.children.last(3) %>  
11 - <td class="<%= "search-field-none" if r.empty? %>">  
12 - <% r.each do |a| %>  
13 - <%= link_to a.title, a.view_url, :class => 'search-folder-sample-item '+icon_for_article(a) %>  
14 - <% end %>  
15 - <%= _('None') if r.empty? %>  
16 - </td>  
17 - </tr>  
18 -  
19 - <%= render :partial => 'article_common', :object => folder %>  
20 - </table>  
21 - <%= render :partial => 'article_last_change', :object => folder %>  
22 -  
23 - <div style="clear:both"></div>  
24 -</li>  
app/views/search/_forum.rhtml
@@ -1,24 +0,0 @@ @@ -1,24 +0,0 @@
1 -<li class="search-forum-item article-item">  
2 - <%= link_to forum.title, forum.view_url, :class => 'search-result-title' %>  
3 - <div class="search-content-first-column">  
4 - <%= render :partial => 'image', :object => forum %>  
5 - </div>  
6 - <table class="noborder search-content-second-column">  
7 - <tr class="search-forum-items">  
8 - <td class="search-field-label"><%= _("Last topics") %></td>  
9 -  
10 - <% r = forum.children.find(:all, :order => :updated_at, :conditions => ['type != ?', 'RssFeed']).last(3) %>  
11 - <td class="<%= "search-field-none" if r.empty? %>">  
12 - <% r.each do |a| %>  
13 - <%= link_to a.title, a.view_url, :class => 'search-forum-sample-item '+icon_for_article(a) %>  
14 - <% end %>  
15 - <%= _('None') if r.empty? %>  
16 - </td>  
17 - </tr>  
18 -  
19 - <%= render :partial => 'article_common', :object => forum %>  
20 - </table>  
21 - <%= render :partial => 'article_last_change', :object => forum %>  
22 -  
23 - <div style="clear:both"></div>  
24 -</li>  
app/views/search/_full_article.html.erb 0 → 100644
@@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
  1 +<li class="search-article-item article-item">
  2 + <%= link_to(article.title, article.url, :class => "search-result-title") %>
  3 + <div class="search-content-first-column">
  4 + <%= render :partial => 'image', :object => article %>
  5 + </div>
  6 + <table class="noborder search-content-second-column">
  7 + <%= render :partial => 'article_common', :object => article %>
  8 + </table>
  9 + <%= render :partial => 'article_last_change', :object => article %>
  10 +
  11 + <div style="clear:both"></div>
  12 +</li>
app/views/search/_full_blog.html.erb 0 → 100644
@@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
  1 +<li class="search-blog article-item">
  2 + <%= link_to blog.title, blog.view_url, :class => 'search-result-title' %>
  3 + <div class="search-content-first-column">
  4 + <%= render :partial => 'image', :object => blog %>
  5 + </div>
  6 + <table class="noborder search-content-second-column">
  7 + <tr class="search-blog-items">
  8 + <td class="search-field-label"><%= _("Last posts") %></td>
  9 +
  10 + <% r = blog.children.find(:all, :order => :updated_at, :conditions => ['type != ?', 'RssFeed']).last(3) %>
  11 + <td class="<%= "search-field-none" if r.empty? %>">
  12 + <% r.each do |a| %>
  13 + <%= link_to a.title, a.view_url, :class => 'search-blog-sample-item '+icon_for_article(a) %>
  14 + <% end %>
  15 + <%= _('None') if r.empty? %>
  16 + </td>
  17 + </tr>
  18 +
  19 + <%= render :partial => 'article_common', :object => blog %>
  20 + </table>
  21 + <%= render :partial => 'article_last_change', :object => blog %>
  22 +
  23 + <div style="clear: both;"/></div>
  24 +</li>
app/views/search/_full_enterprise.html.erb 0 → 100644
@@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
  1 +<li class="search-profile-item">
  2 + <div class="search-enterprise-item">
  3 + <div class="search-enterprise-item-column-left">
  4 + <%= profile_image_link enterprise, :portrait, 'div',
  5 + @filter == 'more_recent' ? enterprise.send(@filter + '_label') + show_date(enterprise.created_at) : enterprise.send(@filter + '_label') %>
  6 + </div>
  7 + <div class="search-enterprise-item-column-right">
  8 + <%= link_to_homepage(enterprise.name, enterprise.identifier, :class => "search-result-title") %>
  9 + <div class="search-enterprise-description">
  10 + <% if enterprise.description %>
  11 + <% body_stripped = strip_tags(enterprise.description) %>
  12 + <% elsif enterprise.home_page and enterprise.home_page.body %>
  13 + <% body_stripped = strip_tags(enterprise.home_page.body) %>
  14 + <% end %>
  15 + <%= excerpt(body_stripped, body_stripped.first(3), 200) if body_stripped %>
  16 + </div>
  17 + <div class="search-enterprise-region">
  18 + <span class="search-enterprise-region-label"><%= _("City") %></span>
  19 + <% if enterprise.region %>
  20 + <span class="search-enterprise-region-name"><%= city_with_state(enterprise.region) %></span>
  21 + <% end %>
  22 + </div>
  23 +
  24 + <div class="search-enterprise-categorization">
  25 + <% enterprise.top_level_categorization.each do |parent, children| %>
  26 + <div class="search-enterprise-category-<%=parent.id%> search-enterprise-category">
  27 + <span class="search-enterprise-categorization-parent"><%= parent.name %></span>
  28 + <span class="search-enterprise-categorization-children">
  29 + <%= children.collect(&:name).join(', ') %>
  30 + </span>
  31 + </div>
  32 + <% end %>
  33 + </div>
  34 + </div>
  35 +
  36 + <hr class="clearfix" />
  37 + </div>
  38 +</li>
app/views/search/_full_event.html.erb 0 → 100644
@@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
  1 +<li class="search-event-item article-item">
  2 +<%= link_to(event.title, event.url, :class => "search-result-title") %>
  3 +<div class="search-content-first-column">
  4 + <%= render :partial => 'image', :object => event %>
  5 +</div>
  6 +<table class="noborder search-content-second-column">
  7 + <% if event.start_date %>
  8 + <tr class="search-article-event-date">
  9 + <td class="search-field-label"><%= _('Start date') %></td>
  10 + <td class="article-item-date"><%= event.start_date %></td>
  11 + </tr>
  12 + <% end %>
  13 + <% if event.end_date %>
  14 + <tr class="search-article-event-date">
  15 + <td class="search-field-label"><%= _('End date') %></td>
  16 + <td class="article-item-date"><%= event.end_date %></td>
  17 + </tr>
  18 + <% end %>
  19 +
  20 + <%= render :partial => 'article_common', :object => event %>
  21 +</table>
  22 +<%= render :partial => 'article_last_change', :object => event %>
  23 +
  24 +<div style="clear: both"></div>
  25 +</li>
app/views/search/_full_folder.html.erb 0 → 100644
@@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
  1 +<li class="search-folder-item article-item">
  2 + <%= link_to folder.title, folder.view_url, :class => 'search-result-title' %>
  3 + <div class="search-content-first-column">
  4 + <%= render :partial => 'image', :object => folder %>
  5 + </div>
  6 + <table class="noborder search-content-second-column">
  7 + <tr class="search-folder-items">
  8 + <td class="search-field-label"><%= _("Last items") %></td>
  9 +
  10 + <% r = folder.children.last(3) %>
  11 + <td class="<%= "search-field-none" if r.empty? %>">
  12 + <% r.each do |a| %>
  13 + <%= link_to a.title, a.view_url, :class => 'search-folder-sample-item '+icon_for_article(a) %>
  14 + <% end %>
  15 + <%= _('None') if r.empty? %>
  16 + </td>
  17 + </tr>
  18 +
  19 + <%= render :partial => 'article_common', :object => folder %>
  20 + </table>
  21 + <%= render :partial => 'article_last_change', :object => folder %>
  22 +
  23 + <div style="clear:both"></div>
  24 +</li>
app/views/search/_full_forum.html.erb 0 → 100644
@@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
  1 +<li class="search-forum-item article-item">
  2 + <%= link_to forum.title, forum.view_url, :class => 'search-result-title' %>
  3 + <div class="search-content-first-column">
  4 + <%= render :partial => 'image', :object => forum %>
  5 + </div>
  6 + <table class="noborder search-content-second-column">
  7 + <tr class="search-forum-items">
  8 + <td class="search-field-label"><%= _("Last topics") %></td>
  9 +
  10 + <% r = forum.children.find(:all, :order => :updated_at, :conditions => ['type != ?', 'RssFeed']).last(3) %>
  11 + <td class="<%= "search-field-none" if r.empty? %>">
  12 + <% r.each do |a| %>
  13 + <%= link_to a.title, a.view_url, :class => 'search-forum-sample-item '+icon_for_article(a) %>
  14 + <% end %>
  15 + <%= _('None') if r.empty? %>
  16 + </td>
  17 + </tr>
  18 +
  19 + <%= render :partial => 'article_common', :object => forum %>
  20 + </table>
  21 + <%= render :partial => 'article_last_change', :object => forum %>
  22 +
  23 + <div style="clear:both"></div>
  24 +</li>
app/views/search/_full_gallery.html.erb 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +<li class="search-gallery article-item">
  2 + <%= link_to gallery.title, gallery.view_url, :class => 'search-result-title' %>
  3 + <div class="search-content-first-column">
  4 + <%= render :partial => 'image', :object => gallery %>
  5 + </div>
  6 + <table class="noborder search-content-second-column">
  7 + <%= render :partial => 'article_common', :object => gallery %>
  8 + </table>
  9 + <%= render :partial => 'article_last_change', :object => gallery %>
  10 +
  11 + <div style="clear: both"></div>
  12 +</li>
  13 +
app/views/search/_full_product.rhtml 0 → 100644
@@ -0,0 +1,85 @@ @@ -0,0 +1,85 @@
  1 +<% extra_content = @plugins.dispatch(:asset_product_extras, product).collect { |content| instance_eval(&content) } %>
  2 +<% extra_properties = @plugins.dispatch(:asset_product_properties, product)%>
  3 +
  4 +<li class="search-product-item <%= 'highlighted' if product.highlighted? %>">
  5 +
  6 + <div class="search-product-item-first-column">
  7 + <%= render :partial => 'search/image', :object => product %>
  8 +
  9 + <% if product.available %>
  10 + <% if product.price && product.price > 0 %>
  11 + <% has_discount = product.discount && product.discount > 0 %>
  12 + <% if product.price %>
  13 + <span class="search-product-price-textid"><%=_("from") if has_discount %></span><%= price_span(product.price, :class => "search-product-price " + (has_discount ? 'with-discount' : '')) %>
  14 + <% if has_discount %>
  15 + <span class="search-product-price-textid"><%=_("by")%></span><%= price_span(product.price_with_discount, :class => "search-product-price") %>
  16 + <% end %>
  17 + <% if product.unit %>
  18 + <span class="search-product-unit">&nbsp;<%= _('/') %>&nbsp;<%= product.unit.name %></span>
  19 + <% end %>
  20 + <% end %>
  21 + <div class="search-product-inputs-info">
  22 + <% if p = product.percentage_from_solidarity_economy %>
  23 + <div class="search-product-percentage-from-solidarity-economy search-product-ecosol-percentage-icon-<%= p[0].to_s %>"
  24 + title="<%=_('Percentage of inputs from solidarity economy')%>">
  25 + <%= p[1] %>
  26 + </div>
  27 + <% end %>
  28 +
  29 + <% if product.price_described? %>
  30 + <% title = (product.inputs.relevant_to_price + product.price_details).map{ |i|
  31 + '<div class="search-product-input-dots-to-price">' +
  32 + '<div class="search-product-input-name">' + i.name + '</div>' +
  33 + price_span(i.price, :class => 'search-product-input-price') +
  34 + '</div>' }.join('') %>
  35 + <%= link_to_function _("Open Price"), '', :title => title, :class => "search-product-price-details" %>
  36 + <% end %>
  37 + </div>
  38 + <% end %>
  39 + <% else %>
  40 + <span class="product-not-available"><%= _('Not available') %></div>
  41 + <% end %>
  42 +
  43 + </div>
  44 + <div class="search-product-item-second-column">
  45 + <%= link_to_product product, :class => 'search-result-title' %>
  46 + <div class="search-product-supplier">
  47 + <span class="search-field-label"><%= _('Supplier') %> </span><%= link_to_homepage(product.enterprise.name, product.enterprise.identifier) %>
  48 + </div>
  49 + <div class="search-product-description">
  50 + <% if product.description %>
  51 + <% desc_stripped = strip_tags(product.description) %>
  52 + <span class="search-field-label"><%= _('Description') %> </span><%= excerpt(desc_stripped, desc_stripped.first(3), 300) %>
  53 + <% end %>
  54 + </div>
  55 + </div>
  56 + <div class="search-product-item-third-column">
  57 + <div class="search-product-region">
  58 + <% if product.enterprise.region %>
  59 + <span class="search-field-label"><%= _('City') %></span>
  60 + <br /><%= city_with_state(product.enterprise.region) %>
  61 + <% end %>
  62 + </div>
  63 + <div class="search-product-qualifiers">
  64 + <% if product.product_qualifiers.count > 0 %>
  65 + <span class="search-field-label"><%= _('Qualifiers') %></span>
  66 + <% product.product_qualifiers.each do |pq| %>
  67 + <% if pq.qualifier %>
  68 + <span class="search-product-qualifier"><%= pq.qualifier.name + (pq.certifier.nil? ? _(";") : '') %></span>
  69 + <% end %>
  70 + <% if pq.certifier %>
  71 + <span class="search-product-certifier">&nbsp;<%= _('cert. ') + pq.certifier.name + _(";") %></span>
  72 + <% end %>
  73 + <% end %>
  74 + <% end %>
  75 + </div>
  76 + </div>
  77 +
  78 + <div style="clear: both"></div>
  79 +
  80 + <%= extra_content.join('\n') %>
  81 + <% extra_properties.each do |property| %>
  82 + <div><%= property[:name] + ': ' + instance_eval(&property[:content]) %></div>
  83 + <% end %>
  84 +
  85 +</li>
app/views/search/_full_text_article.html.erb 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +<li class="search-text-article-item article-item">
  2 + <%= link_to(text_article.title, text_article.url, :class => "search-result-title") %>
  3 +
  4 + <div class="search-content-first-column">
  5 + <%= render :partial => 'image', :object => text_article %>
  6 + </div>
  7 + <table class="noborder search-content-second-column">
  8 + <%= render :partial => 'article_common', :object => text_article %>
  9 + </table>
  10 + <%= render :partial => 'article_last_change', :object => text_article %>
  11 +
  12 + <div style="clear: both"></div>
  13 +</li>
app/views/search/_full_uploaded_file.html.erb 0 → 100644
@@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
  1 +<li class="search-uploaded-file-item article-item">
  2 + <%= link_to uploaded_file.filename, uploaded_file.view_url, :class => 'search-result-title' %>
  3 +
  4 + <div class="search-content-first-column">
  5 + <%= render :partial => 'image', :object => uploaded_file %>
  6 + </div>
  7 +
  8 + <table class="noborder search-content-second-column">
  9 + <%= render :partial => 'article_author', :object => uploaded_file %>
  10 + <%= render :partial => 'article_description', :object => uploaded_file %>
  11 +
  12 + <% if uploaded_file.parent and uploaded_file.parent.published? %>
  13 + <tr class="search-uploaded-file-parent">
  14 + <td class="search-field-label"><%= uploaded_file.parent.gallery? ? _("Gallery") : _("Folder") %></td>
  15 + <td><%= link_to uploaded_file.parent.name, uploaded_file.parent.url %></td>
  16 + </tr>
  17 + <% end %>
  18 +
  19 + <%= render :partial => 'article_tags', :object => uploaded_file.tags %>
  20 + <%= render :partial => 'article_categories', :object => uploaded_file.categories %>
  21 + </table>
  22 + <%= render :partial => 'article_last_change', :object => uploaded_file %>
  23 +
  24 + <div style="clear:both"></div>
  25 +</li>