Recursive Includes
This commit is contained in:
parent
84756f889a
commit
96fea14d60
1 changed files with 36 additions and 15 deletions
|
@ -9,13 +9,14 @@ require 'chunks/wiki'
|
|||
|
||||
class Include < WikiChunk::WikiReference
|
||||
|
||||
INCLUDE_PATTERN = /\[\[!include\s+(.*?)\]\]\s*/i
|
||||
INCLUDE_PATTERN = /\[\[!include\s+([^\]\s][^\]]*?)\s*\]\]/i
|
||||
def self.pattern() INCLUDE_PATTERN end
|
||||
|
||||
def initialize(match_data, content)
|
||||
super
|
||||
@page_name = match_data[1].strip
|
||||
rendering_mode = content.options[:mode] || :show
|
||||
add_to_include_list
|
||||
@unmask_text = get_unmask_text_avoiding_recursion_loops(rendering_mode)
|
||||
end
|
||||
|
||||
|
@ -23,27 +24,47 @@ class Include < WikiChunk::WikiReference
|
|||
|
||||
def get_unmask_text_avoiding_recursion_loops(rendering_mode)
|
||||
if refpage
|
||||
# TODO This way of instantiating a renderer is ugly.
|
||||
return "<em>Recursive include detected: #{@content.page_name} " +
|
||||
"→ #{@content.page_name}</em>\n" if self_inclusion(refpage)
|
||||
renderer = PageRenderer.new(refpage.current_revision)
|
||||
if renderer.wiki_includes.include?(@content.page_name)
|
||||
# this will break the recursion
|
||||
@content.delete_chunk(self)
|
||||
return "<em>Recursive include detected; #{@page_name} --> #{@content.page_name} " +
|
||||
"--> #{@page_name}</em>\n"
|
||||
else
|
||||
included_content =
|
||||
case rendering_mode
|
||||
included_content =
|
||||
case rendering_mode
|
||||
when :show then renderer.display_content
|
||||
when :publish then renderer.display_published
|
||||
when :export then renderer.display_content_for_export
|
||||
else raise "Unsupported rendering mode #{@mode.inspect}"
|
||||
end
|
||||
@content.merge_chunks(included_content)
|
||||
return included_content.pre_rendered
|
||||
end
|
||||
else
|
||||
raise "Unsupported rendering mode #{@mode.inspect}"
|
||||
end
|
||||
@content.merge_chunks(included_content)
|
||||
clear_include_list
|
||||
return included_content.pre_rendered
|
||||
else
|
||||
clear_include_list
|
||||
return "<em>Could not include #{@page_name}</em>\n"
|
||||
end
|
||||
end
|
||||
|
||||
# We track included pages in a thread-local variable.
|
||||
# This allows a multi-threaded Rails to handle one request/thread,
|
||||
# without getting confused.
|
||||
|
||||
def clear_include_list
|
||||
Thread.current[:included_by] = []
|
||||
end
|
||||
|
||||
def add_to_include_list
|
||||
Thread.current[:included_by] ?
|
||||
Thread.current[:included_by].push(@content.page_name) :
|
||||
Thread.current[:included_by] = [@content.page_name]
|
||||
end
|
||||
|
||||
def self_inclusion(refpage)
|
||||
if Thread.current[:included_by].include?(refpage.page.name)
|
||||
@content.delete_chunk(self)
|
||||
clear_include_list
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue