Rails: render ruby logic in i18n string - ruby-on-rails

I'm currently translating a application and i've stumbled upon a problem. I'm using this in my views:
t("page.text")
and i have this is my yaml file:
page:
text: "This is my tekst with a #{link_to "pages index, pages_path}"
This string gets outputted without the link_to logic in it, like this: "This is my tekst with a #{link_to "pages index, pages_path}". This is not what i want, i want the string parsed with the link_to function like this: "This is my tekst with a pages index" where pages index links to the /pages route...
Thanks.

Rails's i18n API allows you to use variable-based interpolation in your YAML file. To do what you're trying to do:
# config/en.yml
page:
text: "This is my test with a %{link}"
# view.html.erb
<%= t("page.text", :link => link_to("pages index", pages_path))
You can read more about it in the official Rails Guide: http://guides.rubyonrails.org/i18n.html#interpolation

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

Multiple i18n submit helpers for same controller action?

I have some i18n helpers set up as follows:
en:
helpers:
submit:
post:
create: "Save and Continue"
update: "Update"
Now in _form.html.erb
<%= f.submit %>
This works great.
Now I add a :status attribute to my Post model and want to give a different message for the :update action based on the #post.status value. Something like:
en:
helpers:
submit:
post:
create: "Save and Continue"
update: "Update"
publish: "Save Draft"
Is this easily doable under i18n or should I just write a helper instead?
en:
foo: "bar"
These are translation keys - not helpers. Helpers in Rails are modules that contain helper methods.
Is this easily doable under i18n or should I just write a helper instead?
Yes and no.
The rails form helpers just translate the button according to the action. Which is good enough for what its used for 99% of the time.
You can use the Rails i18n module to define the translations. And create a helper method to cover your case:
module PostHelper
def post_submit_button(form_builder)
post = form_builder.object
if object.persisted?
concat( form_builder.submit(
I18n.t("helpers.submit.post.update.#{post.status}")
)
else
concat( form_builder.submit )
end
end
end
Definitely doable under I18n. You would basically do something like
message = I18n.t("helpers.submit.post.update.#{post.status}")
Assuming post is an instance of your post model.

HTML in pure Ruby

Is there such a gem exists for writing rails view helpers or even views? If not, what would be the starting point for such a gem?
div class: 'header' do
h1 { 'Hello World' }
a href: 'http://google.com', class: 'button' do
'Google'
end
end
Inspired by how recent javascript front-end libraries implement component based views using pure javascript functions, such as: React, Vue.js etc.
Maybe Markaby will help you, which lets you generate HTML through Ruby.
An example from the official docs:
require 'markaby'
mab = Markaby::Builder.new
mab.html do
head { title "Boats.com" }
body do
h1 "Boats.com has great deals"
ul do
li "$49 for a canoe"
li "$39 for a raft"
li "$29 for a huge boot that floats and can fit 5 people"
end
end
end
puts mab.to_s
Arbre will do the job.
It was extracted from widely used ActiveAdmin gem as independent solution for such needs.
A simple example from project's README:
html = Arbre::Context.new do
h2 "Why is Arbre awesome?"
ul do
li "The DOM is implemented in ruby"
li "You can create object oriented views"
li "Templates suck"
end
end
puts html.to_s # =>
will render the following:
<h2>Why is Arbre awesome?</h2>
<ul>
<li>The DOM is implemented in ruby</li>
<li>You can create object oriented views</li>
<li>Templates suck</li>
</ul>
Firstly, your code looks very similar to HAML:
#app/views/model/your_view.haml
.header
%h1 Hello World
= link_to "Google", "http://google.com", class: "button"
If you're looking for a way to clear up your views, that may be a good place to begin.
#Meeh looks like he has a good answer; if you wanted another opinion, I would start looking into pseudocode.
To my understanding, pseudocode is basically a way to create a "application-level" functionality of a deeper level. For example...
#app/helpers/view_helper.rb
class ViewHelper
def a approved_site, *options
return "Site not valid" unless Site.exists? name: approved_site.to_s
site = Site.find_by name: approved_site.to_s
options.extract_args!
link_to site.name, site.url, options #-> ruby automatically returns the last line
end
end
... this would allow you to call:
#app/views/controller/view.haml
= a :google, class: "button"
--
If you wanted to make that into a full-scale front-end framework, you'd need a collection of "base" functions. On top of those functions, you'd have more specific implementations, such as:
#app/helpers/base_helper.rb
class BaseHelper
def meta type, *args
types = %i(js css title link keywords author description robots favicon)
options = args.join(', ')
# Return Values
case type
when :title
Haml::Engine.new("%title #{options}").render
end
end
end
end
#app/helpers/meta_helper.rb
class MetaHelper
def title value
meta :title, value
end
end
I think you want react.rb (http://reactrb.org) Does everything Abre does, plus can deal with client side interactions as well (if you need it to.)
The dom gem that I have developed does exactly what you wanted to. Using it, you can do things like:
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>"

How to get application context in Rails

I have a URL like http://myapp.myorg.com/MyApp/one/two and I want to extract the first part myapp.myorg.com/MyApp/ in the Rails code. Please help me in getting this URL correct.
I'm currently using $servlet_context for this purpose, but it does not give me the result.
My code snippet:
<%= link_to "My Link", "{#hostname}/#{$servlet_context}/three/four" %>.
This gives me a URL like:
myapp/org.jruby.rack.servlet.ServletRackContext#622209db/three/four
I'm expecting something like:
myapp/MyApp/three/four
You can probably get this by extracting the first part of your path by defining this in your controller:
def context_path(url)
URI.join('/' + request.fullpath.split('/')[1], url)
end
helper_method :context_path
Then that's easy to incorporate into your URL:
<%= link_to "My Link", context_path('three/four') %>

How to generate a `link_to` URL passing some custom parameters?

I am using Ruby on Rails 3.0.9 and I would like to generate a link_to URL passing some custom parameters. That is, having a articles_path (www.my_web_site_name.com/articles) I would like to generate something like the following:
link_to 'Sample link title', ... # Here I should implement the code
# => 'http://www.my_web_site_name.com/articles?param1=value1&param2=value2&...
How can I code the link_to statement "a là Ruby on Rails Way" in order to accomplish that? And what if I would_like to 'link_to' an 'article_path(#article)' by passing some custom parameters?
Somewhere I have seen to use something like link_to 'Sample link title', :param1 => 'value1', :param2 => 'value2' but in this case it isn't involved the named route (the generated URL refers to the current path).
You can send those arguments to the path helper, in this case articles_path. Like this:
link_to 'Sample link title', articles_path(:param1 => 'value1', :param2 => 'value2')
I think that is what you want.

Resources