Giter Club home page Giter Club logo

dynamic_liquid_templates's Introduction

Dynamic Liquid Templates

Use Case

The Rails View system is very complex and complete, 90% of the time you don’t need much else but the occasional Haml support.

But if you want to have your users have the feature of editing their own set of view templates, then the default filesystem-based view system will not be enough. That’s why I wanted to have a way to retrieve templates from the database instead.

By having your templates being user-editable, it’s also not acceptable to use ERB or Haml,because they are too powerful and they expose just too much in the views. You want an engine that exposes just enough so the users can create their own templates without having the risk of they running something nasty such as system(‘rm -Rf /’)

That’s why I chose Tobias Lütke’s excellent Liquid engine that he created for Shopify.com for exactly the same reason. I have no idea how he manages the user templates but in my case I created this plugin to fulfill this requirement.

Usage

Just install it as a plugin into your Rails project and create the needed migration:


./script/plugin install git://github.com/akitaonrails/dynamic_liquid_templates.git
./script/generate dynamic_templates
rake db:migrate

The requirement is to install Tobias’ Liquid gem:


gem install tobi-liquid --source=http://gems.github.com

You also have to require this gem from your config/environment.rb file:


config.gem "tobi-liquid", :lib => "liquid", :source => "http://gems.github.com"

Now, from within the controller that you want to be user-accessible, edit the ‘format.html’ block with the new render method:


...
respond_to do |format|
  format.html { render_with_dynamic_liquid }
end
...

If you created the default migration file, you now have a dynamic_templates table to hold your Liquid templates. Don’t forget to register new entries to the dynamic_templates table. See the spec/fixtures folder for examples on how to write simple Liquid templates. You will register entries such as:


DynamicTemplate.create(:path => "posts/show", :body => "<h2>{{ post.title }}</h2>\n<p>{{ post.body }}</p>")

Every normal controller instance variables such as @post or @comments will be available as ‘post’ or ‘comments’ from inside the Liquid template. Your usual Rails helpers are also available as Liquid filters. In ERB and HAML you usually have access to everything, but Liquid restricts your access (that’s the whole idea) and you have to explicitly assign extra objects to the render method, for instance:


...
@foo = Foo.find_by_name("Bar")
render_with_dynamic_liquid('foo' => @foo)

This will make ‘foo’ available from the Liquid Template. Read the library source code for more details, but it’s enough to understand that this render method will follow Rails’ convention over configuration principals so, for instance, if you’re inside the index action of a PostsController, you’re expected to have a collection named ‘@posts’ and named routes such as posts_path and so on, and so forth.

If you’re inside a nested controller (such as ‘Comment belongs_to Post’), declare a method named ‘parent’, for example:


class CommentsController < ApplicationController
  ...
  def parent
    @post ||= Post.find(params[:post_id])
  end
end

The plugin will use this method to refer to the proper named routes, such as post_comments_path(parent) or post_comment_path(parent, @comment) and so on. Namespaces will work too, for example:


class Admin::PostsController < ApplicationController
  def index
     @posts = Post.all
     respond_to do |format|
       format.html { render_with_dynamic_liquid(:namespace => 'admin') } 
     end
	end
end

There’s probably a better syntax for that, but it works like that too. The other thing is that your models need to be ‘liquified’ in order to be usable from inside a Liquid template. You have to declare a to_liquid method explicitly saying which columns you want exposed:


class Post < ActiveRecord::Base
  ...
  def to_liquid
    { 'title' => self.title, 'body' => self.body }
  end
end

Notice that the hash keys have to be strings, and not symbols. The other thing is that the plugin will append other attributes to this hash automagically, so you can do the following from within your Liquid templates:

{{ 'Show' | link_to: post.show_path }}

It adds ‘show_path’ and ‘edit_path’ to your model instances, so you can use them to create links or form actions. There are other globally assigned variables as well, such as:

  • collection – refers to the controller collection (for index action) such as @posts
  • object – referes to the controller single object (for non-index actions) such as @post
  • collection_path – the named route for the index action, including nested and namespaced versions
  • object_path – the named route for the non-index action, including nested and namespaced versions
  • parent – if you have the ‘parent’ method in your controller, it’s exposed within Liquid
  • parent_path – if you have the ‘parent’ method in your controller, it’s used for named routes

And, of course, your models are properly assigned to Liquid too so, for example, ‘@posts’ is exposed as ‘posts’ to Liquid.

To do

Credits

Fabio Akita ([email protected]) – http://www.akitaonrails.com

dynamic_liquid_templates's People

Contributors

akitaonrails avatar caueguerra avatar okiess avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.