From: Jean-Philippe Lang Date: Sat, 26 Jul 2008 11:46:24 +0000 (+0000) Subject: Wiki page hierarchy (#528). Parent page can be assigned on Rename screen. X-Git-Tag: 0.8.0-RC1~322 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=60d066f943c68a348fee3a8350dc5ba88878b69c;p=redmine.git Wiki page hierarchy (#528). Parent page can be assigned on Rename screen. git-svn-id: http://redmine.rubyforge.org/svn/trunk@1698 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- diff --git a/app/controllers/wiki_controller.rb b/app/controllers/wiki_controller.rb index 8655cfed7..2430205cf 100644 --- a/app/controllers/wiki_controller.rb +++ b/app/controllers/wiki_controller.rb @@ -147,6 +147,7 @@ class WikiController < ApplicationController :joins => "LEFT JOIN #{WikiContent.table_name} ON #{WikiContent.table_name}.page_id = #{WikiPage.table_name}.id", :order => 'title' @pages_by_date = @pages.group_by {|p| p.updated_on.to_date} + @pages_by_parent_id = @pages.group_by(&:parent_id) # export wiki to a single html file when 'export' @pages = @wiki.pages.find :all, :order => 'title' diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 7bcec461e..f5ce7ecda 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -177,7 +177,8 @@ module ApplicationHelper end def breadcrumb(*args) - content_tag('p', args.join(' » ') + ' » ', :class => 'breadcrumb') + elements = args.flatten + elements.any? ? content_tag('p', args.join(' » ') + ' » ', :class => 'breadcrumb') : nil end def html_title(*args) diff --git a/app/helpers/wiki_helper.rb b/app/helpers/wiki_helper.rb index 980035bd4..d27ce3ea3 100644 --- a/app/helpers/wiki_helper.rb +++ b/app/helpers/wiki_helper.rb @@ -17,6 +17,22 @@ module WikiHelper + def render_page_hierarchy(pages, node=nil) + content = '' + if pages[node] + content << "\n" + end + content + end + def html_diff(wdiff) words = wdiff.words.collect{|word| h(word)} words_add = 0 diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 65fc1f68c..2416fab74 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -22,7 +22,8 @@ class WikiPage < ActiveRecord::Base belongs_to :wiki has_one :content, :class_name => 'WikiContent', :foreign_key => 'page_id', :dependent => :destroy has_many :attachments, :as => :container, :dependent => :destroy - + acts_as_tree :order => 'title' + acts_as_event :title => Proc.new {|o| "#{l(:label_wiki)}: #{o.title}"}, :description => :text, :datetime => :created_on, @@ -110,6 +111,24 @@ class WikiPage < ActiveRecord::Base def editable_by?(usr) !protected? || usr.allowed_to?(:protect_wiki_pages, wiki.project) end + + def parent_title + @parent_title || (self.parent && self.parent.pretty_title) + end + + def parent_title=(t) + @parent_title = t + parent_page = t.blank? ? nil : self.wiki.find_page(t) + self.parent = parent_page + end + + protected + + def validate + errors.add(:parent_title, :activerecord_error_invalid) if !@parent_title.blank? && parent.nil? + errors.add(:parent_title, :activerecord_error_circular_dependency) if parent && (parent == self || parent.ancestors.include?(self)) + errors.add(:parent_title, :activerecord_error_not_same_project) if parent && (parent.wiki_id != wiki_id) + end end class WikiDiff diff --git a/app/views/wiki/rename.rhtml b/app/views/wiki/rename.rhtml index 0c069f43d..260f9af8b 100644 --- a/app/views/wiki/rename.rhtml +++ b/app/views/wiki/rename.rhtml @@ -4,8 +4,9 @@ <% labelled_tabular_form_for :wiki_page, @page, :url => { :action => 'rename' } do |f| %>
-

<%= f.text_field :title, :required => true, :size => 255 %>

+

<%= f.text_field :title, :required => true, :size => 100 %>

<%= f.check_box :redirect_existing_links %>

+

<%= f.text_field :parent_title, :size => 100 %>

<%= submit_tag l(:button_rename) %> <% end %> diff --git a/app/views/wiki/show.rhtml b/app/views/wiki/show.rhtml index 8092525bd..255b904f5 100644 --- a/app/views/wiki/show.rhtml +++ b/app/views/wiki/show.rhtml @@ -10,6 +10,8 @@ <%= link_to(l(:label_history), {:action => 'history', :page => @page.title}, :class => 'icon icon-history') %> +<%= breadcrumb(@page.ancestors.reverse.collect {|parent| link_to h(parent.pretty_title), {:page => parent.title}}) %> + <% if @content.version != @page.content.version %>

<%= link_to(('« ' + l(:label_previous)), :action => 'index', :page => @page.title, :version => (@content.version - 1)) + " - " if @content.version > 1 %> diff --git a/app/views/wiki/special_page_index.rhtml b/app/views/wiki/special_page_index.rhtml index f21cc3423..72b395ef7 100644 --- a/app/views/wiki/special_page_index.rhtml +++ b/app/views/wiki/special_page_index.rhtml @@ -4,11 +4,7 @@

<%= l(:label_no_data) %>

<% end %> - +<%= render_page_hierarchy(@pages_by_parent_id) %> <% content_for :sidebar do %> <%= render :partial => 'sidebar' %> diff --git a/db/migrate/095_add_wiki_pages_parent_id.rb b/db/migrate/095_add_wiki_pages_parent_id.rb new file mode 100644 index 000000000..36b922ec1 --- /dev/null +++ b/db/migrate/095_add_wiki_pages_parent_id.rb @@ -0,0 +1,9 @@ +class AddWikiPagesParentId < ActiveRecord::Migration + def self.up + add_column :wiki_pages, :parent_id, :integer, :default => nil + end + + def self.down + remove_column :wiki_pages, :parent_id + end +end diff --git a/lang/bg.yml b/lang/bg.yml index c87e3bebc..e8191dc20 100644 --- a/lang/bg.yml +++ b/lang/bg.yml @@ -632,3 +632,4 @@ label_generate_key: Generate a key setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +field_parent_title: Parent page diff --git a/lang/cs.yml b/lang/cs.yml index 6669c6cf3..68273191a 100644 --- a/lang/cs.yml +++ b/lang/cs.yml @@ -637,3 +637,4 @@ label_generate_key: Generate a key setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +field_parent_title: Parent page diff --git a/lang/da.yml b/lang/da.yml index cf40e1763..1b5aba69c 100644 --- a/lang/da.yml +++ b/lang/da.yml @@ -634,3 +634,4 @@ label_generate_key: Generate a key setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +field_parent_title: Parent page diff --git a/lang/de.yml b/lang/de.yml index adc3dd4e9..dc2960c9c 100644 --- a/lang/de.yml +++ b/lang/de.yml @@ -633,3 +633,4 @@ label_generate_key: Generate a key setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +field_parent_title: Parent page diff --git a/lang/en.yml b/lang/en.yml index 791094674..3cc788b8c 100644 --- a/lang/en.yml +++ b/lang/en.yml @@ -182,6 +182,7 @@ field_time_zone: Time zone field_searchable: Searchable field_default_value: Default value field_comments_sorting: Display comments +field_parent_title: Parent page setting_app_title: Application title setting_app_subtitle: Application subtitle diff --git a/lang/es.yml b/lang/es.yml index 4205402e4..c753f367f 100644 --- a/lang/es.yml +++ b/lang/es.yml @@ -635,3 +635,4 @@ label_generate_key: Generate a key setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +field_parent_title: Parent page diff --git a/lang/fi.yml b/lang/fi.yml index b69b07557..b48d8a319 100644 --- a/lang/fi.yml +++ b/lang/fi.yml @@ -632,3 +632,4 @@ label_generate_key: Generate a key setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +field_parent_title: Parent page diff --git a/lang/fr.yml b/lang/fr.yml index 5b0f04fb0..b9d542da6 100644 --- a/lang/fr.yml +++ b/lang/fr.yml @@ -183,6 +183,7 @@ field_time_zone: Fuseau horaire field_searchable: Utilisé pour les recherches field_default_value: Valeur par défaut field_comments_sorting: Afficher les commentaires +field_parent_title: Page parent setting_app_title: Titre de l'application setting_app_subtitle: Sous-titre de l'application diff --git a/lang/he.yml b/lang/he.yml index 030e09dcc..63aa2bb64 100644 --- a/lang/he.yml +++ b/lang/he.yml @@ -632,3 +632,4 @@ label_generate_key: Generate a key setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +field_parent_title: Parent page diff --git a/lang/hu.yml b/lang/hu.yml index 630294c9d..9becbb349 100644 --- a/lang/hu.yml +++ b/lang/hu.yml @@ -633,3 +633,4 @@ label_generate_key: Kulcs generálása setting_mail_handler_api_enabled: Web Service engedélyezése a beérkezett levelekhez setting_mail_handler_api_key: API kulcs text_email_delivery_not_configured: "Az E-mail küldés nincs konfigurálva, és az értesítések ki vannak kapcsolva.\nÁllítsd be az SMTP szervert a config/email.yml fájlban és indítsd újra az alkalmazást, hogy érvénybe lépjen." +field_parent_title: Parent page diff --git a/lang/it.yml b/lang/it.yml index 471ef49ed..e7a8772cc 100644 --- a/lang/it.yml +++ b/lang/it.yml @@ -632,3 +632,4 @@ label_generate_key: Genera una chiave setting_mail_handler_api_enabled: Abilita WS per le e-mail in arrivo setting_mail_handler_api_key: chiave API text_email_delivery_not_configured: "La consegna via e-mail non è configurata e le notifiche sono disabilitate.\nConfigura il tuo server SMTP in config/email.yml e riavvia l'applicazione per abilitarle." +field_parent_title: Parent page diff --git a/lang/ja.yml b/lang/ja.yml index cba410f6d..f78fcdba4 100644 --- a/lang/ja.yml +++ b/lang/ja.yml @@ -633,3 +633,4 @@ label_generate_key: Generate a key setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +field_parent_title: Parent page diff --git a/lang/ko.yml b/lang/ko.yml index 2b5b0eb0a..77672c601 100644 --- a/lang/ko.yml +++ b/lang/ko.yml @@ -632,3 +632,4 @@ label_generate_key: Generate a key setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +field_parent_title: Parent page diff --git a/lang/lt.yml b/lang/lt.yml index 52b6b6fc8..706133bfe 100644 --- a/lang/lt.yml +++ b/lang/lt.yml @@ -635,3 +635,4 @@ setting_mail_handler_api_enabled: Įgalinti WS įeinantiems laiškams setting_mail_handler_api_key: API raktas text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +field_parent_title: Parent page diff --git a/lang/nl.yml b/lang/nl.yml index 09cdc3c08..3cfb0aa19 100644 --- a/lang/nl.yml +++ b/lang/nl.yml @@ -633,3 +633,4 @@ label_generate_key: Generate a key setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +field_parent_title: Parent page diff --git a/lang/no.yml b/lang/no.yml index eb1ff59ca..0836bd48f 100644 --- a/lang/no.yml +++ b/lang/no.yml @@ -633,3 +633,4 @@ label_generate_key: Generate a key setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +field_parent_title: Parent page diff --git a/lang/pl.yml b/lang/pl.yml index 9c5a382b0..278d56a88 100644 --- a/lang/pl.yml +++ b/lang/pl.yml @@ -632,3 +632,4 @@ label_generate_key: Generate a key setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +field_parent_title: Parent page diff --git a/lang/pt-br.yml b/lang/pt-br.yml index 1582e568f..9276d768e 100644 --- a/lang/pt-br.yml +++ b/lang/pt-br.yml @@ -632,3 +632,4 @@ label_generate_key: Generate a key setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +field_parent_title: Parent page diff --git a/lang/pt.yml b/lang/pt.yml index ece12cd97..a7647e31f 100644 --- a/lang/pt.yml +++ b/lang/pt.yml @@ -632,3 +632,4 @@ label_generate_key: Generate a key setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +field_parent_title: Parent page diff --git a/lang/ro.yml b/lang/ro.yml index 50bbf29af..c3640d7e1 100644 --- a/lang/ro.yml +++ b/lang/ro.yml @@ -632,3 +632,4 @@ label_generate_key: Generate a key setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +field_parent_title: Parent page diff --git a/lang/ru.yml b/lang/ru.yml index c0cac30a0..e8bda05b7 100644 --- a/lang/ru.yml +++ b/lang/ru.yml @@ -636,3 +636,4 @@ label_generate_key: Сгенерировать ключ setting_mail_handler_api_enabled: Включить веб-сервис для входящих сообщений setting_mail_handler_api_key: API ключ text_email_delivery_not_configured: "Параметры работы с почтовым сервером не настроены и функция уведомления по email не активна.\nНастроить параметры для вашего SMTP сервера вы можете в файле config/email.yml. Для применения изменений перезапустите приложение." +field_parent_title: Parent page diff --git a/lang/sr.yml b/lang/sr.yml index fa1b4d847..688fa8ede 100644 --- a/lang/sr.yml +++ b/lang/sr.yml @@ -633,3 +633,4 @@ label_generate_key: Generate a key setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +field_parent_title: Parent page diff --git a/lang/sv.yml b/lang/sv.yml index 9015099e7..58507a0b7 100644 --- a/lang/sv.yml +++ b/lang/sv.yml @@ -633,3 +633,4 @@ label_generate_key: Generate a key setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +field_parent_title: Parent page diff --git a/lang/th.yml b/lang/th.yml index 27f7b14cf..a7f949c96 100644 --- a/lang/th.yml +++ b/lang/th.yml @@ -635,3 +635,4 @@ label_generate_key: Generate a key setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +field_parent_title: Parent page diff --git a/lang/uk.yml b/lang/uk.yml index 0286779be..766ddaaab 100644 --- a/lang/uk.yml +++ b/lang/uk.yml @@ -634,3 +634,4 @@ label_generate_key: Generate a key setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +field_parent_title: Parent page diff --git a/lang/zh-tw.yml b/lang/zh-tw.yml index bad6fcca5..82f26ab86 100644 --- a/lang/zh-tw.yml +++ b/lang/zh-tw.yml @@ -633,3 +633,4 @@ default_activity_development: 開發 enumeration_issue_priorities: 項目優先權 enumeration_doc_categories: 文件分類 enumeration_activities: 活動 (時間追蹤) +field_parent_title: Parent page diff --git a/lang/zh.yml b/lang/zh.yml index 1cde9f502..b4ae89ba7 100644 --- a/lang/zh.yml +++ b/lang/zh.yml @@ -633,3 +633,4 @@ enumeration_issue_priorities: 问题优先级 enumeration_doc_categories: 文档类别 enumeration_activities: 活动(时间跟踪) text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +field_parent_title: Parent page diff --git a/test/fixtures/wiki_pages.yml b/test/fixtures/wiki_pages.yml index ef7242430..e285441ff 100644 --- a/test/fixtures/wiki_pages.yml +++ b/test/fixtures/wiki_pages.yml @@ -4,23 +4,27 @@ wiki_pages_001: title: CookBook_documentation id: 1 wiki_id: 1 - protected: true + protected: true + parent_id: wiki_pages_002: created_on: 2007-03-08 00:18:07 +01:00 title: Another_page id: 2 wiki_id: 1 protected: false + parent_id: wiki_pages_003: created_on: 2007-03-08 00:18:07 +01:00 title: Start_page id: 3 wiki_id: 2 protected: false + parent_id: wiki_pages_004: created_on: 2007-03-08 00:18:07 +01:00 title: Page_with_an_inline_image id: 4 wiki_id: 1 protected: false + parent_id: 1 \ No newline at end of file diff --git a/test/functional/wiki_controller_test.rb b/test/functional/wiki_controller_test.rb index f1ae7a9c2..06d8cacf2 100644 --- a/test/functional/wiki_controller_test.rb +++ b/test/functional/wiki_controller_test.rb @@ -163,8 +163,16 @@ class WikiControllerTest < Test::Unit::TestCase pages = assigns(:pages) assert_not_nil pages assert_equal Project.find(1).wiki.pages.size, pages.size - assert_tag :tag => 'a', :attributes => { :href => '/wiki/ecookbook/CookBook_documentation' }, - :content => /CookBook documentation/ + + assert_tag :ul, :attributes => { :class => 'pages-hierarchy' }, + :child => { :tag => 'li', :child => { :tag => 'a', :attributes => { :href => '/wiki/ecookbook/CookBook_documentation' }, + :content => 'CookBook documentation' }, + :child => { :tag => 'ul', + :child => { :tag => 'li', + :child => { :tag => 'a', :attributes => { :href => '/wiki/ecookbook/Page_with_an_inline_image' }, + :content => 'Page with an inline image' } } } }, + :child => { :tag => 'li', :child => { :tag => 'a', :attributes => { :href => '/wiki/ecookbook/Another_page' }, + :content => 'Another page' } } end def test_not_found diff --git a/test/unit/wiki_page_test.rb b/test/unit/wiki_page_test.rb index bb8111176..e5ebeeea6 100644 --- a/test/unit/wiki_page_test.rb +++ b/test/unit/wiki_page_test.rb @@ -48,6 +48,50 @@ class WikiPageTest < Test::Unit::TestCase assert page.new_record? end + def test_parent_title + page = WikiPage.find_by_title('Another_page') + assert_nil page.parent_title + + page = WikiPage.find_by_title('Page_with_an_inline_image') + assert_equal 'CookBook documentation', page.parent_title + end + + def test_assign_parent + page = WikiPage.find_by_title('Another_page') + page.parent_title = 'CookBook documentation' + assert page.save + page.reload + assert_equal WikiPage.find_by_title('CookBook_documentation'), page.parent + end + + def test_unassign_parent + page = WikiPage.find_by_title('Page_with_an_inline_image') + page.parent_title = '' + assert page.save + page.reload + assert_nil page.parent + end + + def test_parent_validation + page = WikiPage.find_by_title('CookBook_documentation') + + # A page that doesn't exist + page.parent_title = 'Unknown title' + assert !page.save + assert_equal :activerecord_error_invalid, page.errors.on(:parent_title) + # A child page + page.parent_title = 'Page_with_an_inline_image' + assert !page.save + assert_equal :activerecord_error_circular_dependency, page.errors.on(:parent_title) + # The page itself + page.parent_title = 'CookBook_documentation' + assert !page.save + assert_equal :activerecord_error_circular_dependency, page.errors.on(:parent_title) + + page.parent_title = 'Another_page' + assert page.save + end + def test_destroy page = WikiPage.find(1) page.destroy