Forum: Ruby on Rails liquid: passing objects

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Steve K. (Guest)
on 2006-05-16 22:16
I've got Liquid installed and maybe since I'm not coming in with Django
experience, I'm completely mystified by how to pass anything worthwhile
to a template.

In my controller:

    def preview
      @customer = Customer.find(1)
      @letter = Letter.find(1)
      @liquid_body = Liquid::Template.parse(@letter.body)
      @x = @liquid_body.render('fname' => @customer.fname, 'customer' =>
@customer)
      @draft = render_to_string(:inline => @x)
    end

In the view:

    <%= draft -%>

In my template stored in the DB:

    Name: {{ fname }}<br/>
    Weclome {{ customer.fname }}.

The result:

{{ fname }} returns the value. {{ customer.fname }} comes up empty.

I've tried a few variations -- local vs. instance variables, mostly.
Surely I don't have to manually assign an explicit hash every time I
want to pass the attributes of an AR record object to Liquid?

Obviously I'm doing something fundamentally wrong. Unfortunately, the
Liquid docs and Wiki only document what goes in the template when
dealing with an object or set of objects, not what goes in the
controller. The examples are full of constructs like {{
product.description }} and {% for product in products %} but not a word
about how @products or products are passed in.

Can someone help out with a snippet that demonstrates how to get an
object complete with attributes into Liquid?
kris (Guest)
on 2006-05-16 22:35
I know you have to write a liquid 'helper' (helper may be th wrong term)
to be able to pass ActiveRecord classes to a liquid template. There is
an example in an app that uses liquid - dont remember its name.
I know this post aint to helpful but what you are asking is possible it
just requires some extra work...

If you get the solution please post back to the forum and/or liquid docs
(if you can)...

Steve K. wrote:
> I've got Liquid installed and maybe since I'm not coming in with Django
> experience, I'm completely mystified by how to pass anything worthwhile
> to a template.
>
> In my controller:
>
>     def preview
>       @customer = Customer.find(1)
>       @letter = Letter.find(1)
>       @liquid_body = Liquid::Template.parse(@letter.body)
>       @x = @liquid_body.render('fname' => @customer.fname, 'customer' =>
> @customer)
>       @draft = render_to_string(:inline => @x)
>     end
>
> In the view:
>
>     <%= draft -%>
>
> In my template stored in the DB:
>
>     Name: {{ fname }}<br/>
>     Weclome {{ customer.fname }}.
>
> The result:
>
> {{ fname }} returns the value. {{ customer.fname }} comes up empty.
>
> I've tried a few variations -- local vs. instance variables, mostly.
> Surely I don't have to manually assign an explicit hash every time I
> want to pass the attributes of an AR record object to Liquid?
>
> Obviously I'm doing something fundamentally wrong. Unfortunately, the
> Liquid docs and Wiki only document what goes in the template when
> dealing with an object or set of objects, not what goes in the
> controller. The examples are full of constructs like {{
> product.description }} and {% for product in products %} but not a word
> about how @products or products are passed in.
>
> Can someone help out with a snippet that demonstrates how to get an
> object complete with attributes into Liquid?
Steve K. (Guest)
on 2006-05-17 00:25
I contacted Tobias directly and got this:

"Liquid in its default form takes strings, numerics, arrays and hashes.
A nice trick is to export @product.attributes which is a hash on every
AR object with the values. Exporting an array can be done like this:
@products = products.collect { |p| p.attributes }"

So in order to pass a single @customer object in my example using a
liquid template in the DB, you can say:

  @customer = Customer.find(1)
  @letter = Letter.find(1)
  foo = Liquid::Template.parse(@letter.body)
  foo.render('customer' =>  @customer.attributes)

and to pass a list of all customers to be iterated through in the
template, it would be something like

  @customer = Customer.find(:all)
  @letter = Letter.find(1)
  foo = Liquid::Template.parse(@letter.body)
  foo.render('customers' =>  @customers.collect { |c| c.attributes })

Thanks, Tobias!


kris wrote:
> <snip>
>
> If you get the solution please post back to the forum and/or liquid docs
> (if you can)...
>
> Steve K. wrote:
>> I've got Liquid installed and maybe since I'm not coming in with Django
>> experience, I'm completely mystified by how to pass anything worthwhile
>> to a template.
>>
>> In my controller:
>>
>>     def preview
>>       @customer = Customer.find(1)
>>       @letter = Letter.find(1)
>>       @liquid_body = Liquid::Template.parse(@letter.body)
>>       @x = @liquid_body.render('fname' => @customer.fname, 'customer' =>
>> @customer)
>>       @draft = render_to_string(:inline => @x)
>>     end
>>
>> In the view:
>>
>>     <%= draft -%>
>>
>> In my template stored in the DB:
>>
>>     Name: {{ fname }}<br/>
>>     Weclome {{ customer.fname }}.
>>
>> The result:
>>
>> {{ fname }} returns the value. {{ customer.fname }} comes up empty.
>>
>> I've tried a few variations -- local vs. instance variables, mostly.
>> Surely I don't have to manually assign an explicit hash every time I
>> want to pass the attributes of an AR record object to Liquid?
>>
>> Obviously I'm doing something fundamentally wrong. Unfortunately, the
>> Liquid docs and Wiki only document what goes in the template when
>> dealing with an object or set of objects, not what goes in the
>> controller. The examples are full of constructs like {{
>> product.description }} and {% for product in products %} but not a word
>> about how @products or products are passed in.
>>
>> Can someone help out with a snippet that demonstrates how to get an
>> object complete with attributes into Liquid?
This topic is locked and can not be replied to.