GithubHelp home page GithubHelp logo

uri_template's Introduction

URITemplate - a uri template library

Build Status Dependency Status Code Climate Coverage

With URITemplate you can generate URIs based on simple templates and extract variables from URIs using the same templates. There are currently two syntaxes defined. Namely the one defined in RFC 6570 and a colon based syntax, similiar to the one used by sinatra.

From version 0.2.0, it will use escape_utils if available. This will significantly boost uri-escape/unescape performance if more characters need to be escaped ( may be slightly slower in trivial cases. working on that ... ), but does not run everywhere. To enable this, do the following:

# escape_utils has to be loaded when uri_templates is loaded
gem 'escape_utils'
require 'escape_utils'

gem 'uri_template'
require 'uri_template'

URITemplate::Utils.using_escape_utils? #=> true

Examples

require 'uri_template'

tpl = URITemplate.new('http://{host}{/segments*}/{file}{.extensions*}')

# This will give: http://www.host.com/path/to/a/file.x.y
tpl.expand('host'=>'www.host.com','segments'=>['path','to','a'],'file'=>'file','extensions'=>['x','y'])

# This will give: { 'host'=>'www.host.com','segments'=>['path','to','a'],'file'=>'file','extensions'=>['x','y']}
tpl.extract('http://www.host.com/path/to/a/file.x.y')

# If you like colon templates more:
tpl2 = URITemplate.new(:colon, '/:x/y')

# This will give: {'x' => 'z'}
tpl2.extract('/z/y')

# This will give a new uri template with just the host expanded:
tpl.expand_partial(host: "www.host.com")

RFC 6570 Syntax

The syntax defined by RFC 6570 is pretty straight forward. Basically anything surrounded by curly brackets is interpreted as variable.

URITemplate.new('{variable}').expand('variable' => 'value') #=> "value"

The way variables are inserted can be modified using operators. The operator is the first character between the curly brackets. There are seven operators defined #, +, ;, ?, &, / and .. So if you want to create a form-style query do this:

URITemplate.new('{?variable}').expand('variable' => 'value') #=> "?variable=value"

Benchmarks

I have assembled one benchmark based on the uritemplate-test examples. You can find them in the "benchmarks" folder. The short result: uri_template is 2-10x faster than addressable on ruby 1.9.3.

uri_template's People

Contributors

bhollis avatar bmaland avatar hannesg avatar peterhellberg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

uri_template's Issues

Colon templates uri-encode dashes

There seems to be a problem using :colon mode where it will encode dashes:

# With colons:
x = URITemplate.new(:colon, '/:year-:month-:day-:title.html')
x.expand(year: '2010', month: '01', day: '01', title: "foo-bar")
 => "/2010%2D01%2D01%2Dfoo-bar.html"

# With braces:
x = URITemplate.new('/{year}-{month}-{day}-{title}.html')
x.expand(year: '2010', month: '01', day: '01', title: "foo-bar")
 => "/2010-01-01-foo-bar.html"

Support for symbols in hash passed to expand.

I would like uri_template to support symbols in the hash keys passed to expand?

I think it would be quite nice to be able to use the Ruby 1.9 hash syntax to write something like this:

t = URITemplate.new('/search{?q,rows,start}')
t.expand q: 'something', rows: 10, start: 5

Iโ€™d be happy to implement the change if you think it would be a good idea ๐Ÿค˜

Extending beyond RFC6570

We use uri_template in Hyperclient, https://github.com/codegram/hyperclient. Most of the time you have an URI template in some resource and you expand it. For example a link could be http://example.com/widgets/{id}. However sometimes you have things like http://example.com/widgets/{?sort,size,page,offset} which is rather annoying and ends up being copy-pasted all over the place, or usually just forgotten by the API developers.

In code this is used like so:

client.widgets(id: 1)
client.widgets(sort: 'created_at', size: 10)
...

We would like to generally be able to omit these parameters, but still include them in the resulting URI. So a template like http://example.com/widgets{?size} could actually be expanded with client.widgets(sort: 'created_at'), basically using the template as a hint as opposed to a hard requirement.

Furthermore we'd like to fail when a required parameter is missing. Anything that's not a query parameter should probably be required.

See codegram/hyperclient#84.

Generally just looking for feedback. Is an implementation like this in scope of this library? If so I would probably refactor rfc6570.rb somewhat into a generic base, the old rfc6570 implementation and a variation described above.

Affero GPLv3 prevents use in many cases

I just saw that this library is using the Affero GPLv3 license. That license makes this library unsuitable for use except in very narrow situations (when combined into a compatibly-licensed application that also includes functionality to serve the source code of this library to users).

Ruby code is generally licensed with a more permissive license like MIT, which would not force GPLv3 terms on users of that license.

Optional fragments depending on other fragments

I would be more than willing to implement this, but I was wondering if it's desired or if it's already possible:

Let's say, you have the following template:

tpl = URITemplate.new(:colon, 'http://some.api.com[/:optional[/:optional2]]')

:optional2: would only be added if :optional1 existed. In other words:

tpl.expand(optional1: 'foo', optional2: 'bar')
# => http://some.api.com/foo/bar

tpl.expand(optional1: 'foo')
# => http://some.api.com/foo

tpl.expand(optional2: 'bar')
# => http://some.api.com

I have seen this pattern implemented in a few APIs (we can debate the design of said APIs another time). Is this possible with uri_template? If not, would there be any interest in me adding it?

If there is interest in me adding it, could we discuss what the pattern would look like for both formats?

Thanks!

Partial expand changed behavior

Hi, I notice the behavior of URITemplate has changed between 0.6.0 and 0.7.0

URITemplate.new('/foo/{x}/{y}').expand_partial(x: 123).to_s
#0.6.0 => "/foo/123/{y}"
#0.7.0 => "/foo/123{x}/{y}"

is there an API to get the old behaviour? I'm using URITemplate for Yaks and this is blocking me from upgrading.

Partial expand

It would be nice to have partial expand feature which works by binding supplied values to variables and produces another template:

URLTemplate.new("{a}/{b}").partial_expand(a: 1)
=> <URLTemplate @pattern="1/{b}">

Tests

Hi,

FYI, we've started collection JSON-formatted tests for URI templates here:
https://github.com/uri-templates/uritemplate-test
starting with the examples from the spec.

If you'd like to use them in your project, please feel free, and of course we'd love a pull request if you have additional tests in the same format.

(Sorry to submit this as an issue, but I didn't see any other way to contact you.)

Cheers,

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.