Question

Is it possible to render an Inversion template from a hash? And if not, how does one construct a complex template corresponding to a hash such as:

{ :a => [ { :b => 'foo', :c => 'bar' }, { :d => 'blah', :e => 'blubb'} ] }

Unfortunately the user guide doesn't show such examples.

Was it helpful?

Solution

It depends on how you want to render the hash. Assuming the code:

require 'inversion'

the_hash = { :a => [
    { :b => 'foo', :c => 'bar' },
    { :d => 'blah', :e => 'blubb'}
  ] }

You can render it as-is, of course:

<!-- prettyprint.tmpl -->
<code><?pp the_hash ?></code>

and then:

tmpl = Inversion::Template.load( 'prettyprint.tmpl' )
tmpl.the_hash = the_hash
puts tmpl.render

which will render as:

<!-- prettyprint.tmpl -->
<code>{:a=&gt;[{:b=&gt;"foo", :c=&gt;"bar"}, {:d=&gt;"blah", :e=&gt;"blubb"}]}</code>

Assuming you want to do something more complex with the hash, like render some of its members:

<!-- members.tmpl -->
A's first B is: <?call the_hash[:a].first[:b] ?> 
A's first C is: <?call the_hash[:a].first[:c] ?> 
A's second D is: <?call the_hash[:a][1][:d] ?>   
A's second E is: <?call the_hash[:a][1][:e] ?>   

which (with the same code as the previous example except loading 'members.tmpl' instead) will render like so:

<!-- members.tmpl -->
A's first B is: foo 
A's first C is: bar 
A's second D is: blah   
A's second E is: blubb   

But building a big complex data structure like your hash, and then later merging it with a template is not really how Inversion is intended to be used. The idea is really that loading the template gives you a Ruby object with an API, suitable for passing around and incrementally adding stuff to before rendering it. Instead of building a hash, just pass the template object itself around and call accessors on it, then let it pull out what it needs to build the view:

tmpl.users = User.all
tmpl.company = "ACME Widgets, Pty"
tmpl.render

This also has the advantage of being more amenable to mocking:

# (rspec)
tmpl = mock( "members template" )
tmpl.should_receive( :users ).with( User.all )
tmpl.should_receive( :company ).with( company_name )
tmpl.should_receive( :render ).and_return( "the rendered stuff" )

This removes the template contents from the test entirely, and just focuses on what messages the controller should be sending to the view.

There's a fairly full-featured example in the manual, along with the code that renders it.

The library (and its documentation) are fairly new, so thanks for bringing this up. I have a pending patch to merge the manual with the API docs, which should help, but in the meantime it's probably the best place to find examples.

Hope this helps. I'm happy to answer more in-depth questions personally (ged at FaerieMUD.org), or accept patches via pull request on Github or Bitbucket.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top