ramaze 0.0.6

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.
Files changed (174) hide show
  1. data/Rakefile +360 -0
  2. data/bin/ramaze +152 -0
  3. data/doc/CHANGELOG +2021 -0
  4. data/doc/COPYING +56 -0
  5. data/doc/COPYING.ja +51 -0
  6. data/doc/README +275 -0
  7. data/doc/TODO +33 -0
  8. data/doc/allison/LICENSE +184 -0
  9. data/doc/allison/README +37 -0
  10. data/doc/allison/allison.css +300 -0
  11. data/doc/allison/allison.gif +0 -0
  12. data/doc/allison/allison.js +307 -0
  13. data/doc/allison/allison.rb +287 -0
  14. data/doc/allison/cache/BODY +588 -0
  15. data/doc/allison/cache/CLASS_INDEX +4 -0
  16. data/doc/allison/cache/CLASS_PAGE +1 -0
  17. data/doc/allison/cache/FILE_INDEX +4 -0
  18. data/doc/allison/cache/FILE_PAGE +1 -0
  19. data/doc/allison/cache/FONTS +1 -0
  20. data/doc/allison/cache/FR_INDEX_BODY +1 -0
  21. data/doc/allison/cache/IMGPATH +1 -0
  22. data/doc/allison/cache/INDEX +1 -0
  23. data/doc/allison/cache/JAVASCRIPT +307 -0
  24. data/doc/allison/cache/METHOD_INDEX +4 -0
  25. data/doc/allison/cache/METHOD_LIST +1 -0
  26. data/doc/allison/cache/SRC_PAGE +1 -0
  27. data/doc/allison/cache/STYLE +322 -0
  28. data/doc/allison/cache/URL +1 -0
  29. data/examples/blog/main.rb +16 -0
  30. data/examples/blog/public/screen.css +106 -0
  31. data/examples/blog/src/controller.rb +50 -0
  32. data/examples/blog/src/element.rb +53 -0
  33. data/examples/blog/src/model.rb +29 -0
  34. data/examples/blog/template/edit.xhtml +6 -0
  35. data/examples/blog/template/index.xhtml +24 -0
  36. data/examples/blog/template/new.xhtml +5 -0
  37. data/examples/blog/template/view.xhtml +15 -0
  38. data/examples/blog/test/tc_entry.rb +18 -0
  39. data/examples/caching.rb +23 -0
  40. data/examples/element.rb +40 -0
  41. data/examples/hello.rb +23 -0
  42. data/examples/simple.rb +60 -0
  43. data/examples/templates/template/external.haml +21 -0
  44. data/examples/templates/template/external.liquid +28 -0
  45. data/examples/templates/template/external.mab +27 -0
  46. data/examples/templates/template/external.rhtml +29 -0
  47. data/examples/templates/template/external.rmze +24 -0
  48. data/examples/templates/template_erubis.rb +50 -0
  49. data/examples/templates/template_haml.rb +48 -0
  50. data/examples/templates/template_liquid.rb +64 -0
  51. data/examples/templates/template_markaby.rb +52 -0
  52. data/examples/templates/template_ramaze.rb +49 -0
  53. data/examples/whywiki/main.rb +56 -0
  54. data/examples/whywiki/template/edit.xhtml +14 -0
  55. data/examples/whywiki/template/show.xhtml +17 -0
  56. data/lib/proto/conf/benchmark.yaml +35 -0
  57. data/lib/proto/conf/debug.yaml +34 -0
  58. data/lib/proto/conf/live.yaml +33 -0
  59. data/lib/proto/conf/silent.yaml +31 -0
  60. data/lib/proto/conf/stage.yaml +33 -0
  61. data/lib/proto/main.rb +18 -0
  62. data/lib/proto/public/404.jpg +0 -0
  63. data/lib/proto/public/css/coderay.css +105 -0
  64. data/lib/proto/public/css/ramaze_error.css +42 -0
  65. data/lib/proto/public/error.xhtml +74 -0
  66. data/lib/proto/public/favicon.ico +0 -0
  67. data/lib/proto/public/js/jquery.js +1923 -0
  68. data/lib/proto/public/ramaze.png +0 -0
  69. data/lib/proto/src/controller/main.rb +7 -0
  70. data/lib/proto/src/element/page.rb +16 -0
  71. data/lib/proto/src/model.rb +5 -0
  72. data/lib/proto/template/index.xhtml +6 -0
  73. data/lib/ramaze.rb +317 -0
  74. data/lib/ramaze/adapter/mongrel.rb +111 -0
  75. data/lib/ramaze/adapter/webrick.rb +161 -0
  76. data/lib/ramaze/cache.rb +11 -0
  77. data/lib/ramaze/cache/memcached.rb +52 -0
  78. data/lib/ramaze/cache/memory.rb +6 -0
  79. data/lib/ramaze/cache/yaml_store.rb +37 -0
  80. data/lib/ramaze/controller.rb +10 -0
  81. data/lib/ramaze/dispatcher.rb +315 -0
  82. data/lib/ramaze/error.rb +11 -0
  83. data/lib/ramaze/gestalt.rb +108 -0
  84. data/lib/ramaze/global.rb +120 -0
  85. data/lib/ramaze/helper.rb +32 -0
  86. data/lib/ramaze/helper/aspect.rb +189 -0
  87. data/lib/ramaze/helper/auth.rb +120 -0
  88. data/lib/ramaze/helper/cache.rb +52 -0
  89. data/lib/ramaze/helper/feed.rb +135 -0
  90. data/lib/ramaze/helper/form.rb +204 -0
  91. data/lib/ramaze/helper/link.rb +80 -0
  92. data/lib/ramaze/helper/redirect.rb +48 -0
  93. data/lib/ramaze/helper/stack.rb +67 -0
  94. data/lib/ramaze/http_status.rb +66 -0
  95. data/lib/ramaze/inform.rb +166 -0
  96. data/lib/ramaze/snippets.rb +5 -0
  97. data/lib/ramaze/snippets/hash/keys_to_sym.rb +19 -0
  98. data/lib/ramaze/snippets/kernel/aquire.rb +22 -0
  99. data/lib/ramaze/snippets/kernel/autoreload.rb +79 -0
  100. data/lib/ramaze/snippets/kernel/caller_lines.rb +58 -0
  101. data/lib/ramaze/snippets/kernel/constant.rb +24 -0
  102. data/lib/ramaze/snippets/kernel/rescue_require.rb +12 -0
  103. data/lib/ramaze/snippets/kernel/self_method.rb +41 -0
  104. data/lib/ramaze/snippets/kernel/silently.rb +13 -0
  105. data/lib/ramaze/snippets/object/traits.rb +60 -0
  106. data/lib/ramaze/snippets/openstruct/temp.rb +10 -0
  107. data/lib/ramaze/snippets/string/DIVIDE.rb +16 -0
  108. data/lib/ramaze/snippets/string/camel_case.rb +14 -0
  109. data/lib/ramaze/snippets/string/snake_case.rb +12 -0
  110. data/lib/ramaze/snippets/symbol/to_proc.rb +14 -0
  111. data/lib/ramaze/snippets/thread/deadQUESTIONMARK.rb +11 -0
  112. data/lib/ramaze/store/default.rb +48 -0
  113. data/lib/ramaze/template.rb +102 -0
  114. data/lib/ramaze/template/amrita2.rb +40 -0
  115. data/lib/ramaze/template/erubis.rb +58 -0
  116. data/lib/ramaze/template/haml.rb +65 -0
  117. data/lib/ramaze/template/haml/actionview_stub.rb +20 -0
  118. data/lib/ramaze/template/liquid.rb +74 -0
  119. data/lib/ramaze/template/markaby.rb +68 -0
  120. data/lib/ramaze/template/ramaze.rb +177 -0
  121. data/lib/ramaze/template/ramaze/element.rb +166 -0
  122. data/lib/ramaze/template/ramaze/morpher.rb +156 -0
  123. data/lib/ramaze/tool/create.rb +70 -0
  124. data/lib/ramaze/tool/tidy.rb +71 -0
  125. data/lib/ramaze/trinity.rb +38 -0
  126. data/lib/ramaze/trinity/request.rb +244 -0
  127. data/lib/ramaze/trinity/response.rb +41 -0
  128. data/lib/ramaze/trinity/session.rb +129 -0
  129. data/lib/ramaze/version.rb +14 -0
  130. data/spec/spec_all.rb +73 -0
  131. data/spec/spec_helper.rb +215 -0
  132. data/spec/tc_adapter_mongrel.rb +24 -0
  133. data/spec/tc_adapter_webrick.rb +22 -0
  134. data/spec/tc_cache.rb +79 -0
  135. data/spec/tc_controller.rb +39 -0
  136. data/spec/tc_element.rb +100 -0
  137. data/spec/tc_error.rb +23 -0
  138. data/spec/tc_gestalt.rb +90 -0
  139. data/spec/tc_global.rb +46 -0
  140. data/spec/tc_helper_aspect.rb +65 -0
  141. data/spec/tc_helper_auth.rb +61 -0
  142. data/spec/tc_helper_cache.rb +81 -0
  143. data/spec/tc_helper_feed.rb +129 -0
  144. data/spec/tc_helper_form.rb +146 -0
  145. data/spec/tc_helper_link.rb +58 -0
  146. data/spec/tc_helper_redirect.rb +51 -0
  147. data/spec/tc_helper_stack.rb +55 -0
  148. data/spec/tc_morpher.rb +90 -0
  149. data/spec/tc_params.rb +84 -0
  150. data/spec/tc_request.rb +111 -0
  151. data/spec/tc_session.rb +56 -0
  152. data/spec/tc_store.rb +25 -0
  153. data/spec/tc_template_amrita2.rb +34 -0
  154. data/spec/tc_template_erubis.rb +41 -0
  155. data/spec/tc_template_haml.rb +44 -0
  156. data/spec/tc_template_liquid.rb +98 -0
  157. data/spec/tc_template_markaby.rb +74 -0
  158. data/spec/tc_template_ramaze.rb +54 -0
  159. data/spec/tc_tidy.rb +14 -0
  160. data/spec/template/amrita2/data.html +6 -0
  161. data/spec/template/amrita2/index.html +1 -0
  162. data/spec/template/amrita2/sum.html +1 -0
  163. data/spec/template/erubis/sum.rhtml +1 -0
  164. data/spec/template/haml/index.haml +5 -0
  165. data/spec/template/haml/with_vars.haml +4 -0
  166. data/spec/template/liquid/index.liquid +1 -0
  167. data/spec/template/liquid/products.liquid +45 -0
  168. data/spec/template/markaby/external.mab +8 -0
  169. data/spec/template/markaby/sum.mab +1 -0
  170. data/spec/template/ramaze/file_only.rmze +1 -0
  171. data/spec/template/ramaze/index.rmze +1 -0
  172. data/spec/template/ramaze/nested.rmze +1 -0
  173. data/spec/template/ramaze/sum.rmze +1 -0
  174. metadata +317 -0
@@ -0,0 +1,102 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ require 'ramaze/helper'
5
+
6
+ module Ramaze::Template
7
+ %w[ Amrita2 Erubis Haml Liquid Markaby Ramaze ].each do |const|
8
+ autoload(const, "ramaze/template/#{const.downcase}")
9
+ end
10
+
11
+ class Template
12
+ extend ::Ramaze::Helper
13
+
14
+ # Path to the ramaze-internal public directory for error-pages and the like.
15
+ # It acts just as a shadow.
16
+ trait :public => ( ::Ramaze::BASEDIR / 'proto' / 'public' )
17
+
18
+ helper :link, :redirect
19
+
20
+ # This finds the template for the given action on the current controller
21
+ # there are some basic ways how you can provide an alternative path:
22
+ #
23
+ # Global.template_root = 'default/path'
24
+ #
25
+ # class FooController < Template::Ramaze
26
+ # trait :template_root => 'another/path'
27
+ # trait :index_template => :foo
28
+ #
29
+ # def index
30
+ # end
31
+ # end
32
+ #
33
+ # One feature also used in the above example is the custom template for
34
+ # one action, in this case :index - now the template of :foo will be
35
+ # used instead.
36
+
37
+ def self.find_template action
38
+ action = action.to_s
39
+ custom_template = ancestral_trait["#{action}_template".intern]
40
+ action = custom_template if custom_template
41
+
42
+ first_path =
43
+ if template_root = ancestral_trait[:template_root]
44
+ template_root
45
+ else
46
+ Global.template_root / Global.mapping.invert[self]
47
+ end
48
+
49
+ extensions = ancestral_trait[:template_extensions]
50
+
51
+ paths = [ first_path, ancestral_trait[:public], ]
52
+ paths = paths.map{|pa| File.expand_path(pa / action)}.join(',')
53
+
54
+ possible = Dir["{#{paths}}.{#{extensions.join(',')}}"]
55
+ possible.first
56
+ end
57
+
58
+ private
59
+
60
+ # just call self.class.find_template(action)
61
+
62
+ def find_template action
63
+ self.class.find_template(action)
64
+ end
65
+
66
+ # the default error-page handler. you can overwrite this method
67
+ # in your controller and create your own error-template for use.
68
+ #
69
+ # Error-pages can be in whatever the templating-engine of your controller
70
+ # is set to.
71
+ # Thread.current[:exception]
72
+ # holds the exception thrown.
73
+
74
+ def error
75
+ error = Thread.current[:exception]
76
+ backtrace = error.backtrace[0..20]
77
+ title = error.message
78
+
79
+ colors = []
80
+ min = 160
81
+ max = 255
82
+ step = -((max - min) / backtrace.size).abs
83
+ max.step(min, step) do |color|
84
+ colors << color
85
+ end
86
+
87
+ backtrace.map! do |line|
88
+ file, lineno, meth = line.scan(/(.*?):(\d+)(?::in `(.*?)')?/).first
89
+ lines = __caller_lines__(file, lineno, Global.inform_backtrace_size)
90
+ [ lines, lines.object_id.abs, file, lineno, meth ]
91
+ end
92
+
93
+ @backtrace = backtrace
94
+ @colors = colors
95
+ @title = title
96
+ require 'coderay'
97
+ @coderay = true
98
+ rescue LoadError => ex
99
+ @coderay = false
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,40 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ require 'amrita2/template'
5
+
6
+ module Ramaze::Template
7
+ class Amrita2 < Template
8
+
9
+ # No actions on the controller are serached or called.
10
+ trait :actionless => true
11
+
12
+ # usual extensions for templates
13
+ trait :template_extensions => %w[html]
14
+
15
+ class << self
16
+ include Ramaze::Helper
17
+
18
+ # initializes the handling of a request on the controller.
19
+ # Creates a new instances of itself and sends the action and params.
20
+ # Also tries to render the template.
21
+ # In Theory you can use this standalone, this has not been tested though.
22
+
23
+ def handle_request action, *params
24
+
25
+ file = find_template(action)
26
+
27
+ raise Ramaze::Error::Template, "No Template found for #{request.request_path}" unless file
28
+
29
+ template = ::Amrita2::TemplateFile.new(file)
30
+ out = ''
31
+ template.expand(out, self.new)
32
+ out
33
+
34
+ rescue Object => ex
35
+ Informer.error ex
36
+ raise Ramaze::Error::NoAction, "No Action found for #{request.request_path}"
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,58 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ require 'erubis'
5
+
6
+ module Ramaze::Template
7
+ class Erubis < Template
8
+ extend Ramaze::Helper
9
+
10
+ # Actions consist of both templates and methods on the controller.
11
+ trait :actionless => false
12
+
13
+ # usual extensions for templates.
14
+ trait :template_extensions => %w[rhtml rmze xhtml html]
15
+
16
+ class << self
17
+ # initializes the handling of a request on the controller.
18
+ # Creates a new instances of itself and sends the action and params.
19
+ # Also tries to render the template.
20
+ # In Theory you can use this standalone, this has not been tested though.
21
+
22
+ def handle_request action, *params
23
+ controller = self.new
24
+ controller.instance_variable_set('@action', action)
25
+ result = controller.send(action, *params) if controller.respond_to?(action)
26
+
27
+ file = find_template(action)
28
+
29
+ template =
30
+ if file
31
+ File.read(file)
32
+ elsif result.respond_to? :to_str
33
+ result
34
+ end
35
+
36
+ return '' unless template
37
+
38
+ bound = result.is_a?(Binding) ? result : controller.send(:send, :binding)
39
+
40
+ controller.send(:transform, template, bound, file)
41
+ rescue Object => ex
42
+ puts ex
43
+ Informer.error ex
44
+ ''
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ # Transform any String via Erubis, takes an optional binding and filename
51
+
52
+ def transform string, bound = binding, file = nil
53
+ eruby = ::Erubis::Eruby.new(string)
54
+ eruby.init_evaluator(:filename => file) if file
55
+ eruby.result(bound)
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,65 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ require 'ramaze/template/haml/actionview_stub'
5
+ require 'haml/engine'
6
+
7
+ module Ramaze::Template
8
+ class Haml < Template
9
+
10
+ # Actions consist of both templates and methods on the controller.
11
+ trait :actionless => false
12
+
13
+ # Usual extensions for templates.
14
+ trait :template_extensions => %w[haml]
15
+
16
+ # Custom HAML-options for your controller to be merged.
17
+ trait :haml_options => {
18
+ :locals => {}
19
+ }
20
+
21
+ class << self
22
+
23
+ # initializes the handling of a request on the controller.
24
+ # Creates a new instances of itself and sends the action and params.
25
+ # Also tries to render the template.
26
+ # In Theory you can use this standalone, this has not been tested though.
27
+
28
+ def handle_request action, *params
29
+ controller = self.new
30
+ controller.instance_variable_set('@action', action)
31
+ result = controller.send(action, *params) if controller.respond_to?(action)
32
+
33
+ file = find_template(action)
34
+
35
+ template =
36
+ if file
37
+ File.read(file)
38
+ elsif result.respond_to? :to_str
39
+ result
40
+ end
41
+
42
+ return '' unless template
43
+
44
+ controller.send(:transform, template)
45
+ rescue Object => ex
46
+ puts ex
47
+ Informer.error ex
48
+ ''
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ # Transform any String via Haml, takes optionally an hash with the haml_options
55
+ # that you can set also by
56
+ # trait :haml_options => {}
57
+ # if you pass the options it will merge the trait with them. (your options
58
+ # override the defaults from trait[:haml_options]
59
+
60
+ def transform string, options = {}
61
+ haml = ::Haml::Engine.new(string, ancestral_trait[:haml_options].merge(options))
62
+ haml.to_html(self)
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,20 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ # stub, in case the requires for that active_* stuff of Haml doesn't fail
5
+ # but we are not running Rails ;)
6
+
7
+ module ActionView
8
+ class Base
9
+
10
+ # stub
11
+
12
+ def concat
13
+ end
14
+
15
+ # stub
16
+
17
+ def form_tag
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,74 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ require 'liquid'
5
+
6
+ module Ramaze::Template
7
+ class Liquid < Template
8
+ extend Ramaze::Helper
9
+
10
+ # Actions consist of both templates and methods on the controller.
11
+ trait :actionless => false
12
+
13
+ # Usual extensions for templates.
14
+ trait :template_extensions => %w[liquid]
15
+
16
+ # Custom options for Liquid to be merged for your controller.
17
+ trait :liquid_options => {}
18
+
19
+ class << self
20
+ # initializes the handling of a request on the controller.
21
+ # Creates a new instances of itself and sends the action and params.
22
+ # Also tries to render the template.
23
+ # In Theory you can use this standalone, this has not been tested though.
24
+
25
+ def handle_request action, *params
26
+ controller = self.new
27
+ controller.instance_variable_set('@action', action)
28
+ result = controller.send(action, *params) if controller.respond_to?(action)
29
+
30
+ file = find_template(action)
31
+
32
+ p file
33
+
34
+ template =
35
+ if file
36
+ File.read(file)
37
+ elsif result.respond_to? :to_str
38
+ result
39
+ end
40
+
41
+ return '' unless template
42
+
43
+ controller.send(:transform, template)
44
+ rescue Object => ex
45
+ puts ex
46
+ Informer.error ex
47
+ ''
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ # Transform any String via Liquid, takes an optional hash for the parameters
54
+ # transform("hi {{name}}", 'name' => 'tobi') # => "hi tobi"
55
+ #
56
+ # Usually you will just do this in the controller:
57
+ #
58
+ # class MainController < Template::Liquid
59
+ # def index
60
+ # @hash = {'name' => 'tobi'}
61
+ # end
62
+ # end
63
+ #
64
+ # And the templating will use @hash by default, setting it to {} if it is
65
+ # not set yet.
66
+
67
+ def transform string, hash = {}, options = {}
68
+ @hash ||= hash
69
+ template = ::Liquid::Template.parse(string)
70
+ options = ancestral_trait[:liquid_options].merge(options)
71
+ template.render(@hash, options)
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,68 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ require 'markaby'
5
+
6
+ module Ramaze::Template
7
+ class Markaby < Template
8
+ extend Ramaze::Helper
9
+
10
+ # Actions consist of both templates and methods on the controller.
11
+ trait :actionless => false
12
+
13
+ # Usual extensions for templates.
14
+ trait :template_extensions => %w[mab]
15
+
16
+ private
17
+
18
+ # use this inside your controller to directly build Markaby
19
+ # Refer to the Markaby-documentation and testsuite for more examples.
20
+ # Usage:
21
+ # mab { h1 "Apples & Oranges"} #=> "<h1>Apples &amp; Oranges</h1>"
22
+ # mab { h1 'Apples', :class => 'fruits&floots' } #=> "<h1 class=\"fruits&amp;floots\">Apples</h1>"
23
+
24
+ def mab(*args, &block)
25
+ builder = ::Markaby::Builder
26
+ builder.extend(Ramaze::Helper)
27
+ builder.send(:helper, :link)
28
+ builder.new(*args, &block).to_s
29
+ end
30
+
31
+ class << self
32
+
33
+ # Takes the action and parameter
34
+ # creates a new instance of itself, sets the @action instance-variable
35
+ # to the action just called, the sends the action and parameter further
36
+ # on to the instance (if the instance responds to the action)
37
+ #
38
+ # uses the #find_template method for the action to locate the template
39
+ # and uses the response from the template instead in case there is no
40
+ # template (and the response from the template responds to to_str)
41
+
42
+ def handle_request action, *params
43
+ controller = self.new
44
+ controller.instance_variable_set('@action', action)
45
+
46
+ result = controller.send(action, *params) if controller.respond_to?(action)
47
+ file = find_template(action)
48
+
49
+ mab = ::Markaby::Builder.new
50
+
51
+ template =
52
+ if file
53
+ ivs = {}
54
+ controller.instance_variables.each do |iv|
55
+ ivs[iv.gsub('@', '').to_sym] = controller.instance_variable_get(iv)
56
+ end
57
+ controller.send(:mab, ivs) do
58
+ instance_eval(File.read(file))
59
+ end
60
+ elsif result.respond_to? :to_str
61
+ result
62
+ end
63
+
64
+ template ? template : ''
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,177 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ require 'digest/sha1'
5
+ require 'ramaze/template/ramaze/element'
6
+ require 'ramaze/template/ramaze/morpher'
7
+
8
+ module Ramaze::Template
9
+
10
+ # The usual Template for use of Ramaze.
11
+ # It supports erb-style interpolation and a pipeline for the transform
12
+
13
+ class Ramaze < Template
14
+
15
+ # Actions consist of both templates and methods on the controller.
16
+ trait :actionless => false
17
+
18
+ # Usual extensions for templates.
19
+ trait :template_extensions => %w[rmze xhtml rhtml html]
20
+
21
+ # Each Object in this Array will be called :transform upon.
22
+ trait :transform_pipeline => [ Element, Morpher, self ]
23
+
24
+ class << self
25
+ # initializes the handling of a request on the controller.
26
+ # Creates a new instances of itself and sends the action and params.
27
+ # Also tries to render the template.
28
+ # In Theory you can use this standalone, this has not been tested though.
29
+
30
+ def handle_request(action, *params)
31
+ controller = self.new
32
+ controller.send(:render, action, *params)
33
+ end
34
+
35
+ # in case someone wants to call directly (pipeline)
36
+
37
+ def transform(template, bound)
38
+ self.new.send(:transform, template, bound)
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ # render an action
45
+ # this looks up the file depending on your Global.template_root
46
+ # and also takes the mapping of the controller in account.
47
+ # To use the exception of method_missing as flow-control might seem odd,
48
+ # but it works perfect for method_missing defined in the controller...
49
+ # otherwise one has to modify respond_to?... maybe add a special take-all method?
50
+ #
51
+ # for example:
52
+ # / => FooController, /main => MainController
53
+ # an action to /bar would search directly in the template_root for a file called bar
54
+ # and the extensions rmze, xhtml or html (in that order)
55
+ # if it finds a file it will transform it and return the result
56
+ # otherwise nothing happens
57
+ #
58
+ # TODO:
59
+ # - maybe add some way to define a custom template-file per action via traits
60
+ # trait :methodname_template => :foo
61
+ # would point to the template-file of action :foo - template_root/foo.ext
62
+ # - add extensive tests!
63
+ #
64
+
65
+ def render(action, *params)
66
+ alternate = render_template(params.last) if params.size == 1 and action == 'index'
67
+ file_template = render_template(action, *params)
68
+ ctrl_template = render_action(action, *params)
69
+
70
+ pipeline(alternate || file_template || ctrl_template)
71
+ end
72
+
73
+ # Render an action, usually a method on the controller.
74
+
75
+ def render_action(action, *params)
76
+ ctrl_template = send(action, *params).to_s
77
+ rescue => e
78
+ Informer.error e unless e.message =~ /undefined method `#{Regexp.escape(action.to_s)}'/
79
+
80
+ unless caller.select{|bt| bt[/`render_action'/]}.size > 3
81
+ Dispatcher.respond_action([action, *params].join('/'))
82
+ ctrl_template = response.out
83
+ end
84
+ end
85
+
86
+ # Render the template.
87
+
88
+ def render_template(action, *params)
89
+ File.read(find_template(action)) rescue nil
90
+ end
91
+
92
+ # go through the pipeline and call #transform on every object found there,
93
+ # passing the template at that point.
94
+ # the order and contents of the pipeline are determined by an array
95
+ # in trait[:template_pipeline]
96
+ # the default being [Element, Morpher, self]
97
+
98
+ def pipeline(template)
99
+ transform_pipeline = ancestral_trait[:transform_pipeline]
100
+
101
+ transform_pipeline.inject(template) do |memo, current|
102
+ current.transform(memo, binding)
103
+ end
104
+ end
105
+
106
+ # transform a String to a final xhtml
107
+ #
108
+ # All ye who seek magic, look elsewhere, this method is ASAP (as simple as possible)
109
+ #
110
+ # There are some simple gsubs that build a final template which is evaluated
111
+ #
112
+ # The rules are following:
113
+ # <?r rubycode ?>
114
+ # evaluate the code inside the tag, this is considered XHTML-valid and so is the
115
+ # preferred method for executing code inside your templates.
116
+ # The return-value is ignored
117
+ # <% rubycode %>
118
+ # The same as <?r ?>, ERB-style and not valid XHTML, but should give someone who
119
+ # is already familiar with ERB some common ground
120
+ # #{ rubycode }
121
+ # You know this from normal ruby already and it's actually nothing else.
122
+ # Interpolation at the position in the template, isn't any special taggy format
123
+ # and therefor safe to use.
124
+ # <%= rubycode %>
125
+ # The result of this will be interpolated at the position in the template.
126
+ # Not valid XHTML either.
127
+ #
128
+ # Warning:
129
+ # the variables used in here have the schema _variable_ to make it harder to break stuff
130
+ # however, you should take care.
131
+ # At the time of writing, the variables used are:
132
+ # _start_heredoc_, _end_heredoc_, _template_, _out_, _file_ and _bufadd_
133
+ # However, you may reuse _ivs_ if you desperatly need it and just can't live without.
134
+ #
135
+
136
+ def transform(_template_, _binding_ = binding)
137
+ _start_heredoc_ = "T" << Digest::SHA1.hexdigest(_template_)
138
+ _start_heredoc_, _end_heredoc_ = "\n<<#{_start_heredoc_}\n", "\n#{_start_heredoc_}\n"
139
+ _bufadd_ = "_out_ << "
140
+
141
+ _file_, _template_ = _template_, File.read(_template_) if File.file?(_template_)
142
+
143
+ _template_.gsub!(/<%\s+(.*?)\s+%>/m,
144
+ "#{_end_heredoc_} \\1; #{_bufadd_} #{_start_heredoc_}")
145
+ _template_.gsub!(/<\?r\s+(.*?)\s+\?>/m,
146
+ "#{_end_heredoc_} \\1; #{_bufadd_} #{_start_heredoc_}")
147
+
148
+ _template_.gsub!(/<%=\s+(.*?)\s+%>/m,
149
+ "#{_end_heredoc_} #{_bufadd_} (\\1); #{_bufadd_} #{_start_heredoc_}")
150
+
151
+
152
+ # this one should not be used until we find and solution
153
+ # that allows for stuff like
154
+ # #[@foo]!
155
+ # we just don't allow anything except space or newline
156
+ # after the expression #[] to make it sane
157
+ #_template_.gsub!(/#\[(.*?)\]\s*$/) do |m|
158
+ # "#{_end_heredoc_} #{_bufadd_} (#{$1}); #{_bufadd_} #{_start_heredoc_}"
159
+ #end
160
+
161
+ _template_ = [_bufadd_, _start_heredoc_, _template_, _end_heredoc_].join(' ')
162
+ _out_ = eval(*["_out_ = []; #{_template_}; _out_", _binding_, _file_].compact)
163
+
164
+ _out_.map! do |line|
165
+ line.to_s.chomp
166
+ end
167
+
168
+ _template_ = _out_.join.strip
169
+ rescue Object => ex
170
+ Informer.error "something bad happened while transformation"
171
+ Informer.error ex
172
+ #raise Error::Template, "Problem during transformation for: #{request.request_path}"
173
+ {ex.message => _template_}.inspect
174
+ end
175
+
176
+ end
177
+ end