Commit f5d619f5 authored by jplang's avatar jplang
Browse files

Wiki: allows single section edit (#2222).

git-svn-id: https://svn.redmine.org/redmine/trunk@7829 e93f8b46-1217-0410-a6f0-8f06a7374b81
parent 5a8fd2f6
......@@ -100,6 +100,13 @@ class WikiController < ApplicationController
# To prevent StaleObjectError exception when reverting to a previous version
@content.version = @page.content.version
@text = @content.text
if params[:section].present?
@section = params[:section].to_i
@text, @section_hash = Redmine::WikiFormatting.formatter.new(@text).get_section(@section)
render_404 if @text.blank?
end
end
verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed }
......@@ -120,7 +127,17 @@ class WikiController < ApplicationController
redirect_to :action => 'show', :project_id => @project, :id => @page.title
return
end
@content.attributes = params[:content]
@content.comments = params[:content][:comments]
@text = params[:content][:text]
if params[:section].present?
@section = params[:section].to_i
@section_hash = params[:section_hash]
@content.text = Redmine::WikiFormatting.formatter.new(@content.text).update_section(params[:section].to_i, @text, @section_hash)
else
@content.version = params[:content][:version]
@content.text = @text
end
@content.author = User.current
# if page is new @page.save will also save content, but not if page isn't a new record
if (@page.new_record? ? @page.save : @content.save)
......@@ -132,7 +149,7 @@ class WikiController < ApplicationController
render :action => 'edit'
end
rescue ActiveRecord::StaleObjectError
rescue ActiveRecord::StaleObjectError, Redmine::WikiFormatting::StaleSectionError
# Optimistic locking exception
flash.now[:error] = l(:notice_locking_conflict)
render :action => 'edit'
......
......@@ -486,11 +486,11 @@ module ApplicationHelper
project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil)
only_path = options.delete(:only_path) == false ? false : true
text = Redmine::WikiFormatting.to_html(Setting.text_formatting, text, :object => obj, :attribute => attr) { |macro, args| exec_macro(macro, obj, args) }
text = Redmine::WikiFormatting.to_html(Setting.text_formatting, text, :object => obj, :attribute => attr)
@parsed_headings = []
text = parse_non_pre_blocks(text) do |text|
[:parse_inline_attachments, :parse_wiki_links, :parse_redmine_links, :parse_headings].each do |method_name|
[:parse_sections, :parse_inline_attachments, :parse_wiki_links, :parse_redmine_links, :parse_macros, :parse_headings].each do |method_name|
send method_name, text, project, obj, attr, only_path, options
end
end
......@@ -728,7 +728,23 @@ module ApplicationHelper
end
end
HEADING_RE = /<h(1|2|3|4)( [^>]+)?>(.+?)<\/h(1|2|3|4)>/i unless const_defined?(:HEADING_RE)
HEADING_RE = /(<h(1|2|3|4)( [^>]+)?>(.+?)<\/h(1|2|3|4)>)/i unless const_defined?(:HEADING_RE)
def parse_sections(text, project, obj, attr, only_path, options)
return unless options[:edit_section_links]
section = 0
text.gsub!(HEADING_RE) do
section += 1
if section > 1
content_tag('div',
link_to(image_tag('edit.png'), options[:edit_section_links].merge(:section => section)),
:class => 'contextual',
:title => l(:button_edit_section)) + $1
else
$1
end
end
end
# Headings and TOC
# Adds ids and links to headings unless options[:headings] is set to false
......@@ -736,7 +752,7 @@ module ApplicationHelper
return if options[:headings] == false
text.gsub!(HEADING_RE) do
level, attrs, content = $1.to_i, $2, $3
level, attrs, content = $2.to_i, $3, $4
item = strip_tags(content).strip
anchor = sanitize_anchor_name(item)
# used for single-file wiki export
......@@ -746,6 +762,33 @@ module ApplicationHelper
end
end
MACROS_RE = /
(!)? # escaping
(
\{\{ # opening tag
([\w]+) # macro name
(\(([^\}]*)\))? # optional arguments
\}\} # closing tag
)
/x unless const_defined?(:MACROS_RE)
# Macros substitution
def parse_macros(text, project, obj, attr, only_path, options)
text.gsub!(MACROS_RE) do
esc, all, macro = $1, $2, $3.downcase
args = ($5 || '').split(',').each(&:strip)
if esc.nil?
begin
exec_macro(macro, obj, args)
rescue => e
"<div class=\"flash error\">Error executing the <strong>#{macro}</strong> macro (#{e})</div>"
end || all
else
all
end
end
end
TOC_RE = /<p>\{\{([<>]?)toc\}\}<\/p>/i unless const_defined?(:TOC_RE)
# Renders the TOC with given headings
......
<div class="wiki">
<%= textilizable content, :text, :attachments => content.page.attachments %>
<div class="wiki wiki-page">
<%= textilizable content, :text, :attachments => content.page.attachments,
:edit_section_links => (content.is_a?(WikiContent) && @editable && User.current.allowed_to?(:edit_wiki_pages, @page.project) && {:controller => 'wiki', :action => 'edit', :project_id => @page.project, :id => @page.title}) %>
</div>
......@@ -4,9 +4,13 @@
<% form_for :content, @content, :url => {:action => 'update', :id => @page.title}, :html => {:method => :put, :multipart => true, :id => 'wiki_form'} do |f| %>
<%= f.hidden_field :version %>
<% if @section %>
<%= hidden_field_tag 'section', @section %>
<%= hidden_field_tag 'section_hash', @section_hash %>
<% end %>
<%= error_messages_for 'content' %>
<p><%= f.text_area :text, :cols => 100, :rows => 25, :class => 'wiki-edit', :accesskey => accesskey(:edit) %></p>
<p><%= text_area_tag 'content[text]', @text, :cols => 100, :rows => 25, :class => 'wiki-edit', :accesskey => accesskey(:edit) %></p>
<p><label><%= l(:field_comments) %></label><br /><%= f.text_field :comments, :size => 120 %></p>
<p><label><%=l(:label_attachment_plural)%></label><br /><%= render :partial => 'attachments/form' %></p>
......
......@@ -999,3 +999,4 @@ bg:
description_date_range_interval: Изберете диапазон чрез задаване на начална и крайна дати
description_date_from: Въведете начална дата
description_date_to: Въведете крайна дата
button_edit_section: Edit this section
......@@ -1015,3 +1015,4 @@ bs:
label_child_revision: Child
error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
button_edit_section: Edit this section
......@@ -1004,3 +1004,4 @@ ca:
label_child_revision: Child
error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
button_edit_section: Edit this section
......@@ -1005,3 +1005,4 @@ cs:
label_child_revision: Child
error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
button_edit_section: Edit this section
......@@ -1018,3 +1018,4 @@ da:
label_child_revision: Child
error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
button_edit_section: Edit this section
......@@ -1022,3 +1022,4 @@ de:
label_child_revision: Child
error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
button_edit_section: Edit this section
......@@ -1001,3 +1001,4 @@ el:
label_child_revision: Child
error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
button_edit_section: Edit this section
......@@ -1004,3 +1004,4 @@ en-GB:
description_selected_columns: Selected Columns
label_parent_revision: Parent
label_child_revision: Child
button_edit_section: Edit this section
......@@ -874,6 +874,7 @@ en:
button_quote: Quote
button_duplicate: Duplicate
button_show: Show
button_edit_section: Edit this section
status_active: active
status_registered: registered
......
......@@ -1038,3 +1038,4 @@ es:
label_parent_revision: Parent
label_child_revision: Child
setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
button_edit_section: Edit this section
......@@ -1005,3 +1005,4 @@ eu:
label_child_revision: Child
error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
button_edit_section: Edit this section
......@@ -1004,3 +1004,4 @@ fa:
label_child_revision: Child
error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
button_edit_section: Edit this section
......@@ -1022,3 +1022,4 @@ fi:
label_child_revision: Child
error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
button_edit_section: Edit this section
......@@ -850,6 +850,7 @@ fr:
button_quote: Citer
button_duplicate: Dupliquer
button_show: Afficher
button_edit_section: Modifier cette section
status_active: actif
status_registered: enregistré
......
......@@ -1013,3 +1013,4 @@ gl:
label_child_revision: Child
error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
button_edit_section: Edit this section
......@@ -1006,3 +1006,4 @@ he:
label_child_revision: Child
error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
button_edit_section: Edit this section
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment