vanilla 1.0.2 → 1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +112 -109
- data/bin/vanilla +35 -6
- data/lib/vanilla.rb +10 -14
- data/lib/vanilla/app.rb +109 -41
- data/lib/vanilla/console.rb +22 -2
- data/lib/vanilla/dynasnip.rb +4 -36
- data/lib/vanilla/renderers.rb +12 -0
- data/lib/vanilla/renderers/base.rb +58 -34
- data/lib/vanilla/renderers/bold.rb +0 -2
- data/lib/vanilla/renderers/erb.rb +1 -3
- data/lib/vanilla/renderers/haml.rb +13 -0
- data/lib/vanilla/renderers/markdown.rb +0 -2
- data/lib/vanilla/renderers/raw.rb +0 -2
- data/lib/vanilla/renderers/ruby.rb +12 -6
- data/lib/vanilla/renderers/textile.rb +0 -2
- data/lib/vanilla/request.rb +19 -17
- data/lib/vanilla/routes.rb +9 -20
- data/lib/vanilla/snip_reference_parser.rb +94 -0
- data/lib/vanilla/static.rb +28 -0
- data/pristine_app/Gemfile +3 -0
- data/pristine_app/Gemfile.lock +32 -0
- data/pristine_app/README +47 -0
- data/pristine_app/config.ru +26 -0
- data/pristine_app/public/vanilla.css +15 -0
- data/pristine_app/soups/base/layout.snip +18 -0
- data/pristine_app/soups/base/start.snip +19 -0
- data/pristine_app/soups/dynasnips/current_snip.rb +29 -0
- data/{lib/vanilla → pristine_app/soups}/dynasnips/debug.rb +5 -3
- data/pristine_app/soups/dynasnips/index.rb +12 -0
- data/{lib/vanilla → pristine_app/soups}/dynasnips/link_to.rb +4 -2
- data/pristine_app/soups/dynasnips/link_to_current_snip.rb +14 -0
- data/pristine_app/soups/dynasnips/page_title.rb +9 -0
- data/{lib/vanilla → pristine_app/soups}/dynasnips/pre.rb +7 -5
- data/{lib/vanilla → pristine_app/soups}/dynasnips/raw.rb +8 -5
- data/pristine_app/soups/extras/comments.rb +78 -0
- data/{lib/vanilla/dynasnips → pristine_app/soups/extras}/kind.rb +19 -17
- data/{lib/vanilla/dynasnips → pristine_app/soups/extras}/rand.rb +2 -0
- data/pristine_app/soups/extras/url_to.rb +7 -0
- data/pristine_app/soups/tutorial/bad_dynasnip.snip +8 -0
- data/pristine_app/soups/tutorial/hello_world.snip +20 -0
- data/pristine_app/soups/tutorial/markdown_example.snip +13 -0
- data/pristine_app/soups/tutorial/snip.snip +9 -0
- data/pristine_app/soups/tutorial/soup.snip +3 -0
- data/pristine_app/soups/tutorial/test.snip +30 -0
- data/pristine_app/soups/tutorial/textile_example.snip +11 -0
- data/pristine_app/soups/tutorial/tutorial-another-snip.snip +1 -0
- data/pristine_app/soups/tutorial/tutorial-basic-snip-inclusion.snip +1 -0
- data/pristine_app/soups/tutorial/tutorial-dynasnips.snip.markdown +56 -0
- data/pristine_app/soups/tutorial/tutorial-layout.snip +56 -0
- data/pristine_app/soups/tutorial/tutorial-links.snip +4 -0
- data/pristine_app/soups/tutorial/tutorial-renderers.snip.markdown +77 -0
- data/pristine_app/soups/tutorial/tutorial.snip.markdown +69 -0
- data/pristine_app/soups/tutorial/vanilla-rb.snip +16 -0
- data/pristine_app/soups/tutorial/vanilla.snip +8 -0
- data/test/dynasnip_test.rb +42 -0
- data/test/dynasnips/link_to_current_snip_test.rb +19 -0
- data/test/dynasnips/link_to_test.rb +27 -0
- data/test/dynasnips/page_title_test.rb +19 -0
- data/test/renderers/base_renderer_test.rb +43 -0
- data/test/renderers/erb_renderer_test.rb +29 -0
- data/test/renderers/haml_renderer_test.rb +35 -0
- data/test/renderers/markdown_renderer_test.rb +31 -0
- data/test/renderers/raw_renderer_test.rb +23 -0
- data/test/renderers/ruby_renderer_test.rb +59 -0
- data/test/snip_inclusion_test.rb +56 -0
- data/test/snip_reference_parser_test.rb +123 -0
- data/test/test_helper.rb +75 -0
- data/test/vanilla_app_test.rb +83 -0
- data/test/vanilla_presenting_test.rb +125 -0
- data/test/vanilla_request_test.rb +87 -0
- metadata +179 -78
- data/config.example.yml +0 -5
- data/config.ru +0 -9
- data/lib/defensio.rb +0 -59
- data/lib/tasks/vanilla.rake +0 -177
- data/lib/vanilla/dynasnips/comments.rb +0 -108
- data/lib/vanilla/dynasnips/current_snip.rb +0 -32
- data/lib/vanilla/dynasnips/edit.rb +0 -63
- data/lib/vanilla/dynasnips/edit_link.rb +0 -24
- data/lib/vanilla/dynasnips/index.rb +0 -11
- data/lib/vanilla/dynasnips/link_to_current_snip.rb +0 -16
- data/lib/vanilla/dynasnips/login.rb +0 -56
- data/lib/vanilla/dynasnips/new.rb +0 -14
- data/lib/vanilla/dynasnips/notes.rb +0 -42
- data/lib/vanilla/dynasnips/url_to.rb +0 -7
- data/lib/vanilla/snip_handling.rb +0 -33
- data/lib/vanilla/snips/start.rb +0 -27
- data/lib/vanilla/snips/system.rb +0 -76
- data/lib/vanilla/snips/tutorial.rb +0 -157
- data/lib/vanilla/test_snips.rb +0 -85
- data/public/hatch.png +0 -0
- data/public/javascripts/jquery.js +0 -3549
- data/public/javascripts/vanilla.js +0 -21
- data/spec/dynasnip_spec.rb +0 -31
- data/spec/renderers/base_renderer_spec.rb +0 -40
- data/spec/renderers/erb_renderer_spec.rb +0 -27
- data/spec/renderers/markdown_renderer_spec.rb +0 -29
- data/spec/renderers/raw_renderer_spec.rb +0 -21
- data/spec/renderers/ruby_renderer_spec.rb +0 -42
- data/spec/renderers/vanilla_app_detecting_renderer_spec.rb +0 -35
- data/spec/spec_helper.rb +0 -64
- data/spec/vanilla_app_spec.rb +0 -38
- data/spec/vanilla_presenting_spec.rb +0 -84
- data/spec/vanilla_request_spec.rb +0 -73
- data/spec/vanilla_snip_finding_spec.rb +0 -28
@@ -1,108 +0,0 @@
|
|
1
|
-
require 'vanilla/dynasnip'
|
2
|
-
require 'defensio'
|
3
|
-
require 'date'
|
4
|
-
|
5
|
-
class Comments < Dynasnip
|
6
|
-
usage %|
|
7
|
-
Embed comments within snips!
|
8
|
-
|
9
|
-
{comments <snip-name>}
|
10
|
-
|
11
|
-
This will embed a list of comments, and a comment form, in a snip
|
12
|
-
If the snip is being rendered within another snip, it will show a link to the snip,
|
13
|
-
with the number of comments.
|
14
|
-
|
|
15
|
-
|
16
|
-
def get(snip_name=nil, disable_new_comments=false)
|
17
|
-
snip_name = snip_name || app.request.params[:snip]
|
18
|
-
return usage if self.class.snip_name == snip_name
|
19
|
-
comments = Soup.sieve(:commenting_on => snip_name)
|
20
|
-
comments_html = if app.request.snip_name == snip_name
|
21
|
-
rendered_comments = render_comments(comments)
|
22
|
-
rendered_comments += comment_form.gsub('SNIP_NAME', snip_name) unless disable_new_comments
|
23
|
-
rendered_comments
|
24
|
-
else
|
25
|
-
%{<a href="#{Vanilla::Routes.url_to(snip_name)}">#{comments.length} comments for #{snip_name}</a>}
|
26
|
-
end
|
27
|
-
return comments_html
|
28
|
-
end
|
29
|
-
|
30
|
-
def post(*args)
|
31
|
-
snip_name = app.request.params[:snip]
|
32
|
-
existing_comments = Soup.sieve(:commenting_on => snip_name)
|
33
|
-
comment = app.request.params.reject { |k,v| ![:author, :email, :website, :content].include?(k) }
|
34
|
-
|
35
|
-
return "You need to add some details!" if comment.empty?
|
36
|
-
|
37
|
-
comment = check_for_spam(comment)
|
38
|
-
|
39
|
-
if comment[:spam]
|
40
|
-
"Sorry - your comment looks like spam, according to Defensio :("
|
41
|
-
else
|
42
|
-
return "No spam today, thanks anyway" unless app.request.params[:human] == 'human'
|
43
|
-
Soup << comment.merge({
|
44
|
-
:name => "#{snip_name}-comment-#{existing_comments.length + 1}",
|
45
|
-
:commenting_on => snip_name,
|
46
|
-
:created_at => Time.now
|
47
|
-
})
|
48
|
-
"Thanks for your comment! Back to {link_to #{snip_name}}"
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def render_comments(comments)
|
53
|
-
"<h2>Comments</h2><ol class='comments'>" + comments.map do |comment|
|
54
|
-
rendered_comment = comment_template.gsub('COMMENT_CONTENT', app.render(comment)).
|
55
|
-
gsub('COMMENT_DATE', comment.created_at)
|
56
|
-
author = comment.author
|
57
|
-
author = "Anonymous" unless author && author != ""
|
58
|
-
if comment.website && comment.website != ""
|
59
|
-
rendered_comment.gsub!('COMMENT_AUTHOR', "<a href=\"#{comment.website}\">#{author}</a>")
|
60
|
-
else
|
61
|
-
rendered_comment.gsub!('COMMENT_AUTHOR', author)
|
62
|
-
end
|
63
|
-
rendered_comment
|
64
|
-
end.join + "</ol>"
|
65
|
-
end
|
66
|
-
|
67
|
-
def check_for_spam(comment)
|
68
|
-
snip_date = Date.parse(Soup[app.request.params[:snip]].updated_at)
|
69
|
-
Defensio.configure(app.config[:defensio])
|
70
|
-
defensio_params = {
|
71
|
-
:comment_author_email => comment[:email],
|
72
|
-
:comment_author => comment[:author],
|
73
|
-
:comment_author_url => comment[:website],
|
74
|
-
:comment_content => comment[:content],
|
75
|
-
:comment_type => "comment",
|
76
|
-
:user_ip => app.request.ip,
|
77
|
-
:article_date => snip_date.strftime("%Y/%m/%d")
|
78
|
-
}
|
79
|
-
audit = Defensio.audit_comment(defensio_params)
|
80
|
-
|
81
|
-
# Augment the comment hash
|
82
|
-
comment[:user_ip] = app.request.ip
|
83
|
-
comment[:spamminess] = audit["defensio_result"]["spaminess"]
|
84
|
-
comment[:spam] = audit["defensio_result"]["spam"]
|
85
|
-
comment[:defensio_signature] = audit["defensio_result"]["signature"]
|
86
|
-
comment[:defensio_message] = audit["defensio_result"]["message"] if audit["defensio_result"]["message"]
|
87
|
-
comment[:defensio_status] = audit["defensio_result"]["status"]
|
88
|
-
comment
|
89
|
-
end
|
90
|
-
|
91
|
-
attribute :comment_template, %{
|
92
|
-
<li>
|
93
|
-
<p>COMMENT_AUTHOR (COMMENT_DATE)</p>
|
94
|
-
<div>COMMENT_CONTENT</div>
|
95
|
-
</li>
|
96
|
-
}
|
97
|
-
|
98
|
-
attribute :comment_form, %{
|
99
|
-
<form class="comments" action="/#{snip_name}?snip=SNIP_NAME" method="POST">
|
100
|
-
<label>Name: <input type="text" name="author"></input></label>
|
101
|
-
<label>Email: <input type="text" name="email"></input></label>
|
102
|
-
<label>Website: <input type="text" name="website"></input></label>
|
103
|
-
<textarea name="content"></textarea>
|
104
|
-
<label class="human">Type 'human' if you are one: <input type="text" name="human"></input></label>
|
105
|
-
<button>Submit</button>
|
106
|
-
</form>
|
107
|
-
}
|
108
|
-
end
|
@@ -1,32 +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 the name of the current snip in a consistent way:
|
10
|
-
|
11
|
-
{current_snip name}
|
12
|
-
|
13
|
-
will output the name of the current snip, or the name of the snip currently being edited.
|
14
|
-
|
|
15
|
-
|
16
|
-
def handle(*args)
|
17
|
-
if args[0] == 'name'
|
18
|
-
if app.request.snip_name == 'edit' # we're editing so don't use this name
|
19
|
-
app.request.params[:snip_to_edit]
|
20
|
-
else
|
21
|
-
app.request.snip_name
|
22
|
-
end
|
23
|
-
else
|
24
|
-
if app.request.snip
|
25
|
-
app.render(app.request.snip, app.request.part)
|
26
|
-
else
|
27
|
-
app.response.status = 404
|
28
|
-
"Couldn't find snip {link_to #{app.request.snip_name}}"
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
@@ -1,63 +0,0 @@
|
|
1
|
-
require 'vanilla/dynasnip'
|
2
|
-
require 'vanilla/dynasnips/login'
|
3
|
-
|
4
|
-
# The edit dyna will load the snip given in the 'snip_to_edit' part of the
|
5
|
-
# params
|
6
|
-
class EditSnip < Dynasnip
|
7
|
-
include Login::Helper
|
8
|
-
|
9
|
-
snip_name "edit"
|
10
|
-
|
11
|
-
def get(snip_name=nil)
|
12
|
-
return login_required unless logged_in?
|
13
|
-
snip = Vanilla.snip(snip_name || app.request.params[:name])
|
14
|
-
edit(snip)
|
15
|
-
end
|
16
|
-
|
17
|
-
def post(*args)
|
18
|
-
return login_required unless logged_in?
|
19
|
-
snip_attributes = cleaned_params
|
20
|
-
snip_attributes.delete(:save_button)
|
21
|
-
return 'no params' if snip_attributes.empty?
|
22
|
-
snip = Vanilla.snip(snip_attributes[:name])
|
23
|
-
snip_attributes[:updated_at] = Time.now
|
24
|
-
snip_attributes.each do |name, value|
|
25
|
-
snip.__send__(:set_value, name, value)
|
26
|
-
end
|
27
|
-
snip.save
|
28
|
-
%{Saved snip #{Vanilla::Routes.link_to snip_attributes[:name]} ok}
|
29
|
-
rescue Exception => e
|
30
|
-
snip_attributes[:created_at] ||= Time.now
|
31
|
-
Soup << snip_attributes
|
32
|
-
%{Created snip #{Vanilla::Routes.link_to snip_attributes[:name]} ok}
|
33
|
-
end
|
34
|
-
|
35
|
-
def edit(snip)
|
36
|
-
renderer = Vanilla::Renderers::Erb.new(app)
|
37
|
-
renderer.instance_eval { @snip_to_edit = snip } # hacky!
|
38
|
-
snip_in_edit_template = renderer.render_without_including_snips(Vanilla.snip('edit'), :template)
|
39
|
-
prevent_snip_inclusion(snip_in_edit_template)
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
|
44
|
-
def prevent_snip_inclusion(content)
|
45
|
-
content.gsub("{", "{").gsub("}" ,"}")
|
46
|
-
end
|
47
|
-
|
48
|
-
attribute :template, %{
|
49
|
-
<form action="<%= Vanilla::Routes.url_to 'edit' %>" method="post">
|
50
|
-
<dl class="attributes">
|
51
|
-
<% @snip_to_edit.attributes.each do |name, value| %>
|
52
|
-
<dt><%= name %></dt>
|
53
|
-
<% num_rows = (value || "").split("\n").length + 1 %>
|
54
|
-
<dd><textarea name="<%= name %>" class="<%= name %>" rows="<%= num_rows %>"><%=h value %></textarea></dd>
|
55
|
-
<% end %>
|
56
|
-
<dt><input class="attribute_name" type="text"></dt>
|
57
|
-
<dd><textarea></textarea></dd>
|
58
|
-
</dl>
|
59
|
-
<a href="#" id="add">Add</a>
|
60
|
-
<button name='save_button'>Save</button>
|
61
|
-
</form>
|
62
|
-
}
|
63
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
require 'vanilla/dynasnip'
|
2
|
-
|
3
|
-
class EditLink < Dynasnip
|
4
|
-
usage %|
|
5
|
-
You can use the edit_link snip to insert links for editing other snips. For example:
|
6
|
-
|
7
|
-
{edit_link blah}
|
8
|
-
|
9
|
-
would insert a link to an editor for the blah snip.
|
10
|
-
|
11
|
-
You can also give a custom piece of text for the link, like this:
|
12
|
-
|
13
|
-
{edit_link blah,link-name}|
|
14
|
-
|
15
|
-
def handle(*args)
|
16
|
-
if args.length < 2
|
17
|
-
show_usage
|
18
|
-
else
|
19
|
-
snip_name = args[0]
|
20
|
-
link_text = args[1]
|
21
|
-
Vanilla::Routes.edit_link(snip_name, link_text)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,11 +0,0 @@
|
|
1
|
-
require 'vanilla/dynasnip'
|
2
|
-
|
3
|
-
class Index < Dynasnip
|
4
|
-
def get(*args)
|
5
|
-
# TODO: figure out a way around calling Soup/AR methods directly.
|
6
|
-
list = Soup.tuple_class.find_all_by_name('name').map { |tuple|
|
7
|
-
"<li>#{Vanilla::Routes.link_to tuple.value}</li>"
|
8
|
-
}
|
9
|
-
"<ol>#{list}</ol>"
|
10
|
-
end
|
11
|
-
end
|
@@ -1,16 +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
|
-
if app.request.snip_name == 'edit' # we're editing so don't use this name
|
11
|
-
Vanilla::Routes.link_to app.request.params[:snip_to_edit]
|
12
|
-
else
|
13
|
-
Vanilla::Routes.link_to app.request.snip_name
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,56 +0,0 @@
|
|
1
|
-
require 'vanilla/dynasnip'
|
2
|
-
require 'yaml'
|
3
|
-
require 'md5'
|
4
|
-
|
5
|
-
class Login < Dynasnip
|
6
|
-
module Helper
|
7
|
-
def logged_in?
|
8
|
-
!current_user.nil?
|
9
|
-
end
|
10
|
-
|
11
|
-
def current_user
|
12
|
-
app.request.session['logged_in_as']
|
13
|
-
end
|
14
|
-
|
15
|
-
def login_required
|
16
|
-
"You need to <a href='/login'>login</a> to do that."
|
17
|
-
end
|
18
|
-
end
|
19
|
-
include Helper
|
20
|
-
|
21
|
-
def get(*args)
|
22
|
-
if logged_in?
|
23
|
-
login_controls
|
24
|
-
else
|
25
|
-
render(self, 'template')
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def post(*args)
|
30
|
-
if app.config[:credentials][cleaned_params[:name]] == MD5.md5(cleaned_params[:password]).to_s
|
31
|
-
app.request.session['logged_in_as'] = cleaned_params[:name]
|
32
|
-
login_controls
|
33
|
-
else
|
34
|
-
"login fail!"
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def delete(*args)
|
39
|
-
app.request.session['logged_in_as'] = nil
|
40
|
-
"Logged out"
|
41
|
-
end
|
42
|
-
|
43
|
-
attribute :template, <<-EHTML
|
44
|
-
<form action='/login' method='post'>
|
45
|
-
<label>Name: <input type="text" name="name"></input></label>
|
46
|
-
<label>Password: <input type="password" name="password"></input></label>
|
47
|
-
<button>login</button>
|
48
|
-
</form>
|
49
|
-
EHTML
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
def login_controls
|
54
|
-
"logged in as {link_to #{app.request.session['logged_in_as']}}; <a href='/login?_method=delete'>logout</a>"
|
55
|
-
end
|
56
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
require 'vanilla/dynasnip'
|
2
|
-
require 'vanilla/dynasnips/login'
|
3
|
-
|
4
|
-
class NewSnip < Dynasnip
|
5
|
-
include Login::Helper
|
6
|
-
|
7
|
-
snip_name :new
|
8
|
-
|
9
|
-
def handle(*arg)
|
10
|
-
return login_required unless logged_in?
|
11
|
-
base_params = {:render_as => '', :content => '', :author => current_user}.update(app.request.params)
|
12
|
-
editor = EditSnip.new(app).edit(Snip.new(base_params))
|
13
|
-
end
|
14
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
require 'vanilla/dynasnip'
|
2
|
-
|
3
|
-
class Notes < Dynasnip
|
4
|
-
def get(*args)
|
5
|
-
all_notes_content = all_notes.map { |snip|
|
6
|
-
render_note(snip)
|
7
|
-
}.join("")
|
8
|
-
snip.main_template.gsub('[notes]', all_notes_content)
|
9
|
-
end
|
10
|
-
|
11
|
-
def post(*args)
|
12
|
-
new_note = Snip.new(cleaned_params)
|
13
|
-
new_note.name = "note_#{snip.next_note_id}"
|
14
|
-
new_note.kind = "note"
|
15
|
-
new_note.save
|
16
|
-
increment_next_id
|
17
|
-
get(*args)
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def all_notes
|
23
|
-
Snip.with(:kind, "= 'note'")
|
24
|
-
end
|
25
|
-
|
26
|
-
def increment_next_id
|
27
|
-
s = snip
|
28
|
-
s.next_note_id = s.next_note_id.to_i + 1
|
29
|
-
s.save
|
30
|
-
end
|
31
|
-
|
32
|
-
def render_note(note)
|
33
|
-
note_link = Vanilla::Routes.link_to(note.name)
|
34
|
-
note_content = Vanilla.render(note.name, nil, context, [])
|
35
|
-
snip.note_template.gsub('[note]', note_content).gsub('[link]', note_link)
|
36
|
-
end
|
37
|
-
|
38
|
-
attribute :next_note_id, 1
|
39
|
-
|
40
|
-
attribute :note_template, %{<dt>[link]</dt><dd>[note]</dd>}
|
41
|
-
attribute :main_template, %{<dl>[notes]</dl>}
|
42
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
module Vanilla
|
2
|
-
module SnipHandling
|
3
|
-
class MissingSnipException < Exception; end
|
4
|
-
|
5
|
-
def self.included(base)
|
6
|
-
base.extend(ClassMethods)
|
7
|
-
end
|
8
|
-
|
9
|
-
module ClassMethods
|
10
|
-
def snip(name)
|
11
|
-
snip = Soup[name]
|
12
|
-
if snip.is_a?(Array) && snip.empty?
|
13
|
-
return nil
|
14
|
-
end
|
15
|
-
snip
|
16
|
-
end
|
17
|
-
|
18
|
-
def snip!(name)
|
19
|
-
snip = snip(name)
|
20
|
-
raise MissingSnipException, "can't find '#{name}'" unless snip
|
21
|
-
end
|
22
|
-
|
23
|
-
def snip_exists?(name)
|
24
|
-
snip = Soup[name]
|
25
|
-
if snip.is_a?(Array) && snip.empty?
|
26
|
-
false
|
27
|
-
else
|
28
|
-
true
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
data/lib/vanilla/snips/start.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
start = Snip.new(:name => 'start')
|
2
|
-
start.content = <<-START
|
3
|
-
Welcome to Vanilla.rb
|
4
|
-
=============
|
5
|
-
|
6
|
-
Vanilla.rb is a web-experiment (a _websperiment_?) about storing and reusing data on a website. It can also function as a [bliki](http://www.wikipedia.com/wiki/Bliki).
|
7
|
-
|
8
|
-
The fundamental building block is the 'snip', which is a malleable object that can store content and arbitrary metadata.
|
9
|
-
|
10
|
-
---
|
11
|
-
|
12
|
-
This is the {link_to start} snip, which is the default home page.
|
13
|
-
|
14
|
-
You might want to check out the {link_to vanilla-rb-tutorial} snip.
|
15
|
-
|
16
|
-
In fact - I'll include it here for you:
|
17
|
-
|
18
|
-
{vanilla-rb-tutorial}
|
19
|
-
|
20
|
-
---
|
21
|
-
|
22
|
-
That was the end of the tutorial snip. We're back in the start snip now. There's also the {link_to test} snip, that might be interesting.
|
23
|
-
|
24
|
-
Anyway, welcome.
|
25
|
-
START
|
26
|
-
start.render_as = "Markdown"
|
27
|
-
start.save
|