README.md
# Inline Translation
[![Join the chat at https://gitter.im/gdpelican/inline_translation](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/gdpelican/inline_translation?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
![Codeship](https://codeship.com/projects/50421e60-2297-0133-2512-365560d2eeeb/status?branch=master) [![Code Climate](https://img.shields.io/codeclimate/github/gdpelican/inline_translation.svg)](https://codeclimate.com/github/gdpelican/inline_translation)
`InlineTranslation` is a gem which provides your application with a simple, easy-to-use way to perform inline translations of content, into a variety of languages.
It provides automatic caching (and cache-busting!) mechanisms to ensure you never have to request a translation twice, or serve up a stale translation.
It's written as a wrapper for the fine [bing_translator gem](https://github.com/relrod/bing_translator-gem), but can be easily extended to using other translation services with a little elbow grease.
## Demo
Check out the example app [here](http://inline-translation-test.herokuapp.com)
## Installation
Add this line to your application's Gemfile:
```ruby
gem 'inline_translation'
```
And then execute:
$ bundle
Then, execute the install generator
$ rails g inline_translation:install
And migrate
$ rake db:migrate
Now you're all set up!
## Usage
Inline Translation supplies several helper methods to make your translating life easier.
To mark a field on an object as translatable, simply add
`acts_as_translatable, on: :field_name`
to your model.
#### Additional options
- **load_via** - the class method used to find a record for your model. Defaults to `:find`
- **id_field** - field name for the unique identifier for your model. Defaults to `:id`
- **language_field** - field name for the method / column name on your model to retrieve the language. Defaults to `language`
NB: Oftentimes, you may wish to delegate this method to a user or other object, instead of storing the language on every model.
For example:
```ruby
# model.rb
class Model < ActiveRecord::Base
belongs_to :author, class_name: 'User'
acts_as_translatable on: :column
def language
author.locale
end
end
```
## On the frontend
#### The translation link
InlineTranslation provides a simple helper method for translation links in the view.
For example, adding
```ruby
translate_link_for(@model, to: :fr)
```
Will add an ajax link to create and store a French translation. The `to` field will default to I18n.locale.
###### Additional options
- **text** - The text of the anchor generated. Defaults to 'Translate'
- **to** - The language to translate to with this link. Defaults to I18n.locale
(NB: This link will not appear if `@model.language` is equal to the 'to' parameter, since we cannot perform translations to the same language.)
#### Populating the translation (via UJS)
The simplest possible markup for including translations on callback:
```ruby
# /app/views/models/show.html.erb
<div id="model-1">
<%= translated_element_for @model, :field_a %>
<%= translated_element_for @model, :field_b %>
</div>
```
(Note that this markup can occur anywhere, as long as the `translated_element_for` elements are within a div of the format 'className-id')
If this particular markup structure doesn't work for you for whatever reason, feel free to edit the `app/views/translations/create.js.erb` with javascript to your liking.
###### Additional options
- **element** - The type of element generated. Defaults to 'span'
#### Populating the translation (via JSON)
The `translations#create` action can also accept a `:json` format, which will return a list of serialized translations. These can be consumed by your javascript frontend framework as you see fit.
(TODO: provide more robust support for custom serialization, such as through ActiveModel::Serializers PRs welcome!)
ie, a simplistic implementation in angular:
```html
<!--in the view -->
<a href='' ng-click='translateToFrench()'>Translate</a>
```
```javascript
// in the controller
$scope.translateToFrench = function() {
$http.post('/translations', { translatable_id: 1, translatable_type: 'Model', to: 'fr', format: 'json'}).then(function(data) {
$scope.frenchTranslation = data
})
}
```
## On the backend
InlineTranslation uses the Bing Translator API as a default. For instructions on setting up the Bing Translator API, [go here](https://github.com/relrod/bing_translator-gem#getting-a-client-id-and-secret).
## Different Translators
Simply change the line in `config/initializers/inline_translation.rb` to use whatever translator you desire.
Note that a custom translator must implement the following methods:
- `self.ready?`: Returns true if the translator can translate anything
- `can_translate?`: Returns true the translator can translate the given translatable
- `translate`: Returns a translation for all `acts_as_translatable` fields on the translatable
## Contributing
1. Fork it ( https://github.com/gdpelican/inline_translation/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request