Slicker
Clean up the recursive-include code a bit.
This commit is contained in:
parent
3a109d1c82
commit
0f843bc537
|
@ -10,27 +10,22 @@ require 'chunks/wiki'
|
||||||
class Include < WikiChunk::WikiReference
|
class Include < WikiChunk::WikiReference
|
||||||
|
|
||||||
INCLUDE_PATTERN = /\[\[!include\s+([^\]\s][^\]]+?)\s*\]\]/i
|
INCLUDE_PATTERN = /\[\[!include\s+([^\]\s][^\]]+?)\s*\]\]/i
|
||||||
Thread.current[:included_by] = []
|
|
||||||
def self.pattern() INCLUDE_PATTERN end
|
def self.pattern() INCLUDE_PATTERN end
|
||||||
|
|
||||||
def initialize(match_data, content)
|
def initialize(match_data, content)
|
||||||
super
|
super
|
||||||
@page_name = match_data[1].strip
|
@page_name = match_data[1].strip
|
||||||
rendering_mode = content.options[:mode] || :show
|
rendering_mode = content.options[:mode] || :show
|
||||||
Thread.current[:included_by].push(@content.page_name)
|
add_to_include_list
|
||||||
@unmask_text = get_unmask_text_avoiding_recursion_loops(rendering_mode)
|
@unmask_text = get_unmask_text_avoiding_recursion_loops(rendering_mode)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def get_unmask_text_avoiding_recursion_loops(rendering_mode)
|
def get_unmask_text_avoiding_recursion_loops(rendering_mode)
|
||||||
if refpage
|
if refpage
|
||||||
if Thread.current[:included_by].include?(refpage.page.name)
|
return "<em>Recursive include detected: #{@content.page_name} " +
|
||||||
@content.delete_chunk(self)
|
"→ #{@content.page_name}</em>\n" if self_inclusion(refpage)
|
||||||
Thread.current[:included_by] = []
|
|
||||||
return "<em>Recursive include detected: #{@content.page_name} → #{@content.page_name}</em>\n"
|
|
||||||
end
|
|
||||||
# TODO This way of instantiating a renderer is ugly.
|
|
||||||
renderer = PageRenderer.new(refpage.current_revision)
|
renderer = PageRenderer.new(refpage.current_revision)
|
||||||
included_content =
|
included_content =
|
||||||
case rendering_mode
|
case rendering_mode
|
||||||
|
@ -41,12 +36,37 @@ class Include < WikiChunk::WikiReference
|
||||||
raise "Unsupported rendering mode #{@mode.inspect}"
|
raise "Unsupported rendering mode #{@mode.inspect}"
|
||||||
end
|
end
|
||||||
@content.merge_chunks(included_content)
|
@content.merge_chunks(included_content)
|
||||||
Thread.current[:included_by] = []
|
clear_include_list
|
||||||
return included_content.pre_rendered
|
return included_content.pre_rendered
|
||||||
else
|
else
|
||||||
Thread.current[:included_by] = []
|
clear_include_list
|
||||||
return "<em>Could not include #{@page_name}</em>\n"
|
return "<em>Could not include #{@page_name}</em>\n"
|
||||||
end
|
end
|
||||||
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
|
||||||
|
if Thread.current[:included_by]
|
||||||
|
Thread.current[:included_by].push(@content.page_name)
|
||||||
|
else
|
||||||
|
Thread.current[:included_by] = [@content.page_name]
|
||||||
|
end
|
||||||
|
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
|
end
|
||||||
|
|
Loading…
Reference in a new issue