Re: URI Templates - optional variables?

On 02/08/2007, at 8:02 AM, Roy T. Fielding wrote:

> I still think that URI templates need to define a syntax for
> defaulting and other common string substitutions, even if the
> initial authors have no need of it.

It's not that we don't have need of it, it's just that we haven't got  
a good answer for it yet, and we've been focused on the encoding  
issue. I, for one, am very open to suggestions.

> The fact is that there are
> a limited number of special characters left out of the URI syntax
> specifically for allowing delimited expansions like templates.
> Just because *this* application can live without it does not
> justify its denial for all those other applications that might
> need it.
>
> Instead, the draft should define a syntax that is capable of
> supporting more extensive (and perhaps application-specific
> derivatives) and then only require a minimal subset be supported
> by the authors' own class of applications.

That's roughly the path charted forward in previous discussion.

My preference is to define a set of conventions (like the ones you  
nominate below), without "turning them on" for a basic template  
processor; their use should be specifically nominated by the template  
author. That way, conventions like starting with '=' don't get in the  
way of other users, such as those that want to use bare URIs to refer  
to RDF in template variable names (to pull something out of the air).  
See below for an alternate approach.

> For example, the following are all trivial to implement and allow
> the simple case to be distinguished by the initial character:
>
>    {variable}
>         Substitute the value of variable.
>
>    {=default:variable}
>         If variable is defined and non-empty, then substitute the
>         value of variable.  Otherwise, substitute with the default
>         value defined by the string of non-colon characters between
>         the '=' and ':', if any.
>             E.g.,  {=red:favoritecolor}  = "value" or "red"
>
>    {?prefix:variable}
>         If variable is defined and non-empty, then substitute the
>         string of non-colon characters between the '?' and ':', if
>         any, followed by the value of variable.  Otherwise, substitute
>         with the empty string.
>            E.g.,   {?/:variable}       = "/value"      or ""
>                    {?;name=:variable}  = ";name=value" or ""
>                    {?#:variable}       = "#value"      or ""
>
>    {%separator:hashvar}
>         For each variable named in the value of hashvar (which could
>         be a space-separated string or some context-dependent hash
>         mechanism), if the named variable is defined and non-empty,
>         then substitute the concatenation of variable name, "=",
>         variable value.  If more than one substitution is made,
>         separate each substitution with the string of non-colon
>         separator characters between the '%' and ':'.
>            E.g.,   myhash = "name age sex location"
>                      name = "Fred"
>                       age = "41"
>                       sex = ""
>                  location = "USA"
>
>            then  {%&:myhash} = "name=Fred&age=41&location=USA"
>
>    {-offset:variable}
>    {-offset-length:variable}
>         Substitute a substring of the value of variable, as delimited
>         by the non-negative integer offset from the beginning of the
>         value string (0 = start of string) and including the remaining
>         characters (if any) up to the maximum given by the positive
>         integer length.  offset must be in the range [0-255].  length
>         must be in the range [1-256].
>             E.g.,  {-0-3:variable}     = "val" or ""
>                    {-3-2:variable}     = "ue"  or ""
>                    {-3-8:variable}     = "ue"  or ""
>                    {-2:variable}       = "lues"  or ""
>

These look good (though I'm less sure of the last one); however, I  
think you'd need to avoid using characters from the reserved rule  
(i.e., those that are *truly* not allowed in URIs) to avoid  
collisions, at least in the current approach that's taken. That's a  
somewhat smaller set, which is why I suggest NOT turning these rules  
on by default.

An alternate might be to require a prefix character that indicates  
the type of variable, rather than make it optional. A bit uglier for  
the default case ( {variable} would have to be something like  
{:variable}, unless there was a convention that if it were  
alphanumeric, it's a bare variable), but maybe workable.

If we can resolve that issue, I'm all for including a set of sensible  
formatting rules in the spec.

Cheers,

>
> I'll bet that will satisfy every common use case, short of regular
> expression substitutions, without being a burden to implementors.
> And, just in case it doesn't, reserve the other non-variable-name
> first characters for future extensions.  That way, if such an unknown
> character is found at the beginning of the template, all current
> implementations can recognize it as an extension even if they don't
> understand the extension yet.
>
>
> Cheers,
>
> Roy T. Fielding                            <http://roy.gbiv.com/>
> Chief Scientist, Day Software              <http://www.day.com/>
>
>


--
Mark Nottingham     http://www.mnot.net/

Received on Friday, 10 August 2007 05:09:40 UTC