Need To Add Locale To link_to Statement in a Mailer View - ruby-on-rails

I have removed gem routing-filter from my Rails 3.2.13 application in preparation to upgrade it to Rails 4. The author(s) have a beta version for Rails 4 but I could never get it to work. I have implemented the normal Rails process for localization/internationalization. The last issue I need to resolve is a link_to statement that displays a thread in a mailer view.
When I was using routing-filter I had the link_to statement as below where I set #host in my mailer depending on the environment.
<%= link_to "#{t :view_thread}", micropost_url(#item), host: "#{#host}" %>
When I uninstalled routing-filter I started getting errors because of a missing locale when the attempt is made to send the email. It crashes and sends the application back to the landing page. The gem took care of this.
I have been searching for about an hour trying to find the correct syntax for this but I'm not finding any examples that include both the host and locale parameters. I have tried several guesses but I get syntax errors.
Any help would be appreciated. I will keep searching and trying.

Here is the solution I came up with. I was not sure where the locale clause should go related to the host clause. I decided to try the statement below and it worked.
<%= link_to "#{t :view_thread}", micropost_url(#item, locale: I18n.locale.to_s), host: "#{#host}" %>

Updated solution for Rails 6 (and probably 5).
First, make sure you followed Rails guides on localization, so it's all set up
Then, add this to your ApplicationMailer:
def default_url_options(options = {})
ActionMailer::Base.default_url_options
.merge(locale: I18n.locale)
.merge(options)
end
This will use your selected locale for links generation, so you don't have to pass locale: #locale every time.
And then, set current locale in your mailers with the following block.
I18n.with_locale(#locale) do
mail(to: #email,
subject: I18n.t("mailers.my_mailer.subject"))
end
The last piece of advice - don't forget to fallback with your #locale var, so it's smth along these lines: #locale = #user.locale || I18n.default_locale
Update:
Or you can simply monkeypatch mail method, but make sure you know what you're doing.
def mail(**)
I18n.with_locale(#locale || I18n.default_locale) { super }
end

Related

Rails 4 Mailer Uninitialized Constant

I am trying to setup a mailer to where when a listing's available date is today, it will fire off a mailer. To do that, I am using Date.today. The other relevant code and error is below. Thanks in advance.
availabke_date_mailer.rb
class ListingAvailableDateMailer < ActionMailer::Base
default from: "Nooklyn <help#nooklyn.com>"
def listing_available_expire(listing, agent)
#listing = listing
#agent = agent
mail to: "#{agent.email}", subject: 'Availability of your listing needs to be changed!'
end
end
listing_available_expire_notification.html.erb:
Hiya <%= #agent.first_name %>,<br><br>
The Available Date for your listing has passed. Please make the necessary changes.<br><br>
Listing: <%= link_to #listing.short_address, #listing, target: "_blank" %><br><br>
Available Date: <%= #listing.date_available %><br><br>`
available_date.rake:
namespace :listings do
desc "Send a message to an agent if the available date on their listing has passed"
task listing_available_expire: :environment do
Listing.all.each do |listing|
if listing.date_available == Date.today
ListingAvailableDateMailer.listing_available_expire(listing,listing.listing_agent).deliver_now
end
end
end
end
Error:
Rename your availabke_date_mailer.rb and store it at the correct location:
app/mailers/listing_available_date_mailer.rb
Rails does a lot of magic for you, but the magic only works if you follow its conventions. One of the conventions that allows autoloading and removes the need to require all files manually is that class names (in camelcase) have to match the name of the file (in underscore) in which they are defined.
In a next step, you will have to rename your view. Because following Rails conventions it needs to be named like this:
app/views/listing_available_date_mailer/listing_available_expire.html.erb
Read about the Action Mailer Basics in the Rails Guides.
Another reason for this error is if you try to run something like
UserMailer.signup_confirmation(#user).deliver
NameError: uninitialized constant UserMailer
from the rails console.
Note that the exact same code will work from the controller.
A simple way to test such code is to simply place it in a controller action that doesn't require any effort to execute, for example, the users show view is a good candidate, so simply loading that page will cause an email to send

Link to corresponding path in other locale (rails)

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' ) %>

Rails current url helper

Apologies for such a simple question, but I couldn't been able to solve it myself after hours since my RoR knowledge is basically nonexistent. In the Rails application I'm working with, has been used a navigation helper to highlight active menu:
def nav_link(link_text, link_path, ico_path)
class_name = current_page?(link_path) ? 'active' : nil
content_tag :li do
link_to(link_path, class: class_name) do
image_tag("icons/#{ico_path}.svg") + content_tag(:span, link_text)
end
end
end
The circumstances have changed and current_page? is no longer a viable option, since routing now handled on the front-end. Is there a way to achieve the same functionality by retrieving, for instance, current url and check it against link_path?. I've tried a lot of things with different helpers like request.original_url, but to no avail.
request.original_url should work according to the documentation.
Returns the original request URL as a string
http://apidock.com/rails/ActionDispatch/Request/original_url
You could also try string concatenation with different variables.
request.host + request.full_path
If that doesn't work either, you could try
url_for(:only_path => false);
Use
request.url
http://api.rubyonrails.org/classes/ActionDispatch/Http/URL.html#method-i-url
or
request.path
http://www.rubydoc.info/gems/rack/Rack/Request#path-instance_method
You'll want to look at the active_link_to gem:
def nav_link(link_text, link_path, ico_path)
content_tag :li do
active_link_to link_path do
image_tag("icons/#{ico_path}.svg") + content_tag(:span, link_text)
end
end
end
Unlike the current_page? helper, active_link_to uses controller actions and model objects to determine whether you're on a specific page.
current_page? only tests against the current path, leaving you exposed if you're dealing with obscure or ajaxified routes.
--
I was going to write about how current_page? works etc, but since you mentioned that it's nonviable, I won't. I would have to question why it's nonviable though...
routing now handled on the front-end.
Surely even if you're using something like Angular with Rails, you'd have to set the routes for your app?

Fast_Gettext Not Displaying Translations in Rails 3.2.13 Application

I have PO files (en.po & fr.po) that I want to use to localize my Rails application into French. I submitted the question https://stackoverflow.com/questions/17203622/translating-a-rails-application-3-2-13-using-po-gettext-files recently to see if I could get any help. I mentioned that I had read some information about Fast-Gettext and another gem. I decided to look at the Fast-Gettext gem since it allows the use of PO files without using a database.
I added the latest versions of fast_gettext and gettext_i18n_rails in my Gemfile. I installed the latter gem to get rid of an undefined method "_" error message even though I have no plans at this point to use the database feature.
I added the following code in config/application.rb.
# add FastGettext configuration
FastGettext.add_text_domain 'my_app', :path => 'config/locales', :type => :po, :ignore_fuzzy => true, :report_warning => false
FastGettext.default_text_domain = 'my_app' # set the default textdomain
FastGettext.default_available_locales = ["en","fr"] # set available locales # (note: the first one is used as a fallback if you try to set an unavailable locale)
FastGettext.default_locale = 'en'
Here is my setup in application_controller.rb to allow the locale to be set and saved using a cookie.
include FastGettext::Translation
before_filter :set_users_locale
def set_users_locale
I18n.locale = FastGettext.set_locale(params[:locale] || cookies[:locale] ||
request.env['HTTP_ACCEPT_LANGUAGE'] || 'en')
cookies[:locale] = I18n.locale if cookies[:locale] != I18n.locale.to_s
end
I added logic where the user can click a flag and set the value of :locale.
<%= link_to_unless_current image_tag("flag_us_30px.jpg", :alt => "Set Language to English"), locale: "en" %>
<%= link_to_unless_current image_tag("flag_fr_30px.jpg", :alt => "Set Language to French"), locale: "fr" %>
When a person clicks the flag it sets the value of :locale correctly. I have my routes formatted as domain.com/:locale/link. Right now the root will include the locale until I add logic to override it.
Here are two statements in my views that I am testing with:
<%= _("Language") %>
<%= _("Note: If you do not understand the text on the icons, use the text links at the bottom of the page.") %>
When I click the French flag to change the value of :locale to "fr" the link changes properly but the code for both strings remains in English. The PO file has the French translation for both of these terms. I would think that if it had not found the PO files that I should be seeing error messages stating it did not find them.
I first attempted to use the configuration code in config/initializers/fast_gettext.rb but did not get any results so I decided to put it in config/application.rb to see if I could get it to work. I also removed ':ignore_fuzzy => true, :report_warning => false' to see if that may change things. However I get the same results.
I am using fast_gettext because back in 2011 #svenfuchs recommended it for using Gettext. I may try and contact him on Twitter since it looks like that is the only place I can find where he is active these days.
Any help would be appreciated.
Why are you using PO files instead of common Rails translations?
Or the globalize3 if you prefer to save the translations on database and add model translations.
There's also a gem to help you converting your existing translations: i18n-translators-tools.

Rails 3.0.7 Restful_Authentication, Why does destroy try to log in from cookie while others do not?

I have an app that I am upgrading to Rails 3 which uses the restful_authentication plugin. I have the authenticated_system.rb in the lib directory where it seems to be able to find it. I have put puts in the library to figure out what it does on each call. When I call any method besides destroy the puts statement tells me it has logged in from session. When I try to use the destroy method in a controller (does not matter which) it tells me that it is trying to login from cookie, which fails because the system is set up not to use cookies. Why would it be doing this? The code is exactly the same for all of them and the before filter is simply:
def validate_user_type
if ( current_user.user_type == User::UserType::VIEWER )
redirect_to :controller => 'assets', :action => 'myassets'
end
This filter is applied to everything
Any ideas?
Try button_to instead of link_to for you delete actions.
I had the same problem, it was because I was using link_to with the :remote option.
This was not passing the authenticity_token in the post parameters, and therefore restful_authentication was failing.
I switched to using button_to, the authenticity_token was included and my deletes started working.
I found this, never posted though, check the application layout for csrf tags, if these are not there it will do some funky things. This was the problem.

Resources