ensures rel="nofollow" is added to all anchors if a page is retrieved with a SHA
This commit is contained in:
@@ -59,6 +59,11 @@ module Gollum
|
||||
'img' => {'href' => ['http', 'https', :relative]}
|
||||
}
|
||||
}
|
||||
HISTORY_SANITIZATION_OPTIONS = SANITIZATION_OPTIONS.merge(
|
||||
:add_attributes => {
|
||||
'a' => {'rel' => 'nofollow'}
|
||||
}
|
||||
)
|
||||
|
||||
class Error < StandardError; end
|
||||
class DuplicatePageError < Error
|
||||
|
||||
+43
-18
@@ -22,8 +22,14 @@ module Gollum
|
||||
# Render the content with Gollum wiki syntax on top of the file's own
|
||||
# markup language.
|
||||
#
|
||||
# no_follow - Boolean that determines if rel="nofollow" is added to all
|
||||
# <a> tags.
|
||||
#
|
||||
# Returns the formatted String content.
|
||||
def render
|
||||
def render(no_follow = false)
|
||||
sanitize_options = no_follow ?
|
||||
HISTORY_SANITIZATION_OPTIONS :
|
||||
SANITIZATION_OPTIONS
|
||||
data = extract_tex(@data)
|
||||
data = extract_code(data)
|
||||
data = extract_tags(data)
|
||||
@@ -37,9 +43,9 @@ module Gollum
|
||||
end
|
||||
data = process_tags(data)
|
||||
data = process_code(data)
|
||||
data = Sanitize.clean(data, SANITIZATION_OPTIONS)
|
||||
data = Sanitize.clean(data, sanitize_options)
|
||||
data = process_tex(data)
|
||||
data = data.gsub(/<p><\/p>/, '')
|
||||
data.gsub!(/<p><\/p>/, '')
|
||||
data
|
||||
end
|
||||
|
||||
@@ -115,28 +121,33 @@ module Gollum
|
||||
# Process all tags from the tagmap and replace the placeholders with the
|
||||
# final markup.
|
||||
#
|
||||
# data - The String data (with placeholders).
|
||||
# data - The String data (with placeholders).
|
||||
# no_follow - Boolean that determines if rel="nofollow" is added to all
|
||||
# <a> tags.
|
||||
#
|
||||
# Returns the marked up String data.
|
||||
def process_tags(data)
|
||||
def process_tags(data, no_follow = false)
|
||||
@tagmap.each do |id, tag|
|
||||
data.gsub!(id, process_tag(tag))
|
||||
data.gsub!(id, process_tag(tag, no_follow))
|
||||
end
|
||||
data
|
||||
end
|
||||
|
||||
# Process a single tag into its final HTML form.
|
||||
#
|
||||
# tag - The String tag contents (the stuff inside the double brackets).
|
||||
# tag - The String tag contents (the stuff inside the double
|
||||
# brackets).
|
||||
# no_follow - Boolean that determines if rel="nofollow" is added to all
|
||||
# <a> tags.
|
||||
#
|
||||
# Returns the String HTML version of the tag.
|
||||
def process_tag(tag)
|
||||
def process_tag(tag, no_follow = false)
|
||||
if html = process_image_tag(tag)
|
||||
return html
|
||||
elsif html = process_file_link_tag(tag)
|
||||
return html
|
||||
html
|
||||
elsif html = process_file_link_tag(tag, no_follow)
|
||||
html
|
||||
else
|
||||
return process_page_link_tag(tag)
|
||||
process_page_link_tag(tag, no_follow)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -229,11 +240,14 @@ module Gollum
|
||||
|
||||
# Attempt to process the tag as a file link tag.
|
||||
#
|
||||
# tag - The String tag contents (the stuff inside the double brackets).
|
||||
# tag - The String tag contents (the stuff inside the double
|
||||
# brackets).
|
||||
# no_follow - Boolean that determines if rel="nofollow" is added to all
|
||||
# <a> tags.
|
||||
#
|
||||
# Returns the String HTML if the tag is a valid file link tag or nil
|
||||
# if it is not.
|
||||
def process_file_link_tag(tag)
|
||||
def process_file_link_tag(tag, no_follow = false)
|
||||
parts = tag.split('|')
|
||||
name = parts[0].strip
|
||||
path = parts[1] && parts[1].strip
|
||||
@@ -245,26 +259,33 @@ module Gollum
|
||||
nil
|
||||
end
|
||||
|
||||
if name && path && file
|
||||
tag = if name && path && file
|
||||
%{<a href="#{::File.join @wiki.base_path, file.path}">#{name}</a>}
|
||||
elsif name && path
|
||||
%{<a href="#{path}">#{name}</a>}
|
||||
else
|
||||
nil
|
||||
end
|
||||
if tag && no_follow
|
||||
tag.sub! /^<a/, '<a ref="nofollow"'
|
||||
end
|
||||
tag
|
||||
end
|
||||
|
||||
# Attempt to process the tag as a page link tag.
|
||||
#
|
||||
# tag - The String tag contents (the stuff inside the double brackets).
|
||||
# tag - The String tag contents (the stuff inside the double
|
||||
# brackets).
|
||||
# no_follow - Boolean that determines if rel="nofollow" is added to all
|
||||
# <a> tags.
|
||||
#
|
||||
# Returns the String HTML if the tag is a valid page link tag or nil
|
||||
# if it is not.
|
||||
def process_page_link_tag(tag)
|
||||
def process_page_link_tag(tag, no_follow = false)
|
||||
parts = tag.split('|')
|
||||
name = parts[0].strip
|
||||
cname = Page.cname((parts[1] || parts[0]).strip)
|
||||
if name =~ %r{^https?://} && parts[1].nil?
|
||||
tag = if name =~ %r{^https?://} && parts[1].nil?
|
||||
%{<a href="#{name}">#{name}</a>}
|
||||
else
|
||||
presence = "absent"
|
||||
@@ -277,6 +298,10 @@ module Gollum
|
||||
link = ::File.join(@wiki.base_path, CGI.escape(link_name))
|
||||
%{<a class="internal #{presence}" href="#{link}#{extra}">#{name}</a>}
|
||||
end
|
||||
if tag && no_follow
|
||||
tag.sub! /^<a/, '<a ref="nofollow"'
|
||||
end
|
||||
tag
|
||||
end
|
||||
|
||||
# Find the given file in the repo.
|
||||
|
||||
+17
-2
@@ -14,6 +14,11 @@ module Gollum
|
||||
:asciidoc => "AsciiDoc",
|
||||
:pod => "Pod" }
|
||||
|
||||
# Sets a Boolean determing whether this page is a historical version.
|
||||
#
|
||||
# Returns nothing.
|
||||
attr_writer :historical
|
||||
|
||||
# Checks if a filename has a valid extension understood by GitHub::Markup.
|
||||
#
|
||||
# filename - String filename, like "Home.md".
|
||||
@@ -115,7 +120,7 @@ module Gollum
|
||||
#
|
||||
# Returns the String data.
|
||||
def formatted_data
|
||||
@blob && Gollum::Markup.new(self).render
|
||||
@blob && Gollum::Markup.new(self).render(historical?)
|
||||
end
|
||||
|
||||
# Public: The format of the page.
|
||||
@@ -193,6 +198,15 @@ module Gollum
|
||||
find_page_in_tree(map, '_Footer', '')
|
||||
end
|
||||
|
||||
# Gets a Boolean determining whether this page is a historical version.
|
||||
# Historical pages are pulled using exact SHA hashes and format all links
|
||||
# with rel="nofollow"
|
||||
#
|
||||
# Returns true if the page is pulled from a named branch or tag, or false.
|
||||
def historical?
|
||||
!!@historical
|
||||
end
|
||||
|
||||
#########################################################################
|
||||
#
|
||||
# Class Methods
|
||||
@@ -259,7 +273,8 @@ module Gollum
|
||||
map = @wiki.tree_map_for(version)
|
||||
if page = find_page_in_tree(map, name)
|
||||
sha = @wiki.ref_map[version] || version
|
||||
page.version = Grit::Commit.create(@wiki.repo, :id => sha)
|
||||
page.version = Grit::Commit.create(@wiki.repo, :id => sha)
|
||||
page.historical = sha == version
|
||||
page
|
||||
end
|
||||
rescue Grit::GitRuby::Repository::NoSuchShaFound
|
||||
|
||||
@@ -71,6 +71,16 @@ context "Markup" do
|
||||
assert_match /\>Bilbo Baggins\</, output
|
||||
end
|
||||
|
||||
test "adds nofollow to links on historical pages" do
|
||||
sha1 = @wiki.write_page("Sauron", :markdown, "a [[b]] c", commit_details)
|
||||
page = @wiki.page("Sauron")
|
||||
sha2 = @wiki.update_page(page, page.name, :markdown, "c [[b]] a", commit_details)
|
||||
regx = /rel="nofollow"/
|
||||
assert_no_match regx, page.formatted_data
|
||||
assert_match regx, @wiki.page(page.name, sha1).formatted_data
|
||||
assert_match regx, @wiki.page(page.name, sha2).formatted_data
|
||||
end
|
||||
|
||||
test "absent page link" do
|
||||
@wiki.write_page("Tolkien", :markdown, "a [[J. R. R. Tolkien]]'s b", commit_details)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user