mirror of
https://github.com/Shopify/liquid.git
synced 2026-09-17 18:00:41 -07:00
Destroyed Using Liquid without Rails (textile)
@@ -1,115 +0,0 @@
|
||||
Want to use Liquid along with some plain old Ruby code?
|
||||
First, of course, you need to tell Ruby about the Liquid library.
|
||||
Assuming that you're in the @liquid@ directory, as cloned from GitHub,
|
||||
just @require 'lib/liquid'@.
|
||||
|
||||
The big secret, however, is creating a @to_liquid@ method for any classes you want Liquid to access.
|
||||
|
||||
Let's say you have a Product class:
|
||||
|
||||
<pre>
|
||||
class Product
|
||||
attr_accessor :name, :price
|
||||
|
||||
def initialize(name,price)
|
||||
@name = name
|
||||
@price = price
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
|
||||
And you have a chunk of text that you want to Liquidize by inserting some details about your products:
|
||||
|
||||
<pre>
|
||||
sentence = "I'm running to the store with {{ product.price }} dollars in my pocket "
|
||||
sentence += "to buy a {{ product.name }}."
|
||||
</pre>
|
||||
|
||||
And you create a product and parse the sentence:
|
||||
|
||||
<pre>
|
||||
my_purchase = Product.new('box of sausages', 20)
|
||||
puts Liquid::Template.parse(sentence).render('product' => my_purchase)
|
||||
</pre>
|
||||
|
||||
You excitedly execute your code, expecting to see your beautiful new sentence, but instead you get:
|
||||
|
||||
<pre>
|
||||
I'm running to the store with Liquid error:
|
||||
undefined method `to_liquid' for #<Product:0x1388c08 ...
|
||||
</pre>
|
||||
|
||||
@to_liquid@ ???
|
||||
Where did that come from?
|
||||
Turns out you need to add a method to your class that returns your instance variables as part of a hash.
|
||||
(Liquid was built to be very paranoid about not letting people access something they're not supposed to,
|
||||
so you need to explicitly let Liquid know how to access everything in your object.)
|
||||
So, we update the @Product@ class description to include that method:
|
||||
|
||||
<pre>
|
||||
class Product
|
||||
attr_accessor :name, :price
|
||||
|
||||
def initialize(name, price)
|
||||
@name = name
|
||||
@price = price
|
||||
end
|
||||
|
||||
def to_liquid
|
||||
{ "name" => self.name,
|
||||
"price" => self.price }
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
|
||||
Run that again and presto:
|
||||
|
||||
<pre>
|
||||
I'm running to the store with 20 dollars in my pocket to buy a box of sausages.
|
||||
</pre>
|
||||
|
||||
However, that's a bit verbose, so you may want to use @liquid_methods@, instead:
|
||||
|
||||
<pre>
|
||||
class Product
|
||||
attr_accessor :name, :price
|
||||
liquid_methods :name, :price
|
||||
|
||||
def initialize(name, price)
|
||||
@name = name
|
||||
@price = price
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
|
||||
(Thanks to "Tom's":http://github.com/mojombo "Jekyll":http://github.com/mojombo/jekyll/tree/master/lib/jekyll/post.rb#L122-128 code for helping me figuring this out.)
|
||||
|
||||
h2. A bit more detail
|
||||
|
||||
Every variable rendered by liquid must either:
|
||||
* implement a @to_liquid@ method; or
|
||||
* be a Proc. This is called with the @Liquid::Context@ as a parameter and must return an object which responds to @to_liquid@
|
||||
|
||||
Liquid defines @to_liquid@ for the following standard classes: String, Array, Hash, Numeric, Time, DateTime, Date, TrueClass, FalseClass, NilClass. For each of these, @to_liquid@ just returns the object itself. <em>(See: lib/liquid/extensions.rb)</em>
|
||||
|
||||
If the value returned by @to_liquid@ is inserted into the output, it will be further converted with @to_s@ <em>(actually this is done implicitly by Array#join - see lib/liquid/template.rb)</em>
|
||||
|
||||
When used in a chained expression like @foo.bar@ or @foo['bar']@, the result of @to_liquid@ on the left-hand subexpression must either:
|
||||
* respond to @has_key?@ and @[]@ (i.e. duck-type like a Hash); or
|
||||
* respond to @fetch@ and @[]@ with an Integer argument (i.e. duck-type like an Array); or
|
||||
* respond to @size@ or @first@ or @last@
|
||||
|
||||
In each case, the object returned after applying the right-hand subexpression must also respond to @to_liquid@ or be a Proc which returns an object that responds to @to_liquid@. In the latter case, it will only be called if the previous element in the chain also responds to @[]=@ - that is, if the value can be cached in the parent object.
|
||||
|
||||
<em>(See: lib/liquid/context.rb)</em>
|
||||
|
||||
<pre>
|
||||
>> assigns = {"foo"=>{"bar"=>{"baz"=>lambda { |x| Time.now } }}}
|
||||
=> {"foo"=>{"bar"=>{"baz"=>#<Proc:0xb7cd9af8@(irb):11>}}}
|
||||
>> t = Liquid::Template.parse("{{ foo.bar.baz }}")
|
||||
=> #<Liquid::Template:0xb7d2e738 ... >
|
||||
>> t.render(assigns)
|
||||
=> "Fri Jun 05 11:23:56 +0100 2009"
|
||||
>> assigns
|
||||
=> {"foo"=>{"bar"=>{"baz"=>Fri Jun 05 11:23:56 +0100 2009}}}
|
||||
</pre>
|
||||
Reference in New Issue
Block a user