Core Gadget - Variable Substitution and Localization

This is a DRAFT. Because of the close relationship between Variable Substitution and Localization, I edited those sections together... 

    <section title="Variable Substitution" anchor="VariableSubstitution">
      <t>The Variable Substitution capability provides the ability 
      for gadget developers to use special "Expression Language" (EL) 
      statements within their gadget specifications that the container 
      will replace with appropriate values when the gadget is rendered.</t>

      <figure><preamble>For example, given the following partial gadget 
      specification:</preamble><artwork><![CDATA[
  <Module>
    <ModulePrefs>
      ...
    </ModulePrefs>
    <Content type="html">
      One plus one is equal to ${1+1}.
    </Content>
  </Module>
      ]]></artwork></figure>

      <t>When the default view for this gadget is rendered, the expression
      "${1+1}" will be evaluated and replaced with the value "2", resulting 
      in the output:</t>

      <figure><artwork>
  One plus one is equal to 2.
      </artwork></figure>

      <t>Expression Language statements can be used to to access values 
      provided by reserved variable keys, variables defined using data 
      pipeline tags as defined by <xref target="DataPipeling"/>, or 
      literal values as in the previous example.</t>

      <t>The syntax for expressions is based on a subset of the
      <xref target="JSPEL">Java Server Pages Expression Language (JSPEL)</xref>.
      All basic operations defined by the JSPEL specification,
      such as string concatenation and matching, are supported. 
      However, the definition of custom functions, as defined in 
      <xref target="JSPEL" />, Section 1.15, is not supported at this time.</t>

      <t>Containers are required to support variable substitution using this
      Expression Language syntax.</t>

      <section title="Using Literal Statements">
        <t>As is defined by the <xref target="JSPEL">JSPEL</xref> specification,
        literal statements can be used. For instance, the "${1+1}" used in the 
        previous example is a literal statement that outputs the results of 
        adding the two numbers together. All forms of literal statement allowed
        by JSPEL may be used within OpenSocial.</t>

        <t>It is also possible to combine the use of literal statements with 
        other variables. For instance, the expression "${1 + count}" will 
        be replaced by the numeric value of the variable "count" plus the number
        one.</t>
      </section>

      <section title="Using Data Pipelining">
        <t>For all gadget instances, there is a <spanx style="verb">DataContext</spanx>
        object that stores and provides access to all of the data associated with
        the Gadget's use of the <xref target="DataPipelining">Data Pipelining</xref>
        capability. The information stored within the <spanx style="verb">DataContext</spanx>
        can be accessed either via expression statements or using the 
        <spanx style="verb">opensocial.data</spanx> API.</t>

        <figure><preamble>For instance, if we define a simple variable using the 
        data pipelining tags, we can access the value of that variable by naming 
        it within a substitution expression:</preamble><artwork><![CDATA[

  <Module xmlns:os="http://ns.opensocial.org/2008/markup">
    ...
    <Data>
      <os:Var key="myNumber" value="1" />
    </Data>
    <Content type="html">
      The value of myNumber is: ${myNumber}
    </Content>
  </Module>
        ]]></artwork></figure>

        <t>Additional information on the use of the <spanx style="verb">DataContext</spanx>
        with variable substitution can be found in <xref target="DataPipelining" />
        and <xref target="OpenSocial-Templating"/>.</t>
      </section>

      <section title="Using Reserved Variable Keys" anchor="ReservedVariableKeys">

        <t>Reserved Variable Keys are reserved variables names whose values are
        provided by the container. The keys take the form "{Prefix}.{Var}" 
        where "{Prefix}" identifies one of the predefined scopes below, and 
        "{Var}" specifies a specific variable within the identified scope.
        The applicability of each Prefix and Var combination will vary depending
        on where within the gadget specification the variable substitution is
        occurring.</t>

        <texttable align="left">
          <ttcol>Prefix</ttcol>
          <ttcol>Description</ttcol>
          <ttcol>Applicability</ttcol>

            <c>Msg</c>
            <c>References all message bundle variables for the current locale.
            The values of the {Var} component are selected from the applicable
            message bundle. For instance, if the bundle includes a key "FOO",
            then the expression ${Msg.FOO} will be replaced by the localized 
            value associated with "FOO" in the bundle.</c>
            <c>"Msg.*" variables are available anywhere within gadget, including 
            ModulePrefs and root Module element. Message bundle values may 
            reference other message bundle variables by making use of the 
            ${Msg.*} syntax within the value.</c>

            <c>Bidi</c>
            <c>Used to reference information about the currently selected 
            Locale's default text directionality as specified by the 
            text_direction attribute on the &lt;Locale&gt; element. The 
            BIDI variables are discussed in detail in <xref target="Localization"/>.</c>

            <c>ViewParams</c>
            <c>References all values passed as "viewParams" with a call to
            <xref target="gadgets.views.requestNavigateTo">gadgets.views.requestNavigateTo</xref>.
            The values of the {Var} component correlate to each view parameter.
            Expression statements using this prefix will resolve to the same values 
            as calls made to the <xref target="gadgets.views.getParams">gadgets.views.getParams</xref>
            API. For instance, the expression "${ViewParams.FOO}" will be 
            replaced by the same value returned by the API call
            <spanx style="verb">gadgets.views.getParams()["FOO"]</spanx>.</c>
            <c>"ViewParam.*" variables are available only within Content blocks, 
            <xref target="DataPipelining">Data Pipeline</xref> tags, 
            and OpenSocial Markup Language (OSML) tags. TODO: Provide Link</c>

            <c>Prefs</c>
            <c>References all named values defined by &lt;UserPref&gt; elements
            contained in the gadget specification. The values of the {Var} component 
            correlate to each defined user preference. Expression statements using
            this prefix will resolve to the same values as calls
            to the <xref target="gadgets.Prefs">gadgets.Prefs</xref> API.
            For instance, the expression "${Prefs.Lang}" will be replaced by 
            the same value returned by the API call <spanx style="verb">gadgets.Prefs.getLang()</spanx>;
            The expression "${Prefs.FOO}" will be replaced by the same value
            returned by the API call <spanx style="verb">gadgets.Prefs.getString("FOO")</spanx></c>
            <c>Available anywhere within gadget the gadget specification.</c>

            <c>Top</c>
            <c>Reserved variable used by 
            <xref target="OpenSocial-Templating">OpenSocial Templating</xref> 
            to represent the top level variables registered with the 
            <xref target="DataContext">DataContext</xref>.</c>
            <c>Available only within Content elements and templates as defined
            by <xref target="OpenSocial-Templating"/>.</c>

            <c>My</c>
            <c>Reserved variable used by
            <xref target="OpenSocial-Templating">OpenSocial Templating</xref> to
            represent local variables passed to the template instance.</c>
            <c>Available only within a template instance as defined by
            <xref target="OpenSocial-Templating"/>.</c>

            <c>Cur</c>
            <c>Reserved variable used by OpenSocial Markup Language (OSML) "repeaters" 
            as defined in the <xref target="OpenSocial-Templating">OpenSocial Templating specification</xref>.
            Represents the current value or object as a for-each loop would.</c>
            <c>Available only within a "repeater loop" as defined by 
            <xref target="OpenSocial-Templating"/>.</c>

            <c>Context</c>
            <c>Reservied variable used by OSML and templates to hold additional 
            variables generated while processing templates and loops as defined 
            in the <xref target="OpenSocial-Templating">OpenSocial Templating 
            specification</xref>.</c>
            <c>Available only within a template or "repeater loop" as defined 
            by <xref target="OpenSocial-Templating"/>.</c>

            <c>Viewer</c>
            <c>Reserved for future use.</c>
            <c>N/A</c>

            <c>Owner</c>
            <c>Reserved for future use.</c>
            <c>N/A</c>


            <c>Gadget</c>
            <c>Reserved for future use.</c>
            <c>N/A</c>
        </texttable>

        <figure><preamble>The following example illustrates the use of 
        Reserved Variables Names using the "Msg" prefix:</preamble>
        <artwork><![CDATA[
  <Module>
    <ModulePrefs title="${Msg.TITLE}">
      ...
      <Locale lang="en" country="US">
        <msg name="TITLE">My Gadget</msg>
        <msg name="GREETING">Hello There!</msg>
      </Locale>
      ...
    </ModulePrefs>
    <Content type="html"><![CDATA[
      <div>${Msg.GREETING}</div>
    ]]></Content>
  </Module>
        ]]></artwork></figure>
      </section>

      <section title="Deprecated Expression Syntax">

        <t>Previous versions of this specification supported a 
        -- now deprecated -- alternative expression syntax. Container
        implementations are permitted to continue supporting the deprecated
        syntax to provide backwards compatibility for older, 
        existing gadget specifications, however, gadget developers creating 
        new gadget specifications MUST NOT use the deprecated format.</t>

        <t>The legacy syntax takes the form "__{Prefix}_{Var}__" 
        where "{Prefix}" identifies one of the predefined scopes below, and 
        "{Var}" specifies a specific variable within the identified scope.</t>

        <figure><preamble>For instance, in the partial gadget example that 
        follows, the expression "__MSG_FOO__" is replaced for the localized
        value identified by the key "FOO" within the localized message bundle:</preamble>
        <artwork><![CDATA[
  <Module>
    <ModulePrefs title="__MSG_FOO__">
      ...
      <Locale language="en" country="US">
        <msg name="FOO">Hello World!</msg>
      </Locale>
      ...
    </ModulePrefs>
    <Content type="html">
      ...
    </Content>
  </Module>
        ]]></artwork></figure>

         <t>The {Prefix} keys supported by the legacy syntax are:</t>  

        <texttable align="left">
          <ttcol>Prefix</ttcol>
          <ttcol>Description</ttcol>   

          <c>MSG</c>
          <c>References all message bundle variables for the current locale.
          The values of the {Var} component are selected from the applicable
          message bundle. For instance, if the bundle includes a key "FOO",
          then the expression __MSG_FOO__ will be replaced by the localized 
          value associated with "FOO" in the bundle.</c>

          <c>BIDI</c>
          <c>References BIDI substitution variables whose values will reflect
          the default text direction as specified by the selected locale. 
          The BIDI variables are discussed in detail in <xref target="Localization"/>.</c>

          <c>MODULE</c>
          <c>Originally intended to provide a context for information about 
          the gadget specification itself. Currently, "ID" is the only 
          variable key supported (e.g. __MODULE_ID__). When used, the container
          SHOULD replace the "__MODULE_ID__" expression with a unique ID value
          for each instance of a gadget displayed simultaneously.</c>

          <c>UP</c>
          <c>References all named values defined by &lt;UserPref&gt; elements
          contained in the gadget specification. The values of the {Var} component 
          correlate to each defined user preference. Expression statements using
          this prefix will resolve to the same values as calls
          to the <xref target="gadgets.Prefs">gadgets.Prefs</xref> API.
          For instance, the expression "__UP_Lang__" will be replaced by 
          the same value returned by the API call <spanx style="verb">gadgets.Prefs.getLang()</spanx>;
          The expression "__UP_FOO__" will be replaced by the same value
          returned by the API call <spanx style="verb">gadgets.Prefs.getString("FOO")</spanx></c>
        </texttable>
      </section>

      <section title="Processing Requirements">

        <t>Containers perform Variable Substitution when instances of a 
        gadget are rendered or when metadata about the gadget is displayed.
        For instance, if the container includes the gadget specification 
        within a listing of gadgets available to install and use on a page, 
        then the container will perform any substitution necessary on the 
        displayed values.</t>

        <t>Containers are required to perform substitution on all 
        attributes or elements in the gadget specification document 
        exception of &lt;Locale&gt;, &lt;msg&gt;, &lt;EnumValue&gt; elements, 
        but only when the content of those elements and attributes is 
        currently being rendered. If, for instance, a gadget contains 
        multiple &lt;Content&gt; elements, each of which identify different
        views, the container will only process substitutions that are 
        included within the content for the view currently being rendered.
        Further, containers are required to perform all substitutions 
        that use either the Msg reserved variable key (i.e. "${Msg.FOO}") or 
        the MSG legacy syntax format (i.e. "__MSG_FOO__") before applying 
        any other substitutions.</t>

        <t>Variable substitution MUST NOT be applied recursively and 
        circular dependencies detected within variables MUST be ignored
        and treated as literal values rather than expressions. For instance,
        within the following partial gadget specification:</t>

        <figure><artwork><![CDATA[
  <Module xmlns:os="http://ns.opensocial.org/2008/markup">
    ...
    <Data>
      <os:Var key="key1" value="${key2}" />
      <os:Var key="key2" value="${key1}" />
    </Data>
    <Content type="html">
      ${key1}
      ${key2}
    </Content>
  </Module>
        ]]></artwork></figure>

        <t>The value of "key1" would be resolved as the literal value "${key1}".
        The value of "key2" would be resolved as the literal value "${key2}".
        The rendered output generated by the container would be:</t>

        <figure><artwork><![CDATA[
  ${key1}
  ${key2}
        ]]></artwork></figure>
      </section>   
    </section>
    <!--  END VARIABLE SUBSTITUTION -->

    <section title="Localization" anchor="Localization">

      <t>Localization of a gadget is achieved primarily through
      <xref target="VariableSubstitution">Variable Substitution</xref>, using the
      Msg reserved variable key and &lt;Locale&gt; elements.</t>

      <t>To determine the appropriate keys and values to use for substitution,
      containers will inspect the gadget specification for a &lt;Locale&gt; 
      element that matches the current view being rendered, as well as the 
      language and country of the viewer.</t>

      <t>A &lt;Locale&gt; is considered a match if either:
        <list style="symbols">
          <t>The default view is being rendered and the &lt;Locale&gt;
          elements view attribute is either unspecified or includes 
          "default" as one of it's supported views (e.g. views="default", or
          views="myview,default", etc), or the specific view being rendered is 
          named explicitly within the view attribute, and </t>
          <t>The language and country attributes on the &lt;Locale&gt; 
          element exactly match those of the viewer, or</t>
          <t>The language attribute is an exact match for the viewer 
          and the country attribute specifies "all", or</t>
          <t>Both the language and country attributes specify "all".</t>
        </list>
      </t>

      <t>How the container determines the current language and country 
      of the viewer is not defined by this specification.</t>

      <t>If a matching &lt;Locale&gt; is not found within the gadget 
      specification, the container is permitted to provide it's own
      localization data.</t>

      <t>Once an appropriate &lt;Locale&gt; has ben selected, containers
      are required to replace all Msg expressions for which a replacement
      value can be determined.</t>

      <t>For example, given the following partial gadget specification:</t>

      <figure><artwork><![CDATA[
  <Module>
    <ModulePrefs>
      ...
      <Locale language="en" country="all">
        <msg name="greeting">Hello World!</msg>
      </Locale>
      <Locale language="en" country="all" views="other">
        <msg name="greeting">Howdy!</msg>
      </Locale>
      <Locale language="fr" country="all">
        <msg name="greeting">Bonjour tout le monde!</msg>
      </Locale>
      ...
    </ModulePrefs>
    <Content type="html">
      ${Msg.greeting}
    </Content>
  </Module>
      ]]></artwork></figure>

      <t>When rendering the default view, the container will output 
      "Hello World!" for English-speaking viewers and "Bonjour tout le monde!"
      for French-speaking viewers.</t>

      <section title="Considerations for Bidirectional Text">

        <t>Gadget developers need to take care when working with languages 
        that require a default Right-to-Left ordering when rendering text.
        The "Bidi" reserved variable key can be used within Variable 
        Substitution expression statements to access information about the
        default text directionality as specified by the currently selected
        locale.</t>

        <t>The variables supported by the "Bidi" reserved variable key are:
          <list style="hanging">
            <t hangText="START_EDGE">When the selected &lt;Locale&gt; element's
            text_direction attribute specifies "rtl" (Right-to-Left"), the
            value of the Bidi.START_EDGE reserved variable key will be "right".
            When the attribute is either "ltr" (Left-to-Right) or unspecified, 
            the value will be "left".</t>
            <t hangText="END_EDGE">When the text direction is "rtl", the 
            value of Bidi.END_EDGE will be "left". When the attribute is either
            "ltr" or unspecified, the value will be "right".</t>
            <t hangText="DIR">The reserved variable key Bidi.DIR returns the 
            value of the &lt;Locale&gt; element's text_direction attribute 
            or "ltr" if the attribute is unspecified.</t>
            <t hangText="REVERSE_DIR">The reserved variable key Bidi.REVERSE_DIR
            returns the opposite of the &lt;Locale&gt; element's text_direction
            attribute value. If text_direction is "ltr",  Bidi.REVERSE_DIR will 
            return "rtl". If text_direction is "rtl", Bidi.REVERSE_DIR will
            return "ltr".</t>
          </list>
        </t>

        <figure><preamble>The Bidi variables can be used to establish the 
        correct text directionality when rendering. For instance:</preamble><artwork><![CDATA[
  <Module>
    <ModulePrefs>
      ...
      <Locale language="en" country="all">
        <msg name="greeting">Hello World!</msg>
      </Locale>
      <Locale language="ar" country="all" text_direction="rtl">
        <msg name="greeting">&#0645;&#0631;&#062D;&#0628;&#0627 &#0627;&#0644;&#0639;&#0627;&#0644;&#0645!</msg>
      </Locale>
      ...
    </ModulePrefs>
    <Content type="html">
      <div dir="${Bidi.DIR}">${Msg.greeting}</div>
    </Content>
  </Module>        
        ]]></artwork></figure>
      </section>

      <section title="Message Bundle Documents" anchor="MessageBundles">

        <t>The &lt;Locale&gt; element can either directly contain &lt;msg&gt;
        elements that define the keys and values used for localization or 
        can reference "Message Bundle Documents" that provide the collection
        of &lt;msg&gt; elements.</t>

        <figure><preamble>For instance, the following &lt;Locale&gt; element:</preamble>
        <artwork><![CDATA[
  <Locale language="en" country="US">
    <msg name="color">Color</msg>
    <msg name="red">Red</msg>
    <msg name="green">Green</msg>
    <msg name="blue">Blue</msg>
  </Locale>
        ]]></artwork></figure>

        <figure><preamble>Can be replaced with a &lt;Locale&gt; that references
        an external Message Bundle that includes the same &lt;msg&gt; elements:</preamble>
        <artwork><![CDATA[
  <Locale language="en" country="US" messages="http://example.com/en/messages.xml" />
        ]]></artwork>
        </figure>

        <figure><preamble>The Message Bundle at http://example.com/en/messages/xml:</preamble>
        <artwork><![CDATA[
  <messagebundle>
    <msg name="color">Color</msg>
    <msg name="red">Red</msg>
    <msg name="green">Green</msg>
    <msg name="blue">Blue</msg>
  </messagebundle>
        ]]></artwork></figure>

        <t>As illustrated, Message Bundles are XML documents whose root
        element is a &lt;messagebundle&gt; that contains zero or more
        &lt;msg&gt; elements that use the same format as the children 
        of the &lt;Locale&gt; element.</t>

        <figure><artwork>
  messagebundle = element messagebundle {
    undefinedAttribute*,
    element msg {
      attribute name { text },
      text
    }
  }
        </artwork></figure>

        <t>Variable substitution expressions MAY be used within Message 
        Bundle Documents.</t>

        <t>Each Message Bundle Document provides &lt;msg&gt; elements 
        for a single locale. By convention, Message Bundle documents are 
        named as {language}_{country}.xml, where {language} is either 
        an ISO-639-1 Language Code or "ALL" and {country} is an ISO-3166-1
        Country Code or "ALL". For instance, a Message Bundle providing 
        values for English-language speakers within the United States would
        be named "en_US.xml", while a Message Bundle providing German-language
        values for German-language speakers regardless of country would be 
        named "de_ALL.xml". The Message Bundle named "ALL_ALL.xml" would 
        apply to all languages in any country.</t>
      </section>
    </section>
    <!-- END LOCALIZATION -->