Modelos localizados com guiador / bigode

Atualmente estou usando a combinação AngularJS + JADE em quase todos os meus projetos, mas antes disso eu me divertia muito com o Backbone / Backbone Marionette.

Algum tempo atrás, um de nossos clientes decidiu localizar um aplicativo da web inteiro que já continha uma base de código de front end bastante grande, modelos do lado do cliente e Backbone / Marionette , Handlebars , require.js sob o capô.

Ao mesmo tempo, estávamos lançando uma nova versão do aplicativo e não queríamos refatorar quase tudo, em outras palavras – queríamos minimizar o impacto de outro novo recurso, ainda assim – queríamos manter as coisas limpas, simples e de fácil manutenção.

Essa é a solução que eu encontrei. Espero que você ache útil.

Ferramentas

Decidi usar o plugin i18n para require.js

Aula de tradutor

Eu criei uma classe CoffeeScript que retorna um método compile () para a versão de linguagem atualmente selecionada:

# file: modules/localized-template.coffee
define
(require)->
_
= require 'lodash'
Handlebars = require 'handlebars'

LocalizedTemplate = (dict, tpl) ->
(model)->
dictModel
=
i18n
: dict
params = _.extend {}, model, dictModel
rendered
= Handlebars.compile tpl
rendered
params

Graças ao _.extendmétodo, somos capazes de preservar todas as strings / dados do modelo de visualização criados no controlador de visualização e substituir apenas as strings necessárias.

Visão

# file: modules/view-name/view-controller-name.coffee
define
(require)->
require 'jquery'
require 'backbone'
require 'Backbone.Marionette'
Handlebars = require 'handlebars'

VideoView = require './video'
StreamTemplate = require 'text!./tpl/stream.tpl'

# most important part:
LocalizedTemplate = require 'cs!modules/localized-template'

i18n
=
ui
: require 'i18n!nls/ui'

StreamView = VideoView.extend
# here we swap Handlebars.compile method:
template : LocalizedTemplate i18n, StreamTemplate
tagName
: 'li'
StreamView

Modelo

Isso é muito simples: colocamos strings localizadas sob i18n.ui.variableName.

# file: modules/view-name/tpl/stream.tpl
<div class="icon">
<img width="240" height="135" src="{{#if posterUrl}}{{{posterUrl}}}{{else}}/img/video-list/not-found.png{{/if}}" alt="{{title}}">
<div class="labels">
<span class="language">{{language.label}}</span>
<div class="specializations">
{{#each specializations}}
<span class="specialization">{{name}}</span>
{{/each}}
</div>
</div>
</div>
<div class="description">
<div class="title">{{title}}</div>
<div class="author">{{author}}</div>
<div class="affiliation">{{affiliation}}</div>
<div class="labels">
<span class="date">{{parsedStartTime}}</span>
<button class="subscribe">{{i18n.ui.subscribe}}</button>
</div>
</div>

É importante não poluir o escopo do modelo “global”. E se houvesse uma variável localizada chamada specializations = "Specialisierung"? Nesse caso, ele seria substituído pelo array retirado do JSON. Isso é simplesmente mau .

Strings localizadas

Eu implementei de acordo com a documentação oficial .