1

I'd like to use liquid in my Rails app. I've installed the gem. In order to use in all templates, I've created a library (lib/liquid_view.rb:):

class LiquidView
  def self.call(template)
    "LiquidView.new(self).render(#{template.source.inspect}, local_assigns)"
  end

  def initialize(view)
    @view = view
  end

  def render(template, local_assigns = {})
    @view.controller.headers["Content-Type"] ||= 'text/html; charset=utf-8'

    assigns = @view.assigns

    if @view.content_for?(:layout)
      assigns["content_for_layout"] = @view.content_for(:layout)
    end
    assigns.merge!(local_assigns.stringify_keys)

    controller = @view.controller
    filters = if controller.respond_to?(:liquid_filters, true)
                controller.send(:liquid_filters)
              elsif controller.respond_to?(:master_helper_module)
                [controller.master_helper_module]
              else
                [controller._helpers]
              end

    liquid = Liquid::Template.parse(template)
    liquid.render(assigns, :filters => filters, :registers => {:action_view => @view, :controller => @view.controller})
  end

  def compilable?
    false
  end
end

And added the following initialiser (config/initializers/liquid_template_handler.rb:):

require 'liquid_view'
ActionView::Template.register_template_handler :liquid, LiquidView

PS: I've followed these instructions.

Now, if rename a template file with liquid my_template.html.liquid the <%= stylesheet_link_tag 'mycss' %> stopped working, but more importantly the {{user.first_name}} variable did not print. In my controller I have @user = current_user

What am I missing?

My intention is to completely override erb with liquid in some templates, so ideally it should work like erb (in a sense that I can pass variables from the controller and simply render it in the template without using Liquid::Template.parse(@page.template) which by the way, I don't understand how it works on a file-based template.

PS: I'm also using [this] gem (https://github.com/yoolk/themes_on_rails) for separate templates. I'm not sure it does any impact on it.

PPS: I've seen this but doesn't apply as its a older version of Rails and I'm not using prepend.

PPPS: I'm using Ruby 2.2.2 and Rails 4.2

Community
  • 1
  • 1
WagnerMatosUK
  • 4,309
  • 7
  • 56
  • 95

2 Answers2

1

I hope this not the problem you are thinking it is . You can check the way as it was said here Github Description

Mahabub Islam Prio
  • 1,075
  • 11
  • 25
  • Hi @code.prio. Unfortunately that did not answer my question I'm afraid. – WagnerMatosUK Jun 21 '15 at 19:08
  • as it says ... liquid come with proper init by default. so this won't be a problem . And to use it on full way you have to extract it on /vendor . – Mahabub Islam Prio Jun 21 '15 at 19:10
  • Can you confirm this ? well I can be wrong . But please let me know. I didn't work with Liquid more than 3 - 4 times – Mahabub Islam Prio Jun 21 '15 at 19:12
  • The document is from 2013. Rails scripts has been deprecated in Rails 4. I've installed it as a gem in my gemfile and tried to use it as it is and it didn't work. I think is something to do with `Liquid::Template.parse(@page.template)` but I don't understand how to load the template from a file (like regular erb templates are located in `app/views...` – WagnerMatosUK Jun 21 '15 at 19:32
  • Okay , You have used the Gem Named "liquid" . But now can you read something about this and make a decision : https://github.com/yoolk/liquid-rails – Mahabub Islam Prio Jun 21 '15 at 19:53
  • That's the gem I've used: `gem 'liquid-rails'` – WagnerMatosUK Jun 21 '15 at 19:58
0

Did you create a Drop to access @user?

https://github.com/Shopify/liquid/wiki/Introduction-to-Drops

Liquid is a safe template system, so we can interpret on the backend templates that are created by the user. To access anything non trivial (number, string, hashes or arrays) you need a Drop, which is a controlled interface to define what the templates can access.

This is by design and for security reasons.

Julien Portalier
  • 2,959
  • 1
  • 20
  • 22
  • I still don't understand the principle of it. Does the above article says that I need to create a class for each model I want to use liquid with? Or adding `liquid_attributes << :login << :email` in my model would suffice? – WagnerMatosUK Jun 23 '15 at 15:33
  • You can't access objects from liquid templates unless it's a basic type (Boolean, Numeric, String, Array or Hash). The only exception are Liquid::Drop objects that act as a safe interface between the actual objects and the template. – Julien Portalier Jun 23 '15 at 23:43
  • I updated the link to another wiki page, which may better explain how to define and use drops: they are interface objects that define how and what the template may safely access of the original objects. Each method on the drop must either return a basic type or another drop. – Julien Portalier Jun 23 '15 at 23:51