Zooplankton
Zooplankton are the kind of plankton that are animals (as opposed to phytoplankton, which are plants).
Zooplankton is a library for helping you turn Rails routes into URI Template
strings. It's useful for helping yourself generate the
_links
part of HAL, for example.
Usage
Given a route file like this:
SomeApp::Application.routes.draw do
root 'root#index'
get '/posts/:slug', to: 'posts#show', as: :post
get '/posts/:slug/comments', to: 'comments#index', as: :comments
get '/posts/:slug/comments/:comment_id', to: 'commendts#show', as: :comment
end
Without Zooplankton, you might end up generating a URI template for a route by abusing Rails's url helpers like this:
CGI.unescape post_path(slug: "{slug}")
# => '/posts/{slug}'
CGI.unescape comment_path(slug: "{slug}", comment_id: "{comment_id}")
# => '/posts/{slug}/comments/{comment_id}'
If you needed to include query parameters in your template, you'd have an even harder time. Something like:
CGI.unescape "#{comments_path(slug: "{slug}")}{?page,page_size}"
# => '/posts/{slug}/comments{?page,page_size}'
With Zooplankton, you can use it like this:
> Zooplankton.path_template_for(:root)
# => '/'
> Zooplankton.path_template_for(:post)
# => '/posts/{slug}'
> Zooplankton.path_template_for(:comment)
# => '/posts/{slug}/comments/{comment_id}'
It also handles replacing some (or all, though you might decide to use a Rails url helper at that point) of the templated variables if you want to prepopulate some of them ahead of time:
> Zooplankton.path_template_for(:comment, slug: 'the-best-post-ever')
# => '/posts/the-best-post-ever/comments/{comment_id}'
And you can add some query parameters when you're generating the template, if you need:
> Zooplankton.path_template_for(:comments, :page, slug: 'the-best-post-ever')
# => '/posts/the-best-post-ever/comments{?page}'
> Zooplankton.path_template_for(:comments, %i(page page_size), slug: 'the-best-post-ever')
# => '/posts/the-best-post-ever/comments{?page,page_size}'
> Zooplankton.path_template_for(:comments, %i(page page_size))
# => '/posts/{slug}/comments{?page,page_size}'
If you supply a query parameter for replacement, it'll denote a continuation:
> Zooplankton.path_template_for(:comments, %i(page page_size), slug: 'the-best-post-ever', page: 1)
# => '/posts/the-best-post-ever/comments?page=1{&page_size}'
It'll generate URLs, too, not just paths.
> Zooplankton.url_template_for(:root)
# => 'http://example.com/'
> Zooplankton.url_template_for(:post)
# => 'http://example.com/posts/{slug}'
URI Templates LOLWUT
URI Templates are a notation for teaching machines how to build URIs. They're basically rules for string interpolation. Zooplankton supports a small subset of all the notations, outlined here.
Simple String Expansion
This is the simplest part of URI Templates and is what Zooplankton uses for
parameters that are part of the path of a URI. Basically, given a template like
"foo{var}baz"
and assuming you have a value of 'bar'
for var
, you'd end up
with "foobarbaz"
.
Form-Style Query Expansion
This expansion is for telling a computer to build a query string. Something like
"name{?first,last}" with values like in the hash
{first: 'ben', last:
'hamill'}would expand to
"name?first=ben&last=hamill"`. Zooplankton will use
this when it's appropriate for building query strings.
Form-Style Query Continuation
This expansion is for telling a computer to finish off a query string that
you've already started. Basically, it's like a query expansion, but instructs
the computer to use a starting &
, rather than a ?
. So "name{&first,last}"
with values like {first: 'ben', last: 'hamill'}
would end up as
"name&first=ben&last=hamill"
, but the greatest usefulness is for something
like "name?middle=dale{?first,last}"
which would end up as
"name?middle=dale&first=ben&last=hamill"
. Zooplankton will use this when it's
appropriate for building query strings.
Testing
rake spec
This library uses the Appraisal gem to test against multiple versions of Rails. You can run them individually with
appraisal rails4 rake spec
appraisal rails5 rake spec
Look in ./Appraisals
for available Rails versions.
Contributing
Help is gladly welcomed. If you have a feature you'd like to add, it's much more likely to get in (or get in faster) the closer you stick to these steps:
- Open an Issue to talk about it. We can discuss whether it's the right direction or maybe help track down a bug, etc.
- Fork the project, and make a branch to work on your feature/fix. Master is where you'll want to start from.
- Turn the Issue into a Pull Request. There are several ways to do this, but hub is probably the easiest.
- Make sure your Pull Request includes tests.
- Bonus points if your Pull Request updates
CHANGES.md
to include a summary of your changes and your name like the other entries. If the last entry is the last release, add a new## Unreleased
heading.
If you don't know how to fix something, even just a Pull Request that includes a failing test can be helpful. If in doubt, make an Issue to discuss.