vanilla 1.2 → 1.9.9
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +61 -60
- data/bin/vanilla +6 -35
- data/config.example.yml +6 -0
- data/config.ru +10 -0
- data/lib/defensio.rb +59 -0
- data/lib/tasks/vanilla.rake +173 -0
- data/lib/vanilla.rb +3 -10
- data/lib/vanilla/app.rb +48 -104
- data/lib/vanilla/console.rb +5 -19
- data/lib/vanilla/dynasnips/comments.rb +108 -0
- data/lib/vanilla/dynasnips/current_snip.rb +32 -0
- data/{pristine_app/soups → lib/vanilla}/dynasnips/debug.rb +3 -5
- data/lib/vanilla/dynasnips/edit.rb +60 -0
- data/lib/vanilla/dynasnips/edit_link.rb +20 -0
- data/{pristine_app/soups → lib/vanilla}/dynasnips/index.rb +2 -4
- data/{pristine_app/soups/extras → lib/vanilla/dynasnips}/kind.rb +12 -14
- data/{pristine_app/soups → lib/vanilla}/dynasnips/link_to.rb +0 -2
- data/lib/vanilla/dynasnips/link_to_current_snip.rb +16 -0
- data/lib/vanilla/dynasnips/login.rb +56 -0
- data/lib/vanilla/dynasnips/new.rb +14 -0
- data/lib/vanilla/dynasnips/notes.rb +42 -0
- data/{pristine_app/soups → lib/vanilla}/dynasnips/pre.rb +4 -6
- data/{pristine_app/soups/extras → lib/vanilla/dynasnips}/rand.rb +0 -2
- data/{pristine_app/soups → lib/vanilla}/dynasnips/raw.rb +5 -8
- data/{pristine_app/soups/extras → lib/vanilla/dynasnips}/url_to.rb +0 -0
- data/lib/vanilla/renderers/base.rb +22 -32
- data/lib/vanilla/renderers/bold.rb +2 -0
- data/lib/vanilla/renderers/erb.rb +2 -0
- data/lib/vanilla/renderers/markdown.rb +2 -0
- data/lib/vanilla/renderers/raw.rb +2 -0
- data/lib/vanilla/renderers/ruby.rb +5 -9
- data/lib/vanilla/renderers/textile.rb +2 -0
- data/lib/vanilla/request.rb +15 -16
- data/lib/vanilla/routes.rb +18 -5
- data/lib/vanilla/snip_reference.rb +534 -0
- data/lib/vanilla/snip_reference.treetop +48 -0
- data/lib/vanilla/snip_reference_parser.rb +99 -82
- data/lib/vanilla/snips/start.rb +28 -0
- data/lib/vanilla/snips/system.rb +77 -0
- data/lib/vanilla/snips/tutorial.rb +244 -0
- data/lib/vanilla/soup_with_timestamps.rb +21 -0
- data/public/hatch.png +0 -0
- data/public/javascripts/jquery.autogrow-textarea.js +54 -0
- data/public/javascripts/jquery.js +4376 -0
- data/public/javascripts/vanilla.js +22 -0
- data/spec/dynasnip_spec.rb +28 -0
- data/spec/renderers/base_renderer_spec.rb +40 -0
- data/spec/renderers/erb_renderer_spec.rb +27 -0
- data/spec/renderers/markdown_renderer_spec.rb +29 -0
- data/spec/renderers/raw_renderer_spec.rb +21 -0
- data/spec/renderers/ruby_renderer_spec.rb +59 -0
- data/spec/renderers/vanilla_app_detecting_renderer_spec.rb +35 -0
- data/spec/spec_helper.rb +70 -0
- data/spec/tmp/config.yml +2 -0
- data/spec/tmp/soup/current_snip.yml +15 -0
- data/spec/tmp/soup/system.yml +5 -0
- data/spec/vanilla_app_spec.rb +38 -0
- data/spec/vanilla_presenting_spec.rb +84 -0
- data/spec/vanilla_request_spec.rb +73 -0
- metadata +79 -170
- data/lib/vanilla/renderers.rb +0 -12
- data/lib/vanilla/renderers/haml.rb +0 -13
- data/lib/vanilla/static.rb +0 -28
- data/pristine_app/Gemfile +0 -3
- data/pristine_app/Gemfile.lock +0 -32
- data/pristine_app/README +0 -47
- data/pristine_app/config.ru +0 -26
- data/pristine_app/public/vanilla.css +0 -15
- data/pristine_app/soups/base/layout.snip +0 -18
- data/pristine_app/soups/base/start.snip +0 -19
- data/pristine_app/soups/dynasnips/current_snip.rb +0 -29
- data/pristine_app/soups/dynasnips/link_to_current_snip.rb +0 -14
- data/pristine_app/soups/dynasnips/page_title.rb +0 -9
- data/pristine_app/soups/extras/comments.rb +0 -78
- data/pristine_app/soups/tutorial/bad_dynasnip.snip +0 -8
- data/pristine_app/soups/tutorial/hello_world.snip +0 -20
- data/pristine_app/soups/tutorial/markdown_example.snip +0 -13
- data/pristine_app/soups/tutorial/snip.snip +0 -9
- data/pristine_app/soups/tutorial/soup.snip +0 -3
- data/pristine_app/soups/tutorial/test.snip +0 -30
- data/pristine_app/soups/tutorial/textile_example.snip +0 -11
- data/pristine_app/soups/tutorial/tutorial-another-snip.snip +0 -1
- data/pristine_app/soups/tutorial/tutorial-basic-snip-inclusion.snip +0 -1
- data/pristine_app/soups/tutorial/tutorial-dynasnips.snip.markdown +0 -56
- data/pristine_app/soups/tutorial/tutorial-layout.snip +0 -56
- data/pristine_app/soups/tutorial/tutorial-links.snip +0 -4
- data/pristine_app/soups/tutorial/tutorial-renderers.snip.markdown +0 -77
- data/pristine_app/soups/tutorial/tutorial.snip.markdown +0 -69
- data/pristine_app/soups/tutorial/vanilla-rb.snip +0 -16
- data/pristine_app/soups/tutorial/vanilla.snip +0 -8
- data/test/dynasnip_test.rb +0 -42
- data/test/dynasnips/link_to_current_snip_test.rb +0 -19
- data/test/dynasnips/link_to_test.rb +0 -27
- data/test/dynasnips/page_title_test.rb +0 -19
- data/test/renderers/base_renderer_test.rb +0 -43
- data/test/renderers/erb_renderer_test.rb +0 -29
- data/test/renderers/haml_renderer_test.rb +0 -35
- data/test/renderers/markdown_renderer_test.rb +0 -31
- data/test/renderers/raw_renderer_test.rb +0 -23
- data/test/renderers/ruby_renderer_test.rb +0 -59
- data/test/snip_inclusion_test.rb +0 -56
- data/test/snip_reference_parser_test.rb +0 -123
- data/test/test_helper.rb +0 -75
- data/test/vanilla_app_test.rb +0 -83
- data/test/vanilla_presenting_test.rb +0 -125
- data/test/vanilla_request_test.rb +0 -87
data/pristine_app/Gemfile
DELETED
data/pristine_app/Gemfile.lock
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: /Users/james/Code/lazyatom/vanilla-rb
|
3
|
-
specs:
|
4
|
-
vanilla (1.14.1)
|
5
|
-
BlueCloth (>= 1.0.0)
|
6
|
-
RedCloth (>= 4.1.1)
|
7
|
-
haml
|
8
|
-
rack (>= 0.9.1)
|
9
|
-
ratom (>= 0.3.5)
|
10
|
-
soup (>= 1.0.6)
|
11
|
-
treetop (>= 1.4.1)
|
12
|
-
|
13
|
-
GEM
|
14
|
-
remote: http://rubygems.org/
|
15
|
-
specs:
|
16
|
-
BlueCloth (1.0.1)
|
17
|
-
RedCloth (4.2.7)
|
18
|
-
haml (3.1.1)
|
19
|
-
libxml-ruby (2.0.2)
|
20
|
-
polyglot (0.3.1)
|
21
|
-
rack (1.2.2)
|
22
|
-
ratom (0.6.7)
|
23
|
-
libxml-ruby (>= 1.1.2)
|
24
|
-
soup (1.0.6)
|
25
|
-
treetop (1.4.9)
|
26
|
-
polyglot (>= 0.3.1)
|
27
|
-
|
28
|
-
PLATFORMS
|
29
|
-
ruby
|
30
|
-
|
31
|
-
DEPENDENCIES
|
32
|
-
vanilla!
|
data/pristine_app/README
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
WELCOME IN VANILLA
|
2
|
-
Vanilla
|
3
|
-
vanilla
|
4
|
-
.........vanillaaaaaAAAAAAAAAAA
|
5
|
-
|
6
|
-
What you've got:
|
7
|
-
|
8
|
-
Gemfile - specifying your dependencies
|
9
|
-
config.ru - this is the rack configuration, which is used to start
|
10
|
-
the application by your webserver
|
11
|
-
soup/ - the default soup directory, where your snips are stored
|
12
|
-
|
13
|
-
|
14
|
-
For an overview of vanilla, start your site and look at the tutorial:
|
15
|
-
|
16
|
-
$ rackup # then open http://localhost:9292/tutorial
|
17
|
-
|
18
|
-
|
19
|
-
Editing snips
|
20
|
-
-------------
|
21
|
-
You can edit any file in the soup directory using your favourite editor,
|
22
|
-
and the changes will be reflected automatically. The snip files are
|
23
|
-
slightly modified YAML files. Here's an example, which you might save
|
24
|
-
in a file called 'soup.snip':
|
25
|
-
|
26
|
-
|
27
|
-
Soup is a data store supporting the {link_to snip}-space that
|
28
|
-
{link_to vanilla-rb} expects.
|
29
|
-
|
30
|
-
It's hosted on github [here](http://github.com/lazyatom/soup).
|
31
|
-
|
32
|
-
:created_at: 2011-05-23 14:14:16 +01:00
|
33
|
-
:updated_at: 2009-05-23 15:23:22 +01:00
|
34
|
-
:render_as: Markdown
|
35
|
-
|
36
|
-
|
37
|
-
The 'content' of the snip is at the top of the file, followed by the
|
38
|
-
rest of the snip attributes on lines starting with ':'.
|
39
|
-
|
40
|
-
|
41
|
-
The console
|
42
|
-
-----------
|
43
|
-
|
44
|
-
Within a vanilla app directory, you can run `vanilla console` to start
|
45
|
-
an IRB session and interact with your app and snips. The `app` method
|
46
|
-
returns your application object, and `app.soup['start']` will return
|
47
|
-
the start snip from your soup(s).
|
data/pristine_app/config.ru
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'bundler/setup'
|
3
|
-
$:.unshift File.join(File.dirname(__FILE__), *%w[lib])
|
4
|
-
|
5
|
-
require 'vanilla'
|
6
|
-
|
7
|
-
# You can partition your snips into subdirectories to keep things tidy. This
|
8
|
-
# doesn't affect their URL structure on the site (everything is flat).
|
9
|
-
soups = [
|
10
|
-
"soups/base",
|
11
|
-
"soups/dynasnips"
|
12
|
-
]
|
13
|
-
|
14
|
-
# If you don't want the tutorial on your site, remove this and delete the directory
|
15
|
-
soups << "soups/tutorial"
|
16
|
-
|
17
|
-
# This is a dumping ground of ideas at the moment
|
18
|
-
# soups << "soups/extras"
|
19
|
-
|
20
|
-
app = Vanilla::App.new(:soups => soups)
|
21
|
-
|
22
|
-
# If you running your site under a proper webserver, you probably don't need this.
|
23
|
-
require 'vanilla/static'
|
24
|
-
use Vanilla::Static, File.join(File.dirname(__FILE__), 'public')
|
25
|
-
|
26
|
-
run app
|
@@ -1,18 +0,0 @@
|
|
1
|
-
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
2
|
-
<html lang="en">
|
3
|
-
<head>
|
4
|
-
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
5
|
-
<title>{page_title}</title>
|
6
|
-
<link rel="stylesheet" href="/vanilla.css" type="text/css" media="screen" title="no title" charset="utf-8">
|
7
|
-
</head>
|
8
|
-
<body>
|
9
|
-
<ul id="controls">
|
10
|
-
<li><a href="/">home</a></li>
|
11
|
-
<li>{link_to index}</li>
|
12
|
-
<li>you are viewing: {link_to_current_snip}</li>
|
13
|
-
</ul>
|
14
|
-
<div id="content">
|
15
|
-
{current_snip}
|
16
|
-
</div>
|
17
|
-
</body>
|
18
|
-
</html>
|
@@ -1,19 +0,0 @@
|
|
1
|
-
<h1>Welcome to Vanilla.rb</h1>
|
2
|
-
|
3
|
-
<p>Vanilla.rb is a web-experiment (a <em>websperiment</em>?) about storing and reusing data on a website. It can also function as a <a href="http://www.wikipedia.com/wiki/Bliki">bliki</a>.</p>
|
4
|
-
|
5
|
-
<p>From a technical perspective, vanilla is a Ruby rack application, and should play well within the rack ecosystem. It uses a simple document store called `soup` to store data.</p>
|
6
|
-
|
7
|
-
<h2>What now?</h2>
|
8
|
-
|
9
|
-
<p>If this is your first time using vanilla, you should investigate the {link_to tutorial} for some orientation.</p>
|
10
|
-
|
11
|
-
<h2>What next?</h2>
|
12
|
-
|
13
|
-
<p>This is the {link_to start} snip, which is the default home page. You can find this content in `start.snip`.</p>
|
14
|
-
|
15
|
-
<p>You should replace this content with whatever you want on your site's home page.</p>
|
16
|
-
|
17
|
-
<p>Once your site is ready to run, you'll probably want to remove the tutorial; you can do this by editing the configuration in `config.ru`, and deleting the `soups/tutorial` directory.</p>
|
18
|
-
|
19
|
-
<p>Good luck!</p>
|
@@ -1,29 +0,0 @@
|
|
1
|
-
require 'vanilla/dynasnip'
|
2
|
-
|
3
|
-
class CurrentSnip < Dynasnip
|
4
|
-
usage %|
|
5
|
-
The current_snip dyna normally returns the result of rendering the snip named by the
|
6
|
-
'snip' value in the parameters. This way, it can be used in templates to place the currently
|
7
|
-
requested snip, in its rendered form, within the page.
|
8
|
-
|
9
|
-
It can also be used to determine an attribute of the current snip in a consistent way:
|
10
|
-
|
11
|
-
{current_snip name}
|
12
|
-
|
13
|
-
will output the name of the current snip.
|
14
|
-
|
|
15
|
-
|
16
|
-
def handle(attribute=nil)
|
17
|
-
if app.request.snip
|
18
|
-
if attribute ||= app.request.part
|
19
|
-
"{#{app.request.snip_name}.#{attribute}}"
|
20
|
-
else
|
21
|
-
"{#{app.request.snip_name}}"
|
22
|
-
end
|
23
|
-
else
|
24
|
-
app.response.status = 404
|
25
|
-
%{Couldn't find snip "#{app.request.snip_name}"}
|
26
|
-
end
|
27
|
-
end
|
28
|
-
self
|
29
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
require 'vanilla/dynasnip'
|
2
|
-
|
3
|
-
class LinkToCurrentSnip < Dynasnip
|
4
|
-
usage %|
|
5
|
-
Renders a link to the current snip, or the snip currently being edited
|
6
|
-
(if we're currently editing)
|
7
|
-
|
|
8
|
-
|
9
|
-
def handle(*args)
|
10
|
-
link_to app.request.snip_name
|
11
|
-
end
|
12
|
-
|
13
|
-
self
|
14
|
-
end
|
@@ -1,78 +0,0 @@
|
|
1
|
-
require 'vanilla/dynasnip'
|
2
|
-
require 'date'
|
3
|
-
|
4
|
-
class Comments < Dynasnip
|
5
|
-
usage %|
|
6
|
-
Embed comments within snips!
|
7
|
-
|
8
|
-
{comments <false>}
|
9
|
-
|
10
|
-
This will embed a list of comments, and a comment form, in a snip
|
11
|
-
If the snip is being rendered within another snip, it will show a link to the snip,
|
12
|
-
with the number of comments. Add a parameter to disable new comments.
|
13
|
-
|
|
14
|
-
|
15
|
-
def get(disable_new_comments=false)
|
16
|
-
return usage if self.class.snip_name == app.request.snip_name
|
17
|
-
comments = app.soup.with(:commenting_on => enclosing_snip.name)
|
18
|
-
comments_html = if app.request.snip_name == enclosing_snip.name
|
19
|
-
rendered_comments = render_comments(comments)
|
20
|
-
rendered_comments += comment_form.gsub('SNIP_NAME', enclosing_snip.name) unless disable_new_comments
|
21
|
-
rendered_comments
|
22
|
-
else
|
23
|
-
%{<a href="#{url_to(enclosing_snip.name)}">#{comments.length} comments for #{enclosing_snip.name}</a>}
|
24
|
-
end
|
25
|
-
return comments_html
|
26
|
-
end
|
27
|
-
|
28
|
-
def post(*args)
|
29
|
-
snip_name = app.request.params[:snip]
|
30
|
-
existing_comments = app.soup.with(:commenting_on => snip_name)
|
31
|
-
comment = app.request.params.reject { |k,v| ![:author, :email, :website, :content].include?(k) }
|
32
|
-
|
33
|
-
return "You need to add some details!" if comment.empty?
|
34
|
-
return "No spam today, thanks anyway" unless app.request.params[:human] == 'human'
|
35
|
-
|
36
|
-
app.soup << comment.merge({
|
37
|
-
:name => "#{snip_name}-comment-#{existing_comments.length + 1}",
|
38
|
-
:commenting_on => snip_name,
|
39
|
-
:created_at => Time.now
|
40
|
-
})
|
41
|
-
"Thanks for your comment! Back to {link_to #{snip_name}}"
|
42
|
-
end
|
43
|
-
|
44
|
-
def render_comments(comments)
|
45
|
-
"<h2>Comments</h2><ol class='comments'>" + comments.map do |comment|
|
46
|
-
rendered_comment = comment_template.gsub('COMMENT_CONTENT', app.render(comment)).
|
47
|
-
gsub('COMMENT_DATE', comment.created_at.to_s)
|
48
|
-
author = comment.author
|
49
|
-
author = "Anonymous" unless author && author != ""
|
50
|
-
if comment.website && comment.website != ""
|
51
|
-
rendered_comment.gsub!('COMMENT_AUTHOR', "<a href=\"#{comment.website}\">#{author}</a>")
|
52
|
-
else
|
53
|
-
rendered_comment.gsub!('COMMENT_AUTHOR', author)
|
54
|
-
end
|
55
|
-
rendered_comment
|
56
|
-
end.join + "</ol>"
|
57
|
-
end
|
58
|
-
|
59
|
-
attribute :comment_template, %{
|
60
|
-
<li>
|
61
|
-
<p>COMMENT_AUTHOR (COMMENT_DATE)</p>
|
62
|
-
<div>COMMENT_CONTENT</div>
|
63
|
-
</li>
|
64
|
-
}
|
65
|
-
|
66
|
-
attribute :comment_form, %{
|
67
|
-
<form class="comments" action="/comments?snip=SNIP_NAME" method="POST">
|
68
|
-
<label>Name: <input type="text" name="author"></input></label>
|
69
|
-
<label>Email: <input type="text" name="email"></input></label>
|
70
|
-
<label>Website: <input type="text" name="website"></input></label>
|
71
|
-
<textarea name="content"></textarea>
|
72
|
-
<label class="human">Type 'human' if you are one: <input type="text" name="human"></input></label>
|
73
|
-
<button>Submit</button>
|
74
|
-
</form>
|
75
|
-
}
|
76
|
-
|
77
|
-
self
|
78
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
class HelloWorld
|
2
|
-
# although the name doesn't need to match the snip name,
|
3
|
-
# it's simple to follow that convention where appropriate
|
4
|
-
|
5
|
-
def handle(name=nil)
|
6
|
-
if name
|
7
|
-
"Hey #{name} - Hello World!"
|
8
|
-
else
|
9
|
-
"Hello World!"
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
# note that this code must evaluate to a class. One way of achieving that is by
|
14
|
-
# putting 'self' at the end of the class definition.
|
15
|
-
self
|
16
|
-
end
|
17
|
-
# Another way is by referring to the class at the end of the content. Either works fine.
|
18
|
-
HelloWorld
|
19
|
-
|
20
|
-
:render_as: Ruby
|
@@ -1,9 +0,0 @@
|
|
1
|
-
A snip is the basic building block of information for {link_to vanilla-rb}. Essentially, it is a piece of content with arbitrary attributes. Vanilla anticipates the presence of some key attributes:
|
2
|
-
|
3
|
-
* `name` - the name of the snip, which is how it will be referred to. The `name` of this snip is _snip_.
|
4
|
-
* `content` - the default part of the snip to render. You can see the `content` of this snip <a href="/snip/content.raw">here</a>.
|
5
|
-
* `render_as` - the name of the renderer to use when rendering the content. The `render_as` of this snip is {snip.render_as}.
|
6
|
-
|
7
|
-
One implementation of the snip store is {link_to soup}.
|
8
|
-
|
9
|
-
:render_as: Markdown
|
@@ -1,30 +0,0 @@
|
|
1
|
-
Linking is good: {link_to bold}
|
2
|
-
Here's a bold snip: {bold}
|
3
|
-
|
4
|
-
- Here's a random number between 5 and 15: {rand 5,15}
|
5
|
-
- Here's a random number between 1 and 90 (the default min): {rand 90}
|
6
|
-
- Here's a random number between 1 and 100 (the default range): {rand}
|
7
|
-
|
8
|
-
And lets include some textile:
|
9
|
-
|
10
|
-
{textile_example}
|
11
|
-
|
12
|
-
The source for that was
|
13
|
-
|
14
|
-
{pre textile_example}
|
15
|
-
|
16
|
-
And lets include some markdown!:
|
17
|
-
|
18
|
-
{markdown_example}
|
19
|
-
|
20
|
-
The source for that was
|
21
|
-
|
22
|
-
{pre markdown_example}
|
23
|
-
|
24
|
-
How about some {link_to debug} information: {debug}
|
25
|
-
|
26
|
-
What about a missing snip? Lets try to include one: {monkey}
|
27
|
-
|
28
|
-
And an error when running? {bad_dynasnip}
|
29
|
-
|
30
|
-
:render_as: Markdown
|
@@ -1 +0,0 @@
|
|
1
|
-
this is another snip!
|
@@ -1 +0,0 @@
|
|
1
|
-
This is a snip, which includes another {link_to snip}: {tutorial-another-snip}
|
@@ -1,56 +0,0 @@
|
|
1
|
-
{tutorial-links}
|
2
|
-
|
3
|
-
Dynasnips
|
4
|
-
=========
|
5
|
-
|
6
|
-
As mentioned in the general {link_to tutorial}, dynamic content is built in vanilla using "dynasnips". These are snips who content depends on more than just their content.
|
7
|
-
|
8
|
-
Typically they are rendered by the `Vanilla::Renderers::Ruby` renderer. Lets look again at the raw content of `link_to`:
|
9
|
-
|
10
|
-
{raw link_to}
|
11
|
-
|
12
|
-
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.
|
13
|
-
|
14
|
-
You can pass arguments to dynasnips in a number of ways. All of the following are valid:
|
15
|
-
|
16
|
-
* {dynasnip apple}
|
17
|
-
* {dynasnip apple, banana}
|
18
|
-
* {dynasnip apple, big banana, cherry}
|
19
|
-
* {dynasnip apple, big banana, "lovely lucious cherry"}
|
20
|
-
* {dynasnip apple => true, banana => false}
|
21
|
-
* {dynasnip apple: true, banana: false}
|
22
|
-
|
23
|
-
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.
|
24
|
-
|
25
|
-
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.
|
26
|
-
|
27
|
-
|
28
|
-
Writing your own Dynasnips
|
29
|
-
--------------------------
|
30
|
-
|
31
|
-
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`:
|
32
|
-
|
33
|
-
{raw hello_world}
|
34
|
-
|
35
|
-
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.
|
36
|
-
|
37
|
-
If we include the dynasnip here as <tt>{hello\_world}</tt>, gives:
|
38
|
-
|
39
|
-
> {hello_world}
|
40
|
-
|
41
|
-
Note that the `handle` method can take one (optional) argument. Lets try including it with <tt>{hello\_world Dave}</tt>:
|
42
|
-
|
43
|
-
> {hello_world Dave}
|
44
|
-
|
45
|
-
|
46
|
-
HTTP Verbs
|
47
|
-
----------
|
48
|
-
|
49
|
-
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.
|
50
|
-
|
51
|
-
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.
|
52
|
-
|
53
|
-
There's really no limit to what you can do with dynasnips - only what you can imagine.
|
54
|
-
|
55
|
-
|
56
|
-
{tutorial-links}
|