'spaceless' equivalent of Django templates in Rails - ruby-on-rails

Notice the readability and balance of:
<li class='aclass anotherclass <%= maybeaconditionalclass %>'>
<a href="<%= some stuff %>">
<%= some other stuff %>
</a>
</li>
which unfortunately produces trailing whitespace inside the link resulting in a ugly trailing underline. Now although less readable I can live with this:
<li class='apossibleclass anotherclass <%= maybeaconditionalclass %>'>
<%= some other stuff %>
</li>
Still, the same problem remains if I now consider this kind of thing:
li.apossibleclass:after {
content: "/";
}
as the whitespace between the closing A and LI gets in the way of what should be sticking to my list item's end. I could only produce that ugly mess as a workaround:
<li class='apossibleclass anotherclass <%= maybeaconditionalclass %>'>
<%= some other stuff %></li>
Django came up with a nice solution: {% spaceless %}, so I'm looking for the equivalent of the {% spaceless %} tag in Rails erb templates.

Yes, that would be an useful feature, and as far as I know, there's nothing like it in Rails. So I've coded it.
# Strip all whitespace between the HTML tags in the passed block, and
# on its start and end.
def spaceless(&block)
contents = capture(&block)
# Note that string returned by +capture+ is implicitly HTML-safe,
# and this mangling does not introduce unsafe changes, so I'm just
# resetting the flag.
contents.strip.gsub(/>\s+</, '><').html_safe
end
This is a helper you can place in your application_helper.rb, and then use like this:
<%= spaceless do %>
<p>
Foo
</p>
<% end %>
... which will result in the output string like
<p> Foo </p>
Sadly, this only works in Rails 3. Rails 2 support for a feature like this will require some dirty hacks to ERb.

Related

How to trim leading whitespace with `<%=` in ERB templates in Rails that end up in `pre` elements?

(As far as I have researched here, this is not a duplicate question. Trimming spaces -- often trailing newlines -- is being discussed for <%- or -%>, but not for <%=. It could be a minor defect in Erubi template engine as well, the one being used by Rails for ERB templates.)
I want to render / syntax-highlight code in a view, and my ERB view template contains:
<p>
<strong>Code:</strong>
<pre class="highlight github">
<%= highlight(#code.code, #code.language) %>
</pre>
</p>
The result is that the HTML output is:
<p>
<strong>Code:</strong>
<pre class="highlight github">
<span class="kt">[and here's the code, but indented too much]</span>
</pre>
</p>
Because of the pre tag, the spaces in front of the first code line are included in the HTML and thus rendered, resulting that the first code line is indented with four spaces too much.
Obviously, I can also make the ERB view template as:
<p>
<strong>Code:</strong>
<pre class="highlight github">
<%= highlight(#code.code, #code.language) %>
</pre>
</p>
but that looks ugly (because the indenting is off) in my template view.
Question: how can I make the <%= also swallow leading spaces? I know that using -%> as closing tag removes trailing spaces/newlines... but I want the leading spaces (not just newlines) to be removed as well.
Try using the concat helper method with an ERB tag that starts with <% instead of <%=:
<p>
<strong>Code:</strong>
<pre class="highlight github">
<% concat(highlight(#code.code, #code.language)) %>
</pre>
</p>

What is the meaning of <%%= in Ruby on Rails?

I cannot find it anywhere but in the project I am working with.
It doesn't work in the same way as <%= (I tried to change), but I can't understand the difference.
<span class="option-content" placeholder="<%=t('pages.edit.option')%>">
<%%= content %>
</span>
The ERB dock here says
<% Ruby code -- inline with output %>
<%= Ruby expression -- replace with result %>
<%# comment -- ignored -- useful in testing %>
% a line of Ruby code -- treated as <% line %> (optional -- see ERB.new)
%% replaced with % if first thing on a line and % processing is used
<%% or %%> -- replace with <% or %> respectively
this means the
<%%= content %>
will will be replaced with
<%= value of content %>
In short, ERb processes double-percent marks into single-percent marks.
It looks like you're using one layer of ERb templates to generate another layer of ERb templates.
The first layer of ERb doesn't need a variable called content, just the t method:
<span class="option-content" placeholder="<%=t('pages.edit.option')%>">
<%%= content %>
</span>
That first layer is rendered to produce the second layer:
<span class="option-content" placeholder="Edit">
<%= content %>
</span>
As you can see, that is also an ERb template. I expect that something else, later on, takes that second ERb and uses it to render something like:
<span class="option-content" placeholder="Edit">
Hello, world.
</span>

Indent entire yield output 2 spaces in Ruby on Rails?

For the sake of good looking code, is there some way to add a tab of spacing across the entire layout <%= yield %> in Ruby on Rails? Here's what I mean:
THIS:
# layout.html.erb
<body>
<%= yield %>
</body>
PLUS THIS:
# page.html.erb
<h1>Test</h1>
<p>Hello, world!</p>
OUTPUTS:
<body>
<h1>Test</h1>
<p>Hello, world!</p>
</body>
WHAT I REALLY WANT TO OUTPUT:
<body>
<h1>Test</h1>
<p>Hello, World!</p>
</body>
I did some research and found that using a minus sign like <%= yield -%> removes indentation, but I couldn't find a way to add it. Any ideas?
What about this?
# layout.html.erb
<body>
<%= yield.gsub(/^/, " ") %>
</body>
Actually, I have a method String#indent in my own library such as:
class String
def indent s = "\t"; gsub(/^/, s) end
end
Using this, you can reuse it in various places.
# layout.html.erb
<body>
<%= yield.indent %>
</body>
Expanding upon Sawa's answer, I just found a slightly more flexible approach to indenting content. Whilst Sawa's method above works just fine, it doesn't push out your yield code enough spaces if you're dealing with multiple block levels before your <%= yield %>.
Here's a slight improvement that can be customized to specific needs:
class String
def indent(spaces)
num = (" " * spaces)
gsub(/^/, num)
end
end
Now you can specify how many spaces of indentation you need right from your layouts like so:
# layout.html.erb
<body>
<div class="content">
<%= yield.indent(4) -%>
</div>
</body>
The above example will apply 4 spaces of indentation to every line of your yield. If there was another level, you would make change it to 6 and so on...

Getting proper indentation using XMLBuilder in a helper

I'm attempting to use a view helper to create some dynamic links based on if you're logged in or not.
What I want returned, for sake of easy code readability, is:
<ul class="right">
<li>Login</li>
<li>Register</li>
</ul>
In the view helper I have this Ruby code:
def loginh
xm = Builder::XmlMarkup.new(:indent=>2, :margin=>4)
xm.ul("class" => "right") {
xm.li('class' => 'text') {
xm.text("test")
}
}
end
In the view, the line that calls login helper is already indented 4 levels. Because of this, the first line gets 'skewed', so in the view I have:
<%= loginh %>
Which results in:
<ul class="right">
<li class="text">
<text>test</text>
</li>
</ul>
You can see it works perfectly, except for the first line.
It would appear that the first line is affected by the indent before <%= loginh %> is called.
I can easily remedy this by removing the indentation prior to <%= loginh %> - but in essence I'd be sacrificing code readability for markup readability. Which isn't what I'm looking to do.
Is there any way I could remove the beginning whitespace?
<%= loginh -%> is almost what you want.
The trick is the minus sign in the closing part, which suppresses extra whitespace.
Alternatively, you could pipe the output through HTMLTidy using backticks (the ` character).

In RoR, is there an easy way to prevent the view from outputting <p> tags?

I'm new to Ruby and Rails and I have a simple controller that shows an item from the database in a default view. When it is displaying in HTML it is outputting <p> tags along with the text content. Is there a way to prevent this from happening? I suppose if there isn't, is there at least a way to set the default css class for the same output in a statement such as this:
<% #Items.each do |i| %>
<%= i.itemname %>
<div class="menu_body">
Link-1
</div>
<% end %>
So the problem is with the <%= i.itemname %> part. Is there a way to stop it from wrapping it in its own <p> tags? Or set the css class for the output?
Thanks!
You need to enclose it with the HTML tag of your choice. Also if required you can escape bad code by using <%=h i.itemname %> Example:
<% #Items.each do |i| %>
<div><%=h i.itemname %></div>
<div class="menu_body">
Link-1
</div>
<% end %>
Edit: Ryan Bigg is right. Rails doesn't output a <p> tag. Sorry for the wrong info.
You canchange the public/stylesheets/scaffold.css if you want.
Or if you want to change it for a single page say items/index.html.erb
<style>
p{
/* your style here *?
}
</style>

Resources