- From: James M Snell <jasnell@gmail.com>
- Date: Fri, 12 Oct 2007 21:04:48 -0700
- To: Joe Gregorio <joe@bitworking.org>
- CC: uri@w3.org
Joe Gregorio wrote: > [snip] > This is unsatisfactory for a lot of reasons, mostly related to how functional > the spec actually is. There is a large set of cases I think URI Templates can > be used for and I don't think the very simple templating mechanism defined > covers nearly enough cases. I also think that the story around > percent-encoding is hopelessly mired. For example, here are some examples > that I hope show that the current {var} system is inadequate: I'm rather sad that I have to agree. > [snip] > We can keep our simple {var} expansion, but let's add in > a default value: > > {var=default} > Simple substitution > > Example: > > URI Template > http://example.org/{fruit=orange}/ > Template Var > fruit = "apple" > URI > http://example.org/apple > Based on the template, this would actually expand to http://example.org/apple/ (note the trailing forward slash) > URI Template > http://example.org/{fruit=orange}/ > Template Var > fruit is undefined > URI > http://example.org/orange > Likewise, this would expand to http://example.org/orange/ > > {<prefix|var[=default]} > Prefix var with prefix, emit empty string if > var is empty or undefined. > > URI Template > bar{</|var}/ > Template Var > var := foo > URI > bar/foo/ > Again, we need to watch the trailing forward slashes. If var is empty or undefined, we end up with "bar/". > > {<postfix|var[=default]} > Append var with postfix, emit empty string if > var is empty or undefined. > > URI Template > bar/{>#home|var} > Template Var > var := foo > URI > bar/foo#home > My first thought on seeing this was to wonder if we'd need some way of indicating both a prefix and postfix for a single variable. > > {,sep|var1=def1, var2=def2, ...} > Substitute the concatenation of variable name, > "=", variable value. Join more than one var by the value > of 'sep'. > > URI Template > {,&|name,location,age} > Template Var > name := joe > location := NYC > URI > name=joe&location=NYC > You mention later that it's not clear how optional and multiple variables could be handled. Using ? and * is an option, e.g. {,&|?name,location,*age} which would indicate that name is optional, there must be one location parameter, and there may be many age parameters. name := undefined location := NYC age := [12,13,14] expands to location=NYC&age=12&age=13&age=14 > > {&sep|var} > Treat var as a list and join the values in the list > with the given separator. Emit empty string if var > is empty or undefined > URI Template > {&/|segments} > Template Var > segments := ["a", "b", "c"] > URI > a/b/c > I like this, but what about a prefix and postfix? e.g, I want the url template to produce either http://example.org/home or a listing of segments, http://example.org/home http://example.org/home/a http://example.org/home/a/b http://example.org/home/a/b/c We can use the template... http://example.org/home/{&/|segments} But this would always output the / following home. What if I want to make that / conditional on the evaluation of the template var? In theory I could add an empty string as the first element in the segment array and omit the slash from the template, URI Template http://example.org/home{&/|segments} Template Var segments := ["","a","b","c"] URI http://example.org/home/a/b/c > > > {?opt|var} > Inserts opt if var is a string or non-zero length list. > > URI Template > {?/|segments} > Template Var > segments := ["a", "b", "c"] > URI > / > Hmm.. ok, I see, this covers the previous case URI Template http://example.org/home{?/|segments}{&/|segments} Template Var segments := ["a","b","c"] URI http://example.org/a/b/c > [snip] > In the example from Google search, all variable names in the {,} > expansion are optional, i.e. > none of those variables need be defined. > > http://www.google.com/search?q={,&|term,num} > This example doesn't look quite right, if term=foo and num=2, wouldn't this expand to: http://www.google.com/search?q=term=foo&num=2 I would think the correct template would be: http://www.google.com/search{??|term,num}{,&|term,num} > Internationaliztion is also covered: > > http://www.google.com/search?q={term} > term := Îñţérñåţîöñåļîžåţîöñ > http://www.google.com/search?q=%C3%8E%C3%B1%C5%A3%C3%A9r%C3%B1%C3%A5%C5%A3%C3%AE%C3%B6%C3%B1%C3%A5%C4%BC%C3%AE%C5%BE%C3%A5%C5%A3%C3%AE%C3%B6%C3%B1 > While I'm perfectly happy restricting things to UTF-8, I'm wondering if there isn't a simple means by which we can explicitly establish an encoding within the template language. For instance, something like: {.UTF-8}http://www.google.com/search?q={term} > [snip] > So this system is pretty capable without crossing over into > the realm of Turing Complete. On the other hand, it is not > without fault: > > 1. Doesn't handle repeated query parameters. > 2. Doesn't specify if variables are mandatory or optional. > 3. Doesn't handle encodings besides UTF-8. I think these can be easily dealt with as demonstrated above. > 4. Template language is complex, cryptic. It doesn't look like we're going to be able to get around this. > 5. No handling of input validation, enums, ranges, etc. I'm definitely not convinced that this is even going to be necessary. > 6. Possible to define a self-inconsistent URI Template: > 1. {&|fred}{<#|fred} Stupid is as stupid does. > 7. Prefixes and suffixes are redundant, as > they could be handled by using the '?' expansion. Yes, but doing so does increase complexity somewhat. I'll have to stew on this one. > 8. Comma expansions could have two strings, one to separate > name-value pairs (as now), the other to separate names from > values (now hard-coded to "="). This would be simple if we could have a rule that separators had to be a single character, e.g. {,&=|?name,location,*age} name=a&location=b&age=c {,/;|?name,location,age} name;a/location;b/age/c > 9. Sensible defaults need to be invented to deal with parameter values > that are lists when not expected to be (or are not lists when > expected to be) (see #6). I've got no suggestions. > 10. No specification for how to handle IRIs beyond "Turn an IRI Template > into a URI Template and then proceed." This has been on my todo list for a while. Let me stew on this for a few days. > 11. Need way to say "Insert this if some/none of these variables exist" > to strip trailing "?" from URIs with no parameters. > No suggestions. > [snip] > And finally to those of you thinking to yourself, "that would be so > much better as working code", I present: > > http://code.google.com/p/uri-templates/ > > A Python implementation, with unit tests, requires 'tpg', the Toy > Parser Generator. > What, no erlang? > [snip] > So it's clear, I don't believe this is a final or complete solution, but I think > it's a good start and at least proves that expansions are a viable > solution to the percent-encoding issue. > Thank you for pushing forward on this. I'll see if I can get a Java impl going on this next week. - James > Thanks, > -joe >
Received on Saturday, 13 October 2007 04:05:01 UTC