Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursion in Liquid Markup / Liquid Templates

Tags:

ruby

liquid

I've been trying to figure out how I'm gonna do recursion with Liquid. I have an app where I want to give users full control over the rendering of the menu. However, the menu is defined by a tree, thus the need for recursive functions in Liquid.

How would I go about this? After doing some reading, I was thinking I'd tackle it this way:

include

I was thinking of using include this way:

<ul id='site_nav' class='nav'>
  {{ include 'menu_item' with menu_items }}
</ul>

And the menu_item partial is this:

<li id='{{menu_item.dom_id}}' class='{{menu_item.css_menu_class}}'>
  {{ menu_item.name }}
  <ul>
    {{ include 'menu_item' with menu_item.children }}
  </ul>
</li>

However, since it's user editable, I'll need to hack Liquid to make it load partials from a database. Since that will take a lot more time to study, I wanted to ask first if anyone has tackled this problem before.

  • If you have tackled this problem before, how did you render something recursively and allow it to be user editable?
  • If you have not tackled this before, what way would you recommend I take? The way I detailed above?

Thanks in advance!

like image 537
Ramon Tayag Avatar asked May 10 '11 07:05

Ramon Tayag


1 Answers

You don't actually need to 'hack' Liquid to load partials from the DB, simply extend the provided file system classes, read the following for more info:

https://github.com/Shopify/liquid/blob/master/lib/liquid/file_system.rb

I've implemented Liquid this way before myself, and I can vouch for it not being particularly difficult if you know you're way around Ruby.

As for the recursion, Liquid probably won't limit it (your template examples should just work), but I'd wrap your rendering process with a Timeout::timeout (see link below) to ensure it doesn't go on forever.

http://www.ruby-doc.org/stdlib-1.9.3/libdoc/timeout/rdoc/Timeout.html

like image 74
Ryan Townsend Avatar answered Nov 15 '22 07:11

Ryan Townsend