Refactor URL processing/generation into separate module

This is done to prepare for improved permalink generation
for URLs containing special characters, as proposed in
issue #782
This commit is contained in:
Lucas Jenss 2013-04-09 23:53:46 +02:00
parent 1319b823f8
commit cfcbe1f830
4 changed files with 77 additions and 52 deletions

View File

@ -30,6 +30,7 @@ require 'pygments'
require 'jekyll/core_ext' require 'jekyll/core_ext'
require 'jekyll/site' require 'jekyll/site'
require 'jekyll/convertible' require 'jekyll/convertible'
require 'jekyll/url'
require 'jekyll/layout' require 'jekyll/layout'
require 'jekyll/page' require 'jekyll/page'
require 'jekyll/post' require 'jekyll/post'

View File

@ -1,6 +1,7 @@
module Jekyll module Jekyll
class Page class Page
include Convertible include Convertible
include URL
attr_writer :dir attr_writer :dir
attr_accessor :site, :pager attr_accessor :site, :pager
@ -69,28 +70,13 @@ module Jekyll
end end
end end
# The generated relative url of this page. e.g. /about.html. # See url.rb for an explanation
# def url_placeholders
# Returns the String url. {
def url "path" => @dir,
return @url if @url "basename" => self.basename,
"output_ext" => self.output_ext
url = if permalink }
permalink
else
{
"path" => @dir,
"basename" => self.basename,
"output_ext" => self.output_ext,
}.inject(template) { |result, token|
result.gsub(/:#{token.first}/, token.last)
}.gsub(/\/\//, "/")
end
# sanitize url
@url = url.split('/').reject{ |part| part =~ /^\.+$/ }.join('/')
@url += "/" if url =~ /\/$/
@url
end end
# Extract information from the page filename. # Extract information from the page filename.

View File

@ -2,6 +2,7 @@ module Jekyll
class Post class Post
include Comparable include Comparable
include Convertible include Convertible
include URL
class << self class << self
attr_accessor :lsi attr_accessor :lsi
@ -153,36 +154,20 @@ module Jekyll
end end
end end
# The generated relative url of this post. # See url.rb for an explanation
# e.g. /2008/11/05/my-awesome-post.html def url_placeholders
# {
# Returns the String URL. "year" => date.strftime("%Y"),
def url "month" => date.strftime("%m"),
return @url if @url "day" => date.strftime("%d"),
"title" => CGI.escape(slug),
url = if permalink "i_day" => date.strftime("%d").to_i.to_s,
permalink "i_month" => date.strftime("%m").to_i.to_s,
else "categories" => categories.map { |c| URI.escape(c.to_s) }.join('/'),
{ "short_month" => date.strftime("%b"),
"year" => date.strftime("%Y"), "y_day" => date.strftime("%j"),
"month" => date.strftime("%m"), "output_ext" => self.output_ext
"day" => date.strftime("%d"), }
"title" => CGI.escape(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('/'),
"short_month" => date.strftime("%b"),
"y_day" => date.strftime("%j"),
"output_ext" => self.output_ext
}.inject(template) { |result, token|
result.gsub(/:#{Regexp.escape token.first}/, token.last)
}.gsub(/\/\//, "/")
end
# sanitize url
@url = url.split('/').reject{ |part| part =~ /^\.+$/ }.join('/')
@url += "/" if url =~ /\/$/
@url
end end
# The UID for this post (useful in feeds). # The UID for this post (useful in feeds).

53
lib/jekyll/url.rb Normal file
View File

@ -0,0 +1,53 @@
# The URL module provides methods that generate a URL for a resource in which they're
# included, such as a Post or a Page.
#
# Requires
#
# self.permalink - If a permalink is set in the included instance, that permalink
# will be returned instead of any URL that might've been generated
#
# self.url_placeholders - Placeholders that may be used in the URL, which will be replaced
# with the values when the URL is generated. Must return a Hash
# mapping placeholder names to their values. For example, if this
# method returned
#
# { "year" => Time.now.strftime("%Y") }
#
# Every occurrence of ":year" (note the colon) would be replaced with
# the current year.
#
#
module Jekyll
module URL
# The generated relative url of this page. e.g. /about.html.
#
# Returns the String url.
def url
@url ||= sanitize_url(permalink || generate_url)
end
# Generate the URL by replacing all placeholders with their respective values
#
# Returns the _unsanitizied_ String URL
def generate_url
url_placeholders.inject(template) { |result, token|
result.gsub(/:#{token.first}/, token.last)
}
end
# Returns a sanitized String URL
def sanitize_url(in_url)
# Remove all double slashes
url = in_url.gsub(/\/\//, "/")
# Remove every URL segment that consists solely of dots
url = url.split('/').reject{ |part| part =~ /^\.+$/ }.join('/')
# Append a trailing slash to the URL if the unsanitized URL had one
url += "/" if in_url =~ /\/$/
url
end
end
end