Redmine links can be used to link to documents, versions and attachments.
For now, attachments of the current object can be referenced only (if you're on an issue, it's possible reference attachments of this issue only). git-svn-id: http://redmine.rubyforge.org/svn/trunk@1064 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
4e1e5985a1
commit
702b521b45
|
@ -220,8 +220,9 @@ module ApplicationHelper
|
|||
|
||||
project = options[:project] || @project
|
||||
|
||||
# turn wiki links into html links
|
||||
# example:
|
||||
# Wiki links
|
||||
#
|
||||
# Examples:
|
||||
# [[mypage]]
|
||||
# [[mypage|mytext]]
|
||||
# wiki links can refer other project wikis, using project name or identifier:
|
||||
|
@ -229,47 +230,94 @@ module ApplicationHelper
|
|||
# [[project:|mytext]]
|
||||
# [[project:mypage]]
|
||||
# [[project:mypage|mytext]]
|
||||
text = text.gsub(/\[\[([^\]\|]+)(\|([^\]\|]+))?\]\]/) do |m|
|
||||
text = text.gsub(/(!)?(\[\[([^\]\|]+)(\|([^\]\|]+))?\]\])/) do |m|
|
||||
link_project = project
|
||||
page = $1
|
||||
title = $3
|
||||
if page =~ /^([^\:]+)\:(.*)$/
|
||||
link_project = Project.find_by_name($1) || Project.find_by_identifier($1)
|
||||
page = title || $2
|
||||
title = $1 if page.blank?
|
||||
end
|
||||
|
||||
if link_project && link_project.wiki
|
||||
# check if page exists
|
||||
wiki_page = link_project.wiki.find_page(page)
|
||||
link_to((title || page), format_wiki_link.call(link_project, Wiki.titleize(page)),
|
||||
:class => ('wiki-page' + (wiki_page ? '' : ' new')))
|
||||
esc, all, page, title = $1, $2, $3, $5
|
||||
if esc.nil?
|
||||
if page =~ /^([^\:]+)\:(.*)$/
|
||||
link_project = Project.find_by_name($1) || Project.find_by_identifier($1)
|
||||
page = $2
|
||||
title ||= $1 if page.blank?
|
||||
end
|
||||
|
||||
if link_project && link_project.wiki
|
||||
# check if page exists
|
||||
wiki_page = link_project.wiki.find_page(page)
|
||||
link_to((title || page), format_wiki_link.call(link_project, Wiki.titleize(page)),
|
||||
:class => ('wiki-page' + (wiki_page ? '' : ' new')))
|
||||
else
|
||||
# project or wiki doesn't exist
|
||||
title || page
|
||||
end
|
||||
else
|
||||
# project or wiki doesn't exist
|
||||
title || page
|
||||
all
|
||||
end
|
||||
end
|
||||
|
||||
# turn issue and revision ids into links
|
||||
# example:
|
||||
# #52 -> <a href="/issues/show/52">#52</a>
|
||||
# r52 -> <a href="/repositories/revision/6?rev=52">r52</a> (project.id is 6)
|
||||
text = text.gsub(%r{([\s\(,-^])(#|r)(\d+)(?=[[:punct:]]|\s|<|$)}) do |m|
|
||||
leading, otype, oid = $1, $2, $3
|
||||
# Redmine links
|
||||
#
|
||||
# Examples:
|
||||
# Issues:
|
||||
# #52 -> Link to issue #52
|
||||
# Changesets:
|
||||
# r52 -> Link to revision 52
|
||||
# Documents:
|
||||
# document#17 -> Link to document with id 17
|
||||
# document:Greetings -> Link to the document with title "Greetings"
|
||||
# document:"Some document" -> Link to the document with title "Some document"
|
||||
# Versions:
|
||||
# version#3 -> Link to version with id 3
|
||||
# version:1.0.0 -> Link to version named "1.0.0"
|
||||
# version:"1.0 beta 2" -> Link to version named "1.0 beta 2"
|
||||
# Attachments:
|
||||
# attachment:file.zip -> Link to the attachment of the current object named file.zip
|
||||
text = text.gsub(%r{([\s\(,-^])(!)?(attachment|document|version)?((#|r)(\d+)|(:)([^"][^\s<>]+|"[^"]+"))(?=[[:punct:]]|\s|<|$)}) do |m|
|
||||
leading, esc, prefix, sep, oid = $1, $2, $3, $5 || $7, $6 || $8
|
||||
link = nil
|
||||
if otype == 'r'
|
||||
if project && (changeset = project.changesets.find_by_revision(oid))
|
||||
link = link_to("r#{oid}", {:controller => 'repositories', :action => 'revision', :id => project.id, :rev => oid}, :class => 'changeset',
|
||||
:title => truncate(changeset.comments, 100))
|
||||
end
|
||||
else
|
||||
if issue = Issue.find_by_id(oid.to_i, :include => [:project, :status], :conditions => Project.visible_by(User.current))
|
||||
link = link_to("##{oid}", {:controller => 'issues', :action => 'show', :id => oid}, :class => 'issue',
|
||||
:title => "#{truncate(issue.subject, 100)} (#{issue.status.name})")
|
||||
link = content_tag('del', link) if issue.closed?
|
||||
if esc.nil?
|
||||
if prefix.nil? && sep == 'r'
|
||||
if project && (changeset = project.changesets.find_by_revision(oid))
|
||||
link = link_to("r#{oid}", {:controller => 'repositories', :action => 'revision', :id => project.id, :rev => oid}, :class => 'changeset',
|
||||
:title => truncate(changeset.comments, 100))
|
||||
end
|
||||
elsif sep == '#'
|
||||
oid = oid.to_i
|
||||
case prefix
|
||||
when nil
|
||||
if issue = Issue.find_by_id(oid, :include => [:project, :status], :conditions => Project.visible_by(User.current))
|
||||
link = link_to("##{oid}", {:controller => 'issues', :action => 'show', :id => oid}, :class => 'issue',
|
||||
:title => "#{truncate(issue.subject, 100)} (#{issue.status.name})")
|
||||
link = content_tag('del', link) if issue.closed?
|
||||
end
|
||||
when 'document'
|
||||
if document = Document.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
|
||||
link = link_to h(document.title), {:controller => 'documents', :action => 'show', :id => document}, :class => 'document'
|
||||
end
|
||||
when 'version'
|
||||
if version = Version.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
|
||||
link = link_to h(version.name), {:controller => 'versions', :action => 'show', :id => version}, :class => 'version'
|
||||
end
|
||||
end
|
||||
elsif sep == ':'
|
||||
# removes the double quotes if any
|
||||
name = oid.gsub(%r{^"(.*)"$}, "\\1")
|
||||
case prefix
|
||||
when 'document'
|
||||
if project && document = project.documents.find_by_title(name)
|
||||
link = link_to h(document.title), {:controller => 'documents', :action => 'show', :id => document}, :class => 'document'
|
||||
end
|
||||
when 'version'
|
||||
if project && version = project.versions.find_by_name(name)
|
||||
link = link_to h(version.name), {:controller => 'versions', :action => 'show', :id => version}, :class => 'version'
|
||||
end
|
||||
when 'attachment'
|
||||
if attachments && attachment = attachments.detect {|a| a.filename == name }
|
||||
link = link_to h(attachment.filename), {:controller => 'attachments', :action => 'download', :id => attachment}, :class => 'attachment'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
leading + (link || "#{otype}#{oid}")
|
||||
leading + (link || "#{prefix}#{sep}#{oid}")
|
||||
end
|
||||
|
||||
text
|
||||
|
|
|
@ -395,15 +395,15 @@ class RedCloth < String
|
|||
# Elements to handle
|
||||
GLYPHS = [
|
||||
# [ /([^\s\[{(>])?\'([dmst]\b|ll\b|ve\b|\s|:|$)/, '\1’\2' ], # single closing
|
||||
[ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)\'/, '\1’' ], # single closing
|
||||
[ /\'(?=[#{PUNCT_Q}]*(s\b|[\s#{PUNCT_NOQ}]))/, '’' ], # single closing
|
||||
[ /\'/, '‘' ], # single opening
|
||||
# [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)\'/, '\1’' ], # single closing
|
||||
# [ /\'(?=[#{PUNCT_Q}]*(s\b|[\s#{PUNCT_NOQ}]))/, '’' ], # single closing
|
||||
# [ /\'/, '‘' ], # single opening
|
||||
[ /</, '<' ], # less-than
|
||||
[ />/, '>' ], # greater-than
|
||||
# [ /([^\s\[{(])?"(\s|:|$)/, '\1”\2' ], # double closing
|
||||
[ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)"/, '\1”' ], # double closing
|
||||
[ /"(?=[#{PUNCT_Q}]*[\s#{PUNCT_NOQ}])/, '”' ], # double closing
|
||||
[ /"/, '“' ], # double opening
|
||||
# [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)"/, '\1”' ], # double closing
|
||||
# [ /"(?=[#{PUNCT_Q}]*[\s#{PUNCT_NOQ}])/, '”' ], # double closing
|
||||
# [ /"/, '“' ], # double opening
|
||||
[ /\b( )?\.{3}/, '\1…' ], # ellipsis
|
||||
[ /\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/, '<acronym title="\2">\1</acronym>' ], # 3+ uppercase acronym
|
||||
[ /(^|[^"][>\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:
|
|||
version: 1
|
||||
author_id: 1
|
||||
comments:
|
||||
|
||||
wiki_contents_003:
|
||||
text: |-
|
||||
h1. Start page
|
||||
|
||||
E-commerce web site start page
|
||||
updated_on: 2007-03-08 00:18:07 +01:00
|
||||
page_id: 3
|
||||
id: 3
|
||||
version: 1
|
||||
author_id: 1
|
||||
comments:
|
||||
|
|
|
@ -9,4 +9,9 @@ wiki_pages_002:
|
|||
title: Another_page
|
||||
id: 2
|
||||
wiki_id: 1
|
||||
wiki_pages_003:
|
||||
created_on: 2007-03-08 00:18:07 +01:00
|
||||
title: Start_page
|
||||
id: 3
|
||||
wiki_id: 2
|
||||
|
|
@ -4,3 +4,9 @@ wikis_001:
|
|||
start_page: CookBook documentation
|
||||
project_id: 1
|
||||
id: 1
|
||||
wikis_002:
|
||||
status: 1
|
||||
start_page: Start page
|
||||
project_id: 2
|
||||
id: 2
|
||||
|
|
@ -20,7 +20,7 @@ require File.dirname(__FILE__) + '/../../test_helper'
|
|||
class ApplicationHelperTest < HelperTestCase
|
||||
include ApplicationHelper
|
||||
include ActionView::Helpers::TextHelper
|
||||
fixtures :projects, :repositories, :changesets, :trackers, :issue_statuses, :issues
|
||||
fixtures :projects, :repositories, :changesets, :trackers, :issue_statuses, :issues, :documents, :versions, :wikis, :wiki_pages, :wiki_contents
|
||||
|
||||
def setup
|
||||
super
|
||||
|
@ -66,12 +66,52 @@ class ApplicationHelperTest < HelperTestCase
|
|||
def test_redmine_links
|
||||
issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
|
||||
:class => 'issue', :title => 'Error 281 when updating a recipe (New)')
|
||||
|
||||
changeset_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 1, :rev => 1},
|
||||
:class => 'changeset', :title => 'My very first commit')
|
||||
|
||||
document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
|
||||
:class => 'document')
|
||||
|
||||
version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
|
||||
:class => 'version')
|
||||
|
||||
to_test = {
|
||||
'#3, #3 and #3.' => "#{issue_link}, #{issue_link} and #{issue_link}.",
|
||||
'r1' => changeset_link
|
||||
'r1' => changeset_link,
|
||||
'document#1' => document_link,
|
||||
'document:"Test document"' => document_link,
|
||||
'version#2' => version_link,
|
||||
'version:1.0' => version_link,
|
||||
'version:"1.0"' => version_link,
|
||||
# escaping
|
||||
'!#3.' => '#3.',
|
||||
'!r1' => 'r1',
|
||||
'!document#1' => 'document#1',
|
||||
'!document:"Test document"' => 'document:"Test document"',
|
||||
'!version#2' => 'version#2',
|
||||
'!version:1.0' => 'version:1.0',
|
||||
'!version:"1.0"' => 'version:"1.0"',
|
||||
}
|
||||
@project = Project.find(1)
|
||||
to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
|
||||
end
|
||||
|
||||
def test_wiki_links
|
||||
to_test = {
|
||||
'[[CookBook documentation]]' => '<a href="/wiki/ecookbook/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
|
||||
'[[Another page|Page]]' => '<a href="/wiki/ecookbook/Another_page" class="wiki-page">Page</a>',
|
||||
# page that doesn't exist
|
||||
'[[Unknown page]]' => '<a href="/wiki/ecookbook/Unknown_page" class="wiki-page new">Unknown page</a>',
|
||||
'[[Unknown page|404]]' => '<a href="/wiki/ecookbook/Unknown_page" class="wiki-page new">404</a>',
|
||||
# link to another project wiki
|
||||
'[[onlinestore:]]' => '<a href="/wiki/onlinestore/" class="wiki-page">onlinestore</a>',
|
||||
'[[onlinestore:|Wiki]]' => '<a href="/wiki/onlinestore/" class="wiki-page">Wiki</a>',
|
||||
'[[onlinestore:Start page]]' => '<a href="/wiki/onlinestore/Start_page" class="wiki-page">Start page</a>',
|
||||
'[[onlinestore:Start page|Text]]' => '<a href="/wiki/onlinestore/Start_page" class="wiki-page">Text</a>',
|
||||
'[[onlinestore:Unknown page]]' => '<a href="/wiki/onlinestore/Unknown_page" class="wiki-page new">Unknown page</a>',
|
||||
# escaping
|
||||
'![[Another page|Page]]' => '[[Another page|Page]]',
|
||||
}
|
||||
@project = Project.find(1)
|
||||
to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
|
||||
|
|
Loading…
Reference in New Issue