Move URL generation to own class instead of a module
As suggested by @parkr in #944
This commit is contained in:
parent
41b2f0824e
commit
f5d0be9660
|
@ -1,7 +1,6 @@
|
|||
module Jekyll
|
||||
class Page
|
||||
include Convertible
|
||||
include URL
|
||||
|
||||
attr_writer :dir
|
||||
attr_accessor :site, :pager
|
||||
|
@ -63,6 +62,17 @@ module Jekyll
|
|||
end
|
||||
end
|
||||
|
||||
# The generated relative url of this page. e.g. /about.html.
|
||||
#
|
||||
# Returns the String url.
|
||||
def url
|
||||
@url ||= URL.new({
|
||||
:template => template,
|
||||
:placeholders => url_placeholders,
|
||||
:permalink => permalink
|
||||
}).to_s
|
||||
end
|
||||
|
||||
# See url.rb for an explanation
|
||||
def url_placeholders
|
||||
{
|
||||
|
|
|
@ -2,7 +2,6 @@ module Jekyll
|
|||
class Post
|
||||
include Comparable
|
||||
include Convertible
|
||||
include URL
|
||||
|
||||
class << self
|
||||
attr_accessor :lsi
|
||||
|
@ -195,6 +194,17 @@ module Jekyll
|
|||
end
|
||||
end
|
||||
|
||||
# The generated relative url of this post.
|
||||
#
|
||||
# Returns the String url.
|
||||
def url
|
||||
@url ||= URL.new({
|
||||
:template => template,
|
||||
:placeholders => url_placeholders,
|
||||
:permalink => permalink
|
||||
}).to_s
|
||||
end
|
||||
|
||||
# See url.rb for an explanation
|
||||
def url_placeholders
|
||||
{
|
||||
|
@ -204,7 +214,7 @@ module Jekyll
|
|||
"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('/'),
|
||||
"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
|
||||
|
|
|
@ -1,38 +1,49 @@
|
|||
# The URL module provides methods that generate a URL for a resource in which they're
|
||||
# included, such as a Post or a Page.
|
||||
# Public: Methods that generate a URL for a resource such as a Post or a Page.
|
||||
#
|
||||
# Requires
|
||||
# Examples
|
||||
#
|
||||
# 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
|
||||
# URL.new({
|
||||
# :template => /:categories/:title.html",
|
||||
# :placeholders => {:categories => "ruby", :title => "something"}
|
||||
# }).to_s
|
||||
#
|
||||
# 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
|
||||
class URL
|
||||
|
||||
# The generated relative url of this page. e.g. /about.html.
|
||||
#
|
||||
# Returns the String url.
|
||||
def url
|
||||
@url ||= sanitize_url(permalink || generate_url)
|
||||
# options - One of :permalink or :template must be supplied.
|
||||
# :template - The String used as template for URL generation,
|
||||
# for example "/:path/:basename:output_ext", where
|
||||
# a placeholder is prefixed with a colon.
|
||||
# :placeholders - A hash containing the placeholders which will be
|
||||
# replaced when used inside the template. E.g.
|
||||
# { "year" => Time.now.strftime("%Y") } would replace
|
||||
# the placeholder ":year" with the current year.
|
||||
# :permalink - If supplied, no URL will be generated from the
|
||||
# template. Instead, the given permalink will be
|
||||
# used as URL.
|
||||
def initialize(options)
|
||||
@template = options[:template]
|
||||
@placeholders = options[:placeholders] || {}
|
||||
@permalink = options[:permalink]
|
||||
|
||||
if (@template || @permalink).nil?
|
||||
raise ArgumentError, "One of :template or :permalink must be supplied."
|
||||
end
|
||||
end
|
||||
|
||||
# Generate the URL by replacing all placeholders with their respective values
|
||||
# The generated relative URL of the resource
|
||||
#
|
||||
# Returns the String URL
|
||||
def to_s
|
||||
sanitize_url(@permalink || generate_url)
|
||||
end
|
||||
|
||||
# Internal: 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|
|
||||
@placeholders.inject(@template) { |result, token|
|
||||
result.gsub(/:#{token.first}/, token.last)
|
||||
}
|
||||
end
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
require 'helper'
|
||||
|
||||
class TestURL < Test::Unit::TestCase
|
||||
context "The URL class" do
|
||||
|
||||
should "throw an exception if neither permalink or template is specified" do
|
||||
assert_raises ArgumentError do
|
||||
URL.new(:placeholders => {})
|
||||
end
|
||||
end
|
||||
|
||||
should "replace placeholders in templates" do
|
||||
assert_equal "/foo/bar", URL.new(
|
||||
:template => "/:x/:y",
|
||||
:placeholders => {:x => "foo", :y => "bar"}
|
||||
).to_s
|
||||
end
|
||||
|
||||
should "return permalink if given" do
|
||||
assert_equal "/le/perma/link", URL.new(
|
||||
:template => "/:x/:y",
|
||||
:placeholders => {:x => "foo", :y => "bar"},
|
||||
:permalink => "/le/perma/link"
|
||||
).to_s
|
||||
end
|
||||
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue