From b2833502d0184d05a577d9544379302412dc38f8 Mon Sep 17 00:00:00 2001 From: AntonioTerceiro Date: Tue, 13 May 2008 23:21:48 +0000 Subject: [PATCH] ActionItem158: a better CMS --- app/controllers/my_profile/cms_controller.rb | 20 ++++++++++++++++---- app/models/article.rb | 4 ++++ app/models/folder.rb | 4 ++++ app/views/cms/edit.rhtml | 7 ++++++- app/views/cms/view.rhtml | 107 +++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------------------------- test/functional/cms_controller_test.rb | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/unit/article_test.rb | 4 ++++ test/unit/folder_test.rb | 4 ++++ 8 files changed, 170 insertions(+), 63 deletions(-) diff --git a/app/controllers/my_profile/cms_controller.rb b/app/controllers/my_profile/cms_controller.rb index 8adf0f2..b364bcf 100644 --- a/app/controllers/my_profile/cms_controller.rb +++ b/app/controllers/my_profile/cms_controller.rb @@ -19,12 +19,14 @@ class CmsController < MyProfileController def view @article = profile.articles.find(params[:id]) - @subitems = @article.children + @subitems = @article.children.reject {|item| item.folder? } + @folders = @article.children.select {|item| item.folder? } end def index @article = nil - @subitems = profile.top_level_articles + @subitems = profile.top_level_articles.reject {|item| item.folder? } + @folders = profile.top_level_articles.select {|item| item.folder?} render :action => 'view' end @@ -35,7 +37,7 @@ class CmsController < MyProfileController if request.post? @article.last_changed_by = user if @article.update_attributes(params[:article]) - redirect_to :action => 'view', :id => @article.id + redirect_back return end end @@ -78,7 +80,7 @@ class CmsController < MyProfileController @article.last_changed_by = user if request.post? if @article.save - redirect_to :action => 'view', :id => @article.id + redirect_back return end end @@ -102,5 +104,15 @@ class CmsController < MyProfileController redirect_to :action => (@article.parent ? 'view' : 'index'), :id => @article.parent end + protected + + def redirect_back + if @article.parent + redirect_to :action => 'view', :id => @article.parent + else + redirect_to :action => 'index' + end + end + end diff --git a/app/models/article.rb b/app/models/article.rb index 423edc6..b877bd5 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -112,6 +112,10 @@ class Article < ActiveRecord::Base true end + def folder? + false + end + def self.find_by_initial(initial) self.find(:all, :order => 'articles.name', :conditions => [ 'articles.name like (?) or articles.name like (?)', initial + '%', initial.upcase + '%']) end diff --git a/app/models/folder.rb b/app/models/folder.rb index 699ee49..f288b32 100644 --- a/app/models/folder.rb +++ b/app/models/folder.rb @@ -20,4 +20,8 @@ class Folder < Article content_tag('ul', children.map { |child| content_tag('li', link_to(child.name, child.url)) }, :class => 'folder-listing') end + def folder? + true + end + end diff --git a/app/views/cms/edit.rhtml b/app/views/cms/edit.rhtml index ac22745..186cb2e 100644 --- a/app/views/cms/edit.rhtml +++ b/app/views/cms/edit.rhtml @@ -16,6 +16,11 @@ %> <% button_bar do %> - <%= submit_button('save', _('Save'), :cancel => (@article.parent ? { :action => 'view', :id => @article.parent.id } : { :action => 'index' } )) %> + <%= submit_button :save, _('Save') %> + <% if @parent_id || @article.parent %> + <%= button :cancel, _('Cancel'), :action => 'view', :id => @parent_id || @article.parent %> + <% else %> + <%= button :cancel, _('Cancel'), :action => 'index' %> + <% end %> <% end %> <% end %> diff --git a/app/views/cms/view.rhtml b/app/views/cms/view.rhtml index 71383f1..eabbe15 100644 --- a/app/views/cms/view.rhtml +++ b/app/views/cms/view.rhtml @@ -9,68 +9,59 @@ <%= icon('cms') %> <%= _('Content management') %> - - <% button_bar(:style => 'margin-bottom: 1em;') do %> - <%= lightbox_button('new', _('New article'), :action => 'new') %> - <% end %> - <% end %> -<%# subitem %> -<% if !@subitems.empty? && @article %> - <%= toggle_panel(_('Hide subitems'), _('Show subitems'), 'article-subitems') %> +<% button_bar(:style => 'margin-bottom: 1em;') do %> + <% parent_id = ((@article && @article.allow_children?) ? @article : nil) %> + <%= button :add, _('New folder'), :action => 'new', :type => 'Folder', :parent_id => parent_id %> + <%= lightbox_button('new', _('New article'), :action => 'new', :parent_id => parent_id) %> <% end %> - -
-
<%= @article ? _('Subitems') : _('Articles') %>
-
- <% unless @subitems.empty? %> -
    - <% @subitems.each do |item| %> -
  • - <%= file_manager_button(item.name, icon_for_article(item), :action => 'view', :id => item.id) %> -
  • - <% end %> -
- <% end %> - <% if @article %> - <% button_bar(:class => 'file-manager-controls') do %> - <% if @article.allow_children? %> - <%= lightbox_button('new', _('New subitem'), :action => 'new', :parent_id => @article.id) %> - <% end %> - <%= button('up', _('Go up one level'), :action => (@article.parent ? 'view' : 'index'), :id => @article.parent) %> - <% end %> - <% end %> -
-
+ -<%# display the article content %> -
- <% if @article %> -

- <%= @article.name %> - <%= image_tag(icon_for_article(@article)) %> -

- <% button_bar(:id => 'article-controls') do %> - - + <%# folders %> +
+ + + <% if @folders.empty? %> + + <% end %> + <% for folder in @folders %> + + + + + <% end %> - <%= button('edit', _('Edit'), { :action => 'edit', :id => @article}) %> - <%= button('home', _('Use as homepage'), { :action => 'set_home_page', :id => @article }, { :method => :post }) %> - <%= button('delete', _('Delete'), { :action => 'destroy', :id => @article }, :method => :post, :confirm => _('Are you sure you wan to remove this article?')) %> - <% end %> - <%= @article.to_html %> + <%# non-folder subitems %> + + + + <% if @subitems.empty? %> + + <% end %> + <% for item in @subitems %> + + + + <% end %> - + + +
+ <%= _('Folders') %> +
<%= _('None') %>
+ <%= image_tag(icon_for_article(folder)) %> + <%= link_to folder.name, :action => 'view', :id => folder.id %> + + <%= link_to _('Properties'), :action => 'edit', :id => folder.id %> + <%= link_to _('View'), folder.url %> +
+ <%= _('Articles') %> +
<%= _('None') %>
+ <%= image_tag(icon_for_article(item)) %> + <%= link_to item.name, :id => item.id %> + + <%= link_to _('Edit'), :action => 'edit', :id => item.id %> + <%= link_to _('View'), item.url %> +
diff --git a/test/functional/cms_controller_test.rb b/test/functional/cms_controller_test.rb index 942670f..109a37a 100644 --- a/test/functional/cms_controller_test.rb +++ b/test/functional/cms_controller_test.rb @@ -313,6 +313,89 @@ class CmsControllerTest < Test::Unit::TestCase assert_tag :tag => 'input', :attributes => { :name => 'parent_id', :value => profile.home_page.id } end + should 'list folders at top level' do + f1 = Folder.new(:name => 'f1'); profile.articles << f1; f1.save! + f2 = Folder.new(:name => 'f2'); profile.articles << f2; f2.save! + get :index, :profile => profile.identifier + assert_equal [f1, f2], assigns(:folders) + assert_not_includes assigns(:subitems), f1 + assert_not_includes assigns(:subitems), f2 + end + + should 'list folders inside another folder' do + parent = Folder.new(:name => 'parent'); profile.articles << parent; parent.save! + f1 = Folder.new(:name => 'f1', :parent => parent); profile.articles << f1; f1.save! + f2 = Folder.new(:name => 'f2', :parent => parent); profile.articles << f2; f2.save! + + get :view, :profile => profile.identifier, :id => parent.id + assert_equal [f1, f2], assigns(:folders) + assert_not_includes assigns(:subitems), f1 + assert_not_includes assigns(:subitems), f2 + end + + should 'offer to create new top-level folder' do + get :index, :profile => profile.identifier + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/new?type=Folder"} + end + + should 'offer to create sub-folder' do + f = Folder.new(:name => 'f'); profile.articles << f; f.save! + get :view, :profile => profile.identifier, :id => f.id + + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/new?parent_id=#{f.id}&type=Folder" } + end + + should 'redirect back to index after creating top-level article' do + post :new, :profile => profile.identifier, :type => 'TextileArticle', :article => { :name => 'test' } + assert_redirected_to :action => 'index' + end + + should 'redirect back to folder after creating article inside it' do + f = Folder.new(:name => 'f'); profile.articles << f; f.save! + post :new, :profile => profile.identifier, :type => 'TextileArticle', :parent_id => f.id, :article => { :name => 'test' } + assert_redirected_to :action => 'view', :id => f.id + end + + should 'redirect back to index after editing top-level article' do + f = Folder.new(:name => 'f'); profile.articles << f; f.save! + post :edit, :profile => profile.identifier, :id => f.id + assert_redirected_to :action => 'index' + end + + should 'redirect back to folder after editing article inside it' do + f = Folder.new(:name => 'f'); profile.articles << f; f.save! + a = TextileArticle.create!(:parent => f, :name => 'test', :profile_id => profile.id) + + post :edit, :profile => profile.identifier, :id => a.id + assert_redirected_to :action => 'view', :id => f.id + end + + should 'point back to index when cancelling creation of top-level article' do + get :new, :profile => profile.identifier, :type => 'Folder' + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms" }, :descendant => { :content => /Cancel/ } + end + + should 'point back to index when cancelling edition of top-level article' do + f = Folder.new(:name => 'f'); profile.articles << f; f.save! + get :edit, :profile => profile.identifier, :id => f.id + + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms" }, :descendant => { :content => /Cancel/ } + end + + should 'point back to folder when cancelling creation of an article inside it' do + f = Folder.new(:name => 'f'); profile.articles << f; f.save! + get :new, :profile => profile.identifier, :type => 'Folder', :parent_id => f.id + + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/view/#{f.id}" }, :descendant => { :content => /Cancel/ } + end + + should 'point back to folder when cancelling edition of an article inside it' do + f = Folder.new(:name => 'f'); profile.articles << f; f.save! + a = TextileArticle.create!(:name => 'test', :parent => f, :profile_id => profile.id) + get :edit, :profile => profile.identifier, :id => a.id + + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/view/#{f.id}" }, :descendant => { :content => /Cancel/ } + end end diff --git a/test/unit/article_test.rb b/test/unit/article_test.rb index 2381c9e..e412877 100644 --- a/test/unit/article_test.rb +++ b/test/unit/article_test.rb @@ -229,4 +229,8 @@ class ArticleTest < Test::Unit::TestCase assert_not_includes list, a2 end + should 'identify itself as a non-folder' do + assert !Article.new.folder?, 'should identify itself as non-folder' + end + end diff --git a/test/unit/folder_test.rb b/test/unit/folder_test.rb index 842336c..b4ab4a6 100644 --- a/test/unit/folder_test.rb +++ b/test/unit/folder_test.rb @@ -30,4 +30,8 @@ class FolderTest < ActiveSupport::TestCase assert_match(/
  • otherarticle<\/a><\/li>/, f.to_html) end + should 'identify as folder' do + assert Folder.new.folder?, 'folder must identity itself as folder' + end + end -- libgit2 0.21.2