nyara 0.0.1.pre.9 → 0.1.pre.0
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.
- 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
|
|