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