tanuki 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +5 -4
- data/app/tanuki/controller/{link.thtml → controller.link.thtml} +0 -0
- data/app/tanuki/controller/controller.page.thtml +14 -0
- data/app/tanuki/controller/controller.rb +1 -2
- data/app/tanuki/controller/controller.title.ttxt +1 -0
- data/app/tanuki/controller/controller.view.thtml +3 -0
- data/app/tanuki/fetcher/sequel/sequel.rb +34 -0
- data/app/tanuki/manager/controller/controller.rb +1 -1
- data/app/tanuki/manager/page/page.rb +1 -1
- data/app/tanuki/meta_model/{manager.ttxt → meta_model.manager.ttxt} +0 -0
- data/app/tanuki/meta_model/{manager_base.ttxt → meta_model.manager_base.ttxt} +0 -0
- data/app/tanuki/meta_model/{model.ttxt → meta_model.model.ttxt} +0 -0
- data/app/tanuki/meta_model/{model_base.ttxt → meta_model.model_base.ttxt} +0 -0
- data/app/tanuki/meta_model/meta_model.rb +1 -2
- data/app/tanuki/model/controller/controller.rb +1 -1
- data/app/tanuki/model/page/page.rb +1 -1
- data/app/tanuki/page/missing/{default.thtml → missing.page.thtml} +1 -1
- data/app/tanuki/page/missing/missing.rb +3 -2
- data/app/user/page/home/home.rb +2 -0
- data/app/user/page/home/home.title.thtml +1 -0
- data/app/user/page/home/home.view.css +88 -0
- data/app/user/page/home/home.view.thtml +22 -0
- data/bin/tanuki +2 -1
- data/config/common.rb +1 -0
- data/config/common_application.rb +3 -6
- data/config/development_application.rb +0 -3
- data/lib/tanuki.rb +8 -7
- data/lib/tanuki/application.rb +108 -81
- data/lib/tanuki/argument.rb +10 -5
- data/lib/tanuki/argument/integer_range.rb +4 -2
- data/lib/tanuki/{behavior/object_behavior.rb → base_behavior.rb} +21 -4
- data/lib/tanuki/configurator.rb +20 -8
- data/lib/tanuki/const.rb +32 -0
- data/lib/tanuki/context.rb +18 -7
- data/lib/tanuki/controller.rb +517 -0
- data/lib/tanuki/css_compressor.rb +50 -0
- data/lib/tanuki/extensions/module.rb +21 -5
- data/lib/tanuki/extensions/rack/frozen_route.rb +35 -0
- data/lib/tanuki/extensions/rack/static_dir.rb +1 -1
- data/lib/tanuki/extensions/sequel/model.rb +7 -0
- data/lib/tanuki/i18n.rb +8 -6
- data/lib/tanuki/loader.rb +166 -33
- data/lib/tanuki/meta_model.rb +176 -0
- data/lib/tanuki/{behavior/model_behavior.rb → model_behavior.rb} +7 -3
- data/lib/tanuki/model_generator.rb +49 -29
- data/lib/tanuki/template_compiler.rb +72 -41
- data/lib/tanuki/utility.rb +11 -4
- data/lib/tanuki/utility/create.rb +52 -11
- data/lib/tanuki/utility/generate.rb +16 -10
- data/lib/tanuki/utility/version.rb +1 -1
- data/lib/tanuki/version.rb +7 -2
- metadata +50 -66
- data/app/tanuki/controller/default.thtml +0 -5
- data/app/tanuki/controller/index.thtml +0 -1
- data/app/user/page/index/default.thtml +0 -121
- data/app/user/page/index/index.rb +0 -2
- data/config/test_application.rb +0 -2
- data/lib/tanuki/behavior/controller_behavior.rb +0 -366
- data/lib/tanuki/behavior/meta_model_behavior.rb +0 -160
- data/lib/tanuki/extensions/rack/builder.rb +0 -26
- data/lib/tanuki/extensions/rack/server.rb +0 -18
- data/lib/tanuki/launcher.rb +0 -21
- data/lib/tanuki/utility/server.rb +0 -23
data/README.rdoc
CHANGED
@@ -11,9 +11,10 @@ Right now it's very raw, so don't expect things to work properly.
|
|
11
11
|
Fire up the terminal and type:
|
12
12
|
|
13
13
|
$ gem install tanuki
|
14
|
-
$ tanuki
|
15
|
-
|
16
|
-
|
14
|
+
$ tanuki create test
|
15
|
+
$ cd test
|
16
|
+
$ bundle install
|
17
|
+
$ rackup -p 3000
|
17
18
|
|
18
19
|
View the result at: http://localhost:3000
|
19
20
|
|
@@ -27,4 +28,4 @@ Tanuki is thankful to:
|
|
27
28
|
|
28
29
|
* All of the core contributors
|
29
30
|
* Erika Olehno, for the cute logo
|
30
|
-
* {Rack}[http://rack.rubyforge.org/], {Sequel}[http://sequel.rubyforge.org/], {escape_utils}[https://github.com/brianmario/escape_utils], and {Active Support}[https://github.com/rails/rails/tree/master/activesupport] authors and contributors, for their amazing work
|
31
|
+
* {Rack}[http://rack.rubyforge.org/], {Sequel}[http://sequel.rubyforge.org/], {Bundler}[http://gembundler.com/], {escape_utils}[https://github.com/brianmario/escape_utils], and {Active Support}[https://github.com/rails/rails/tree/master/activesupport] authors and contributors, for their amazing work
|
File without changes
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en-US">
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<title><%! title_view %></title>
|
6
|
+
<link rel="stylesheet" href="/bundle.css" media="screen" />
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
%! view
|
10
|
+
%~ ctx.javascripts.each_key do |js|
|
11
|
+
<script><%= File.read js %></script>
|
12
|
+
%~ end
|
13
|
+
</body>
|
14
|
+
</html>
|
@@ -0,0 +1 @@
|
|
1
|
+
Untitled
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class Tanuki::Fetcher::Sequel
|
2
|
+
def initialize(dataset, controller_class)
|
3
|
+
@dataset = dataset
|
4
|
+
@controller_class = controller_class
|
5
|
+
end
|
6
|
+
|
7
|
+
def fetch(md, format)
|
8
|
+
keys = Hash[md.names.map {|name| [name.to_sym, md[name]] }]
|
9
|
+
item = @dataset.filter(keys).first
|
10
|
+
if item
|
11
|
+
{
|
12
|
+
:class => @controller_class,
|
13
|
+
:model => item,
|
14
|
+
:route => format.call(item).to_sym
|
15
|
+
}
|
16
|
+
else
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def fetch_all(format)
|
22
|
+
@dataset.each do |item|
|
23
|
+
yield({
|
24
|
+
:class => @controller_class,
|
25
|
+
:model => item,
|
26
|
+
:route => format.call(item).to_sym
|
27
|
+
})
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def length
|
32
|
+
@dataset.count
|
33
|
+
end
|
34
|
+
end
|
@@ -1,2 +1,2 @@
|
|
1
1
|
class Tanuki::Manager::Controller
|
2
|
-
end
|
2
|
+
end
|
@@ -1,2 +1,2 @@
|
|
1
1
|
class Tanuki::Manager::Page
|
2
|
-
end
|
2
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -1,2 +1,2 @@
|
|
1
1
|
class Tanuki::Model::Controller
|
2
|
-
end
|
2
|
+
end
|
@@ -1,2 +1,2 @@
|
|
1
1
|
class Tanuki::Model::Page
|
2
|
-
end
|
2
|
+
end
|
@@ -39,7 +39,7 @@
|
|
39
39
|
<body>
|
40
40
|
<h1>Page not found!</h1>
|
41
41
|
<div>
|
42
|
-
<p>It seems that the page <code><%= ctx.env['REQUEST_URI'] %></code> at <a href="/"><%= ctx.env['HTTP_HOST'] %></a></p>
|
42
|
+
<p>It seems that the page <code><%= ctx.request.env['REQUEST_URI'] %></code> at <a href="/"><%= ctx.request.env['HTTP_HOST'] %></a></p>
|
43
43
|
<ul>
|
44
44
|
<li>has moved,</li>
|
45
45
|
<li>no longer exists,</li>
|
@@ -0,0 +1 @@
|
|
1
|
+
Welcome to Tanuki!
|
@@ -0,0 +1,88 @@
|
|
1
|
+
body {
|
2
|
+
margin: 0;
|
3
|
+
padding: 0;
|
4
|
+
font-family: 'Trebuchet MS', Helvetica, sans-serif;
|
5
|
+
font-size: 11pt;
|
6
|
+
background-color: #f5f4ef;
|
7
|
+
color: #000305;
|
8
|
+
}
|
9
|
+
|
10
|
+
#header {
|
11
|
+
margin: 0 auto;
|
12
|
+
width: 540px;
|
13
|
+
}
|
14
|
+
|
15
|
+
div.top {
|
16
|
+
background-color: #fff;
|
17
|
+
margin: 0 auto 20px auto;
|
18
|
+
padding: 15px 20px 0 20px;
|
19
|
+
width: 540px;
|
20
|
+
border-radius: 10px;
|
21
|
+
-moz-border-radius: 10px;
|
22
|
+
-webkit-border-radius: 10px;
|
23
|
+
}
|
24
|
+
|
25
|
+
h1 {
|
26
|
+
margin: 20px 0;
|
27
|
+
padding: 0;
|
28
|
+
font-size: 22pt;
|
29
|
+
}
|
30
|
+
|
31
|
+
h1 em {
|
32
|
+
display: block;
|
33
|
+
font-style: normal;
|
34
|
+
font-size: 12pt;
|
35
|
+
color: #777a7c;
|
36
|
+
}
|
37
|
+
|
38
|
+
h2 {
|
39
|
+
margin: 0 0 15px 0;
|
40
|
+
padding: 0;
|
41
|
+
font-size: 16pt;
|
42
|
+
}
|
43
|
+
|
44
|
+
#next ol {
|
45
|
+
margin: 0;
|
46
|
+
padding-bottom: 25px;
|
47
|
+
}
|
48
|
+
|
49
|
+
#next li {
|
50
|
+
margin: 0;
|
51
|
+
padding: 0;
|
52
|
+
font-size: 16pt;
|
53
|
+
font-weight: bold;
|
54
|
+
color: #c74451;
|
55
|
+
}
|
56
|
+
|
57
|
+
#next li span {
|
58
|
+
font-size: 11pt;
|
59
|
+
font-weight: normal;
|
60
|
+
color: #000305;
|
61
|
+
}
|
62
|
+
|
63
|
+
code {
|
64
|
+
font-family: 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', Menlo, Monaco, Consolas, 'Courier New', monospace;
|
65
|
+
font-size: 10pt;
|
66
|
+
background-color: #fffccc;
|
67
|
+
padding: 1px 3px;
|
68
|
+
}
|
69
|
+
|
70
|
+
#env div {
|
71
|
+
padding-bottom: 25px;
|
72
|
+
}
|
73
|
+
|
74
|
+
#env table {
|
75
|
+
margin: 0;
|
76
|
+
padding: 0;
|
77
|
+
border-collapse: collapse;
|
78
|
+
color: #444;
|
79
|
+
}
|
80
|
+
|
81
|
+
#env table th {
|
82
|
+
text-align: left;
|
83
|
+
}
|
84
|
+
|
85
|
+
#env table td {
|
86
|
+
padding-left: 20px;
|
87
|
+
font-size: 10pt;
|
88
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<div id="header">
|
2
|
+
<h1>It Works! <em>You have been granted one Tanuki.</em></h1>
|
3
|
+
</div>
|
4
|
+
<div class="top" id="next">
|
5
|
+
<h2>What to do next</h2>
|
6
|
+
<div>
|
7
|
+
<p>Here's a few suggestions to get things going:</p>
|
8
|
+
<ol>
|
9
|
+
<li><span>To use a database, describe its contents in <code>schema/user</code>.</span></li>
|
10
|
+
<li><span>To generate models from your schema, run <code>tanuki generate</code>.</span></li>
|
11
|
+
<li><span>To add or edit controllers, navigate to <code>app/user</code>.</span></li>
|
12
|
+
</ol>
|
13
|
+
</div>
|
14
|
+
</div>
|
15
|
+
<div class="top" id="env">
|
16
|
+
<h2>Your setup</h2>
|
17
|
+
<div><table>
|
18
|
+
<tr><th>Ruby</th><td><%= RUBY_VERSION %>p<%= RUBY_PATCHLEVEL %> (<%= RUBY_RELEASE_DATE %> revision <%= RUBY_REVISION %>) [<%= RUBY_PLATFORM %>]</td></tr>
|
19
|
+
<tr><th>Rack</th><td><%= Rack.version %> (on <%= ctx.request.env['SERVER_SOFTWARE'] %>)</td></tr>
|
20
|
+
<tr><th>Tanuki</th><td><%= Tanuki.version %></td></tr>
|
21
|
+
</table></div>
|
22
|
+
</div>
|
data/bin/tanuki
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
$:.unshift File.expand_path(
|
2
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
3
|
+
require 'active_support/core_ext/string/inflections'
|
3
4
|
require 'tanuki/utility'
|
4
5
|
Tanuki::Utility.init if File.basename(__FILE__) == File.basename($0)
|
data/config/common.rb
CHANGED
@@ -2,16 +2,13 @@ load_config :common
|
|
2
2
|
|
3
3
|
# Rack middleware
|
4
4
|
use Rack::Head
|
5
|
-
use Rack::StaticDir,
|
5
|
+
use Rack::StaticDir, @context.public_root
|
6
6
|
|
7
|
-
#
|
8
|
-
set :server, [:thin, :mongrel, :webrick]
|
9
|
-
set :host, '0.0.0.0'
|
10
|
-
set :port, 3000
|
7
|
+
# Environment
|
11
8
|
set :development, false
|
12
9
|
|
13
10
|
# Default controllers
|
14
|
-
set :root_page, ::User::Page::
|
11
|
+
set :root_page, ::User::Page::Home
|
15
12
|
set :missing_page, ::Tanuki::Page::Missing
|
16
13
|
|
17
14
|
# Internationalization
|
data/lib/tanuki.rb
CHANGED
@@ -9,19 +9,20 @@ require 'yaml'
|
|
9
9
|
require 'escape_utils'
|
10
10
|
require 'escape_utils/url/rack'
|
11
11
|
require 'tanuki/version'
|
12
|
+
require 'tanuki/const'
|
12
13
|
require 'tanuki/extensions/module'
|
13
|
-
require 'tanuki/extensions/rack/
|
14
|
-
require 'tanuki/extensions/rack/server'
|
14
|
+
require 'tanuki/extensions/rack/frozen_route'
|
15
15
|
require 'tanuki/extensions/rack/static_dir'
|
16
|
-
require 'tanuki/
|
17
|
-
require 'tanuki/
|
18
|
-
require 'tanuki/behavior/model_behavior'
|
19
|
-
require 'tanuki/behavior/object_behavior'
|
16
|
+
require 'tanuki/base_behavior'
|
17
|
+
require 'tanuki/extensions/sequel/model'
|
20
18
|
require 'tanuki/argument'
|
21
19
|
require 'tanuki/configurator'
|
22
20
|
require 'tanuki/context'
|
23
|
-
require 'tanuki/
|
21
|
+
require 'tanuki/controller'
|
22
|
+
require 'tanuki/css_compressor'
|
24
23
|
require 'tanuki/loader'
|
24
|
+
require 'tanuki/meta_model'
|
25
|
+
require 'tanuki/model_behavior'
|
25
26
|
require 'tanuki/i18n'
|
26
27
|
require 'tanuki/template_compiler'
|
27
28
|
require 'tanuki/application'
|
data/lib/tanuki/application.rb
CHANGED
@@ -1,50 +1,29 @@
|
|
1
1
|
module Tanuki
|
2
2
|
|
3
3
|
# Tanuki::Application is the starting point for all framework applications.
|
4
|
-
# It contains core application functionality like configuration, request
|
4
|
+
# It contains core application functionality like configuration, request
|
5
|
+
# handling and view management.
|
5
6
|
class Application
|
6
7
|
|
7
|
-
|
8
|
+
Loader.context = Context
|
8
9
|
@rack_middleware = []
|
9
10
|
|
10
11
|
class << self
|
11
12
|
|
12
|
-
# Initializes application
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
if pwd != default_root
|
23
|
-
@cfg.config_root = File.join(default_root, 'config')
|
24
|
-
@cfg.load_config(([:development, :production].include? env) ? :"#{env}_application" : :common_application)
|
25
|
-
end
|
26
|
-
|
27
|
-
# Configure in application root
|
28
|
-
@cfg.config_root = File.join(pwd, 'config')
|
29
|
-
@cfg.load_config :"#{env}_application", pwd != default_root
|
30
|
-
|
31
|
-
return true
|
32
|
-
rescue NameError => e
|
33
|
-
if e.name =~ /\AA-Z/
|
34
|
-
raise NameError, "missing class or module for constant `#{e.name}'", e.backtrace
|
35
|
-
else
|
36
|
-
raise e
|
37
|
-
end
|
38
|
-
end
|
39
|
-
false
|
13
|
+
# Initializes the application in a given Rack::Builder +builder+.
|
14
|
+
def build(builder)
|
15
|
+
puts %{Calling for Tanuki #{Tanuki.version} in "#{Dir.pwd}"}
|
16
|
+
configure
|
17
|
+
Loader.prepare_for_production unless @cfg.context.development
|
18
|
+
at_exit { puts 'Tanuki ran away!' }
|
19
|
+
configure_middleware(builder)
|
20
|
+
vowel = @environment =~ /\A[aeiou]/
|
21
|
+
puts "A#{'n' if vowel} #{@environment} Tanuki appears!"
|
22
|
+
rack_app
|
40
23
|
end
|
41
24
|
|
42
|
-
#
|
43
|
-
|
44
|
-
@rack_middleware.each {|item| rack_builder.use(item[0], *item[1], &item[2]) }
|
45
|
-
end
|
46
|
-
|
47
|
-
# Removes all occurences of a given +middleware+ from the Rack middleware pipeline.
|
25
|
+
# Removes all occurences of a given +middleware+ from the Rack
|
26
|
+
# middleware pipeline.
|
48
27
|
def discard(middleware)
|
49
28
|
@rack_middleware.delete_if {|item| item[0] == middleware }
|
50
29
|
end
|
@@ -55,21 +34,18 @@ module Tanuki
|
|
55
34
|
@environment ||= nil
|
56
35
|
end
|
57
36
|
|
58
|
-
#
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
@context.running_server.run rack_builder.to_app, :Host => @context.host, :Port => @context.port do |server|
|
66
|
-
[:INT, :TERM].each {|sig| trap(sig) { (server.respond_to? :stop!) ? server.stop! : server.stop } }
|
67
|
-
puts "A#{'n' if @environment =~ /\A[aeiou]/} #{@environment} Tanuki appears! Press Ctrl-C to set it free.",
|
68
|
-
"You used #{@context.running_server.name.gsub(/.*::/, '')} at #{@context.host}:#{@context.port}."
|
37
|
+
# Pulls all occurences of a given +middleware+ down to the end
|
38
|
+
# of the Rack middleware pipeline (it would have the lowest priority).
|
39
|
+
def pull_down(middleware)
|
40
|
+
items = @rack_middleware.select {|item| item[0] == middleware }
|
41
|
+
if items
|
42
|
+
@rack_middleware.reject! {|item| item[0] == middleware }
|
43
|
+
items.each {|item| @rack_middleware << item }
|
69
44
|
end
|
70
45
|
end
|
71
46
|
|
72
|
-
# Adds a given +middleware+ with optional +args+ and +block+
|
47
|
+
# Adds a given +middleware+ with optional +args+ and +block+
|
48
|
+
# to the Rack middleware pipeline.
|
73
49
|
def use(middleware, *args, &block)
|
74
50
|
@rack_middleware << [middleware, args, block]
|
75
51
|
end
|
@@ -90,70 +66,121 @@ module Tanuki
|
|
90
66
|
# <%_escape escaped_view %>
|
91
67
|
# <%_printf('<div>%s</div>') formatted_view %>
|
92
68
|
def visitor(sym, &block)
|
93
|
-
BaseBehavior.instance_eval
|
69
|
+
BaseBehavior.instance_eval do
|
70
|
+
define_method "#{sym}_visitor".to_sym, &block
|
71
|
+
end
|
94
72
|
end
|
95
73
|
|
96
74
|
private
|
97
75
|
|
98
|
-
#
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
76
|
+
# Initializes application settings using configuration
|
77
|
+
# for the current Rack environment.
|
78
|
+
# These include settings for server, context, and middleware.
|
79
|
+
def configure
|
80
|
+
@environment = ENV['RACK_ENV'].to_sym
|
81
|
+
default_root = File.expand_path('../../..', __FILE__)
|
82
|
+
@cfg = Configurator.new(Context, pwd = Dir.pwd)
|
83
|
+
env_config = :"#{@environment}_application"
|
84
|
+
|
85
|
+
# Configure in default root (e.g. gem root)
|
86
|
+
if pwd != default_root
|
87
|
+
@cfg.config_root = File.join(default_root, 'config')
|
88
|
+
if [:development, :production].include? @environment
|
89
|
+
default_config = env_config
|
90
|
+
else
|
91
|
+
default_config = :common_application
|
105
92
|
end
|
93
|
+
@cfg.load_config default_config
|
106
94
|
end
|
107
|
-
|
95
|
+
|
96
|
+
# Configure in application root
|
97
|
+
@cfg.config_root = File.join(pwd, 'config')
|
98
|
+
if @cfg.config_file? env_config
|
99
|
+
@cfg.load_config env_config, pwd != default_root
|
100
|
+
elsif @cfg.config_file? :common_application
|
101
|
+
@cfg.load_config :common_application
|
102
|
+
end
|
103
|
+
|
104
|
+
self
|
105
|
+
rescue NameError => e
|
106
|
+
raise e unless e.name =~ /\AA-Z/
|
107
|
+
message = "missing class or module for constant `#{e.name}'"
|
108
|
+
raise NameError, message, e.backtrace
|
108
109
|
end
|
109
110
|
|
110
|
-
#
|
111
|
-
|
112
|
-
|
113
|
-
|
111
|
+
# Add utilized middleware to a given Rack::Builder instance
|
112
|
+
# +rack_builder+.
|
113
|
+
def configure_middleware(rack_builder)
|
114
|
+
@rack_middleware.each do |item|
|
115
|
+
rack_builder.use item[0], *item[1], &item[2]
|
116
|
+
end
|
114
117
|
end
|
115
118
|
|
116
119
|
# Returns a Rack app block for Rack::Builder.
|
117
|
-
# This block is passed a request environment
|
120
|
+
# This block is passed a request environment
|
121
|
+
# and returns and array of three elements:
|
118
122
|
# * a response status code,
|
119
123
|
# * a hash of headers,
|
120
124
|
# * an iterable body object.
|
121
125
|
# It is run on each request.
|
122
126
|
def rack_app
|
123
|
-
ctx = @context
|
124
127
|
proc do |env|
|
125
|
-
request_ctx = ctx.child
|
126
|
-
request_ctx.templates = {}
|
127
128
|
|
128
129
|
# If there are trailing slashes in path, don't dispatch
|
129
|
-
|
130
|
+
path_info = env[Const::PATH_INFO]
|
131
|
+
if match = path_info.match(Const::TRAILING_SLASH)
|
130
132
|
|
131
133
|
# Remove trailing slash in the path and redirect
|
132
134
|
loc = match[1]
|
133
|
-
|
134
|
-
|
135
|
+
query_string = env[Const::QUERY_STRING]
|
136
|
+
loc << "?#{query_string}" unless query_string.empty?
|
137
|
+
[
|
138
|
+
301,
|
139
|
+
{
|
140
|
+
Const::LOCATION => loc,
|
141
|
+
Const::CONTENT_TYPE => Const::MIME_TEXT_HTML
|
142
|
+
},
|
143
|
+
Const::EMPTY_ARRAY
|
144
|
+
]
|
135
145
|
|
136
146
|
else
|
147
|
+
ctx = Context.child
|
148
|
+
ctx.templates = {}
|
149
|
+
ctx.resources = {}
|
150
|
+
ctx.javascripts = {}
|
137
151
|
|
138
152
|
# Dispatch controller chain for the current path
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
153
|
+
Loader.refresh_css if ctx.development
|
154
|
+
ctx.request = Rack::Request.new(env)
|
155
|
+
resp = ctx.response = Rack::Response.new(
|
156
|
+
[],
|
157
|
+
200,
|
158
|
+
{Const::CONTENT_TYPE => Const::MIME_TEXT_HTML}
|
159
|
+
)
|
160
|
+
template = nil
|
161
|
+
catch :halt do
|
162
|
+
template = ::Tanuki::Controller.dispatch(
|
163
|
+
ctx,
|
164
|
+
Context.i18n ? ::Tanuki::I18n : Context.root_page,
|
165
|
+
Rack::Utils.unescape(path_info).force_encoding(Const::UTF_8)
|
166
|
+
)
|
167
|
+
end
|
168
|
+
if template &&
|
169
|
+
template.is_a?(Method) &&
|
170
|
+
template.receiver.is_a?(BaseBehavior) &&
|
171
|
+
template.name =~ Const::VIEW_METHOD
|
172
|
+
then
|
173
|
+
resp.finish do |resp|
|
174
|
+
template.call.call(proc {|s| resp.write s }, ctx)
|
175
|
+
end
|
149
176
|
else
|
150
|
-
|
177
|
+
resp.finish
|
151
178
|
end
|
152
179
|
|
153
180
|
end # if
|
154
181
|
|
155
|
-
end
|
156
|
-
end
|
182
|
+
end # proc
|
183
|
+
end # rack_app
|
157
184
|
|
158
185
|
end # class << self
|
159
186
|
|