Dynamically Writing in generator template SCSS file - ruby

I'm trying to create my own generator in rails for my standard set up of assets for the pipeline. I've been following Ryan Bates Railscast on the generators
He explains how to add dynamic code the html.erb files but I tried to do something similar in scss file and it simply outputs the tags:
<% if options.add %>
//Some optional code here
#import "add.css.scss";
<% end %>
But instead of executing it when I call create_template it just adds the code into the template. I've tried calling the file .scss.erb but no joy with that either?
Any ideas on how I might tweak the files to make the if statement work?

Try this <%- if options.add -%>

Related

How to pass Ruby variable's value from a Ruby page to a Ruby template

Let's say I have a Ruby files structure like this:
app.rb
/views/index.erb
/views/layout.erb
app.rb is the main app file that contains the routes. Let's say I have one route as this:
get "/" do
erb :index
end
In layout.erb I have my html head and closing </body> and </html> and etc. It is also where I have <head>..</head> and where I can put that scope for some JavaScript methods.
Let's say now that I have my Ruby logic in index.erb. I get a value somehow from my logic (index.erb) and I want to pass that value to my layout.erb. Is it possible? If so, how we do that?
I have checked the #variable_name to pass it as argument from the route definition:
get "/" do
#variable_name = ??? -> this do not works since I did not get the logic yet from index.erb, no?
erb :index
end
I also have tried to use simply <%= variable_name %> or #{variable_name} directly in the layout.erb but without any success.
I actually found out that I was able to transport my "code" to view the widgets I wanted to populated in the index.erb so by that I resolve my problem of accessing the value that was define from a variable declared in index.erb.
Problem solved and a better way to work with Ruby as this issue makes me read more about how to structure myself (Thx to Dave).

How to render Mustache partials in Sinatra while using ERB as the primary tempate engine

I have a sinatra app that is mostly using erb for templates, but I am adding some mustache partials for blocks of html that need to be rendered on both the server and client side. I have a "views" directory where I'm keeping all my templates, including the mustache templates I'm adding. For example, the structure looks something like this:
views/
index.html.erb
_wingding.html.erb
_widget.html.mustache
Let's say I'm rendering index.html.erb using this endpoint:
get '/' do
erb :index
end
And inside that template, I want to render both of the above partials [UPDATE: it turns out this partial method is not built into sinatra, but is included via a gem (see my answer for details), but it still relies on the main sinatra rendering component, so the problem here still stands.]. So index.html.erb contains:
<%= partial :wingding %>
<%= partial :widget %>
The erb partial (wingding) renders fine, but the mustache partial (widget) does not. It causes the application to throw an exception:
Template engine not found: mustache
I have included the 'mustache' gem in the project. I tried 'require mustache/sinatra' and register Mustache::Sinatra. Both of these statements worked, but didn't solve the problem above. Any idea how to tell sinatra about mustache so that it can render mustache partials?
I'm setting my views directory by including this configuration:
configure do
set :views, File.join(File.dirname(__FILE__), 'views')
end
Version numbers:
sinatra 1.3.1
mustache 0.99.4
ruby 1.9.3
So it turns out the gem listed in the solution in my other answer caches output, meaning you can't use it to include the same partial with different locals in the same request, which makes it worthless for my purposes. So here's another (admittedly hackish) solution that I've settled on. I created a helper that will just deliver the contents of a given view:
helpers do
def template_contents(path)
File.open("#{settings.views}/#{path}") { |f| f.read }
end
end
Then, I just do a regular Mustache#render:
<%= Mustache.render(template_contents('_widget.html.mustache'), { ... }) %>
This works great for my use case.
I figured this out. First, I must note something I didn't realize when I posted the question. partial is not actually built into sinatra. It is being included in my app as part of the sinatra-more gem (discontinued, most of it's functionality is now in a project called padrino, but still using sinatra-more in this app). The partial method is included like this:
require 'sinatra_more/render_plugin'
module Sinatra
register SinatraMore::RenderPlugin
end
Anyway, that just adds the partial method (along with some other rendering helpers) but this method falls back on the built-in sinatra rendering code, so this fact is independent of the actual issue at hand in this question -- that sinatra does not by default recognize the mustache template engine. Turns out someone created a super simple gem to make it work, sinatra-mustache. You simply include the gem and require the library:
require 'sinatra/mustache'
That's it -- it just works! No additional configuration necessary. If you're curious how it works, the source code is pretty simple. It's by no means a one-liner to register a new template engine with sinatra (even saying "register" is a misnomer -- you basically have to implement it), but it's still fairly simple.
UPDATE: This gem caches the output for a given request/template, so you can't use it a second time with different locals. I could see cases where that's okay, but that makes it worthless for my use case.

heroku re-orders ruby on rails loop output of partials

I have a page which renders several partials; on my local mac everything is fine but after I push to heroku and visit the page the order of the partials is different!
I render partials with the code below and thought I controlled the order with a file naming convention.
html.erb:
<% Dir["app/views/partials/ws/*.html.erb"].each do |ws| %>
<%= render 'partials/ws/' + File.basename(ws,'.html.erb').slice(1..-1) %>
<% end %>
The partials use a naming convention:
_ws_01-why.html.erb
_ws_02-what.html.erb
_ws_03-who.html.erb
_ws_04-where.html.erb
_ws_05-when1.html.erb
_ws_06-how.html.erb
Heroku renders in this order:
_ws_01-why.html.erb
_ws_02-what.html.erb
_ws_06-how.html.erb
_ws_04-where.html.erb
_ws_05-when1.html.erb
_ws_03-who.html.erb
I'm not sure how heroku is interpreting the naming convention / ruby loop order... Wondering if there is a better naming convection or logic to add in my loop to control the order?
Thanks!
Change this:
<% Dir["app/views/partials/ws/*.html.erb"].each do |ws| %>
to this:
<% Dir["app/views/partials/ws/*.html.erb"].sort.each do |ws| %>
You cannot be sure than an enumerator will choose the same order in all cases unless you force it somehow.

erb template and new line/spacing problems

I have a erb template that I am using to generate source code, but the problem is I want the erb template to look readable, but at the same time I want the generated output to look good also.
So I have this snippet:
<% model.attributes.each do |attribute| %>
private <%= model.get_instance(attribute) %> <%= ... %>;<% end%>
So my code output isn't coming out as I would like, I want it like:
private type name;
private type name2;
private type name3;
But it is coming out with an extra space between each line.
How can I fix this?
The other challenge like I mentioned is that I don't want my erb to look unreadable (if possible).
I had had the same issues.. trying to get the output source code well formated without compromising the readability of the template was a nightmare. I've opted for using a code formatter chained in the code generation process and just concentrate in my template file. Good luck

Ruby: How to use generate HTML with dynamic values?

I am writing a Ruby script that will generate a large flat HTML menu for my website, I could generate this menu on the fly each time a page loads, but I think doing so is a waste of resources, especially as this will almost never need to change.
I want to effectively do the following (in semi-sudocode):
part_of_my_menu = eval %{
<script type="text/javascript">
var mapper = new Array();
<% parent_categories.each_with_index do |parent_category,i| -%>
mapper["#{parent_category.name}"] = <%= i -%>;
<% end -%>
</script>
}
and then be able to write the part_of_my_menu string variable to a HTML file (this I can do).
I know this is not how eval works in Ruby but does anyone know how to achieve this same "wrapper" functionality?
(fyi - the code I want to wrap with my "eval" function is much longer than this, I've only posted a very small snippet to illustrate what I am trying to achieve)
Thanks!
ERB is part of the standard library so you could do things like this:
tmpl = %q{<script type="text/javascript">...</script>}
erb = ERB.new(tmpl)
parent_categories = [ ... ]
part_of_my_menu = erb.result
The ERB documentation contains some good examples of how to use it.
You don't need a hand rolled eval construction, you can use standard existing libraries and your existing knowledge.
You might be interested in the dom gem that I have developed. You can generate HTML strings like this:
require "dom"
["foo".dom(:span, class: "bold"), "bar"].dom(:div).dom(:body).dom(:html)
# => "<html><body><div><span class=\"bold\">foo</span>bar</div></body></html>"

Resources