vanilla 1.17 → 1.17.1

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.
Files changed (56) hide show
  1. data/Rakefile +21 -7
  2. data/bin/vanilla +2 -2
  3. data/lib/vanilla.rb +10 -7
  4. data/lib/vanilla/app.rb +57 -97
  5. data/lib/vanilla/config.rb +46 -0
  6. data/lib/vanilla/console.rb +1 -1
  7. data/lib/vanilla/renderers/base.rb +12 -2
  8. data/lib/vanilla/request.rb +9 -34
  9. data/lib/vanilla/routing.rb +34 -0
  10. data/lib/vanilla/test_helper.rb +10 -7
  11. data/pristine_app/Gemfile.lock +35 -0
  12. data/pristine_app/application.rb +2 -4
  13. data/pristine_app/public/vanilla.css +299 -9
  14. data/pristine_app/soups/base/layout.snip +11 -7
  15. data/pristine_app/soups/base/start.snip +15 -14
  16. data/pristine_app/soups/system/current_snip.rb +2 -2
  17. data/pristine_app/soups/system/feed.rb +30 -0
  18. data/pristine_app/soups/system/index.rb +3 -3
  19. data/pristine_app/soups/system/link_to.rb +5 -1
  20. data/pristine_app/soups/system/link_to_current_snip.rb +2 -3
  21. data/pristine_app/soups/tutorial/tutorial-layout.snip +9 -2
  22. data/pristine_app/soups/tutorial/tutorial-links.snip +2 -1
  23. data/pristine_app/soups/tutorial/tutorial-removing.snip.markdown +8 -0
  24. data/pristine_app/soups/tutorial/tutorial-renderers.snip.markdown +10 -4
  25. data/pristine_app/soups/tutorial/tutorial.snip.markdown +0 -1
  26. data/pristine_app/soups/tutorial/vanilla-rb.snip +4 -6
  27. data/pristine_app/tmp/restart.txt +0 -0
  28. data/test/core/configuration_test.rb +89 -0
  29. data/test/{dynasnip_test.rb → core/dynasnip_test.rb} +0 -0
  30. data/test/{renderers → core/renderers}/base_renderer_test.rb +37 -0
  31. data/test/{renderers → core/renderers}/erb_renderer_test.rb +0 -0
  32. data/test/{renderers → core/renderers}/haml_renderer_test.rb +0 -0
  33. data/test/{renderers → core/renderers}/markdown_renderer_test.rb +0 -0
  34. data/test/{renderers → core/renderers}/raw_renderer_test.rb +0 -0
  35. data/test/{renderers → core/renderers}/ruby_renderer_test.rb +0 -0
  36. data/test/core/routing_test.rb +30 -0
  37. data/test/{snip_inclusion_test.rb → core/snip_inclusion_test.rb} +0 -0
  38. data/test/{snip_reference_parser_test.rb → core/snip_reference_parser_test.rb} +0 -0
  39. data/test/{test_helper.rb → core/test_helper.rb} +5 -4
  40. data/test/core/vanilla_app_test.rb +51 -0
  41. data/test/{vanilla_presenting_test.rb → core/vanilla_presenting_test.rb} +15 -1
  42. data/test/{vanilla_request_test.rb → core/vanilla_request_test.rb} +0 -0
  43. data/test/pristine_app/current_snip_test.rb +46 -0
  44. data/test/pristine_app/feed_test.rb +47 -0
  45. data/test/pristine_app/index_test.rb +34 -0
  46. data/test/pristine_app/link_to_current_snip_test.rb +11 -0
  47. data/test/pristine_app/link_to_test.rb +27 -0
  48. data/test/pristine_app/page_title_test.rb +15 -0
  49. data/test/pristine_app/raw_test.rb +24 -0
  50. data/test/pristine_app/test_helper.rb +25 -0
  51. metadata +83 -42
  52. data/lib/vanilla/routes.rb +0 -18
  53. data/test/dynasnips/link_to_current_snip_test.rb +0 -19
  54. data/test/dynasnips/link_to_test.rb +0 -27
  55. data/test/dynasnips/page_title_test.rb +0 -19
  56. data/test/vanilla_app_test.rb +0 -111
@@ -1,19 +1,20 @@
1
- <h1>Welcome to Vanilla.rb</h1>
1
+ <div id="welcome">
2
+ <h1>Welcome to <a href="/">Vanilla.rb</a></h1>
3
+ </div>
2
4
 
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>
5
+ <div class="grid_16 alpha">
6
+ <h2>First time?</h2>
4
7
 
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>
8
+ <p>Start at {link_to tutorial, the tutorial} for some orientation.</p>
6
9
 
7
- <h2>What now?</h2>
10
+ <h2>What is this?</h2>
11
+ <p>Vanilla is a simple web framework for playing with content. It can function as a a CMS, a wiki, a bliki, or anything in between.</p>
12
+
13
+ <p>Under the hood it is a Rack application, which means it should play nice in the Ruby web ecosystem. {link_to vanilla-rb, Learn more}.</p>
14
+
15
+ <h2>Adding your content</h2>
8
16
 
9
- <p>If this is your first time using vanilla, you should investigate the {link_to tutorial} for some orientation.</p>
17
+ <p>This is the {link_to start} snip, which is the default home page. You can find this content in <code>soups/base/start.snip</code>. You should replace this content with whatever you want on your site's home page.</p>
10
18
 
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>
19
+ <p>Good luck!</p>
20
+ </div>
@@ -16,9 +16,9 @@ class CurrentSnip < Dynasnip
16
16
  def handle(attribute=nil)
17
17
  if app.request.snip
18
18
  if attribute ||= app.request.part
19
- "{#{app.request.snip_name}.#{attribute}}"
19
+ %|{"#{app.request.snip_name}"."#{attribute}"}|
20
20
  else
21
- "{#{app.request.snip_name}}"
21
+ %|{"#{app.request.snip_name}"}|
22
22
  end
23
23
  else
24
24
  app.response.status = 404
@@ -0,0 +1,30 @@
1
+ require "vanilla/dynasnip"
2
+
3
+ class Feed < Dynasnip
4
+ def handle(*args)
5
+ Atom::Feed.new do |f|
6
+ f.title = "blah"
7
+ f.updated = Time.now
8
+ f.id = "tag:x,2008-06-01:kind/x"
9
+ f.entries = entries
10
+ end.to_xml
11
+ end
12
+
13
+ private
14
+
15
+ def entries
16
+ app.soup.all_snips.map do |snip|
17
+ Atom::Entry.new do |e|
18
+ # e.published = snip.created_at
19
+ # e.updated = snip.updated_at || snip.created_at
20
+ e.content = Atom::Content::Html.new(app.render(snip))
21
+ # e.title = snip.name
22
+ # e.authors = [Atom::Person.new(:name => snip.author || domain)]
23
+ # e.links << Atom::Link.new(:href => "http://#{domain}#{url_to(snip.name)}")
24
+ # e.id = "tag:#{domain},#{(snip.created_at.to_s || Date.today.to_s).split[0]}:/#{snip.name}"
25
+ end
26
+ end
27
+ end
28
+
29
+ self
30
+ end
@@ -2,10 +2,10 @@ require 'vanilla/dynasnip'
2
2
 
3
3
  class Index < Dynasnip
4
4
  def get(*args)
5
- list = app.soup.instance_eval { @backend }.send(:all_snips).sort_by { |a| a.updated_at || Time.at(0) }.reverse.map { |snip|
6
- "<li>#{link_to snip.name}</li>"
5
+ list = app.soup.all_snips.sort_by { |a| a.updated_at || Time.at(0) }.reverse.map { |snip|
6
+ "<li>{link_to #{snip.name}}</li>"
7
7
  }
8
- "<ol>#{list}</ol>"
8
+ %{<ol id="index">#{list}</ol>}
9
9
  end
10
10
 
11
11
  self
@@ -9,7 +9,11 @@ The link_to dyna lets you create links between snips:
9
9
  would insert a link to the blah snip.|
10
10
 
11
11
  def handle(snip_name, link_text=snip_name, part=nil)
12
- link_to(link_text, snip_name, part)
12
+ if app.soup[snip_name]
13
+ %{<a href="#{url_to(snip_name, part)}">#{link_text}</a>}
14
+ else
15
+ %{<a class="missing" href="#{url_to(snip_name, part)}">#{link_text}</a>}
16
+ end
13
17
  end
14
18
 
15
19
  self
@@ -2,12 +2,11 @@ require 'vanilla/dynasnip'
2
2
 
3
3
  class LinkToCurrentSnip < Dynasnip
4
4
  usage %|
5
- Renders a link to the current snip, or the snip currently being edited
6
- (if we're currently editing)
5
+ Renders a link to the current snip
7
6
  |
8
7
 
9
8
  def handle(*args)
10
- link_to app.request.snip_name
9
+ %{<a href="#{url_to(app.request.snip_name)}">#{app.request.snip_name}</a>}
11
10
  end
12
11
 
13
12
  self
@@ -41,9 +41,16 @@ The second dynasnip used is `link_to_current_snip`, which returns an HTML link t
41
41
  Other layouts
42
42
  -------------
43
43
 
44
- Vanilla looks for a snip called `layout` by default, but this can be changed by passing in a `:default_layout` option to `Vanilla::App.new`, e.g.
44
+ Vanilla looks for a snip called `layout` by default, but this can be changed by setting the `default_layout` configuration option in your application, e.g.
45
45
 
46
- Vanilla::App.new(:default_layout => "my_layout")
46
+ class Application < Vanilla::App; end
47
+
48
+ Application.configure do |config|
49
+
50
+ # other stuff..
51
+
52
+ config.default_layout = "my_layout"
53
+ end
47
54
 
48
55
 
49
56
  You can also override the layout on a per-snip basis, simply by setting the `:layout` attribute of the snip to the name of the layout snip to use instead.
@@ -1,4 +1,5 @@
1
1
  {link_to tutorial, "Basics"}
2
2
  {link_to tutorial-layout, "Learn about Layouts"}
3
3
  {link_to tutorial-renderers, "Renderer fun"}
4
- {link_to tutorial-dynasnips, "More about Dynasnips"}
4
+ {link_to tutorial-dynasnips, "More about Dynasnips"}
5
+ {link_to tutorial-removing, "Cleaning up"}
@@ -0,0 +1,8 @@
1
+ {tutorial-links}
2
+
3
+ Removing this tutorial
4
+ ======================
5
+
6
+ Once your site is ready to run, you'll probably want to remove the tutorial; you can do this by editing the configuration in `application.rb`, and deleting the `soups/tutorial` directory.
7
+
8
+ {tutorial-links}
@@ -42,9 +42,15 @@ Adding renderers
42
42
 
43
43
  New renderers can be added as part of the application configuration:
44
44
 
45
- Vanilla::App.new(:renderers => {
46
- "rdoc" => MyRenderers::RDoc
47
- })
45
+ class Application < Vanilla::App; end
46
+
47
+ Application.configure do |config|
48
+
49
+ # other stuff..
50
+
51
+ config.renderers[:my_format] = MyRenderer # the class
52
+ end
53
+
48
54
 
49
55
  These will be added to the lookup, and can also used to override the defaults (changing the renderer for "markdown" snips to use RDiscount, or Redcarpet, for example).
50
56
 
@@ -57,7 +63,7 @@ The simplest renderer inherits from `Vanilla::Renderers::Base`, and reimplement
57
63
  module Vanilla::Renderers
58
64
  class Bold < Base
59
65
  def process_text(content)
60
- "<b>#{content}</b>"
66
+ "<b>#{content}</b>"
61
67
  end
62
68
  end
63
69
  end
@@ -65,5 +65,4 @@ Anyway - that should be enough to get you started.
65
65
 
66
66
  {tutorial-links}
67
67
 
68
-
69
68
  :updated_at: 2011-04-28 16:21:00 +01:00
@@ -2,15 +2,13 @@ Vanilla.rb is the software powering this site. It's a sort-of wiki/bliki thing,
2
2
 
3
3
  Here's the [introductory blog post][3].
4
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.
5
+ It's developed on [github][1], and has a [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
6
 
7
- Here's the tutorial (helpfully included from {link_to tutorial}).
7
+ You may be able to view the {link_to tutorial} on this site, if it hasn't been removed.
8
8
 
9
- {tutorial}
10
9
 
11
-
12
- [1]: http://github.com/lazyatom/vanilla
13
- [2]: http://lazyatom.lighthouseapp.com/projects/11797-vanilla/tickets
10
+ [1]: http://github.com/lazyatom/vanilla-rb
11
+ [2]: http://github.com/lazyatom/vanilla-rb/issues
14
12
  [3]: http://interblah.net/introducing-vanilla-rb
15
13
 
16
14
  :render_as: Markdown
File without changes
@@ -0,0 +1,89 @@
1
+ require "test_helper"
2
+
3
+ context "Configuring a Vanilla app" do
4
+ class TestConfigurationApp < Vanilla::App
5
+ end
6
+
7
+ setup do
8
+ TestConfigurationApp.reset!
9
+ end
10
+
11
+ context "with defaults" do
12
+ should "set the soups to base and system" do
13
+ assert_equal ["soups/base", "soups/system"], TestConfigurationApp.new.config.soups
14
+ end
15
+
16
+ should "set the default layout snip to 'layout'" do
17
+ assert_equal "layout", TestConfigurationApp.new.config.default_layout_snip
18
+ end
19
+
20
+ should "set the default root directory to the current directory" do
21
+ assert_equal Dir.pwd, TestConfigurationApp.new.config.root
22
+ end
23
+
24
+ should "use Vanilla::Renderers::Base as the default renderer" do
25
+ assert_equal Vanilla::Renderers::Base, TestConfigurationApp.new.config.default_renderer
26
+ end
27
+ end
28
+
29
+ context "with a custom root" do
30
+ setup do
31
+ soup_dir = File.join(Dir.tmpdir, "my_soup")
32
+ FileUtils.mkdir_p(soup_dir)
33
+ File.open(File.join(soup_dir, "blah.snip"), "w") { |f| f.write "Hello superfriends" }
34
+
35
+ TestConfigurationApp.configure do |c|
36
+ c.root = Dir.tmpdir
37
+ c.soups = ["my_soup"]
38
+ end
39
+ end
40
+
41
+ should "expand soup paths relative to the root to aide loading external soups" do
42
+ assert_equal "Hello superfriends", TestConfigurationApp.new.soup['blah'].content
43
+ end
44
+ end
45
+
46
+ context "with a custom root_snip" do
47
+ setup do
48
+ TestConfigurationApp.configure do |c|
49
+ c.root_snip = "hello"
50
+ end
51
+ end
52
+
53
+ should "use the given snip as the root_snip" do
54
+ assert_equal "hello", TestConfigurationApp.new.config.root_snip
55
+ end
56
+ end
57
+
58
+ context "with a specific set of soups" do
59
+ setup do
60
+ TestConfigurationApp.configure do |c|
61
+ c.soups = ["blah", "monkey"]
62
+ end
63
+ end
64
+
65
+ should "use only the specified soups" do
66
+ assert_equal ["blah", "monkey"], TestConfigurationApp.new.config.soups
67
+ end
68
+ end
69
+
70
+ context "with new renderers" do
71
+ should "load new renderer constants presented as a string" do
72
+ class ::MyRenderer
73
+ end
74
+ TestConfigurationApp.configure do |c|
75
+ c.renderers[:my_renderer] = "MyRenderer"
76
+ end
77
+ snip = create_snip(:name => "blah", :render_as => "my_renderer")
78
+ assert_equal MyRenderer, TestConfigurationApp.new.renderer_for(snip)
79
+ end
80
+
81
+ should "allow existing renderers to be overridden" do
82
+ TestConfigurationApp.configure do |c|
83
+ c.renderers["markdown"] = "Vanilla::Renderers::Bold"
84
+ end
85
+ snip = create_snip(:name => "blah", :extension => "markdown")
86
+ assert_equal Vanilla::Renderers::Bold, TestConfigurationApp.new.renderer_for(snip)
87
+ end
88
+ end
89
+ end
File without changes
@@ -40,4 +40,41 @@ describe Vanilla::Renderers::Base do
40
40
  assert_response_body "include a [snip 'missing_snip' cannot be found]", "/blah"
41
41
  end
42
42
  end
43
+
44
+ context "when generating a link" do
45
+ setup do
46
+ snip = create_snip(:name => "blah")
47
+ @soup = stub('soup', :[] => snip)
48
+ @app = stub('app', :url_to => "/url", :soup => @soup)
49
+ @renderer = Vanilla::Renderers::Base.new(@app)
50
+ end
51
+
52
+ should "call url_to on the app to generate the url" do
53
+ @app.expects(:url_to).with("blah", nil).returns("/blah")
54
+ link = @renderer.link_to("blah")
55
+ assert_equal %{<a href="/blah">blah</a>}, link
56
+ end
57
+
58
+ should "use the snip name as the link text" do
59
+ link = @renderer.link_to("blah")
60
+ assert_equal %{<a href="/url">blah</a>}, link
61
+ end
62
+
63
+ should "use any explicit link text given" do
64
+ link = @renderer.link_to("something", "blah")
65
+ assert_equal %{<a href="/url">something</a>}, link
66
+ end
67
+
68
+ should "render a missing link if the snip couldn't be found" do
69
+ @soup.stubs(:[]).returns(nil)
70
+ link = @renderer.link_to("blah")
71
+ assert_equal %{<a class="missing" href="/url">blah</a>}, link
72
+ end
73
+
74
+ should "be able to link to a specified part" do
75
+ @app.expects(:url_to).with("blah", "part").returns("/blah/part")
76
+ link = @renderer.link_to("blah part", "blah", "part")
77
+ assert_equal %{<a href="/blah/part">blah part</a>}, link
78
+ end
79
+ end
43
80
  end
@@ -0,0 +1,30 @@
1
+ require "test_helper"
2
+
3
+ context "Parsing routes" do
4
+
5
+ { "/" => [nil, nil, nil],
6
+ "/blah" => ["blah", nil, nil],
7
+ "/blah-face" => ["blah-face", nil, nil],
8
+ "/blah+face" => ["blah face", nil, nil],
9
+ "/blah.text" => ["blah", nil, "text"],
10
+ "/blah.html" => ["blah", nil, "html"],
11
+ "/blah/part" => ["blah", "part", nil],
12
+ "/blah/part.raw" => ["blah", "part", "raw"]}.each do |path, (snip, part, format)|
13
+
14
+ context "parsing #{path}" do
15
+ setup { @parsed_route = Vanilla::Routing.parse(path) }
16
+
17
+ should "return #{snip.inspect} as the snip" do
18
+ assert_equal snip, @parsed_route[0]
19
+ end
20
+ should "return #{part.inspect} as the part" do
21
+ assert_equal part, @parsed_route[1]
22
+ end
23
+ should "return #{format.inspect} as the format" do
24
+ assert_equal format, @parsed_route[2]
25
+ end
26
+
27
+ end
28
+ end
29
+
30
+ end
@@ -1,16 +1,16 @@
1
- $LOAD_PATH.unshift(File.expand_path("../../lib"), __FILE__)
1
+ $LOAD_PATH.unshift(File.expand_path("../../../lib"), __FILE__)
2
2
  require "kintama"
3
3
  require "kintama/mocha"
4
4
  require "vanilla/test_helper"
5
5
 
6
- class Application < Vanilla::App
6
+ class TestApplication < Vanilla::App
7
7
  end
8
8
 
9
9
  module TestHelper
10
10
  include Vanilla::TestHelper
11
-
11
+
12
12
  def create_simple_layout
13
- require File.expand_path("../../pristine_app/soups/system/current_snip", __FILE__)
13
+ require File.expand_path("../../../pristine_app/soups/system/current_snip", __FILE__)
14
14
  app.soup << CurrentSnip.snip_attributes
15
15
  create_snip :name => "layout", :content => "{current_snip}"
16
16
  end
@@ -20,6 +20,7 @@ Kintama.include TestHelper
20
20
 
21
21
  Kintama.setup do
22
22
  vanilla_setup
23
+ TestApplication.reset!
23
24
  create_simple_layout
24
25
  end
25
26
 
@@ -0,0 +1,51 @@
1
+ require "test_helper"
2
+ require "tmpdir"
3
+
4
+ describe Vanilla::App do
5
+ context "when behaving as a Rack application" do
6
+ should "return a valid rack response" do
7
+ create_snip(:name => "test", :content => "content")
8
+ get "/test.text"
9
+ assert_equal 200, last_response.status
10
+ assert_kind_of Hash, last_response.headers
11
+ assert_equal "content", last_response.body
12
+ end
13
+ end
14
+
15
+ context "when detecting the snip renderer" do
16
+ should "return the constant refered to in the render_as property of the snip" do
17
+ snip = create_snip(:name => "blah", :render_as => "Raw")
18
+ assert_equal Vanilla::Renderers::Raw, app.renderer_for(snip)
19
+ end
20
+
21
+ context "using the snip extension" do
22
+ {
23
+ "markdown" => Vanilla::Renderers::Markdown,
24
+ "textile" => Vanilla::Renderers::Textile,
25
+ "erb" => Vanilla::Renderers::Erb,
26
+ "rb" => Vanilla::Renderers::Ruby,
27
+ "haml" => Vanilla::Renderers::Haml
28
+ }.each do |extension, renderer|
29
+ should "return the renderer #{renderer} when the snip has extension #{extension}" do
30
+ snip = create_snip(:name => "blah", :extension => extension)
31
+ assert_equal renderer, app.renderer_for(snip)
32
+ end
33
+ end
34
+ end
35
+
36
+ should "return Vanilla::Renderers::Base if no render_as property exists" do
37
+ snip = create_snip(:name => "blah")
38
+ assert_equal Vanilla::Renderers::Base, app.renderer_for(snip)
39
+ end
40
+
41
+ should "return Vanilla::Renderers::Base if the render_as property is blank" do
42
+ snip = create_snip(:name => "blah", :render_as => '')
43
+ assert_equal Vanilla::Renderers::Base, app.renderer_for(snip)
44
+ end
45
+
46
+ should "raise an error if the specified renderer doesn't exist" do
47
+ snip = create_snip(:name => "blah", :render_as => "NonExistentClass")
48
+ assert_raises(NameError) { app.renderer_for(snip) }
49
+ end
50
+ end
51
+ end