tanuki 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/README.rdoc +5 -4
  2. data/app/tanuki/controller/{link.thtml → controller.link.thtml} +0 -0
  3. data/app/tanuki/controller/controller.page.thtml +14 -0
  4. data/app/tanuki/controller/controller.rb +1 -2
  5. data/app/tanuki/controller/controller.title.ttxt +1 -0
  6. data/app/tanuki/controller/controller.view.thtml +3 -0
  7. data/app/tanuki/fetcher/sequel/sequel.rb +34 -0
  8. data/app/tanuki/manager/controller/controller.rb +1 -1
  9. data/app/tanuki/manager/page/page.rb +1 -1
  10. data/app/tanuki/meta_model/{manager.ttxt → meta_model.manager.ttxt} +0 -0
  11. data/app/tanuki/meta_model/{manager_base.ttxt → meta_model.manager_base.ttxt} +0 -0
  12. data/app/tanuki/meta_model/{model.ttxt → meta_model.model.ttxt} +0 -0
  13. data/app/tanuki/meta_model/{model_base.ttxt → meta_model.model_base.ttxt} +0 -0
  14. data/app/tanuki/meta_model/meta_model.rb +1 -2
  15. data/app/tanuki/model/controller/controller.rb +1 -1
  16. data/app/tanuki/model/page/page.rb +1 -1
  17. data/app/tanuki/page/missing/{default.thtml → missing.page.thtml} +1 -1
  18. data/app/tanuki/page/missing/missing.rb +3 -2
  19. data/app/user/page/home/home.rb +2 -0
  20. data/app/user/page/home/home.title.thtml +1 -0
  21. data/app/user/page/home/home.view.css +88 -0
  22. data/app/user/page/home/home.view.thtml +22 -0
  23. data/bin/tanuki +2 -1
  24. data/config/common.rb +1 -0
  25. data/config/common_application.rb +3 -6
  26. data/config/development_application.rb +0 -3
  27. data/lib/tanuki.rb +8 -7
  28. data/lib/tanuki/application.rb +108 -81
  29. data/lib/tanuki/argument.rb +10 -5
  30. data/lib/tanuki/argument/integer_range.rb +4 -2
  31. data/lib/tanuki/{behavior/object_behavior.rb → base_behavior.rb} +21 -4
  32. data/lib/tanuki/configurator.rb +20 -8
  33. data/lib/tanuki/const.rb +32 -0
  34. data/lib/tanuki/context.rb +18 -7
  35. data/lib/tanuki/controller.rb +517 -0
  36. data/lib/tanuki/css_compressor.rb +50 -0
  37. data/lib/tanuki/extensions/module.rb +21 -5
  38. data/lib/tanuki/extensions/rack/frozen_route.rb +35 -0
  39. data/lib/tanuki/extensions/rack/static_dir.rb +1 -1
  40. data/lib/tanuki/extensions/sequel/model.rb +7 -0
  41. data/lib/tanuki/i18n.rb +8 -6
  42. data/lib/tanuki/loader.rb +166 -33
  43. data/lib/tanuki/meta_model.rb +176 -0
  44. data/lib/tanuki/{behavior/model_behavior.rb → model_behavior.rb} +7 -3
  45. data/lib/tanuki/model_generator.rb +49 -29
  46. data/lib/tanuki/template_compiler.rb +72 -41
  47. data/lib/tanuki/utility.rb +11 -4
  48. data/lib/tanuki/utility/create.rb +52 -11
  49. data/lib/tanuki/utility/generate.rb +16 -10
  50. data/lib/tanuki/utility/version.rb +1 -1
  51. data/lib/tanuki/version.rb +7 -2
  52. metadata +50 -66
  53. data/app/tanuki/controller/default.thtml +0 -5
  54. data/app/tanuki/controller/index.thtml +0 -1
  55. data/app/user/page/index/default.thtml +0 -121
  56. data/app/user/page/index/index.rb +0 -2
  57. data/config/test_application.rb +0 -2
  58. data/lib/tanuki/behavior/controller_behavior.rb +0 -366
  59. data/lib/tanuki/behavior/meta_model_behavior.rb +0 -160
  60. data/lib/tanuki/extensions/rack/builder.rb +0 -26
  61. data/lib/tanuki/extensions/rack/server.rb +0 -18
  62. data/lib/tanuki/launcher.rb +0 -21
  63. data/lib/tanuki/utility/server.rb +0 -23
@@ -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
- tanuki> create test
16
- tanuki> server
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
@@ -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>
@@ -1,3 +1,2 @@
1
- class Tanuki::Controller < Tanuki::Base
2
- include Tanuki::ControllerBehavior
1
+ class Tanuki::Controller
3
2
  end
@@ -0,0 +1,3 @@
1
+ %~ if visual_child
2
+ %! visual_child.view
3
+ %~ end
@@ -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
@@ -1,3 +1,2 @@
1
- class Tanuki::MetaModel < Tanuki::Base
2
- include Tanuki::MetaModelBehavior
1
+ class Tanuki::MetaModel
3
2
  end
@@ -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>
@@ -3,7 +3,8 @@ class Tanuki::Page::Missing < Tanuki::Controller
3
3
  nil
4
4
  end
5
5
 
6
- def result_type
7
- :not_found
6
+ def get # TODO: add other request methods
7
+ status 404
8
+ super
8
9
  end
9
10
  end
@@ -0,0 +1,2 @@
1
+ class User::Page::Home < Tanuki::Controller
2
+ end
@@ -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(File.join('..', '..', 'lib'), __FILE__)
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)
@@ -2,6 +2,7 @@
2
2
  set :app_root, proc { File.join(root, 'app') }
3
3
  set :gen_root, proc { File.join(root, 'gen') }
4
4
  set :schema_root, proc { File.join(root, 'schema') }
5
+ set :public_root, proc { File.join(root, 'public') }
5
6
 
6
7
  # Cache
7
8
  set :templates, {}
@@ -2,16 +2,13 @@ load_config :common
2
2
 
3
3
  # Rack middleware
4
4
  use Rack::Head
5
- use Rack::StaticDir, 'public'
5
+ use Rack::StaticDir, @context.public_root
6
6
 
7
- # Server
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::Index
11
+ set :root_page, ::User::Page::Home
15
12
  set :missing_page, ::Tanuki::Page::Missing
16
13
 
17
14
  # Internationalization
@@ -2,7 +2,4 @@ load_config :common_application
2
2
  set :development, true
3
3
 
4
4
  # Rack middleware
5
- use Rack::CommonLogger
6
- use Rack::Lint
7
5
  use Rack::Reloader, 0
8
- use Rack::ShowExceptions
@@ -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/builder'
14
- require 'tanuki/extensions/rack/server'
14
+ require 'tanuki/extensions/rack/frozen_route'
15
15
  require 'tanuki/extensions/rack/static_dir'
16
- require 'tanuki/behavior/controller_behavior'
17
- require 'tanuki/behavior/meta_model_behavior'
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/launcher'
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'
@@ -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 handling and view management.
4
+ # It contains core application functionality like configuration, request
5
+ # handling and view management.
5
6
  class Application
6
7
 
7
- @context = (Loader.context = Context).child
8
+ Loader.context = Context
8
9
  @rack_middleware = []
9
10
 
10
11
  class << self
11
12
 
12
- # Initializes application settings using configuration for environment +env+.
13
- # These include settings for server, context, and middleware.
14
- # Returns true, if configuration is successful.
15
- def configure(env)
16
- @environment = env
17
- begin
18
- default_root = File.expand_path(File.join('..', '..', '..'), __FILE__)
19
- @cfg = Configurator.new(Context, pwd = Dir.pwd)
20
-
21
- # Configure in default root (e.g. gem root)
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
- # Add utilized middleware to a given Rack::Builder instance +rack_builder+.
43
- def configure_middleware(rack_builder)
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
- # Runs the application with current settings.
59
- def run
60
- configure_middleware(rack_builder = Rack::Builder.new)
61
- rack_builder.run(rack_app)
62
-
63
- # Choose and start a Rack handler
64
- @context.running_server = available_server
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+ to the Rack middleware pipeline.
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 { define_method "#{sym}_visitor".to_sym, &block }
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
- # Returns the first available server from a server list in the current context.
99
- def available_server
100
- @context.server.each do |server_name|
101
- begin
102
- return Rack::Handler.get(server_name.downcase)
103
- rescue LoadError
104
- rescue NameError
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
- raise "servers #{@context.server.join(', ')} not found"
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
- # Returns an array of template outputs for controller +ctrl+ in context +request_ctx+.
111
- def build_body(ctrl, request_ctx)
112
- arr = []
113
- Launcher.new(ctrl, request_ctx).each &proc {|out| arr << out.to_s }
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 and returns and array of three elements:
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
- if match = env['PATH_INFO'].match(/^(.+)(?<!\$)\/$/)
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
- loc << "?#{env['QUERY_STRING']}" unless env['QUERY_STRING'].empty?
134
- [301, {'Location' => loc, 'Content-Type' => 'text/html; charset=utf-8'}, []]
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
- request_ctx.env = env
140
- result = ::Tanuki::ControllerBehavior.dispatch(request_ctx, ctx.i18n ? ::Tanuki::I18n : ctx.root_page,
141
- Rack::Utils.unescape(env['PATH_INFO']).force_encoding('UTF-8'))
142
-
143
- # Handle dispatch result
144
- case result[:type]
145
- when :redirect then
146
- [302, {'Location' => result[:location], 'Content-Type' => 'text/html; charset=utf-8'}, []]
147
- when :page then
148
- [200, {'Content-Type' => 'text/html; charset=utf-8'}, build_body(result[:controller], request_ctx)]
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
- [404, {'Content-Type' => 'text/html; charset=utf-8'}, build_body(result[:controller], request_ctx)]
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