##// END OF EJS Templates
Redmine links can be used to link to documents, versions and attachments....
Jean-Philippe Lang -
r1050:702b521b453a
parent child
Show More
@@ -220,8 +220,9 module ApplicationHelper
220
220
221 project = options[:project] || @project
221 project = options[:project] || @project
222
222
223 # turn wiki links into html links
223 # Wiki links
224 # example:
224 #
225 # Examples:
225 # [[mypage]]
226 # [[mypage]]
226 # [[mypage|mytext]]
227 # [[mypage|mytext]]
227 # wiki links can refer other project wikis, using project name or identifier:
228 # wiki links can refer other project wikis, using project name or identifier:
@@ -229,47 +230,94 module ApplicationHelper
229 # [[project:|mytext]]
230 # [[project:|mytext]]
230 # [[project:mypage]]
231 # [[project:mypage]]
231 # [[project:mypage|mytext]]
232 # [[project:mypage|mytext]]
232 text = text.gsub(/\[\[([^\]\|]+)(\|([^\]\|]+))?\]\]/) do |m|
233 text = text.gsub(/(!)?(\[\[([^\]\|]+)(\|([^\]\|]+))?\]\])/) do |m|
233 link_project = project
234 link_project = project
234 page = $1
235 esc, all, page, title = $1, $2, $3, $5
235 title = $3
236 if esc.nil?
236 if page =~ /^([^\:]+)\:(.*)$/
237 if page =~ /^([^\:]+)\:(.*)$/
237 link_project = Project.find_by_name($1) || Project.find_by_identifier($1)
238 link_project = Project.find_by_name($1) || Project.find_by_identifier($1)
238 page = title || $2
239 page = $2
239 title = $1 if page.blank?
240 title ||= $1 if page.blank?
240 end
241 end
241
242
242 if link_project && link_project.wiki
243 if link_project && link_project.wiki
243 # check if page exists
244 # check if page exists
244 wiki_page = link_project.wiki.find_page(page)
245 wiki_page = link_project.wiki.find_page(page)
245 link_to((title || page), format_wiki_link.call(link_project, Wiki.titleize(page)),
246 link_to((title || page), format_wiki_link.call(link_project, Wiki.titleize(page)),
246 :class => ('wiki-page' + (wiki_page ? '' : ' new')))
247 :class => ('wiki-page' + (wiki_page ? '' : ' new')))
248 else
249 # project or wiki doesn't exist
250 title || page
251 end
247 else
252 else
248 # project or wiki doesn't exist
253 all
249 title || page
250 end
254 end
251 end
255 end
252
256
253 # turn issue and revision ids into links
257 # Redmine links
254 # example:
258 #
255 # #52 -> <a href="/issues/show/52">#52</a>
259 # Examples:
256 # r52 -> <a href="/repositories/revision/6?rev=52">r52</a> (project.id is 6)
260 # Issues:
257 text = text.gsub(%r{([\s\(,-^])(#|r)(\d+)(?=[[:punct:]]|\s|<|$)}) do |m|
261 # #52 -> Link to issue #52
258 leading, otype, oid = $1, $2, $3
262 # Changesets:
263 # r52 -> Link to revision 52
264 # Documents:
265 # document#17 -> Link to document with id 17
266 # document:Greetings -> Link to the document with title "Greetings"
267 # document:"Some document" -> Link to the document with title "Some document"
268 # Versions:
269 # version#3 -> Link to version with id 3
270 # version:1.0.0 -> Link to version named "1.0.0"
271 # version:"1.0 beta 2" -> Link to version named "1.0 beta 2"
272 # Attachments:
273 # attachment:file.zip -> Link to the attachment of the current object named file.zip
274 text = text.gsub(%r{([\s\(,-^])(!)?(attachment|document|version)?((#|r)(\d+)|(:)([^"][^\s<>]+|"[^"]+"))(?=[[:punct:]]|\s|<|$)}) do |m|
275 leading, esc, prefix, sep, oid = $1, $2, $3, $5 || $7, $6 || $8
259 link = nil
276 link = nil
260 if otype == 'r'
277 if esc.nil?
261 if project && (changeset = project.changesets.find_by_revision(oid))
278 if prefix.nil? && sep == 'r'
262 link = link_to("r#{oid}", {:controller => 'repositories', :action => 'revision', :id => project.id, :rev => oid}, :class => 'changeset',
279 if project && (changeset = project.changesets.find_by_revision(oid))
263 :title => truncate(changeset.comments, 100))
280 link = link_to("r#{oid}", {:controller => 'repositories', :action => 'revision', :id => project.id, :rev => oid}, :class => 'changeset',
264 end
281 :title => truncate(changeset.comments, 100))
265 else
282 end
266 if issue = Issue.find_by_id(oid.to_i, :include => [:project, :status], :conditions => Project.visible_by(User.current))
283 elsif sep == '#'
267 link = link_to("##{oid}", {:controller => 'issues', :action => 'show', :id => oid}, :class => 'issue',
284 oid = oid.to_i
268 :title => "#{truncate(issue.subject, 100)} (#{issue.status.name})")
285 case prefix
269 link = content_tag('del', link) if issue.closed?
286 when nil
287 if issue = Issue.find_by_id(oid, :include => [:project, :status], :conditions => Project.visible_by(User.current))
288 link = link_to("##{oid}", {:controller => 'issues', :action => 'show', :id => oid}, :class => 'issue',
289 :title => "#{truncate(issue.subject, 100)} (#{issue.status.name})")
290 link = content_tag('del', link) if issue.closed?
291 end
292 when 'document'
293 if document = Document.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
294 link = link_to h(document.title), {:controller => 'documents', :action => 'show', :id => document}, :class => 'document'
295 end
296 when 'version'
297 if version = Version.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
298 link = link_to h(version.name), {:controller => 'versions', :action => 'show', :id => version}, :class => 'version'
299 end
300 end
301 elsif sep == ':'
302 # removes the double quotes if any
303 name = oid.gsub(%r{^"(.*)"$}, "\\1")
304 case prefix
305 when 'document'
306 if project && document = project.documents.find_by_title(name)
307 link = link_to h(document.title), {:controller => 'documents', :action => 'show', :id => document}, :class => 'document'
308 end
309 when 'version'
310 if project && version = project.versions.find_by_name(name)
311 link = link_to h(version.name), {:controller => 'versions', :action => 'show', :id => version}, :class => 'version'
312 end
313 when 'attachment'
314 if attachments && attachment = attachments.detect {|a| a.filename == name }
315 link = link_to h(attachment.filename), {:controller => 'attachments', :action => 'download', :id => attachment}, :class => 'attachment'
316 end
317 end
270 end
318 end
271 end
319 end
272 leading + (link || "#{otype}#{oid}")
320 leading + (link || "#{prefix}#{sep}#{oid}")
273 end
321 end
274
322
275 text
323 text
@@ -395,15 +395,15 class RedCloth < String
395 # Elements to handle
395 # Elements to handle
396 GLYPHS = [
396 GLYPHS = [
397 # [ /([^\s\[{(>])?\'([dmst]\b|ll\b|ve\b|\s|:|$)/, '\1&#8217;\2' ], # single closing
397 # [ /([^\s\[{(>])?\'([dmst]\b|ll\b|ve\b|\s|:|$)/, '\1&#8217;\2' ], # single closing
398 [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)\'/, '\1&#8217;' ], # single closing
398 # [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)\'/, '\1&#8217;' ], # single closing
399 [ /\'(?=[#{PUNCT_Q}]*(s\b|[\s#{PUNCT_NOQ}]))/, '&#8217;' ], # single closing
399 # [ /\'(?=[#{PUNCT_Q}]*(s\b|[\s#{PUNCT_NOQ}]))/, '&#8217;' ], # single closing
400 [ /\'/, '&#8216;' ], # single opening
400 # [ /\'/, '&#8216;' ], # single opening
401 [ /</, '&lt;' ], # less-than
401 [ /</, '&lt;' ], # less-than
402 [ />/, '&gt;' ], # greater-than
402 [ />/, '&gt;' ], # greater-than
403 # [ /([^\s\[{(])?"(\s|:|$)/, '\1&#8221;\2' ], # double closing
403 # [ /([^\s\[{(])?"(\s|:|$)/, '\1&#8221;\2' ], # double closing
404 [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)"/, '\1&#8221;' ], # double closing
404 # [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)"/, '\1&#8221;' ], # double closing
405 [ /"(?=[#{PUNCT_Q}]*[\s#{PUNCT_NOQ}])/, '&#8221;' ], # double closing
405 # [ /"(?=[#{PUNCT_Q}]*[\s#{PUNCT_NOQ}])/, '&#8221;' ], # double closing
406 [ /"/, '&#8220;' ], # double opening
406 # [ /"/, '&#8220;' ], # double opening
407 [ /\b( )?\.{3}/, '\1&#8230;' ], # ellipsis
407 [ /\b( )?\.{3}/, '\1&#8230;' ], # ellipsis
408 [ /\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/, '<acronym title="\2">\1</acronym>' ], # 3+ uppercase acronym
408 [ /\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/, '<acronym title="\2">\1</acronym>' ], # 3+ uppercase acronym
409 [ /(^|[^"][>\s])([A-Z][A-Z0-9 ]+[A-Z0-9])([^<A-Za-z0-9]|$)/, '\1<span class="caps">\2</span>\3', :no_span_caps ], # 3+ uppercase caps
409 [ /(^|[^"][>\s])([A-Z][A-Z0-9 ]+[A-Z0-9])([^<A-Za-z0-9]|$)/, '\1<span class="caps">\2</span>\3', :no_span_caps ], # 3+ uppercase caps
@@ -21,4 +21,14 wiki_contents_002:
21 page_id: 2
21 page_id: 2
22 id: 2
22 id: 2
23 version: 1
23 version: 1
24 author_id: 1 No newline at end of file
24 author_id: 1
25 comments:
26 wiki_contents_003:
27 text: |-
28 h1. Start page
29
30 E-commerce web site start page
31 updated_on: 2007-03-08 00:18:07 +01:00
32 page_id: 3
33 id: 3
34 version: 1
@@ -9,4 +9,9 wiki_pages_002:
9 title: Another_page
9 title: Another_page
10 id: 2
10 id: 2
11 wiki_id: 1
11 wiki_id: 1
12 wiki_pages_003:
13 created_on: 2007-03-08 00:18:07 +01:00
14 title: Start_page
15 id: 3
16 wiki_id: 2
12 No newline at end of file
17
@@ -4,3 +4,9 wikis_001:
4 start_page: CookBook documentation
4 start_page: CookBook documentation
5 project_id: 1
5 project_id: 1
6 id: 1
6 id: 1
7 wikis_002:
8 status: 1
9 start_page: Start page
10 project_id: 2
11 id: 2
12 No newline at end of file
@@ -20,7 +20,7 require File.dirname(__FILE__) + '/../../test_helper'
20 class ApplicationHelperTest < HelperTestCase
20 class ApplicationHelperTest < HelperTestCase
21 include ApplicationHelper
21 include ApplicationHelper
22 include ActionView::Helpers::TextHelper
22 include ActionView::Helpers::TextHelper
23 fixtures :projects, :repositories, :changesets, :trackers, :issue_statuses, :issues
23 fixtures :projects, :repositories, :changesets, :trackers, :issue_statuses, :issues, :documents, :versions, :wikis, :wiki_pages, :wiki_contents
24
24
25 def setup
25 def setup
26 super
26 super
@@ -66,12 +66,52 class ApplicationHelperTest < HelperTestCase
66 def test_redmine_links
66 def test_redmine_links
67 issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
67 issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
68 :class => 'issue', :title => 'Error 281 when updating a recipe (New)')
68 :class => 'issue', :title => 'Error 281 when updating a recipe (New)')
69
69 changeset_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 1, :rev => 1},
70 changeset_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 1, :rev => 1},
70 :class => 'changeset', :title => 'My very first commit')
71 :class => 'changeset', :title => 'My very first commit')
71
72
73 document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
74 :class => 'document')
75
76 version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
77 :class => 'version')
78
72 to_test = {
79 to_test = {
73 '#3, #3 and #3.' => "#{issue_link}, #{issue_link} and #{issue_link}.",
80 '#3, #3 and #3.' => "#{issue_link}, #{issue_link} and #{issue_link}.",
74 'r1' => changeset_link
81 'r1' => changeset_link,
82 'document#1' => document_link,
83 'document:"Test document"' => document_link,
84 'version#2' => version_link,
85 'version:1.0' => version_link,
86 'version:"1.0"' => version_link,
87 # escaping
88 '!#3.' => '#3.',
89 '!r1' => 'r1',
90 '!document#1' => 'document#1',
91 '!document:"Test document"' => 'document:"Test document"',
92 '!version#2' => 'version#2',
93 '!version:1.0' => 'version:1.0',
94 '!version:"1.0"' => 'version:"1.0"',
95 }
96 @project = Project.find(1)
97 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
98 end
99
100 def test_wiki_links
101 to_test = {
102 '[[CookBook documentation]]' => '<a href="/wiki/ecookbook/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
103 '[[Another page|Page]]' => '<a href="/wiki/ecookbook/Another_page" class="wiki-page">Page</a>',
104 # page that doesn't exist
105 '[[Unknown page]]' => '<a href="/wiki/ecookbook/Unknown_page" class="wiki-page new">Unknown page</a>',
106 '[[Unknown page|404]]' => '<a href="/wiki/ecookbook/Unknown_page" class="wiki-page new">404</a>',
107 # link to another project wiki
108 '[[onlinestore:]]' => '<a href="/wiki/onlinestore/" class="wiki-page">onlinestore</a>',
109 '[[onlinestore:|Wiki]]' => '<a href="/wiki/onlinestore/" class="wiki-page">Wiki</a>',
110 '[[onlinestore:Start page]]' => '<a href="/wiki/onlinestore/Start_page" class="wiki-page">Start page</a>',
111 '[[onlinestore:Start page|Text]]' => '<a href="/wiki/onlinestore/Start_page" class="wiki-page">Text</a>',
112 '[[onlinestore:Unknown page]]' => '<a href="/wiki/onlinestore/Unknown_page" class="wiki-page new">Unknown page</a>',
113 # escaping
114 '![[Another page|Page]]' => '[[Another page|Page]]',
75 }
115 }
76 @project = Project.find(1)
116 @project = Project.find(1)
77 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
117 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
General Comments 0
You need to be logged in to leave comments. Login now