tutorial-dynasnips

Basics Learn about Layouts Renderer fun More about Dynasnips Cleaning up

Dynasnips

As mentioned in the general tutorial, dynamic content is built in vanilla using “dynasnips”. These are snips who content depends on more than just their content.

Typically they are rendered by the Vanilla::Renderers::Ruby renderer. Lets look again at the raw content of link_to:

class LinkTo < Vanilla::Dynasnip
  usage %|
The link_to dyna lets you create links between snips: 

  {link_to blah} 

would insert a link to the blah snip.|

  def handle(name=nil, link_text=name, part=nil)
    return usage if requesting_this_snip?
    return "You must provide a snip name" unless name
    if app.soup[name]
      %{<a href="#{url_to(name, part)}">#{link_text}</a>}
    else
      %{<a class="missing" href="#{url_to(name, part)}">#{link_text}</a>}
    end
  end

  self
end

As you can see, it simply refers to the Ruby class LinkTo, which is contained within the vanilla-rb codebase. When the Ruby renderer is called, expects the given code to evaulate to a Ruby class. It then instantiates the class, and calls a handle method on the instance, passing it any other arguments from the snip inclusion.

You can pass arguments to dynasnips in a number of ways. All of the following are valid:

Where a simple list of arguments is given, these will be passed to the handle method as an array. If a ruby-hash-like syntax is used, a hash of these options will be passed.

Of course, it depends entirely on the implementation of the dynasnip what arguments it expects and accepts; some may require a flat list, while others may require hash-like named arguments.

Writing your own Dynasnips

While dynasnip classes can be provided as part of the vanilla codebase, it’s envisioned that much of these will be created by end users in their own sites, either by refering to local classes, or defining the classes directly as the content. Here’s an example of that, as the raw content of hello_world:

class HelloWorld
  # although the name doesn't need to match the snip name,
  # it's simple to follow that convention where appropriate

  def handle(name=nil)
    if name
      "Hey #{name} - Hello World!"
    else
      "Hello World!"
    end
  end

  # note that this code must evaluate to a class. One way of achieving that is by 
  # putting 'self' at the end of the class definition.
  self
end
# Another way is by referring to the class at the end of the content. Either works fine.
HelloWorld

It’s important that the contents of the snip evaluate to a Ruby class; this is easy to achieve by placing self as the last statement in the class definition, or referencing the class at the end of the snip; both are shown above.

If we include the dynasnip here as Hello World!, gives:

Hello World!

Note that the handle method can take one (optional) argument. Lets try including it with Hey Dave - Hello World!:

Hey Dave - Hello World!

HTTP Verbs

By default, the Ruby renderer will attempt to call handle on a dynasnip instance, but if the instance responds to methods corresponding to the HTTP Verbs - get, post, put, or delete - then these methods will be called instead.

This means you can have a single dynasnip which responds differently when receiving a POST request - quite useful if you want to write dynasnips that generate and respond to forms, like the comments dynasnip in your extras soup directory.

There’s really no limit to what you can do with dynasnips - only what you can imagine.

Basics Learn about Layouts Renderer fun More about Dynasnips Cleaning up