Merge pull request #1568 from nitoyon/url-escape
This commit is contained in:
commit
806f43cdbc
|
@ -135,7 +135,7 @@ module Jekyll
|
||||||
#
|
#
|
||||||
# Returns the destination file path String.
|
# Returns the destination file path String.
|
||||||
def destination(dest)
|
def destination(dest)
|
||||||
path = Jekyll.sanitized_path(dest, url)
|
path = Jekyll.sanitized_path(dest, URL.unescape_path(url))
|
||||||
path = File.join(path, "index.html") if url =~ /\/$/
|
path = File.join(path, "index.html") if url =~ /\/$/
|
||||||
path
|
path
|
||||||
end
|
end
|
||||||
|
|
|
@ -208,10 +208,10 @@ module Jekyll
|
||||||
:year => date.strftime("%Y"),
|
:year => date.strftime("%Y"),
|
||||||
:month => date.strftime("%m"),
|
:month => date.strftime("%m"),
|
||||||
:day => date.strftime("%d"),
|
:day => date.strftime("%d"),
|
||||||
:title => CGI.escape(slug),
|
:title => slug,
|
||||||
:i_day => date.strftime("%d").to_i.to_s,
|
:i_day => date.strftime("%d").to_i.to_s,
|
||||||
:i_month => date.strftime("%m").to_i.to_s,
|
:i_month => date.strftime("%m").to_i.to_s,
|
||||||
:categories => (categories || []).map { |c| URI.escape(c.to_s) }.join('/'),
|
:categories => (categories || []).map { |c| c.to_s }.join('/'),
|
||||||
:short_month => date.strftime("%b"),
|
:short_month => date.strftime("%b"),
|
||||||
:y_day => date.strftime("%j"),
|
:y_day => date.strftime("%j"),
|
||||||
:output_ext => output_ext
|
:output_ext => output_ext
|
||||||
|
@ -260,7 +260,7 @@ module Jekyll
|
||||||
# Returns destination file path String.
|
# Returns destination file path String.
|
||||||
def destination(dest)
|
def destination(dest)
|
||||||
# The url needs to be unescaped in order to preserve the correct filename
|
# The url needs to be unescaped in order to preserve the correct filename
|
||||||
path = Jekyll.sanitized_path(dest, CGI.unescape(url))
|
path = Jekyll.sanitized_path(dest, URL.unescape_path(url))
|
||||||
path = File.join(path, "index.html") if path[/\.html$/].nil?
|
path = File.join(path, "index.html") if path[/\.html$/].nil?
|
||||||
path
|
path
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
require 'uri'
|
||||||
|
|
||||||
# Public: Methods that generate a URL for a resource such as a Post or a Page.
|
# Public: Methods that generate a URL for a resource such as a Post or a Page.
|
||||||
#
|
#
|
||||||
# Examples
|
# Examples
|
||||||
|
@ -44,7 +46,7 @@ module Jekyll
|
||||||
# Returns the _unsanitizied_ String URL
|
# Returns the _unsanitizied_ String URL
|
||||||
def generate_url
|
def generate_url
|
||||||
@placeholders.inject(@template) do |result, token|
|
@placeholders.inject(@template) do |result, token|
|
||||||
result.gsub(/:#{token.first}/, token.last)
|
result.gsub(/:#{token.first}/, self.class.escape_path(token.last))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -65,5 +67,43 @@ module Jekyll
|
||||||
|
|
||||||
url
|
url
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Escapes a path to be a valid URL path segment
|
||||||
|
#
|
||||||
|
# path - The path to be escaped.
|
||||||
|
#
|
||||||
|
# Examples:
|
||||||
|
#
|
||||||
|
# URL.escape_path("/a b")
|
||||||
|
# # => "/a%20b"
|
||||||
|
#
|
||||||
|
# Returns the escaped path.
|
||||||
|
def self.escape_path(path)
|
||||||
|
# Because URI.escape doesn't escape '?', '[' and ']' by defaut,
|
||||||
|
# specify unsafe string (except unreserved, sub-delims, ":", "@" and "/").
|
||||||
|
#
|
||||||
|
# URI path segment is defined in RFC 3986 as follows:
|
||||||
|
# segment = *pchar
|
||||||
|
# pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
||||||
|
# unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
||||||
|
# pct-encoded = "%" HEXDIG HEXDIG
|
||||||
|
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
||||||
|
# / "*" / "+" / "," / ";" / "="
|
||||||
|
URI.escape(path, /[^a-zA-Z\d\-._~!$&\'()*+,;=:@\/]/)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Unescapes a URL path segment
|
||||||
|
#
|
||||||
|
# path - The path to be unescaped.
|
||||||
|
#
|
||||||
|
# Examples:
|
||||||
|
#
|
||||||
|
# URL.unescape_path("/a%20b")
|
||||||
|
# # => "/a b"
|
||||||
|
#
|
||||||
|
# Returns the unescaped path.
|
||||||
|
def self.unescape_path(path)
|
||||||
|
URI.unescape(path)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
layout: default
|
||||||
|
title : Page name with non-alphabetic character
|
||||||
|
---
|
||||||
|
Line 1
|
||||||
|
{{ page.title }}
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
layout: default
|
||||||
|
title: Plus space percent
|
||||||
|
---
|
||||||
|
|
||||||
|
Signs are nice
|
|
@ -125,7 +125,7 @@ class TestFilters < Test::Unit::TestCase
|
||||||
case g["name"]
|
case g["name"]
|
||||||
when "default"
|
when "default"
|
||||||
assert g["items"].is_a?(Array), "The list of grouped items for 'default' is not an Array."
|
assert g["items"].is_a?(Array), "The list of grouped items for 'default' is not an Array."
|
||||||
assert_equal 4, g["items"].size
|
assert_equal 5, g["items"].size
|
||||||
when "nil"
|
when "nil"
|
||||||
assert g["items"].is_a?(Array), "The list of grouped items for 'nil' is not an Array."
|
assert g["items"].is_a?(Array), "The list of grouped items for 'nil' is not an Array."
|
||||||
assert_equal 2, g["items"].size
|
assert_equal 2, g["items"].size
|
||||||
|
|
|
@ -30,6 +30,11 @@ class TestPage < Test::Unit::TestCase
|
||||||
assert_equal false, @page.published?
|
assert_equal false, @page.published?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
should "create url with non-alphabetic characters" do
|
||||||
|
@page = setup_page('+', '%# +.md')
|
||||||
|
assert_equal "/+/%25%23%20+.html", @page.url
|
||||||
|
end
|
||||||
|
|
||||||
context "in a directory hierarchy" do
|
context "in a directory hierarchy" do
|
||||||
should "create url based on filename" do
|
should "create url based on filename" do
|
||||||
@page = setup_page('/contacts', 'bar.html')
|
@page = setup_page('/contacts', 'bar.html')
|
||||||
|
@ -174,6 +179,15 @@ class TestPage < Test::Unit::TestCase
|
||||||
assert File.exists?(File.join(dest_dir, '+', 'plus+in+url'))
|
assert File.exists?(File.join(dest_dir, '+', 'plus+in+url'))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
should "write even when permalink has '%# +'" do
|
||||||
|
page = setup_page('+', '%# +.md')
|
||||||
|
do_render(page)
|
||||||
|
page.write(dest_dir)
|
||||||
|
|
||||||
|
assert File.directory?(dest_dir)
|
||||||
|
assert File.exists?(File.join(dest_dir, '+', '%# +.html'))
|
||||||
|
end
|
||||||
|
|
||||||
should "write properly without html extension" do
|
should "write properly without html extension" do
|
||||||
page = setup_page('contacts.html')
|
page = setup_page('contacts.html')
|
||||||
page.site.permalink_style = :pretty
|
page.site.permalink_style = :pretty
|
||||||
|
|
|
@ -86,13 +86,20 @@ class TestPost < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
should "CGI escape urls" do
|
should "escape urls" do
|
||||||
@post.categories = []
|
@post.categories = []
|
||||||
@post.process("2009-03-12-hash-#1.markdown")
|
@post.process("2009-03-12-hash-#1.markdown")
|
||||||
assert_equal "/2009/03/12/hash-%231.html", @post.url
|
assert_equal "/2009/03/12/hash-%231.html", @post.url
|
||||||
assert_equal "/2009/03/12/hash-#1", @post.id
|
assert_equal "/2009/03/12/hash-#1", @post.id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
should "escape urls with non-alphabetic characters" do
|
||||||
|
@post.categories = []
|
||||||
|
@post.process("2014-03-22-escape-+ %20[].markdown")
|
||||||
|
assert_equal "/2014/03/22/escape-+%20%2520%5B%5D.html", @post.url
|
||||||
|
assert_equal "/2014/03/22/escape-+ %20[]", @post.id
|
||||||
|
end
|
||||||
|
|
||||||
should "respect permalink in yaml front matter" do
|
should "respect permalink in yaml front matter" do
|
||||||
file = "2008-12-03-permalinked-post.textile"
|
file = "2008-12-03-permalinked-post.textile"
|
||||||
@post.process(file)
|
@post.process(file)
|
||||||
|
@ -533,6 +540,26 @@ class TestPost < Test::Unit::TestCase
|
||||||
assert File.exists?(File.join(dest_dir, '2008', '10', '18', 'foo-bar.html'))
|
assert File.exists?(File.join(dest_dir, '2008', '10', '18', 'foo-bar.html'))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
should "write properly when url has hash" do
|
||||||
|
post = setup_post("2009-03-12-hash-#1.markdown")
|
||||||
|
do_render(post)
|
||||||
|
post.write(dest_dir)
|
||||||
|
|
||||||
|
assert File.directory?(dest_dir)
|
||||||
|
assert File.exists?(File.join(dest_dir, '2009', '03', '12',
|
||||||
|
'hash-#1.html'))
|
||||||
|
end
|
||||||
|
|
||||||
|
should "write properly when url has space" do
|
||||||
|
post = setup_post("2014-03-22-escape-+ %20[].markdown")
|
||||||
|
do_render(post)
|
||||||
|
post.write(dest_dir)
|
||||||
|
|
||||||
|
assert File.directory?(dest_dir)
|
||||||
|
assert File.exists?(File.join(dest_dir, '2014', '03', '22',
|
||||||
|
'escape-+ %20[].html'))
|
||||||
|
end
|
||||||
|
|
||||||
should "write properly without html extension" do
|
should "write properly without html extension" do
|
||||||
post = setup_post("2008-10-18-foo-bar.textile")
|
post = setup_post("2008-10-18-foo-bar.textile")
|
||||||
post.site.permalink_style = ":title"
|
post.site.permalink_style = ":title"
|
||||||
|
|
|
@ -159,6 +159,7 @@ class TestSite < Test::Unit::TestCase
|
||||||
@site.process
|
@site.process
|
||||||
# files in symlinked directories may appear twice
|
# files in symlinked directories may appear twice
|
||||||
sorted_pages = %w(
|
sorted_pages = %w(
|
||||||
|
%#\ +.md
|
||||||
.htaccess
|
.htaccess
|
||||||
about.html
|
about.html
|
||||||
bar.html
|
bar.html
|
||||||
|
|
Loading…
Reference in New Issue