<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The WebDevil &#187; locales</title>
	<atom:link href="http://dmitry.shaposhnik.name/category/locales/feed/" rel="self" type="application/rss+xml" />
	<link>http://dmitry.shaposhnik.name</link>
	<description>Enjoy development</description>
	<lastBuildDate>Mon, 24 May 2010 01:29:18 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Multilingual site on Rails</title>
		<link>http://dmitry.shaposhnik.name/2008/08/29/multilingual-site-on-rails/</link>
		<comments>http://dmitry.shaposhnik.name/2008/08/29/multilingual-site-on-rails/#comments</comments>
		<pubDate>Thu, 28 Aug 2008 22:29:35 +0000</pubDate>
		<dc:creator>dm</dc:creator>
				<category><![CDATA[RoR]]></category>
		<category><![CDATA[locales]]></category>
		<category><![CDATA[webtech]]></category>

		<guid isPermaLink="false">http://dmitry.shaposhnik.name/?p=232</guid>
		<description><![CDATA[Задавался давно уже вопросом о том, как сделать многоязычный сайт на рельсах. Сначала нехватало знаний, потом времени.
Недавно понадобилось таки реализовать такой сайт. Сразу скажу, получилось.

Первым делом задумался над переводом в шаблонах. Благо, тут вариантов было много и я выбрал simple-localization. С рельсами 2.1 работает версия 3.0. Но она ставится экспортом из svn:
cd vendor/plugins
svn co http://svn.arkanis.de/projects/rails_plugins/simple_localization/branches/3.0 [...]]]></description>
			<content:encoded><![CDATA[<p>Задавался давно уже вопросом о том, как сделать многоязычный сайт на рельсах. Сначала нехватало знаний, потом времени.<br />
Недавно понадобилось таки реализовать такой сайт. Сразу скажу, получилось.<br />
<span id="more-232"></span><br />
Первым делом задумался над переводом в шаблонах. Благо, тут вариантов было много и я выбрал <a href="http://simple-localization.arkanis.de/">simple-localization</a>. С рельсами 2.1 работает версия 3.0. Но она ставится экспортом из svn:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">cd</span> vendor<span style="color: #000000; font-weight: bold;">/</span>plugins<br />
<span style="color: #c20cb9; font-weight: bold;">svn</span> <span style="color: #c20cb9; font-weight: bold;">co</span> http:<span style="color: #000000; font-weight: bold;">//</span>svn.arkanis.de<span style="color: #000000; font-weight: bold;">/</span>projects<span style="color: #000000; font-weight: bold;">/</span>rails_plugins<span style="color: #000000; font-weight: bold;">/</span>simple_localization<span style="color: #000000; font-weight: bold;">/</span>branches<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">3.0</span> simple_localization</div></div>
<p>Теперь можно вставлять конструкции <tt>l(:domain, :key)</tt>, которые из файла перевода из раздела <tt>app:</tt> будут брать домен и ключ, указанные в методе. Кстати, я вынес файлы перевода в директорию translations в корень проекта.<br />
Также в перевод я добавил массив с датами в родительном падеже (:declinable_monthnames).<br />
Подключается плагин в config/initializers/simple_localization.rb строками:</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SimpleLocalization.<span style="color:#9900CC;">init</span> <span style="color:#ff3333; font-weight:bold;">:languages</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:ru</span>, <span style="color:#ff3333; font-weight:bold;">:en</span>, <span style="color:#ff3333; font-weight:bold;">:uk</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#ff3333; font-weight:bold;">:lang_file_dir</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;#{RAILS_ROOT}/translations&quot;</span><br />
<br />
<span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#CC00FF; font-weight:bold;">Date</span><br />
&nbsp; silence_warnings <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; &nbsp; DECLINABLE_MONTHNAMES = <span style="color:#6666ff; font-weight:bold;">ArkanisDevelopment::SimpleLocalization::ProxyObject</span>.<span style="color:#9900CC;">new</span> <span style="color:#ff3333; font-weight:bold;">:dates</span>, <span style="color:#ff3333; font-weight:bold;">:declinable_monthnames</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>localized_data<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">+</span> localized_data<br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>Язык я категорически отказался хранить в сессии &#8211; это несерьезно. Так невозможно дать ссылку товарищу и быть уверенным, что он увидит о же что и вы.<br />
В роутах реализовал так:</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#6666ff; font-weight:bold;">ActionController::Routing::Routes</span>.<span style="color:#9900CC;">draw</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>map<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; <br />
&nbsp; map.<span style="color:#9900CC;">with_options</span> <span style="color:#ff3333; font-weight:bold;">:path_prefix</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'/:lang'</span> <span style="color:#9966CC; font-weight:bold;">do</span> &nbsp;<span style="color:#006600; font-weight:bold;">|</span>lang<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; lang.<span style="color:#9900CC;">connect</span> <span style="color:#996600;">'news'</span>, <span style="color:#ff3333; font-weight:bold;">:controller</span><span style="color:#006600; font-weight:bold;">=&gt;</span><span style="color:#996600;">&quot;news&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:action</span><span style="color:#006600; font-weight:bold;">=&gt;</span><span style="color:#996600;">&quot;index&quot;</span><br />
&nbsp; &nbsp; lang.<span style="color:#9900CC;">connect</span> <span style="color:#996600;">'news/:id'</span>, <span style="color:#ff3333; font-weight:bold;">:controller</span><span style="color:#006600; font-weight:bold;">=&gt;</span><span style="color:#996600;">&quot;news&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:action</span><span style="color:#006600; font-weight:bold;">=&gt;</span><span style="color:#996600;">&quot;show&quot;</span><br />
&nbsp; &nbsp; lang.<span style="color:#9900CC;">connect</span> <span style="color:#996600;">''</span>, <span style="color:#ff3333; font-weight:bold;">:controller</span><span style="color:#006600; font-weight:bold;">=&gt;</span><span style="color:#996600;">&quot;pages&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:action</span><span style="color:#006600; font-weight:bold;">=&gt;</span><span style="color:#996600;">&quot;index&quot;</span><br />
&nbsp; &nbsp; lang.<span style="color:#9900CC;">connect</span> <span style="color:#996600;">'feedback'</span>, <span style="color:#ff3333; font-weight:bold;">:controller</span><span style="color:#006600; font-weight:bold;">=&gt;</span><span style="color:#996600;">&quot;pages&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:action</span><span style="color:#006600; font-weight:bold;">=&gt;</span><span style="color:#996600;">&quot;feedback&quot;</span><br />
&nbsp; &nbsp; lang.<span style="color:#9900CC;">connect</span> <span style="color:#996600;">'*link'</span>, <span style="color:#ff3333; font-weight:bold;">:controller</span><span style="color:#006600; font-weight:bold;">=&gt;</span><span style="color:#996600;">&quot;pages&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:action</span><span style="color:#006600; font-weight:bold;">=&gt;</span><span style="color:#996600;">&quot;show&quot;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
&nbsp; map.<span style="color:#9900CC;">root</span> <span style="color:#ff3333; font-weight:bold;">:controller</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;pages&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:action</span><span style="color:#006600; font-weight:bold;">=&gt;</span><span style="color:#996600;">&quot;index&quot;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>В app/controllers/application.rb добавил парочку методов и фильтр:</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#9966CC; font-weight:bold;">class</span> ApplicationController <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActionController::Base</span><br />
&nbsp; &nbsp; before_filter <span style="color:#ff3333; font-weight:bold;">:localize</span><br />
&nbsp; &nbsp; ...<br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> localize<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> params <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:lang</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> Localization.<span style="color:#9900CC;">loaded_languages</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:lang</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">to_sym</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Localization.<span style="color:#9900CC;">use</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:lang</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">to_sym</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
&nbsp; &nbsp; <span style="color:#008000; font-style:italic;">#it can accept only URL_FOR :(</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> localized_redirect<span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; url = <span style="color:#996600;">''</span> <span style="color:#9966CC; font-weight:bold;">if</span> url==<span style="color:#996600;">'/'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; redirect_to <span style="color:#996600;">&quot;/#{Localization.used.to_s}/#{url}&quot;</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>Тут я задумался как работать с урлами. Ведь они же будут на корень ссылаться.<br />
Так в config/initializers/simple_localization.rb был добавлен еще кусок кода, в котором переопределялись основные хелперы:</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#9966CC; font-weight:bold;">module</span> ActionView<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">module</span> Helpers<br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">module</span> UrlHelper<br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> url_for<span style="color:#006600; font-weight:bold;">&#40;</span>options = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">case</span> options<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#CC00FF; font-weight:bold;">Hash</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; show_path = &nbsp;options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:host</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>? ? <span style="color:#0000FF; font-weight:bold;">true</span> : <span style="color:#0000FF; font-weight:bold;">false</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; options = <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:only_path</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> show_path <span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">update</span><span style="color:#006600; font-weight:bold;">&#40;</span>options.<span style="color:#9900CC;">symbolize_keys</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; escape &nbsp;= options.<span style="color:#9900CC;">key</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:escape</span><span style="color:#006600; font-weight:bold;">&#41;</span> ? options.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:escape</span><span style="color:#006600; font-weight:bold;">&#41;</span> : <span style="color:#0000FF; font-weight:bold;">true</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; url &nbsp; &nbsp; = <span style="color:#0066ff; font-weight:bold;">@controller</span>.<span style="color:#9900CC;">send</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:url_for</span>, options<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#CC0066; font-weight:bold;">String</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; escape = <span style="color:#0000FF; font-weight:bold;">true</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; url &nbsp; &nbsp;= options<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#CC00FF; font-weight:bold;">NilClass</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; url = <span style="color:#0066ff; font-weight:bold;">@controller</span>.<span style="color:#9900CC;">send</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:url_for</span>, <span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; escape = <span style="color:#0000FF; font-weight:bold;">false</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; url &nbsp; &nbsp;= polymorphic_path<span style="color:#006600; font-weight:bold;">&#40;</span>options<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; url = escape ? escape_once<span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span> : url<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> url =~ <span style="color:#006600; font-weight:bold;">/</span>\<span style="color:#006600; font-weight:bold;">/</span>.<span style="color:#006600; font-weight:bold;">+/</span> <span style="color:#9966CC; font-weight:bold;">and</span> url !~ <span style="color:#006600; font-weight:bold;">/</span>^\<span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#008000; font-style:italic;">#{Localization.loaded_languages.join('|')})(\/.+)?$/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; url = <span style="color:#996600;">&quot;/#{Localization.used.to_s}#{url}&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; url<br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> link_to<span style="color:#006600; font-weight:bold;">&#40;</span>name, options = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>, html_options = <span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; url = <span style="color:#9966CC; font-weight:bold;">case</span> options<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#CC0066; font-weight:bold;">String</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">url_for</span> options<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#ff3333; font-weight:bold;">:back</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0066ff; font-weight:bold;">@controller</span>.<span style="color:#9900CC;">request</span>.<span style="color:#9900CC;">env</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;HTTP_REFERER&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">||</span> <span style="color:#996600;">'javascript:history.back()'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">url_for</span><span style="color:#006600; font-weight:bold;">&#40;</span>options<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> html_options<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; html_options = html_options.<span style="color:#9900CC;">stringify_keys</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; href = html_options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'href'</span><span style="color:#006600; font-weight:bold;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; convert_options_to_javascript!<span style="color:#006600; font-weight:bold;">&#40;</span>html_options, url<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tag_options = tag_options<span style="color:#006600; font-weight:bold;">&#40;</span>html_options<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tag_options = <span style="color:#0000FF; font-weight:bold;">nil</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; href_attr = <span style="color:#996600;">&quot;href=<span style="color:#000099;">\&quot;</span>#{url}<span style="color:#000099;">\&quot;</span>&quot;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> href<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#996600;">&quot;&lt;a #{href_attr}#{tag_options}&gt;#{name || url}&lt;/a&gt;&quot;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>Я знаю что это жутко некрасиво, но я не знаю как изменить в методе всего одну строку. Можно было создать свой хелпер, но хотелось переопределить существующие, чтобы все было по возможности прозрачно.</p>
<p>Теперь дело дошло и до хранения локализованого контента в БД. Вот как у меня устроена таблица Pages:</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#9966CC; font-weight:bold;">class</span> CreatePages <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Migration</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">up</span><br />
&nbsp; &nbsp; create_table <span style="color:#ff3333; font-weight:bold;">:pages</span>, <span style="color:#ff3333; font-weight:bold;">:force</span><span style="color:#006600; font-weight:bold;">=&gt;</span>true <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>t<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; &nbsp; t.<span style="color:#CC0066; font-weight:bold;">string</span> <span style="color:#ff3333; font-weight:bold;">:lang</span>, <span style="color:#ff3333; font-weight:bold;">:title</span>, <span style="color:#ff3333; font-weight:bold;">:link</span>, <span style="color:#ff3333; font-weight:bold;">:null</span><span style="color:#006600; font-weight:bold;">=&gt;</span>false<br />
&nbsp; &nbsp; &nbsp; t.<span style="color:#9900CC;">text</span> <span style="color:#ff3333; font-weight:bold;">:body</span><br />
&nbsp; &nbsp; &nbsp; t.<span style="color:#9900CC;">boolean</span> <span style="color:#ff3333; font-weight:bold;">:textilize</span>, <span style="color:#ff3333; font-weight:bold;">:default</span><span style="color:#006600; font-weight:bold;">=&gt;</span><span style="color:#006666;">1</span>, <span style="color:#ff3333; font-weight:bold;">:null</span><span style="color:#006600; font-weight:bold;">=&gt;</span>false<br />
&nbsp; &nbsp; &nbsp; t.<span style="color:#9900CC;">timestamps</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; add_index <span style="color:#ff3333; font-weight:bold;">:pages</span>, <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:link</span>, <span style="color:#ff3333; font-weight:bold;">:lang</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#ff3333; font-weight:bold;">:unique</span><span style="color:#006600; font-weight:bold;">=&gt;</span>true<br />
&nbsp; &nbsp; add_index <span style="color:#ff3333; font-weight:bold;">:pages</span>, <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:link</span><span style="color:#006600; font-weight:bold;">&#93;</span><br />
&nbsp; &nbsp; <br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">down</span><br />
&nbsp; &nbsp; drop_table <span style="color:#ff3333; font-weight:bold;">:pages</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>а в app/models/page.rb имеем следующее:</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#9966CC; font-weight:bold;">class</span> Page <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span><br />
&nbsp; named_scope <span style="color:#ff3333; font-weight:bold;">:localized</span>, <span style="color:#ff3333; font-weight:bold;">:conditions</span><span style="color:#006600; font-weight:bold;">=&gt;</span><span style="color:#006600; font-weight:bold;">&#123;</span>:lang<span style="color:#006600; font-weight:bold;">=&gt;</span>Localization.<span style="color:#9900CC;">used</span>.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#125;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>Так можно оперировать локализоваными страницами как Page.localized.</p>
<p>Вроде бы из интересного все, остальное рутина. Если у кого есть советы как что дополнить/измениь &#8211; с радостью выслушаю.</p>
]]></content:encoded>
			<wfw:commentRss>http://dmitry.shaposhnik.name/2008/08/29/multilingual-site-on-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>locales</title>
		<link>http://dmitry.shaposhnik.name/2007/08/07/locales/</link>
		<comments>http://dmitry.shaposhnik.name/2007/08/07/locales/#comments</comments>
		<pubDate>Tue, 07 Aug 2007 15:52:57 +0000</pubDate>
		<dc:creator>dm</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[locales]]></category>

		<guid isPermaLink="false">http://0804team.kiev.ua/dm/blog/2007/08/07/locales/</guid>
		<description><![CDATA[Сайт работает в cp1251. Не моя прихоть, так сложилось.
И вот в него вкручивается gettext. Все было бы неплохо, только из трех языков ru, en, uk &#8211; для последнего отсутствует локаль uk_UA.cp1251.
Я пол-дня мучался, пока добрый Rubik не направил в сторону localedef.
Итак, вот что вышло:
sudo localedef -f CP1251 -i en_US en_US.cp1251
sudo localedef -f CP1251 -i uk_UA [...]]]></description>
			<content:encoded><![CDATA[<p>Сайт работает в cp1251. Не моя прихоть, так сложилось.</p>
<p>И вот в него вкручивается gettext. Все было бы неплохо, только из трех языков ru, en, uk &#8211; для последнего отсутствует локаль uk_UA.cp1251.</p>
<p>Я пол-дня мучался, пока добрый Rubik не направил в сторону localedef.</p>
<p>Итак, вот что вышло:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">sudo</span> localedef <span style="color: #660033;">-f</span> CP1251 <span style="color: #660033;">-i</span> en_US en_US.cp1251<br />
<span style="color: #c20cb9; font-weight: bold;">sudo</span> localedef <span style="color: #660033;">-f</span> CP1251 <span style="color: #660033;">-i</span> uk_UA uk_UA.cp1251</div></div>
<p>и локали появились. Теперь сайт спокойно использует их, а вместе с ним и gettext заработал.</p>
]]></content:encoded>
			<wfw:commentRss>http://dmitry.shaposhnik.name/2007/08/07/locales/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>gettext and cyrillic</title>
		<link>http://dmitry.shaposhnik.name/2007/08/07/gettext-and-cyrillic/</link>
		<comments>http://dmitry.shaposhnik.name/2007/08/07/gettext-and-cyrillic/#comments</comments>
		<pubDate>Tue, 07 Aug 2007 14:24:44 +0000</pubDate>
		<dc:creator>dm</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[locales]]></category>

		<guid isPermaLink="false">http://0804team.kiev.ua/dm/blog/2007/08/07/gettext-and-cyrillic/</guid>
		<description><![CDATA[Возникла задача &#8211; подружить gettext и кириллицу. Да к тому же еще и кириллицу в cp1251. И, что самое главное, оригинальные строки для перевода в кириллице.
Попробовав Zend_Translate ощутил несоответствие идее:
&#60;?php
require_once&#40;&#34;Zend/Translate.php&#34;&#41;;

$translate = new Zend_Translate&#40;'gettext', '/my/path/source-de.mo', 'de'&#41;;

print $translate-&#62;_&#40;&#34;Example&#34;&#41;.&#34;\n&#34;;
Вот что должно произойти если нет /my/path/source-de.mo? Правильно, должно отобразиться &#8220;Example&#8221;. На самом же деле отображаются матюки об отсутствии .mo. [...]]]></description>
			<content:encoded><![CDATA[<p>Возникла задача &#8211; подружить gettext и кириллицу. Да к тому же еще и кириллицу в cp1251. И, что самое главное, оригинальные строки для перевода в кириллице.</p>
<p>Попробовав Zend_Translate ощутил несоответствие идее:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Zend/Translate.php&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000088;">$translate</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Translate<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'gettext'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'/my/path/source-de.mo'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'de'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #b1b100;">print</span> <span style="color: #000088;">$translate</span><span style="color: #339933;">-&gt;</span>_<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Example&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span></div></div>
<p>Вот что должно произойти если нет /my/path/source-de.mo? Правильно, должно отобразиться &#8220;Example&#8221;. На самом же деле отображаются матюки об отсутствии .mo. Что есть неправильно.</p>
<p>Кроме того Zend_Translate не предоставляет никаких возможностей по работе с кодировками.</p>
<p>Хоть я и приверженец ZF, но тут он меня сильно разочаровал.</p>
<p>Так я вернулся к стандартному подходу, несколько доправив его. Итак, вот что получилось:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">locale <span style="color: #660033;">-a</span></div></div>
<p>убедился что есть локаль ru_RU.cp1251 на сервере. В убунте если она отсутствует ее можно создать так:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">sudo</span> locale-gen ru_RU.CP1251</div></div>
<p>Отлично. Теперь очередь php:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #000088;">$language</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'ru_RU.cp1251'</span><span style="color: #339933;">;</span><br />
<a href="http://www.php.net/putenv"><span style="color: #990000;">putenv</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;LANG=<span style="color: #006699; font-weight: bold;">$language</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<a href="http://www.php.net/setlocale"><span style="color: #990000;">setlocale</span></a><span style="color: #009900;">&#40;</span>LC_ALL<span style="color: #339933;">,</span> <span style="color: #000088;">$language</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000088;">$domain</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'messages'</span><span style="color: #339933;">;</span><br />
<a href="http://www.php.net/bindtextdomain"><span style="color: #990000;">bindtextdomain</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$domain</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;./locale&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<a href="http://www.php.net/bind_textdomain_codeset"><span style="color: #990000;">bind_textdomain_codeset</span></a> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$domain</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'cp1251'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<a href="http://www.php.net/textdomain"><span style="color: #990000;">textdomain</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$domain</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #b1b100;">echo</span> <a href="http://www.php.net/gettext"><span style="color: #990000;">gettext</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;мегастрока&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></div>
<p>По сравнению со стандартным примером тут появилась такая строка:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://www.php.net/bind_textdomain_codeset"><span style="color: #990000;">bind_textdomain_codeset</span></a> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$domain</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'cp1251'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>Это говорит, что все строки будут нам возвращаться в cp1251.</p>
<p>Далее мы выдираем на сервере все строки для перевода:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">xgettext .<span style="color: #000000; font-weight: bold;">/*</span>.php <span style="color: #660033;">--from-code</span>=cp1251</div></div>
<p>с указанием кодировки, в которой текст внутри, потому что по умолчанию gettext считает, что там ASCII.</p>
<p>Теперь внутри файла messages.po все лежит в UTF-8, и никаких проблем&#8230; если бы не cp1251, черт подери.</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">iconv <span style="color: #660033;">-f</span> utf-<span style="color: #000000;">8</span> <span style="color: #660033;">-t</span> cp1251 .<span style="color: #000000; font-weight: bold;">/</span>messages.po <span style="color: #000000; font-weight: bold;">&gt;</span> messages.po1251</div></div>
<p>Вот так мы конвертаем его в cp1251. Полученый файл редактируем, добавляя перевод, и кроме того заменяем в нем строку:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&quot;Content-Type: text/plain; charset=UTF-8\n&quot;</div></div>
<p>на</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&quot;Content-Type: text/plain; charset=CP1251\n&quot;</div></div>
<p>Теперь переименовываем файл messages.po1251 и убираем из его имени 1251, затем делаем</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">msgfmt</span> messages.po</div></div>
<p>и так получаем скомпилированый перевод. Который теперь работает <img src='http://dmitry.shaposhnik.name/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  Наконец-то.</p>
<p>А вообще русские строки в качестве ключей работают чудесно и без такого шаманства если они в UTF8.</p>
]]></content:encoded>
			<wfw:commentRss>http://dmitry.shaposhnik.name/2007/08/07/gettext-and-cyrillic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
