Commit b2833502d0184d05a577d9544379302412dc38f8

Authored by AntonioTerceiro
1 parent 7707a13c

ActionItem158: a better CMS


git-svn-id: https://svn.colivre.coop.br/svn/noosfero/trunk@1790 3f533792-8f58-4932-b0fe-aaf55b0a4547
app/controllers/my_profile/cms_controller.rb
... ... @@ -19,12 +19,14 @@ class CmsController < MyProfileController
19 19  
20 20 def view
21 21 @article = profile.articles.find(params[:id])
22   - @subitems = @article.children
  22 + @subitems = @article.children.reject {|item| item.folder? }
  23 + @folders = @article.children.select {|item| item.folder? }
23 24 end
24 25  
25 26 def index
26 27 @article = nil
27   - @subitems = profile.top_level_articles
  28 + @subitems = profile.top_level_articles.reject {|item| item.folder? }
  29 + @folders = profile.top_level_articles.select {|item| item.folder?}
28 30 render :action => 'view'
29 31 end
30 32  
... ... @@ -35,7 +37,7 @@ class CmsController < MyProfileController
35 37 if request.post?
36 38 @article.last_changed_by = user
37 39 if @article.update_attributes(params[:article])
38   - redirect_to :action => 'view', :id => @article.id
  40 + redirect_back
39 41 return
40 42 end
41 43 end
... ... @@ -78,7 +80,7 @@ class CmsController < MyProfileController
78 80 @article.last_changed_by = user
79 81 if request.post?
80 82 if @article.save
81   - redirect_to :action => 'view', :id => @article.id
  83 + redirect_back
82 84 return
83 85 end
84 86 end
... ... @@ -102,5 +104,15 @@ class CmsController < MyProfileController
102 104 redirect_to :action => (@article.parent ? 'view' : 'index'), :id => @article.parent
103 105 end
104 106  
  107 + protected
  108 +
  109 + def redirect_back
  110 + if @article.parent
  111 + redirect_to :action => 'view', :id => @article.parent
  112 + else
  113 + redirect_to :action => 'index'
  114 + end
  115 + end
  116 +
105 117 end
106 118  
... ...
app/models/article.rb
... ... @@ -112,6 +112,10 @@ class Article < ActiveRecord::Base
112 112 true
113 113 end
114 114  
  115 + def folder?
  116 + false
  117 + end
  118 +
115 119 def self.find_by_initial(initial)
116 120 self.find(:all, :order => 'articles.name', :conditions => [ 'articles.name like (?) or articles.name like (?)', initial + '%', initial.upcase + '%'])
117 121 end
... ...
app/models/folder.rb
... ... @@ -20,4 +20,8 @@ class Folder < Article
20 20 content_tag('ul', children.map { |child| content_tag('li', link_to(child.name, child.url)) }, :class => 'folder-listing')
21 21 end
22 22  
  23 + def folder?
  24 + true
  25 + end
  26 +
23 27 end
... ...
app/views/cms/edit.rhtml
... ... @@ -16,6 +16,11 @@
16 16 %>
17 17  
18 18 <% button_bar do %>
19   - <%= submit_button('save', _('Save'), :cancel => (@article.parent ? { :action => 'view', :id => @article.parent.id } : { :action => 'index' } )) %>
  19 + <%= submit_button :save, _('Save') %>
  20 + <% if @parent_id || @article.parent %>
  21 + <%= button :cancel, _('Cancel'), :action => 'view', :id => @parent_id || @article.parent %>
  22 + <% else %>
  23 + <%= button :cancel, _('Cancel'), :action => 'index' %>
  24 + <% end %>
20 25 <% end %>
21 26 <% end %>
... ...
app/views/cms/view.rhtml
... ... @@ -9,68 +9,59 @@
9 9 <%= icon('cms') %>
10 10 <%= _('Content management') %>
11 11 </h2>
12   -
13   - <% button_bar(:style => 'margin-bottom: 1em;') do %>
14   - <%= lightbox_button('new', _('New article'), :action => 'new') %>
15   - <% end %>
16   -
17 12 <% end %>
18 13  
19   -<%# subitem %>
20   -<% if !@subitems.empty? && @article %>
21   - <%= toggle_panel(_('Hide subitems'), _('Show subitems'), 'article-subitems') %>
  14 +<% button_bar(:style => 'margin-bottom: 1em;') do %>
  15 + <% parent_id = ((@article && @article.allow_children?) ? @article : nil) %>
  16 + <%= button :add, _('New folder'), :action => 'new', :type => 'Folder', :parent_id => parent_id %>
  17 + <%= lightbox_button('new', _('New article'), :action => 'new', :parent_id => parent_id) %>
22 18 <% end %>
23   -
24   -<div id='article-subitems'>
25   - <div class='file-manager-title'><%= @article ? _('Subitems') : _('Articles') %></div>
26   - <div class='file-manager-small'>
27   - <% unless @subitems.empty? %>
28   - <ul>
29   - <% @subitems.each do |item| %>
30   - <li>
31   - <%= file_manager_button(item.name, icon_for_article(item), :action => 'view', :id => item.id) %>
32   - </li>
33   - <% end %>
34   - </ul>
35   - <% end %>
36 19  
37   - <% if @article %>
38   - <% button_bar(:class => 'file-manager-controls') do %>
39   - <% if @article.allow_children? %>
40   - <%= lightbox_button('new', _('New subitem'), :action => 'new', :parent_id => @article.id) %>
41   - <% end %>
42   - <%= button('up', _('Go up one level'), :action => (@article.parent ? 'view' : 'index'), :id => @article.parent) %>
43   - <% end %>
44   - <% end %>
45   - </div>
46   -</div> <!-- article-children -->
  20 +<table width='100%'>
47 21  
48   -<%# display the article content %>
49   -<div id='article-contents' style='clear: left;'>
50   - <% if @article %>
51   - <h2>
52   - <%= @article.name %>
53   - <%= image_tag(icon_for_article(@article)) %>
54   - </h2>
55   - <% button_bar(:id => 'article-controls') do %>
56   -
57   - <ul>
58   - <li>
59   - <%= _('"%{article}", last changed by %{author}') % { :article => @article.name, :author => (@article.last_changed_by ? @article.last_changed_by.name : _('Unknown User')) } %>
60   - </li>
61   - <li>
62   - <%= _('Public address of this article: %s') % link_to(url_for(@article.url), @article.url) %>
63   - </li>
64   - <li>
65   - <%= _('Tags:') %> <%= @article.tag_list %>
66   - </li>
67   - <%= _('Categories:') %> <%= @article.categories.map { |item| item.name }.join(', ') %>
68   - </ul>
  22 + <%# folders %>
  23 + <tr>
  24 + <th colspan='2'>
  25 + <%= _('Folders') %>
  26 + </th>
  27 + </tr>
  28 + <% if @folders.empty? %>
  29 + <tr><td colspan='2' align='center'><em><%= _('None') %></em></td></tr>
  30 + <% end %>
  31 + <% for folder in @folders %>
  32 + <tr>
  33 + <td>
  34 + <%= image_tag(icon_for_article(folder)) %>
  35 + <%= link_to folder.name, :action => 'view', :id => folder.id %>
  36 + </td>
  37 + <td>
  38 + <%= link_to _('Properties'), :action => 'edit', :id => folder.id %>
  39 + <%= link_to _('View'), folder.url %>
  40 + </td>
  41 + </tr>
  42 + <% end %>
69 43  
70   - <%= button('edit', _('Edit'), { :action => 'edit', :id => @article}) %>
71   - <%= button('home', _('Use as homepage'), { :action => 'set_home_page', :id => @article }, { :method => :post }) %>
72   - <%= button('delete', _('Delete'), { :action => 'destroy', :id => @article }, :method => :post, :confirm => _('Are you sure you wan to remove this article?')) %>
73   - <% end %>
74   - <%= @article.to_html %>
  44 + <%# non-folder subitems %>
  45 + <tr>
  46 + <th colspan='2'>
  47 + <%= _('Articles') %>
  48 + </th>
  49 + </tr>
  50 + <% if @subitems.empty? %>
  51 + <tr><td colspan='2' align='center'><em><%= _('None') %></em></td></tr>
  52 + <% end %>
  53 + <% for item in @subitems %>
  54 + <tr>
  55 + <td>
  56 + <%= image_tag(icon_for_article(item)) %>
  57 + <%= link_to item.name, :id => item.id %>
  58 + </td>
  59 + <td>
  60 + <%= link_to _('Edit'), :action => 'edit', :id => item.id %>
  61 + <%= link_to _('View'), item.url %>
  62 + </td>
  63 + </tr>
75 64 <% end %>
76   -</div>
  65 +
  66 +
  67 +</table>
... ...
test/functional/cms_controller_test.rb
... ... @@ -313,6 +313,89 @@ class CmsControllerTest &lt; Test::Unit::TestCase
313 313 assert_tag :tag => 'input', :attributes => { :name => 'parent_id', :value => profile.home_page.id }
314 314 end
315 315  
  316 + should 'list folders at top level' do
  317 + f1 = Folder.new(:name => 'f1'); profile.articles << f1; f1.save!
  318 + f2 = Folder.new(:name => 'f2'); profile.articles << f2; f2.save!
316 319  
  320 + get :index, :profile => profile.identifier
  321 + assert_equal [f1, f2], assigns(:folders)
  322 + assert_not_includes assigns(:subitems), f1
  323 + assert_not_includes assigns(:subitems), f2
  324 + end
  325 +
  326 + should 'list folders inside another folder' do
  327 + parent = Folder.new(:name => 'parent'); profile.articles << parent; parent.save!
  328 + f1 = Folder.new(:name => 'f1', :parent => parent); profile.articles << f1; f1.save!
  329 + f2 = Folder.new(:name => 'f2', :parent => parent); profile.articles << f2; f2.save!
  330 +
  331 + get :view, :profile => profile.identifier, :id => parent.id
  332 + assert_equal [f1, f2], assigns(:folders)
  333 + assert_not_includes assigns(:subitems), f1
  334 + assert_not_includes assigns(:subitems), f2
  335 + end
  336 +
  337 + should 'offer to create new top-level folder' do
  338 + get :index, :profile => profile.identifier
  339 + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/new?type=Folder"}
  340 + end
  341 +
  342 + should 'offer to create sub-folder' do
  343 + f = Folder.new(:name => 'f'); profile.articles << f; f.save!
  344 + get :view, :profile => profile.identifier, :id => f.id
  345 +
  346 + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/new?parent_id=#{f.id}&amp;type=Folder" }
  347 + end
  348 +
  349 + should 'redirect back to index after creating top-level article' do
  350 + post :new, :profile => profile.identifier, :type => 'TextileArticle', :article => { :name => 'test' }
  351 + assert_redirected_to :action => 'index'
  352 + end
  353 +
  354 + should 'redirect back to folder after creating article inside it' do
  355 + f = Folder.new(:name => 'f'); profile.articles << f; f.save!
  356 + post :new, :profile => profile.identifier, :type => 'TextileArticle', :parent_id => f.id, :article => { :name => 'test' }
  357 + assert_redirected_to :action => 'view', :id => f.id
  358 + end
  359 +
  360 + should 'redirect back to index after editing top-level article' do
  361 + f = Folder.new(:name => 'f'); profile.articles << f; f.save!
  362 + post :edit, :profile => profile.identifier, :id => f.id
  363 + assert_redirected_to :action => 'index'
  364 + end
  365 +
  366 + should 'redirect back to folder after editing article inside it' do
  367 + f = Folder.new(:name => 'f'); profile.articles << f; f.save!
  368 + a = TextileArticle.create!(:parent => f, :name => 'test', :profile_id => profile.id)
  369 +
  370 + post :edit, :profile => profile.identifier, :id => a.id
  371 + assert_redirected_to :action => 'view', :id => f.id
  372 + end
  373 +
  374 + should 'point back to index when cancelling creation of top-level article' do
  375 + get :new, :profile => profile.identifier, :type => 'Folder'
  376 + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms" }, :descendant => { :content => /Cancel/ }
  377 + end
  378 +
  379 + should 'point back to index when cancelling edition of top-level article' do
  380 + f = Folder.new(:name => 'f'); profile.articles << f; f.save!
  381 + get :edit, :profile => profile.identifier, :id => f.id
  382 +
  383 + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms" }, :descendant => { :content => /Cancel/ }
  384 + end
  385 +
  386 + should 'point back to folder when cancelling creation of an article inside it' do
  387 + f = Folder.new(:name => 'f'); profile.articles << f; f.save!
  388 + get :new, :profile => profile.identifier, :type => 'Folder', :parent_id => f.id
  389 +
  390 + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/view/#{f.id}" }, :descendant => { :content => /Cancel/ }
  391 + end
  392 +
  393 + should 'point back to folder when cancelling edition of an article inside it' do
  394 + f = Folder.new(:name => 'f'); profile.articles << f; f.save!
  395 + a = TextileArticle.create!(:name => 'test', :parent => f, :profile_id => profile.id)
  396 + get :edit, :profile => profile.identifier, :id => a.id
  397 +
  398 + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/view/#{f.id}" }, :descendant => { :content => /Cancel/ }
  399 + end
317 400  
318 401 end
... ...
test/unit/article_test.rb
... ... @@ -229,4 +229,8 @@ class ArticleTest &lt; Test::Unit::TestCase
229 229 assert_not_includes list, a2
230 230 end
231 231  
  232 + should 'identify itself as a non-folder' do
  233 + assert !Article.new.folder?, 'should identify itself as non-folder'
  234 + end
  235 +
232 236 end
... ...
test/unit/folder_test.rb
... ... @@ -30,4 +30,8 @@ class FolderTest &lt; ActiveSupport::TestCase
30 30 assert_match(/<li><a href=".*\/testuser\/f\/otherarticle">otherarticle<\/a><\/li>/, f.to_html)
31 31 end
32 32  
  33 + should 'identify as folder' do
  34 + assert Folder.new.folder?, 'folder must identity itself as folder'
  35 + end
  36 +
33 37 end
... ...