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.
Related
I currently have a very simple form for search written in HAML:
%form.search{ method: 'get', action: '/users/search' }
...
What would be the correct rails conventions for rendering a different search route based on the model that the controller sets in an instance variable when rendering this view?
I found this blog post, but this code <%= form_tag(recipes_path, :method => "get" is not generic enough for me. I would like to set this value, recipes_path, based on the model that the controller is collaborating with when it renders this view. The search form could be used across multiple controllers with their own search action. My app can search on different pages for different models.
I can definitely come up with a way to do it, but I would like to know the 'right' way or I suppose the 'rails' way of dynamically setting the form action to a different controller action based on the data that the form will be searching against.
I don't know what the 'right' or 'rails' way of doing this is. (But, it sure isn't hand-crafting a form with %form.)
In my apps, I tend to only have one form partial that looks something like this:
app/views/widgets/form
- #presenter = local_assigns[:presenter] if local_assigns[:presenter]
= form_tag #presenter.form_path, remote: true, id: #presenter.form_id, class: #presenter.form_classes, data: #presenter.form_data, method: #presenter.form_method do
= #presenter.form_inner
In my presenter_base.rb file, I have something like this:
class PresenterBase
def render_partial
render(partial: "#{file_name}", locals: {presenter: self})
end
def render_form
render_partial 'widgets/form'
end
end
So, to render the form in a FooPresenter, I might do something like:
class FooPresenter < PresenterBase
def present
render_form
end
def form_path
some_form_path(and: :maybe, some: :query_params)
end
def form_id
'my-cool-form'
end
def form_classes
'some cool classes'
end
def form_data
{some: :form, data: :here}
end
def form_method
:post
end
def form_inner
...
end
end
Naturally, there's more to it than just that (like, how I get a plain old ruby object to render). But, that should give you a sense of one way of doing it.
A simple way if there are no complications and you follow the conventions, can be something like this
%form.search{ method: 'get', action: "/#{controller_name}/search" }
so if you are in users_controller, it will print "users", if you are in static_pages_controller, it will show "static_pages" and so on.
I have a multi-lingual application in Ruby on Rails 4. For that I use the following domains:
Swedish: exempel.se
English: example.com
French: fr.example.com
Spanish: es.example.com
I want to be able to link to the corresponding path in another corresponding locale. For example if I am at www.exempel.se/denna-bloggpost I want to be able to easily link to (English/Spanish/French) to e.g. www.example.com/this-here-blog-post and es.example.com/este-posto-de-bloggo (sorry, can't speak Spanish :)).
I understand this is done with link_to 'Spanish', locale => :es but this gives me the url www.exempel.se/denna-bloggpost?locale=es which is not what I want. I expect to access es.example.com/esto-posto-de-bloggo
It seems like default_url_options has something to do with this but I can't make it work.
How do I solve this?
Edit (2017-03-30): I will also need this solution for hreflang in the section.
I am using the route_translator gem.
I have seen several solutions for this but they all include solutions with ?locale=en or are just to simplified (like, only working for one single controller). What I am hoping for is a solution that would do something like this:
<% I18n.available_locales.each |locale| do %>
<% I18n.t(this route e.g. /denna-bloggpost) #=> /este-posto-de-bloggo, /this-blog-post, /le-post-du-blog %>
<% end %>
You can use the locale-specific routes that route_translator generates for you. Run rake routes to see what these are. And then:
# Create links for every other locale
<% (I18n.available_locales - I18n.locale).each |locale| do %>
# Example URL helper here - replace with your own!
<%= Rails.application.routes.url_helpers.send("posts_#{locale}_url",
'denna-bloggpost') %>
<% end %>
In order to create such a dynamic mapping, you must presumably have something like this defined in your application config:
APP_CONFIG = {
# ...
base_urls: {
se: 'exempel.se',
en: 'example.com',
fr: 'fr.example.com',
es: 'es.example.com'
}
# ...
}
(It wouldn't necessarily need to be in this format, of course; this is just an example.)
In the locale switching menu, you can then define your links like this:
link_to("French", "#{APP_CONFIG[:base_urls][:fr]}#{request.env['PATH_INFO']}")
In order to actually set the locale in your application, you could then place something like this in your ApplicationController:
class ApplicationController
before_action :set_locale
def set_locale
I18n.locale = APP_CONFIG[:base_urls].key(request.host) || I18n.default_locale
end
end
For more information, see here: http://guides.rubyonrails.org/i18n.html#managing-the-locale-across-requests
This question is addressed a number of times and many ways. Yet the simplest approach in my opinion is
<%= link_to "ру", request.params.merge( locale: 'ru' ) %>
I have to add view for custom action which is member action, and want to display association records on it. Is there way to add custom view instead of just adding html.erb in admin's view folder?
I dont want to add or create html files but by using the active admins helpers.
The member action in nothing else like a controller action, thats mean you can do the same things in it.
You can use thinks like:
render text: "Hello world!"
Or if you want a complex markup:
message1 = "Hello"
#message2 = "world!"
view = Arbre::Context.new(message: message, self) do
h1 do
span message
span #message
end
end
render body: view.to_html # or .to_s
You can use the following code for the render html for rails 4.1:
render html: '<html><body>Some body text</body></html>'.html_safe ## Add html_safe
But, if you use rails 4.2, so you can use the following:
render text: '<html><body>Some body text</body></html>'
I think the following answer is very useful for your question.
Ended up with adding the following in html.erb file in admin/user/messages.html.erb
<% view = Arbre::Context.new({messages: #messages, user: #user}, self) do
panel "Sent Messages" do
paginated_collection(messages, download_links: false) do
table_for collection do
column :id
column :content
end
end
end
end
%>
<%= view.to_s %>
Depending on your namespace (ActiveAdmin is on /admin in my case) you can create the folder app/views/admin in the same way you would in the rest of your application.
For example, if you have a resource User and an action apply_discount
ActiveAdmin.register User do
member_action :apply_discount, method: [:get, :put] do
if request.get?
render :apply_discount
else
# TODO ...
end
end
end
you could put your ARBRE view file into app/views/admin/users/apply_discount.html.arb -> notice the extension is ARB, not ERB - though ERB should work too according to the docs
I want to translate my applications' views and as I'm using partial to render headers for each view like this:
<%=t "#{controller.controller_name.capitalize} #{controller.action_name}" %>
...I got stucked on translating them. How do I translate controller.action_name in custom translation file?
I've tried to access action names like this:
parkings:
index: "Parkings index"
new: "New %{model}"
And many different variations of it, but every one failed. Could you help me?
This is a fragment of my controller:
def new
#parking = Parking.new
end
def create
#parking = Parking.new(parking_params)
if #parking.save
redirect_to #parking, notice: t(:parking_created)
else
render action: 'new'
end
end
Thanks.
You should have the translations in your locale file. Add an underscore or hyphen to separate words in the key
eg:
# config/locales/en.yml
en:
parkings_index: Parkings index
parkings_new: Parkings new page
view file
<%=t "#{controller_name}_#{action_name}" %>
First of all, when you say #{controller.controller_name} it means that you have an object called controller accessible from your view, which is not true. Even if you manage to access the controller and the name of its action I don't think it's worth the effort and time.
Instead, you can structure your translation file somehow like this:
views:
model_name (parkings): "Parkings"
action_1_name (index): "Parkings Index"
action_2_name (new): "New Parking"
...
and in your view say (for example) <%= link_to (t "views.model_name.action_name"), :action %>
I'm using STI with a Rails 3.2 app. I want to force Rails to use the superclass name in link_to helpers (or any where else when it's generating paths) and not the subclass name.
So, <%= link_to current_user.name, current_user %> produces /:class_name/:id (class name can be "Moderator," "Member," etc...).
I would like it to produce /users/:id, where users does not change to the name of the subclass. I know I can change current_user to user_path(current_user), but I prefer to use the shortcut, letting Rails figure it out.
Is this possible?
I think you should define url helpers, something like this
def moderator_url record
user_url record
end
Or just use aliases
alias :moderator_url :user_url
This is code which rails use for url generation when you pass a record as a option
https://github.com/rails/rails/blob/537ede912895d421b24acfcbc86daf08f8f22157/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb#L90
Use the named route:
<%= link_to current_user.name, user_path(current_user) %>
For links, I can get around this by adding a resource:
resources :owners, path: 'users', controller: 'users'
For forms, I need to specify generic form. My initial form was
= simple_form_for #user do |f|
To make this work, I had to specify the path and the method, while using a generic name instead of passing the user object to the form directly:
= simple_form_for :user, url: user_path(#user) do |f|