Alternative URL template proposal

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