Skip to content

Commit

Permalink
Merge pull request #484 from knu/liquid-to_uri
Browse files Browse the repository at this point in the history
 	Add a new Liquid filter `to_uri`.
  • Loading branch information
knu committed Sep 9, 2014
2 parents 2db902a + ca6de90 commit 5101cd5
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 0 deletions.
20 changes: 20 additions & 0 deletions app/concerns/liquid_droppable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ def initialize(object)
@object = object
end

def to_s
@object.to_s
end

def each
(public_instance_methods - Drop.public_instance_methods).each { |name|
yield [name, __send__(name)]
Expand All @@ -23,4 +27,20 @@ def each
def to_liquid
self.class::Drop.new(self)
end

require 'uri'

class URIDrop < Drop
URI::Generic::COMPONENT.each { |attr|
define_method(attr) {
@object.__send__(attr)
}
}
end

class ::URI::Generic
def to_liquid
URIDrop.new(self)
end
end
end
16 changes: 16 additions & 0 deletions app/concerns/liquid_interpolatable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,22 @@ def uri_escape(string)
CGI.escape(string) rescue string
end

# Parse an input into a URI object, optionally resolving it
# against a base URI if given.
#
# A URI object will have the following properties: scheme,
# userinfo, host, port, registry, path, opaque, query, and
# fragment.
def to_uri(uri, base_uri = nil)
if base_uri
URI(base_uri) + uri.to_s
else
URI(uri.to_s)
end
rescue URI::Error
nil
end

# Escape a string for use in XPath expression
def to_xpath(string)
subs = string.to_s.scan(/\G(?:\A\z|[^"]+|[^']+)/).map { |x|
Expand Down
34 changes: 34 additions & 0 deletions spec/concerns/liquid_droppable_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
require 'spec_helper'

describe LiquidDroppable do
before do
class DroppableTest
include LiquidDroppable

def initialize(value)
@value = value
end

attr_reader :value

def to_s
"[value:#{value}]"
end
end

class DroppableTestDrop
def value
@object.value
end
end
end

describe 'test class' do
it 'should be droppable' do
five = DroppableTest.new(5)
five.to_liquid.class.should == DroppableTestDrop
Liquid::Template.parse('{{ x.value | plus:3 }}').render('x' => five).should == '8'
Liquid::Template.parse('{{ x }}').render('x' => five).should == '[value:5]'
end
end
end
37 changes: 37 additions & 0 deletions spec/concerns/liquid_interpolatable_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,41 @@ def @filter.to_xpath_roundtrip(string)
@filter.to_xpath_roundtrip(1).should == '1'
end
end

describe 'to_uri' do
before do
@agent = Agents::InterpolatableAgent.new(name: "test", options: { 'foo' => '{% assign u = s | to_uri %}{{ u.path }}' })
@agent.interpolation_context['s'] = 'http://example.com/dir/1?q=test'
end

it 'should parse an abosule URI' do
@filter.to_uri('http://example.net/index.html', 'http://example.com/dir/1').should == URI('http://example.net/index.html')
end

it 'should parse an abosule URI with a base URI specified' do
@filter.to_uri('http://example.net/index.html', 'http://example.com/dir/1').should == URI('http://example.net/index.html')
end

it 'should parse a relative URI with a base URI specified' do
@filter.to_uri('foo/index.html', 'http://example.com/dir/1').should == URI('http://example.com/dir/foo/index.html')
end

it 'should parse an abosule URI with a base URI specified' do
@filter.to_uri('http://example.net/index.html', 'http://example.com/dir/1').should == URI('http://example.net/index.html')
end

it 'should stringify a non-string operand' do
@filter.to_uri(123, 'http://example.com/dir/1').should == URI('http://example.com/dir/123')
end

it 'should return a URI value in interpolation' do
@agent.interpolated['foo'].should == '/dir/1'
end

it 'should return a URI value resolved against a base URI in interpolation' do
@agent.options['foo'] = '{% assign u = s | to_uri:"http://example.com/dir/1" %}{{ u.path }}'
@agent.interpolation_context['s'] = 'foo/index.html'
@agent.interpolated['foo'].should == '/dir/foo/index.html'
end
end
end

0 comments on commit 5101cd5

Please sign in to comment.