Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
= SplendeoSplendeoTranslator - i18n tooling for Rails
SplendeoTranslator makes using the internationalization (i18n) facility introduced in Rails 2.2 simpler through:
== The Problem
The (very!) helpful I18n[http://api.rubyonrails.org/classes/I18n.html] library finds keys in locale bundles (and more), but doesn't know anything about Rails applications. Applications that have a lot of strings need a system of keeping them organized. SplendeoTranslator adds smarts to controllers, views, models & mailers to follow a simple convention when finding keys. Having a convention for the hierarchy of keys within locale bundles that makes it easier to code and maintain, while still using the capabilities of the underlying I18n library. (Note: SplendeoTranslator does not depend on how the actual YAML/Ruby files are stored in the filesystem.)
Quick example - if you follow the key convention of structuring your locale bundle like: blog_posts: # controller show: # action title: "My Awesome Blog Post" byline: "Written by {{author}}"
Then when writing the BlogPostsController.show action you can just use t('title') to fetch the string (equivalent to I18n.translate('blog_posts.show.title')). Similarly, in the show.erb template you can get use t('byline', :author => "Mike"). This extends to models and mailers as well. As they say, "Look at all the things I'm not doing!"
== Installation
To install this plugin into your Rails app (2.2 or 2.3+):
./script/plugin install git://github.com/splendeo/SplendeoTranslator.git
To install as a gem add the following to config/environment.rb:
config.gem "SplendeoTranslator"
== RDocs
{The RDocs are online}[http://splendeo.github.com/SplendeoTranslator/rdoc/index.html] or can be generated via rake rdoc in the SplendeoTranslator plugin directory.
== Problems or Suggestions
Please {file an issue in the Github bug tracker}[http://github.com/splendeo/SplendeoTranslator/issues/] or contact me.
== Simple +translate+ Everywhere
SplendeoTranslator adds an enhanced +translate+ (or shorter +t+) method to:
In the spirit of Rails, the convention for a hierarchy of keys borrows the same layout as the typical "views" directory. A sample Blog application is used as an example.
For controllers/views/mailers it is: en: # locale # the controller name blog_posts: # the action name index: key: "Hello World"
# partials w/o underscore (template "_footer.erb")
footer:
key: "My Copyright"
# "layouts" is fixed
layouts:
# the layout name (template "main.erb")
main:
key: "My App Name"
# for shared partials called like: render :template => "shared/user"
# where "shared" is the directory name
shared:
# partial name w/o underscore (template "_user.erb")
user:
key: "Foo"
# the full mailer name
blog_comment_mailer:
# the method name (does not include "deliver")
comment_notification:
subject: "New Comment"
For models it is: en: # The model name blog_post: key: "Custom validation error"
=== Key Lookup
When a key is looked up, SplendeoTranslator adds extra scoping to the lookup based on where it is called from. For:
But what happens if you want to share strings across a controller? Let's say you have error messages that are set in flash notices and then are shared between actions in a controller defined in the locale bundle like: blog_posts: errors: permission_denied: "Permission denied to read this blog post"
If SplendeoTranslator doesn't find the original key, it will remove a layer of scoping and try again. So if in our Blogs controller +show+ action we want to set a flash[:error] to a permission denied message it can find the string by calling t('errors.permission_denied'). SplendeoTranslator will first look for "blog_posts.show.errors.permission_denied", which doesn't exist. So it will then try to find "blog_posts.errors.permission_denied" and return the correct string. This can be used to create greater levels of scoping, or to force finding global strings (e.g. t("global.app_name")).
== Graceful Locale Fallback
Let's say you've extracted all your English strings, and even had them translated to Spanish to make your Spanish-speaking users extra happy. Then you have a brilliant idea for a new feature that needs to go live before the new pages are translated into Spanish. You still want your Spanish-speaking users to keep seeing the site in Spanish, but for these new pages to fallback to English. (While not exactly ideal, it is better than having "translation missing" messages or not externalizing strings.) To enable this fallback behavior:
I18n.default_locale = :en
SplendeoTranslator.fallback(true)
I18n.locale = :es
t('page_title')
== Key fallback
Let's say that you don't want to have to extract your English strings. You can use them directly as strings for other languages:
SplendeoTranslator.key_fallback(true)
t('My Title in Plain English') will return 'My Title in Plain English' if no translation is found
'My Title in Plain English': "Mi Título en Español"
== Testing Help
SplendeoTranslator.strict_mode will cause an exception to be raised for any missing translations. Enabled by default during testing to help find mistyped or accidently forgotten keys. It can be disabled by calling SplendeoTranslator.strict_mode(false) (in test_helper for example).
assert_translated takes a block and asserts that all lookups within that block have real translations. It is a more targeted version of strict_mode. Example:
assert_translated do # Will assert that all keys find valid translations inside the block get :show end
If you're trying to avoid hard-coding strings in tests, you can still use the lookup that is added to models and controllers:
get :show, :id => 123
assert_match @controller.t('byline', :name => "Mike"), @response.body
Pseudo-translation mode. Pseudo-translation wraps all extracted strings with leading and trailing text so that you can spot if you forgot any. It can be enabled by SplendeoTranslator.pseudo_translate (in an environment file or locale.rb for example). It does not change the lookup process (e.g. t('blog_title')) but will transform the returned string from "My Blog" to "[[ My Blog ]]". The text that is prepended / appended can be set by calling SplendeoTranslator.pseudo_prepend = "@@" (or +append+). Pro Tip: This can also be used to see how a layout will display in a localized language that is longer than the default. or example, German words tend to be significantly longer than their English equivalents. By padding all strings you can test how a layout will adapt and make changes.
Rake task to validate that YAML files are, in fact, valid YAML. Useful when getting back translations from a 3rd party service, this can be a quick way to catch a missing quote. Run like rake i18n:validate_yml and it will check all .yml files below RAILS_ROOT/config/locales.
== Changelog
1.0.0 - 4/17/2009 - Declaring 1.0 after successfully using SplendeoTranslator in production.
Bug reports welcome. {Patches very welcome}[http://github.com/splendeo/SplendeoTranslator].
Copyright (c) 2009 {Mike Champion}[http://splendeo.org], released under the MIT license.
FAQs
Unknown package
We found that splendeo_translator demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.