ensures rel="nofollow" is added to all anchors if a page is retrieved with a SHA

This commit is contained in:
rick
2010-09-30 17:19:37 -07:00
parent cc929bbc56
commit 4dbe3ea844
4 changed files with 75 additions and 20 deletions
+5
View File
@@ -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
View File
@@ -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
View File
@@ -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
+10
View File
@@ -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)