diff options
Diffstat (limited to 'docs/developers')
-rw-r--r-- | docs/developers/api.md | 6 | ||||
-rw-r--r-- | docs/developers/directory_structure.md | 119 | ||||
-rw-r--r-- | docs/developers/i18n.md | 177 | ||||
-rw-r--r-- | docs/developers/index.md | 6 |
4 files changed, 225 insertions, 83 deletions
diff --git a/docs/developers/api.md b/docs/developers/api.md index cbd4c7c85..1e6c15cfd 100644 --- a/docs/developers/api.md +++ b/docs/developers/api.md @@ -22,7 +22,7 @@ these ways: * Look for the RSS feed links. * Examine the `<link rel="alternate" type="application/atom+xml">` tag in the head of the HTML. -* Add `/feed` to the start of another URL. +* Add `/feed` to the start of another URL. Note that even complicated search queries have Atom feeds. You can do all sorts of things with them, such as query by authority, by file type, by date range, @@ -73,9 +73,13 @@ as follows: * as form variable `json`: * `direction` - either `request` (from the user - might be a followup, reminder, etc) or `response` (from the authority) * `body` - the message itself + * `state` - optional, allows the authority to include an updated request `state` value when sending an update. Allowable values: `waiting_response`, `rejected`, `successful` and `partially_successful`. Only used in the `response` direction * `sent_at` - ISO-8601 formatted time that the correspondence was sent * (optionally) the variable `attachments` as `multipart/form-data`: * attachments to the correspondence. Attachments can only be attached to messages in the `response` direction +* `/api/v2/request/<id>/update.json` - POST a new state for the request: + * as form variable `json`: + * `state` - the user's assessment of the `state` of a request that has received a response from the authority. Allowable values: `waiting_response`, `rejected`, `successful` and `partially_successful`. Should only be used for the user's feedback, an authority wishing to update the request `state` should use `/api/v2/request/<id>.json` instead diff --git a/docs/developers/directory_structure.md b/docs/developers/directory_structure.md index 9dbe06789..34a92b411 100644 --- a/docs/developers/directory_structure.md +++ b/docs/developers/directory_structure.md @@ -33,6 +33,30 @@ website](http://guides.rubyonrails.org/getting_started.html). <p><em>the core Alaveteli application code</em></p> <dl> <dt> + assets + </dt> + <dd> + <em>static assets that require precompilation before being served</em> + <dl> + <dt> + fonts + </dt> + <dt> + images + </dt> + <dt> + javascripts + </dt> + <dt class="last"> + stylesheets + </dt> + <dd class="last"> + <p><em>stylesheets in CSS or <a href="http://sass-lang.com/">SCSS</a> format.</em></p> + <p>SCSS stylesheets are compiled to CSS.</p> + </dd> + </dl> + </dd> + <dt> controllers </dt> <dt> @@ -44,54 +68,16 @@ website](http://guides.rubyonrails.org/getting_started.html). <dt> models </dt> - <dt> - sass - </dt> <dt class="last"> views </dt> </dl> </dd> - <dt> - assets + <dt>cache </dt> - <dd> - Static assets - <dl> - <dt> - css - </dt> - <dd> - Rendered stylesheets - </dd> - <dt> - img - </dt> - <dd> - static images - </dd> - <dt> - sass - </dt> - <dd> - Stylesheets in SCSS format, which are compiled to CSS - </dd> - <dt class="last"> - scripts - </dt> - <dd class="last"> - JavaScript - </dd> - </dl> + <dd><p><em>cached files for downloads, attachments and templates.</em></p> </dd> <dt> - bootstrap - </dt> - <dd> - <p> - Alaveteli's default style uses Bootstrap. - </p> - <dt> commonlib </dt> <dd> @@ -155,9 +141,13 @@ website](http://guides.rubyonrails.org/getting_started.html). <dt> tasks </dt> + <dd><a href="http://guides.rubyonrails.org/command_line.html#rake">Rake</a> tasks. + </dd> <dt class="last"> - whatdotheyknow + themes </dt> + <dd class="last">This is where your Alaveteli theme lives. + </dd> </dl> </dd> <dt> @@ -171,33 +161,15 @@ website](http://guides.rubyonrails.org/getting_started.html). </p> </dd> <dt> - public + log </dt> <dd> - <p><em>static assets</em></p> - <dl> - <dt> - admin - </dt> - <dd> - images, JavaScript and stylesheets used by the admin back-end - </dd> - <dt> - fcgi - </dt> - <dd> - Fast CGI files for serving static assets - </dd> - <dt> - images - </dt> - <dt> - javascripts - </dt> - <dt class="last"> - stylesheets - </dt> - </dl> + <p><em>application log files.</em></p> + </dd> + <dt> + public + </dt> + <dd> <p><em>static files that can be served directly.</em></p> </dd> <dt> script @@ -219,17 +191,6 @@ website](http://guides.rubyonrails.org/getting_started.html). </p> </dd> <dt> - stylesheets - </dt> - <dd> - <p> - <em>global stylesheet</em> - </p> - <p> - Actually just <code>global.css</code> - </p> - </dd> - <dt> tmp </dt> <dd> @@ -243,10 +204,10 @@ website](http://guides.rubyonrails.org/getting_started.html). <dd class="last"> <p><em>third-party software</em></p> <dl> - <dt class="last">plugins</dt> + <dt class="last">bundle</dt> <dd class="last"> <p> - Plugins + <em>the bundle of gems needed to run Alaveteli</em> </p> </dd> </dl> diff --git a/docs/developers/i18n.md b/docs/developers/i18n.md new file mode 100644 index 000000000..fb7f2930b --- /dev/null +++ b/docs/developers/i18n.md @@ -0,0 +1,177 @@ +--- +layout: page +title: Internationalisation (for devs) +--- + +# Internationalisation in the code + +<p class="lead"> + This page describes some technical aspects of + <a href="{{ site.baseurl }}docs/glossary/#i18n" class="glossary__link">internationalising</a> + 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 <a href="{{ site.baseurl }}docs/glossary/#transifex" class="glossary__link">Transifex</a> +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> + +### What to do if you don't have complete translations for an older release of Alaveteli + +Before a new release of Alaveteli is made, the translation files are +pulled from Transifex and added to Alaveteli's ``locale/`` directory in +github. These represent the most complete translations for the previous +release. Then the files in Transifex are updated with any new strings +that need to be translated for the upcoming release. At this point old +strings that are no longer used in the new release are also removed. The +latest [release tag](https://github.com/mysociety/alaveteli/releases) +for a release in github should contain the most complete translations +for that release from Transifex. + +If you're using an older release of Alaveteli and you want to add to or +change the translations, you can edit the .po files directly using a +local program such as [PoEdit](http://poedit.net/). + +### 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 9d1869246..f1167a22b 100644 --- a/docs/developers/index.md +++ b/docs/developers/index.md @@ -45,7 +45,7 @@ title: For developers [manual installation]({{ site.baseurl }}docs/installing/manual_install/). Alternatively, there's an [Alaveteli EC2 AMI]({{ site.baseurl }}docs/installing/ami/) that might help you get up and running quickly. - [Get in touch](http://www.alaveteli.org/contact/) on the project mailing list or IRC + [Get in touch]({{ site.baseurl }}community/) on the project mailing list or IRC for help. * A standard initial step for customising your deployment is [writing a @@ -53,10 +53,10 @@ title: For developers 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... |