Multiple Haml Elements on Same Line - haml

I want to be able to have two Haml elements on the same line. For example:
%h1 %a{:href => '/'} Professio.
That doesn't work. How would I get something like this to work without borking?

Late answer, but I was just tackling the same problem myself and knew HAML had a way to do this as part of the language. See the White Space Removal section of the HAML reference.
You could do it this way:
%h1<
%a{ :href => '/' } Professio.
Or this way:
%h1
%a{ :href => '/' }> Professio.

Unfortunately, you cannot put two haml elements on the same line.
You can achieve something similar by using inline html elements:
%h1 <a href='/'>Lorem ipsum</a>
Why don't you like this format?
%h1
%a{:href => '/'} Professio.
Another option is to write special 'helper' method (that generate an html link). For example, the link_to in Rails:
%h1= link_to 'Professio', root_url

Haml cannot do this. Slim can:
h1: a( href='/' ) Professio.
is the same as:
h1
a( href="/ ) Professio
You can write as deeper tree as you need:
ul.nav
li.active: a( href="/home" ): strong Home
li: a( href="/contact" ): span Contact
Jade also has similar syntax and support this feature, but it's been designed for Node.js environment.

If you're looking to preserve the HTML on the same line you could try something like this:
irb> print Haml::Engine.new("%h1<\n %a{:href => '/'} Profession.").render()
<h1><b href='/'>Profession.</a></h1>
Found here: HAML whitespace removal
[Edit: I know that's says b href above...]

Related

Adding placeholder text to chosen chosen-jquery

I am using the chosen-rails gem with great success. However, I want to customise the placeholder text. From the gem documentation it looks like the following should be in the coffee script file
$('.chzn-select').chosen
allow_single_deselect: true
no_results_text: 'No results matched'
When I use this code I can alter the deslectbehaviour, so the script is being called, but the placeholder text does not change
has anyone experienced similar behaviour?
You can just set your data-placeholder attribute and Chosen will parse it automatically:
:data => {:placeholder => 'User Name'}
I found a better solution to this.
Following this https://github.com/harvesthq/chosen/issues/176, one can use .attr("data-placeholder", "my message here...").chosen(); instead of .data().
The right solution here is to place an empty option element on top.
To set a default text in the coffeescript file use:
$('.chzn-select').chosen
allow_single_deselect: true
no_results_text: 'No results matched',
placeholder_text_single: 'Please select an option',
placeholder_text_multiple: 'Please select some options'
Works for me with chosen-rails 1.5.2
Documentation says in the "Default Text Support" section that you should use data-placeholder attribute on the select element. I haven't tested it yet and I'm also curious how to do it from script not from the markup.
EDIT:
I've just found a solution: -- simple overriding data attribute from a script (pretty obvious :)).
Rails 5 - 2018
This code works with the simple_form gem:
<%= f.input :tag, as: :select, collection: Tag.all, input_html: {class: 'chosen-select', :data => {:placeholder => "your custom placeholder"}, multiple: true} %>

Element class in Haml

I am using Haml in a Ruby on Rails project. I know you use the = sign to execute Ruby, but so far what I have seen is that the Ruby code has to be the last part of a line.
I am trying to add a class to a th element dynamically. (In case it's relevant: each td also contains more Ruby.)
I have the following code:
%th= link_to 'Name', res_path
I want to add a class to th, and the name of this class is in an instance variable called class_name. I tried this:
%th.=#class_name
But it doesn't work.
How should one include Ruby code twice on the same line using Haml?
The html_options solution offered by Alok will add the class to the 'a' tag. I would do this over two lines instead of one:
%th{ :class => #class_name }
= link_to 'Name', res_path
As #DavB pointed out, only static text can be used with the ./# notation. Otherwise, you can either pass your options to your helper method (if it accepts them), or, more universally, use a hash attribute as in %th{:class => #name}. It will result in <th class="namevalue">.
You could use the html_options of the link_to tag and then add the class there. I think thats the standard way of doing this.

How to make rails 3 I18n translation automatically safe?

I use rails 3. Is there any easy way to tell I18n to respect 'html safness' of string used in interpolation and make all translated string html safe by default? So if I have this en.yml:
en:
user_with_name: 'User with name <em>%{name}</em>'
and I use t('user_with_name', :name => #user.name), I get users name html escaped, but <em> and </em> is left as is?
http://guides.rubyonrails.org/i18n.html#using-safe-html-translations
The official Rails guide says you can use the interpolated variables without concern, since they are html escaped automatically, unless you specifically declare them to be String.html_safe.
From the guide:
Interpolation escapes as needed though. For example, given:
en:
welcome_html: "<b>Welcome %{username}!</b>"
you can safely pass the username as set by the user:
<%# This is safe, it is going to be escaped if needed. %>
<%= t('welcome_html', username: #current_user.username %>
Safe strings on the other hand are interpolated verbatim.
Change the name from user_with_name to user_with_name_html, then rails will know you have included html in the text.
Old question, but if someone wants to achieve this, here's the monkey patch I came up with :
module ActionView
module Helpers
module TranslationHelper
private
def html_safe_translation_key?(key)
true
end
end
end
end
Put this in an initializers and that's it!
Works with Rails 3.2.6.
Only marks the text in localization files as safe, not the interpolation parameters.

How can I automatically render partials using markdown in Rails 3?

I want to have some of my partials as markdown snippets. What is the easiest way to render them using the standard rails erb templating?
Ideally, I'd like to do something like this:
If I have a partial in app/views/_my_partial.md.erb:
My awesome view
===============
Look, I can **use** <%= language %>!
which I reference from a view like so:
<%= render "my_partial", :language => "Markdown!" %>
I want to get output that looks like this:
<h1>My awesome view</h1>
<p>Look, I can <strong>use</strong> Markdown!</p>
Turns out, the Right Way (tm) to do this is using ActionView::Template.register_template_handler:
lib/markdown_handler.rb:
require 'rdiscount'
module MarkdownHandler
def self.erb
#erb ||= ActionView::Template.registered_template_handler(:erb)
end
def self.call(template)
compiled_source = erb.call(template)
"RDiscount.new(begin;#{compiled_source};end).to_html"
end
end
ActionView::Template.register_template_handler :md, MarkdownHandler
If you require 'markdown_handler' in your config/application.rb (or an initializer), then any view or partial can be rendered as Markdown with ERb interpolation using the extension .html.md:
app/views/home/index.html.md:
My awesome view
===============
Look, I can **use** <%= #language %>!
app/controllers/home_controller.rb:
class HomeController < ApplicationController
def index
#language = "Markdown"
end
end
Not a pure markdown solution but you can use HAML filters to render markdown, as well as other markup languages.
For example, in app/views/_my_partial.html.haml:
:markdown
My awesome view
===============
Look, I can **use** #{language}!
Have found way not to use haml in such situation.
in views/layouts/_markdown.html.erb
<%= m yield %>
in app/helpers/application_helper.rb
def m(string)
RDiscount.new(string).to_html.html_safe
end
in Gemfile
gem 'rdiscount'
So, in view you can call it like:
<%= render :partial => "contract.markdown", :layout => 'layouts/markdown.html.erb' %>
And contract.markdown will be formatted as markdown
I just released a markdown-rails gem, which handles .html.md views.
You cannot chain it with Erb though -- it's only for static views and partials. To embed Ruby code, you'd have to use tjwallace's solution with :markdown.
Piling on the solutions already presented, this is an interpolation-ary way in Rails 3 to render a pure Markdown file in a view from a partial without unnecessary indentation using Haml's :markdown filter and the RDiscount gem. The only catch is that your Markdown file is a Haml file, but that shouldn't matter for someone like a copy person.
In Gemfile:
gem 'rdiscount'
In app/views/my_page.html.haml
:markdown
#{render 'my_partial', language: 'Markdown!'}
In app/views/_my_partial.html.haml
My awesome view
===============
Look, I can **use** #{language}!
If you didn't need the :language variable passed in to the markdown file, you could do away altogether with your Markdown being a Haml file:
In app/views/my_page.html.haml
:markdown
#{render 'my_partial.md'}
In app/views/_my_partial.md
My awesome view
===============
Sorry, cannot **use** #{language} here!
Don't like those pesky underscores on your Markdown files?
In app/views/my_page.html.haml
:markdown
#{render file: 'my_markdown.md'}
In app/views/my_markdown.md
My awesome view
===============
Sorry, cannot **use** #{language} here!
Leveraged your answer to make a gem to render for GitHub Flavored Markdown in Rails (via HTML::Pipeline): https://github.com/afeld/html_pipeline_rails
Here is a version similar to #Jacob's but using Redcarpet.
module MarkdownHandler
def self.erb
#erb ||= ActionView::Template.registered_template_handler(:erb)
end
def self.call(template)
options = {
fenced_code_blocks: true,
smartypants: true,
disable_indented_code_blocks: true,
prettify: true,
tables: true,
with_toc_data: true,
no_intra_emphasis: true
}
#markdown ||= Redcarpet::Markdown.new(Redcarpet::Render::HTML, options)
"#{#markdown.render(template.source).inspect}.html_safe"
end
end
ActionView::Template.register_template_handler :md, MarkdownHandler
Full credit to lencioni who posted this in this gist.
And if you'd like to evaluate erb:
erb = ERB.new(template.source).result
#markdown ||= Redcarpet::Markdown.new(Redcarpet::Render::HTML, options)
"#{#markdown.render(erb).inspect}.html_safe"
You can use embedded Markdown in Rails 5. Embedded Markdown is based on the solution provided by Jacob above
Add these to your application's Gemfile:
gem 'coderay' #optional for Syntax Highlighting
gem 'redcarpet'
gem 'emd'
bundle install.
Then create a view app/view/home/changelog.html.md and paste your markdown in that .md file.
Generate a home controller using the following command
rails generate controller home
Add the following line to your route.rb:
get '/changelog', :to 'home#changelog'
That's all. Visit http://localhost:3000/changelog to see your rendered markdown
Source: http://github.com/ytbryan/emd

escape HTML output but no line-breaks

I have a description text field in my Model.
No I want to add this description on the show page.
But the text renders ugly because of no linebreaks.
If i replace them with <br/> then the rails escape them with.
So i tried to use the raw() method.
I want to escape bad HTML but have the linebreaks in my output.
I end up with some ugly code.
raw(h(#place.description.gsub("\n","#linebreak#")).gsub("#linebreak#","<br/>"))
Do you have any suggestions?
you should use the simple_format helper:
<%= simple_format #place.description %>
http://api.rubyonrails.org/classes/ActionView/Helpers/TextHelper.html#method-i-simple_format
3 years later, but it's never too late to provide a good working solution
This will escape all HTML chars but the newlines (compatible Linux, Windows and Mac)
html_escape(#place.description).gsub(/(?:\n\r?|\r\n?)/, '<br />').html_safe
is what you are looking for
#place.description.html_safe.gsub("\n", '<br/>')
? But on second thought, doesn't the html_safe usage like that make it easy for the site to get XSS attack? (because it assumes the description is safe).
So won't a better solution be
<%= (h #place.description).gsub("\n", '<br/>') %>
at first I thought
<%= (h #place.description).gsub("\n", '<br/>'.html_safe) %>
is needed but actually both versions work. I then tested by adding some HTML tags to description and it got escaped into < etc, so it does prevent XSS attack.
Here's a solution that works:
<%= sanitize(#place.description.gsub("\n", "<br />"), :tags => %w(br), :attributes => %w()) %>
More reading:
Parsing newline characters in textareas without allowing all html tags
Documentation:
http://api.rubyonrails.org/classes/ActionView/Helpers/SanitizeHelper.html
From sanitize:
This sanitize helper will html encode all tags and strip all attributes that aren’t specifically allowed.
It also strips href/src tags with invalid protocols, like javascript: especially. It does its best to counter any tricks that hackers may use, like throwing in unicode/ascii/hex values to get past the javascript: filters. Check out the extensive test suite.
You can specify allowed tags with :tags option, and attributes with :attributes option.