nyara 0.0.1.pre.9 → 0.1.pre.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/nyara +3 -3
- data/changes +1 -0
- data/ext/event.c +16 -22
- data/ext/hashes.c +222 -4
- data/ext/inc/rdtsc.h +56 -0
- data/ext/inc/status_codes.inc +64 -0
- data/ext/inc/version.inc +1 -1
- data/ext/nyara.c +12 -10
- data/ext/nyara.h +5 -5
- data/ext/request.c +18 -24
- data/ext/request_parse.c +1 -1
- data/ext/route.cc +2 -4
- data/ext/url_encoded.c +51 -193
- data/lib/nyara/command.rb +39 -12
- data/lib/nyara/config.rb +10 -10
- data/lib/nyara/controller.rb +60 -14
- data/lib/nyara/cookie.rb +1 -1
- data/lib/nyara/hashes/config_hash.rb +2 -24
- data/lib/nyara/nyara.rb +33 -19
- data/lib/nyara/part.rb +7 -3
- data/lib/nyara/reload.rb +85 -0
- data/lib/nyara/request.rb +1 -1
- data/lib/nyara/route.rb +55 -19
- data/lib/nyara/templates/Gemfile +10 -1
- data/lib/nyara/templates/Rakefile +6 -1
- data/lib/nyara/templates/app/controllers/application_controller.rb +3 -0
- data/lib/nyara/templates/app/controllers/welcome_controller.rb +5 -0
- data/lib/nyara/templates/app/views/layouts/application.erb +12 -0
- data/lib/nyara/templates/app/views/welcome/index.erb +1 -0
- data/lib/nyara/templates/config/application.rb +34 -0
- data/lib/nyara/templates/config/boot.rb +4 -0
- data/lib/nyara/templates/config/development.rb +5 -0
- data/lib/nyara/templates/config/production.rb +8 -0
- data/lib/nyara/templates/config/test.rb +2 -0
- data/lib/nyara/templates/public/css/app.css +1 -0
- data/lib/nyara/templates/public/js/app.js +1 -0
- data/lib/nyara/templates/spec/spec_helper.rb +9 -0
- data/lib/nyara/test.rb +10 -2
- data/lib/nyara/view.rb +116 -67
- data/nyara.gemspec +3 -1
- data/rakefile +1 -1
- data/readme.md +1 -1
- data/spec/command_spec.rb +28 -24
- data/spec/config_spec.rb +24 -1
- data/spec/dummy/app/controllers/dummy_controller.rb +2 -0
- data/spec/dummy/app/models/dmmy_model.rb +2 -0
- data/spec/evented_io_spec.rb +2 -1
- data/spec/ext_route_spec.rb +2 -2
- data/spec/flash_spec.rb +8 -0
- data/spec/hashes_spec.rb +127 -0
- data/spec/integration_spec.rb +15 -0
- data/spec/path_helper_spec.rb +17 -5
- data/spec/performance/escape.rb +15 -4
- data/spec/performance/layout_render.rb +15 -10
- data/spec/performance/parse_accept_value.rb +24 -8
- data/spec/performance/parse_param.rb +14 -8
- data/spec/performance/performance_helper.rb +8 -21
- data/spec/performance_spec.rb +5 -4
- data/spec/route_spec.rb +7 -2
- data/spec/url_encoded_spec.rb +18 -74
- data/spec/view_spec.rb +1 -3
- data/spec/views/_partial.slim +1 -0
- data/spec/views/_partial_with_yield.erb +1 -0
- metadata +73 -43
- data/example/factorial.rb +0 -19
- data/example/hello.rb +0 -5
- data/example/project.rb +0 -11
- data/example/stream.rb +0 -14
- data/lib/nyara/controllers/public_controller.rb +0 -14
- data/lib/nyara/templates/config/session.key +0 -1
- data/tools/bench-cookie.rb +0 -22
- data/tools/foo.rb +0 -9
- data/tools/hello.rb +0 -46
- data/tools/memcheck.rb +0 -33
- data/tools/s.rb +0 -11
data/lib/nyara/reload.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require "listen"
|
2
|
+
|
3
|
+
module Nyara
|
4
|
+
# listen to fs events and reload code / views
|
5
|
+
# todo add to development env: require 'nyara/reload'; Reload.listen
|
6
|
+
module Reload
|
7
|
+
# init, should require all files that needs to be reloaded in the given block
|
8
|
+
def self.init
|
9
|
+
@new_classes = []
|
10
|
+
@trace_point = TracePoint.new :class do |tp|
|
11
|
+
@new_classes << tp.self.to_s.to_sym
|
12
|
+
end
|
13
|
+
@file_list = {}
|
14
|
+
@first_load = true
|
15
|
+
yield
|
16
|
+
@first_load = false
|
17
|
+
end
|
18
|
+
|
19
|
+
# NOTE file should end with '.rb'
|
20
|
+
def self.load_file file
|
21
|
+
if consts = @file_list[file]
|
22
|
+
consts.reverse_each do |const|
|
23
|
+
Object.send :remove_const, const
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
@trace_point.enable
|
28
|
+
old_consts = Object.send :constants
|
29
|
+
if @first_load
|
30
|
+
require file
|
31
|
+
else
|
32
|
+
if l = Nyara.logger
|
33
|
+
l.info "reloading: #{file}"
|
34
|
+
end
|
35
|
+
begin
|
36
|
+
load file
|
37
|
+
@last_error = nil
|
38
|
+
rescue Exception
|
39
|
+
@last_error = $!
|
40
|
+
end
|
41
|
+
end
|
42
|
+
@trace_point.disable
|
43
|
+
added_consts = Object.send(:constants) - old_consts
|
44
|
+
|
45
|
+
added_consts.concat @new_classes
|
46
|
+
@new_classes.clear
|
47
|
+
added_consts.uniq!
|
48
|
+
added_consts.sort!
|
49
|
+
|
50
|
+
@file_list[file] = added_consts
|
51
|
+
@last_error
|
52
|
+
end
|
53
|
+
|
54
|
+
# start listening
|
55
|
+
def self.listen
|
56
|
+
views_path = Config.views_path('/')
|
57
|
+
if views_path
|
58
|
+
if l = Nyara.logger
|
59
|
+
l.info "watching views change under #{views_path}"
|
60
|
+
end
|
61
|
+
Listen.to Config.views_path('/'), relative_paths: true do |modified, added, removed|
|
62
|
+
modified.each do |file|
|
63
|
+
View.on_modified file
|
64
|
+
end
|
65
|
+
removed.each do |file|
|
66
|
+
View.on_removed file
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
return unless Config.development?
|
72
|
+
if l = Nyara.logger
|
73
|
+
l.info "watching app change under #{Config['root']}"
|
74
|
+
end
|
75
|
+
Listen.to Config['root'], filter: /\.rb$/, relative_paths: false do |modified, added, removed|
|
76
|
+
(added + modified).uniq.each do |file|
|
77
|
+
load_file file
|
78
|
+
end
|
79
|
+
# (1.0) todo send notification on bad files
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# todo (don't forget wiki doc!)
|
84
|
+
end
|
85
|
+
end
|
data/lib/nyara/request.rb
CHANGED
data/lib/nyara/route.rb
CHANGED
@@ -24,6 +24,14 @@ module Nyara
|
|
24
24
|
m
|
25
25
|
end
|
26
26
|
|
27
|
+
# nil for get / post
|
28
|
+
def http_method_override
|
29
|
+
m = http_method_to_s
|
30
|
+
if m != 'GET' and m != 'POST'
|
31
|
+
m
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
27
35
|
# enum all combinations of matching selectors
|
28
36
|
def selectors
|
29
37
|
if classes
|
@@ -96,6 +104,9 @@ module Nyara
|
|
96
104
|
# private
|
97
105
|
# +++
|
98
106
|
|
107
|
+
TOKEN = /%(?:[sz]|(?>\.\d+)?[dfux])/
|
108
|
+
FORWARD_SPLIT = /(?=#{TOKEN})/
|
109
|
+
|
99
110
|
# #### Returns
|
100
111
|
#
|
101
112
|
# [str_re, conv]
|
@@ -103,21 +114,32 @@ module Nyara
|
|
103
114
|
def compile_re suffix
|
104
115
|
return ['', []] unless suffix
|
105
116
|
conv = []
|
106
|
-
|
117
|
+
segs = suffix.split(FORWARD_SPLIT).flat_map do |s|
|
118
|
+
if (s =~ TOKEN) == 0
|
119
|
+
part1 = s[TOKEN]
|
120
|
+
[part1, s.slice(part1.size..-1)]
|
121
|
+
else
|
122
|
+
s
|
123
|
+
end
|
124
|
+
end
|
125
|
+
re_segs = segs.map do |s|
|
107
126
|
case s
|
108
|
-
when
|
109
|
-
|
110
|
-
'
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
'
|
118
|
-
|
119
|
-
|
120
|
-
'
|
127
|
+
when /\A%(?>\.\d+)?([dfux])\z/
|
128
|
+
case $1
|
129
|
+
when 'd'
|
130
|
+
conv << :to_i
|
131
|
+
'(-?\d+)'
|
132
|
+
when 'f'
|
133
|
+
conv << :to_f
|
134
|
+
# just copied from scanf
|
135
|
+
'([-+]?(?:0[xX](?:\.\h+|\h+(?:\.\h*)?)[pP][-+]\d+|\d+(?![\d.])|\d*\.\d*(?:[eE][-+]?\d+)?))'
|
136
|
+
when 'u'
|
137
|
+
conv << :to_i
|
138
|
+
'(\d+)'
|
139
|
+
when 'x'
|
140
|
+
conv << :hex
|
141
|
+
'(\h+)'
|
142
|
+
end
|
121
143
|
when '%s'
|
122
144
|
conv << :to_s
|
123
145
|
'([^/]+)'
|
@@ -138,12 +160,16 @@ module Nyara
|
|
138
160
|
raise 'path must start with /' unless path.start_with? '/'
|
139
161
|
path = path.sub(/\/$/, '') if path != '/'
|
140
162
|
|
141
|
-
path.split(
|
163
|
+
path.split(FORWARD_SPLIT, 2)
|
142
164
|
end
|
143
165
|
end
|
144
166
|
|
145
167
|
# class methods
|
146
168
|
class << Route
|
169
|
+
def routes
|
170
|
+
@routes || []
|
171
|
+
end
|
172
|
+
|
147
173
|
# #### Param
|
148
174
|
#
|
149
175
|
# * `controller` - string or class which inherits [Nyara::Controller](Controller.html)
|
@@ -161,7 +187,7 @@ module Nyara
|
|
161
187
|
@global_path_templates = {} # "name#id" => path
|
162
188
|
mapped_controllers = {}
|
163
189
|
|
164
|
-
routes = @controllers.flat_map do |scope, c|
|
190
|
+
@routes = @controllers.flat_map do |scope, c|
|
165
191
|
if c.is_a?(String)
|
166
192
|
c = name2const c
|
167
193
|
end
|
@@ -177,15 +203,15 @@ module Nyara
|
|
177
203
|
@global_path_templates[name + e.id] = e.path_template
|
178
204
|
end
|
179
205
|
end
|
180
|
-
routes.sort_by! &:prefix
|
181
|
-
routes.reverse!
|
206
|
+
@routes.sort_by! &:prefix
|
207
|
+
@routes.reverse!
|
182
208
|
|
183
209
|
mapped_controllers.each do |c, _|
|
184
210
|
c.path_templates = @global_path_templates.merge c.path_templates
|
185
211
|
end
|
186
212
|
|
187
213
|
Ext.clear_route
|
188
|
-
routes.each do |e|
|
214
|
+
@routes.each do |e|
|
189
215
|
Ext.register_route e
|
190
216
|
end
|
191
217
|
end
|
@@ -213,6 +239,16 @@ module Nyara
|
|
213
239
|
@controllers = []
|
214
240
|
end
|
215
241
|
|
242
|
+
def print_routes
|
243
|
+
puts "all routes:"
|
244
|
+
Nyara::Route.routes.each do |route|
|
245
|
+
print (route.id || "").gsub("#", "").rjust(30), " "
|
246
|
+
print route.http_method_to_s.ljust(6), " "
|
247
|
+
print route.path
|
248
|
+
puts ""
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
216
252
|
# private
|
217
253
|
|
218
254
|
def const2name c
|
data/lib/nyara/templates/Gemfile
CHANGED
@@ -1,4 +1,13 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
gem '
|
3
|
+
gem 'erubis'
|
4
|
+
gem 'nyara', '<%= Nyara::VERSION %>', require: 'nyara/nyara'
|
4
5
|
gem 'mongoid', '3.1.4'
|
6
|
+
|
7
|
+
group :deploy do
|
8
|
+
gem 'rake'
|
9
|
+
end
|
10
|
+
|
11
|
+
group :test do
|
12
|
+
gem 'rspec'
|
13
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
5
|
+
<title><%= app_name %></title>
|
6
|
+
<link type="text/css" rel="stylesheet" href="/css/app.css">
|
7
|
+
<script type="text/javascript" src="/js/app.js"></script>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
<%%== yield %>
|
11
|
+
</body>
|
12
|
+
</html>
|
@@ -0,0 +1 @@
|
|
1
|
+
Welcome to use Nyara.
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler.require :default, ENV['NYARA_ENV'] || 'development'
|
3
|
+
|
4
|
+
configure do
|
5
|
+
set :env, ENV['NYARA_ENV'] || 'development'
|
6
|
+
|
7
|
+
set :views, 'app/views'
|
8
|
+
|
9
|
+
set :session, :name, '_aaa'
|
10
|
+
|
11
|
+
## If you've configured https with nginx:
|
12
|
+
# set :session, :secure, true
|
13
|
+
|
14
|
+
## Default session expires when browser closes.
|
15
|
+
## If you need time-based expiration, 30 minutes for example:
|
16
|
+
# set :session, :expires, 30 * 60
|
17
|
+
|
18
|
+
# Routing
|
19
|
+
map '/', 'welcome'
|
20
|
+
|
21
|
+
# Application loading order
|
22
|
+
set :app_files, %w|
|
23
|
+
app/controllers/application_controller.rb
|
24
|
+
app/{helpers,models,controllers}/**/*.rb
|
25
|
+
|
|
26
|
+
|
27
|
+
# Environment specific configure at last
|
28
|
+
require_relative env
|
29
|
+
end
|
30
|
+
|
31
|
+
# Configure Mongoid
|
32
|
+
Mongoid.load!(Nyara.config.project_path('config/database.yml'), Nyara.config.env)
|
33
|
+
|
34
|
+
Nyara.load_app
|
@@ -0,0 +1 @@
|
|
1
|
+
/* Put You css in here */
|
@@ -0,0 +1 @@
|
|
1
|
+
// Put you Javascript in here
|
data/lib/nyara/test.rb
CHANGED
@@ -49,7 +49,7 @@ module Nyara
|
|
49
49
|
# merge Set-Cookie
|
50
50
|
response.set_cookies.each do |cookie_seg|
|
51
51
|
# todo distinguish delete, value and set
|
52
|
-
|
52
|
+
ParamHash.parse_cookie cookie, cookie_seg
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
@@ -83,7 +83,7 @@ module Nyara
|
|
83
83
|
Session.encode_to_cookie session, cookie
|
84
84
|
headers['Cookie'] = Cookie.encode cookie
|
85
85
|
|
86
|
-
request_data = ["#{meth.upcase} #{Ext.escape path, true} HTTP/1.1\r\n"]
|
86
|
+
request_data = ["#{meth.to_s.upcase} #{Ext.escape path, true} HTTP/1.1\r\n"]
|
87
87
|
headers.each do |k, v|
|
88
88
|
request_data << "#{k}: #{v}\r\n"
|
89
89
|
end
|
@@ -97,6 +97,14 @@ module Nyara
|
|
97
97
|
@_env ||= Env.new
|
98
98
|
end
|
99
99
|
|
100
|
+
# #### Call-seq
|
101
|
+
#
|
102
|
+
# http :trace, '/'
|
103
|
+
#
|
104
|
+
def http *xs
|
105
|
+
env.http *xs
|
106
|
+
end
|
107
|
+
|
100
108
|
# #### Call-seq
|
101
109
|
#
|
102
110
|
# get '/', headers
|
data/lib/nyara/view.rb
CHANGED
@@ -1,7 +1,4 @@
|
|
1
1
|
module Nyara
|
2
|
-
module Renderable
|
3
|
-
end
|
4
|
-
|
5
2
|
# A support class which provides:
|
6
3
|
#
|
7
4
|
# - layout / locals for rendering
|
@@ -25,27 +22,104 @@ module Nyara
|
|
25
22
|
# Path extension (without dot) => stream friendly
|
26
23
|
ENGINE_STREAM_FRIENDLY = ParamHash.new
|
27
24
|
|
25
|
+
# meth name => method obj
|
26
|
+
RENDER = {}
|
27
|
+
|
28
|
+
# nested level => layout render, 0 means no layout
|
29
|
+
LAYOUT = {}
|
30
|
+
|
28
31
|
autoload :ERB, File.join(__dir__, "view_handlers/erb")
|
29
32
|
autoload :Erubis, File.join(__dir__, "view_handlers/erubis")
|
30
33
|
autoload :Haml, File.join(__dir__, "view_handlers/haml")
|
31
34
|
autoload :Slim, File.join(__dir__, "view_handlers/slim")
|
32
35
|
|
33
36
|
class Buffer < Array
|
37
|
+
def initialize parent=nil
|
38
|
+
@parent = parent
|
39
|
+
end
|
40
|
+
attr_reader :parent
|
41
|
+
|
34
42
|
alias safe_append= <<
|
35
43
|
|
36
44
|
def append= thingy
|
37
45
|
self << CGI.escape_html(thingy.to_s)
|
38
46
|
end
|
39
47
|
|
48
|
+
alias _join join
|
40
49
|
def join
|
41
50
|
r = super
|
42
51
|
clear
|
43
52
|
r
|
44
53
|
end
|
54
|
+
|
55
|
+
def push_level
|
56
|
+
Buffer.new self
|
57
|
+
end
|
58
|
+
|
59
|
+
def pop_level
|
60
|
+
@parent << _join
|
61
|
+
end
|
62
|
+
|
63
|
+
def flush instance
|
64
|
+
parents = [self]
|
65
|
+
buf = self
|
66
|
+
while buf = buf.parent
|
67
|
+
parents << buf
|
68
|
+
end
|
69
|
+
parents.reverse_each do |buf|
|
70
|
+
instance.send_chunk buf._join
|
71
|
+
buf.clear
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
module Renderable
|
77
|
+
def self.make_render_method file, line, sig, src
|
78
|
+
class_eval <<-RUBY, file, line
|
79
|
+
def render#{sig}
|
80
|
+
#{src}
|
81
|
+
end
|
82
|
+
RUBY
|
83
|
+
instance_method :render
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.make_layout_method nested_level=0
|
87
|
+
sig = 'e'
|
88
|
+
src = "e.call locals"
|
89
|
+
nested_level.times do |i|
|
90
|
+
sig << ", e#{i}"
|
91
|
+
src = "e#{i}.call{ #{src} }"
|
92
|
+
end
|
93
|
+
sig = "#{sig}"
|
94
|
+
class_eval <<-RUBY
|
95
|
+
def layout #{sig}, locals
|
96
|
+
#{src}
|
97
|
+
end
|
98
|
+
RUBY
|
99
|
+
instance_method(:layout).bind self
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
class TiltRenderable
|
104
|
+
def initialize tilt
|
105
|
+
@tilt = tilt
|
106
|
+
end
|
107
|
+
|
108
|
+
def bind instance
|
109
|
+
@instance = instance
|
110
|
+
self
|
111
|
+
end
|
112
|
+
|
113
|
+
def call locals=nil, &p
|
114
|
+
inst = @instance
|
115
|
+
@instance = nil
|
116
|
+
@tilt.render inst, locals, &p
|
117
|
+
end
|
45
118
|
end
|
46
119
|
|
47
120
|
class << self
|
48
121
|
def init
|
122
|
+
RENDER.delete_if{|k, v| k.start_with?('!') }
|
49
123
|
@root = Config['views']
|
50
124
|
@meth2ext = {} # meth => ext (without dot)
|
51
125
|
@meth2sig = {}
|
@@ -58,22 +132,18 @@ module Nyara
|
|
58
132
|
attr_reader :root
|
59
133
|
|
60
134
|
# NOTE: `path` needs extension
|
61
|
-
def
|
135
|
+
def on_removed path
|
62
136
|
meth = path2meth path
|
63
|
-
|
64
|
-
undef meth
|
65
|
-
end
|
137
|
+
RENDER.delete meth
|
66
138
|
|
67
139
|
@meth2ext.delete meth
|
68
140
|
@meth2sig.delete meth
|
69
141
|
end
|
70
142
|
|
71
|
-
def
|
143
|
+
def on_removed_all
|
72
144
|
meths = @meth2sig
|
73
|
-
|
74
|
-
|
75
|
-
undef meth
|
76
|
-
end
|
145
|
+
meths.each do |meth, _|
|
146
|
+
RENDER.delete meth
|
77
147
|
end
|
78
148
|
@meth2sig.clear
|
79
149
|
@meth2ext.clear
|
@@ -84,7 +154,7 @@ module Nyara
|
|
84
154
|
# #### Returns
|
85
155
|
#
|
86
156
|
# dot_ext for further use
|
87
|
-
def
|
157
|
+
def on_modified path
|
88
158
|
meth = path2meth path
|
89
159
|
return unless @meth2sig[meth] # has not been searched before, see also View.template
|
90
160
|
|
@@ -98,21 +168,14 @@ module Nyara
|
|
98
168
|
sig = @meth2sig[meth].map{|k| "#{k}: nil" }.join ','
|
99
169
|
sig = '_={}' if sig.empty?
|
100
170
|
sig = "(#{sig})" # 2.0.0-p0 requirement
|
101
|
-
Renderable.
|
102
|
-
def render#{sig}
|
103
|
-
#{src}
|
104
|
-
end
|
105
|
-
alias :#{meth.inspect} render
|
106
|
-
RUBY
|
171
|
+
RENDER[meth] = Renderable.make_render_method path, 0, sig, src
|
107
172
|
else
|
108
173
|
t = Dir.chdir @root do
|
109
174
|
# todo display template error
|
110
175
|
Tilt.new path rescue return
|
111
176
|
end
|
112
177
|
# partly precompiled
|
113
|
-
|
114
|
-
t.render self, locals, &p
|
115
|
-
end
|
178
|
+
RENDER[meth] = TiltRenderable.new t
|
116
179
|
end
|
117
180
|
|
118
181
|
@meth2ext[meth] = ext
|
@@ -126,22 +189,16 @@ module Nyara
|
|
126
189
|
line = 1
|
127
190
|
|
128
191
|
if stream_friendly
|
129
|
-
Renderable.
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
instance_eval src, #{file}, #{line}
|
135
|
-
end
|
136
|
-
alias :#{meth.inspect} render
|
192
|
+
RENDER[meth] = Renderable.make_render_method __FILE__, __LINE__, '(locals={})', <<-RUBY
|
193
|
+
@_nyara_locals = locals
|
194
|
+
src = locals.map{|k, _| "\#{k} = @_nyara_locals[:\#{k}];" }.join
|
195
|
+
src << View.precompile(#{ext.inspect}){ @_nyara_view.in }
|
196
|
+
instance_eval src, #{file}, #{line}
|
137
197
|
RUBY
|
138
198
|
ENGINE_STREAM_FRIENDLY[ext] = true
|
139
199
|
else
|
140
|
-
Renderable.
|
141
|
-
|
142
|
-
Tilt[#{ext.inspect}].new(#{file}, #{line}){ @_nyara_view.in }.render self, locals
|
143
|
-
end
|
144
|
-
alias :#{meth.inspect} render
|
200
|
+
RENDER[meth] = Renderable.make_render_method __FILE__, __LINE__, '(locals=nil)', <<-RUBY
|
201
|
+
Tilt[#{ext.inspect}].new(#{file}, #{line}){ @_nyara_view.in }.render self, locals
|
145
202
|
RUBY
|
146
203
|
end
|
147
204
|
ENGINE_DEFAULT_CONTENT_TYPES[ext] = default_content_type
|
@@ -151,7 +208,7 @@ module Nyara
|
|
151
208
|
#
|
152
209
|
# #### Returns
|
153
210
|
#
|
154
|
-
# `[
|
211
|
+
# `[meth_obj, ext_without_dot]`
|
155
212
|
def template path, locals={}
|
156
213
|
if File.extname(path).empty?
|
157
214
|
Dir.chdir @root do
|
@@ -165,12 +222,12 @@ module Nyara
|
|
165
222
|
|
166
223
|
meth = path2meth path
|
167
224
|
ext = @meth2ext[meth]
|
168
|
-
return [meth, ext] if ext
|
225
|
+
return [RENDER[meth], ext] if ext
|
169
226
|
|
170
227
|
@meth2sig[meth] = locals.keys
|
171
|
-
ext =
|
228
|
+
ext = on_modified path
|
172
229
|
raise "template not found or not valid in Tilt: #{path}" unless ext
|
173
|
-
[meth, ext]
|
230
|
+
[RENDER[meth], ext]
|
174
231
|
end
|
175
232
|
|
176
233
|
# private
|
@@ -192,11 +249,11 @@ module Nyara
|
|
192
249
|
end
|
193
250
|
|
194
251
|
def path2meth path
|
195
|
-
"
|
252
|
+
"!#{path}"
|
196
253
|
end
|
197
254
|
|
198
255
|
def engine2meth engine
|
199
|
-
"
|
256
|
+
":#{engine}"
|
200
257
|
end
|
201
258
|
end
|
202
259
|
|
@@ -225,59 +282,52 @@ module Nyara
|
|
225
282
|
unless @deduced_content_type = ENGINE_DEFAULT_CONTENT_TYPES[ext]
|
226
283
|
raise ArgumentError, "unkown template engine: #{ext.inspect}"
|
227
284
|
end
|
228
|
-
|
229
|
-
@layouts = [[meth, ext]]
|
230
285
|
else
|
231
286
|
raise ArgumentError, "too many options, expected only 1: #{opts.inspect}" if opts.size > 1
|
232
|
-
ext,
|
233
|
-
meth = View.engine2meth ext
|
287
|
+
ext, @in = opts.first
|
234
288
|
|
235
289
|
unless @deduced_content_type = ENGINE_DEFAULT_CONTENT_TYPES[ext]
|
236
290
|
raise ArgumentError, "unkown template engine: #{ext.inspect}"
|
237
291
|
end
|
238
292
|
|
239
|
-
|
240
|
-
@in = template
|
293
|
+
meth = RENDER[View.engine2meth(ext)]
|
241
294
|
end
|
242
295
|
|
296
|
+
@args = [meth.bind(instance)]
|
243
297
|
unless layout.is_a?(Array)
|
244
298
|
layout = layout ? [layout] : []
|
245
299
|
end
|
246
300
|
layout.each do |l|
|
247
301
|
pair = View.template(l)
|
248
302
|
# see notes on View
|
249
|
-
raise "can not use #{
|
250
|
-
@
|
303
|
+
raise "can not use #{pair[1]} as layout" unless ENGINE_STREAM_FRIENDLY[pair[1]]
|
304
|
+
@args << pair.first.bind(instance)
|
251
305
|
end
|
252
306
|
|
253
|
-
@
|
307
|
+
@layout_render = (LAYOUT[@args.size] ||= Renderable.make_layout_method(@args.size - 1))
|
308
|
+
@args << locals
|
309
|
+
|
254
310
|
@instance = instance
|
255
311
|
@instance.instance_variable_set :@_nyara_view, self
|
256
312
|
@out = Buffer.new
|
257
313
|
end
|
258
314
|
attr_reader :deduced_content_type, :in, :out
|
259
315
|
|
260
|
-
def
|
261
|
-
@
|
262
|
-
@
|
263
|
-
|
316
|
+
def partial
|
317
|
+
@out = @out.push_level
|
318
|
+
res = @layout_render.call *@args
|
319
|
+
@out = @out.pop_level
|
320
|
+
res
|
264
321
|
end
|
265
322
|
|
266
|
-
def
|
267
|
-
|
268
|
-
|
269
|
-
@instance.send t, @locals
|
270
|
-
else
|
271
|
-
@instance.send t do
|
272
|
-
_render
|
273
|
-
end
|
274
|
-
end
|
323
|
+
def render
|
324
|
+
@instance.send_chunk @layout_render.call *@args
|
325
|
+
Fiber.yield :term_close
|
275
326
|
end
|
276
327
|
|
277
328
|
def stream
|
278
|
-
@rest_layouts = @layouts.dup
|
279
329
|
@fiber = Fiber.new do
|
280
|
-
@rest_result =
|
330
|
+
@rest_result = @layout_render.call *@args
|
281
331
|
nil
|
282
332
|
end
|
283
333
|
self
|
@@ -287,8 +337,7 @@ module Nyara
|
|
287
337
|
r = @fiber.resume
|
288
338
|
Fiber.yield r if r
|
289
339
|
unless @out.empty?
|
290
|
-
@
|
291
|
-
@out.clear
|
340
|
+
@out.flush @instance
|
292
341
|
end
|
293
342
|
end
|
294
343
|
|