igel / it Goto Github PK
View Code? Open in Web Editor NEWA helper for links and other html tags in your translations
License: MIT License
A helper for links and other html tags in your translations
License: MIT License
Have you given any thought to support for other HTML elements such as <strong>
or <i>
using a similar syntax. Perhaps something like https://gist.github.com/hagenburger/b96fada108d05d3c8f52
IMHO would compliment the link functions nicely.
I tried to write a spec that asserted that It would obey translation keys like ".widgets_link," but I had some trouble getting the spec to work. It looks like It uses ActionView::Helpers::TranslationHelper#t
under the hood, so this should work. There's no functionality problem; I was just trying to improve the test suite. If you have any suggestions on how to get that spec to pass, I'd love to hear them.
What I tried:
it 'should support dot-prefixed keys' do
I18n.backend.store_translations(:en, :widgets => { :show => { :all_widgets => "See %{widgets_link:all widgets}" } })
@view.it('.all_widgets', :widgets_link => '/widgets').should == 'See <a href="/widgets>all widgets</a>'
end
The problem is that the t
method relies on a @_virtual_path
instance variable to be available. Other than just setting that instance variable directly on @view
, I don't see how to get it in there.
The :locale option works with t but not with it
Hello,
your post on Stackoverflow has saved my day! Thank you for implementing this as a gem.
However I think I have found a bug: Pluralization (using :count) does not work. If I have something like
foobar:
one: You have %{foobar_link:one Foobar} pending.
other: You have %{foobar_link:%{count} Foobars} pending.
and then use
<%= t( 'foobar', :count => 4, :foobar_link => foobar_path(foobar) ) %>
I get
oneYou have _one Foobar_ pending.otherYou have _4 Foobars_ pending.
in my template (where the ... is the correct link).
Do you have an idea why this happens?
Thank you! :)
Regards
Jens
Terrific gem.
It can be done on a one-off basis in Rails 3+ using view_context.it(key,...)
But the preferred method is probably this:
class ApplicationController < ActionController::Base
include It::Helper
Very useful for controller flash
messages like this:
if @invitation.accepted?
flash[:notice] = it('flash.invitation_accepted_already', link: new_password_reset_path)
with en.yml
like this:
flash:
invitation_accepted_already:
This invitation has already been accepted.
Sign up as a new user or %{link:reset password} if an existing user.
Hello,
neither "I18n.it(...)", "It.it(...)" nor "it(...)" work from inside a model. However, I have translatable content in my models (e.g. description, validation messages which contain links and formatting, etc).
Is it possible to use It outside views?
Thanks!
I have a situation where I would like to make use of It's link / tag interpolation, without using the it helper.
More specifically the project already uses a custom 'translate'-helper with added functionality.
I thus decided to use the It::Parser directly from our helper, which works fine. Yet it is undocumented api, so my suggestion would be to officially document that scenario. I think I could do so and create a pull request.
Second I have a problem with It escaping the strings, as we're already using a different approach of sanitising our translations. Because we want to keep html characters like & or we're using the Rails::Html::WhiteListSanitizer.new.sanitize(str, tags: []).
'It' however is using Erb::Util.h which escapes those html entities. Would you accept a pull request that optionally disables escaping? As long as 'it' still returns String instead of ActiveSupport::SafeBuffer, current rails versions would still escape them, unless developers choose to mark them as html_safe.
one
and other
for English).one
, few
, many
, and other
pluralization keys.Using the it
helper results in I18n::InvalidPluralizationData
. This line is calling I18n.backend#pluralize
with the English key hash but with the Serbian locale. In this case, because the keys fell back to English, it should be calling it with the English locale.
Using t
does not have the issue - string is rendered in English without error.
Is there any way to use it in controllers like t
? I know I can use it with view_context.it
, but then I lose automatic scoping (view_context.it('.something')
gives a Cannot use t(".something") shortcut because path is not available
). t
on the other hand works like in views getting the scope from controller name and action.
If you had an idea where to start/look in the source I could try to make a PR implementing this.
Hi
About time someone actually is working on this. Indeed I18n is in need of an update in its format to allow foreign elements without always marking the subsequent string as html_safe.
Nevertheless, I see something missing: basically using it on top of I18ninstead of trying to replace it. So, instead of using the helper #it, i'd be using the old I18n.t, but I would be able to use the other It helpers inside it to handle the new markup.
Advantages: This lowers the overhead of introducing It in a new project by enhancing its features; otherwise I'll have to replace all I18n.t calls, and for some projects that's prohibitive. Also, the future merge of your idea into the actual i18n gem would be easened and the gems would be more of collaborators instead of competitors.
Version in rubygems have failed in tests with error and master branch works fine
Error:
TransactionsControllerTest#test_should_get_index:
ActionView::Template::Error: uninitialized constant ActionView::CompiledTemplates::It
app/views/shared/_footer.html.slim:4:in `_app_views_shared__footer_html_slim___2638031837804342381_70358124235060'
app/views/layouts/application.html.slim:10:in `_app_views_layouts_application_html_slim___1387193488641502264_70358137769220'
test/controllers/transactions_controller_test.rb:9:in `block in <class:TransactionsControllerTest>'
Any documentation on how to implement this using slim?
Some i18n tools (e.g. Tolk, different translation services) attempt to detect the default %{key}
syntax, and warn you if the same placeholder is missing from the translation. Understandably, they often stumble at the syntax used by It, as %{link:potato}
differs from %{link:pomme de terre}
.
What do you think about enabling an alternative syntax, that would be "backwards-compatible" with conventional i18n
interpolations? It would of course be optional, e.g. enabled in an initializer.
My first thought would be to pass the text content in separate parentheses after the normal interpolation, e.g. %{link}(potato)
or %{link}[potato]
. Maybe there are other viable options as well?
I'd be ready to develop this feature, but I thought I'd ask for opinions first to see if someone else considers it an idea worth pursuing.
Currently internationalising our app and using It for inline links. Would be great to support mail_to
style links.
E.g. it('.contact_us', mail: It.mail(Rails.config.support_email)
and then the corresponding translation: contact_us: "Click %{mail:here} to send us an email!"
It's not that difficult to implement as mail_to
is just a call to link_to
that adds mailto:
in front of the href
.
I18n.backend.store_translations(:en, test1: 'I have %{some_link: this %{text}} in the middle')
It.it('.test1', some_link: '#', text: 'linked text')
# "I have <a href=\"#\">this linked text</a>} in the middle"
It.it('.test1', some_link: '#', text: 'linked text{}')
# Expected: "I have <a href=\"#\">this linked text{}</a>} in the middle"
# Now: "I have %{some_link: this linked text{}} in the middle"
Note: there's a fix for this, see comments below. Basically you need i18n
version <= 1.2, or >= 1.4.
This crashes:
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'rails', '5.1.6.1', require: false
gem 'it', '1.0.0', require: false
gem 'i18n', '1.3.0', require: false
end
require 'action_view' # `it` depends on this, need to require after gemfile?
require 'active_support/all' # `it` depends on this, need to require after gemfile?
require 'it'
require 'i18n'
puts "using I18n #{I18n::VERSION}"
I18n::Backend::Simple.include(I18n::Backend::Fallbacks)
I18n.backend.store_translations(:en, {test1: "test1 %{interp}"})
I18n.backend.store_translations(:"en-AU", {test1: "test1 %{interp}, mate"})
I18n.backend.store_translations(:en, {test2: "test2 %{b: %{interp}}"})
I18n.backend.store_translations(:"en-AU", {test2: "test2 %{b:%{interp}}, mate"})
puts I18n.t("test1", interp: "using I18n.t")
puts I18n.t("test1", interp: "using I18n.t", locale: "en-AU")
puts I18n.t("test2", interp: "using I18n.t")
puts I18n.t("test2", interp: "using I18n.t", locale: "en-AU")
puts It.it("test1", interp: "using It.it") # this crashes on i18n v 1.3.0
puts It.it("test2", interp: "using It.it", b: It.tag(:b))
=begin
using I18n 1.3.0
test1 using I18n.t
test1 using I18n.t, mate
test2 %{b: using I18n.t}
test2 %{b:using I18n.t}, mate
/Users/alex/.rvm/gems/ruby-2.3.8/gems/i18n-1.3.0/lib/i18n/config.rb:99:in `block in missing_interpolation_argument_handler': missing interpolation argument :interp in "test1 %{interp}" ({"fallback_in_progress"=>true} given) (I18n::MissingInterpolationArgument)
from /Users/alex/.rvm/gems/ruby-2.3.8/gems/i18n-1.3.0/lib/i18n/interpolate/ruby.rb:31:in `block in interpolate_hash'
from /Users/alex/.rvm/gems/ruby-2.3.8/gems/i18n-1.3.0/lib/i18n/interpolate/ruby.rb:23:in `gsub'
from /Users/alex/.rvm/gems/ruby-2.3.8/gems/i18n-1.3.0/lib/i18n/interpolate/ruby.rb:23:in `interpolate_hash'
from /Users/alex/.rvm/gems/ruby-2.3.8/gems/i18n-1.3.0/lib/i18n/interpolate/ruby.rb:19:in `interpolate'
=end
This works fine:
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'rails', '5.1.6.1', require: false
gem 'it', '1.0.0', require: false
gem 'i18n', '1.2.0', require: false
end
require 'action_view' # `it` depends on this, need to require after gemfile?
require 'active_support/all' # `it` depends on this, need to require after gemfile?
require 'it'
require 'i18n'
puts "using I18n #{I18n::VERSION}"
I18n::Backend::Simple.include(I18n::Backend::Fallbacks)
I18n.backend.store_translations(:en, {test1: "test1 %{interp}"})
I18n.backend.store_translations(:"en-AU", {test1: "test1 %{interp}, mate"})
I18n.backend.store_translations(:en, {test2: "test2 %{b: %{interp}}"})
I18n.backend.store_translations(:"en-AU", {test2: "test2 %{b:%{interp}}, mate"})
puts I18n.t("test1", interp: "using I18n.t")
puts I18n.t("test1", interp: "using I18n.t", locale: "en-AU")
puts I18n.t("test2", interp: "using I18n.t")
puts I18n.t("test2", interp: "using I18n.t", locale: "en-AU")
puts It.it("test1", interp: "using It.it")
puts It.it("test2", interp: "using It.it", b: It.tag(:b))
=begin
using I18n 1.2.0
test1 using I18n.t
test1 using I18n.t, mate
test2 %{b: using I18n.t}
test2 %{b:using I18n.t}, mate
test1 using It.it
test2 <b>using It.it</b>
=end
This also works fine:
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'rails', '5.1.6.1', require: false
gem 'it', '1.0.0', require: false
gem 'i18n', '1.3.0', require: false
end
require 'action_view' # `it` depends on this, need to require after gemfile?
require 'active_support/all' # `it` depends on this, need to require after gemfile?
require 'it'
require 'i18n'
puts "using I18n #{I18n::VERSION}"
# note that we are not using fallbacks this time
I18n.backend.store_translations(:en, {test1: "test1 %{interp}"})
I18n.backend.store_translations(:"en-AU", {test1: "test1 %{interp}, mate"})
I18n.backend.store_translations(:en, {test2: "test2 %{b: %{interp}}"})
I18n.backend.store_translations(:"en-AU", {test2: "test2 %{b:%{interp}}, mate"})
puts I18n.t("test1", interp: "using I18n.t")
puts I18n.t("test1", interp: "using I18n.t", locale: "en-AU")
puts I18n.t("test2", interp: "using I18n.t")
puts I18n.t("test2", interp: "using I18n.t", locale: "en-AU")
puts It.it("test1", interp: "using It.it")
puts It.it("test2", interp: "using It.it", b: It.tag(:b))
=begin
using I18n 1.3.0
test1 using I18n.t
test1 using I18n.t, mate
test2 %{b: using I18n.t}
test2 %{b:using I18n.t}, mate
test1 using It.it
test2 <b>using It.it</b>
=end
So in summary, since upgrading to i18n
1.3, if fallbacks are enabled, It.it
is crashing when attempting to do any interpolation.
In a few cases, I'd like the label and the link to "be the same." Notice that the url (https://example.com
) and the email address ('[email protected]') is in both the ruby and the translation file. In my case these are dynamic values coming from the code.
If you'd like me to suggest a PR for the readme, let me know.
It.it "example", link: "https://example.com"
en:
example:
'Go see %{link:https://example.com}.'
It.it "example", email_link: "mailto:[email protected]"
en:
example:
'We are here to help. Email %{email_link:[email protected]}.'
The following solution works. I'm not sure if there is something better for Example 2.
CORRECTION: this does not work.
It.it "example", link: "https://example.com"
en:
example:
'Go see %{link:link}.'
This does work:
raw I18n.t "example", link: link_to("https://example.com", "https://example.com")
en:
example:
'Go see %{link}.'
CORRECTION: this does not work.
It.it "example", email_link: "mailto:[email protected]", email_address: '[email protected]'
en:
example:
'We are here to help. Email %{email_link:email_address}.'
This does work:
I18n.t "example", email_link: mail_to("[email protected]")
en:
example:
'We are here to help. Email %{email_link}.'
it
gem seems to expect that I18n just ignores missing interpolations and returns uninterpolated but translated string. Then, it
interpolates everything on its own. This hovewer fails with recent i18n (0.7.0) which by default raises the MissingInterpolationArgument exception on every missing interpolation that matches traditional interpolation regex (like %{email}
). It only happens in the helper version of t
and as a result it only happens in helper version of it
which calls t
helper. Using I18n.it
allows to bypass this problem.
In my case, fixing the it
helper was possible by adding the following into app initializer:
I18n.config.missing_interpolation_argument_handler = Proc.new do |key|
"%{#{key}}"
end
But it's not always a good solution. I think it
should handle this internally as it's a matter of communication between it and I18n
.
Our app is passing pre-built html tags to It.it
as interpolated variables, but to get these to render on the frontend and not be escaped by It we have to call html_safe
on every variable we pass to It in a method.
However, with normal hrefs (not HTML we've already built) we get invalid href given
from It, due to this line:
raise TypeError, 'Invalid href given' unless [Hash, String].include?(href.class)
We can solve this problem by adding ActiveSupport::SafeBuffer
to the array in the conditional, and it doesn't seem to cause any other errors in our test suite.
Is there any reason you don't consider an html safe string a valid href?
If not, can ActiveSupport::SafeBuffer
be added to the array of valid types in the gem, so we don't have to use a workaround/override the method ourselves?
hi. i'm making a pull request for a tiny change and noticed that lib/it/interpolation.rb is pretty different between master and 0.8.0 [the last gem version]. seems like this was 2 years ago also. is there a chance of getting a gem update? not sure where i should make this change [as it's in the very code that's in different places] and i use the last gem release not git [master] in my gemfile. thanks.
Feel free to close this issue if we don't want to solve it. I'm including it here to help the next person who sees this error message, which might be me =)
In my haste to use this gem, I didn't carefully look at the examples.
When I read this following line, I thought that I could use %{advises}
for It.it
when I really need to pass a label for the link %{link:**label**}
. In my one of cases, my label for my link is the same text as the link, so I assumed it was optional.
en:
copy: "Read the %{guide:Rails I18n guide} for more than %{advises} advises.
My code done in haste:
It.it "example", link: "https://example.com"
en:
example:
Go see %{link}'
This will give the error: 'wrong number of arguments (given 0, expected 1)'
Correct code:
It.it "example", link: "https://example.com"
en:
example:
'Go see %{link:https://example.com}.'
Perhaps the code could detect this situation and give a better error message.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.