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.
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 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.
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"
.
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.
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.
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.