diff options
Diffstat (limited to 'docs/developers')
-rw-r--r-- | docs/developers/directory_structure.md | 6 | ||||
-rw-r--r-- | docs/developers/i18n.md | 161 | ||||
-rw-r--r-- | docs/developers/index.md | 17 | ||||
-rw-r--r-- | docs/developers/overview.md | 2 |
4 files changed, 173 insertions, 13 deletions
diff --git a/docs/developers/directory_structure.md b/docs/developers/directory_structure.md index e073a96ce..9dbe06789 100644 --- a/docs/developers/directory_structure.md +++ b/docs/developers/directory_structure.md @@ -13,7 +13,7 @@ directories.</p> Alaveteli -- this is really more useful if you're a developer planning on making more substantive changes to the code. You don't need to be familiar with Ruby to install or make basic [customisations to your -installation](/docs/customising). +installation](/docs/customising/). <!-- (and if you do, remember to read the page about [feeding your changes back](/feeding-back)).--> @@ -140,7 +140,7 @@ website](http://guides.rubyonrails.org/getting_started.html). <p><em>documentation</em></p> <p> These are technical notes. This is in addition to the <a - href="http://code.fixmystreet.com">core documentation</a> — which + href="http://code.alaveteli.org/docs/">core documentation</a> — which you are reading now — which is actually stored in the git repository in the <code>gh-pages</code> branch, and published as GitHub pages. @@ -215,7 +215,7 @@ website](http://guides.rubyonrails.org/getting_started.html). <dd> <p><em>tests</em></p> <p> - Alaveteli's test suite runs under <a href="TODO">spec</a>. + Alaveteli's test suite runs under <a href="http://rspec.info/">rspec</a>. </p> </dd> <dt> diff --git a/docs/developers/i18n.md b/docs/developers/i18n.md new file mode 100644 index 000000000..deabc99a1 --- /dev/null +++ b/docs/developers/i18n.md @@ -0,0 +1,161 @@ +--- +layout: page +title: Internationalisation (for devs) +--- + +# Internationalisation in the code + +<p class="lead"> + This page describes some technical aspects of internationalising the + Alaveteli code. It's mostly aimed at devs who are working on the + codebase — if you just want to translate Alaveteli into your + own language, see + <a href="{{ site.baseurl }}docs/customising/translation">translating Alaveteli</a> + instead. +</p> + +## Deployment notes + +Deployed translations for the project live in ``locale/``. + +We encourage translations to be done on +[Transifex](https://www.transifex.net/projects/p/alaveteli/) +because translators can work through its web interface rather than needing to edit the +<a href="{{ site.baseurl }}docs/glossary/#po" class="glossary__link">`.po` and `.pot` files</a> +directly. Ultimately, Transifex just captures translators' +work and turns it into the files that Alaveteli needs (using gettext). + +### How to get the latest translations onto your site + +For example, to deploy English and Spanish translations at once: + + * Ensure their `.po` files are at ```locale/en/app.po``` and ```locale/es/app.po``` + (for example, by downloading them from Transifex) + * Set <code><a href="{{ site.baseurl }}docs/customising/config/#available_locales">AVAILABLE_LOCALES</a></code> + to <code>en es</code> + +### How to add new strings to the translations + +You need to do this if you've added any new strings to the code that need +translations (or if you change an existing one). + +To update the +<a href="{{ site.baseurl }}docs/glossary/#po" class="glossary__link">`.po` or `.pot` files</a> +for each language, run: + + bundle exec rake gettext:store_model_attributes + +followed by: + + bundle exec rake gettext:find + +If `gettext:find` only creates the file `locale/im-config.pot` then you need to +unset the `TEXTDOMAIN` environment variable and try again. + +For more details about the translations, see the page about +[translating Alaveteli]({{ site.baseurl }}docs/customising/translation/). + + +## Technical implementation details + +### Getting the current locale + +This is complicated by the fact that there are two competing ways to define a +locale+territory combination. The POSIX (and gettext and Transifex) way is +like `en_GB`; the Rails way is like `en-US`. Because we are using gettext and +Transifex for translations, we must deal with both. + + * for the Rails version of the currently selected locale, use `I18n.locale` + * for the POSIX version of the locale, use `FastGettext.locale` + +## I18n in templates + +Before you add i18n strings to the source, you should read +[internationalisation guidelines](http://mysociety.github.io/internationalization.html) +that apply to all our projects. + +Some hints for adding the strings into the Alaveteli code: + +* Simple strings: ```<% = _("String to translate") %>``` +* Strings that include variables: give the translator a hand by inserting + strings that can be interpolated, so the variable has meaning. For example, + ```<%= "Nothing found for '" + h(@query) + "'" %>``` might become ```<%= + _("Nothing found for '{{search_terms}}'", :search_terms => h(@query)) %>``` +* Strings containing numbers: ```<%= n_('%d request', '%d requests', @quantity) % @quantity %>``` +* We allow some inline HTML where it helps with meaningful context, for example: + +``` +_('<a href="{{browse_url}}">Browse all</a> or <a href="{{add_url}}">ask us to add it</a>.', + :browse_url => @browse_url, :add_url => @add_url) +``` + +Similar rules can apply to strings in the Ruby source code. + +## Programmatic access of translated PublicBodies + +Apart from the templates, the only other area of i18n currently implemented is +in the PublicBodies. + +The implementation allows for getting different locales of a PublicBody like so: + +```ruby + PublicBody.with_locale("es") do + puts PublicBody.find(230).name + end +``` + +Usually, that's all the code you need to know about. There's a method +```self.locale_from_params()``` available on all models which returns a locale +specified as ```locale=xx``` in the query string, and which falls back to the +default locale, that you can use in conjunction with the ```with_locale``` +method above. All the joining on internal translation tables should usually be +handled automagically -- but there are some exceptions, that follow below. + +### Overriding model field setters + +Internally, we use the [Globalize plugin](https://github.com/globalize/globalize) +to localize model fields. Where column "foo" has been marked in the model as +```:translates```, globalize overrides ```foo.baz = 12``` to actually set the +value in column ```baz``` of table ```foo_translations```. + +A side effect of the way it does this is that if you wish to override a +specific attribute setter, you will need to explicitly call the Globalize +machinery; something like: + +```ruby + def name=(name) + globalize.write(self.class.locale || I18n.locale, "name", name) + self["name"] = short_name + # your other stuff here + end +``` + +### Searching + +The ```find_first_by_<attr>``` and ```find_all_by_<attr>``` magic methods +should work. If you want to do a more programmatic search, you will need to +join on the translation table. For example: + +```ruby + query = "#{translated_attr_name(someattr) = ? AND #{translated_attr_name('locale')} IN (?)" + locales = Globalize.fallbacks(locale || I18n.locale).map(&:to_s) + find( + :first, + :joins => :translations, + :conditions => [query, value, locales], + :readonly => false + ) +``` + +You may also need to do some lower-level SQL joins or conditions. See +```PublicBodyController.list``` for an example of a query that has a condition +that is explicitly locale-aware (look for the ```locale_condition``` variable) + +## Translation and releases + +The release manager will enforce a translation freeze just before a new release +is cut. During such time, you must not introduce new strings to the code if +your work is due for inclusion in this release. This is necessary to allow +translators time to complete and check their translations against all the known +strings. See more about [translating Alaveteli]({{ site.baseurl }}docs/customising/translation/). + diff --git a/docs/developers/index.md b/docs/developers/index.md index f98261a77..22390f236 100644 --- a/docs/developers/index.md +++ b/docs/developers/index.md @@ -12,14 +12,14 @@ title: For developers * The software is written in **Ruby on Rails 3.x**. We support postgresql as the backend database. A configured mail transfer agent (MTA) like exim, postfix or sendmail is necessary to parse incoming emails. We have production - sites deployed on Debian (Squeeze and Wheezy) and Ubuntu (10.04 and 12.04 LTS). For performance + sites deployed on Debian (Squeeze and Wheezy) and Ubuntu (12.04 LTS). For performance reasons, we recommend the use of [Varnish](https://www.varnish-cache.org). * To help you understand what the code is doing, read this [high-level - overview]({{ site.baseurl }}docs/developers/overview), which includes a diagram of + overview]({{ site.baseurl }}docs/developers/overview/), which includes a diagram of the models and how they are related. -* See the [API documentation]({{ site.baseurl }}docs/developers/api) for how to get +* See the [API documentation]({{ site.baseurl }}docs/developers/api/) for how to get data into or out of Alaveteli. * If you need to change or add strings in the interface, see our [guidelines @@ -49,14 +49,14 @@ title: For developers for help. * A standard initial step for customising your deployment is [writing a - theme]({{ site.baseurl }}docs/customising/themes). **If you only read one thing, + theme]({{ site.baseurl }}docs/customising/themes/). **If you only read one thing, it should be this!** * Like many Ruby on Rails sites, the software is not hugely performant (see - some notes about [[performance issues]] gathered over time with + [these notes about performance issues](https://github.com/mysociety/alaveteli/wiki/Performance-issues) gathered over time with WhatDoTheyKnow). The site will run on a server with 512MB RAM but at least 2GB is recommended. Deployment behind [Varnish](https://www.varnish-cache.org) is also fairly essential. See - [[Production Server Best Practices]] for more. + [production server best practices]({{site.baseurl}}docs/running/server/) for more. * There's a number of [proposals for enhancements](https://github.com/mysociety/alaveteli/wiki/Proposals-for-enhancements), such as more user-focused features, but see also... @@ -74,10 +74,9 @@ title: For developers * If you're experiencing memory issues, [this blog post about some strategies used in the - past](http://www.mysociety.org/2009/09/17/whatdotheyknow-growing-pains-and-rub - y-memory-leaks/) might be useful. + past](https://www.mysociety.org/2009/09/17/whatdotheyknow-growing-pains-and-ruby-memory-leaks/) might be useful. -* If you're coding on a mac, see these [MacOS X installation notes]({{ site.baseurl }}docs/installing/macos). <!-- [[OS X Quickstart]] --> +* If you're coding on a mac, see these [MacOS X installation notes]({{ site.baseurl }}docs/installing/macos/). <!-- [[OS X Quickstart]] --> * We try to adhere to similar good practice across all our projects: see [mysociety.github.io](http://mysociety.github.io/) for things like our diff --git a/docs/developers/overview.md b/docs/developers/overview.md index ca2d27985..af312f997 100644 --- a/docs/developers/overview.md +++ b/docs/developers/overview.md @@ -43,7 +43,7 @@ ensure they have an envelope-from header set (to combat spam). ## Schema diagram -<a name="schema-diagram" href="{{ site.baseurl }}images/railsmodels.png"><img src="{{ site.baseurl }}images/railsmodels.png"></a> +<a href="{{ site.baseurl }}assets/img/railsmodels.png"><img src="{{ site.baseurl }}assets/img/railsmodels.png"></a> This schema for the Rails models was generated from the code on 19 Dec 2012 using [Railroad](http://railroad.rubyforge.org/). |