Embedding an ejs template inside of an erb template - ruby-on-rails

I'm building a javascript-heavy rails 3 app. It uses underscore.js, which has a very elegant templating mechanism built on top of ejs ( http://embeddedjs.com/).
The problem: embeddedjs borrows heavily from the erb syntax, so including ejs templates in an erb template causes rendering problems with the view.
Is there a way to include "non-erb" sections in an erb file? This would let me define ejs templates inside erb files. Right now I'm using a hack where I have a helper that reads the raw contents of a file containing ejs templates, and outputting that as a raw string in the erb template.

I use this trick to solve the problem:
// Using custom tags to be able to use regular for templates in templates
var ejs = require('ejs');
ejs.open = '{{';
ejs.close = '}}';
// Using html extension for custom ejs tags
app.register('.html', ejs);
app.set('views', __dirname + '/views');
app.set('view engine', 'html');
This changes <% %> to {{ }}, and let me use <% %> for templates which are used by JS. This works for me as I don't have classic style templates (<% %>).
If you have a lot of those you may want to do the same trick but for underscore.js templates.

You could save ejs as a seperate file and than render it as a text (which won't be evaluated as erb) inside script tag.
Inside your erb partial:
<script id="my_awesome_template" type="text/x-ejs">
<%= render :text => File.open("app/views/controller_name/_my_awesome_template.html.ejs").read %>
</script>`
In your JavaScript file:
new EJS({element: document.getElementById('my_awesome_template')}).render(data)

Escape your Underscore variables: (The ones you do not want erb to interpolate)
<%= foo %> becomes:
<%%= foo %>

Related

How do you use a link_to helper in a YML file that is being sanitized?

I have this key in my locales.yml file that uses a link_to helper.
payment_types:
credit_card: "Requires bank authorization. <%= link_to 'Tutorial', 'www.linktotutorial.com', target: '_blank' %>"
Previously we used an a tag with the href inside along with sanitize, like so:
sanitize(t("payment_types.#{payment_type}"),
tags: %w(a), attributes: %w(target href)), payment_type
But I have to refactor it to use the link_to helper.
The problem is that sanitize is filtering the erb tag alltogether (nothing appears past "Requires bank authorization"), and I can't find a way to allow the erb tag and render the link_to properly.
Getting rid of sanitize in the other hand, renders the string with the erb tags included.
Are erb tags even allowed in yml files?
To parse that ERB tag you can create something like locales.yml.erb
But again there will be too much of hassle to check if Rails is internally parsing ERB yml or not.
And even if it is parsing then will link_to helper will be available or not.
Instead I would suggest a simple way:
# locales.yml
payment_types:
credit_card_html: "Requires bank authorization. %{titorial_link}"
# Usage in views
= t("payment_types.#{payment_type}_html", tutorial_link: link_to('Tutorial', 'www.linktotutorial.com', target: '_blank'))
Please note _html suffix. It is for HTML safe translations.
Read more about HTML safe translations here

Rendering a partial via coffeescript prints literal

I'm trying to render a partial from coffeescript when a button is clicked, so I have one of my coffeescript files "script.js.coffee" with the following code:
$('[id^="btn_add_rep_dia_"]').click ->
id = this.id.substring(16)
$("#dia" + id).append("<%= j render('repeticions/form') %>")
But what's happenning is that at the end of $("#dia" + id) appears litterally the text "<%= j render('repeticions/form') %>". The partial is located in "repeticions" folder and it's called "_form.html.haml"
I have also tested the last code line as:
$("#dia" + id).append("<%= escape_javascript( render partial: 'repeticions/form') %>")
You are trying to execute an erb (embedded ruby) template inside a .coffee file. Rails doesn't know that it should pre-process the file before sending it to the client.
If you are using a Rails version > 3.2, then simply renaming your coffeescript file from script.js.coffee to script.js.coffee.erb should be enough to instruct rails to interpret the erb style template strings (<%...%>).
You can't render a partial from a plain coffeescript file. If you wanted to do this approach, I suggest turning that button into a link_to with remote: true which will enable you to use ajax in rails.

Access asset_host inside javascript for Rails?

I have the following javascript (shortened for clarity):
$modal = $('<img src="/assets/loading.gif">');
$('body').append($modal);
But I am not sure how to access the asset_host within that javascript? Any suggestions? (I am trying to not use coffee script)
There are several options:
asset_path
If you're not accessing the file inside the asset pipeline (and consequently can use ERB code), you could use this:
$img = '<%=j image_tag asset_path("loading.gif)" %>'
$('body').append($img);
Gon
If you are accessing inside the asset pipeline (where you can only use pure JS), you'll have to pass the asset host variable to JS through HTML. Gon is a great way to do this:
#config/initializers/gon.rb
gon.push({asset_host: ActionController::Base.asset_host})
#app/views/layouts/application.html.erb
<%= include_gon %>
#app/assets/javascripts/application.js
$modal = $('<img src="' + gon.asset_host + '/assets/loading.gif">');
$('body').append($modal);
Got the asset_host reference from here

How does one minify a javascript partial within a rails erb file?

The application is not using the standard asset pipeline due to having some of the javascript being rendered dynamically by controller variables.
I'd like to minify the js before appending/inline-ing it into the html file that it would be served out from.
I've tried <render :partial => 'javascript.js'> which is the standard way to render a partial in an erb.
Ideally i'd just be able to do <render :partial => Minify.new.minify('javascript.js')> to render out a minified version of the js
You can try the uglifier gem (http://rubygems.org/gems/uglifier), I don't know about the performance, but you can do something like:
<script type="text/javascript">
<%= raw Uglifier.new.compile(render "your_js_in_a_partial.js") %>
<script>

How to use rails code / pass variables to a .coffee javascript file?

What would be the best way to pass values inside a .coffee script? Renaming the file to .erb breaks my app so what are the alternatives?
checkout this rails guide. this section : 2.3.3 JavaScript/CoffeeScript and ERB
You can use rails code in .coffee-script file. It's built-in feature.
2nd Edit___
If the file is in assets pipeline then you need to add .erb extension at end of coffee file so that the rails tag works otherwise there is no need to add .erb extension if you moves the file in views folder rails tag works there.
You can either (1) move the file into your app/views directory (so it won't be in the asset pipeline), or (2) pass the information via query string.
(1) app/views/users/script.js.coffee.erb
var username = <%= #user.name %>
(2) I'm using this function
<%= link_to "User", user_path(#user, :username => #user.name) %>
...
var username = getParameterByName('username')
Untested but this is the general idea.

Resources