diff --git a/lib/jekyll/filters.rb b/lib/jekyll/filters.rb index d8915b3a..29f2a2b5 100644 --- a/lib/jekyll/filters.rb +++ b/lib/jekyll/filters.rb @@ -3,8 +3,11 @@ require "json" require "date" require "liquid" +require_all "jekyll/filters" + module Jekyll module Filters + include URLFilters # Convert a Markdown string into HTML output. # # input - The Markdown String to convert. diff --git a/lib/jekyll/filters/url_filters.rb b/lib/jekyll/filters/url_filters.rb new file mode 100644 index 00000000..e907c91b --- /dev/null +++ b/lib/jekyll/filters/url_filters.rb @@ -0,0 +1,45 @@ +module Jekyll + module Filters + module URLFilters + # Produces an absolute URL based on site.url and site.baseurl. + # + # input - the URL to make absolute. + # + # Returns the absolute URL as a String. + def absolute_url(input) + return if input.nil? + site = @context.registers[:site] + return relative_url(input).to_s if site.config["url"].nil? + URI(site.config["url"] + relative_url(input)).to_s + end + + # Produces a URL relative to the domain root based on site.baseurl. + # + # input - the URL to make relative to the domain root + # + # Returns a URL relative to the domain root as a String. + def relative_url(input) + return if input.nil? + site = @context.registers[:site] + return ensure_leading_slash(input.to_s) if site.config["baseurl"].nil? + ensure_leading_slash( # in case the baseurl doesn't have a leading slash + URI( + site.config["baseurl"] + ensure_leading_slash(input.to_s) + # in case the input doesn't have a leading slash + ).to_s + ) + end + + private + def ensure_leading_slash(input) + return input if input.nil? || input.empty? + if input.start_with?("/") + input + else + "/#{input}" + end + end + + end + end +end diff --git a/test/helper.rb b/test/helper.rb index 9505c762..8fc43d67 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -120,12 +120,9 @@ class JekyllUnitTest < Minitest::Test "destination" => dest_dir, "incremental" => false })) - build_configs({ + Configuration.from(full_overrides.merge({ "source" => source_dir - }, full_overrides) - .fix_common_issues - .backwards_compatibilize - .add_default_collections + })) end def clear_dest diff --git a/test/test_filters.rb b/test/test_filters.rb index d6ff9eac..d027cbb4 100644 --- a/test/test_filters.rb +++ b/test/test_filters.rb @@ -8,23 +8,28 @@ class TestFilters < JekyllUnitTest attr_accessor :site, :context def initialize(opts = {}) - @site = Jekyll::Site.new( - Jekyll.configuration(opts.merge("skip_config_files" => true)) - ) + @site = Jekyll::Site.new(opts.merge("skip_config_files" => true)) @context = Liquid::Context.new({}, {}, { :site => @site }) end end + def make_filter_mock(opts = {}) + JekyllFilter.new(site_configuration(opts)).tap do |f| + tz = f.site.config["timezone"] + Jekyll.set_timezone(tz) if tz + end + end + class SelectDummy def select; end end context "filters" do setup do - @filter = JekyllFilter.new({ - "source" => source_dir, - "destination" => dest_dir, - "timezone" => "UTC" + @filter = make_filter_mock({ + "timezone" => "UTC", + "url" => "http://example.com", + "baseurl" => "/base" }) @sample_time = Time.utc(2013, 3, 27, 11, 22, 33) @sample_date = Date.parse("2013-03-27") @@ -65,7 +70,7 @@ class TestFilters < JekyllUnitTest end should "escapes special characters when configured to do so" do - kramdown = JekyllFilter.new({ :kramdown => { :entity_output => :symbolic } }) + kramdown = make_filter_mock({ :kramdown => { :entity_output => :symbolic } }) assert_equal( "“This filter’s test…”", kramdown.smartify(%q{"This filter's test..."}) @@ -307,6 +312,99 @@ class TestFilters < JekyllUnitTest assert_equal "my%20things", @filter.uri_escape("my things") end + context "absolute_url filter" do + should "produce an absolute URL from a page URL" do + page_url = "/about/my_favorite_page/" + assert_equal "http://example.com/base#{page_url}", @filter.absolute_url(page_url) + end + + should "ensure the leading slash" do + page_url = "about/my_favorite_page/" + assert_equal "http://example.com/base/#{page_url}", @filter.absolute_url(page_url) + end + + should "ensure the leading slash for the baseurl" do + page_url = "about/my_favorite_page/" + filter = make_filter_mock({ + "url" => "http://example.com", + "baseurl" => "base" + }) + assert_equal "http://example.com/base/#{page_url}", filter.absolute_url(page_url) + end + + should "be ok with a blank but present 'url'" do + page_url = "about/my_favorite_page/" + filter = make_filter_mock({ + "url" => "", + "baseurl" => "base" + }) + assert_equal "/base/#{page_url}", filter.absolute_url(page_url) + end + + should "be ok with a nil 'url'" do + page_url = "about/my_favorite_page/" + filter = make_filter_mock({ + "url" => nil, + "baseurl" => "base" + }) + assert_equal "/base/#{page_url}", filter.absolute_url(page_url) + end + + should "be ok with a nil 'baseurl'" do + page_url = "about/my_favorite_page/" + filter = make_filter_mock({ + "url" => "http://example.com", + "baseurl" => nil + }) + assert_equal "http://example.com/#{page_url}", filter.absolute_url(page_url) + end + + should "not prepend a forward slash if input is empty" do + page_url = "" + filter = make_filter_mock({ + "url" => "http://example.com", + "baseurl" => "/base" + }) + assert_equal "http://example.com/base", filter.absolute_url(page_url) + end + end + + context "relative_url filter" do + should "produce a relative URL from a page URL" do + page_url = "/about/my_favorite_page/" + assert_equal "/base#{page_url}", @filter.relative_url(page_url) + end + + should "ensure the leading slash between baseurl and input" do + page_url = "about/my_favorite_page/" + assert_equal "/base/#{page_url}", @filter.relative_url(page_url) + end + + should "ensure the leading slash for the baseurl" do + page_url = "about/my_favorite_page/" + filter = make_filter_mock({ "baseurl" => "base" }) + assert_equal "/base/#{page_url}", filter.relative_url(page_url) + end + + should "be ok with a nil 'baseurl'" do + page_url = "about/my_favorite_page/" + filter = make_filter_mock({ + "url" => "http://example.com", + "baseurl" => nil + }) + assert_equal "/#{page_url}", filter.relative_url(page_url) + end + + should "not prepend a forward slash if input is empty" do + page_url = "" + filter = make_filter_mock({ + "url" => "http://example.com", + "baseurl" => "/base" + }) + assert_equal "/base", filter.relative_url(page_url) + end + end + context "jsonify filter" do should "convert hash to json" do assert_equal "{\"age\":18}", @filter.jsonify({ :age => 18 })