diff --git a/app/controllers/wiki_controller.rb b/app/controllers/wiki_controller.rb index 65a67aa6..efe89ef2 100644 --- a/app/controllers/wiki_controller.rb +++ b/app/controllers/wiki_controller.rb @@ -6,7 +6,7 @@ require 'zip/zip' class WikiController < ApplicationController # 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] diff --git a/app/models/page.rb b/app/models/page.rb index 7d0e8695..715ac6ce 100644 --- a/app/models/page.rb +++ b/app/models/page.rb @@ -1,6 +1,7 @@ class Page < ActiveRecord::Base belongs_to :web has_many :revisions, :order => 'id' + has_many :wiki_references, :order => 'referenced_page_name' has_one :current_revision, :class_name => 'Revision', :order => 'id DESC' 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, renderer.revision = Revision.new( :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. # Not to record every such iteration as a new revision, if the previous revision was done diff --git a/lib/chunks/include.rb b/lib/chunks/include.rb index 90dc02a7..72c89b54 100644 --- a/lib/chunks/include.rb +++ b/lib/chunks/include.rb @@ -12,7 +12,6 @@ class Include < WikiChunk::WikiReference INCLUDE_PATTERN = /\[\[!include\s+(.*?)\]\]\s*/i def self.pattern() INCLUDE_PATTERN end - def initialize(match_data, content) super @page_name = match_data[1].strip diff --git a/lib/page_renderer.rb b/lib/page_renderer.rb index db10730a..39b28052 100644 --- a/lib/page_renderer.rb +++ b/lib/page_renderer.rb @@ -12,11 +12,37 @@ class PageRenderer @@url_generator = nil end - attr_accessor :revision - + attr_reader :revision 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 # Returns an array of all the WikiIncludes present in the content of this revision. @@ -35,7 +61,7 @@ class PageRenderer @wiki_references_cache = chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq end @wiki_references_cache - end + end # Returns an array of all the WikiWords present in the content of this revision. def wiki_words @@ -58,61 +84,21 @@ class PageRenderer wiki_words - existing_pages end - # Explicit check for new type of display cache with chunks_by_type method. - # Ensures new version works with older snapshots. - def display_content - unless @display_cache && @display_cache.respond_to?(:chunks_by_type) - @display_cache = WikiContent.new(@revision, @@url_generator) - @display_cache.render! - end - @display_cache - 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 + private - 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 -
Markup engine has failed to render this page, raising the following error:
-#{message}
-#{@revision.content}- EOL - clear_display_cache - raise e + def render(options = {}) + result = WikiContent.new(@revision, @@url_generator, options).render! + @revision.page.wiki_references.delete + + 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 + result end - - protected - -end \ No newline at end of file +end diff --git a/test/unit/page_renderer_test.rb b/test/unit/page_renderer_test.rb index d84a74ff..e04540c8 100644 --- a/test/unit/page_renderer_test.rb +++ b/test/unit/page_renderer_test.rb @@ -1,7 +1,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../test_helper') class PageRendererTest < Test::Unit::TestCase - fixtures :webs, :pages, :revisions, :system + fixtures :webs, :pages, :revisions, :system, :wiki_references def setup @wiki = Wiki.new @@ -325,6 +325,18 @@ class PageRendererTest < Test::Unit::TestCase "!http://google.com!\r\nss") 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 def add_sample_pages