Commit 275fdc75bcbff79e6e5ff4732c7dc0fdc3b8ed2a
Committed by
Antonio Terceiro
1 parent
a18ff65c
Exists in
master
and in
29 other branches
ActionItem856: adding list of products in article EnterpriseHomepage
Showing
11 changed files
with
168 additions
and
135 deletions
Show diff stats
app/helpers/application_helper.rb
| @@ -22,6 +22,8 @@ module ApplicationHelper | @@ -22,6 +22,8 @@ module ApplicationHelper | ||
| 22 | 22 | ||
| 23 | include ProfileEditorHelper | 23 | include ProfileEditorHelper |
| 24 | 24 | ||
| 25 | + include DisplayHelper | ||
| 26 | + | ||
| 25 | # Displays context help. You can pass the content of the help message as the | 27 | # Displays context help. You can pass the content of the help message as the |
| 26 | # first parameter or using template code inside a block passed to this | 28 | # first parameter or using template code inside a block passed to this |
| 27 | # method. *Note*: the block is ignored if <tt>content</tt> is not | 29 | # method. *Note*: the block is ignored if <tt>content</tt> is not |
| @@ -261,19 +263,6 @@ module ApplicationHelper | @@ -261,19 +263,6 @@ module ApplicationHelper | ||
| 261 | concat(content_tag('div', capture(&block) + tag('br', :style => 'clear: left;'), { :class => 'button-bar' }.merge(options)), block.binding) | 263 | concat(content_tag('div', capture(&block) + tag('br', :style => 'clear: left;'), { :class => 'button-bar' }.merge(options)), block.binding) |
| 262 | end | 264 | end |
| 263 | 265 | ||
| 264 | - def link_to_category(category, full = true) | ||
| 265 | - return _('Uncategorized product') unless category | ||
| 266 | - name = full ? category.full_name(' → ') : category.name | ||
| 267 | - link_to name, :controller => 'search', :action => 'category_index', :category_path => category.path.split('/') | ||
| 268 | - end | ||
| 269 | - | ||
| 270 | - def link_to_product(product, opts={}) | ||
| 271 | - return _('No product') unless product | ||
| 272 | - link_to content_tag( 'span', product.name ), | ||
| 273 | - { :controller => 'catalog', :action => 'show', :id => product, :profile => product.enterprise.identifier }, | ||
| 274 | - opts | ||
| 275 | - end | ||
| 276 | - | ||
| 277 | def partial_for_class(klass) | 266 | def partial_for_class(klass) |
| 278 | if klass.nil? | 267 | if klass.nil? |
| 279 | raise ArgumentError, 'No partial for object. Is there a partial for any class in the inheritance hierarchy?' | 268 | raise ArgumentError, 'No partial for object. Is there a partial for any class in the inheritance hierarchy?' |
| @@ -578,17 +567,6 @@ module ApplicationHelper | @@ -578,17 +567,6 @@ module ApplicationHelper | ||
| 578 | end | 567 | end |
| 579 | end | 568 | end |
| 580 | 569 | ||
| 581 | - def txt2html(txt) | ||
| 582 | - txt. | ||
| 583 | - gsub( /\n\s*\n/, ' <p/> ' ). | ||
| 584 | - gsub( /\n/, ' <br/> ' ). | ||
| 585 | - gsub( /(^|\s)(www\.[^\s])/, '\1http://\2' ). | ||
| 586 | - gsub( /(https?:\/\/([^\s]+))/, | ||
| 587 | - '<a href="\1" target="_blank" rel="nofolow" onclick="return confirm(\'' + | ||
| 588 | - escape_javascript( _('Are you sure you want to visit this web site?') ) + | ||
| 589 | - '\n\n\'+this.href)">\2</a>' ) | ||
| 590 | - end | ||
| 591 | - | ||
| 592 | # Should be on the forms_helper file but when its there the translation of labels doesn't work | 570 | # Should be on the forms_helper file but when its there the translation of labels doesn't work |
| 593 | class NoosferoFormBuilder < ActionView::Helpers::FormBuilder | 571 | class NoosferoFormBuilder < ActionView::Helpers::FormBuilder |
| 594 | include GetText | 572 | include GetText |
app/helpers/catalog_helper.rb
| 1 | module CatalogHelper | 1 | module CatalogHelper |
| 2 | + | ||
| 3 | +include DisplayHelper | ||
| 4 | + | ||
| 5 | + def display_products_list(profile, products) | ||
| 6 | + data = '' | ||
| 7 | + products.each { |product| | ||
| 8 | + | ||
| 9 | + data << content_tag('li', | ||
| 10 | + link_to_product(product, :class => 'product-pic', :style => 'background-image:url(%s)' % ( product.image ? product.image.public_filename(:portrait) : '/images/icons-app/product-default-pic-portrait.png' )) + | ||
| 11 | + content_tag('h3', link_to_product(product)) + | ||
| 12 | + content_tag('ul', | ||
| 13 | + (product.price ? content_tag('li', _('Price: %s') % ( "%.2f" % product.price), :class => 'product_price') : '') + | ||
| 14 | + content_tag('li', link_to_category(product.product_category), :class => 'product_category') | ||
| 15 | + ) + | ||
| 16 | + (product.description ? content_tag('div', txt2html(product.description), :class => 'description') : tag('br', :style => 'clear:both')), | ||
| 17 | + :class => 'product') | ||
| 18 | + } | ||
| 19 | + content_tag('h1', _('Products/Services')) + content_tag('ul', data, :id => 'product_list') | ||
| 20 | + end | ||
| 2 | end | 21 | end |
| @@ -0,0 +1,26 @@ | @@ -0,0 +1,26 @@ | ||
| 1 | +module DisplayHelper | ||
| 2 | + | ||
| 3 | + def link_to_product(product, opts={}) | ||
| 4 | + return _('No product') unless product | ||
| 5 | + link_to content_tag( 'span', product.name ), | ||
| 6 | + product.enterprise.generate_url(:controller => 'catalog', :action => 'show', :id => product), | ||
| 7 | + opts | ||
| 8 | + end | ||
| 9 | + | ||
| 10 | + def link_to_category(category, full = true) | ||
| 11 | + return _('Uncategorized product') unless category | ||
| 12 | + name = full ? category.full_name(' → ') : category.name | ||
| 13 | + link_to name, Noosfero.url_options.merge({:controller => 'search', :action => 'category_index', :category_path => category.path.split('/'),:host => category.environment.default_hostname }) | ||
| 14 | + end | ||
| 15 | + | ||
| 16 | + def txt2html(txt) | ||
| 17 | + txt. | ||
| 18 | + gsub( /\n\s*\n/, ' <p/> ' ). | ||
| 19 | + gsub( /\n/, ' <br/> ' ). | ||
| 20 | + gsub( /(^|\s)(www\.[^\s])/, '\1http://\2' ). | ||
| 21 | + gsub( /(https?:\/\/([^\s]+))/, | ||
| 22 | + '<a href="\1" target="_blank" rel="nofolow" onclick="return confirm(\'' + | ||
| 23 | + escape_javascript( _('Are you sure you want to visit this web site?') ) + | ||
| 24 | + '\n\n\'+this.href)">\2</a>' ) | ||
| 25 | + end | ||
| 26 | +end |
app/helpers/enterprise_homepage_helper.rb
app/models/enterprise_homepage.rb
| @@ -14,8 +14,12 @@ class EnterpriseHomepage < Article | @@ -14,8 +14,12 @@ class EnterpriseHomepage < Article | ||
| 14 | include ActionController::UrlWriter | 14 | include ActionController::UrlWriter |
| 15 | include ActionView::Helpers::AssetTagHelper | 15 | include ActionView::Helpers::AssetTagHelper |
| 16 | include EnterpriseHomepageHelper | 16 | include EnterpriseHomepageHelper |
| 17 | + include CatalogHelper | ||
| 18 | + | ||
| 17 | def to_html | 19 | def to_html |
| 18 | - display_profile_info(self.profile) + content_tag('div', self.body || '') | 20 | + products = self.profile.products |
| 21 | + display_profile_info(self.profile) + content_tag('div', self.body || '') + | ||
| 22 | + (self.profile.environment.enabled?('disable_products_for_enterprises') ? '' : display_products_list(self.profile, products)) | ||
| 19 | end | 23 | end |
| 20 | 24 | ||
| 21 | end | 25 | end |
app/views/catalog/index.rhtml
| 1 | -<h1> <%= _('Products/Services') % @profile.name %> </h1> | ||
| 2 | - | ||
| 3 | -<ul id="product_list"> | ||
| 4 | -<% @products.each do |product| %> | ||
| 5 | - <li class="product"> | ||
| 6 | - <%= link_to_product product, :class => 'product-pic', :style => 'background-image:url(%s)' % | ||
| 7 | - ( product.image ? product.image.public_filename(:portrait) : '/images/icons-app/product-default-pic-portrait.png' ) %> | ||
| 8 | - <h3> | ||
| 9 | - <%= link_to_product product %> | ||
| 10 | - </h3> | ||
| 11 | - <ul> | ||
| 12 | - <% if product.price %> | ||
| 13 | - <li class="product_price"> <%= _('Price: %s') % ( "%.2f" % product.price) %> </li> | ||
| 14 | - <% end %> | ||
| 15 | - <li class="product_category"> <%= link_to_category(product.product_category) %> </li> | ||
| 16 | - </ul> | ||
| 17 | - <% if product.description %> | ||
| 18 | - <div class="description"> | ||
| 19 | - <%= txt2html product.description %> | ||
| 20 | - <div> | ||
| 21 | - <% else %> | ||
| 22 | - <br style="clear:both" /> | ||
| 23 | - <% end %> | ||
| 24 | - </li> | ||
| 25 | -<% end %> | ||
| 26 | -</ul> | ||
| 27 | - | 1 | +<%= display_products_list @profile, @products %> |
public/stylesheets/controller_catalog.css
| 1 | - | ||
| 2 | -/* * * List Products * * * * * * * * * * * * */ | ||
| 3 | - | ||
| 4 | -#product_list { | ||
| 5 | - margin: 0px; | ||
| 6 | - padding: 0px; | ||
| 7 | -} | ||
| 8 | - | ||
| 9 | -#product_list ul { | ||
| 10 | - margin: 0px; | ||
| 11 | - padding: 0px; | ||
| 12 | -} | ||
| 13 | - | ||
| 14 | -#content #product_list li { | ||
| 15 | - margin: 0px; | ||
| 16 | - padding: 0px; | ||
| 17 | - list-style: none; | ||
| 18 | -} | ||
| 19 | - | ||
| 20 | -#content #product_list li.product { | ||
| 21 | - border: 1px solid #888; | ||
| 22 | - margin-bottom: 10px; | ||
| 23 | - padding: 5px 10px; | ||
| 24 | -} | ||
| 25 | - | ||
| 26 | -#product_list .product-pic { | ||
| 27 | - display: block; | ||
| 28 | - width: 64px; | ||
| 29 | - height: 64px; | ||
| 30 | - background-repeat: no-repeat; | ||
| 31 | - background-position: 50% 50%; | ||
| 32 | - float: left; | ||
| 33 | - margin-right: 15px; | ||
| 34 | - position: relative; /* work arround msie bug */ | ||
| 35 | -} | ||
| 36 | - | ||
| 37 | -#product_list .product-pic span { | ||
| 38 | - display: none; | ||
| 39 | -} | ||
| 40 | - | ||
| 41 | -#content #product_list h3 { | ||
| 42 | - margin: 0px; | ||
| 43 | - padding: 0px; | ||
| 44 | - font-size: 120%; | ||
| 45 | -} | ||
| 46 | -.msie #content #product_list h3 { | ||
| 47 | - margin-top: -15px; | ||
| 48 | -} | ||
| 49 | -#product_list h3 a { | ||
| 50 | - text-decoration: none; | ||
| 51 | -} | ||
| 52 | - | ||
| 53 | -#product_list .product_category { | ||
| 54 | - font-size: 11px; | ||
| 55 | -} | ||
| 56 | - | ||
| 57 | -#product_list .description { | ||
| 58 | - clear: left; | ||
| 59 | - font-size: 11px; | ||
| 60 | - text-align: justify; | ||
| 61 | - padding: 5px 10px 0px 10px; | ||
| 62 | -} | ||
| 63 | -.msie #product_list .description { | ||
| 64 | - padding: 5px 10px 10px 10px; | ||
| 65 | -} | ||
| 66 | - | ||
| 67 | -/* * * Show Product * * * * * * * * * * * * */ | ||
| 68 | - | ||
| 69 | -#show_product .product-pic { | ||
| 70 | - float: left; | ||
| 71 | - margin-right: 15px; | ||
| 72 | - border: 1px solid #444; | ||
| 73 | - padding: 2px; | ||
| 74 | - background: #FFF; | ||
| 75 | -} | ||
| 76 | - | ||
| 77 | -#show_product .product_category { | ||
| 78 | - padding-top: 10px; | ||
| 79 | - clear: left; | ||
| 80 | -} | ||
| 81 | - | 1 | +@import url('products.css'); |
public/stylesheets/controller_content_viewer.css
| @@ -0,0 +1,80 @@ | @@ -0,0 +1,80 @@ | ||
| 1 | +/* * * List Products * * * * * * * * * * * * */ | ||
| 2 | + | ||
| 3 | +#product_list { | ||
| 4 | + margin: 0px; | ||
| 5 | + padding: 0px; | ||
| 6 | +} | ||
| 7 | + | ||
| 8 | +#product_list ul { | ||
| 9 | + margin: 0px; | ||
| 10 | + padding: 0px; | ||
| 11 | +} | ||
| 12 | + | ||
| 13 | +#content #product_list li { | ||
| 14 | + margin: 0px; | ||
| 15 | + padding: 0px; | ||
| 16 | + list-style: none; | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +#content #product_list li.product { | ||
| 20 | + border: 1px solid #888; | ||
| 21 | + margin-bottom: 10px; | ||
| 22 | + padding: 5px 10px; | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +#product_list .product-pic { | ||
| 26 | + display: block; | ||
| 27 | + width: 64px; | ||
| 28 | + height: 64px; | ||
| 29 | + background-repeat: no-repeat; | ||
| 30 | + background-position: 50% 50%; | ||
| 31 | + float: left; | ||
| 32 | + margin-right: 15px; | ||
| 33 | + position: relative; /* work arround msie bug */ | ||
| 34 | +} | ||
| 35 | + | ||
| 36 | +#product_list .product-pic span { | ||
| 37 | + display: none; | ||
| 38 | +} | ||
| 39 | + | ||
| 40 | +#content #product_list h3 { | ||
| 41 | + margin: 0px; | ||
| 42 | + padding: 0px; | ||
| 43 | + font-size: 120%; | ||
| 44 | +} | ||
| 45 | +.msie #content #product_list h3 { | ||
| 46 | + margin-top: -15px; | ||
| 47 | +} | ||
| 48 | +#product_list h3 a { | ||
| 49 | + text-decoration: none; | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +#product_list .product_category { | ||
| 53 | + font-size: 11px; | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | +#product_list .description { | ||
| 57 | + clear: left; | ||
| 58 | + font-size: 11px; | ||
| 59 | + text-align: justify; | ||
| 60 | + padding: 5px 10px 0px 10px; | ||
| 61 | +} | ||
| 62 | +.msie #product_list .description { | ||
| 63 | + padding: 5px 10px 10px 10px; | ||
| 64 | +} | ||
| 65 | + | ||
| 66 | +/* * * Show Product * * * * * * * * * * * * */ | ||
| 67 | + | ||
| 68 | +#show_product .product-pic { | ||
| 69 | + float: left; | ||
| 70 | + margin-right: 15px; | ||
| 71 | + border: 1px solid #444; | ||
| 72 | + padding: 2px; | ||
| 73 | + background: #FFF; | ||
| 74 | +} | ||
| 75 | + | ||
| 76 | +#show_product .product_category { | ||
| 77 | + padding-top: 10px; | ||
| 78 | + clear: left; | ||
| 79 | +} | ||
| 80 | + |
test/unit/application_helper_test.rb
| @@ -62,9 +62,11 @@ class ApplicationHelperTest < Test::Unit::TestCase | @@ -62,9 +62,11 @@ class ApplicationHelperTest < Test::Unit::TestCase | ||
| 62 | cat = mock | 62 | cat = mock |
| 63 | cat.expects(:path).returns('my-category/my-subcatagory') | 63 | cat.expects(:path).returns('my-category/my-subcatagory') |
| 64 | cat.expects(:full_name).returns('category name') | 64 | cat.expects(:full_name).returns('category name') |
| 65 | + cat.expects(:environment).returns(Environment.default) | ||
| 66 | + Environment.any_instance.expects(:default_hostname).returns('example.com') | ||
| 65 | 67 | ||
| 66 | result = "/cat/my-category/my-subcatagory" | 68 | result = "/cat/my-category/my-subcatagory" |
| 67 | - expects(:link_to).with('category name', :controller => 'search', :action => 'category_index', :category_path => ['my-category', 'my-subcatagory']).returns(result) | 69 | + expects(:link_to).with('category name', :controller => 'search', :action => 'category_index', :category_path => ['my-category', 'my-subcatagory'], :host => 'example.com').returns(result) |
| 68 | assert_same result, link_to_category(cat) | 70 | assert_same result, link_to_category(cat) |
| 69 | end | 71 | end |
| 70 | 72 |
test/unit/enterprise_homepage_test.rb
| @@ -24,4 +24,33 @@ class EnterpriseHomepageTest < Test::Unit::TestCase | @@ -24,4 +24,33 @@ class EnterpriseHomepageTest < Test::Unit::TestCase | ||
| 24 | assert_match /5555 5555/, result | 24 | assert_match /5555 5555/, result |
| 25 | end | 25 | end |
| 26 | 26 | ||
| 27 | + should 'display products list' do | ||
| 28 | + ent = Enterprise.create!(:identifier => 'test_enterprise', :name => 'Test enteprise') | ||
| 29 | + prod = ent.products.create!(:name => 'Product test') | ||
| 30 | + a = EnterpriseHomepage.new(:name => 'article homepage') | ||
| 31 | + ent.articles << a | ||
| 32 | + result = a.to_html | ||
| 33 | + assert_match /Product test/, result | ||
| 34 | + end | ||
| 35 | + | ||
| 36 | + should 'not display products list if environment do not let' do | ||
| 37 | + e = Environment.default | ||
| 38 | + e.enable('disable_products_for_enterprises') | ||
| 39 | + e.save! | ||
| 40 | + ent = Enterprise.create!(:identifier => 'test_enterprise', :name => 'Test enteprise', :environment => e) | ||
| 41 | + prod = ent.products.create!(:name => 'Product test') | ||
| 42 | + a = EnterpriseHomepage.new(:name => 'article homepage') | ||
| 43 | + ent.articles << a | ||
| 44 | + result = a.to_html | ||
| 45 | + assert_no_match /Product test/, result | ||
| 46 | + end | ||
| 47 | + | ||
| 48 | + should 'display link to product' do | ||
| 49 | + ent = Enterprise.create!(:identifier => 'test_enterprise', :name => 'Test enteprise') | ||
| 50 | + prod = ent.products.create!(:name => 'Product test') | ||
| 51 | + a = EnterpriseHomepage.new(:name => 'article homepage') | ||
| 52 | + ent.articles << a | ||
| 53 | + result = a.to_html | ||
| 54 | + assert_match /catalog\/test_enterprise\/#{prod.id}/, result | ||
| 55 | + end | ||
| 27 | end | 56 | end |