OpenAjax Metadata 1.0 Specification Substitution

From MemberWiki

Jump to: navigation, search

NOTE: This wiki page holds part of the OpenAjax Metadata 1.0 Specification.


<--previous       contents--^       next-->


Contents

Chapter 12: Variable Substitution

Introduction

This chapter describes the variable substitution features within OpenAjax Metadata.

OpenAjax Metadata includes the following variable substitution features:

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):


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.)

VariableDescription
__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:

ConstructTarget usage scenarioDescription
entityencode(...) Strings that contain HTML markup Causes the following characters in the substitution string to be replaced by an appropriate HTML character entity:
  • '&' (ampersand) becomes '&amp;'
  • '"' (double quote) becomes '&quot;'
  • ''' (single quote) becomes '&#039;'
  • '<' (less than) becomes '&lt;'
  • '>' (greater than) becomes '&gt;'
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:
  • '"' (double quote) becomes '\"'
  • ''' (single quote) becomes '\''
  • '\' (backslash) becomes '\\'


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&#039;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> &lt;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&#039;Azur </h2>
    <p> &lt;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.



<--previous       contents--^       next-->
Personal tools