nancy 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -0
- data/README.md +47 -2
- data/examples/app.rb +3 -1
- data/lib/nancy.rb +1 -0
- data/lib/nancy/base.rb +10 -20
- data/lib/nancy/render.rb +16 -0
- data/lib/nancy/version.rb +1 -1
- data/nancy.gemspec +1 -1
- data/test/base_test.rb +15 -4
- data/test/fixtures/view_with_trim.erb +4 -0
- metadata +35 -12
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -3,10 +3,12 @@ _Sinatra's little daughter_
|
|
3
3
|
|
4
4
|
![Frank and Nancy by classic film scans](http://farm6.staticflickr.com/5212/5386187897_e3155cec68.jpg)
|
5
5
|
|
6
|
+
|
6
7
|
## Description
|
7
8
|
|
8
9
|
Minimal Ruby microframework for web development inspired in [Sinatra](http://www.sinatrarb.com/)
|
9
10
|
|
11
|
+
|
10
12
|
## Installation
|
11
13
|
|
12
14
|
Install the gem:
|
@@ -17,6 +19,7 @@ or add it to your Gemfile:
|
|
17
19
|
|
18
20
|
gem "nancy"
|
19
21
|
|
22
|
+
|
20
23
|
## Usage
|
21
24
|
|
22
25
|
Here's a simple application:
|
@@ -26,7 +29,8 @@ Here's a simple application:
|
|
26
29
|
require "nancy"
|
27
30
|
|
28
31
|
class Hello < Nancy::Base
|
29
|
-
use Rack::Session::Cookie
|
32
|
+
use Rack::Session::Cookie # for sessions
|
33
|
+
include Nancy::Render # for templates
|
30
34
|
|
31
35
|
get "/" do
|
32
36
|
"Hello World"
|
@@ -48,12 +52,26 @@ class Hello < Nancy::Base
|
|
48
52
|
@message = "Hello world"
|
49
53
|
render("views/hello.erb")
|
50
54
|
end
|
55
|
+
|
56
|
+
post "/login" do
|
57
|
+
@user = User.find(params['username'])
|
58
|
+
halt 401, "unauthorized" unless @user.authenticate(params['password'])
|
59
|
+
session[:authenticated] = true
|
60
|
+
render("views/layout.erb") { render("views/welcome.erb") }
|
61
|
+
end
|
62
|
+
|
63
|
+
get "/users/:id.json" do
|
64
|
+
@user = User.find(params['id'])
|
65
|
+
response["Content-Type"] = "application/json"
|
66
|
+
halt 404 unless @user
|
67
|
+
UserSerializer.new(@user).to_json
|
68
|
+
end
|
51
69
|
end
|
52
70
|
```
|
53
71
|
|
54
72
|
To run it, you can create a `config.ru` file:
|
55
73
|
|
56
|
-
```
|
74
|
+
```ruby
|
57
75
|
# config.ru
|
58
76
|
require "./hello"
|
59
77
|
|
@@ -64,6 +82,33 @@ You can now run `rackup` and enjoy what you have just created.
|
|
64
82
|
|
65
83
|
Check examples folder for a detailed example.
|
66
84
|
|
85
|
+
|
86
|
+
## Features
|
87
|
+
|
88
|
+
* "Sinatra-like" routes: support for get, post, put, patch, delete
|
89
|
+
* Template rendering and caching through Tilt
|
90
|
+
* Include middlewares with the use method
|
91
|
+
* Sessions through Rack::Session
|
92
|
+
* Halt execution at any point using Ruby's throw/catch mechanism
|
93
|
+
* Thread-safe
|
94
|
+
|
95
|
+
|
96
|
+
## Version history
|
97
|
+
|
98
|
+
### 0.1.0
|
99
|
+
|
100
|
+
* Created a new [Github Page](http://guilleiguaran.github.com/nancy) for the project
|
101
|
+
* Added env accessor, this add support for [Shield](https://github.com/cyx/shield)
|
102
|
+
* Added support for templates caching using Tilt::Cache
|
103
|
+
* Moved render method from Nancy::Base to Nancy::Render module
|
104
|
+
* Refactored Nancy::Base to evaluate code blocks at instance level
|
105
|
+
* Fixed passing of render options to Tilt (thanks to [lporras](https://github.com/lporras))
|
106
|
+
|
107
|
+
### 0.0.1
|
108
|
+
|
109
|
+
* Initial Release
|
110
|
+
|
111
|
+
|
67
112
|
## Contributing
|
68
113
|
|
69
114
|
1. Fork it
|
data/examples/app.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
$:.push File.expand_path("../../lib", __FILE__)
|
2
2
|
|
3
3
|
require "nancy/base"
|
4
|
+
require "nancy/render"
|
4
5
|
|
5
6
|
class App < Nancy::Base
|
6
7
|
use Rack::Runtime
|
7
8
|
use Rack::Session::Cookie
|
8
9
|
use Rack::Static, :urls => ["/javascripts"], :root => "public"
|
10
|
+
include Nancy::Render
|
9
11
|
|
10
12
|
get "/" do
|
11
13
|
"Hello World"
|
@@ -57,7 +59,7 @@ class App < Nancy::Base
|
|
57
59
|
end
|
58
60
|
|
59
61
|
# Helper method
|
60
|
-
def
|
62
|
+
def render(*args)
|
61
63
|
args[0] = "views/#{args[0]}"
|
62
64
|
super(*args)
|
63
65
|
end
|
data/lib/nancy.rb
CHANGED
data/lib/nancy/base.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'rack'
|
2
|
-
require 'tilt'
|
3
2
|
|
4
3
|
module Nancy
|
5
4
|
class Base
|
@@ -24,17 +23,15 @@ module Nancy
|
|
24
23
|
@route_set ||= Hash.new { |h, k| h[k] = [] }
|
25
24
|
end
|
26
25
|
|
27
|
-
|
28
|
-
|
29
|
-
define_method(accessor){ Thread.current[accessor.to_sym] }
|
30
|
-
end
|
26
|
+
%w(request response params env).each do |accessor|
|
27
|
+
define_method(accessor){ Thread.current[accessor.to_sym] }
|
31
28
|
end
|
32
29
|
|
33
|
-
def
|
30
|
+
def session
|
34
31
|
request.env["rack.session"]
|
35
32
|
end
|
36
33
|
|
37
|
-
def
|
34
|
+
def redirect(uri)
|
38
35
|
halt 302, {"Location" => uri}
|
39
36
|
end
|
40
37
|
|
@@ -53,38 +50,35 @@ module Nancy
|
|
53
50
|
middleware, *args, block = middleware
|
54
51
|
use(middleware, *args, &block)
|
55
52
|
end
|
56
|
-
run
|
53
|
+
run self
|
57
54
|
end
|
58
55
|
end
|
59
56
|
|
60
57
|
def call(env)
|
61
|
-
@app.call(env)
|
62
|
-
end
|
63
|
-
|
64
|
-
def self.call(env)
|
65
58
|
Thread.current[:request] = Rack::Request.new(env)
|
66
59
|
Thread.current[:response] = Rack::Response.new
|
67
60
|
Thread.current[:params] = request.params
|
61
|
+
Thread.current[:env] = env
|
68
62
|
response = catch(:halt) do
|
69
63
|
route_eval(request.request_method, request.path_info)
|
70
64
|
end.finish
|
71
65
|
end
|
72
66
|
|
73
|
-
def
|
74
|
-
route_set[request_method].each do |matcher, block|
|
67
|
+
def route_eval(request_method, path_info)
|
68
|
+
self.class.route_set[request_method].each do |matcher, block|
|
75
69
|
if match = path_info.match(matcher[0])
|
76
70
|
if (captures = match.captures) && !captures.empty?
|
77
71
|
url_params = Hash[*matcher[1].zip(captures).flatten]
|
78
72
|
Thread.current[:params] = url_params.merge(params)
|
79
73
|
end
|
80
|
-
response.write(block
|
74
|
+
response.write instance_eval(&block)
|
81
75
|
halt response
|
82
76
|
end
|
83
77
|
end
|
84
78
|
halt 404
|
85
79
|
end
|
86
80
|
|
87
|
-
def
|
81
|
+
def halt(*res)
|
88
82
|
throw :halt, res.first if res.first.is_a?(Rack::Response)
|
89
83
|
response.status = res.select{|x| x.is_a?(Fixnum)}.first || 200
|
90
84
|
headers = res.select{|x| x.is_a?(Hash)}.first || {}
|
@@ -92,9 +86,5 @@ module Nancy
|
|
92
86
|
response.body = [(res.select{|x| x.is_a?(String)}.first || "")]
|
93
87
|
throw :halt, response
|
94
88
|
end
|
95
|
-
|
96
|
-
def self.render(template, locals = {}, options = {}, &block)
|
97
|
-
Tilt.new(template).render(self, locals, &block)
|
98
|
-
end
|
99
89
|
end
|
100
90
|
end
|
data/lib/nancy/render.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'tilt'
|
2
|
+
|
3
|
+
module Nancy
|
4
|
+
module Render
|
5
|
+
|
6
|
+
def render(template, locals = {}, options = {}, &block)
|
7
|
+
templates_cache.fetch(template) {
|
8
|
+
Tilt.new(template, options)
|
9
|
+
}.render(self, locals, &block)
|
10
|
+
end
|
11
|
+
|
12
|
+
def templates_cache
|
13
|
+
Thread.current[:templates_cache] ||= Tilt::Cache.new
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/nancy/version.rb
CHANGED
data/nancy.gemspec
CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |gem|
|
|
6
6
|
gem.email = ["guilleiguaran@gmail.com"]
|
7
7
|
gem.description = %q{Sinatra's little daughter}
|
8
8
|
gem.summary = %q{Ruby Microframework inspired in Sinatra}
|
9
|
-
gem.homepage = "
|
9
|
+
gem.homepage = "http://guilleiguaran.github.com/nancy"
|
10
10
|
|
11
11
|
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
12
12
|
gem.files = `git ls-files`.split("\n")
|
data/test/base_test.rb
CHANGED
@@ -5,6 +5,8 @@ class BaseTest < MiniTest::Unit::TestCase
|
|
5
5
|
include Rack::Test::Methods
|
6
6
|
|
7
7
|
class TestApp < Nancy::Base
|
8
|
+
include Nancy::Render
|
9
|
+
|
8
10
|
get "/" do
|
9
11
|
"Hello World"
|
10
12
|
end
|
@@ -44,18 +46,22 @@ class BaseTest < MiniTest::Unit::TestCase
|
|
44
46
|
render("#{view_path}/layout.erb") { render("#{view_path}/view.erb") }
|
45
47
|
end
|
46
48
|
|
47
|
-
|
49
|
+
get "/view_with_option_trim" do
|
50
|
+
render("#{view_path}/view_with_trim.erb", {}, :trim => "%")
|
51
|
+
end
|
52
|
+
|
53
|
+
def view_path
|
48
54
|
File.expand_path("fixtures", Dir.pwd)
|
49
55
|
end
|
50
56
|
end
|
51
57
|
|
52
58
|
def app
|
53
|
-
TestApp
|
59
|
+
TestApp.new
|
54
60
|
end
|
55
61
|
|
56
62
|
def test_app_respond_with_call
|
57
|
-
assert TestApp.respond_to?(:call)
|
58
|
-
request = Rack::MockRequest.new(TestApp)
|
63
|
+
assert TestApp.new.respond_to?(:call)
|
64
|
+
request = Rack::MockRequest.new(TestApp.new)
|
59
65
|
response = request.get('/')
|
60
66
|
assert_equal 200, response.status
|
61
67
|
assert_equal 'Hello World', response.body
|
@@ -99,4 +105,9 @@ class BaseTest < MiniTest::Unit::TestCase
|
|
99
105
|
assert last_response.body.include?("<html>")
|
100
106
|
assert last_response.body.include?("Hello from view")
|
101
107
|
end
|
108
|
+
|
109
|
+
def test_send_tilt_options_to_render
|
110
|
+
get '/view_with_option_trim'
|
111
|
+
assert_equal "\nhello\n", last_response.body
|
112
|
+
end
|
102
113
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nancy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-04-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: tilt
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,10 +37,15 @@ dependencies:
|
|
32
37
|
version: '0'
|
33
38
|
type: :runtime
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: minitest
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ! '>='
|
@@ -43,10 +53,15 @@ dependencies:
|
|
43
53
|
version: '0'
|
44
54
|
type: :development
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
47
62
|
- !ruby/object:Gem::Dependency
|
48
63
|
name: rack-test
|
49
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
50
65
|
none: false
|
51
66
|
requirements:
|
52
67
|
- - ! '>='
|
@@ -54,7 +69,12 @@ dependencies:
|
|
54
69
|
version: '0'
|
55
70
|
type: :development
|
56
71
|
prerelease: false
|
57
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
58
78
|
description: Sinatra's little daughter
|
59
79
|
email:
|
60
80
|
- guilleiguaran@gmail.com
|
@@ -74,13 +94,15 @@ files:
|
|
74
94
|
- examples/views/layout.erb
|
75
95
|
- lib/nancy.rb
|
76
96
|
- lib/nancy/base.rb
|
97
|
+
- lib/nancy/render.rb
|
77
98
|
- lib/nancy/version.rb
|
78
99
|
- nancy.gemspec
|
79
100
|
- test/base_test.rb
|
80
101
|
- test/fixtures/layout.erb
|
81
102
|
- test/fixtures/view.erb
|
103
|
+
- test/fixtures/view_with_trim.erb
|
82
104
|
- test/test_helper.rb
|
83
|
-
homepage:
|
105
|
+
homepage: http://guilleiguaran.github.com/nancy
|
84
106
|
licenses: []
|
85
107
|
post_install_message:
|
86
108
|
rdoc_options: []
|
@@ -100,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
100
122
|
version: '0'
|
101
123
|
requirements: []
|
102
124
|
rubyforge_project:
|
103
|
-
rubygems_version: 1.8.
|
125
|
+
rubygems_version: 1.8.21
|
104
126
|
signing_key:
|
105
127
|
specification_version: 3
|
106
128
|
summary: Ruby Microframework inspired in Sinatra
|
@@ -108,4 +130,5 @@ test_files:
|
|
108
130
|
- test/base_test.rb
|
109
131
|
- test/fixtures/layout.erb
|
110
132
|
- test/fixtures/view.erb
|
133
|
+
- test/fixtures/view_with_trim.erb
|
111
134
|
- test/test_helper.rb
|