Store wiki references found during rendering

This commit is contained in:
Alexey Verkhovsky 2005-09-11 05:44:34 +00:00
parent bfecd09b56
commit cd68db01d2
5 changed files with 61 additions and 63 deletions

View file

@ -6,7 +6,7 @@ require 'zip/zip'
class WikiController < ApplicationController class WikiController < ApplicationController
# TODO implement cache sweeping # TODO implement cache sweeping
caches_page :show caches_page :show, :published
layout 'default', :except => [:rss_feed, :rss_with_content, :rss_with_headlines, :tex, :export_tex, :export_html] layout 'default', :except => [:rss_feed, :rss_with_content, :rss_with_headlines, :tex, :export_tex, :export_html]

View file

@ -1,6 +1,7 @@
class Page < ActiveRecord::Base class Page < ActiveRecord::Base
belongs_to :web belongs_to :web
has_many :revisions, :order => 'id' has_many :revisions, :order => 'id'
has_many :wiki_references, :order => 'referenced_page_name'
has_one :current_revision, :class_name => 'Revision', :order => 'id DESC' has_one :current_revision, :class_name => 'Revision', :order => 'id DESC'
def revise(content, time, author, renderer) def revise(content, time, author, renderer)
@ -15,7 +16,7 @@ class Page < ActiveRecord::Base
# Try to render content to make sure that markup engine can take it, # Try to render content to make sure that markup engine can take it,
renderer.revision = Revision.new( renderer.revision = Revision.new(
:page => self, :content => content, :author => author, :revised_at => time) :page => self, :content => content, :author => author, :revised_at => time)
renderer.force_rendering renderer.display_content
# A user may change a page, look at it and make some more changes - several times. # A user may change a page, look at it and make some more changes - several times.
# Not to record every such iteration as a new revision, if the previous revision was done # Not to record every such iteration as a new revision, if the previous revision was done

View file

@ -12,7 +12,6 @@ class Include < WikiChunk::WikiReference
INCLUDE_PATTERN = /\[\[!include\s+(.*?)\]\]\s*/i INCLUDE_PATTERN = /\[\[!include\s+(.*?)\]\]\s*/i
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

View file

@ -12,11 +12,37 @@ class PageRenderer
@@url_generator = nil @@url_generator = nil
end end
attr_accessor :revision attr_reader :revision
def initialize(revision = nil) def initialize(revision = nil)
@revision = revision self.revision = revision
end
def revision=(r)
@revision = r
@wiki_words_cache = @wiki_includes_cache = @wiki_references_cache = nil
end
def display_content
render
end
def display_content_for_export
render :mode => :export
end
def display_published
render :mode => :publish
end
def display_diff
previous_revision = @revision.page.previous_revision(@revision)
if previous_revision
rendered_previous_revision = WikiContent.new(previous_revision, @@url_generator).render!
HTMLDiff.diff(rendered_previous_revision, display_content)
else
display_content
end
end end
# Returns an array of all the WikiIncludes present in the content of this revision. # Returns an array of all the WikiIncludes present in the content of this revision.
@ -58,61 +84,21 @@ class PageRenderer
wiki_words - existing_pages wiki_words - existing_pages
end end
# Explicit check for new type of display cache with chunks_by_type method. private
# Ensures new version works with older snapshots.
def display_content def render(options = {})
unless @display_cache && @display_cache.respond_to?(:chunks_by_type) result = WikiContent.new(@revision, @@url_generator, options).render!
@display_cache = WikiContent.new(@revision, @@url_generator) @revision.page.wiki_references.delete
@display_cache.render!
wiki_word_chunks = result.find_chunks(WikiChunk::WikiLink)
wiki_words = wiki_word_chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq
wiki_words.each do |referenced_page_name|
@revision.page.wiki_references.create({
:referenced_page_name => referenced_page_name,
:link_type => WikiReference.link_type(@revision.page.web, referenced_page_name)
})
end end
@display_cache result
end end
# TODO this probably doesn't belong in revision (because it has to call back the page)
def display_diff
previous_revision = @revision.page.previous_revision(@revision)
if previous_revision
HTMLDiff.diff(PageRenderer.new(previous_revision).display_content, display_content)
else
display_content
end
end
def clear_display_cache
@wiki_words_cache = @published_cache = @display_cache = @wiki_includes_cache =
@wiki_references_cache = nil
end
def display_published
unless @published_cache && @published_cache.respond_to?(:chunks_by_type)
@published_cache = WikiContent.new(@revision, @@url_generator, {:mode => :publish})
@published_cache.render!
end
@published_cache
end
def display_content_for_export
WikiContent.new(@revision, @@url_generator, {:mode => :export} ).render!
end
def force_rendering
begin
display_content.render!
rescue => e
ActionController::Base.logger.error "Failed rendering page #{@name}"
ActionController::Base.logger.error e
message = e.message
# substitute content with an error message
@revision.content = <<-EOL
<p>Markup engine has failed to render this page, raising the following error:</p>
<p>#{message}</p>
<pre>#{@revision.content}</pre>
EOL
clear_display_cache
raise e
end
end
protected
end end

View file

@ -1,7 +1,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper') require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
class PageRendererTest < Test::Unit::TestCase class PageRendererTest < Test::Unit::TestCase
fixtures :webs, :pages, :revisions, :system fixtures :webs, :pages, :revisions, :system, :wiki_references
def setup def setup
@wiki = Wiki.new @wiki = Wiki.new
@ -325,6 +325,18 @@ class PageRendererTest < Test::Unit::TestCase
"!http://google.com!\r\nss") "!http://google.com!\r\nss")
end end
# Tests for the caching of wiki references and categories
def test_references_creation
new_page = @web.add_page('NewPage', 'HomePage',
Time.local(2004, 4, 4, 16, 50), 'AlexeyVerkhovsky', test_renderer)
references = new_page.wiki_references(true)
assert_equal 1, references.size
assert_equal 'HomePage', references[0].referenced_page_name
assert_equal WikiReference::LINKED_PAGE, references[0].link_type
end
private private
def add_sample_pages def add_sample_pages