Browse files

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
  • Loading branch information...
1 parent 1319b82 commit cfcbe1f83011f1ee0887cf8e420827b1c95afd07 @x3ro committed Apr 9, 2013
Showing with 77 additions and 52 deletions.
  1. +1 −0 lib/jekyll.rb
  2. +8 −22 lib/jekyll/page.rb
  3. +15 −30 lib/jekyll/post.rb
  4. +53 −0 lib/jekyll/url.rb
View
1 lib/jekyll.rb
@@ -30,6 +30,7 @@ def require_all(path)
require 'jekyll/core_ext'
require 'jekyll/site'
require 'jekyll/convertible'
+require 'jekyll/url'
require 'jekyll/layout'
require 'jekyll/page'
require 'jekyll/post'
View
30 lib/jekyll/page.rb
@@ -1,6 +1,7 @@
module Jekyll
class Page
include Convertible
+ include URL
attr_writer :dir
attr_accessor :site, :pager
@@ -69,28 +70,13 @@ def template
end
end
- # The generated relative url of this page. e.g. /about.html.
- #
- # Returns the String url.
- def url
- return @url if @url
-
- 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
+ # See url.rb for an explanation
+ def url_placeholders
+ {
+ "path" => @dir,
+ "basename" => self.basename,
+ "output_ext" => self.output_ext
+ }
end
# Extract information from the page filename.
View
45 lib/jekyll/post.rb
@@ -2,6 +2,7 @@ module Jekyll
class Post
include Comparable
include Convertible
+ include URL
class << self
attr_accessor :lsi
@@ -153,36 +154,20 @@ def template
end
end
- # The generated relative url of this post.
- # e.g. /2008/11/05/my-awesome-post.html
- #
- # Returns the String URL.
- def url
- return @url if @url
-
- url = if permalink
- permalink
- else
- {
- "year" => date.strftime("%Y"),
- "month" => date.strftime("%m"),
- "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
+ # See url.rb for an explanation
+ def url_placeholders
+ {
+ "year" => date.strftime("%Y"),
+ "month" => date.strftime("%m"),
+ "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
+ }
end
# The UID for this post (useful in feeds).
View
53 lib/jekyll/url.rb
@@ -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

0 comments on commit cfcbe1f

Please sign in to comment.