mirror of
https://github.com/jekyll/jekyll.git
synced 2026-04-06 03:01:43 -04:00
Fix Post#url escape
Post#url was escaped using CGI.escape. When file name contains a space character, its url points to non-existing URL. For example, when we have a post named '2014-01-02-foo bar.md', we expect its url to be '/2014/01/02/foo%20bar.html', but it was actually '/2014/01/02/foo+bar.html'. We now define Jekyll::URL.escape_path and Jekyll::URL.unescape_path, and use them to escape and unescape Post#url
This commit is contained in:
@@ -208,10 +208,10 @@ module Jekyll
|
||||
:year => date.strftime("%Y"),
|
||||
:month => date.strftime("%m"),
|
||||
:day => date.strftime("%d"),
|
||||
:title => CGI.escape(slug),
|
||||
:title => URL.escape_path(slug),
|
||||
:i_day => date.strftime("%d").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| URL.escape_path(c.to_s) }.join('/'),
|
||||
:short_month => date.strftime("%b"),
|
||||
:y_day => date.strftime("%j"),
|
||||
:output_ext => output_ext
|
||||
@@ -260,7 +260,7 @@ module Jekyll
|
||||
# Returns destination file path String.
|
||||
def destination(dest)
|
||||
# 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
|
||||
end
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'uri'
|
||||
|
||||
# Public: Methods that generate a URL for a resource such as a Post or a Page.
|
||||
#
|
||||
# Examples
|
||||
@@ -65,5 +67,43 @@ module Jekyll
|
||||
|
||||
url
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user