This is a summary of all of our key learnings from the I18n sprint. I've also added this to our best practices page
Decorators are classes we use to add presentation logic to specific models. They should be instantiated with a single model. An example is the Member Decorator
The MemberDecorator
adds presentation logic to the Member
model, which shouldn't know how to render your friends_gender
, for instance.
Presenters are essentially wrappers around multiple decorators or models which provides more presentation logic that requires more than one model. For instance, if I have a tickets view which has logic around a member, tickets, and pools, I can instantiate a presenter with member, tickets, and pools objects and it deals with any particular presentation that combines these objects.
Here is an example I just added:
The signature view contains logic for formatted_phone_number
which requires knowledge of both the sender and the member. Because multiple objects are required, I can't just place this in a decorator (which only decorates a single object). Instead, a presenter takes both the member and sender, and creates presentation logic based off of both of them.
All of our i18n keys should be namespaced by the view name or model name. In particular, the namespace for keys within decorators and presenters should be the class name minus the design pattern being used.
For example, the full translation key for a member's name within MemberDecorator
should be en.member.name
and not en.memberdecorator.name.
This separates domain knowledge from the design patterns that we use, and makes refactoring much easier.
Lazy translations are automatically provided for you for Views, Controllers, and Decorators (if you subclass from ApplicationDecorator
).
Presenters should include the Translator
module, which does this for you.
Try to name keys off of concepts vs the exact text. For example, "Welcome to Grouper" should have the key welcome_text
, not welcome_to_grouper
. If we want to tweak the translation later, then we won't have to create a new key. See Alex' excellent gist