<?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>Armbruster IT Blog &#187; i18n</title>
	<atom:link href="http://blog.armbruster-it.de/tag/i18n/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.armbruster-it.de</link>
	<description>Real world fun with Java, Grails, Groovy, Zope, Plone, Linux and much others.</description>
	<lastBuildDate>Tue, 11 Oct 2011 11:42:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Grails countries plugin 0.2 released</title>
		<link>http://blog.armbruster-it.de/2010/08/grails-countries-plugin-0-2-released/</link>
		<comments>http://blog.armbruster-it.de/2010/08/grails-countries-plugin-0-2-released/#comments</comments>
		<pubDate>Sat, 07 Aug 2010 21:16:11 +0000</pubDate>
		<dc:creator>Stefan Armbruster</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://blog.armbruster-it.de/?p=172</guid>
		<description><![CDATA[Thanks to the contributions of other hackers I&#8217;m announcing the 0.2 release of the Grails countries plugin. The changes: added languages for country and continent names: af: contributed by Robert Fletcher es, fr, it, pt_BR: contributed by Lucas Teixeira country list is now maintained outside CountryBootstrap.groovy in seperate csv files reworked properties file to consistently [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to the contributions of other hackers I&#8217;m announcing the 0.2 release of the Grails countries plugin. The changes:</p>
<ul>
<li>added languages for country and continent names:
<ul>
<li> af: contributed by <a href="http://adhockery.blogspot.com/">Robert Fletcher</a></li>
<li> es, fr, it, pt_BR: contributed by <a href="http://blog.lucastex.com/">Lucas Teixeira</a></li>
</ul>
</li>
<li>country list is now maintained outside CountryBootstrap.groovy in seperate csv files</li>
<li>reworked properties file to consistently use ISO-3166 3-letter-code as key</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.armbruster-it.de/2010/08/grails-countries-plugin-0-2-released/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>new Grails plugin: Countries</title>
		<link>http://blog.armbruster-it.de/2010/08/new-grails-plugin-countries/</link>
		<comments>http://blog.armbruster-it.de/2010/08/new-grails-plugin-countries/#comments</comments>
		<pubDate>Wed, 04 Aug 2010 14:19:20 +0000</pubDate>
		<dc:creator>Stefan Armbruster</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://blog.armbruster-it.de/?p=163</guid>
		<description><![CDATA[A common requirement in many applications is to deal with countries and/or continents. The plugin&#8217;s goal is to apply the DRY principle to these requirements. In short, the plugin offers: populated domain classes for countries and continents i18n for continent and country names (for now, only en and de locales). Currently there are 190 countries [...]]]></description>
			<content:encoded><![CDATA[<p>A common requirement in many applications is to deal with countries and/or continents. The plugin&#8217;s goal is to apply the DRY principle to these requirements.</p>
<p>In short, the plugin offers:</p>
<ul>
<li>populated domain classes for countries and continents</li>
<li> i18n for continent and country names (for now, only en and de locales). Currently there are 190 countries available.</li>
<li>tags for simple usage of
<ul>
<li>localized names for countries and continents</li>
<li>select boxes: for all countries, for all continents, for all countries of a continent or for a defined set of countries. The select box contents are automatically sorted by the the localized country/continent name.</li>
</ul>
</li>
</ul>
<p>resources:</p>
<ul>
<li> homepage: <a href="http://www.grails.org/plugin/countries">http://www.grails.org/plugin/countries</a></li>
<li> docs:<a href="http://sarmbruster.github.com/grails-countries-plugin/">http://sarmbruster.github.com/grails-countries-plugin/</a></li>
<li> sources:<a href="http://github.com/sarmbruster/grails-countries-plugin"> http://github.com/sarmbruster/grails-countries-plugin</a></li>
</ul>
<p>For bug reports please use <a href="http://jira.codehaus.org">http://jira.codehaus.org</a>, project &#8220;GrailsPlugins&#8221;, component &#8220;countries&#8221;.</p>
<p><strong>Update:</strong> since the initial release requires the usage of Grails 1.3.4-SNAPSHOT a bugfix release 0.1.1 has been release shortly afterwards. 0.1.1 should work with Grails &gt;= 1.0.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.armbruster-it.de/2010/08/new-grails-plugin-countries/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>getting a list of all i18n properties used in a Grails application</title>
		<link>http://blog.armbruster-it.de/2010/07/getting-a-list-of-all-i18n-properties-used-in-a-grails-application/</link>
		<comments>http://blog.armbruster-it.de/2010/07/getting-a-list-of-all-i18n-properties-used-in-a-grails-application/#comments</comments>
		<pubDate>Wed, 14 Jul 2010 19:43:45 +0000</pubDate>
		<dc:creator>Stefan Armbruster</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[i18n]]></category>

		<guid isPermaLink="false">http://blog.armbruster-it.de/?p=152</guid>
		<description><![CDATA[You might know this situation: in a project you start by hacking code that uses i18n properties instead of fixed strings in order to support multiple languages. The normal process in Grails is to use the g:message tag in controllers or gsp templates. Side by side you append the new introduced i18n property with some [...]]]></description>
			<content:encoded><![CDATA[<p>You might know this situation: in a project you start by hacking code that uses i18n properties instead of fixed strings in order to support multiple languages. The normal process in Grails is to use the <a href="http://grails.org/doc/latest/ref/Tags/message.html">g:message</a> tag in controllers or gsp templates. Side by side you append the new introduced i18n property with some value in your messsages.properties file.</p>
<p>When support for a new language is requested, all you have to do is translating messages.properties. So far so good &#8211; this make i18n really easy.</p>
<p>But: when the project evolves, there&#8217;s a good chance that some of your i18n properties in messages.properties gets orphaned. Assume you remove a block of code from a gsp. It happens often that the i18n properties used in this block are not removed from messages*.properties because at some point you are not sure if it is referenced elsewhere. So what would be really useful here would be a list of all referenced i18n properties from your *.groovy/*.gsp files.</p>
<p>Doing so is pretty easy, just add a new <a href="http://grails.org/doc/latest/guide/4.%20The%20Command%20Line.html">gant script</a> to your Grails application&#8217;s script folder, let&#8217;s name it i18nList.groovy. This script basically contains:</p>

<div class="wp_syntax"><div class="wp_syntax_download"><div class="wp_syntax_download_filename"><a name="file-includeTargets%20&amp;lt;&amp;lt;%20grailsScript(%22Init%22)%0D%0A%0D%0Atarget(main:%20%22create%20a%20list%20of%20all%20i18n%20properties%20used%20in%20groovy%20code%20and%20gsp%20templates%22)%20%7B%0D%0A%0D%0A%20%20%20%20def%20properties%20=%20%5B%5D%0D%0A%0D%0A%20%20%20%20new%20File(%22.%22).eachFileRecurse%20%7B%0D%0A%20%20%20%20%20%20%20%20if%20(it.file)%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20switch%20(it)%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20case%20~/.*%5C.groovy/:%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20def%20matcher%20=%20it.text%20=~%20/code:%5Cs*%5B%22'%5D(.*?)%5B%22'%5D/%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20matcher.each%20%7B%20properties%20&amp;lt;&amp;lt;%20it%5B1%5D%20%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20case%20~/.*%5C.gsp/:%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20def%20matcher%20=%20it.text%20=~%20/code=%5B%22'%5D(.*?)%5B%22'%5D/%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20matcher.each%20%7B%20properties%20&amp;lt;&amp;lt;%20it%5B1%5D%20%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20println%20properties.sort().unique().join(%22%5Cn%22)%0D%0A%0D%0A%7D%0D%0A%0D%0AsetDefaultTarget(main)" href="#file-includeTargets+%26lt%3B%26lt%3B+grailsScript%28%22Init%22%29%0D%0A%0D%0Atarget%28main%3A+%22create+a+list+of+all+i18n+properties+used+in+groovy+code+and+gsp+templates%22%29+%7B%0D%0A%0D%0A++++def+properties+%3D+%5B%5D%0D%0A%0D%0A++++new+File%28%22.%22%29.eachFileRecurse+%7B%0D%0A++++++++if+%28it.file%29+%7B%0D%0A++++++++++++switch+%28it%29+%7B%0D%0A++++++++++++++++case+%7E%2F.%2A%5C.groovy%2F%3A%0D%0A++++++++++++++++++++def+matcher+%3D+it.text+%3D%7E+%2Fcode%3A%5Cs%2A%5B%22%27%5D%28.%2A%3F%29%5B%22%27%5D%2F%0D%0A++++++++++++++++++++matcher.each+%7B+properties+%26lt%3B%26lt%3B+it%5B1%5D+%7D%0D%0A++++++++++++++++++++break%0D%0A++++++++++++++++case+%7E%2F.%2A%5C.gsp%2F%3A%0D%0A++++++++++++++++++++def+matcher+%3D+it.text+%3D%7E+%2Fcode%3D%5B%22%27%5D%28.%2A%3F%29%5B%22%27%5D%2F%0D%0A++++++++++++++++++++matcher.each+%7B+properties+%26lt%3B%26lt%3B+it%5B1%5D+%7D%0D%0A++++++++++++++++++++break%0D%0A++++++++++++%7D%0D%0A++++++++%7D%0D%0A++++%7D%0D%0A++++println+properties.sort%28%29.unique%28%29.join%28%22%5Cn%22%29%0D%0A%0D%0A%7D%0D%0A%0D%0AsetDefaultTarget%28main%29" title="includeTargets &amp;lt;&amp;lt; grailsScript(&quot;Init&quot;)

target(main: &quot;create a list of all i18n properties used in groovy code and gsp templates&quot;) {

    def properties = []

    new File(&quot;.&quot;).eachFileRecurse {
        if (it.file) {
            switch (it) {
                case ~/.*\.groovy/:
                    def matcher = it.text =~ /code:\s*[&quot;'](.*?)[&quot;']/
                    matcher.each { properties &amp;lt;&amp;lt; it[1] }
                    break
                case ~/.*\.gsp/:
                    def matcher = it.text =~ /code=[&quot;'](.*?)[&quot;']/
                    matcher.each { properties &amp;lt;&amp;lt; it[1] }
                    break
            }
        }
    }
    println properties.sort().unique().join(&quot;\n&quot;)

}

setDefaultTarget(main)">includeTargets &amp;lt;&amp;lt; grailsScript("Init")

target(main: "create a list of all i18n properties used in groovy code and gsp templates") {

    def properties = []

    new File(".").eachFileRecurse {
        if (it.file) {
            switch (it) {
                case ~/.*\.groovy/:
                    def matcher = it.text =~ /code:\s*["'](.*?)["']/
                    matcher.each { properties &amp;lt;&amp;lt; it[1] }
                    break
                case ~/.*\.gsp/:
                    def matcher = it.text =~ /code=["'](.*?)["']/
                    matcher.each { properties &amp;lt;&amp;lt; it[1] }
                    break
            }
        }
    }
    println properties.sort().unique().join("\n")

}

setDefaultTarget(main)</a></div><div class="wp_syntax_download_actions"><a href="http://blog.armbruster-it.de/wp-content/plugins/wp-syntax-download-extension/wp-syntax-download-extension.php/152/includeTargets%20&amp;lt;&amp;lt;%20grailsScript(%22Init%22)%0D%0A%0D%0Atarget(main:%20%22create%20a%20list%20of%20all%20i18n%20properties%20used%20in%20groovy%20code%20and%20gsp%20templates%22)%20%7B%0D%0A%0D%0A%20%20%20%20def%20properties%20=%20%5B%5D%0D%0A%0D%0A%20%20%20%20new%20File(%22.%22).eachFileRecurse%20%7B%0D%0A%20%20%20%20%20%20%20%20if%20(it.file)%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20switch%20(it)%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20case%20~/.*%5C.groovy/:%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20def%20matcher%20=%20it.text%20=~%20/code:%5Cs*%5B%22'%5D(.*?)%5B%22'%5D/%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20matcher.each%20%7B%20properties%20&amp;lt;&amp;lt;%20it%5B1%5D%20%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20case%20~/.*%5C.gsp/:%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20def%20matcher%20=%20it.text%20=~%20/code=%5B%22'%5D(.*?)%5B%22'%5D/%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20matcher.each%20%7B%20properties%20&amp;lt;&amp;lt;%20it%5B1%5D%20%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20println%20properties.sort().unique().join(%22%5Cn%22)%0D%0A%0D%0A%7D%0D%0A%0D%0AsetDefaultTarget(main)">raw</a> <a href="http://blog.armbruster-it.de/wp-content/plugins/wp-syntax-download-extension/wp-syntax-download-extension.php/152/download/includeTargets%20&amp;lt;&amp;lt;%20grailsScript(%22Init%22)%0D%0A%0D%0Atarget(main:%20%22create%20a%20list%20of%20all%20i18n%20properties%20used%20in%20groovy%20code%20and%20gsp%20templates%22)%20%7B%0D%0A%0D%0A%20%20%20%20def%20properties%20=%20%5B%5D%0D%0A%0D%0A%20%20%20%20new%20File(%22.%22).eachFileRecurse%20%7B%0D%0A%20%20%20%20%20%20%20%20if%20(it.file)%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20switch%20(it)%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20case%20~/.*%5C.groovy/:%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20def%20matcher%20=%20it.text%20=~%20/code:%5Cs*%5B%22'%5D(.*?)%5B%22'%5D/%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20matcher.each%20%7B%20properties%20&amp;lt;&amp;lt;%20it%5B1%5D%20%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20case%20~/.*%5C.gsp/:%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20def%20matcher%20=%20it.text%20=~%20/code=%5B%22'%5D(.*?)%5B%22'%5D/%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20matcher.each%20%7B%20properties%20&amp;lt;&amp;lt;%20it%5B1%5D%20%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20println%20properties.sort().unique().join(%22%5Cn%22)%0D%0A%0D%0A%7D%0D%0A%0D%0AsetDefaultTarget(main)">download</a></div></div><div class="code"><pre class="groovy" style="font-family:monospace;">includeTargets <span style="color: #66cc66;">&lt;&lt;</span> grailsScript<span style="color: #66cc66;">(</span><span style="color: #ff0000;">"Init"</span><span style="color: #66cc66;">)</span>
 
target<span style="color: #66cc66;">(</span>main: <span style="color: #ff0000;">"create a list of all i18n properties used in groovy code and gsp templates"</span><span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span>
 
    <span style="color: #000000; font-weight: bold;">def</span> properties <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">[</span><span style="color: #66cc66;">]</span>
 
    <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #aaaadd; font-weight: bold;">File</span><span style="color: #66cc66;">(</span><span style="color: #ff0000;">"."</span><span style="color: #66cc66;">)</span>.<span style="color: #FFCC33;">eachFileRecurse</span> <span style="color: #66cc66;">{</span>
        <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">(</span>it.<span style="color: #006600;">file</span><span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span>
            <span style="color: #b1b100;">switch</span> <span style="color: #66cc66;">(</span>it<span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span>
                <span style="color: #b1b100;">case</span> ~/.<span style="color: #66cc66;">*</span>\.<span style="color: #006600;">groovy</span>/:
                    <span style="color: #000000; font-weight: bold;">def</span> matcher <span style="color: #66cc66;">=</span> it.<span style="color: #006600;">text</span> <span style="color: #66cc66;">=</span>~ /code:\s<span style="color: #66cc66;">*</span><span style="color: #66cc66;">[</span><span style="color: #ff0000;">"'](.*?)["</span><span style="color: #ff0000;">']/
                    matcher.each { properties &lt;&lt; it[1] }
                    break
                case ~/.*<span style="color: #000099; font-weight: bold;">\.</span>gsp/:
                    def matcher = it.text =~ /code=["'</span><span style="color: #66cc66;">]</span><span style="color: #66cc66;">(</span>.<span style="color: #66cc66;">*?</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">[</span><span style="color: #ff0000;">"']/
                    matcher.each { properties &lt;&lt; it[1] }
                    break
            }
        }
    }
    println properties.sort().unique().join("</span>\n<span style="color: #ff0000;">")
 
}
 
setDefaultTarget(main)</span></pre></div></div>

<p>(sorry the color coding seems to fail for some Groovy regexes) The script recursivly iterates over all *.groovy and *.gsp files in your project and extract the part after the &#8216;code&#8217; attribute of the message tag using a regex. The regex result are collected into an array. This array is sorted, unique&#8217;d and printed to the console. That&#8217;s it.</p>
<p>One word of caution: this gant script &#8216;works for me&#8217;. So depending on your code, you might notice that the used regex are not sufficient or even fail. Feel free to modify them for your needs, even better send back your modifications.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.armbruster-it.de/2010/07/getting-a-list-of-all-i18n-properties-used-in-a-grails-application/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

