These are my thoughts, on how the translation files should be modeled, take into consideration the following postulates:
- Web applications are modeled around their data.
- Web applications data models have the following states.
- Saved
- Deleted
- Updated
- Empty
- Created
- Loading
- CRUD Operations
- Copy Should be consistent
- They are plural
- They are singular
- Forms and table headers can share the same copy.
- All models forms have
- placeholders
- hints
In order to have scalable, maintainable and clean translation files we should, model them according to their data models.
This means:
- Every model should have it's name translated in singular and plural,
- Every attribute should have a translation 1 to 1 relationship.
Model names could share the same namespace as attributes, but that could cause conflicts, so we would rather keep them seperate.
Take the following application models:
Model = Ember.Data.Model.extend({
name: DS.string(),
age: DS.number(),
})
Model = Ember.Data.Model.extend({
surname: DS.date(),
age: DS.number(),
})
The resultant translation file would look as follows:
modelNames:{
patient:{
one: 'patient'
other: 'patients
},
inventory:{
one: 'inventory'
other: 'inventory items'
}
}
models: {
patient: {
labels: {
default: {
firstName: 'First Name',
lastName: 'Last Name'
},
edit: {
firstName: 'Change First Name',
lastName: 'Change Last Name'
},
new: {
firstName: 'Set your first name',
lastName: 'Set your Last Name'
}
},
placeholders: {
firstName: 'Enter your first bame',
lastName: 'Enter your first last Name'
},
hints: {
firstName: 'This is the name that your parents gave you, unless you changed it',
lastName: 'this is the name you share with your family, , unless you changed it'
}
},
inventory: {
labels: {
default: {
name: 'Name',
quantity: 'Quantity'
},
edit: {
quantity: 'How many are there now'
},
},
placeholders: {
name: 'Name of inventory item',
quantity: 'Quantity of item'
},
hints: {
name: 'What do you call',
quantity: 'Go to storage and count :)'
}
}
}
Here is an example of crud operation message translations:
en: {
messages: {
empty: {
one: "no {{objects}} were found
},
loading: {
success: {
one: 'Successfully loaded {{object}}',
other: 'Successfully loaded {{count}} {{object}}'
},
error: {
one: 'oops, something happend when loading {{object}}',
other: 'Loading {{count}} {{object}}'
},
delete: {
success: {
one: '{{object}} Successfully deleted',
other: '{{count}} {{object}} have been successfully deleted'
},
error: {
one: 'Something went wrong deleting {{object}}',
other: 'Something went wrong deleting these records {{object}}'
},
confirmation: {
one: 'Are you sure you wish to delete this {{object}}?'
other: 'Are you sure you wish to delete {{object}}?'
}
},
save: {
success: {
one: '{{object}} Successfully saved'
other: '{{object}} have been Successfully saved'
},
error: {
one: 'Something went wrong saving {{object}}'
other: 'Something went wrong saving these records {{object}}'
}
},
update: {
success: {
one: '{{object}} Successfully updated'
other: '{{object}} have been Successfully updated'
},
error: {
one: 'Something went wrong updating {{object}}'
other: 'Something went wrong updating these records {{object}}'
}
},
}
}
Since the translations are now organised, it is easy to generated localised forms, or build helpers for CRUD operation copy
here is an example helper for crud operations
{{translate-message "messages.delete_singular" object=(t "model.lab._one")}}
or a more magical one
{{translate-message "messages.delete" model="lab" count=1}} // displays plural delete
{{translate-message "messages.delete" model="lab" count=2}} // displays plural save
inputs can be wrapped in a {{translated-input}}
wrapper
{{translated-input model='invoice' property="price" class="required pricing-override-price"}}
Forms and list labels can share the same copy. <- Are list labels table headers?