Commit ac4a7edca517d5c2b50c4e0779749fbc3905de2c
Committed by
Fabio Teixeira
1 parent
fa785f1a
Exists in
article_blog_visualization_format
Add date format option for profile's articles
Signed-off-by: Arthur Del Esposte <arthurmde@gmail.com> Signed-off-by: David Carlos <ddavidcarlos1392@gmail.com> Signed-off-by: Gabriela Navarro <navarro1703@gmail.com>
Showing
13 changed files
with
181 additions
and
5 deletions
Show diff stats
app/controllers/my_profile/cms_controller.rb
| @@ -188,6 +188,18 @@ class CmsController < MyProfileController | @@ -188,6 +188,18 @@ class CmsController < MyProfileController | ||
| 188 | render :action => 'edit' | 188 | render :action => 'edit' |
| 189 | end | 189 | end |
| 190 | 190 | ||
| 191 | + def general_configuration | ||
| 192 | + @profile_data = profile | ||
| 193 | + if request.post? | ||
| 194 | + if @profile_data.update_attributes(params[:profile_data]) | ||
| 195 | + session[:notice] = _("Article date format updated successfully") | ||
| 196 | + else | ||
| 197 | + session[:notice] = _("Could not update article's date format") | ||
| 198 | + end | ||
| 199 | + redirect_to :action => 'index' | ||
| 200 | + end | ||
| 201 | + end | ||
| 202 | + | ||
| 191 | post_only :set_home_page | 203 | post_only :set_home_page |
| 192 | def set_home_page | 204 | def set_home_page |
| 193 | return render_access_denied unless user.can_change_homepage? | 205 | return render_access_denied unless user.can_change_homepage? |
app/helpers/blog_helper.rb
| @@ -2,7 +2,6 @@ module BlogHelper | @@ -2,7 +2,6 @@ module BlogHelper | ||
| 2 | 2 | ||
| 3 | include ArticleHelper | 3 | include ArticleHelper |
| 4 | 4 | ||
| 5 | - | ||
| 6 | def custom_options_for_article(article,tokenized_children) | 5 | def custom_options_for_article(article,tokenized_children) |
| 7 | @article = article | 6 | @article = article |
| 8 | hidden_field_tag('article[published]', 1) + | 7 | hidden_field_tag('article[published]', 1) + |
app/helpers/content_viewer_helper.rb
| @@ -24,8 +24,9 @@ module ContentViewerHelper | @@ -24,8 +24,9 @@ module ContentViewerHelper | ||
| 24 | unless args[:no_comments] || !article.accept_comments | 24 | unless args[:no_comments] || !article.accept_comments |
| 25 | comments = (" - %s") % link_to_comments(article) | 25 | comments = (" - %s") % link_to_comments(article) |
| 26 | end | 26 | end |
| 27 | + date_format = show_with_right_format_date article | ||
| 27 | title << content_tag('span', | 28 | title << content_tag('span', |
| 28 | - content_tag('span', show_date(article.published_at), :class => 'date') + | 29 | + date_format + |
| 29 | content_tag('span', _(", by %s") % (article.author ? link_to(article.author_name, article.author_url) : article.author_name), :class => 'author') + | 30 | content_tag('span', _(", by %s") % (article.author ? link_to(article.author_name, article.author_url) : article.author_name), :class => 'author') + |
| 30 | content_tag('span', comments, :class => 'comments'), | 31 | content_tag('span', comments, :class => 'comments'), |
| 31 | :class => 'created-at' | 32 | :class => 'created-at' |
| @@ -34,6 +35,24 @@ module ContentViewerHelper | @@ -34,6 +35,24 @@ module ContentViewerHelper | ||
| 34 | title | 35 | title |
| 35 | end | 36 | end |
| 36 | 37 | ||
| 38 | + def show_with_right_format_date article | ||
| 39 | + date_format = article.profile.date_format | ||
| 40 | + use_numbers = false | ||
| 41 | + year = true | ||
| 42 | + left_time = false | ||
| 43 | + if date_format == 'numbers_with_year' | ||
| 44 | + use_numbers = true | ||
| 45 | + elsif date_format == 'numbers' | ||
| 46 | + use_numbers = true | ||
| 47 | + year = false | ||
| 48 | + elsif date_format == 'month_name' | ||
| 49 | + year = false | ||
| 50 | + elsif date_format == 'past_time' | ||
| 51 | + left_time = true | ||
| 52 | + end | ||
| 53 | + content_tag('span', show_date(article.published_at, use_numbers , year, left_time), :class => 'date') | ||
| 54 | + end | ||
| 55 | + | ||
| 37 | def link_to_comments(article, args = {}) | 56 | def link_to_comments(article, args = {}) |
| 38 | return '' unless article.accept_comments? | 57 | return '' unless article.accept_comments? |
| 39 | reference_to_article number_of_comments(article), article, 'comments_list' | 58 | reference_to_article number_of_comments(article), article, 'comments_list' |
app/helpers/dates_helper.rb
| @@ -15,10 +15,12 @@ module DatesHelper | @@ -15,10 +15,12 @@ module DatesHelper | ||
| 15 | end | 15 | end |
| 16 | 16 | ||
| 17 | # formats a date for displaying. | 17 | # formats a date for displaying. |
| 18 | - def show_date(date, use_numbers = false, year=true) | 18 | + def show_date(date, use_numbers = false, year = true, left_time = false) |
| 19 | if date && use_numbers | 19 | if date && use_numbers |
| 20 | date_format = year ? _('%{month}/%{day}/%{year}') : _('%{month}/%{day}') | 20 | date_format = year ? _('%{month}/%{day}/%{year}') : _('%{month}/%{day}') |
| 21 | date_format % { :day => date.day, :month => date.month, :year => date.year } | 21 | date_format % { :day => date.day, :month => date.month, :year => date.year } |
| 22 | + elsif date && left_time | ||
| 23 | + date_format = time_ago_in_words(date) | ||
| 22 | elsif date | 24 | elsif date |
| 23 | date_format = year ? _('%{month_name} %{day}, %{year}') : _('%{month_name} %{day}') | 25 | date_format = year ? _('%{month_name} %{day}, %{year}') : _('%{month_name} %{day}') |
| 24 | date_format % { :day => date.day, :month_name => month_name(date.month), :year => date.year } | 26 | date_format % { :day => date.day, :month_name => month_name(date.month), :year => date.year } |
app/models/profile.rb
| @@ -3,7 +3,17 @@ | @@ -3,7 +3,17 @@ | ||
| 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 | - attr_accessible :name, :identifier, :public_profile, :nickname, :custom_footer, :custom_header, :address, :zip_code, :contact_phone, :image_builder, :description, :closed, :template_id, :environment, :lat, :lng, :is_template, :fields_privacy, :preferred_domain_id, :category_ids, :country, :city, :state, :national_region_code, :email, :contact_email, :redirect_l10n, :notification_time, :redirection_after_login, :email_suggestions, :allow_members_to_invite, :invite_friends_only, :secret | 6 | + |
| 7 | + attr_accessible :name, :identifier, :public_profile, :nickname, | ||
| 8 | + :custom_footer, :custom_header, :address, :zip_code, | ||
| 9 | + :contact_phone, :image_builder, :description, :closed, | ||
| 10 | + :template_id, :environment, :lat, :lng, :is_template, | ||
| 11 | + :fields_privacy, :preferred_domain_id, :category_ids, | ||
| 12 | + :country, :city, :state, :national_region_code, :email, | ||
| 13 | + :contact_email, :redirect_l10n, | ||
| 14 | + :notification_time, :redirection_after_login, | ||
| 15 | + :email_suggestions, :allow_members_to_invite, | ||
| 16 | + :invite_friends_only, :secret, :date_format | ||
| 7 | 17 | ||
| 8 | # use for internationalizable human type names in search facets | 18 | # use for internationalizable human type names in search facets |
| 9 | # reimplement on subclasses | 19 | # reimplement on subclasses |
| @@ -181,6 +191,12 @@ class Profile < ActiveRecord::Base | @@ -181,6 +191,12 @@ class Profile < ActiveRecord::Base | ||
| 181 | 191 | ||
| 182 | validates_length_of :description, :maximum => 550, :allow_nil => true | 192 | validates_length_of :description, :maximum => 550, :allow_nil => true |
| 183 | 193 | ||
| 194 | + validates_inclusion_of :date_format, | ||
| 195 | + :in => [ 'numbers_with_year', 'numbers', | ||
| 196 | + 'month_name_with_year', 'month_name', | ||
| 197 | + 'past_time'], | ||
| 198 | + :if => :date_format | ||
| 199 | + | ||
| 184 | # Valid identifiers must match this format. | 200 | # Valid identifiers must match this format. |
| 185 | IDENTIFIER_FORMAT = /^#{Noosfero.identifier_format}$/ | 201 | IDENTIFIER_FORMAT = /^#{Noosfero.identifier_format}$/ |
| 186 | 202 |
| @@ -0,0 +1,25 @@ | @@ -0,0 +1,25 @@ | ||
| 1 | +<div class="general-configuration"> | ||
| 2 | + | ||
| 3 | +<h2> <%= _('General Configuration:') %> </h2> | ||
| 4 | +<%= labelled_form_for :profile_data do |f|%> | ||
| 5 | + <h2><%= _("Article's date format") %> </h2> | ||
| 6 | + | ||
| 7 | + <%= _("This option will define how article's date will be showed") %> | ||
| 8 | + <br> | ||
| 9 | + <br> | ||
| 10 | + <%= select_tag('profile_data[date_format]', options_for_select([ | ||
| 11 | + [ _('mm/dd/yyyy'), 'numbers_with_year'], | ||
| 12 | + [ _('mm/dd'), 'numbers'], | ||
| 13 | + [ _('Month dd, yyyy'), 'month_name_with_year'], | ||
| 14 | + [ _('Month dd'), 'month_name'], | ||
| 15 | + [ _('X minutes/hours/days/months/years ago'), 'past_time'] | ||
| 16 | + ], @profile_data.date_format)) %> | ||
| 17 | + | ||
| 18 | + <br> | ||
| 19 | + <br> | ||
| 20 | + | ||
| 21 | + <%= submit_button('save', _('Save')) %> | ||
| 22 | + <%= modal_close_button(_('Cancel')) %> | ||
| 23 | +<% end %> | ||
| 24 | + | ||
| 25 | +</div> |
app/views/cms/view.html.erb
| @@ -18,6 +18,7 @@ | @@ -18,6 +18,7 @@ | ||
| 18 | <% parent_id = ((@article && @article.allow_children?) ? @article : nil) %> | 18 | <% parent_id = ((@article && @article.allow_children?) ? @article : nil) %> |
| 19 | 19 | ||
| 20 | <%= modal_button('new', _('New content'), :action => 'new', :parent_id => parent_id, :cms => true) %> | 20 | <%= modal_button('new', _('New content'), :action => 'new', :parent_id => parent_id, :cms => true) %> |
| 21 | + <%= modal_button('edit', _('General Configuration'), :action => 'general_configuration', :parent_id => parent_id, :cms => true) %> | ||
| 21 | <%= button(:back, _('Back to control panel'), :controller => 'profile_editor', :action => "index") %> | 22 | <%= button(:back, _('Back to control panel'), :controller => 'profile_editor', :action => "index") %> |
| 22 | <% end %> | 23 | <% end %> |
| 23 | 24 |
public/stylesheets/application.css
| @@ -3462,6 +3462,11 @@ table.cms-articles .icon:hover { | @@ -3462,6 +3462,11 @@ table.cms-articles .icon:hover { | ||
| 3462 | width: 455px; | 3462 | width: 455px; |
| 3463 | } | 3463 | } |
| 3464 | 3464 | ||
| 3465 | +.general-configuration { | ||
| 3466 | + padding: 5px 20px; | ||
| 3467 | + width: 455px; | ||
| 3468 | +} | ||
| 3469 | + | ||
| 3465 | .article-types { | 3470 | .article-types { |
| 3466 | padding-left: 5px; | 3471 | padding-left: 5px; |
| 3467 | margin-top: 20px; | 3472 | margin-top: 20px; |
test/functional/cms_controller_test.rb
| @@ -1869,6 +1869,24 @@ class CmsControllerTest < ActionController::TestCase | @@ -1869,6 +1869,24 @@ class CmsControllerTest < ActionController::TestCase | ||
| 1869 | assert_equal '[{"label":"linux","value":"linux"}]', @response.body | 1869 | assert_equal '[{"label":"linux","value":"linux"}]', @response.body |
| 1870 | end | 1870 | end |
| 1871 | 1871 | ||
| 1872 | + should 'save general configuration when is passed a valid value' do | ||
| 1873 | + post :general_configuration, profile: profile.identifier, :profile_data => { date_format: "numbers_with_year" } | ||
| 1874 | + profile.reload | ||
| 1875 | + | ||
| 1876 | + assert_equal profile.date_format, "numbers_with_year" | ||
| 1877 | + end | ||
| 1878 | + | ||
| 1879 | + should 'not save general configuration when is not passed a valid value' do | ||
| 1880 | + profile.date_format = "month_name_with_year" | ||
| 1881 | + profile.save! | ||
| 1882 | + | ||
| 1883 | + post :general_configuration, profile: profile.identifier, :profile_data => { date_format: "invalid_format" } | ||
| 1884 | + profile.reload | ||
| 1885 | + | ||
| 1886 | + assert_equal profile.date_format, "month_name_with_year" | ||
| 1887 | + end | ||
| 1888 | + | ||
| 1889 | + | ||
| 1872 | protected | 1890 | protected |
| 1873 | 1891 | ||
| 1874 | # FIXME this is to avoid adding an extra dependency for a proper JSON parser. | 1892 | # FIXME this is to avoid adding an extra dependency for a proper JSON parser. |
test/unit/content_viewer_helper_test.rb
| @@ -18,7 +18,7 @@ class ContentViewerHelperTest < ActionView::TestCase | @@ -18,7 +18,7 @@ class ContentViewerHelperTest < ActionView::TestCase | ||
| 18 | result = article_title(post) | 18 | result = article_title(post) |
| 19 | assert_tag_in_string result, :tag => 'span', :content => show_date(post.published_at) | 19 | assert_tag_in_string result, :tag => 'span', :content => show_date(post.published_at) |
| 20 | end | 20 | end |
| 21 | - | 21 | + |
| 22 | should 'display published-at for forum posts' do | 22 | should 'display published-at for forum posts' do |
| 23 | forum = fast_create(Forum, :name => 'Forum test', :profile_id => profile.id) | 23 | forum = fast_create(Forum, :name => 'Forum test', :profile_id => profile.id) |
| 24 | post = TextileArticle.create!(:name => 'post test', :profile => profile, :parent => forum) | 24 | post = TextileArticle.create!(:name => 'post test', :profile => profile, :parent => forum) |
| @@ -112,6 +112,42 @@ class ContentViewerHelperTest < ActionView::TestCase | @@ -112,6 +112,42 @@ class ContentViewerHelperTest < ActionView::TestCase | ||
| 112 | assert_match 'bt-bookmark.gif', addthis_image_tag | 112 | assert_match 'bt-bookmark.gif', addthis_image_tag |
| 113 | end | 113 | end |
| 114 | 114 | ||
| 115 | + should 'show date with mm/dd/yyyy' do | ||
| 116 | + article = TextileArticle.new(:name => 'post for test', :body => 'post for test', :profile => profile) | ||
| 117 | + article.published_at = Time.zone.local(2007, 2, 1, 15, 30, 45) | ||
| 118 | + article.save! | ||
| 119 | + profile.date_format = "numbers_with_year" | ||
| 120 | + result = show_with_right_format_date article | ||
| 121 | + assert_match /2\/1\/2007/, result | ||
| 122 | + end | ||
| 123 | + | ||
| 124 | + should 'show date with mm/dd' do | ||
| 125 | + article = TextileArticle.new(:name => 'post for test', :body => 'post for test', :profile => profile) | ||
| 126 | + article.published_at = Time.zone.local(2007, 2, 1, 15, 30, 45) | ||
| 127 | + article.save! | ||
| 128 | + profile.date_format = "numbers" | ||
| 129 | + result = show_with_right_format_date article | ||
| 130 | + assert_match /2\/1/, result | ||
| 131 | + end | ||
| 132 | + | ||
| 133 | + should 'show date with month name' do | ||
| 134 | + article = TextileArticle.new(:name => 'post for test', :body => 'post for test', :profile => profile) | ||
| 135 | + article.published_at = Time.zone.local(2007, 2, 1, 15, 30, 45) | ||
| 136 | + article.save! | ||
| 137 | + profile.date_format = "month_name" | ||
| 138 | + result = show_with_right_format_date article | ||
| 139 | + assert_match /February 1/, result | ||
| 140 | + end | ||
| 141 | + | ||
| 142 | + should 'show date with month name and year' do | ||
| 143 | + article = TextileArticle.new(:name => 'post for test', :body => 'post for test', :profile => profile) | ||
| 144 | + article.published_at = Time.zone.local(2007, 2, 1, 15, 30, 45) | ||
| 145 | + article.save! | ||
| 146 | + profile.date_format = "month_name_with_year" | ||
| 147 | + result = show_with_right_format_date article | ||
| 148 | + assert_match /February 1, 2007/, result | ||
| 149 | + end | ||
| 150 | + | ||
| 115 | protected | 151 | protected |
| 116 | include NoosferoTestHelper | 152 | include NoosferoTestHelper |
| 117 | include ActionView::Helpers::TextHelper | 153 | include ActionView::Helpers::TextHelper |
test/unit/dates_helper_test.rb
| @@ -146,4 +146,9 @@ class DatesHelperTest < ActiveSupport::TestCase | @@ -146,4 +146,9 @@ class DatesHelperTest < ActiveSupport::TestCase | ||
| 146 | assert_equal Date.new(Date.today.year, Date.today.month, 1), build_date('', '') | 146 | assert_equal Date.new(Date.today.year, Date.today.month, 1), build_date('', '') |
| 147 | end | 147 | end |
| 148 | 148 | ||
| 149 | + should 'show how long it has passed since a specific date' do | ||
| 150 | + date = Time.zone.now | ||
| 151 | + assert_equal show_date(date, false, false, true), time_ago_in_words(date) | ||
| 152 | + end | ||
| 153 | + | ||
| 149 | end | 154 | end |
test/unit/profile_test.rb
| @@ -2176,4 +2176,33 @@ class ProfileTest < ActiveSupport::TestCase | @@ -2176,4 +2176,33 @@ class ProfileTest < ActiveSupport::TestCase | ||
| 2176 | assert_includes Profile.enabled, p2 | 2176 | assert_includes Profile.enabled, p2 |
| 2177 | assert_not_includes Profile.enabled, p3 | 2177 | assert_not_includes Profile.enabled, p3 |
| 2178 | end | 2178 | end |
| 2179 | + | ||
| 2180 | + should 'validates_inclusion_of date format' do | ||
| 2181 | + profile = fast_create(Profile) | ||
| 2182 | + | ||
| 2183 | + profile.date_format = "invalid_format" | ||
| 2184 | + profile.valid? | ||
| 2185 | + assert profile.errors[:date_format.to_s].present? | ||
| 2186 | + | ||
| 2187 | + profile.date_format = "numbers_with_year" | ||
| 2188 | + profile.valid? | ||
| 2189 | + assert !profile.errors[:date_format.to_s].present? | ||
| 2190 | + | ||
| 2191 | + profile.date_format = "numbers" | ||
| 2192 | + profile.valid? | ||
| 2193 | + assert !profile.errors[:date_format.to_s].present? | ||
| 2194 | + | ||
| 2195 | + profile.date_format = "month_name_with_year" | ||
| 2196 | + profile.valid? | ||
| 2197 | + assert !profile.errors[:date_format.to_s].present? | ||
| 2198 | + | ||
| 2199 | + profile.date_format = "month_name" | ||
| 2200 | + profile.valid? | ||
| 2201 | + assert !profile.errors[:date_format.to_s].present? | ||
| 2202 | + | ||
| 2203 | + profile.date_format = "past_time" | ||
| 2204 | + profile.valid? | ||
| 2205 | + assert !profile.errors[:date_format.to_s].present? | ||
| 2206 | + | ||
| 2207 | + end | ||
| 2179 | end | 2208 | end |