OpenAjax Metadata 1.0 Specification Substitution
From MemberWiki
NOTE: This wiki page holds part of the OpenAjax Metadata 1.0 Specification.
Contents
|
Chapter 12: Variable Substitution
Introduction
This chapter describes the variable substitution features within OpenAjax Metadata.
OpenAjax Metadata includes the following variable substitution features:
- Property value substitution - (@@propname@@)
- Localization value substitution - (##localizationkey##)
- Widget ID substitution - (__WID__)
- BIDI substitution - (__BIDI_*__)
Additionally, OpenAjax Metadata includes the ability to encode HTML strings (entityencode(...)
) and escape JavaScript strings (escapequotes(...)
) in conjunction with @@propname@@
property name substitution and ##localizationkey##
localization substitution.
The sections below provide details on these features.
Property value substitution
For particular elements in OpenAjax Metadata (see element list below), the @@propname@@
syntax results in macro substitution such that the entire string, including the @@ symbols, is replaced by the current value for the property whose name is propname
.
To illustrate:
<widget ... > <property name="country" type="String" defaultValue="Iceland"/> <content> Current country is @@country@@. </content> </widget>
If the user brings up a property editor and changes the value of the 'country' property to "Spain", the developer tool MUST replace the string @@country@@
with the string "Spain" such that the following appears on the display screen at run time:
Current country is Spain.
Property substitution additional notes
If the text content contains the string @@propname@@
and there is no property named 'propname
', then the developer tool MUST NOT perform string substitution on the string @@propname@@
(i.e., the run-time value will be the string "@@propname@@").
Property substitution strings can use the entityencode()
construct to tell the developer tool to entity-encode HTML strings or the escapequotes()
construct to tell the developer tool to escape JavaScript strings. For details, see the section titled Encoding HTML strings and escaping JavaScript strings below.
Elements on which property substitution occurs
Developer tools MUST perform property substitution on the following elements (and no other elements):
- <content> (both when the content is inline and when a 'src' attribute is provided)
- <javascript> (both when the content is inline and when a 'src' attribute is provided)
Localization value substitution
For particular elements in OpenAjax Metadata (see element list below), the ##localizationkey##
syntax results in macro substitution such that the entire string, including the ## characters, is replaced by the localization string value corresponding to localizationkey
in the message bundle file.
To illustrate, consider the following widget metadata:
<widget ... > <locale lang="de" messages="localizations/de_ALL.xml"/> <locale lang="fr" messages="localizations/fr_ALL.xml"/> <locale messages="localizations/ALL_ALL.xml"/> <content> <input type="button" value="##PressMe##" NAME="button1" onClick="alert('Boo!')" /> </content> </widget>
The metadata contains one localization substitution variable (##PressMe##
), and it references three message bundle files, one for German, one for French, and one for all other languages.
The fr_ALL.xml
file contains the following:
<messagebundle> <msg name="PressMe">Presse-moi</msg> </messagebundle>
If the user's system is configured for the French language, the developer tool MUST replace the string ##PressMe##
with the string "Presse-moi" such that the following HTML content is used at run time:
<input type="button" value="Presse-moi" NAME="button1" onClick="alert('Boo!')" />
Localization substitution additional notes
If the text content contains the string ##localizationkey##
and there is no <msg>
element in the message bundle file named 'localizationkey
', then the developer tool MUST NOT perform string substitution on the string ##localizationkey##
(i.e., the run-time value will be the string "##localizationkey##").
Localization substitution strings can use the entityencode()
construct to tell the developer tool to entity-encode HTML strings or the escapequotes()
construct to tell the developer tool to escape JavaScript strings. For details, see the section titled Encoding HTML strings and escaping JavaScript strings below.
Elements on which localization substitution occurs
Developer tools MUST perform localization substitution on the following elements (and no other elements):
- <content> (both when the content is inline and when a 'src' attribute is provided)
- <javascript> (both when the content is inline and when a 'src' attribute is provided)
- Inline <require> elements (i.e., when the <require> element does not have a 'src' attribute)
- <preload> and <postload> elements
- <aboutMe>
- <author>
- <description>
- <directoryTitle>
- <example>
- <license>
- <quote>
- <reference>
- <remarks>
- <shortDescription>
- <title>
Widget ID (__WID__) substitution
Developer tools MUST generate a unique widget identifier string (the __WID__
string) for each widget instance, and MUST ensure that all occurrences of the string __WID__
within particular elements in OpenAjax Metadata (see element list below) are replaced by the unique widget identifier string.
To illustrate:
<widget ... > <content> <input id="__WID__-button" type="button" value="Press me" NAME="button1" onClick="alert('Boo!')" /> </content> </widget>
If the unique widget identifier string is W798311
, then the following HTML must be used at run time:
<input id="W798311-button" type="button" value="Press me" NAME="button1" onClick="alert('Boo!')" />
Widget ID substitution additional notes
Developer tools SHOULD create widget identifier strings that can be used without causing parsing problems in a variety of scenarios, including:
- An HTML attribute value (e.g.,
<div id="__WID__-title">
or<div class="__WID__-class">
) - A CSS selector (e.g.,
#__WID__-title: { color:green; }
) - JavaScript logic (e.g.,
var wid = "__WID__";
) - Different HTML character set encodings
To avoid parsing errors in the above scenarios, one recommended approach is to have the widget identifier string start with an ASCII alpha character (upper case A to Z or lower case a to z) and subsequently only contain ASCII alpha and ASCII numeric characters (0 to 9) and underscore characters (0x5F).
Elements on which widget ID substitution occurs
Developer tools MUST perform widget ID substitution on the following elements (and no other elements):
- <content> (both when the content is inline and when a 'src' attribute is provided)
- <javascript> (both when the content is inline and when a 'src' attribute is provided)
BIDI substitution
OpenAjax Metadata supports the following four substitution variables that can be useful to manage the rendering of content across languages whose primary directions are left-to-right (e.g., European languages) and right-to-left (e.g., Arabic and Hebrew). (Note: these four substitution variables come from the OpenSocial Gadgets specification version 0.9.)
Variable | Description |
---|---|
__BIDI_START_EDGE__ | This variable represents the side of the widget that is the starting point for content display. The value is "left" when the widget is in LTR-mode and "right" when the widget is in RTL-mode. |
__BIDI_END_EDGE__ | This variable represents the edge of the widget that is opposite to where content display starts. The value is "right" when the widget is in LTR-mode and "left" when the widget is in RTL-mode. |
__BIDI_DIR__ | The value of this variable is "ltr" when the widget is in LTR-mode and "rtl" when the widget is in RTL-mode. |
__BIDI_REVERSE_DIR__ | The value of this variable is "rtl" when the widget is in LTR-mode and "ltr" when the widget is in RTL-mode. |
Developer tools MUST ensure that macro substitution happens such that, at run-time, all occurrences of the above BIDI substitution strings within particular elements in OpenAjax Metadata (see element list below) are replaced by the appropriate substitution strings as described in the table above.
To illustrate:
<widget ... > <locale lang="en" messages="localizations/en_ALL.xml"/> <locale lang="ar" messages="localizations/ar_ALL.xml" language_direction="rtl"/> <locale messages="localizations/ALL_ALL.xml"/> <content> <div style="margin-__BIDI_START_EDGE__:30px;"> ... </div> </content> </widget>
Note that the widget metadata file references three message bundle files, one for English, one for Arabic (which includes the 'language_direction'
attribute to indicate that the dominant writing direction for that message bundle file is rtl
- right-to-left), and one for all other languages. If the user's system is configured for the Arabic language, then the following HTML content will be used at run time:
<div style="margin-right:30px;"> ... </div>
Elements on which BIDI substitution occurs
Developer tools MUST perform BIDI substitution on the following elements (and no other elements):
- <content> (both when the content is inline and when a 'src' attribute is provided)
- <javascript> (both when the content is inline and when a 'src' attribute is provided)
Variable substitution rules and guidelines
The order in which variable substitutions occur is implementation-dependent.
Widget developers SHOULD NOT nest the construction of variables. For example, the following snippet attempts to embed a Widget ID (__WID__
) substitution within a property substitution (@@MyProperty@@
). This technique represents nesting and is not permitted:
// NOT PERMITTED! @@MyProperty__WID__@@
Developer tools and widget developers SHOULD include appropriate protection against cross-site scripting (XSS) vulnerabilities. (See Security considerations in the Introduction chapter.)
Encoding HTML strings and escaping JavaScript strings
The following constructs can be used with @@propname@@
and ##localizationkey##
substitution variables:
Construct | Target usage scenario | Description |
---|---|---|
entityencode(...) | Strings that contain HTML markup | Causes the following characters in the substitution string to be replaced by an appropriate HTML character entity:
|
escapequotes(...) | Strings that contain JavaScript logic | Causes the following characters in the substitution string to be escaped by inserting a backslash character before each occurrence of the given character:
|
To illustrate, consider the following widget metadata for a widget that allows you to find hotels on the French Riviera within a particular price range (via the "PriceRange" property). The widget has message bundle files for German (de_ALL.xml
) and French (fr_ALL.xml
), as well as a fallback file for all other languages (ALL_ALL.xml
):
<widget ... > <property name="PriceRange" type="String" defaultValue=""/> <locale lang="de" messages="localizations/de_ALL.xml"/> <locale lang="fr" messages="localizations/fr_ALL.xml"/> <locale messages="localizations/ALL_ALL.xml"/> <content> <h2> ##entityencode(french_riviera)## </h2> <p> @@entityencode(PriceRange)@@ </p> <script type="text/javascript"> var french_riviera_string = "##escapequotes(french_riviera)##"; </script> </content> </widget>
If the user's system is configured for the French language and the fr_ALL.xml
file contains the following:
<messagebundle> <msg name="french_riviera">Cote d'Azur</msg> </messagebundle>
If the user brings up a property editor for the widget and enters the value "<100" for property "PriceRange", substitutions will be made as follows:
<h2> ##entityencode(french_riviera)## </h2>
- The developer tool MUST apply entityencode() substititution rules on the localization string for localization key "french_riviera" (whose value is
Cote d'Azur
), which will result in the string
<h2> Cote d'Azur </h2>
<p> @@entityencode(PriceRange)@@ </p>
- The developer tool MUST apply entityencode() substitution rules on the value for the
PriceRange
property (whose value is<100
), which will result in the string
<p> <100 </p>
var french_riviera_string = "##escapequotes(french_riviera)##";
- The developer tool MUST apply escapequotes() substitution rules on the localization string for localization key "french_riviera" (whose value is
Cote d'Azur
), which will result in the string
var french_riviera_string = "Cote d\'Azur";
All of the above will result in the following HTML content at run time:
<h2> Cote d'Azur </h2> <p> <100 </p> <script type="text/javascript"> var french_riviera_string = "Cote d\'Azur"; </script>
Unrecognized substitution functions
The previous section described two "substitution function" constructs, entityencode()
and escapequotes
, that can be used within @@propname
and ##localizationkey##
substitution variables.
Future versions of this specification might define other similar substitution functions. Also, particular products might extend the OpenAjax Metadata format by defining additional substitution functions. Therefore, it is possible that an OpenAjax Metadata file might use a substitution function that will not be recognized by a particular developer tool.
If a developer tool encounters a substitution function that it does not recognize, the result is implementation-dependent.