vanilla 1.0.2 → 1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|