paulb@615 | 1 | <?xml version="1.0" encoding="iso-8859-1"?> |
paulb@444 | 2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
paulb@444 | 3 | <html xmlns="http://www.w3.org/1999/xhtml"><head> |
paulb@444 | 4 | <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type" /> |
paulb@615 | 5 | <title>Creating Applications: Labelling Multiple-Choice Values</title> |
paulb@444 | 6 | <link href="styles.css" rel="stylesheet" type="text/css" /></head> |
paulb@444 | 7 | <body> |
paulb@444 | 8 | <h1>Creating Applications: Labelling Multiple-Choice Values</h1> |
paul@693 | 9 | |
paul@693 | 10 | <p>When introducing the item type multiple-choice field into the application, we defined the following values:</p> |
paul@693 | 11 | |
paul@693 | 12 | <pre> |
paul@693 | 13 | <?xml version="1.0"?> |
paul@693 | 14 | <type> |
paul@693 | 15 | <type-enum value="(Not selected)"/> |
paul@693 | 16 | <type-enum value="Important"/> |
paul@693 | 17 | <type-enum value="Not important"/> |
paul@693 | 18 | <type-enum value="Personal"/> |
paul@693 | 19 | </type> |
paul@693 | 20 | </pre> |
paul@693 | 21 | |
paul@693 | 22 | <p>For simple applications with a limited audience, it is often acceptable to |
paul@693 | 23 | use values which are then presented unchanged such that the value |
paul@693 | 24 | <code>Personal</code> is known both inside the application and is also shown to |
paul@693 | 25 | the user as the textual string <code>Personal</code>. However, for other |
paul@693 | 26 | applications there may be good reasons not to show values directly in this |
paul@693 | 27 | way:</p> |
paul@693 | 28 | |
paul@693 | 29 | <ol> |
paul@693 | 30 | <li>There may be a special internal value which is not descriptive; for example |
paul@693 | 31 | <code>123</code> representing the same concept as <code>Personal</code>.</li> |
paul@693 | 32 | <li>The value might be understandable not be understandable to some users; for |
paul@693 | 33 | example, the text <code>Personal</code> may not be understood by users who do |
paul@693 | 34 | not speak or otherwise use the English language.</li> |
paul@693 | 35 | </ol> |
paul@693 | 36 | |
paul@693 | 37 | <p>We must therefore consider introducing additional label information in order |
paul@693 | 38 | to remedy the first case, at least. Consequently, we may modify the defined |
paul@693 | 39 | values as follows:</p> |
paul@693 | 40 | |
paul@693 | 41 | <pre>?xml version="1.0"?> |
paul@693 | 42 | <type> |
paul@693 | 43 | <type-enum value="0">(Not selected)</type-enum> |
paul@693 | 44 | <type-enum value="I">Important</type-enum> |
paul@693 | 45 | <type-enum value="N">Not important</type-enum> |
paul@693 | 46 | <type-enum value="P">Personal</type-enum> |
paul@693 | 47 | </type></pre> |
paul@693 | 48 | |
paul@693 | 49 | <p>Here, we have provided user-visible labels which can now be used by the |
paul@693 | 50 | template. A single change to the item type choices list is required to include |
paul@693 | 51 | these labels as the visible text in that particular form control whilst |
paul@693 | 52 | maintaining the usage of the internal values:</p> |
paul@693 | 53 | |
paul@693 | 54 | <pre> |
paul@693 | 55 | <p> |
paul@693 | 56 | Item type: |
paul@693 | 57 | <select template:multiple-choice-list-field="type,type-enum,value" name="..." multiple="multiple" |
paul@693 | 58 | onchange="requestUpdate( |
paul@693 | 59 | 'comments', |
paul@693 | 60 | '{template:list-attribute('type-enum', 'value')}', |
paul@693 | 61 | '{template:other-elements(../options)}', |
paul@693 | 62 | '{template:child-attribute('value', template:child-element('comment', 1, template:other-elements(../options)))}', |
paul@693 | 63 | '/structure/item/options')"> |
paul@693 | 64 | <option template:multiple-choice-list-value="type-enum,value,selected<span style="font-weight: bold;">,text()</span>" value="..." /> |
paul@693 | 65 | </select> |
paul@693 | 66 | </p> |
paul@693 | 67 | </pre> |
paul@693 | 68 | |
paul@693 | 69 | <p>The addition, as described in the <a |
paul@693 | 70 | href="reference.html#multiple-choice-value"><code>template:multiple-choice-value</code></a> |
paul@693 | 71 | and <a href="reference.html#multiple-choice-list-value"><code>template:multiple-choice-list-value</code></a> |
paul@693 | 72 | sections of the <a href="reference.html">"Template Attribute Reference"</a> |
paul@693 | 73 | document, selects the text inside the appropriate <code>type-enum</code> |
paul@693 | 74 | elements and inserts it as a label into each choice in the item type list.</p> |
paul@693 | 75 | |
paul@693 | 76 | <h3>Updating the Web Resource</h3> |
paul@693 | 77 | |
paulb@615 | 78 | <p>To update the special WebStack resource, we |
paulb@444 | 79 | now need to modify a few of the class attributes:</p> |
paul@693 | 80 | |
paul@693 | 81 | <pre> |
paul@693 | 82 | template_resources = { |
paul@693 | 83 | "structure" : ("structure_multivalue_label_template.xhtml", "structure_output.xsl") |
paul@693 | 84 | } |
paul@693 | 85 | init_resources = { |
paul@693 | 86 | "structure" : ("structure_multivalue_label_template.xhtml", "structure_input.xsl") |
paul@693 | 87 | } |
paul@693 | 88 | document_resources = { |
paul@693 | 89 | "types" : "structure_types_label.xml" |
paul@693 | 90 | } |
paul@693 | 91 | </pre> |
paul@693 | 92 | |
paul@693 | 93 | <p>With these adjustments, it should now be possible to see the original labels |
paul@693 | 94 | and yet have the application manipulate a separate set of internal values. |
paul@693 | 95 | Note that it may be necessary to remove the old stylesheet for producing |
paul@693 | 96 | output, <code>structure_output.xsl</code>, so that the updated version of the |
paul@693 | 97 | template is taken into use.</p> |
paul@693 | 98 | |
paul@693 | 99 | <h3>Translating Labels</h3> |
paul@693 | 100 | |
paul@693 | 101 | <p>Whilst the above work made it possible to satisfy the first motivation of |
paul@693 | 102 | the use of labels - to hide internal values - it did not permit us to provide |
paul@693 | 103 | translations for different languages. In fact, there are at least two |
paul@693 | 104 | approaches which could provide labels in multiple languages:</p> |
paul@693 | 105 | |
paul@693 | 106 | <ol> |
paul@693 | 107 | <li>Define a file containing the <code>types</code> and <code>type-enum</code> |
paul@693 | 108 | elements for each language.</li> |
paul@693 | 109 | <li>Use the internationalisation support in XSLForms to translate the |
paul@693 | 110 | labels.</li> |
paul@693 | 111 | </ol> |
paul@693 | 112 | |
paul@693 | 113 | <p>The former approach might work in situations where multiple-choice values |
paul@693 | 114 | are obtained from a repository, such as a database, which contains the labels |
paul@693 | 115 | for items in each supported language. One can envisage a product database, for |
paul@693 | 116 | example, containing product descriptions for each language or market, and such |
paul@693 | 117 | information could be extracted in such a way that it could be convenient to use |
paul@693 | 118 | many different data files (or to extract the information dynamically, insert it |
paul@693 | 119 | into the form data document, and to provide a reference to the form data |
paul@693 | 120 | document as a source of value information).</p> |
paul@693 | 121 | |
paul@693 | 122 | <p>Let us concentrate, however, on the latter, more convenient approach for our |
paul@693 | 123 | example application. In order to produce translated labels, we must first |
paul@693 | 124 | define a <a href="internationalisation.html#PreparingTheTranslations">translations file</a> |
paul@693 | 125 | as described in the <a href="internationalisation.html">"Internationalisation"</a> |
paul@693 | 126 | document; this file can be saved alongside our other resources with the name |
paul@693 | 127 | <code>translations.xml</code>, and its contents can be defined as follows:</p> |
paul@693 | 128 | |
paul@693 | 129 | <pre> |
paul@693 | 130 | <?xml version="1.0" encoding="iso-8859-1"?> |
paul@693 | 131 | <translations> |
paul@693 | 132 | <locale> |
paul@693 | 133 | <code value="nb"/> |
paul@693 | 134 | <code value="nb_NO"/> |
paul@693 | 135 | <translation value="(Not selected)">(Ikke valgt)</translation> |
paul@693 | 136 | <translation value="Important">Viktig</translation> |
paul@693 | 137 | <translation value="Not important">Ikke viktig</translation> |
paul@693 | 138 | <translation value="Personal">Personlig</translation> |
paul@693 | 139 | </locale> |
paul@693 | 140 | </translations></pre> |
paul@693 | 141 | |
paul@693 | 142 | <p>To make use of this file, we must add additional references in the Web |
paul@693 | 143 | resource's attributes:</p> |
paul@693 | 144 | |
paul@693 | 145 | <pre> |
paul@693 | 146 | document_resources = { |
paul@693 | 147 | "types" : "structure_types_label.xml", |
paul@693 | 148 | <span style="font-weight: bold;">"translations" : "translations.xml"</span> |
paul@693 | 149 | } |
paul@693 | 150 | </pre> |
paul@693 | 151 | |
paul@693 | 152 | <p>And to introduce the translation mechanisms into the output production, we |
paul@693 | 153 | must modify the resource further:</p> |
paul@693 | 154 | |
paul@693 | 155 | <pre> |
paul@693 | 156 | # Complete the response. |
paul@693 | 157 | |
paul@693 | 158 | <span style="font-weight: bold;">stylesheet_parameters["locale"] = trans.get_content_languages()[0]</span> |
paul@693 | 159 | self.send_output(trans, [trans_xsl], structure, stylesheet_parameters, |
paul@693 | 160 | <span style="font-weight: bold;">references={"translations" : self.prepare_document("translations")}</span>) |
paul@693 | 161 | </pre> |
paul@693 | 162 | |
paul@693 | 163 | <p>Here, we define a <code>locale</code> parameter for the output stylesheet |
paul@693 | 164 | using the first language specified in each user's browser's language |
paul@693 | 165 | preferences. Then, we add a reference to the translations document specified |
paul@693 | 166 | above.</p> |
paul@693 | 167 | |
paul@693 | 168 | <p>Finally, we have to change the template to make use of the translations:</p> |
paul@693 | 169 | |
paul@693 | 170 | <pre> |
paul@693 | 171 | <p> |
paul@693 | 172 | Item type: |
paul@693 | 173 | <select name="..." template:multiple-choice-list-field="type,type-enum,value" multiple="multiple"> |
paul@693 | 174 | <option template:multiple-choice-list-value="type-enum,value,selected<span style="font-weight: bold;">,template:i18n(text())</span>" value="..." /> |
paul@693 | 175 | </select> |
paul@693 | 176 | </p> |
paul@693 | 177 | </pre> |
paul@693 | 178 | |
paul@693 | 179 | <p>Note that we use the <a |
paul@693 | 180 | href="../apidocs/XSLForms.Output-module.html#i18n"><code>template:i18n</code></a> |
paul@693 | 181 | extension function to modify the text found in each <code>type-enum</code> |
paul@693 | 182 | element in the types document. The usage of this function is described in the |
paul@693 | 183 | <a href="../apidocs/XSLForms.Output-module.html">extension function API |
paul@693 | 184 | documentation</a>.</p><p>Now, upon adding items in the application, if the |
paul@693 | 185 | browser is set up appropriately - in this case using <code>Norwegian |
paul@693 | 186 | Bokm?l [nb]</code> as the first choice of language - the item types will |
paul@693 | 187 | appear translated in the final output.</p> |
paul@693 | 188 | |
paul@693 | 189 | <h3>Sorting Choices</h3> |
paul@693 | 190 | |
paul@693 | 191 | <p>Despite offering translations of labels, our work may not be complete. For |
paul@693 | 192 | long lists of values, it may be desirable to sort the choices in an order that |
paul@693 | 193 | is meaningful to the user, and it might not be possible to rely on a suitable |
paul@693 | 194 | ordering of values from the source which provides them. Consider a list of |
paul@693 | 195 | countries where the underlying multiple-choice value is a two letter country |
paul@693 | 196 | code. If such a list were presented sorted by the country codes, yet were to |
paul@693 | 197 | employ labels which gave the translated names of the countries, the ordering |
paul@693 | 198 | would seem almost arbitrary and difficult to navigate for the user.</p> |
paul@693 | 199 | |
paul@693 | 200 | <p>To resolve such matters, we have to introduce an additional annotation in |
paul@693 | 201 | order to control the ordering of choices:</p> |
paul@693 | 202 | |
paul@693 | 203 | <pre> |
paul@693 | 204 | <p> |
paul@693 | 205 | Item type: |
paul@693 | 206 | <select name="..." template:multiple-choice-list-field="type,type-enum,value" multiple="multiple"> |
paul@693 | 207 | <option template:multiple-choice-list-value="type-enum,value,selected,template:i18n(text())" <span style="font-weight: bold;">template:sort="template:i18n(text())"</span> value="..." /> |
paul@693 | 208 | </select> |
paul@693 | 209 | </p> |
paul@693 | 210 | </pre> |
paul@693 | 211 | |
paul@693 | 212 | <p>By requesting that the choices be sorted according to the translated label, |
paul@693 | 213 | they should have an ordering that the user can relate to and navigate more |
paul@693 | 214 | easily.</p> |
paul@693 | 215 | |
paulb@444 | 216 | <h2>Further Reading</h2> |
paul@693 | 217 | |
paulb@444 | 218 | <p>Now that we have designed and implemented a simple application, it |
paulb@444 | 219 | may be worth reading some <a href="advice.html">recommendations</a> |
paulb@444 | 220 | about developing your own applications.</p> |
paulb@615 | 221 | </body></html> |