Including a partial "as is" in Ruby on Rails - ruby-on-rails

I am using stache for server-side evaluation of Mustache templates. I would like to re-use some of these templates on the client-side from JavaScript using ICanHaz.js, but to do so I need to include them into script tags. I would like to avoid duplicating the templates (DRY), but obviously, the templates must not be evaluated before being sent to the client, so using a simple render :partial invocation like in this (HAML) snippet does not work:
%script{:id => 'project_snippet'}
= render :partial => 'project'
Is there any way to include a partial without evaluating it using the underlying template engine (kind of like a raw include)?
In other places the partial is to be used as regular partial, i.e., evaluation is supposed to happen, so changing the file extension to always avoid evaluation is not an option.

do you need a partial as is or you want it to be rendered as HTML with some placeholders for JavaScript templating? you can pass :locals => { ... } with something to be replaced by JS template engine later i.e.
%script{:id => 'project_snippet'}
= render :partial => 'project', :locals => {:name => '{{{ project_name }}}'}
if as is then read the partial content (but it doesn't look like you want this)
%script{:id => 'project_snippet'}
= File.open("#{path/to}/partial.html.haml", "r").read

Well, it seems that I should have read the stache documentation: There is a tag helper available, so
= template_include_tag 'projects/project'
will do the trick after setting the template base directory in an initializer:
Stache.configure do |c|
c.template_base_path = "#{Rails.root}/app/views"
end

Related

Passing locales to javascript partial in haml

I have a partial that contains javascript
#shared/monkey.js
:javascript
//javascript code here
and I want to be able to use partial in that
render :partial => 'shared/monkey', :locals => {:monkey => 'HELLO'}
how do i use the variable monkey inside my partial?
actually, found out a way.
in order to execute ruby code in your :javascript block, you need to do
"#{ruby_code}"

Specify namespace when using "render" with an object in rails 3

So, you can do something like that in rails:
#features.each do |feature|
render feature
end
and it will look for a partial called _feature.html.erb in the views/features folder, based on the class name.
But what if features are in a cms namespace?
Is it possible to specify the namespace? Doing something like this (it doesnt work, obviously)
render [:cms, feature]
Thx
You'll have to be more explicit:
render :partial => '/cms/feature', :object => feature
This will render the 'app/views/cms/_feature.html.erb' partial with the object being 'feature'.

Rendering a Heterogeneous Collection: How can I specify a single directory for the partials?

I have a collection, #comments, that is heterogeneous but hierarchical. Each comment is either an instance of Comment or some derived class, like ActionComment or InactionComment. I am rendering a different partial for each type of Comment. The View code is:
= render #comments
As all the partials are related, I would like to keep them in a single view directory, i.e.:
app/views/comments/_comment.haml
app/views/comments/_action_comment.haml
app/views/comments/_inaction_comment.haml
But right now in order to use the automatic rendering of the correct partial, I am using separate directories, like:
app/views/comments/_comment.haml
app/views/action_comments/_action_comment.haml
app/views/inaction_comments/_inaction_comment.haml
Rails 3.2 makes a Model#to_partial_path method available which allows you (as its name suggests) to override the partial pathname.
def to_partial_path
self.action.to_s
end
The path it returns does not include the leading underscore and is assumed to be relative to .../views/modelname/. See http://blog.plataformatec.com.br/2012/01/my-five-favorite-hidden-features-in-rails-3-2/ for an overview
You can't do it quite as magically, but you can do it by just rendering each item individually and specifying the partial.
example in haml:
- #comments.each do |c|
= render :partial => "comments/#{c.class.to_s.underscore}", :locals => {:comment => c}

ERB in command line with render :partial method in html.erb

I want to render an HTML-EMail and send it to our customers using some ERB Templates.
The basic code I am using:
ERB.new("newsletter.html.erb").result(binding)
doesn't allow me to add partials to the html.erb-File. I would love to move the header and footer to a partial and use the render :partial-Method in that call.
Is this possible? What do I have to add?
This is what I came up with:
viewer = ActionView::Base.new(File.join(Rails::Configuration.new.view_path, "PATH/TO/PARTIALS"))
html = viewer.render(
:file => "PATH/TO/FILE.ERB),
:locals => {:variable => #var}
)
please correct me if there is a more elegant solution than this.

How can you render a template within a layout using Liquid template language?

I'm trying to render a liquid template within a liquid layout (Liquid Template lang, not CSS liquid layout stuff). I can't seem to get the layout part to render. Currently using:
assigns = {'page_name' => 'test'}
#layout = Liquid::Template.parse(File.new(#theme.layout.path).read)
#template = Liquid::Template.parse(File.new(self.template.path).read)
#rend_temp = #template.render(assigns)
#rend_layout = #layout.render({'content_for_layout' => #rend_temp})
render :text => #rend_layout, :content_type => :html
The resulting HTML of the page shows that the 'template' rendered in liquid fine, but it isn't wrapped with the layout (replacing 'content_for_layout' in the layout with the rendered template)
Just to let anyone else know who comes across this problem, the code posted above actually does work, the issue is with the variable named #template. I renamed #template, and #layout to #_tempalte, and #_layout and everything works as expected.
For using liquid in ruby on rails (especially rails 3) - I believe the proper way to render your liquid templates (and also maintain all the work rails is doing for you) is as follows...
The liquid gem itself provides a liquid_view for rails so you can wire up the rails to look for "liquid" templates when you call #render. This liquid_view only works fully with rails 2.3
but can easily be updated to work with rails 3 by making the following update
if content_for_layout = #view.instance_variable_get("#content_for_layout")
assigns['content_for_layout'] = content_for_layout
elsif #view.content_for?(:layout)
assigns["content_for_layout"] = #view.content_for(:layout)
end
assigns.merge!(local_assigns.stringify_keys)
This can be seen here --> https://github.com/danshultz/liquid/commit/e27b5fcd174f4b3916a73b9866e44ac0a012b182
Then to properly render your liquid view just call
render :template => "index", :layout => "my_layout", :locals => { liquid_drop1 => drop, liquid_drop2 => drop }
In our application, since we have a handful of common liquid attributes we have overriden the "render" method in our base controller to automatically include the default locals by referencing #liquid_view_assigns which roll up additionally added liquid drops for the render call
def render(...)
options[:locals] = options.fetch(:locals, {}).merge(liquid_view_assigns)
super
end

Resources