- From: DeWitt Clinton <dewitt@unto.net>
- Date: Fri, 9 Nov 2007 18:26:23 -0800
- To: uri@w3.org
Hi all,
I want to offer the following draft up as an alternative proposal for URL
templates.
My goals are much the same as Joe's here -- to define a syntax that can
generate the 80% or so of the template-driven URLs that are most commonly
found on the web. As such this syntax is roughly equivalent to his in its
expressive capability.
The major differences are that I've traded the extensibility of Joe's operator
syntax for a more compact and concise representation, as well as slanted it
slightly toward the use-case of explicitly mapping values to keys in the
template (as is common when defining templates for existing search engines).
I'd love to hear feedback as I get to work coding this up. As we know,
code talks. Everything else walks.
-DeWitt
For the following examples, please assume that the following data is
available:
userId = "1776"
searchTerms = "kittens"
startIndex = <null>
count = "10"
page = "company/about.html"
categories = [ "uri", "atom", "search" ]
undefined = <null>
protocol = "http"
Rules:
- Templates patterns are surrounded by "{" and "}" characters and can appear
zero or more, non-overlapping times anywhere in a URL:
http://example.com/user/{userId} ->
http://example.com/user/1776
{protocol}://example.com/user/{userId} ->
http://example.com/user/1776
- Template parameters may take one of three forms:
- Form 1, stand-alone values:
http://example.com/user/{userId} ->
http://example.com/user/1776
- Form 2, key/value pairs:
http://example.com?{q=searchTerms} ->
http://example.com?q=kittens
- Form 3, values that are automatically assigned a key equal to the
template value name:
http://example.com/feed?{=count} ->
http://example.com/feed?count=10
- Templates consist of: an optional prefix, a list of parameters, and
an optional separator character.
If any template parameter in the list is expanded, then the prefix
is inserted at the beginning of the template substitution. The
default prefix is the empty string.
If two or more template parameters in the list are expanded, then
the separator is inserted between the substituted strings. The
default separator is the "&" character.
http://example.com{?q=searchTerms,num=count} ->
http://example.com?q=kittens&num=10
http://example.com{?q=searchTerms,n=startIndex?} ->
http://example.com?q=kittens
http://example.com{?x=undefined?,y=undefined?} ->
http://example.com
- Cardinality for repeating parameters is supported using the "?",
"+", and "*" characters, representing "zero or one", "one or more",
and "zero or more" substitutions respectively.
http://example.com{?q=searchTerms,start=startIndex?,num=count?} ->
http://example.com?q=kittens&num=10
http://example.com/{categories+/}
http://example.com/uri/atom/search
http://example.com{?category=categories*}
http://example.com?category=uri&category=atom&category=search
- Multi-character prefixes and suffixes, and prefixes and suffixes
that contain reserved characters or empty strings, are supported using
the "(" and ")" grouping characters.
http://example.com{(/static/)page?} ->
http://example.com/static/company/about.html
http://example.com{(/-/)categories*/} ->
http://example.com/-/uri/atom/search
http://example.com{?labels=categories*(,)} ->
http://example.com?labels=uri,atom,search
http://example.com{?mashup=categories*()} ->
http://example.com?mashup=uriatomsearch
http://example.com{?concat=categories*(+)} ->
http://example.com?concat=uri+atom+search
Limitations:
- Parameters are considered opaque. Semantic and/or type meaning can not
assigned via the template.
- Default parameter values are not supported.
- Enumerated choices for possible parameter values are not supported.
- Parameter list suffixes are not supported.
- Characters other than "=" to denote key/value pairs are not supported.
- More specific cardinalities, such as "two or more", "one or two", etc.,
are not supported
- Prefixes and suffixes (such as quotes) around individual repeated values
are not supported.
Notes:
- The "," character is used as the parameter list delimiter, rather than more
obvious "&" character (the default separator character) because templates
often appear in XML documents and escaping the "&" has proven to be
error-prone in practice, harmful to legibility, and adds to the string
length.
- The <xalphas> production perhaps should be broadened or narrowed
depending on the character set we think should be supported.
Examples:
Original OpenSearch 1.1 template example (still valid):
http://example.com/?q={searchTerms}&pw={startPage?}&format=atom
Revised OpensSearch example template:
http://example.com/{?q=searchTerms,pw=startPage?,format=example:format}
An Amazon product page URL:
http://www.amazon.com/gp/product/
{product-id}{/ref=source-id?}{/referrer-id?}
{?=pf_rd_m?,=pf_rd_s?,=pf_rd_r?,=pf_rd_t?,=pf_rd_p?,=pf_rd_i?,=pf_rd_i?}
Yahoo web search API, using names from OpenSearch and extension namespaces:
http://search.yahooapis.com/WebSearchService/V1/webSearch
{?appid=yahoo:appid,query=searchTerms,start=startIndex?,
results=count?,region=yahoo:region?}
Google Notebook (without namespace prefixes):
http://www.google.com/notebook/feeds/{user-id}/
notebooks/{notebook-id}/
{(/-/)category*/}
{?=updated-min?,=updated-max?,=alt?,=start-index?,
=max-results?,=entryID?,=orderby?}
Google Notebook (OpenSearch 1.1-style, with namespace prefixes):
http://www.google.com/notebook/feeds/{google:user-id}/
notebooks/{google:notebook-id}/
{(/-/)google:category*/}
{?updated-min=google:start-date?,updated-max=google:end-date?,
alt=google:format?,start-index=startIndex?,max-results=count?,
entryID=google:entry-id?,orderby=google:order-by?}
Bitworking:
http://bitworking.org/news{/entrypath*/}
Sparklines:
http://bitworking.org/projects/sparklines/spark.cgi
{?=d,=type?,=height?,=limits?,=min-m?,=max-m?,=last-m?,
=min-color?,=max-color?,=last-color?,=step?}
Code.google.com
http://code.google.com/p/{project}/
https://{project}.googlecode.com/svn/trunk
Google Apps for Your Domain
http://docs.google.com/a/{domain}/
mailto:{userid}@{domain}
BNF
<grouping-char> :: ="{" | "}" | "(" | ")"
<cardinality-char> ::= "+" | "*" | "?"
<reserved-char> ::= <grouping-char> | <cardinality-char> | "," | "="
<unreserved-char> ::= <xalphas> excluding <reserved-char>
<template> ::= "{" <template-body> "}"
<template-body> ::= <parameter-list> |
<prefix> <parameter-list> |
<parameter-list> <separator> |
<prefix> <parameter-list> <separator>
<prefix> ::= <unreserved-char> | "(" <ungrouped> ")"
<separator> ::= <unreserved-char> | "(" <ungrouped> ")"
<ungrouped> :: <ungrouped-char> | <ungrouped-char> <ungrouped>
<ungrouped-char> ::= <xalphas> excluding <grouping-char>
<parameter-list> ::= <parameter> | <parameter> "," <parameter-list>
<parameter> ::= <term> | <term> <cardinality-char>
<term> ::= <stand-alone-value> | "=" <auto-named-value> | <name> "=" <value>
<stand-alone-value> ::= <term>
<auto-named-value> ::= <term>
<name> ::= <term>
<value> ::= <term>
<term> ::= <unreserved-char> | <unreserved-char> <term>
Received on Saturday, 10 November 2007 02:26:33 UTC