Core-Gadget - Document Structure
This is a DRAFT rewrite of the basic document structure for gadgets... it is ONLY A DRAFT
<section title="Document Structure">
<section title="The <Module> Element"
<t>The root of the Gadget Specification Document is the <Module>
element. It's children MUST consist of no more than one <ModulePrefs>
element, no more than one <UserPref> element, and one or more
<Content> elements.</t>
<figure><artwork>
Module = element Module {
attribute specificationVersion { text },
undefinedAttribute*,
ModulePrefs?,
UserPref*,
Content+,
extensionElement*
}
</artwork></figure>
<t>The "specificationVersion" attribute identifies the version of the
OpenSocial specification the container MUST use to process and render
the Gadget Specification. The value is a string conforming to the
version identifier described in <xref target="Versioning"/>. If absense,
the default value is "1.0".</t>
<t>Text nodes included as children of the <Module> element
SHOULD be ignored.</t>
</section>
<section title="The <ModulePrefs> Element">
<t>The <ModulePrefs> element serves as a container for all
metadata, features and processing rules dealing with the gadget.
The children of the element consist of a variety of optional
attributes and elements.</t>
<figure><artwork>
ModulePrefs = element ModulePrefs {
attribute title { text }?,
attribute title_url { IRI }?,
attribute description { text }?,
attribute author { text }?,
attribute author_email { text }?,
attribute screenshot { IRI }?,
attribute thumbnail { IRI }?,
attribute height { text }?,
attribute width { text }?,
attribute doctype { "quirksmode" | text },
undefinedAttribute*,
(Require*
& Optional*
& Preload*
& Icon*
& Locale*
& Link*
& OAuth?
& OAuth2?,
extensionElement*)
}
</artwork></figure>
<t>The <ModulePrefs> element MAY contain zero or more <Require>,
<Optional>, <Preload>, <Icon>, <Locale> and
<Link> elements and MAY contain no more than one each of the
<OAuth> and <OAuth2> elements.</t>
<t>The "title" attribute specifies the gadget's title. If provided,
A container SHOULD use this value in any situation where a title bar or
other identifying name for the gadget is required.</t>
<t>If provided, containers SHOULD use the value of the "title_url"
attribute to provide a link target whenever the value of the "title"
attribute is displayed.</t>
<t>The "description" attribute provides an optional description of
the gagdget. If provided, Container's SHOULD use this value to provide
a description of the gadget wherever appropriate.</t>
<t>The "author" attribute optionally provides the name of the
author of the gadget. If provided, Container's SHOULD use this
value wherever appropriate.</t>
<t>The "author_email" attribute optionally provides the an email
address to serve as a point of contact for the author of the gadget.
Containers MAY display this value wherever appropriate.</t>
<t>The "screenshot" attribute provides an optional IRI of a visual representation
of the gadget, for instance, a screenshot. The referenced resource MUST
be an image on a publicly-accessible web site that is not blocked by
robots.txt. PNG is the preferred format, though GIF and JPG are also
acceptable. Gadget screenshots should be 280 pixels wide. The height of
the screenshot should be the "natural" height of the gadget when it is
in use. Containers SHOULD display this image on wherever appropriate to
provide a preview of the gadget to Users.</t>
<t>The "thumbnail" attribute provides an optional IRI of a gadget thumbnail.
The referenced resource MUST be an image on a publicly-accessible web site
that is not blocked by robots.txt. PNG is the preferred format, though GIF
and JPG are also acceptable. Gadget thumbnails SHOULD be 120x60 pixels and
SHOULD be smaller than images referenced using the "screenshot" attribute
but larger than any images linked to using
<xref target="Icons">/ModulePrefs/Link/@rel="icon"</xref>elements.</t>
<t>The optional "height" and "width" attributes respectively define, in pixes,
the preferred default display height and width of the gadget. Container's
SHOULD use this value to set the appropriate display dimensions for the
gadget.</t>
<t>The optional "doctype" attribute is a string that identifies the
preferred rendering model for the gadget. When set to "quirksmode",
the gadget SHOULD be rendered using the so-called "browser quirks mode".
Additional values can be used to support other rendering modes but
only "quirksmode" is defined by this specification.</t>
</section>
<section title="The <Require> and <Optional> Elements">
<t>The <Require> and <Optional> elements share a
common structure and are each used to declare OpenSocial features
that are either required or optional for the gadget to operate.
Element element consists of a feature identifier, a version, a
list of specific gadget views the feature dependency applies to,
and zero or more <Param> elements that provide specific
feature-dependent detail.</t>
<figure><artwork>
dependency =
attribute feature { text },
attribute version { text },
attribute views { text },
undefinedAttribute*,
Param*,
extensionElement,
Optional = element Optional { dependency }
Require = element Require { dependency }
Param = element Param {
attribute name { text },
undefinedAttribute*,
text
}
</artwork></figure>
<t>Features are collections of processing instructions and JavaScript
Library APIs that provide specific functionality to a gadget. A
feature might also place various constraints and rules on the container
and gadget when in use. Containers MUST honor the constraints and rules
of any feature it claims to support.</t>
<t>The "feature" attribute on the <Optiona> and <Require>
elements specifies the unique identifier of a feature.</t>
<t>The "version" attribute specifies the specific version of the identified
feature, using the syntax described in <xref target="Versioning"/>.</t>
<t>The "views" attribute specifies a comma separated list of views
for which the feature is optional or required. Containers SHOULD only
load features when an appropriate view is being rendered.</t>
<t>For every feature identified using a <Require> element,
the container MUST provide an implementation that matches the
version specified by the "version" attribute. The container
MUST display an error if it is incapable of providing an appropriate
implementation for a required feature.</t>
<t>For every feature identified using a <Optional> element,
the container MAY provide an implementation of the feature. If an
implementation is provided, it MUST match the version specified by
the "version" attribute.</t>
<t>Containers MUST NOT substitute versions of features that do not
match that which is requested by the gadget.</t>
<t>Containers SHOULD support as many versions of a feature as is
practical to facilitate backwards compatibility with existing gadgets.</t>
<t>Containers MAY refuse to support features or specific versions of features
that are known or assumed to be incompatible with the specification version
required by the Gadget, or that are known to be incompatible with other
Features or versions of Features required by the Gadget. For example, a
Container MAY not support the combination of @specificationVersion="1.0"
and <Require feature="opensocial" version="2.0">, or the combination
of <Require feature="opensocial" version="1.0"> and
<Require feature="opensocial-data" version="1.1">. In cases where such
combinations are requested, the Features are said to be conflicting.
Conflicting Features SHOULD be treated by Containers as if they were
unsupported. Containers SHOULD provide an error message describing conflicts
to Developers when a conflict is detected. If one or more of the conflicting
Features is specified as Optional by a Gadget, and the set of Required
features and specification version do not conflict, Containers SHOULD attempt
to render the Gadget by removing the conflicting optional Features, returning
false from
<xref target="gadgets.util.hasFeature">gadgets.util.hasFeature</xref>
for the features that have been removed. Containers SHOULD include the
largest set of Optional Features that does not produce conflicts.</t>
<t>It is possible for there to be feature version conflicts when two valid
feature dependencies exist for the same feature. This situation can occur
when the same feature is declared at a global scope (no @views specified)
and at a view scope (@views specified) but with differing @version values.
For example, if we are rendering a Gadget's "default" view and with
<Require feature="myfeature" version="1"> and
<Require feature="myfeature" version="2" views="default"> declared.
In such cases, Containers SHOULD use the Feature version from the Feature
declaration that explicitly matches the current View (See
/ModulePrefs/Required/@views and /ModulePrefs/Optional/@views) over other
Feature declarations. Developers can easily correct this conflict by always
using the @views attribute for Features in Gadgets that use mixed Feature
versions. <xref target="Issue-1133">Discussion</xref></t>
<section title="The <Param> Element">
<t>The <Param> element provides configuration details for a
feature dependency. When specified, these values will be made available
by the container to the gadget developer using the <spanx style="verb">gadgets.util.getFeatureParameters</spanx>
API, with the value of the "name" attribute serving as the parameter
key and the text value of the element serving as the parameter value.</t>
<t>When a feature dependency for a specific view has been defined,
the container SHOULD make only the parameters from the view-specific
dependency available to the gadget using the getFeatureParameters
API.</t>
</section>
</section>
<section title="The <Preload> Element">
<t>The <Preload> element is used to identify resources that
a container SHOULD load automatically when the gadget is processed
and rendered.</t>
<figure><artwork>
Preload = element Preload {
SignedFetch,
attribute href { IRI },
attribute views { text }?
}
</artwork></figure>
<t>The processing semantics of the <Preload> are generally
identical to those of those defined for the <spanx style="verb">gadgets.io.makeRequest</spanx>
API.</t>
<t>The "href" attribute specifies the IRI of the resource to fetch. The
value of this attribute matches the "url" parameter of the
<spanx style="verb">gadgets.io.makeRequest</spanx> API.</t>
<t><Preload> elements MAY use the Signed Fetch mechanism defined
by <xref target="SignedFetch"/> and MAY contain the same optional
attributes used to configure <Content> elements for signed
fetch as described in <xref target="signed-fetch"/>.</t>
<t>The "views" attribute provides a comma-separated list of views
for which this <Preload> element applies. Containers SHOULD NOT
preload resources that are not specified for the view being rendered.
If no "views" attribute is specified, then the content SHOULD be
preloaded for all views.</t>
<t>When processing the <Preload> element, the container
MUST sends an HTTP request to the IRI specified by the href
attribute. The results of that request MUST be converted into a
temporary object that is stored and accessed at runtime via
the <spanx style="verb">gadgets.io.makeRequest</spanx> API. The
container MUST NOT return a preloaded resource in response to
a call to <spanx style="verb">gadgets.io.makeRequest</spanx> unless:
<list style="symbols">
<t>The "url" parameter of the makeRequest call matches the
value of the <Preload> element's href attribute,</t>
<t>The <Preload> element's authz attribute value matches
one of the acceptable authorization types,</t>
<t>The "sign_owner" parameter of the makeRequest call matches the
value of the <Preload> element's sign_owner attribute,</t>
<t>The "sign_viewer" parameter of the makeRequest call matches the
value of the <Preload> element's sign_viewer attribute, and</t>
<t>The views attribute on the <Preload> element is either
unspecified or contains the name of the current view.</t>
</list>
</t>
</section>
<section title="The <Icon> Element (deprecated)">
<t>The <Link> Element is a currently deprecated mechanism
that was used in previous versions of this specification for
to provide an image to serve as an icon for the gadget. The
definition of the <Link> element is included here
for backwards compatibility purposes only and will be
permanently removed from future versions of this specification.</t>
<figure><artwork>
Icon = element Icon {
attribute mode { "base64" }?,
attribute type { mimeType }?,
text
}
</artwork></figure>
<t>Historically, <Icon> element was used in one of two ways:
(1) to provide a link via a URL to the image resource or (2) to
directly embed the image into the gadget specification using a
Base64-encoding of the binary data. The "mode" attribute is used
to identify which method is being used. When specified, the value
of "mode" MUST be "base64", in which case the text content of the
<Icon> element MUST be processed as Base64-encoded binary
data. If the "mode" attribute is omitted, the text content of the
element MUST be processed as a URL referencing an image document.
The "type" attribute is used to specified the MIME media type of
the image resource in either case.</t>
<figure><preamble>For example, to reference an icon by URL, it would be:</preamble>
<artwork><![CDATA[
<Icon type="image/png">http://www.example.org/images/icon.png</Icon>
]]></artwork></figure>
<figure><preamble>To embed the icon directly, it would be:</preamble>
<artwork><![CDATA[
<Icon mode="base64" type="image/png>{base64 data}</Icon>
]]></artwork></figure>
<t>Use of the <Icon> element has been deprecated in the current
version of this specification. Gadget developers SHOULD use the
<Link> element with a "rel" attribute value equal to "icon"
in place of the <Icon> element:</t>
<figure><artwork><![CDATA[
<Link href="http://www.example.org/images/icon.png" rel="icon" />
]]></artwork></figure>
</section>
<section title="The <Link> Element">
<t>The <Link> element is used to associate a variety of additional
resources with the gadget specification. At a minimum, the element MUST
contain the "rel" and "href" attributes.</t>
<figure><artwork>
Link = element Link {
attribute rel { text },
attribute href { IRI },
attribute method { "GET" | "POST" }?,
undefinedAttribute*,
text
}
</artwork></figure>
<t>The "href" attribute specifies the IRI of the resource being linked
to the gadget specification. The value MUST be usable for dereferencing
and therefore MUST be mapped to a URL following the rules specified
in [TODO: RFC 3987].</t>
<t>The specific relationship between the gadget specification and the
referenced resource is specified by the value of the "rel" attribute.
The value of the rel attribute can be any string value. This specification
defines a number of rel attribute values that are significant.
Implementations MUST NOT use any rel attribute value prefixed with
the characters "opensocial", "gadgets", or "events" that are not
defined by this specification.</t>
<t>The optional "match" attribute can be used with certain links to
specify the HTTP method that is to be used when dereferencing the
Link href. The "match" attribute is primarily used when working with
<xref target="gadget-lifecycle-events">Gadget Lifecycle Events</xref>.</t>
<t>The "rel" attribute values currently defined by this specification
are:</t>
<texttable>
<ttcol align="left" width="15%">"rel"</ttcol>
<ttcol align="left">Description</ttcol>
<c><spanx style="verb">icon</spanx></c>
<c>Used to link an image resource to the gadget specification that
serves as a representative icon for the gadget.</c>
<c><spanx style="verb">event</spanx></c>
<c>Used to associate a remote endpoint to which
<xref target="gadget-lifecycle-events">Gadget Lifecycle Events</xref>
are to be delivered.</c>
<c><spanx style="verb">event.addapp</spanx></c>
<c>Used to associate a remote endpoint to which
<xref target="gadget-lifecycle-events">Gadget Lifecycle Events</xref>
matching the "event.addapp" event are to be delivered.</c>
<c><spanx style="verb">event.removeapp</spanx></c>
<c>Used to associate a remote endpoint to which
<xref target="gadget-lifecycle-events">Gadget Lifecycle Events</xref>
matching the "event.removeapp" event are to be delivered.</c>
<c><spanx style="verb">event.app</spanx></c>
<c>Used to associate a remote endpoint to which
<xref target="gadget-lifecycle-events">Gadget Lifecycle Events</xref>
matching the "event.app" event are are to be delivered.</c>
</texttable>
</section>
<section title="The <Locale> Element">
<t>The <Locale> element is used to provide localization
information for a gadget. Containers are required to honor
localization rules as specified in <xref target="Localization">
Localization</xref>. Each Locale tag represents localization
information for a single locale.</t>
<figure><artwork>
Msg = element msg {
attribute name { text },
undefinedAttribute*,
text
}
Locale = element Locale {
attribute lang { "all" | text }?,
attribute country { "all" | text }?,
attribute messages { IRI }?,
attribute language_direction { "rtl" | "ltr" }?,
attribute views { text },
undefinedAttribute*,
Msg*
}
</artwork></figure>
<t>The "lang" attribute specifies the language for the locale specified
as an ISO-639-1 Language Code, or the special value "all", which
containers MUST interpret as applying to all languages unless a more
specific match is found. If the lang attribute is not specified, the
default is considered to be "all".</t>
<t>The "country" attribute specifies the country code for the locale
specified as an ISO-3166-1 Country code, or the special value "all",
which containers MUST interpret as applying to all countries unless
a more specific match is found. If the country attribute is not specified,
the default is considered to be "all".</t>
<t>The optional "language_direction" attribute is used to specify
the default text rendering direction for the gadget. Valid values
are "ltr", to indicate "Left-to-Right" ordering, or "rtl" to indicate
"Right-to-Left" ordering. Directional rendering of text is discussed
in detail in <xref target="Localization"/>.</t>
<t>The optional "views" attribute specifies a comma-separated list
of gadget views for which the Locale information applies. Containers
SHOULD only use the information provided by the containing <Locale>
element when an appropriate view is being rendered.</t>
<t>The optional "messages" attribute specifies the IRI of an XML
document conforming to the <xref target="message-bundle-document">
Message Bundle Document</xref> format. The IRI specified MUST be
suitable for dereferencing. The container processing the gadget
specification MUST fetch the referenced resource and treat all
child elements of the root XML element in the document as though
they are child nodes of the containing <Locale> element.</t>
<t>The <Locale> element MAY contain zero or more <msg>
elements, each of which provide a singular localized value. The
key used to identify the value is specified using the "name" attribute.
The text content of the <msg> element provides the localized
value.</t>
<figure><preamble>An example <Locale> that uses a referenced
Message Bundle Document:</preamble><artwork><![CDATA[
<Locale language="en" country="US"
messages="http://example.org/i18n/en/messages.xml" />
]]></artwork></figure>
<figure><preamble>An example <Locale> that uses contained
<msg> elements:</preamble><artwork><![CDATA[
<Locale language="en" country="US">
<msg name="foo">This is the American English Version</msg>
<msg name="bar">Hello From My Gadget</msg>
</Locale>
]]></artwork></figure>
</section>
<section title="The <OAuth> Element">
<t>The <OAuth> element supplies the container with OAuth 1.0
specific configuration details for the gadget. For details see
<xref target="OAuth"/>.</t>
<figure><artwork>
OAuth = element OAuth {
undefinedAttribute*,
Service*,
extensionElement*
}
</artwork></figure>
<t>The <OAuth> element contains zero or more <Service>
elements, each of which detail a specific OAuth 1.0 service associated
with the gadget.</t>
<figure><artwork>
Service = element Service {
attribute name { text }?,
undefinedAttribute*,
element Request { OAuthResourceType }?,
element Access { OAuthResourceType }?,
element Authorization {
attribute url { IRI },
undefinedAttribute*,
extensionElement*
}?
}
OAuthResourceType = {
attribute url { IRI },
attribute method { "GET" | "POST" }?,
attribute param_location {
"auth-header" | "uri-query" | "post-body" }?,
extensionElement*
}
</artwork></figure>
<t>The optional "name" attribute on the <Service> element specifies
a name used to reference the service at runtime. If unspecified, the
value is assumed to be an empty string. Gadget developers specify which
OAuth Service they wish to use by passing the service name as a parameter
to the <spanx style="verb">gadgets.io.makeRequest</spanx> API.</t>
<t>The child elements of the <Service> element consist of the
<Request>, <Access> and <Authorization> elements,
each of which are optional but MUST NOT appear more than once within
a single <Service> element.</t>
<t>The <Request> element identifies the endpoint for acquiring
OAuth request tokens. The "url" attribute specifies the IRI of the
endpoint. This IRI MUST be suitable for dereferencing. The "method"
attribute specifies the HTTP verb to use when sending the request,
valid values are either "GET" or "POST". If not specified, the value
is assumed to be "POST". The "param_location" attributes specifies
how OAuth parameters are to be passed in the request. Valid options
are either "uri-query", "auth-header", and "post-body", corresponding
to the options described in <xref target="OAuth-Core">Section 5.2
of the OAuth specification</xref>. If not specified, the value is
assumed to be "auth-header".</t>
<t>The <Access> element identifies the endpoint for acquiring
OAuth access tokens. The <Access> element shares the same
attribute definitions as the <Request> element.</t>
<t>The <Authorization> element is used to acquire authorization.
The "url" attribute specifies the IRI of the endpoint. This IRI MUST
be suitable for dereferencing. For details, refer to
<xref target="OAuth-Core">Section 6.2 of the OAuth specification.</xref></t>
</section>
<section title="The <OAuth2> Element">
<t>The <OAuth2> element supplies the container with OAuth 2.0
specific configuration details for the gadget. For details see
<xref target="OAuth"/>.</t>
<figure><artwork>
OAuth2 = element OAuth2 {
undefinedAttribute*,
Service*,
extensionElement*
}
</artwork></figure>
<t>The <OAuth2> element contains zero or more <Service>
elements, each of which detail a specific OAuth 2.0 service associated
with the gadget.</t>
<figure><artwork>
Service = element Service {
attribute name { text }?,
attribute scope { text }?,
undefinedAttribute*,
element Authorization {
attribute url { IRI },
attribute method { "GET" | "POST" }?,
undefinedAttribute*,
extensionElement*
}?,
element Token {
attribute url {IRI},
undefinedAttribute*
}?
}
</artwork></figure>
<t>The optional "name" attribute on the <Service> element specifies
a name used to reference the service at runtime. If unspecified, the
value is assumed to be an empty string. Gadget developers specify which
OAuth Service they wish to use by passing the service name as a parameter
to the <spanx style="verb">gadgets.io.makeRequest</spanx> API.</t>
<t>OAuth2 Service elements MAY also specify an optional "scope" attribute
providing the scope used by default in all requests. Access Token Scope
is defined in Section 3.3 of the <xref target="OAuth2-Core">OAuth 2.0
specification.</xref></t>
<t>The child elements of the <Service> element consist of the
<Authorization>, <Token> elements,
each of which are optional but MUST NOT appear more than once within
a single <Service> element.</t>
<t>The <Authorization> element identifies the endpoint for acquiring
OAuth authorization tokens. The "url" attribute specifies the IRI of the
endpoint. This IRI MUST be suitable for dereferencing. The "method"
attribute specifies the HTTP verb to use when sending the request,
valid values are either "GET" or "POST". If not specified, the value
is assumed to be "GET".</t>
<t>The <Token> element is used to acquire OAuth 2.0 access tokens.
The "url" attribute specifies the IRI of the endpoint. This IRI MUST
be suitable for dereferencing. For details, refer to
<xref target="OAuth2-Core">Section 3.2 of the OAuth 2.0 specification.</xref></t>
</section>
<section title="The <UserPref> Element">
<t>The <UserPref> element is used within a gadget specification
to define a "user preference" for use within instances of the gadget.
Each instance of the <UserPref> element defines exactly one
preference value. Multiple <UserPref> elements MAY be used within
a gadget specification.</t>
<t>Containers MUST process each <UserPref> by making each
available to the gadget via the <spanx style="verb">gadgets.Prefs</spanx>
API, using the value of <UserPref> element's required "name" attribute as the
index key for storing and retrieving preferences using the API.</t>
<figure><artwork>
BaseUserPref = {
attribute name { text },
attribute display_name { text }?,
attribute default_value { text }?,
attribute required { "true" | "false" }?,
undefinedAttribute*,
extensionElement*
}
SimpleUserPref = element UserPref {
BaseUserPref,
attribute datatype {
"string" |
"hidden" |
"bool" |
"list" |
"number" }?
}
EnumUserPref = element UserPref {
BaseUserPref,
attribute datatype { "enum" },
element EnumValue {
attribute value { text },
attribute display_value { text }?,
undefinedAttribute*,
extensionElement*
}*,
extensionElement*
}
EnumPref = element SimpleUserPref | EnumUserPref
</artwork></figure>
<t>The "datatype" attribute specifies the data type for the instances
of the preference value at runtime. Valid values are "string", "hidden",
"bool", "list" and "number". If not specified, the value is assumed
to be "string". For more information on "datatype", refer to
<xref target="datatypes-values"/> below.</t>
<t>The "display_name" attribute specifies a preferred display name for the
preference. The value SHOULD be localized as described in <xref target="Localization" />.</t>
<t>The "default_value" attribute specifies the default value for instances
of the preference. The value of the attribute depends on the value
of the "datatype" attribute. Container's MUST provide the value of
the "default_value" attribute as the value of the preference when using the
<spanx style="verb">gadgets.Prefs</spanx> API and a stored value for the
preference does not yet exist.</t>
<t>The "required" attribute specifies whether instances of the preference
require a valid value in order for the gadget to function correctly.
Valid values are "true" and "false". If not specified, the value is
assumed to be "false". If the value is "true", Containers SHOULD
display an error message or a prompt if there is no value stored.</t>
<section title="User Preference Data Types">
<t>The default data type for all user preference values is "string",
represented either by omitting the "datatype" attribute on the
<UserPref> element or by explicitly specifying
<spanx style="verb">datatype="string"</spanx>. When datatype is "string",
The value of the "default_value" attribute and the stored value of
the user preference at runtime MUST be a string.</t>
<figure><preamble>An example "string" preference:</preamble>
<artwork><![CDATA[
<UserPref name="foo" datatype="string" default_value="foo"
display_name="Foo" required="true" />
]]></artwork></figure>
<t>When datatype equals "number", the value of the "default_value"
attribute and the stored value of the user preference at runtime
MUST be a numeric value.</t>
<figure><preamble>An example "number" preference:</preamble>
<artwork><![CDATA[
<UserPref name="foo" datatype="number" default_value="123"
display_name="Foo" required="true" />
]]></artwork></figure>
<t>When datatype equals "bool", the value of the "default_value"
attribute and the stored value of the user preference MUST
evaluate to "true" or "false" when accessed via the
<spanx style="verb">gadgets.Prefs.getBool</spanx> API.</t>
<figure><preamble>An example "bool" preference:</preamble>
<artwork><![CDATA[
<UserPref name="foo" datatype="bool" default_value="true"
display_name="Foo" required="true" />
]]></artwork></figure>
<t>When datatype equals "list", the value of the "default_value"
attribute and the stored value of the user preference MUST
be a pipe-delimited (|) string of values, returned as a
JavaScript array when accessed via the <spanx style="verb">gadgets.Prefs.getArray</spanx>
API.</t>
<figure><preamble>An example "list" preference:</preamble>
<artwork><![CDATA[
<UserPref name="foo" datatype="list" default_value="foo|bar|baz"
display_name="Foo" required="true" />
]]></artwork></figure>
<t>When datatype equals "hidden", the value of the "default_value"
attribute and the stored value of the user preference MUST
be a string. The difference between "hidden" and "string" is
that "hidden" user preferences are not visible and are not editable
by users by can be accessible via the <spanx style="verb">gadgets.Prefs.getString</spanx>
API.</t>
<figure><preamble>An example "hidden" preference:</preamble>
<artwork><![CDATA[
<UserPref name="foo" datatype="hidden" default_value="foo"
display_name="Foo" required="true" />
]]></artwork></figure>
<t>When datatype equals "enum", the <UserPref> element SHOULD
contain one or more <EnumValue> elements, each of which define
a single possible value for the preference. Each <EnumValue>
element contains a required "value" attribute that specifies a
string value, and an optional "display_value" attribute that specifies
a textual representation of the "value". If unspecified, the
"display_value" defaults to the "value". Containers SHOULD display
the "display_value" in place of "value" when rendering a user
interface for editing purposes. The value of the "default_value"
attribute and the stored value of the user preference MUST equal
one of the supplied <EnumValue> "value" attributes.</t>
<figure><preamble>An example "enum" preference:</preamble>
<artwork><![CDATA[
<UserPref name="foo" datatype="string" default_value="foo"
display_name="Foo" required="true">
<EnumValue value="foo" display_value="Foo" />
<EnumValue value="bar" display_value="Bar" />
<EnumValue value="baz" display_value="Baz" />
</UserPref>
]]></artwork></figure>
</section>
</section>
<section title="The <Data> Element">
<t>The <Data> element contains data pineline elements as
defined by <xref target="DataPipelining"/>. All data pipeline
elements defined in this block are registered globlly for all
views by default. Individual data pipeline elements MAY be specified
for particular views by adding the "view" attribute to the tag.</t>
<t>See <xref target="DataPipelining"/> for complete information
on the data pipelining mechanism and element definitions.</t>
</section>
<section title="The <ExternalServices> Element">
<t>The <ExternalServices> element contains zero or more
<ServiceTag> elements used to establish an "alias"
for container-managed external services utilized by the gadget.</t>
<figure><artwork>
ExternalServices = element ExternalServices {
undefinedAttribute*,
element ServiceTag {
attribute alias { text },
text
}*
}
</artwork></figure>
<t>The <ServiceTag> element has a single "alias" attribute whose
value is a string and textual content that provides a gadget-specific
plain-text label for the alias. Additional markup within the <ServiceTag>
is not allowed.</t>
<t>Currently, when making a remote request from within a gadget using
either the <spanx style="verb">OSAPI</spanx> or <spanx style="verb">gadgets.io.makeRequest</spanx> APIs,
the full URL of the remote service that is being invoked must be known
to the gadget and specified within the request, along with all other
details of the request. Often, however, it is desirable to offload the
responsibility of managing access to external services to the container,
for instance, when multiple services are available that implement the
same protocol and it would be difficult for a single gadget to keep
track of all instances; or when a potentially untrusted gadget needs to be given
access to secure backend systems. In such cases, a container can choose
to manage all of the details involved with connecting to and communicating
with the service and expose that service to the gadget via an "alias".</t>
<t>Once an alias for a service is established, a gadget specification
can use the <ServiceTag> element within <ExternalServices>
to declare a gadget-specific reference label for the alias that can be
used when invoking the <spanx style="verb">OSAPI</spanx> or
<spanx style="verb">gadgets.io.makeRequest</spanx> APIs in place of
the URL.</t>
<t>For example, suppose that a gadget requires access to a backend
enterprise application that implements a proprietary communications
protocol. Software is added to the container that allows it to
communicate with the backend system. All of the details including the
URL, authentication details, authorization, and so forth are configured
within the container by an administrator and an alias is assigned to
the service: "opensocial:service://example.com/api?version=1".</t>
<t>The gadget developer then creates the gadget specification and adds
a <ServiceTag> element referencing the alias and created a lobel
for the alias that can be used within the gadget's Javascript:</t>
<figure><artwork><![CDATA[
<Module>
...
<ExternalServices>
<ServiceTag alias="opensocial:service://example.com/api?version=1">
EnterpriseService
</ServiceTag>
</ExternalServices>
<Content>
...
<script>
...
var params = {
'alias' : 'EnterpriseService',
'href' : '/files',
'format': 'json',
};
osapi.http.get(params).execute(
function(result) {
...
}
);
...
</script>
...
</Content>
</Module>
]]></artwork></figure>
<t>When the gadget is installed, the container will attempt to match
the alias specified in the <ServiceTag> to any known configured
services -- in this case, our backend enterprise service -- and will
automatically proxy all gadget requests to the "EnterpriseService" label
to the backend service.</t>
<t>It is possible for multiple service instances managed by a
single container to share the same alias; for instance, when there are
multiple servers available that implement the same communication protocols.
In such cases, when the gadget is installed, the container can either
automatically select an appropriate service instance to map the <ServiceTag>
to or provide a choice to the user installing the gadget to select
which service instance to use.</t>
<t>If a <ServiceTag> specifies an alias that is not currently
known to the container, installation of the gadget SHOULD fail and
an error reported.</t>
</section>
<section title="The <Content> Element">
<t>The <Content> element provides the user interface and
runtime code for the gadget. A gadget specification MUST have
at least one <Content> element.</t>
<figure><artwork>
CommonContent = {
attribute preferred_height { text }?,
attribute preferred_width { text }?,
attribute view { text }?,
undefinedAttribute*
}
UrlContent = element Content {
CommonContent,
SignedFetch,
attribute type { "url" },
attribute href ( IRI ),
extensionElement*
}
ProxiedContent = element Content {
CommonContent,
SignedFetch,
attribute type { "html" }?,
attribute href { IRI },
extensionElement*
}
HtmlContent = element Content {
CommonContent,
attribute type { "html" }?,
text
}
Content = UrlContent | HtmlContent | ProxiedContent
</artwork></figure>
<t>The required "type" attribute specifies the type of content provided
by the <Content> element. Valid values are either "html" or "url".
Containers MUST process the <Content> element according to the
specific rules for each type.</t>
<t>The <Content> element MUST conform to the following rules:</t>
<list style="numbers">
<t>If the value of "type" is "html" and the "href" attribute is
specified, the content of <Content> MAY contain one or more
Data Pipeline elements as defined in <xref target="DataPipelining"/>.
The <Content> element MAY also contain any combination of the
"Signed Fetch" attributes defined by <xref target="signed-fetch" />.</t>
<t>If the value of "type" is "html", and the "href" attribute is
not specified, the content of <Content>
MUST NOT contain child elements and SHOULD be suitable for
handling as HTML [TODO: HTML]. The HTML markup SHOULD be wrapped
within a CDATA tag otherwise it MUST be escaped in order to prevent
the HTML from being interpreted by the XML parser; for
example, "<br>" as "&lt;br>".</t>
<t>If the value of "type" is "url", the <Content> element
MUST contain the "href" attribute and MUST NOT contain child elements
or text. Containers SHOULD ignore any elements or text contained
within the <Content>. The element MAY contain any combination
of the "Signed Fetch" attributes defined by <xref taret="signed-fetch"/>.</t>
<t>Any <Content> element MAY contain "preferred_height" and "
preferred_width" attributes that specify the preferred dimensions, in pixels,
the container SHOULD use when rendering the content.</t>
<t>Any <Content< element MAY contain a "views" attribute
that specifies a comma-separated list of views. A single gadget can
support multiple views. Each view is associated with at least one <Content>
element. When the container renders a gadget with multiple <Content>
elements, it will use the view name to select the appropriate content.</t>
</list>
<t>When a <Content> element uses the "href" attribute, the
view names listed in it's views attribute MUST NOT be used in any
other <Content> element. A single view name MAY
appear within multiple <Content> elements that specify
a "type" attribute value of "html" and do not include an "href" attribute.
How multiple <Content> elements sharing the same view name are
processed to provide the rendered content for a view is defined in
<xref target="content-processing-model"/>.</t>
<t><Content> elements that do not specify a "views" attribute
are considered, by default, to be associated with the "default" view.</t>
<section title="Processing Model" anchor="content-processing-model">
<t>Containers MUST conform to the following rules when rendering a
gadget view.</t>
<section title="HTML Content">
<figure><preamble>The simplest form of content provided by a gadget is HTML
associated with the "default" view:</preamble><artwork>
<Content type="html"><![CDATA[
<div>Hello World!</div>
]]></Content>
</artwork></figure>
<figure><preamble>The same example can be provided by explicitly naming
the default view in the element's views attribute:</preamble><artwork>
<Content type="html" views="default"><![CDATA[
<div>Hello World!</div>
]]></Content>
</artwork></figure>
<t>When the container renders the "default" view for the gadget, it
will select this <Content> element and display the HTML "<div>Hello World!</div>"
to the user.</t>
<t>If a gadget provides multiple "html" <Content> elements that
specify the same view, the content is concatenated together when
rendered in the order those <Content> elements appear within
the gadget specification:</t>
<figure><preamble>For instance, given two "html" Content elements
for the "default" view:</preamble><artwork>
<Content type="html"><![CDATA[
<div>Hello World!</div>
]]></Content>
<Content type="html" views="default,greeting"><![CDATA[
<div>How are you?</div>
]]></Content>
</artwork></figure>
<figure><preamble>When rendering the default view, the container
would generate the following:</preamble><artwork>
<div>Hello World!</div>
<div>How are you?</div>
</artwork></figure>
<figure><preamble>However, when rendering the "greeting" view,
the container would only select the <Content> element
that lists the "greeting" view:</preamble><artwork>
<div>How are you?</div>
</artwork></figure>
<t>Once the HTML content for a view has been assembled from the
appropriate <Content> elements, the container MUST perform
Variable Substitution on the resulting content as defined by
<xref target="variable-substitution"/>.</t>
</section>
<section title="Proxied Content">
<t>As an alternative to including HTML markup directly within
the gadget specification, a <Content> element that uses
type="html" MAY reference an external resource containing
HTML markup using the "href" attribute. When the gadget is
rendered, the container will fetch the external resource and
process it's HTML content as if it were included directly
within the <Content> element. This is commonly referred
to as "Proxied Content".</t>
<figure><preamble>An example of proxied content
associated with the "default" view:</preamble><artwork>
<Content type="html" href="http://example.org/hello.html"/>
</artwork></figure>
<t>When rendering the "default" view for a gadget containing
the above <Content> element, the container will issue an
HTTP request to the address provided by the "href" attribute
to retrieve the content.</t>
<t>The container MUST add the following additional query
string parameters to the address provided by the "href" attribute:
<list style="hanging">
<t hangText="lang">The preferred language of the user for which
the content is being rendered, specified as an ISO-639-1
language code.</t>
<t hangText="country">The country of the user for which the
content is being rendered, specified as an ISO-3166-1
country code.</t>
<t hangText="opensocial_proxied_content">MUST be specified
using the value "1". Servers can use this to identify
proxied content renders from other types of requests.</t>
</list>
</t>
<t>When the remote service returns the HTML content back to the
container, the container will continue to process it as if the
HTML had been directly included within the gadget specification.</t>
<t>Note that, whereas multiple HTML Content elements MAY share a
common view name, the view names associated with Proxied Content MUST be
unique to that <Content> element, therefore making concatentation
unnecessary. The container MUST, however, still perform
Variable Substitution on the returned HTML content.</t>
<t>If the response to the proxied request returns a successful HTTP
status code, the container MUST interpret the resulting response
body according to the rules for content declared inline.</t>
<t>If the response to the proxied request returns an unsuccessful
HTTP status code, the container SHOULD present a meaningful error
message to the end user. Containers SHOULD obtain a suitable error
message for display by displaying the content specified for a view
named as "{view-name}.error", where {view-name} matches the name
of the view that the proxied request was being processed for. If an
exact match can not be found, the special view name "default.error" should
be used. If content for the "default.error" is not present, the
container SHOULD display a generic message indicating that a
problem occurred.</t>
<figure><preamble>For instance, A Proxied Content for the "greeting"
view with a specific "greeting.error" view to display error responses:</preamble><artwork>
<Content type="html" href="http://example.org/hello.html" views="greeting"/>
<Content type="html" views="greeting.error">
There was an error retrieving the greeting content.
</Content>
</artwork></figure>
<figure><preamble>An alternative Proxied Content for the "greeting"
view that uses the "default.error" view to display error responses:</preamble><artwork>
<Content type="html" href="http://example.org/hello.html" views="greeting"/>
<Content type="html" views="default.error">
There was an error retrieving the content.
</Content>
</artwork></figure>
<t>Containers SHOULD cache the results of the HTTP request following
the recommendations of Section 13 of <xref target="RFC2616"/>. If
a container does support caching of data, it MUST also support
using the "refresh_interval" parameter to override the default
caching directives. TODO: How does that work?</t>
<t>TODO: Discuss the cache key requirements... the ones that are
in the spec currently need to be clarified.</t>
<t>TODO: Discuss Pipelined content</t>
</section>
<section title="Redirected Content">
<t>When using Proxied Content, the container is responsible for
sending the HTTP request to the remote server and processing the
content while the gadget is being rendered. Alternatively, by
using type="url" within the <Content> element, the container
can be instructed to provide a "direct view" of the content retrieved
from the remote source without additional processing. When the
gadget is being rendered for display within a Web Browser, this
can be achieved by using an HTML IFrame whose src attribute is
set to the value of the <Content> element's href attribute.
This is commonly referred to as "Redirected Content".</t>
<figure><preamble>An example of redirected content
associated with the "default" view:</preamble><artwork>
<Content type="type" href="http://example.org/hello.html"/>
</artwork></figure>
<t>When rendering the "default" view for a gadget containing
the above <Content> element, the container will issue an
HTTP request to the address provided by the "href" attribute
to retrieve the content and will display that to the user exactly
as it is returned from the server without any further processing.</t>
<t>The container MUST add the following additional query
string parameters to the address provided by the "href" attribute:
<list style="hanging">
<t hangText="lang">The preferred language of the user for which
the content is being rendered, specified as an ISO-639-1
language code.</t>
<t hangText="country">The country of the user for which the
content is being rendered, specified as an ISO-3166-1
country code.</t>
<t hangText="libs">A relative URL reference that points to
any JavaScript resources necessary to satisfy the optional
or required features listed within the gadget specifications
<ModulePrefs>. TODO: this needs more explanation</t>
</list>
</t>
<figure><preamble>When rendering the default view for a gadget containing
the above Redirected Content element, the container
would generate the following:</preamble><artwork>
...
>iframe src="http://example.org/hello.html?language=en&country=US&libs=????"
...
</artwork></figure>
<t>Like Proxied Content, view names associated with Redirected
Content MUST not be shared with any other <Content> elements
making concatenation unnecessary. Additionally, because Redirected
Content is rendered exactly as it is provided by the remote service,
Variable Substitution is not required. </t>
</section>
<section title="Authentication for Proxied and Redirected Content" anchor="signed-fetch">
<t>For Proxied and Redirected Content (as well as the <Preload>
element) the Signed Fetch mechanism described in
<xref target="SignedFetch"/> MAY be used to specify the type of
authentication used in the request sent to the remote service.</t>
<figure><preamble>The Signed Fetch attributes defined below MAY
be used on any Proxied and Redirected Content elements:</preamble><artwork>
NoAuth = {
attribute authz { "none" }?
}
AuthCommon = {
attribute refresh_interval { text }?,
attribute sign_owner { "true" | "false" }?,
attribute sign_viewer { "true" | "false" }?
}
OAuth1 = {
AuthCommon,
attribute authz { "oauth" },
attribute oauth_received_callback { text }?,
attribute oauth_request_token { text }?,
attribute oauth_request_token_secret { text }?,
attribute oauth_service_name { text }?,
attribute oauth_token_name { text }?,
}
OAuth2 = {
AuthCommon,
attribute authz { "oauth2" },
attribute oauth_received_callback { text }?,
attribute oauth_request_token { text }?,
attribute oauth_request_token_secret { text }?,
attribute oauth_service_name { text }?,
attribute oauth2_scope { text }?,
attribute oauth_token_name { text }?,
}
SignedAuth = {
AuthCommon,
attribute authz { "signed" },
}
SignedFetch = NoAuth | OAuth1 | OAuth 2 | SignedAuth
</artwork></figure>
<t>The "authz" attribute identifies the authentication type used when
submitting the request to fetch the resource. The valid values
are "none", "oauth", "oauth2" or "signed" and each correspond to
the values and meanings defined for the <spanx style="verb">gadgets.io.AuthorizationType</spanx> API.
When not specified, the default is assumed to be "none" indicating
that authentication is to be used.</t>
<t>When "authz" is equal to "oauth", requests sent to the
remote service MUST be authenticated using the OAuth 1.0 protocol.</t>
<t>When "authz" is equal to "oauth2", requests sent to the
remote service MUST be authenticated using the OAuth 2.0 protocol.</t>
<t>When "authz" is either "oauth" or "oauth2", the following
additional optional attributes MAY be included as defined by
<xref target="OAuth"/>:
<list style="symbols">
<t>oauth_received_callback</t>
<t>oauth_received_callback</t>
<t>oauth_request_token</t>
<t>oauth_request_token_secret</t>
<t>oauth_service_name</t>
<t>oauth2_scope</t>
<t>oauth_token_name</t>
</list>
</t>
<t>When "authz" is equal to "signed", the "Signed Fetch" mechanism
described by <xref target="SignedFetch"/> is to be used.</t>
<t>The "sign_owner" attribute indicates whether the identity of the
gadget "OWNER" needs be included in the request sent to fetch the
resource. If the value of this attribute is "true", the container
MUST include the identity of the gadget "OWNER".</t>
<t>The "sign_viewer" attribute indicates whether the identity of the
current gadget "VIEWER" needs to be included in the request sent to
fetch the resource. If the value of this attribute is "true", the
container MUST include the identity of the gadget "VIEWER".</t>
<t>TODO: Define refresh_interval.. currently it's role in
signed fetch is undefined</t>
</section>
</section>
</section>
</section> <!-- END DOCUMENT STRUCTURE -->
, multiple selections available,