Commit 85161ab0 authored by jplang's avatar jplang

Adds a setting to cache textile rendering (off by default).

* it uses ActionController cache store which is MemoryStore by default and can be configured with config.action_controller.cache_store
* macro processing was moved out of textile rendering so that it doesn't get cached
* no noticeable improvement is expected for small portions of text, so only texts larger than 2KB are cached

git-svn-id: https://svn.redmine.org/redmine/trunk@3372 e93f8b46-1217-0410-a6f0-8f06a7374b81
parent 10819e2b
...@@ -396,13 +396,14 @@ module ApplicationHelper ...@@ -396,13 +396,14 @@ module ApplicationHelper
text = args.shift text = args.shift
when 2 when 2
obj = args.shift obj = args.shift
text = obj.send(args.shift).to_s attr = args.shift
text = obj.send(attr).to_s
else else
raise ArgumentError, 'invalid arguments to textilizable' raise ArgumentError, 'invalid arguments to textilizable'
end end
return '' if text.blank? return '' if text.blank?
text = Redmine::WikiFormatting.to_html(Setting.text_formatting, text) { |macro, args| exec_macro(macro, obj, args) } text = Redmine::WikiFormatting.to_html(Setting.text_formatting, text, :object => obj, :attribute => attr) { |macro, args| exec_macro(macro, obj, args) }
only_path = options.delete(:only_path) == false ? false : true only_path = options.delete(:only_path) == false ? false : true
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
<p><%= setting_select :text_formatting, Redmine::WikiFormatting.format_names.collect{|name| [name, name.to_s]}, :blank => :label_none %></p> <p><%= setting_select :text_formatting, Redmine::WikiFormatting.format_names.collect{|name| [name, name.to_s]}, :blank => :label_none %></p>
<p><%= setting_check_box :cache_formatted_text %></p>
<p><%= setting_select :wiki_compression, [['Gzip', 'gzip']], :blank => :label_none %></p> <p><%= setting_select :wiki_compression, [['Gzip', 'gzip']], :blank => :label_none %></p>
<p><%= setting_text_field :feeds_limit, :size => 6 %></p> <p><%= setting_text_field :feeds_limit, :size => 6 %></p>
......
...@@ -32,7 +32,7 @@ Rails::Initializer.run do |config| ...@@ -32,7 +32,7 @@ Rails::Initializer.run do |config|
# Enable page/fragment caching by setting a file-based store # Enable page/fragment caching by setting a file-based store
# (remember to create the caching directory and make it readable to the application) # (remember to create the caching directory and make it readable to the application)
# config.action_controller.fragment_cache_store = :file_store, "#{RAILS_ROOT}/cache" # config.action_controller.cache_store = :file_store, "#{RAILS_ROOT}/tmp/cache"
# Activate observers that should always be running # Activate observers that should always be running
# config.active_record.observers = :cacher, :garbage_collector # config.active_record.observers = :cacher, :garbage_collector
......
...@@ -879,3 +879,4 @@ bg: ...@@ -879,3 +879,4 @@ bg:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -903,3 +903,4 @@ bs: ...@@ -903,3 +903,4 @@ bs:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -882,3 +882,4 @@ ca: ...@@ -882,3 +882,4 @@ ca:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -885,3 +885,4 @@ cs: ...@@ -885,3 +885,4 @@ cs:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -905,3 +905,4 @@ da: ...@@ -905,3 +905,4 @@ da:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -905,3 +905,4 @@ de: ...@@ -905,3 +905,4 @@ de:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -885,3 +885,4 @@ el: ...@@ -885,3 +885,4 @@ el:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -329,6 +329,7 @@ en: ...@@ -329,6 +329,7 @@ en:
setting_issue_done_ratio_issue_status: Use the issue status setting_issue_done_ratio_issue_status: Use the issue status
setting_start_of_week: Start calendars on setting_start_of_week: Start calendars on
setting_rest_api_enabled: Enable REST web service setting_rest_api_enabled: Enable REST web service
setting_cache_formatted_text: Cache formatted text
permission_add_project: Create project permission_add_project: Create project
permission_add_subprojects: Create subprojects permission_add_subprojects: Create subprojects
......
...@@ -929,3 +929,4 @@ es: ...@@ -929,3 +929,4 @@ es:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -889,3 +889,4 @@ eu: ...@@ -889,3 +889,4 @@ eu:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -915,3 +915,4 @@ fi: ...@@ -915,3 +915,4 @@ fi:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -352,6 +352,7 @@ fr: ...@@ -352,6 +352,7 @@ fr:
setting_rest_api_enabled: Activer l'API REST setting_rest_api_enabled: Activer l'API REST
setting_gravatar_default: Image Gravatar par défaut setting_gravatar_default: Image Gravatar par défaut
setting_start_of_week: Jour de début des calendriers setting_start_of_week: Jour de début des calendriers
setting_cache_formatted_text: Mettre en cache le texte formaté
permission_add_project: Créer un projet permission_add_project: Créer un projet
permission_add_subprojects: Créer des sous-projets permission_add_subprojects: Créer des sous-projets
......
...@@ -905,3 +905,4 @@ gl: ...@@ -905,3 +905,4 @@ gl:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -889,3 +889,4 @@ he: ...@@ -889,3 +889,4 @@ he:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -892,3 +892,4 @@ hr: ...@@ -892,3 +892,4 @@ hr:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -910,3 +910,4 @@ ...@@ -910,3 +910,4 @@
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -897,3 +897,4 @@ id: ...@@ -897,3 +897,4 @@ id:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -892,3 +892,4 @@ it: ...@@ -892,3 +892,4 @@ it:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -914,3 +914,4 @@ ja: ...@@ -914,3 +914,4 @@ ja:
enumeration_activities: 作業分類 (時間トラッキング) enumeration_activities: 作業分類 (時間トラッキング)
enumeration_system_activity: システム作業分類 enumeration_system_activity: システム作業分類
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -945,3 +945,4 @@ ko: ...@@ -945,3 +945,4 @@ ko:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -953,3 +953,4 @@ lt: ...@@ -953,3 +953,4 @@ lt:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -867,3 +867,4 @@ nl: ...@@ -867,3 +867,4 @@ nl:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -880,3 +880,4 @@ ...@@ -880,3 +880,4 @@
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -910,3 +910,4 @@ pl: ...@@ -910,3 +910,4 @@ pl:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -913,3 +913,4 @@ pt-BR: ...@@ -913,3 +913,4 @@ pt-BR:
label_board_locked: Travado label_board_locked: Travado
label_change_log: Registro de alterações label_change_log: Registro de alterações
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -897,3 +897,4 @@ pt: ...@@ -897,3 +897,4 @@ pt:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -882,3 +882,4 @@ ro: ...@@ -882,3 +882,4 @@ ro:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -993,3 +993,4 @@ ru: ...@@ -993,3 +993,4 @@ ru:
label_board_sticky: Прикреплена label_board_sticky: Прикреплена
label_board_locked: Заблокирована label_board_locked: Заблокирована
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -884,3 +884,4 @@ sk: ...@@ -884,3 +884,4 @@ sk:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -881,3 +881,4 @@ sl: ...@@ -881,3 +881,4 @@ sl:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -900,3 +900,4 @@ ...@@ -900,3 +900,4 @@
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -934,3 +934,4 @@ sv: ...@@ -934,3 +934,4 @@ sv:
enumeration_activities: Aktiviteter (tidsuppföljning) enumeration_activities: Aktiviteter (tidsuppföljning)
enumeration_system_activity: Systemaktivitet enumeration_system_activity: Systemaktivitet
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -882,3 +882,4 @@ th: ...@@ -882,3 +882,4 @@ th:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -912,3 +912,4 @@ tr: ...@@ -912,3 +912,4 @@ tr:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -881,3 +881,4 @@ uk: ...@@ -881,3 +881,4 @@ uk:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -944,3 +944,4 @@ vi: ...@@ -944,3 +944,4 @@ vi:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -976,3 +976,4 @@ ...@@ -976,3 +976,4 @@
enumeration_activities: 活動 (時間追蹤) enumeration_activities: 活動 (時間追蹤)
enumeration_system_activity: 系統活動 enumeration_system_activity: 系統活動
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -907,3 +907,4 @@ zh: ...@@ -907,3 +907,4 @@ zh:
label_board_sticky: Sticky label_board_sticky: Sticky
label_board_locked: Locked label_board_locked: Locked
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text
...@@ -53,6 +53,8 @@ plain_text_mail: ...@@ -53,6 +53,8 @@ plain_text_mail:
default: 0 default: 0
text_formatting: text_formatting:
default: textile default: textile
cache_formatted_text:
default: 0
wiki_compression: wiki_compression:
default: "" default: ""
default_language: default_language:
......
...@@ -44,7 +44,58 @@ module Redmine ...@@ -44,7 +44,58 @@ module Redmine
end end
def to_html(format, text, options = {}, &block) def to_html(format, text, options = {}, &block)
formatter_for(format).new(text).to_html(&block) text = if Setting.cache_formatted_text? && text.size > 2.kilobyte && cache && cache_key = cache_key_for(format, options[:object], options[:attribute])
# Text retrieved from the cache store may be frozen
# We need to dup it so we can do in-place substitutions with gsub!
cache.fetch cache_key do
formatter_for(format).new(text).to_html
end.dup
else
formatter_for(format).new(text).to_html
end
if block_given?
execute_macros(text, block)
end
text
end
# Returns a cache key for the given text +format+, +object+ and +attribute+ or nil if no caching should be done
def cache_key_for(format, object, attribute)
if object && attribute && !object.new_record? && object.respond_to?(:updated_on) && !format.blank?
"formatted_text/#{format}/#{object.class.model_name.cache_key}/#{object.id}-#{attribute}-#{object.updated_on.to_s(:number)}"
end
end
# Returns the cache store used to cache HTML output
def cache
ActionController::Base.cache_store
end
MACROS_RE = /
(!)? # escaping
(
\{\{ # opening tag
([\w]+) # macro name
(\(([^\}]*)\))? # optional arguments
\}\} # closing tag
)
/x unless const_defined?(:MACROS_RE)
# Macros substitution
def execute_macros(text, macros_runner)
text.gsub!(MACROS_RE) do
esc, all, macro = $1, $2, $3.downcase
args = ($5 || '').split(',').each(&:strip)
if esc.nil?
begin
macros_runner.call(macro, args)
rescue => e
"<div class=\"flash error\">Error executing the <strong>#{macro}</strong> macro (#{e})</div>"
end || all
else
all
end
end
end end
end end
......
...@@ -24,7 +24,7 @@ module Redmine ...@@ -24,7 +24,7 @@ module Redmine
class Formatter < RedCloth3 class Formatter < RedCloth3
# auto_link rule after textile rules so that it doesn't break !image_url! tags # auto_link rule after textile rules so that it doesn't break !image_url! tags
RULES = [:textile, :block_markdown_rule, :inline_auto_link, :inline_auto_mailto, :inline_toc, :inline_macros] RULES = [:textile, :block_markdown_rule, :inline_auto_link, :inline_auto_mailto, :inline_toc]
def initialize(*args) def initialize(*args)
super super
...@@ -33,9 +33,8 @@ module Redmine ...@@ -33,9 +33,8 @@ module Redmine
self.filter_styles=true self.filter_styles=true
end end
def to_html(*rules, &block) def to_html(*rules)
@toc = [] @toc = []
@macros_runner = block
super(*RULES).to_s super(*RULES).to_s
end end
...@@ -102,32 +101,6 @@ module Redmine ...@@ -102,32 +101,6 @@ module Redmine
end end
end end
MACROS_RE = /
(!)? # escaping
(
\{\{ # opening tag
([\w]+) # macro name
(\(([^\}]*)\))? # optional arguments
\}\} # closing tag
)
/x unless const_defined?(:MACROS_RE)
def inline_macros(text)
text.gsub!(MACROS_RE) do
esc, all, macro = $1, $2, $3.downcase
args = ($5 || '').split(',').each(&:strip)
if esc.nil?
begin
@macros_runner.call(macro, args)
rescue => e
"<div class=\"flash error\">Error executing the <strong>#{macro}</strong> macro (#{e})</div>"
end || all
else
all
end
end
end
AUTO_LINK_RE = %r{ AUTO_LINK_RE = %r{
( # leading text ( # leading text
<\w+.*?>| # leading HTML tag, or <\w+.*?>| # leading HTML tag, or
......
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