vanilla 1.12.5 → 1.13.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +3 -4
- data/config.example.yml +1 -0
- data/config.ru +0 -14
- data/lib/tasks/vanilla.rake +13 -50
- data/lib/vanilla/app.rb +0 -3
- data/lib/vanilla/dynasnips/comments.rb +16 -47
- data/lib/vanilla/dynasnips/index.rb +2 -2
- data/lib/vanilla/request.rb +0 -16
- data/lib/vanilla/snips/system/layout.snip +19 -0
- data/lib/vanilla/snips/{start.rb → system/start.snip} +3 -6
- data/lib/vanilla/snips/system/system.snip +17 -0
- data/lib/vanilla/snips/tutorial/bad_dynasnip.snip +8 -0
- data/lib/vanilla/snips/tutorial/hello_world.snip +20 -0
- data/lib/vanilla/snips/tutorial/markdown_example.snip +13 -0
- data/lib/vanilla/snips/tutorial/snip.snip +9 -0
- data/lib/vanilla/snips/tutorial/soup.snip +5 -0
- data/lib/vanilla/snips/tutorial/test.snip +30 -0
- data/lib/vanilla/snips/tutorial/textile_example.snip +11 -0
- data/lib/vanilla/snips/tutorial/tutorial-another-snip.snip +1 -0
- data/lib/vanilla/snips/tutorial/tutorial-basic-snip-inclusion.snip +1 -0
- data/lib/vanilla/snips/tutorial/vanilla-rb-tutorial.snip +73 -0
- data/lib/vanilla/snips/tutorial/vanilla-rb.snip +16 -0
- data/lib/vanilla/snips/tutorial/vanilla.snip +8 -0
- data/lib/vanilla.rb +4 -0
- data/test/tmp/config.yml +1 -1
- data/test/tmp/soup/current_snip.snip +2 -2
- metadata +28 -42
- data/lib/defensio.rb +0 -59
- data/lib/vanilla/authentication/warden.rb +0 -58
- data/lib/vanilla/authentication.rb +0 -24
- data/lib/vanilla/dynasnips/edit.rb +0 -59
- data/lib/vanilla/dynasnips/edit_link.rb +0 -20
- data/lib/vanilla/dynasnips/logout.rb +0 -8
- data/lib/vanilla/dynasnips/new.rb +0 -12
- data/lib/vanilla/snips/system.rb +0 -84
- data/lib/vanilla/snips/tutorial.rb +0 -244
- data/public/javascripts/jquery.autogrow-textarea.js +0 -54
- data/public/javascripts/jquery.js +0 -4376
- data/public/javascripts/vanilla.js +0 -22
data/Rakefile
CHANGED
@@ -24,7 +24,7 @@ if Object.const_defined?(:Gem)
|
|
24
24
|
|
25
25
|
# Change these as appropriate
|
26
26
|
s.name = "vanilla"
|
27
|
-
s.version =
|
27
|
+
s.version = Vanilla::VERSION
|
28
28
|
s.summary = "A bliki-type web content thing."
|
29
29
|
s.author = "James Adam"
|
30
30
|
s.email = "james@lazyatom.com.com"
|
@@ -41,16 +41,15 @@ if Object.const_defined?(:Gem)
|
|
41
41
|
|
42
42
|
# All the other gems we need.
|
43
43
|
s.add_dependency("rack", ">= 0.9.1")
|
44
|
-
s.add_dependency("soup", ">= 1.0.
|
44
|
+
s.add_dependency("soup", ">= 1.0.3")
|
45
45
|
s.add_dependency("ratom", ">= 0.3.5")
|
46
46
|
s.add_dependency("RedCloth", ">= 4.1.1")
|
47
47
|
s.add_dependency("BlueCloth", ">= 1.0.0")
|
48
48
|
s.add_dependency("treetop", ">= 1.4.1")
|
49
|
-
s.add_dependency("
|
49
|
+
s.add_dependency("haml")
|
50
50
|
|
51
51
|
s.add_development_dependency("shoulda") # add any other gems for testing/development
|
52
52
|
s.add_development_dependency("mocha")
|
53
|
-
s.add_development_dependency("haml")
|
54
53
|
|
55
54
|
# If you want to publish automatically to rubyforge, you'll may need
|
56
55
|
# to tweak this, and the publishing task below too.
|
data/config.example.yml
CHANGED
data/config.ru
CHANGED
@@ -6,19 +6,5 @@ require 'vanilla'
|
|
6
6
|
require 'vanilla/static'
|
7
7
|
|
8
8
|
app = Vanilla::App.new(ENV['VANILLA_CONFIG'])
|
9
|
-
|
10
|
-
use Rack::Session::Cookie, :key => 'vanilla.session',
|
11
|
-
:path => '/',
|
12
|
-
:expire_after => 2592000,
|
13
|
-
:secret => app.config[:secret]
|
14
|
-
|
15
|
-
require 'vanilla/authentication/warden'
|
16
|
-
app.authenticator = Vanilla::Authentication::Warden.new(app)
|
17
|
-
use Warden::Manager do |manager|
|
18
|
-
manager.default_strategies :vanilla
|
19
|
-
manager.failure_app = Vanilla::Authentication::Warden::FailApp.new
|
20
|
-
end
|
21
|
-
|
22
9
|
use Vanilla::Static, File.join(File.dirname(__FILE__), 'public')
|
23
|
-
|
24
10
|
run app
|
data/lib/tasks/vanilla.rake
CHANGED
@@ -13,50 +13,6 @@ namespace :vanilla do
|
|
13
13
|
puts "TODO, but should be easier thanks to multi-space soup."
|
14
14
|
end
|
15
15
|
|
16
|
-
desc 'Add a user (or change an existing password)'
|
17
|
-
task :add_user => :prepare do
|
18
|
-
puts "Adding a new user"
|
19
|
-
# config_file = ENV['VANILLA_CONFIG'] || 'config.yml'
|
20
|
-
# config_file = YAML.load(File.open(config_file)) rescue {}
|
21
|
-
app = Vanilla::App.new(ENV['VANILLA_CONFIG'])
|
22
|
-
print "Username: "
|
23
|
-
username = STDIN.gets.chomp.strip
|
24
|
-
print "Password: "
|
25
|
-
password = STDIN.gets.chomp.strip
|
26
|
-
print "Confirm password: "
|
27
|
-
confirm_password = STDIN.gets.chomp.strip
|
28
|
-
if password != confirm_password
|
29
|
-
raise "Passwords don't match!"
|
30
|
-
else
|
31
|
-
app.config[:credentials] ||= {}
|
32
|
-
app.config[:credentials][username] = MD5.md5(password).to_s
|
33
|
-
app.config.save!
|
34
|
-
puts "User '#{username}' added."
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
desc 'Generate file containing secret for cookie-based session storage'
|
39
|
-
task :generate_secret do
|
40
|
-
print "Generating cookie secret... "
|
41
|
-
# Adapted from old rails secret generator.
|
42
|
-
require 'openssl'
|
43
|
-
if !File.exist?("/dev/urandom")
|
44
|
-
# OpenSSL transparently seeds the random number generator with
|
45
|
-
# data from /dev/urandom. On platforms where that is not
|
46
|
-
# available, such as Windows, we have to provide OpenSSL with
|
47
|
-
# our own seed. Unfortunately there's no way to provide a
|
48
|
-
# secure seed without OS support, so we'll have to do with
|
49
|
-
# rand() and Time.now.usec().
|
50
|
-
OpenSSL::Random.seed(rand(0).to_s + Time.now.usec.to_s)
|
51
|
-
end
|
52
|
-
data = OpenSSL::BN.rand(2048, -1, false).to_s
|
53
|
-
secret = OpenSSL::Digest::SHA1.new(data).hexdigest
|
54
|
-
app = Vanilla::App.new(ENV['VANILLA_CONFIG'])
|
55
|
-
app.config[:secret] = secret
|
56
|
-
app.config.save!
|
57
|
-
puts "done; cookies are twice baked. BIS-CUIT!"
|
58
|
-
end
|
59
|
-
|
60
16
|
desc 'Prepare a new vanilla.rb installation'
|
61
17
|
task :setup do
|
62
18
|
puts <<-EOM
|
@@ -67,7 +23,6 @@ thing ever. Lets get started.
|
|
67
23
|
|
68
24
|
EOM
|
69
25
|
Rake::Task['vanilla:setup:prepare_files'].invoke
|
70
|
-
Rake::Task['vanilla:generate_secret'].invoke
|
71
26
|
Rake::Task['vanilla:setup:load_snips'].invoke
|
72
27
|
|
73
28
|
puts <<-EOM
|
@@ -95,17 +50,25 @@ load 'tasks/vanilla.rake'
|
|
95
50
|
EOF
|
96
51
|
f.write rakefile.strip
|
97
52
|
end
|
53
|
+
File.open("Gemfile", "w") do |f|
|
54
|
+
gemfile =<<-EOF
|
55
|
+
source :rubygems
|
56
|
+
|
57
|
+
gem "vanilla", #{Vanilla::VERSION.inspect}
|
58
|
+
EOF
|
59
|
+
f.write gemfile.strip
|
60
|
+
end
|
98
61
|
end
|
99
62
|
|
100
63
|
task :load_snips do
|
101
64
|
print "Preparing soup... "
|
102
|
-
|
103
|
-
|
65
|
+
|
66
|
+
mkdir_p "soup/system"
|
67
|
+
FileUtils.cp_r(File.join(File.dirname(__FILE__), '..', 'vanilla', 'snips', 'system'), "soup")
|
68
|
+
FileUtils.cp_r(File.join(File.dirname(__FILE__), '..', 'vanilla', 'snips', 'tutorial'), "soup")
|
69
|
+
|
104
70
|
dynasnip_soup = ::Soup.new(::Soup::Backends::FileBackend.new("soup/system/dynasnips"))
|
105
71
|
Dynasnip.all.each { |ds| dynasnip_soup << ds.snip_attributes }
|
106
|
-
Dir[File.join(File.dirname(__FILE__), '..', 'vanilla', 'snips', '{start,tutorial}.rb')].each do |f|
|
107
|
-
load f
|
108
|
-
end
|
109
72
|
puts "the soup is simmering."
|
110
73
|
end
|
111
74
|
end
|
data/lib/vanilla/app.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'soup'
|
2
2
|
require 'vanilla/request'
|
3
|
-
require 'vanilla/authentication'
|
4
3
|
require 'vanilla/routes'
|
5
4
|
|
6
5
|
# Require the base set of renderers
|
@@ -13,12 +12,10 @@ module Vanilla
|
|
13
12
|
include Routes
|
14
13
|
|
15
14
|
attr_reader :request, :response, :config, :soup
|
16
|
-
attr_accessor :authenticator
|
17
15
|
|
18
16
|
def initialize(config_file=nil)
|
19
17
|
prepare_configuration(config_file)
|
20
18
|
@soup = prepare_soup(config)
|
21
|
-
@authenticator = Vanilla::Authentication::Base.new(self)
|
22
19
|
end
|
23
20
|
|
24
21
|
# Returns a Rack-appropriate 3-element array (via Rack::Response#finish)
|
@@ -1,13 +1,12 @@
|
|
1
1
|
require 'vanilla/dynasnip'
|
2
|
-
require 'defensio'
|
3
2
|
require 'date'
|
4
3
|
|
5
4
|
class Comments < Dynasnip
|
6
5
|
usage %|
|
7
6
|
Embed comments within snips!
|
8
|
-
|
7
|
+
|
9
8
|
{comments <false>}
|
10
|
-
|
9
|
+
|
11
10
|
This will embed a list of comments, and a comment form, in a snip
|
12
11
|
If the snip is being rendered within another snip, it will show a link to the snip,
|
13
12
|
with the number of comments. Add a parameter to disable new comments.
|
@@ -25,29 +24,23 @@ class Comments < Dynasnip
|
|
25
24
|
end
|
26
25
|
return comments_html
|
27
26
|
end
|
28
|
-
|
27
|
+
|
29
28
|
def post(*args)
|
30
29
|
snip_name = app.request.params[:snip]
|
31
30
|
existing_comments = app.soup.with(:commenting_on => snip_name)
|
32
31
|
comment = app.request.params.reject { |k,v| ![:author, :email, :website, :content].include?(k) }
|
33
|
-
|
32
|
+
|
34
33
|
return "You need to add some details!" if comment.empty?
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
:name => "#{snip_name}-comment-#{existing_comments.length + 1}",
|
44
|
-
:commenting_on => snip_name,
|
45
|
-
:created_at => Time.now
|
46
|
-
})
|
47
|
-
"Thanks for your comment! Back to {link_to #{snip_name}}"
|
48
|
-
end
|
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}}"
|
49
42
|
end
|
50
|
-
|
43
|
+
|
51
44
|
def render_comments(comments)
|
52
45
|
"<h2>Comments</h2><ol class='comments'>" + comments.map do |comment|
|
53
46
|
rendered_comment = comment_template.gsub('COMMENT_CONTENT', app.render(comment)).
|
@@ -60,40 +53,16 @@ class Comments < Dynasnip
|
|
60
53
|
rendered_comment.gsub!('COMMENT_AUTHOR', author)
|
61
54
|
end
|
62
55
|
rendered_comment
|
63
|
-
end.join + "</ol>"
|
64
|
-
end
|
65
|
-
|
66
|
-
def check_for_spam(comment)
|
67
|
-
snip_date = Date.parse(app.soup[app.request.params[:snip]].updated_at)
|
68
|
-
Defensio.configure(app.config[:defensio])
|
69
|
-
defensio_params = {
|
70
|
-
:comment_author_email => comment[:email],
|
71
|
-
:comment_author => comment[:author],
|
72
|
-
:comment_author_url => comment[:website],
|
73
|
-
:comment_content => comment[:content],
|
74
|
-
:comment_type => "comment",
|
75
|
-
:user_ip => app.request.ip,
|
76
|
-
:article_date => snip_date.strftime("%Y/%m/%d")
|
77
|
-
}
|
78
|
-
audit = Defensio.audit_comment(defensio_params)
|
79
|
-
|
80
|
-
# Augment the comment hash
|
81
|
-
comment[:user_ip] = app.request.ip
|
82
|
-
comment[:spamminess] = audit["defensio_result"]["spaminess"]
|
83
|
-
comment[:spam] = audit["defensio_result"]["spam"]
|
84
|
-
comment[:defensio_signature] = audit["defensio_result"]["signature"]
|
85
|
-
comment[:defensio_message] = audit["defensio_result"]["message"] if audit["defensio_result"]["message"]
|
86
|
-
comment[:defensio_status] = audit["defensio_result"]["status"]
|
87
|
-
comment
|
56
|
+
end.join + "</ol>"
|
88
57
|
end
|
89
|
-
|
58
|
+
|
90
59
|
attribute :comment_template, %{
|
91
60
|
<li>
|
92
61
|
<p>COMMENT_AUTHOR (COMMENT_DATE)</p>
|
93
62
|
<div>COMMENT_CONTENT</div>
|
94
63
|
</li>
|
95
64
|
}
|
96
|
-
|
65
|
+
|
97
66
|
attribute :comment_form, %{
|
98
67
|
<form class="comments" action="/#{snip_name}?snip=SNIP_NAME" method="POST">
|
99
68
|
<label>Name: <input type="text" name="author"></input></label>
|
@@ -2,9 +2,9 @@ require 'vanilla/dynasnip'
|
|
2
2
|
|
3
3
|
class Index < Dynasnip
|
4
4
|
def get(*args)
|
5
|
-
list = app.soup.all_snips.sort_by { |a| a.updated_at || Time.at(0) }.reverse.map { |snip|
|
5
|
+
list = app.soup.instance_eval { @backend }.send(:all_snips).sort_by { |a| a.updated_at || Time.at(0) }.reverse.map { |snip|
|
6
6
|
"<li>#{link_to snip.name}</li>"
|
7
7
|
}
|
8
8
|
"<ol>#{list}</ol>"
|
9
9
|
end
|
10
|
-
end
|
10
|
+
end
|
data/lib/vanilla/request.rb
CHANGED
@@ -36,22 +36,6 @@ module Vanilla
|
|
36
36
|
@rack_request.env["rack.session"]
|
37
37
|
end
|
38
38
|
|
39
|
-
def authenticated?
|
40
|
-
@app.authenticator.authenticated?
|
41
|
-
end
|
42
|
-
|
43
|
-
def user
|
44
|
-
@app.authenticator.user
|
45
|
-
end
|
46
|
-
|
47
|
-
def authenticate!
|
48
|
-
@app.authenticator.authenticate!
|
49
|
-
end
|
50
|
-
|
51
|
-
def logout
|
52
|
-
@app.authenticator.logout
|
53
|
-
end
|
54
|
-
|
55
39
|
private
|
56
40
|
|
57
41
|
def determine_request_uri_parts
|
@@ -0,0 +1,19 @@
|
|
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>{title}</title>
|
6
|
+
<link rel="stylesheet" type="text/css" media="screen" href="<%= url_to("system", "css.css") %>" />
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<div id="content">
|
10
|
+
<div id="controls">
|
11
|
+
<strong><a href="/">home</a></strong> ::
|
12
|
+
<strong>{link_to_current_snip}</strong>
|
13
|
+
</div>
|
14
|
+
{current_snip}
|
15
|
+
</div>
|
16
|
+
</body>
|
17
|
+
</html>
|
18
|
+
|
19
|
+
:render_as: Erb
|
@@ -1,6 +1,3 @@
|
|
1
|
-
app = Vanilla::App.new(ENV['VANILLA_CONFIG'])
|
2
|
-
start = app.snip(:name => 'start')
|
3
|
-
start.content = <<-START
|
4
1
|
Welcome to Vanilla.rb
|
5
2
|
=============
|
6
3
|
|
@@ -23,6 +20,6 @@ In fact - I'll include it here for you:
|
|
23
20
|
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.
|
24
21
|
|
25
22
|
Anyway, welcome.
|
26
|
-
|
27
|
-
|
28
|
-
|
23
|
+
|
24
|
+
|
25
|
+
:render_as: "Markdown"
|
@@ -0,0 +1,20 @@
|
|
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
|
@@ -0,0 +1,9 @@
|
|
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
|
@@ -0,0 +1,30 @@
|
|
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
|
@@ -0,0 +1 @@
|
|
1
|
+
this is another snip!
|
@@ -0,0 +1 @@
|
|
1
|
+
This is a snip, which includes another {link_to snip}: {tutorial-another-snip}
|
@@ -0,0 +1,73 @@
|
|
1
|
+
Basic Concepts
|
2
|
+
------------
|
3
|
+
|
4
|
+
Firstly, open the raw contents of this snip - either in your edit (search for 'vanilla-rb-tutorial.snip'), or by opening <a href="vanilla-rb-tutorial.raw">this snip in raw format</a> in a new window or tab. Ready? OK.
|
5
|
+
|
6
|
+
Every piece of information displayed here is stored as a {link_to snip}. Snips, within their contents, can also reference other snips. When you request a snip, it will render into a page (or another kind of response), and also render any snips that it internally references.
|
7
|
+
|
8
|
+
For example, consider the snip {link_to tutorial-basic-snip-inclusion}:
|
9
|
+
|
10
|
+
{raw tutorial-basic-snip-inclusion}
|
11
|
+
|
12
|
+
When this snip is rendered, it appears like this:
|
13
|
+
|
14
|
+
{tutorial-basic-snip-inclusion}
|
15
|
+
|
16
|
+
Notice the use of curly brackets to reference one snip from inside another. Vanilla.rb finds these references to snips, then renders that snip and replaces it in the first snip. Neat!
|
17
|
+
|
18
|
+
Renderers
|
19
|
+
--------
|
20
|
+
|
21
|
+
The way that a snip is rendered depends on whether or not it has a `render_as` attribute set. For instance, the `render_as` property of this snip is "Markdown". Scroll to the bottom of the raw snip you opened earlier, and you'll see this being declared.
|
22
|
+
|
23
|
+
This means that the `content` of this snip will be passed through `Vanilla::Renderers::Markdown` before it is then rendered to the page. There are several different renders provided by Vanilla.rb at the moment:
|
24
|
+
|
25
|
+
* Markdown - as described above
|
26
|
+
* Textile - which performs similarly for Textile. This means that you can mix how you write the content of snips!
|
27
|
+
* Raw - which simply returns the content of the snip, as-is. If you attach a `.raw` extension to this url, you'll see it in action
|
28
|
+
* Bold - simply wraps the content in bold. It's a demo, essentially.
|
29
|
+
* Erb - passes the snip contents through Ruby's `Erb` library. It also makes some information available for use by ruby code within the snip's contents
|
30
|
+
* Ruby - parses the snips content as Ruby itself.
|
31
|
+
|
32
|
+
It's using this last renderer that a second concept of Vanilla is implemented - dynasnips.
|
33
|
+
|
34
|
+
|
35
|
+
Dynasnips
|
36
|
+
--------
|
37
|
+
|
38
|
+
Because the curly braces simply cause a snip to be rendered, we can use this in conjunction with the Ruby renderer to run actual code. For instance, in the snip above:
|
39
|
+
|
40
|
+
{raw tutorial-basic-snip-inclusion}
|
41
|
+
|
42
|
+
we can see a reference to the `link_to` snip - <tt>{link\_to snip}</tt>.
|
43
|
+
|
44
|
+
Lets look at the raw content of `link_to`:
|
45
|
+
|
46
|
+
{raw link_to}
|
47
|
+
|
48
|
+
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. So, in the case of <tt>{link\_to snip}</tt>, the only argument is `snip`.
|
49
|
+
|
50
|
+
Vanilla.rb includes a number of dynasnips by default. Here are a couple:
|
51
|
+
|
52
|
+
* `rand`, which generates a random number (a silly demo really); {link_to rand}, or an example: {rand}
|
53
|
+
* `link_to`, to produce a link to another snip
|
54
|
+
* `kind`, which selects and renders sets of snips based on their `kind` attribute (this is how the blog is currently implemented)
|
55
|
+
* `raw`, which displays the raw contents of a snip
|
56
|
+
* `index`, which shows all of the available snips: {link_to index}
|
57
|
+
* ... and several others.
|
58
|
+
|
59
|
+
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:
|
60
|
+
|
61
|
+
{raw hello_world}
|
62
|
+
|
63
|
+
which, when rendered, gives:
|
64
|
+
|
65
|
+
{hello_world}
|
66
|
+
|
67
|
+
Note that the `handle` method can take one (optional) argument. Lets try including it with <tt>{hello\_world Dave}</tt>:
|
68
|
+
|
69
|
+
{hello_world Dave}
|
70
|
+
|
71
|
+
Anyway - that should be enough to get you started.
|
72
|
+
|
73
|
+
:render_as: Markdown
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Vanilla.rb is the software powering this site. It's a sort-of wiki/bliki thing, based on {link_to vanilla}.
|
2
|
+
|
3
|
+
Here's the [introductory blog post][3].
|
4
|
+
|
5
|
+
It's developed on [github][1], and has a [lighthouse bug tracker][2]. At the moment it's not very well documented, since I'm exploring how the concept might work and the internals are subject to change. However, please do play around with it.
|
6
|
+
|
7
|
+
Here's the tutorial (helpfully included from {link_to vanilla-rb-tutorial}).
|
8
|
+
|
9
|
+
{vanilla-rb-tutorial}
|
10
|
+
|
11
|
+
|
12
|
+
[1]: http://github.com/lazyatom/vanilla
|
13
|
+
[2]: http://lazyatom.lighthouseapp.com/projects/11797-vanilla/tickets
|
14
|
+
[3]: http://interblah.net/introducing-vanilla-rb
|
15
|
+
|
16
|
+
:render_as: Markdown
|
data/lib/vanilla.rb
CHANGED
data/test/tmp/config.yml
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
---
|
2
|
-
:soup: /Users/james/
|
2
|
+
:soup: /Users/james/Code/lazyatom/vanilla-rb/test/tmp/soup
|
@@ -1,7 +1,5 @@
|
|
1
1
|
CurrentSnip
|
2
2
|
|
3
|
-
:render_as: Ruby
|
4
|
-
:name: current_snip
|
5
3
|
:usage: |-
|
6
4
|
The current_snip dyna normally returns the result of rendering the snip named by the
|
7
5
|
'snip' value in the parameters. This way, it can be used in templates to place the currently
|
@@ -12,3 +10,5 @@ CurrentSnip
|
|
12
10
|
{current_snip name}
|
13
11
|
|
14
12
|
will output the name of the current snip, or the name of the snip currently being edited.
|
13
|
+
:name: current_snip
|
14
|
+
:render_as: Ruby
|