Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

translate_columns

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

translate_columns

  • 1.2.1
  • Rubygems
  • Socket score

Version published
Maintainers
1
Created
Source

= Translate Columns Plugin

Copyright (c) 2007-2013 Samuel Lown <me (AT) samlown.com>

This Plugin is released under the MIT license, as Rails itself. Please see the attached LICENSE file for further details.

This document and plugin should be considered a work in progress until further notice!

== Introduction

The aim of the Translate Columns plugin is to aid the normally difficult task of supporting multiple languages in the models. It provides a near transparent interface to the data contained in the models and their translations such that your current controllers, views and models only need to be modified slightly to support multiple languages in a scalable fashion.

If you already have your rails app set up and functioning, using translate columns will not require any major refactoring of your code (unless you're really unlucky), and can be simply added. Indeed, the plugin was written to be added to an existing application.

== Updates

=== v1.2 - 12th March 2013

  • Updated to support Rails 3.2.12. Please hold back if you are not running this version of Rails. Thanks Matthias Frick (@mattherick)

=== v1.1 - 21st January 2011

  • Now only supports ActiveRecord 3
  • Converted to gem
  • +include TranslateColumns+ now required on a per model basis

=== 24th September 2009

  • Added support for setting the locale variable on the parent, which disables translations. See below.

=== 23rd September 2009

  • Testing finally added (hope to add more tests soon)
  • Validations now only performed by the parent model
  • Changed namespace to TranslateColumns (as opposed to Translate::Columns)
  • Parent model's +locale+ variable changed to +translation_locale+ so that it can be added as a column/attribute if needed.

=== 20th May 2009

  • Finally got round to moving to github
  • Added support for the rails 2.2 I18n stuff (WIN!)

WARNING Translate Columns will now only work with Rails 3 as a gem. For older 2.3 projects, use as a plugin with the v_1.0 release tag.

== Architecture

Translate columns while simple, does require a specific architecture. The basic idea is that each of your models has an associated model that defines the translations. An ASCII ERM that uses an example primary class called document follows:


| | 1 * | | | Document |---------------| DocumentTranslation | |________| |___________________|

The data contained by these entities may be similar to the following:

Document:

| Column | Type |

| id | integer | | name | string | | title | string | | sub_title | string | | body | text | | created_on | datetime | | updated_on | datetime |

DocumentTranslation:

| Column | Type |

| id | integer | | document_id | integer | | locale | string |
| title | string | | sub_title | string | | body | text |

In Rails, thsee models would be defined as follows:

class Document < ActiveRecord::Base has_many :translations, :class_name => 'DocumentTranslation' end

class DocumentTranslation < ActiveRecord::Base belongs_to :document end

Each DocumentTranslation belongs to a Document and defines the locale of the translation and only those fields that require a translation. If you really wanted to, a composite key could be used on the document_id and the locale, as these should always uniquely identify the translation.

In previous versions of translate_columns a Locale model and associations was used to determine the language of a translation, this is no longer required with the new Rails 2.2 I18n code and simple string for the locale code of your choice can be used instead.

IMPORTANT: Default locale. In order for this setup to work, there must be a single, pre-defined locale for the default data, this is the data contained in the 'Document' entity and will be used whenever we're operating in default mode, or if there is no translation available. It is essential that this default locale never change during the lifetime of your application, otherwise you'll end up with a mess.

The Document's translations association uses the :class_name option to name the correct class. Aside from saving on typing, this is an essential requirement of the translate_columns plugin. (At least until I get chance to add an option to allow for different names.)

== Installation

Assuming you've read the above and understand the basic requirements, the plugin can now be installed and setup.

The latest details and updates are available on the github repository:

http://github.com/samlown/translate_columns

To install plugin, use the standard rails plugin install method:

./script/plugin install git://github.com/samlown/translate_columns.git

There are no more installation steps, and the plugin does not install any extra files or customise the setup. To uninstall, simply remove the directory.

== Setup

Now for the hard part :-) Re-using the example above for documents, to use the plugin modify the model so that it looks like the following:

class Document < ActiveRecord::Base include TranslateColumns has_many :translations, :class_name => 'DocumentTranslation' translate_columns :title, :sub_title, :body end

I'm working on getting it so that you don't need to specify the columns manually, but it is not yet ready.

In earlier versions you'd need to mess around with a Locale class but thanks to the Rails I18n extension, this is no longer necessary.

== Upgrading

If you're using a realy old version of Translate Columns, then you'll need to perform an upgrade and migration to use the fabulous new I18n Rails code. Fortunately, this is very easy to do.

To upgrade, remove and previous entries to your Locale class in you translation models and generate a migration to convert the local_id column into a string. Something like the following will surfice.

class UpgradeTranslationModels < ActiveRecord::Migration def self.up alter_column :product_translations, :locale_id, :string, :length => 10 rename_column :product_translations, :locale_id, :locale end

def self.down rename_column :product_translations, :locale, :locale_id alter_column :product_translations, :locale_id, :integer end end

After ensuring you're using the I18n.locale calls throughout your application, it should work fine.

== Usage

The idea here is that you forget about the fact your models can be translated and just use the app as normal. Indeed, if you don't set a locale, you won't even notice the plugin is there.

Here's a really basic example of what we can do on the console.

I18n.locale = I18n.default_locale # First try default language => :en doc = Document.find(:first) -- output hidden -- doc.title => "Sample Document" # title in english I18n.locale = 'es' # set to other language => "es" doc = Document.find(:first) # Reload to avoid caching problems! -- output hidden -- doc.title => "Titulo español" # Title now in spanish doc.title_default => "Sample Document" # original field data doc.title = "Nuevo Título Español" => "Nuevo Título Español" doc.save # set the title and save => true I18n.locale = 'en' => "en" # return to english doc = Document.find(:first) -- output hidden -- doc.title => "Sample Document"

As can be seen, just by setting the locale we are able to edit the data without having to worry about the details.

The current version also has support for disabling translations by giving the parent object a +locale+ field and setting it to something. This is actually a very powerful feature as it allows new objects to be created under a specific locale and filtered as such. A typical example would be a blog where most of the posts you'd like to be translated into several languages, but occaisionly some posts will only be relevant for a specific region:

I18n.locale = I18n.default_locale post = Post.new(:title => "Example") # WIN

I18n.locale = 'es' post = Post.new(:title => "Ejemplo") # FAIL TranslateColumns::MissingParent: Cannot create translations without a stored parent

post = Post.new(:locale => 'es', :title => "Ejemplo") # WIN

Provide posts, with either a translation of for the current locale

posts = Post.paginate(:conditions => ['posts.locale IS NULL OR posts.locale = ?', I18n.locale.to_s])

A useful +named_scope+ could be as follows:

class Post < ActiveRecord::Base

... translate columns stuff ...

named_scope :for_current_locale, :conditions => ['posts.locale IS NULL OR posts.locale = ?', I18n.locale.to_s] end

@posts = Post.for_current_locale.paginate

Changing locale of an object after it has been created will cause its translations to be ignored, but by emptying the locale value the translations should work as before. Of course, if you don't want this funcionality simply do not add a locale attribute or method to the parent model.

== How it works

The plugin overrides the default attribute accessor functions and automatically uses the 'translations' association to find the request fields. It also provides a new method that extends the original method name to access the original values.

== Todos / Bugs

  • Caching - Using a basic rails setup, everything should work fine, however if you have a more complex caching setup strange things might happen. Please mail me if you have any problems!

FAQs

Package last updated on 12 Mar 2013

Did you know?

Socket

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.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc