Skip to content

Latest commit

 

History

History
167 lines (117 loc) · 4.11 KB

README.md

File metadata and controls

167 lines (117 loc) · 4.11 KB

Groobalize

Build Status

Internacionalization plugin for grails inspired by Globalize

Installation

Add dependency to your BuildConfig;

compile "com.ticketbis:groobalize:0.2.3"

Usage

Simple usage example for a book with translateable title:

// grails-app/domain
import com.ticketbis.groobalize.ast.Translatable

@Translatable(with = BookTranslation)
class Book {

    String author
    Date releaseDate
    Book inspiredBy

    static hasMany = [
        related: Book
    ]

    static mapping = { }
    static constraints = { }
    static namedQueries = { }
}
// grails-app/domain
import com.ticketbis.groobalize.Translation

class BookTranslation extends Translation<Book> {
    @Field(inherit=false)
    String title

    String synopsis = null // Inherit from parent locale

    static constraints = {
        synopsis(nullable: true)
    }
}
def book = new Book(author: "Endika", releaseDate: new Date())

book.addToTranslations(title: "english title", synopsis: "synopsis in english", locale: new Locale('en'))
book.addToTranslations(title: "american english title", locale: new Locale('en', 'US'))
book.addToTranslations(title: "british english title", locale: new Locale('en', 'GB'))

book.title // => american english title
book.synopsis // => synopsis in english

import org.springframework.context.i18n.LocaleContextHolder as LCH
LCH.locale = new Locale('en', 'AU')

book.title // => null // Title set as no-inheritable field
book.synopsis // => synopsis in english

Accessing properties

There are some custom proxy getters for properties in translatable classes.

book.title  // or book.getTitle() => Gets field for the current locale
            // context (LocaleContextHolder).

book.getTitle(localeContext) // Retrives property for the given locale context.

book.getTitle { locale } // Builds a LocaleContext based on the given closure.

Accessing translation objects

Translation acts like a regular domain class in Grails that is belonged to the translatable class.

book.getTranslations() // => returns queried translations

book.getTranslation(Locale.US) // => returns US translation if exists

Customizing fallbacks

Groobalize also includes a WithFallbackLocaleContext that supports custom fallback.

import com.ticketbis.groobalize.WithFallbackLocaleContext

LCH.localeContext = new WithFallbackLocaleContext([new Locale('en', 'AU'),
        new Locale('en', 'GB'), new Locale('en')])

book.title // => null
book.synopsis // => synopsis in english

Eagerly fetch translations

def books = Book.includeTranslations([new Locale('en', 'US'), new Locale('en')]).list()

books*.translations*.locale // => [[en, en_US], [en, en_US], [en_US, en]]

This will fetch books with given translations in 1 query.

It's also supported on Criterias:

// Fetch book with current translation
def books = Book.translated().list()

// Fetch book with all translation
def books = Book.includeTranslation().list()

books = Book.createCriteria().list {
    // Fetch all translations
    fetchTranslations()
    // Fetch current locale for inspiredBy
    withDefaultTranslations('inspiredBy')
    // Fetch english translations for related
    withTranslations('related', [new Locale('en')])
}
// No more queries from here 🎉
books.each {
    println([it.title, it.translations*.locale, it.inspiredBy?.translations*.title].join("\t"))
}

Customizing behaviour of translatable fields

import com.ticketbis.groobalize.Translation
import com.ticketbis.groobalize.ast.Field

class BookTranslation extends Translation<Book> {
    String title

    @Field(inherit=false)
    String synopsis
}

Supported options are:

  • inherit: when this option is set to false, proxy getter only look for translations that match exactly with first option of LocaleContext
  • skipGetter: when this option is set to true, the proxy getter is not added to domain class