<?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; RoR</title>
	<atom:link href="http://dmitry.shaposhnik.name/category/ror/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>Bzr rocks</title>
		<link>http://dmitry.shaposhnik.name/2008/07/02/bzr-rocks/</link>
		<comments>http://dmitry.shaposhnik.name/2008/07/02/bzr-rocks/#comments</comments>
		<pubDate>Wed, 02 Jul 2008 04:12:59 +0000</pubDate>
		<dc:creator>dm</dc:creator>
				<category><![CDATA[RoR]]></category>
		<category><![CDATA[bzr]]></category>

		<guid isPermaLink="false">http://dmitry.shaposhnik.name/?p=181</guid>
		<description><![CDATA[С первого знакомства мне очень понравился bazaar-ng. И вот почему.
Он нацелен на usability. И это видно сразу. Вот наверняка многие пользовались TortoiseSVN. Там все делается просто, легко и удобно, правда? А вот теперь пойдем в консоль удаленного сервера. И добавим маски для игнорирования файлов (логи, темпы, кеши всякие). А теперь еще добавим в репозитарий те [...]]]></description>
			<content:encoded><![CDATA[<p>С первого знакомства мне очень понравился <a href="http://bazaar-vcs.org/">bazaar-ng</a>. И вот почему.</p>
<p>Он нацелен на usability. И это видно сразу. Вот наверняка многие пользовались TortoiseSVN. Там все делается просто, легко и удобно, правда? А вот теперь пойдем в консоль удаленного сервера. И добавим маски для игнорирования файлов (логи, темпы, кеши всякие). А теперь еще добавим в репозитарий те два десятка сорсов в разных папках, которые написали/докопировали в проект.<br />
Все svn это не проблематично, но несколько неудобно. В bzr же все это делается легким движением руки &#8211; правим .bzrignore в корне проекта добавляя маски, потом жмем bzr add &#038;&#038; bzr commit.</p>
<p>Bzr ориентирован на <a href="http://doc.bazaar-vcs.org/bzr.dev/en/user-guide/index.html#branch">ветки</a>. И у меня получается ветка == проект. Я выгружаю себе его целиком. В результате в каждой папке нету папок .svn, есть лишь одна папка .bzr в корне проекта. Мне очень редко требовалось делать чекаут определенной папки из проекта. </p>
<p>Проект часто требуется обновить до того, что живет в репозитории. Bzr имеет т.н. <a href="http://doc.bazaar-vcs.org/bzr.dev/en/user-guide/index.html#getting-a-lightweight-checkout">легковесные чекауты</a>, которые не содержат подробной истории изменений. Как-раз то, что чаще всего нужно на рабочем сервере.</p>
<p>Также весьма порадовала только-что сложившаяся ситуация: я делал commit, и внезапно пропал линк. bzr стоял и терпеливо ждал, пока я ребутнул модем. Как только пинги появились, он все быстро завершил. Ни обрывов, ни страшных ругательств небыло.</p>
<p>Что касается скорости работы &#8211; она вполне приемлема. Да, есть системы и быстрее, но bzr меня вполне устраивает. Кроме того, мне абсолютно неважно, будет коммит выполняться 5 или 10 секунд, или даже 20 &#8211; я же не собираюсь безостановочно коммитить.</p>
<p>Навеяно <a href="http://www.html-blog.ru/2008/6/6/git">впечатлениями о Git.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://dmitry.shaposhnik.name/2008/07/02/bzr-rocks/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Railsforum.ru</title>
		<link>http://dmitry.shaposhnik.name/2008/01/18/railsforumru/</link>
		<comments>http://dmitry.shaposhnik.name/2008/01/18/railsforumru/#comments</comments>
		<pubDate>Thu, 17 Jan 2008 23:24:17 +0000</pubDate>
		<dc:creator>dm</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[RoR]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://dmitry.shaposhnik.name/2008/01/18/railsforumru/</guid>
		<description><![CDATA[
Открылся новый ресурс &#8211; http://www.railsforum.ru.
Прошу любить и жаловать.
]]></description>
			<content:encoded><![CDATA[<p><img src='http://dmitry.shaposhnik.name/files/2008/01/rails.png' alt='rails logo' /><br />
Открылся новый ресурс &#8211; <a href="http://www.railsforum.ru">http://www.railsforum.ru</a>.<br />
Прошу любить и жаловать.</p>
]]></content:encoded>
			<wfw:commentRss>http://dmitry.shaposhnik.name/2008/01/18/railsforumru/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>rails and bzr</title>
		<link>http://dmitry.shaposhnik.name/2008/01/16/rails-and-bzr/</link>
		<comments>http://dmitry.shaposhnik.name/2008/01/16/rails-and-bzr/#comments</comments>
		<pubDate>Wed, 16 Jan 2008 10:50:43 +0000</pubDate>
		<dc:creator>dm</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Newbie]]></category>
		<category><![CDATA[RoR]]></category>
		<category><![CDATA[bzr]]></category>

		<guid isPermaLink="false">http://dmitry.shaposhnik.name/2008/01/16/rails-and-bzr/</guid>
		<description><![CDATA[Попробовал bzr и остался весьма доволен.

Что же из себя представляет Bazaar? Bzr &#8211; распределенная система контроля версий. После SVN такой термин не совсем понятен. И зачем на что-то переходить когда и SVN отлично работает?
Распределенная система контроля версий не привязана к серверу. Что случится если в процессе работы над проектом теряется свзять с svn-сервером? Система рассчитана [...]]]></description>
			<content:encoded><![CDATA[<p>Попробовал <a href="http://bazaar-vcs.org/">bzr</a> и остался весьма доволен.<br />
<span id="more-165"></span><br />
Что же из себя представляет <a href="http://bazaar-vcs.org/">Bazaar</a>? Bzr &#8211; распределенная система контроля версий. После SVN такой термин не совсем понятен. И зачем на что-то переходить когда и SVN отлично работает?<br />
Распределенная система контроля версий не привязана к серверу. Что случится если в процессе работы над проектом теряется свзять с svn-сервером? Система рассчитана на обязательное его наличие. Как результат &#8211; работаем дальше без истории изменений.<br />
А что же дает bzr?<br />
Локальные коммиты. Используя его мы можем сделать bzr commit &#8211;local, и так у нас будет история и версионность. Локально. И при появлении сервера можно вновь делать коммиты на него.<br />
Привязка-отвязка от сервера. Можно сделать чекаут, отвязать его от сервера. Например, при поездке куда-то.<br />
Наш репозитарий может служить репозитарием для других. Так, можно иметь рабочий репозитарий для проектов, и репозитарий для активной разработки. После того как development-версия оттестирована можно делать коммит в рабочий репозитарий. Такое дополнительное звено для проверки работоспособности.</p>
<p>Собственно, существуют и другие подобные системы &#8211; git, mercurial. Но bzr считается самым дружественным. Далее на примере это можно будет увидеть <img src='http://dmitry.shaposhnik.name/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Итак, создание репозитария происходит командой <tt>bzr init-repository</tt>. </p>
<blockquote><p>New branches created under the repository directory will store their revisions in the repository, not in the branch directory.</p></blockquote>
<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;">mkdir</span> railsproject <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #7a0874; font-weight: bold;">cd</span> railsproject</div></div>
<p>Создание проекта в нем &#8211; <tt>bzr init</tt></p>
<blockquote><p>Use this to create an empty branch, or before importing an existing project.<br />
If there is a repository in a parent directory of the location, then the history of the branch will be stored in the repository.<br />
Otherwise init creates a standalone branch which carries its own history in the .bzr directory.</p></blockquote>
<p>Теперь на локальной машинке давайте создадим проект на rails:</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">rails railsproject</div></div>
<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">bzr checkout bzr+<span style="color: #c20cb9; font-weight: bold;">ssh</span>:<span style="color: #000000; font-weight: bold;">//</span>my.server<span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>user<span style="color: #000000; font-weight: bold;">/</span>bzr<span style="color: #000000; font-weight: bold;">/</span>railsproject<span style="color: #000000; font-weight: bold;">/</span> .</div></div>
<p>Отлично. Теперь у нас есть папка .bzr в корне проекта. Прежде чем делать добавления в проект давайте пропишем маски для исключений. Это делается легко и просто =)</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">bzr ignore <span style="color: #ff0000;">&quot;log/*.log&quot;</span><br />
bzr ignore <span style="color: #ff0000;">&quot;tmp/*&quot;</span></div></div>
<p>Мне кажется, это приятней и понятней чем в svn. Кроме того, в корне проекта появился файлик .bzrignore, в который можно дописывать маски.<br />
Если в маске встречается символ &#8220;/&#8221; то путь определяется от корня проекта. Например, вложенная где-нибудь папка log будет добавлена в репозитарий со всем содержимым. Для такого случая есть префикс &#8220;/**/logs/*.log&#8221;.<br />
Отлично, теперь в корне проекта сделаем</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">bzr add<br />
bzr commit <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;initial import&quot;</span></div></div>
<p>и наши файлы ушли в репозитарий. Все, можно работать.<br />
Чтобы не делать много мелких несущественных коммитов можно делать их локально &#8211; &#8220;bzr commit &#8211;local&#8221;.<br />
Более подробный мануал по bzr иожно <a href="http://bazaar-vcs.org/Documentation">найти на оффсайте</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://dmitry.shaposhnik.name/2008/01/16/rails-and-bzr/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails and multilingual site</title>
		<link>http://dmitry.shaposhnik.name/2008/01/14/rails-and-multilingual-site/</link>
		<comments>http://dmitry.shaposhnik.name/2008/01/14/rails-and-multilingual-site/#comments</comments>
		<pubDate>Mon, 14 Jan 2008 07:57:56 +0000</pubDate>
		<dc:creator>dm</dc:creator>
				<category><![CDATA[RoR]]></category>

		<guid isPermaLink="false">http://dmitry.shaposhnik.name/2008/01/14/rails-and-multilingual-site/</guid>
		<description><![CDATA[Надо сделать сайт с поддержкой многоязычности. И вот к чему я пришел.

Во-первых, структура публикаций выходит одинаковая (новости, статьи&#8230;).
То есть для использования прекрасно подходит SingleTableInheritance. При таком подходе все поля очень близких по структуре классов сводятся в одну таблицу в БД.
Также надо добавить поле &#8220;type&#8221; &#8211; тип публикации. Он будет содержать имя класса, на самом деле.

Далее, [...]]]></description>
			<content:encoded><![CDATA[<p>Надо сделать сайт с поддержкой многоязычности. И вот к чему я пришел.<br />
<span id="more-161"></span><br />
Во-первых, структура публикаций выходит одинаковая (новости, статьи&#8230;).<br />
То есть для использования прекрасно подходит <a href="http://wiki.rubyonrails.org/rails/pages/SingleTableInheritance">SingleTableInheritance</a>. При таком подходе все поля очень близких по структуре классов сводятся в одну таблицу в БД.<br />
Также надо добавить поле &#8220;type&#8221; &#8211; тип публикации. Он будет содержать имя класса, на самом деле.<br />
<img src='http://dmitry.shaposhnik.name/files/2008/01/diagram1.png' alt='multilingual db - step2' /></p>
<p>Далее, надо что-то сделать с языком. Вариант №1 &#8211; сделать композитный первичный ключ, который будет состоять из id + language. Но мне больше нравится вариант с разделением локализуемой части и нелокализуемой:<br />
<img src='http://dmitry.shaposhnik.name/files/2008/01/diagram2.png' alt='diagram2.png' /><br />
И далее по ссылкам:<br />
<a href="http://compositekeys.rubyforge.org/">compositekeys gem</a> и <a href="http://errtheblog.com/posts/14-composite-migrations">ее практическое использование в rails</a></p>
<p>Также для Content задействовал <a href="http://code.google.com/p/scope-out-rails/">Scope-out</a>.</p>
<p>Чтобы модель &#8220;знала&#8221; какой язык сейчас запрошен:</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:#008000; font-style:italic;">## config/environment.rb</span><br />
...<br />
<span style="color:#ff6633; font-weight:bold;">$language</span> = <span style="color:#996600;">'ru'</span><br />
...<br />
<br />
<span style="color:#008000; font-style:italic;">## config/initializers/activerecord_localized.rb</span><br />
<span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</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;">set_language</span><span style="color:#006600; font-weight:bold;">&#40;</span>lang<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; @@language = lang<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#008000; font-style:italic;">## app/controllers/application.rb</span><br />
<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 />
...<br />
&nbsp; <span style="color:#9900CC;">before_filter</span> <span style="color:#ff3333; font-weight:bold;">:set_model_language</span><br />
&nbsp; private<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> set_model_language<br />
&nbsp; &nbsp; @@language = 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;">||</span> <span style="color:#ff6633; font-weight:bold;">$language</span><br />
&nbsp; &nbsp; <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">set_language</span> @@language<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
<span style="color:#008000; font-style:italic;">## app/models/news.rb</span><br />
<span style="color:#9966CC; font-weight:bold;">class</span> Content <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span><br />
&nbsp; scope_out <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;">&#91;</span><span style="color:#996600;">'language=?'</span>, <span style="color:#9966CC; font-weight:bold;">defined</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>@@language<span style="color:#006600; font-weight:bold;">&#41;</span> ? @@language : <span style="color:#ff6633; font-weight:bold;">$language</span><span style="color:#006600; font-weight:bold;">&#93;</span><br />
... &nbsp; &nbsp;<br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>Задумался, как бы получше сделать локализацию Views. Пока думаю о написании helper&#8217;а, который будет подставлять из конфига стоки вместо констант &#8211; как упрощенный вариант <a href="http://code.google.com/p/xres/wiki/LocalizeViews">ActiveCulture</a>.</p>
<p>Кто чего подскажет?</p>
]]></content:encoded>
			<wfw:commentRss>http://dmitry.shaposhnik.name/2008/01/14/rails-and-multilingual-site/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>lighttpd and rails</title>
		<link>http://dmitry.shaposhnik.name/2008/01/05/lighttpd-and-rails/</link>
		<comments>http://dmitry.shaposhnik.name/2008/01/05/lighttpd-and-rails/#comments</comments>
		<pubDate>Sat, 05 Jan 2008 02:33:27 +0000</pubDate>
		<dc:creator>dm</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[RoR]]></category>
		<category><![CDATA[lighttpd]]></category>
		<category><![CDATA[webtech]]></category>

		<guid isPermaLink="false">http://dmitry.shaposhnik.name/2008/01/05/lighttpd-and-rails/</guid>
		<description><![CDATA[Сделал небольшую пачку оберток на сервере для управления приложениями.

Для начала воспользовался кластером mongrel:
gem install mongrel_cluster
и создал юзеря, от которого все монгрели будут выполняться:
adduser --system --no-create-home --shell /bin/false --group mongrel
Правда, мне понадобилось сделать vipw и vigr, чтобы подправить ID пользователя и группы &#8211; чтоб они совпадали.
Теперь, в папке с приложением сделал
mongrel_rails cluster::configure -e production -p 3000 [...]]]></description>
			<content:encoded><![CDATA[<p>Сделал небольшую пачку оберток на сервере для управления приложениями.<br />
<span id="more-159"></span><br />
Для начала воспользовался кластером mongrel:</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">gem <span style="color: #c20cb9; font-weight: bold;">install</span> mongrel_cluster</div></div>
<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">adduser <span style="color: #660033;">--system</span> <span style="color: #660033;">--no-create-home</span> <span style="color: #660033;">--shell</span> <span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">false</span> <span style="color: #660033;">--group</span> mongrel</div></div>
<p>Правда, мне понадобилось сделать vipw и vigr, чтобы подправить ID пользователя и группы &#8211; чтоб они совпадали.</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">mongrel_rails cluster::configure <span style="color: #660033;">-e</span> production <span style="color: #660033;">-p</span> <span style="color: #000000;">3000</span> <span style="color: #660033;">-N</span> <span style="color: #000000;">5</span> <span style="color: #660033;">-c</span> .<span style="color: #000000; font-weight: bold;">/</span> <span style="color: #660033;">-a</span> 127.0.0.1 <span style="color: #660033;">--user</span> mongrel <span style="color: #660033;">--group</span> mongrel</div></div>
<p>и получил в результате в config/mongrel_cluster.yml конфиг для кластера монгрелей. Вот такого вида:</p>
<div class="codecolorer-container ini default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ini codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">--- <br />
user: mongrel<br />
cwd: /var/www/lighttpd/www.example.com<br />
log_file: log/mongrel.log<br />
port: <span style="color: #933;">&quot;8000&quot;</span><br />
environment: production<br />
group: mongrel<br />
address: 127.0.0.1<br />
pid_file: tmp/pids/mongrel.pid<br />
servers: <span style="">5</span></div></div>
<p>Запускается оно через <tt>mongrel_rails cluster::start</tt>.<br />
Но надо же что-то сделать, чтоб оно загружалось при старте системы. И вот что я нашел и сделал.</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;">mkdir</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>mongrel_cluster<span style="color: #000000; font-weight: bold;">/</span><br />
<span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>mongrel_cluster<span style="color: #000000; font-weight: bold;">/</span>available<br />
<span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>mongrel_cluster<span style="color: #000000; font-weight: bold;">/</span>enabled<br />
<span style="color: #c20cb9; font-weight: bold;">mv</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>lighttpd<span style="color: #000000; font-weight: bold;">/</span>www.example.com<span style="color: #000000; font-weight: bold;">/</span>config<span style="color: #000000; font-weight: bold;">/</span>mongrel_cluster.yml <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>mongrel_cluster<span style="color: #000000; font-weight: bold;">/</span>available<span style="color: #000000; font-weight: bold;">/</span>www.example.com.yml<br />
<span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>mongrel_cluster<span style="color: #000000; font-weight: bold;">/</span>available<span style="color: #000000; font-weight: bold;">/</span>www.example.com.yml <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>mongrel_cluster<span style="color: #000000; font-weight: bold;">/</span>enabled<span style="color: #000000; font-weight: bold;">/</span>www.example.com.yml</div></div>
<p>Теперь создадим скрипт /etc/init.d/mongrel_cluster:</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: #666666; font-style: italic;">#!/bin/bash</span><br />
<br />
<span style="color: #000000; font-weight: bold;">set</span> <span style="color: #660033;">-e</span><br />
<br />
mongrel_cluster_ctl <span style="color: #660033;">-v</span> <span style="color: #660033;">-c</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>mongrel_cluster<span style="color: #000000; font-weight: bold;">/</span>enabled $<span style="color: #000000; font-weight: bold;">@</span></div></div>
<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;">chmod</span> +x <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>mongrel_cluster<br />
update-rc.d <span style="color: #660033;">-f</span> mongrel_cluster defaults</div></div>
<p>Также для удобства запуска-остановки отдельного приложения я сделал мелкий скрипт /etc/mongrel_cluster/operation.sh:</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: #666666; font-style: italic;">#!/bin/bash</span><br />
<br />
<span style="color: #000000; font-weight: bold;">set</span> <span style="color: #660033;">-e</span><br />
<br />
<span style="color: #007800;">CONFIGS</span>=<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>mongrel_cluster<span style="color: #000000; font-weight: bold;">/</span>enabled<br />
<br />
mongrel_rails cluster::<span style="color: #007800;">$1</span> <span style="color: #660033;">-C</span> <span style="color: #007800;">$CONFIGS</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$2</span>.yml</div></div>
<p>Поьзоваться им можно так: <tt>/etc/mongrel_cluster/operation.sh start www.example.com</tt><br />
Собственно, на этом с монгрелем все.<br />
Далее &#8211; lighttpd. Почему не nginx? Я не нашел никаких доводов за или против. В конце-концов, оба они работают как reverse-proxy к монгрелю, и несложно сменить демон &#8211; никаких переработок приложения не потребуется.</p>
<p>Итак, вот конфиг lighttpd:</p>
<div class="codecolorer-container ini default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="ini codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">server.modules &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> <span style="">&#40;</span> </span><span style="color: #933;">&quot;mod_access&quot;</span>, <span style="color: #933;">&quot;mod_accesslog&quot;</span>, <span style="color: #933;">&quot;mod_compress&quot;</span>, <span style="color: #933;">&quot;mod_rewrite&quot;</span>, <span style="color: #933;">&quot;mod_proxy&quot;</span>, <span style="color: #933;">&quot;mod_redirect&quot;</span> <span style="">&#41;</span><br />
server.document-root &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;/var/www/lighttpd/default/&quot;</span><br />
server.errorlog &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;/var/log/lighttpd/error.log&quot;</span><br />
server.port &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 80</span><br />
server.bind &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;77.120.99.179&quot;</span><br />
server.pid-file &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;/var/run/lighttpd.pid&quot;</span><br />
server.username &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;www-data&quot;</span><br />
server.groupname &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;www-data&quot;</span><br />
server.tag &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;lighttpd&quot;</span><br />
<br />
index-file.names &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> <span style="">&#40;</span> </span><span style="color: #933;">&quot;index.php&quot;</span>, <span style="color: #933;">&quot;index.html&quot;</span>, <span style="color: #933;">&quot;index.htm&quot;</span> <span style="">&#41;</span><br />
url.access-deny &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> <span style="">&#40;</span> </span><span style="color: #933;">&quot;~&quot;</span>, <span style="color: #933;">&quot;.inc&quot;</span> <span style="">&#41;</span><br />
static-file.exclude-extensions &nbsp;<span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> <span style="">&#40;</span> </span><span style="color: #933;">&quot;.php&quot;</span>, <span style="color: #933;">&quot;.pl&quot;</span>, <span style="color: #933;">&quot;.fcgi&quot;</span> <span style="">&#41;</span><br />
<br />
accesslog.filename &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;/var/log/lighttpd/access.log&quot;</span><br />
<br />
compress.cache-dir &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;/var/cache/lighttpd/compress/&quot;</span><br />
compress.filetype &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> <span style="">&#40;</span></span><span style="color: #933;">&quot;text/plain&quot;</span>, <span style="color: #933;">&quot;text/html&quot;</span>, <span style="color: #933;">&quot;application/x-javascript&quot;</span>, <span style="color: #933;">&quot;text/css&quot;</span>, <span style="color: #933;">&quot;text/xml&quot;</span> <span style="">&#41;</span><br />
<br />
include_shell &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #933;">&quot;/usr/share/lighttpd/create-mime.assign.pl&quot;</span><br />
include_shell &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #933;">&quot;/usr/share/lighttpd/include-conf-enabled.pl&quot;</span><br />
<br />
var.basedir <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;/var/www/lighttpd/&quot;</span><br />
<br />
#### SITES ####<br />
$HTTP<span style="">&#91;</span><span style="color: #933;">&quot;host&quot;</span><span style="">&#93;</span> <span style="color: #000066; font-weight:bold;">==</span> <span style="color: #933;">&quot;example.com&quot;</span> <span style="">&#123;</span><br />
&nbsp; &nbsp; url.redirect <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> <span style="">&#40;</span></span><span style="color: #933;">&quot;^/(.*)$&quot;</span> <span style="color: #000066; font-weight:bold;">=</span>&gt; <span style="color: #933;">&quot;http://www.example.com/$1&quot;</span><span style="">&#41;</span><br />
<span style="">&#125;</span><br />
$HTTP<span style="">&#91;</span><span style="color: #933;">&quot;host&quot;</span><span style="">&#93;</span> <span style="color: #000066; font-weight:bold;">==</span> <span style="color: #933;">&quot;www.example.com&quot;</span> <span style="">&#123;</span><br />
&nbsp; &nbsp; server.name <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;www.example.com&quot;</span><br />
&nbsp; &nbsp; server.document-root <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> basedir + server.name + </span><span style="color: #933;">&quot;/public&quot;</span><br />
&nbsp; &nbsp; accesslog.filename <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> basedir + server.name + </span><span style="color: #933;">&quot;/log/access.log&quot;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; $HTTP<span style="">&#91;</span><span style="color: #933;">&quot;url&quot;</span><span style="">&#93;</span> !~ <span style="color: #933;">&quot;^/(stylesheets|javascripts|images|files)/&quot;</span> <span style="">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; proxy.balance <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;fair&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; proxy.server &nbsp;<span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> <span style="">&#40;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #933;">&quot;/&quot;</span> <span style="color: #000066; font-weight:bold;">=</span>&gt; <span style="">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="">&#40;</span> <span style="color: #933;">&quot;host&quot;</span> <span style="color: #000066; font-weight:bold;">=</span>&gt; <span style="color: #933;">&quot;127.0.0.1&quot;</span>, <span style="color: #933;">&quot;port&quot;</span> <span style="color: #000066; font-weight:bold;">=</span>&gt; <span style="">8000</span> <span style="">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="">&#40;</span> <span style="color: #933;">&quot;host&quot;</span> <span style="color: #000066; font-weight:bold;">=</span>&gt; <span style="color: #933;">&quot;127.0.0.1&quot;</span>, <span style="color: #933;">&quot;port&quot;</span> <span style="color: #000066; font-weight:bold;">=</span>&gt; <span style="">8001</span> <span style="">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="">&#40;</span> <span style="color: #933;">&quot;host&quot;</span> <span style="color: #000066; font-weight:bold;">=</span>&gt; <span style="color: #933;">&quot;127.0.0.1&quot;</span>, <span style="color: #933;">&quot;port&quot;</span> <span style="color: #000066; font-weight:bold;">=</span>&gt; <span style="">8002</span> <span style="">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="">&#40;</span> <span style="color: #933;">&quot;host&quot;</span> <span style="color: #000066; font-weight:bold;">=</span>&gt; <span style="color: #933;">&quot;127.0.0.1&quot;</span>, <span style="color: #933;">&quot;port&quot;</span> <span style="color: #000066; font-weight:bold;">=</span>&gt; <span style="">8003</span> <span style="">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="">&#40;</span> <span style="color: #933;">&quot;host&quot;</span> <span style="color: #000066; font-weight:bold;">=</span>&gt; <span style="color: #933;">&quot;127.0.0.1&quot;</span>, <span style="color: #933;">&quot;port&quot;</span> <span style="color: #000066; font-weight:bold;">=</span>&gt; <span style="">8004</span> <span style="">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="">&#41;</span><br />
&nbsp; &nbsp; <span style="">&#125;</span><br />
<span style="">&#125;</span></div></div>
<p>Я обеспечил прямой доступ к статике посредством lighttpd, не заворачивая статику через mongrel (везде я встречал заворачивание всего на монгрели, что, ИМХО, не есть хорошо).<br />
Весьма настоятельно рекомендую в приложении создать файлик log/access.log и обеспечить в него запись пользователю www-data, от которого работает lighttpd.</p>
<p>Собственно, все. Ругайте.</p>
<p>UPD: в процессе работы проявились особенности Safari &#038; IE. Для них надо в конфиге lighttpd добавить</p>
<div class="codecolorer-container perl default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">$HTTP</span><span style="color: #009900;">&#91;</span><span style="color: #ff0000;">&quot;useragent&quot;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=~</span> <span style="color: #ff0000;">&quot;^(.*MSIE.*)|(.*AppleWebKit.*)$&quot;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; server<span style="color: #339933;">.</span>max<span style="color: #339933;">-</span>keep<span style="color: #339933;">-</span>alive<span style="color: #339933;">-</span>requests <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><br />
<span style="color: #009900;">&#125;</span></div></div>
]]></content:encoded>
			<wfw:commentRss>http://dmitry.shaposhnik.name/2008/01/05/lighttpd-and-rails/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>ruby directory listing</title>
		<link>http://dmitry.shaposhnik.name/2007/12/29/ruby-directory-listing/</link>
		<comments>http://dmitry.shaposhnik.name/2007/12/29/ruby-directory-listing/#comments</comments>
		<pubDate>Fri, 28 Dec 2007 22:27:54 +0000</pubDate>
		<dc:creator>dm</dc:creator>
				<category><![CDATA[RoR]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://dmitry.shaposhnik.name/2007/12/29/ruby-directory-listing/</guid>
		<description><![CDATA[Делая первые шаги в руби и рельсах наткнулся на необходимость получить листинг папки без &#8220;.&#8221; и &#8220;..&#8221;. Вот так реализовалось:
class Dir
&#160; def self.listing&#40;path, &#38;block&#41;
&#160; &#160; return nil if path.nil?
&#160; &#160; entries = Dir.entries&#40;path&#41;.reject! &#123; &#124;filename&#124; filename=='.' or filename=='..'&#125;
&#160; &#160; entries.each&#40;&#38;block&#41; if block_given?
&#160; &#160; entries
&#160; end
end
Огромаднейшее спасибо kpumuk&#8216;у за подсказки и помощь нюбу =)
]]></description>
			<content:encoded><![CDATA[<p>Делая первые шаги в руби и рельсах наткнулся на необходимость получить листинг папки без &#8220;.&#8221; и &#8220;..&#8221;. Вот так реализовалось:</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> <span style="color:#CC00FF; font-weight:bold;">Dir</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;">listing</span><span style="color:#006600; font-weight:bold;">&#40;</span>path, <span style="color:#006600; font-weight:bold;">&amp;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">nil</span> <span style="color:#9966CC; font-weight:bold;">if</span> path.<span style="color:#0000FF; font-weight:bold;">nil</span>?<br />
&nbsp; &nbsp; entries = <span style="color:#CC00FF; font-weight:bold;">Dir</span>.<span style="color:#9900CC;">entries</span><span style="color:#006600; font-weight:bold;">&#40;</span>path<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">reject</span>! <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>filename<span style="color:#006600; font-weight:bold;">|</span> filename==<span style="color:#996600;">'.'</span> <span style="color:#9966CC; font-weight:bold;">or</span> filename==<span style="color:#996600;">'..'</span><span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; entries.<span style="color:#9900CC;">each</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&amp;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> block_given?<br />
&nbsp; &nbsp; entries<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>Огромаднейшее спасибо <a href="http://kpumuk.info">kpumuk</a>&#8216;у за подсказки и помощь нюбу =)</p>
]]></content:encoded>
			<wfw:commentRss>http://dmitry.shaposhnik.name/2007/12/29/ruby-directory-listing/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>rails got the power</title>
		<link>http://dmitry.shaposhnik.name/2007/12/19/rails-got-the-power/</link>
		<comments>http://dmitry.shaposhnik.name/2007/12/19/rails-got-the-power/#comments</comments>
		<pubDate>Wed, 19 Dec 2007 12:38:24 +0000</pubDate>
		<dc:creator>dm</dc:creator>
				<category><![CDATA[RoR]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://dmitry.shaposhnik.name/2007/12/19/rails-got-the-power/</guid>
		<description><![CDATA[Работаю сейчас над проектом. И вот для публикации надо сделать

кол-во просмотров
теги
рейтинги
комментарии

Начал писать на рельсах. И обнаружил

acts_as_taggable
acts_as_rated
acts_as_commentable

Только кол-во просмотров надо писать самому. Сильно впечатлился.
]]></description>
			<content:encoded><![CDATA[<p>Работаю сейчас над проектом. И вот для публикации надо сделать</p>
<ul>
<li>кол-во просмотров</li>
<li>теги</li>
<li>рейтинги</li>
<li>комментарии</li>
</ul>
<p>Начал писать на рельсах. И обнаружил</p>
<ul>
<li><a href="http://agilewebdevelopment.com/plugins/acts_as_taggable_on_steroids">acts_as_taggable</a></li>
<li><a href="http://acts-as-rated.rubyforge.org/">acts_as_rated</a></li>
<li><a href="http://www.juixe.com/techknow/index.php/2006/06/18/acts-as-commentable-plugin/">acts_as_commentable</a></li>
</ul>
<p>Только кол-во просмотров надо писать самому. Сильно впечатлился.</p>
]]></content:encoded>
			<wfw:commentRss>http://dmitry.shaposhnik.name/2007/12/19/rails-got-the-power/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Rails 2 released</title>
		<link>http://dmitry.shaposhnik.name/2007/12/07/rails-2-released/</link>
		<comments>http://dmitry.shaposhnik.name/2007/12/07/rails-2-released/#comments</comments>
		<pubDate>Fri, 07 Dec 2007 19:10:24 +0000</pubDate>
		<dc:creator>dm</dc:creator>
				<category><![CDATA[RoR]]></category>

		<guid isPermaLink="false">http://dmitry.shaposhnik.name/2007/12/07/rails-2-released/</guid>
		<description><![CDATA[Приятно видеть, что вышел Rails 2.0.1 (это потому что был найден небольшой баг сразу после выпуска 2.0.0).

Список изменений и улучшений. В общем и целом &#8211; фреймворк стал легче, многое из него убрали в плагины.
]]></description>
			<content:encoded><![CDATA[<p>Приятно видеть, что вышел Rails 2.0.1 (это потому что был найден небольшой баг сразу после выпуска 2.0.0).<br />
<img src='http://dmitry.shaposhnik.name/files/2007/12/rails.png' alt='rails.png' /></p>
<p><a href="http://weblog.rubyonrails.com/2007/12/7/rails-2-0-it-s-done">Список изменений и улучшений.</a> В общем и целом &#8211; фреймворк стал легче, многое из него убрали в плагины.</p>
]]></content:encoded>
			<wfw:commentRss>http://dmitry.shaposhnik.name/2007/12/07/rails-2-released/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>NetBeans 6.0 released</title>
		<link>http://dmitry.shaposhnik.name/2007/12/04/netbeans-60-released/</link>
		<comments>http://dmitry.shaposhnik.name/2007/12/04/netbeans-60-released/#comments</comments>
		<pubDate>Mon, 03 Dec 2007 21:26:22 +0000</pubDate>
		<dc:creator>dm</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[RoR]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://dmitry.shaposhnik.name/2007/12/04/netbeans-60-released/</guid>
		<description><![CDATA[Наконец-то вышел NetBeans 6.0 &#8211; замечательная Java IDE. Для меня она ценна изумительной поддержкой Ruby, а также наличием в плагинах средств для работы с UML, PHP, C/C++.

]]></description>
			<content:encoded><![CDATA[<p>Наконец-то вышел NetBeans 6.0 &#8211; замечательная Java IDE. Для меня она ценна изумительной поддержкой Ruby, а также наличием в плагинах средств для работы с UML, PHP, C/C++.</p>
<p><a href="http://download.netbeans.org/netbeans/6.0/final/"><img src="http://blogs.sun.com/tor/resource/110x32_dl2.gif"/></a></p>
]]></content:encoded>
			<wfw:commentRss>http://dmitry.shaposhnik.name/2007/12/04/netbeans-60-released/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
