This file is indexed.

/usr/share/doc/gnumed/user-manual/Gnumed/BackendI18N.html is in gnumed-doc 1.4.6+dfsg-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en_US" lang="en_US">
<head>
	<title> BackendI18N &lt; Gnumed &lt; Foswiki</title>
		  
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <meta name="robots" content="noindex" /> <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="WebRss.html" />
	<link rel="icon" href="../rsrc/System/ProjectLogos/favicon.ico" type="image/x-icon" /> <link rel="shortcut icon" href="../rsrc/System/ProjectLogos/favicon.ico" type="image/x-icon" />
	<link rel="alternate" href="http://wiki.gnumed.de/bin/edit/Gnumed/BackendI18N?t=1391005508" type="application/x-wiki" title="edit BackendI18N" />
	<meta name="description" content="BackendI18N" />
	 <!--[if IE]></base><![endif]-->
	
	<style type="text/css" media="all">
@import url('../rsrc/System/SkinTemplates/base.css');
</style>
<style type="text/css" media="all">
@import url('../rsrc/System/SkinTemplates/default.css');
</style>
<!--[if IE]><style type="text/css" media="screen">
pre {
	overflow-x:auto;
	padding-bottom:expression(this.scrollWidth > this.offsetWidth ? 16 : 0);
}
</style>
<![endif]-->

<meta name="foswiki.PUBURL" content="http://wiki.gnumed.de/pub" /> <!-- PUBURL -->
<meta name="foswiki.PUBURLPATH" content="/pub" /> <!-- PUBURLPATH -->
<meta name="foswiki.SCRIPTSUFFIX" content="" /> <!-- SCRIPTSUFFIX -->
<meta name="foswiki.SCRIPTURL" content="http://wiki.gnumed.de/bin" /> <!-- SCRIPTURL -->
<meta name="foswiki.SCRIPTURLPATH" content="/bin" /> <!-- SCRIPTURLPATH -->
<meta name="foswiki.SERVERTIME" content="29%20Jan%202014%20-%2015:25" /> <!-- SERVERTIME -->
<meta name="foswiki.SKIN" content="twikinet%2c%20pattern" /> <!-- SKIN -->
<meta name="foswiki.SYSTEMWEB" content="System" /> <!-- SYSTEMWEB -->
<meta name="foswiki.TOPIC" content="BackendI18N" /> <!-- TOPIC -->
<meta name="foswiki.USERNAME" content="KarstenHilbert" /> <!-- USERNAME -->
<meta name="foswiki.USERSWEB" content="Main" /> <!-- USERSWEB -->
<meta name="foswiki.WEB" content="Gnumed" /> <!-- WEB -->
<meta name="foswiki.WIKINAME" content="KarstenHilbert" /> <!-- WIKINAME -->
<meta name="foswiki.WIKIUSERNAME" content="Main.KarstenHilbert" /> <!-- WIKIUSERNAME -->
<meta name="foswiki.NAMEFILTER" content="%5b%5cs%5c*%3f~%5e%5c%24%40%25%60%22'%26%3b%7c%3c%3e%5c%5b%5c%5d%23%5cx00-%5cx1f%5d" /> <!-- NAMEFILTER --><!--JQUERYPLUGIN::FOSWIKI::META-->
<script type='text/javascript' src='../rsrc/System/JQueryPlugin/jquery-1.4.3.js'></script><!--JQUERYPLUGIN-->
<script type='text/javascript' src='../rsrc/System/JQueryPlugin/plugins/livequery/jquery.livequery.js'></script><!--JQUERYPLUGIN::LIVEQUERY-->
<script type='text/javascript' src='../rsrc/System/JQueryPlugin/plugins/foswiki/jquery.foswiki.js'></script><!--JQUERYPLUGIN::FOSWIKI-->
<script type='text/javascript' src='../rsrc/System/JSTreeContrib/jquery.jstree.js'></script><!--JQUERYPLUGIN::JSTREE-->
</head>
<body class=""><div class="foswikiPage">
<a name="PageTop"></a> 
<p></p>
<p></p>
<h1><a name="i18n_47l10n_handling_in_the_backend"></a>  i18n/l10n handling in the backend </h1>
<p></p>
<a name="foswikiTOC"></a><div class="foswikiToc"> <ul>
<li> <a href="#Rationale"> Rationale </a>
</li> <li> <a href="#Concepts"> Concepts </a>
</li> <li> <a href="#Database_objects"> Database objects </a> <ul>
<li> <a href="#Tables_and_Views"> Tables and Views </a>
</li> <li> <a href="#Functions"> Functions </a>
</li></ul> 
</li> <li> <a href="#How_it_all_fits_together"> How it all fits together </a> <ul>
<li> <a href="#How_to_add_translation_capabilities_to_your_database"> How to add translation capabilities to your database </a>
</li> <li> <a href="#How_to_provide_a_translated_column"> How to provide a translated column </a>
</li> <li> <a href="#How_to_add_translated_data_to_the_database"> How to add translated data to the database </a>
</li> <li> <a href="#How_to_add_a_translation_target_40language_41_to_the_database"> How to add a translation target (language) to the database </a>
</li></ul> 
</li></ul> 
</div>
<p></p>
<h2><a name="Rationale"></a>  Rationale </h2>
<p></p>
Many tables in GNUmed store enumerations such as the types of a document. It is not useful for German users to see a document type <em>referral letter</em>. They would much rather see <em>Arztbrief</em>. This sort of translation could be done at the application level by <code><a href="http://docs.python.org/library/gettext.html" target="_top">gettext</a></code>. However, it would be useful if there was a way to tell the database and the application that <em>referral letter</em> and <em>Arztbrief</em> really are one and the same thing such that users speaking different languages can work with one and the same database and understand each others document types. Hence there is a need to provide this translation capability right in the backend. However, <a href="PostgreSQL.html">PostgreSQL</a> does not directly support localization of database content yet.
<p></p>
<h2><a name="Concepts"></a>  Concepts </h2>
<p></p> <ul>
<li> translations are not to affect data in any way
</li> <li> allow for translations transparent to a SELECT
</li> <li> allow for on-demand translations in a SELECT
</li> <li> allow user to select a default output language
</li> <li> allow for switching the default output language per user as desired
</li> <li> allow for incomplete translations by falling back to a "default" language if no translation is available for a given string 
</li> <li> translations should refer to the same row in the translated column
</li></ul> 
<p></p>
<h2><a name="Database_objects"></a>  Database objects </h2>
<p></p>
For all the gory details refer to the <a href="DbStructure.html">database schema</a> docs. All the relevant objects are aggregated in the schema <code>i18n</code>.
<p></p>
<h3><a name="Tables_and_Views"></a>  Tables and Views </h3>
<p></p> <ul>
<li> <code>i18n.i18n_curr_lang</code> <ul>
<li> stores the per-user default output language
</li></ul> 
</li> <li> <code>i18n.i18n_keys</code> <ul>
<li> lists all the source strings that should be translated
</li></ul> 
</li> <li> <code>i18n.i18n_translations</code> <ul>
<li> holds all the string translations
</li></ul> 
</li> <li> <code>i18n.v_missing_translations</code> <ul>
<li> lists those strings that do not have a translation for a language found in <code>i18n.i18n_curr_lang</code>
</li></ul> 
</li></ul> 
<p></p>
<h3><a name="Functions"></a>  Functions </h3>
<p></p> <ul>
<li> <code>i18n.i18n(text)</code> <ul>
<li> used by database DDL scripts to register strings for translation
</li></ul> 
</li> <li> <code>i18n._(text)</code> and <code>i18n._(text, text)</code> <ul>
<li> used in =SELECT=s and view definitions to translate a given string
</li> <li> pretty much like <code>gettext()</code> in other programming languages, usually aliased as <code>_()</code>
</li> <li> there are convenience wrappers in the schema <code>public</code>
</li></ul> 
</li> <li> <code>i18n.set_curr_lang(text)</code> <ul>
<li> sets the default output language for the current user
</li></ul> 
</li> <li> <code>i18n.set_curr_lang(text, name)</code> <ul>
<li> sets the default output language for the user <code>name</code>
</li></ul> 
</li> <li> <code>i18n.force_curr_lang(text)</code> <ul>
<li> forces setting the default output language for the current user even if there are no translations available
</li></ul> 
</li></ul> 
<p></p>
<h2><a name="How_it_all_fits_together"></a>  How it all fits together </h2>
<p></p>
<h3><a name="How_to_add_translation_capabilities_to_your_database"></a>  How to add translation capabilities to your database </h3>
<p></p>
Import <code>gnumed/server/sql/gmI18N.sql</code> into your database. This is typically done during the bootstrapping process via the configuration files.
<p></p>
<a name="AddTranslatedColumn"></a>
<h3><a name="How_to_provide_a_translated_column"></a>  How to provide a translated column </h3>
<p></p>
Suppose we have a table which enumerates family relations. An obvious table design would be
<pre>
create table relationship (
    pk serial primary key,
    description text
);
</pre>
<p></p>
<a href="ClinicalOrganizingAndWorkflows.html">ClinicalOrganizingAndWorkflows</a> tables will <em>reference</em> the table by <code>relationship.pk</code>. Running a query like <code>select description from relationship where pk=1;</code> will return whatever was put into the database with the primary key 1, for example "sister". A German user, however, would prefer to get back the string "Schwester" instead. In other words we want frontends to be able to show a translation for the family member type, eg. for relationship.description. The simplest way owuld be to use the <code>_()</code> SQL function in the SELECT statement, eg.: <code>select description, _(description) as l10n_description from member where pk=1;</code>. This returns the translation for <code>relationship.description</code> as an additional column <code>l10n_description</code>.
<p></p>
In many cases it will be more convenient to define views that add a translation column such as:
<pre>
create view v&#95;relationships as
    select
        pk,
        description,
        &#95;(description) as l10n&#95;description
    from relationship
;
</pre>
One can then simply select from that view by <code>select l10n_description from v_relationships where pk=1;</code>.
<p></p>
<a name="AddTranslatedData"></a>
<h3><a name="How_to_add_translated_data_to_the_database"></a>  How to add translated data to the database </h3>
<p></p>
Even if the output language for a user is set and the appropriate columns are generated such that they translate their content we still need translated <em>data</em> in the database.
<p></p>
Typically, data is added by statements like <code>insert into relationship(description) values('sister');</code> which does not help any with translations. When inserting data that is to be used in translating columns one should do it like this: <code>insert into relationship(description) values(i18n.i18n('sister'));</code> The <code>i18n.i18n()</code> function will take care of additionally inserting the string <em>'sister'</em> into the <code>i18n.i18n_keys</code> table where translation teams will find it and provide a translation for, say, German like so: <code>insert into i18n_translations(lang, orig, trans) values ('de_DE', 'sister', 'Schwester');</code>. Now an appropriate SELECT should return the translated data.
<p></p>
A <a href="http://cvs.savannah.gnu.org/viewvc/gnumed/gnumed/server/locale/dump-missing-db_translations.py?root=gnumed&amp;view=markup" target="_top">script</a> is provided to help with finding and providing missing translations in the database.
<p></p>
<a name="AddTranslation"></a>
<h3><a name="How_to_add_a_translation_target_40language_41_to_the_database"></a>  How to add a translation target (language) to the database </h3>
<p></p>
Suppose you want to add a translation named <em>klg_PLUTO</em> to your host <code>farout</code>.
<p></p> <ul>
<li> use <code>select i18n.force_curr_lang('klg_PLUTO');</code> to set the language for the current user to <em>klg_PLUTO</em>
</li> <li> use <code>gnumed/server/locale/dump-missing-db_translations.py</code> to get the missing translations
</li> <li> translate the strings in the SQL script that was generated
</li> <li> run <code>psql -h farout -d gnumed_vXX -U gm-dbo -f the-file.sql</code> (replace XX with the version in question)
</li> <li> contact the developers so they can add your translation to the bootstrapping procedure
</li></ul> 
<a name="TopicEnd"></a>
<p></p>
<p></p>
<p></p>
<p></p>
</div>
</body></html>