rad_core 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (258) hide show
  1. data/Rakefile +10 -0
  2. data/lib/rad/controller/abstract_controller/micelaneous.rb +31 -0
  3. data/lib/rad/controller/abstract_controller/render.rb +160 -0
  4. data/lib/rad/controller/abstract_controller/responder.rb +17 -0
  5. data/lib/rad/controller/abstract_controller.rb +64 -0
  6. data/lib/rad/controller/controller_context.rb +15 -0
  7. data/lib/rad/controller/http_controller.rb +48 -0
  8. data/lib/rad/controller/processors/controller_caller.rb +28 -0
  9. data/lib/rad/controller/processors/controller_error_handling.rb +51 -0
  10. data/lib/rad/controller/processors/controller_logger.rb +12 -0
  11. data/lib/rad/controller.rb +28 -0
  12. data/lib/rad/conveyor/conveyor.rb +74 -0
  13. data/lib/rad/conveyor/conveyors.rb +20 -0
  14. data/lib/rad/conveyor/params.rb +14 -0
  15. data/lib/rad/conveyor/processor.rb +68 -0
  16. data/lib/rad/conveyor/processors/conveyor_logger.rb +25 -0
  17. data/lib/rad/conveyor/workspace.rb +36 -0
  18. data/lib/rad/conveyor.rb +29 -0
  19. data/lib/rad/environment/config.rb +111 -0
  20. data/lib/rad/environment/dependency_resolver.rb +107 -0
  21. data/lib/rad/environment/environment.rb +29 -0
  22. data/lib/rad/environment/files_helper.rb +55 -0
  23. data/lib/rad/environment/logger.rb +21 -0
  24. data/lib/rad/environment.rb +55 -0
  25. data/lib/rad/html/flash.rb +42 -0
  26. data/lib/rad/html/helpers/basic_html_helper.rb +83 -0
  27. data/lib/rad/html/helpers/flash_helper.rb +5 -0
  28. data/lib/rad/html/helpers/form_helper.rb +115 -0
  29. data/lib/rad/html/helpers/html_helper.rb +5 -0
  30. data/lib/rad/html/helpers/javascript_helper.rb +18 -0
  31. data/lib/rad/html/helpers/model_helper.rb +135 -0
  32. data/lib/rad/html/include_into_controller.rb +0 -0
  33. data/lib/rad/html/processors/prepare_flash.rb +26 -0
  34. data/lib/rad/html/processors/scoped_params.rb +26 -0
  35. data/lib/rad/html.rb +26 -0
  36. data/lib/rad/http/http.rb +21 -0
  37. data/lib/rad/http/http_adapter.rb +36 -0
  38. data/lib/rad/http/middleware/static_files.rb +21 -0
  39. data/lib/rad/http/processors/evaluate_format.rb +22 -0
  40. data/lib/rad/http/processors/http_logger.rb +15 -0
  41. data/lib/rad/http/processors/http_writer.rb +30 -0
  42. data/lib/rad/http/processors/prepare_params.rb +22 -0
  43. data/lib/rad/http/support/rack/fixes.rb +36 -0
  44. data/lib/rad/http/support/rack/rack_adapter.rb +67 -0
  45. data/lib/rad/http/support/rack/request.rb +42 -0
  46. data/lib/rad/http/support/rack/response.rb +86 -0
  47. data/lib/rad/http.rb +48 -0
  48. data/lib/rad/integration/controller_micelaneous_helper.rb +19 -0
  49. data/lib/rad/integration/router/abstract_routing_helper.rb +22 -0
  50. data/lib/rad/integration/router/controller_routing_helper.rb +58 -0
  51. data/lib/rad/integration/router/view_routing_helper.rb +104 -0
  52. data/lib/rad/integration.rb +30 -0
  53. data/lib/rad/mail/letter.rb +30 -0
  54. data/lib/rad/mail/mail_controller.rb +31 -0
  55. data/lib/rad/mail/mailer.rb +23 -0
  56. data/lib/rad/mail/processors/letter_builder.rb +36 -0
  57. data/lib/rad/mail.rb +15 -0
  58. data/lib/rad/profiles/mail.rb +16 -0
  59. data/lib/rad/profiles/web.rb +68 -0
  60. data/lib/rad/profiles/web_require.rb +5 -0
  61. data/lib/rad/remote/processors/remote_caller.rb +54 -0
  62. data/lib/rad/remote/processors/remote_logger.rb +13 -0
  63. data/lib/rad/remote/remote.rb +15 -0
  64. data/lib/rad/remote.rb +9 -0
  65. data/lib/rad/router/core/configurator.rb +25 -0
  66. data/lib/rad/router/core/core_routing_helper.rb +41 -0
  67. data/lib/rad/router/core/default_format_processor.rb +12 -0
  68. data/lib/rad/router/core/processors/router.rb +29 -0
  69. data/lib/rad/router/core/router.rb +271 -0
  70. data/lib/rad/router/core/simple_router.rb +23 -0
  71. data/lib/rad/router/routers/abstract_router.rb +62 -0
  72. data/lib/rad/router/routers/alias_router.rb +113 -0
  73. data/lib/rad/router/routers/restful_router.rb +113 -0
  74. data/lib/rad/router.rb +29 -0
  75. data/lib/rad/spec/controller.rb +41 -0
  76. data/lib/rad/spec/environment.rb +51 -0
  77. data/lib/rad/spec/http.rb +93 -0
  78. data/lib/rad/spec/mail.rb +31 -0
  79. data/lib/rad/spec/remote.rb +9 -0
  80. data/lib/rad/spec/router.rb +18 -0
  81. data/lib/rad/spec/template.rb +12 -0
  82. data/lib/rad/spec/view.rb +10 -0
  83. data/lib/rad/spec/xhtml.rb +33 -0
  84. data/lib/rad/spec.rb +11 -0
  85. data/lib/rad/support/active_support/locales/en/actionpack.yml +154 -0
  86. data/lib/rad/support/active_support/locales/en/activesupport.yml +36 -0
  87. data/lib/rad/support/active_support/micelaneous.rb +2 -0
  88. data/lib/rad/support/active_support/time.rb +105 -0
  89. data/lib/rad/support/active_support.rb +49 -0
  90. data/lib/rad/support/addressable.rb +45 -0
  91. data/lib/rad/support/buffered_logger.rb +44 -0
  92. data/lib/rad/support/callbacks.rb +168 -0
  93. data/lib/rad/support/exception.rb +31 -0
  94. data/lib/rad/support/filters.rb +34 -0
  95. data/lib/rad/support/format.rb +17 -0
  96. data/lib/rad/support/hacks_and_fixes.rb +23 -0
  97. data/lib/rad/support/micon.rb +13 -0
  98. data/lib/rad/support/mime.rb +13 -0
  99. data/lib/rad/support/module.rb +48 -0
  100. data/lib/rad/support/rson.rb +53 -0
  101. data/lib/rad/support/ruby_ext_with_active_support.rb +4 -0
  102. data/lib/rad/support/string.rb +26 -0
  103. data/lib/rad/support.rb +63 -0
  104. data/lib/rad/template/support/tilt.rb +68 -0
  105. data/lib/rad/template/support/tilt_fixes.rb +17 -0
  106. data/lib/rad/template/template.rb +250 -0
  107. data/lib/rad/template/template_context.rb +62 -0
  108. data/lib/rad/template.rb +25 -0
  109. data/lib/rad_core/gems.rb +31 -0
  110. data/readme.md +33 -0
  111. data/spec/controller/abstract_controller_spec/views/OperationsOrderSpec/action.erb +1 -0
  112. data/spec/controller/abstract_controller_spec/views/ViewVariablesSpec/action.erb +11 -0
  113. data/spec/controller/abstract_controller_spec.rb +132 -0
  114. data/spec/controller/controller_context_spec/views/ItemSpec/actions.erb +4 -0
  115. data/spec/controller/controller_context_spec/views/ItemSpec/show.erb +0 -0
  116. data/spec/controller/controller_context_spec/views/ItemSpec/update.erb +0 -0
  117. data/spec/controller/controller_context_spec/views/NamespaceSpec/ClassSpec/show.erb +0 -0
  118. data/spec/controller/controller_context_spec/views/PageSpec/actions.erb +3 -0
  119. data/spec/controller/controller_context_spec/views/PageSpec/show.erb +0 -0
  120. data/spec/controller/controller_context_spec/views/namespace_spec/class_spec/update.erb +0 -0
  121. data/spec/controller/controller_context_spec.rb +123 -0
  122. data/spec/controller/controller_helper_spec/views/HelperMethodSpec/action.erb +1 -0
  123. data/spec/controller/controller_helper_spec/views/HelperSpec/action.erb +1 -0
  124. data/spec/controller/controller_helper_spec.rb +53 -0
  125. data/spec/controller/controller_render_spec/views/AlreadyRenderedSpec/action.erb +1 -0
  126. data/spec/controller/controller_render_spec/views/AlreadyRenderedSpec/custom_template.erb +1 -0
  127. data/spec/controller/controller_render_spec/views/AnotherActionSpec/another_action.erb +1 -0
  128. data/spec/controller/controller_render_spec/views/AnotherLayout/action.erb +1 -0
  129. data/spec/controller/controller_render_spec/views/ForbidPartialAsActionSpec/_action.erb +1 -0
  130. data/spec/controller/controller_render_spec/views/FormatSpec/action.html.erb +1 -0
  131. data/spec/controller/controller_render_spec/views/FormatSpec/action.js.erb +1 -0
  132. data/spec/controller/controller_render_spec/views/LayoutFiltersSpec/action_with_layout.erb +1 -0
  133. data/spec/controller/controller_render_spec/views/LayoutFiltersSpec/action_without_layout.erb +1 -0
  134. data/spec/controller/controller_render_spec/views/LayoutSpec/action.erb +1 -0
  135. data/spec/controller/controller_render_spec/views/MultipleActions/actions.haml +7 -0
  136. data/spec/controller/controller_render_spec/views/layouts/admin.erb +1 -0
  137. data/spec/controller/controller_render_spec/views/layouts/app.html.erb +1 -0
  138. data/spec/controller/controller_render_spec/views/layouts/app.js.erb +1 -0
  139. data/spec/controller/controller_render_spec/views/rem ExplicitRenderSpec/action.erb +1 -0
  140. data/spec/controller/controller_render_spec/views/rem ExplicitRenderSpec/another_action.erb +1 -0
  141. data/spec/controller/controller_render_spec/views/some_template.erb +1 -0
  142. data/spec/controller/controller_render_spec/views/standalone.html.erb +1 -0
  143. data/spec/controller/controller_render_spec.rb +217 -0
  144. data/spec/controller/error_handling_spec/views/diferrent_error_handling_spec/a.erb +1 -0
  145. data/spec/controller/error_handling_spec/views/diferrent_error_handling_spec/b.erb +1 -0
  146. data/spec/controller/error_handling_spec/views/diferrent_error_handling_spec/c.erb +1 -0
  147. data/spec/controller/error_handling_spec.rb +117 -0
  148. data/spec/controller/http_controller_spec.rb +130 -0
  149. data/spec/controller/spec_helper.rb +19 -0
  150. data/spec/conveyor/conveyor_spec.rb +124 -0
  151. data/spec/conveyor/spec_helper.rb +3 -0
  152. data/spec/environment/config_spec/config.default.yml +3 -0
  153. data/spec/environment/config_spec/config.development.yml +3 -0
  154. data/spec/environment/config_spec/config.yml +5 -0
  155. data/spec/environment/config_spec.rb +30 -0
  156. data/spec/environment/environment_spec/path1/file1 +0 -0
  157. data/spec/environment/environment_spec/path1/some_folder/some_file +0 -0
  158. data/spec/environment/environment_spec/path2/file2 +0 -0
  159. data/spec/environment/environment_spec/path2/some_folder/some_file +0 -0
  160. data/spec/environment/environment_spec.rb +65 -0
  161. data/spec/environment/logger_spec.rb +19 -0
  162. data/spec/environment/minimal_app_spec/app.rb +1 -0
  163. data/spec/environment/minimal_app_spec.rb +25 -0
  164. data/spec/environment/spec_helper.rb +1 -0
  165. data/spec/environment/standard_app_spec/app/lib/app/init.rb +3 -0
  166. data/spec/environment/standard_app_spec/plugin_a/lib/plugin_a/init.rb +1 -0
  167. data/spec/environment/standard_app_spec/plugin_b/lib/emptygit +0 -0
  168. data/spec/environment/standard_app_spec.rb +48 -0
  169. data/spec/html/basic_html_helper_spec.rb +29 -0
  170. data/spec/html/form_helper_spec.rb +63 -0
  171. data/spec/html/javascript_helper_spec.rb +15 -0
  172. data/spec/html/model_helper_spec.rb +81 -0
  173. data/spec/html/scoped_params_spec.rb +15 -0
  174. data/spec/html/spec_helper.rb +28 -0
  175. data/spec/http/http_spec/app/lib/app/init.rb +10 -0
  176. data/spec/http/http_spec/app/runtime/public/emptygit +0 -0
  177. data/spec/http/http_spec/plugin_a/lib/plugin_a/init.rb +0 -0
  178. data/spec/http/http_spec/plugin_b/lib/plugin_b/init.rb +5 -0
  179. data/spec/http/http_spec/plugin_b/static/emptygit +0 -0
  180. data/spec/http/http_spec.rb +51 -0
  181. data/spec/http/micelaneous_spec.rb +13 -0
  182. data/spec/http/spec_helper.rb +5 -0
  183. data/spec/integration/basic_spec/views/smoke_test_spec/action.erb +1 -0
  184. data/spec/integration/basic_spec.rb +79 -0
  185. data/spec/integration/controller_routing_helper_spec.rb +84 -0
  186. data/spec/integration/flash_spec.rb +206 -0
  187. data/spec/integration/spec_helper.rb +5 -0
  188. data/spec/integration/spec_helper_spec.rb +63 -0
  189. data/spec/integration/view_routing_helper_spec.rb +134 -0
  190. data/spec/mail/mail_controller_spec/views/body_template_spec/signup.erb +1 -0
  191. data/spec/mail/mail_controller_spec.rb +61 -0
  192. data/spec/mail/spec_helper.rb +7 -0
  193. data/spec/remote/remote_spec.rb +75 -0
  194. data/spec/remote/spec_helper.rb +17 -0
  195. data/spec/router/alias_router_spec.rb +98 -0
  196. data/spec/router/basic_spec.rb +111 -0
  197. data/spec/router/configurator_spec.rb +18 -0
  198. data/spec/router/integration_spec.rb +42 -0
  199. data/spec/router/persistent_params_spec.rb +65 -0
  200. data/spec/router/restful_router_spec.rb +120 -0
  201. data/spec/router/routing_helper_spec.rb +55 -0
  202. data/spec/router/spec_helper.rb +20 -0
  203. data/spec/support/callbacks_spec.rb +157 -0
  204. data/spec/support/filters_spec.rb +60 -0
  205. data/spec/support/spec_helper.rb +4 -0
  206. data/spec/template/spec_helper.rb +6 -0
  207. data/spec/template/template_spec/file.erb +1 -0
  208. data/spec/template/template_spec/views/basic/custom_context.erb +1 -0
  209. data/spec/template/template_spec/views/basic/extension.erb +1 -0
  210. data/spec/template/template_spec/views/basic/general.html.erb +5 -0
  211. data/spec/template/template_spec/views/basic/non_existing_format.html.erb +0 -0
  212. data/spec/template/template_spec/views/format/format.erb +1 -0
  213. data/spec/template/template_spec/views/format/format.html.erb +1 -0
  214. data/spec/template/template_spec/views/format/format.js.erb +1 -0
  215. data/spec/template/template_spec/views/format_for_partials/_form.html.erb +1 -0
  216. data/spec/template/template_spec/views/format_for_partials/dialog.js.erb +1 -0
  217. data/spec/template/template_spec/views/layout/basic/content.erb +1 -0
  218. data/spec/template/template_spec/views/layout/basic/layout.erb +1 -0
  219. data/spec/template/template_spec/views/layout/content_for/content.erb +3 -0
  220. data/spec/template/template_spec/views/layout/content_for/layout.erb +3 -0
  221. data/spec/template/template_spec/views/layout/format/content.html.erb +1 -0
  222. data/spec/template/template_spec/views/layout/format/content.js.erb +1 -0
  223. data/spec/template/template_spec/views/layout/format/layout.html.erb +1 -0
  224. data/spec/template/template_spec/views/layout/format/layout.js.erb +1 -0
  225. data/spec/template/template_spec/views/layout/nested_yield/a.erb +1 -0
  226. data/spec/template/template_spec/views/layout/nested_yield/layout.erb +1 -0
  227. data/spec/template/template_spec/views/layout/nested_yield/layout_b.erb +1 -0
  228. data/spec/template/template_spec/views/layout/same_context/a.erb +1 -0
  229. data/spec/template/template_spec/views/layout/same_context/b.erb +1 -0
  230. data/spec/template/template_spec/views/layout/same_context/layout.erb +1 -0
  231. data/spec/template/template_spec/views/nested/format/a.erb +1 -0
  232. data/spec/template/template_spec/views/nested/format/b.erb +1 -0
  233. data/spec/template/template_spec/views/nested/relative/a.erb +1 -0
  234. data/spec/template/template_spec/views/nested/relative/b.erb +1 -0
  235. data/spec/template/template_spec/views/nested/relative/c.erb +1 -0
  236. data/spec/template/template_spec/views/nested/shared/c.erb +1 -0
  237. data/spec/template/template_spec/views/nesting_format/_edit.html.erb +1 -0
  238. data/spec/template/template_spec/views/nesting_format/_form.html.erb +1 -0
  239. data/spec/template/template_spec/views/nesting_format/dialog.js.erb +1 -0
  240. data/spec/template/template_spec/views/other/template.erb +1 -0
  241. data/spec/template/template_spec/views/prefixes/_underscored.erb +1 -0
  242. data/spec/template/template_spec/views/prefixes/without_prefix.erb +1 -0
  243. data/spec/template/template_spec.rb +204 -0
  244. data/spec/template/tilt_spec/views/concat_and_capture.erb +1 -0
  245. data/spec/template/tilt_spec/views/concat_and_capture.haml +3 -0
  246. data/spec/template/tilt_spec/views/encoding/erb.erb +1 -0
  247. data/spec/template/tilt_spec/views/encoding/haml.haml +1 -0
  248. data/spec/template/tilt_spec/views/errors.erb +3 -0
  249. data/spec/template/tilt_spec/views/errors.haml +3 -0
  250. data/spec/template/tilt_spec/views/mixed_templates/broken_erb_concat_erb.erb +4 -0
  251. data/spec/template/tilt_spec/views/mixed_templates/broken_erb_concat_haml.haml +1 -0
  252. data/spec/template/tilt_spec/views/mixed_templates/broken_haml_concat_erb.erb +1 -0
  253. data/spec/template/tilt_spec/views/mixed_templates/broken_haml_concat_haml.haml +2 -0
  254. data/spec/template/tilt_spec/views/nested_capture_and_concat.haml +3 -0
  255. data/spec/template/tilt_spec/views/ugly.haml +3 -0
  256. data/spec/template/tilt_spec/views/yield.erb +1 -0
  257. data/spec/template/tilt_spec.rb +98 -0
  258. metadata +531 -0
@@ -0,0 +1,250 @@
1
+ module Rad
2
+ module Template
3
+ # DIRECTORY_NAME = "/views"
4
+ DIRECTORY_NAME = ""
5
+
6
+ class << self
7
+ def paths; @paths ||= [] end
8
+
9
+ inject(
10
+ logger: :logger,
11
+ config: :config,
12
+ environment: :environment
13
+ )
14
+
15
+ def render *args, &block
16
+ result, context = basic_render(parse_arguments(*args), &block)
17
+ result
18
+ end
19
+
20
+ # def render_and_return_context *args, &block
21
+ # basic_render(*parse_arguments(*args), &block)
22
+ # end
23
+
24
+ def render_layout *args
25
+ options = parse_arguments(*args)
26
+ options.must.include :content
27
+ options.must.include :context
28
+
29
+ result, context = basic_render options do |*args|
30
+ if args.empty?
31
+ options.content
32
+ else
33
+ args.size.must_be == 1
34
+ variable_name = args.first.to_s
35
+ self.context.content_variables[variable_name]
36
+ end
37
+ end
38
+
39
+ result
40
+ end
41
+
42
+ def exist? tname, options = {}
43
+ options = options.to_openobject
44
+ !!find_template(tname, calculate_prefixes(options), options.format, exact_format?(options), options.current_dir)
45
+ end
46
+
47
+ def read tname, options = {}
48
+ options = options.to_openobject
49
+ file = find_template tname, calculate_prefixes(options), options.format, exact_format?(options), options.current_dir
50
+ raise "No template '#{tname}'!" unless file
51
+ File.read file
52
+ end
53
+
54
+ def template_name_with_prefix tname, prefix
55
+ index = tname.rindex('/')
56
+ index = index ? index + 1 : 0
57
+ tname = tname.clone
58
+ tname.insert index, prefix
59
+ end
60
+
61
+ def parse_arguments *args
62
+ options = args.extract_options!.to_openobject
63
+ if args.size == 1
64
+ options.template = args.first
65
+ else
66
+ raise "Invalid input" if args.size != 0
67
+ end
68
+
69
+ options
70
+ end
71
+
72
+ def basic_render options, &block
73
+ options = options.clone.to_openobject
74
+
75
+ with_context options do |context|
76
+ context.content_block ||= block
77
+
78
+ with_scope options, context do |scope|
79
+ unless file = options.file
80
+ file = find_template options.template!, calculate_prefixes(options), scope.format, exact_format?(options), scope.current_dir
81
+ raise "No template '#{options.template!}'!" unless file
82
+ end
83
+
84
+ scope.current_dir = dirname(file)
85
+
86
+ template = create_tilt_template file
87
+
88
+ result = with_template context, template do
89
+ render_template template, options, &context.content_block
90
+ end
91
+
92
+ return result, context
93
+ end
94
+ end
95
+ end
96
+
97
+ protected
98
+ def context
99
+ Thread.current[:render_context]
100
+ end
101
+
102
+ def calculate_prefixes options
103
+ options.action ? [''] : options.prefixes
104
+ end
105
+
106
+ def exact_format? options
107
+ options.action? || options.exact_format?
108
+ end
109
+
110
+ def with_context options, &block
111
+ context = Thread.current[:render_context] || options.context || create_context(options)
112
+
113
+ old = Thread.current[:render_context]
114
+ begin
115
+ Thread.current[:render_context] = context
116
+ block.call context
117
+ ensure
118
+ Thread.current[:render_context] = old
119
+ end
120
+ end
121
+
122
+ def with_scope options, context, &block
123
+ initial = context.scope_variables
124
+
125
+ old = context.scope_variables || OpenObject.new
126
+ begin
127
+ context.scope_variables = {
128
+ current_dir: (options.current_dir || old.current_dir),
129
+ format: (options.format || old.format)
130
+ # prefixes: options.prefixes || old.prefixes
131
+ }.to_openobject
132
+
133
+ block.call context.scope_variables
134
+ ensure
135
+ context.scope_variables = old if initial
136
+ end
137
+ end
138
+
139
+ def with_template context, template, &block
140
+ old = context._tilt_template
141
+ begin
142
+ context._tilt_template = template
143
+ block.call context
144
+ ensure
145
+ context._tilt_template = old
146
+ end
147
+ end
148
+
149
+ def create_context options
150
+ context_class = options.context_class || TemplateContext
151
+ raise "#{context_class} must inherit from TemplateContext!" unless context_class.is? TemplateContext
152
+ context = context_class.new
153
+
154
+ context.options = options
155
+
156
+ if ivs = options.instance_variables
157
+ (ivs.is_a?(Array) ? ivs : [ivs]).each do |container|
158
+ if container.is_a? Hash
159
+ container.each do |name, value|
160
+ context.instance_variable_set("@#{name}", value)
161
+ end
162
+ else
163
+ container.instance_variables.each do |ivname|
164
+ iv = container.instance_variable_get(ivname)
165
+ context.instance_variable_set(ivname, iv)
166
+ end
167
+ end
168
+ end
169
+ end
170
+
171
+ context
172
+ end
173
+
174
+ def dirname path;
175
+ File.dirname path
176
+ end
177
+ cache_method_with_params_in_production :dirname
178
+
179
+ def find_template tname, prefixes, format, exact_format, current_dir
180
+ tname.must_be.a String
181
+ # splitted into two to optimize cache
182
+ if tname =~ /^\//
183
+ find_absolute_template tname, prefixes, format, exact_format
184
+ else
185
+ find_relative_template tname, prefixes, format, exact_format, current_dir
186
+ end
187
+ end
188
+
189
+ def find_absolute_template tname, prefixes, format, exact_format
190
+ prefixes = prefixes || config.default_template_prefixes!
191
+ prefixes.each do |prefix|
192
+ tname_with_prefix = template_name_with_prefix("#{DIRECTORY_NAME}#{tname}", prefix)
193
+ file = find_file(tname_with_prefix, format, exact_format, paths) #environment.directories)
194
+ return file if file
195
+ end
196
+ return nil
197
+ end
198
+ cache_method_with_params_in_production :find_absolute_template
199
+
200
+ def find_relative_template tname, prefixes, format, exact_format, current_dir
201
+ raise "You can't use relative template path '#{tname}' without :current_dir!" unless current_dir
202
+ prefixes = prefixes || config.default_template_prefixes!
203
+ prefixes.each do |prefix|
204
+ tname_with_prefix = template_name_with_prefix("/#{tname}", prefix)
205
+ file = find_file(tname_with_prefix, format, exact_format, [current_dir])
206
+ return file if file
207
+ end
208
+ return nil
209
+ end
210
+ cache_method_with_params_in_production :find_relative_template
211
+
212
+ def find_file tname, format, exact_format, directories
213
+ if tname.include? '.'
214
+ _find_file(tname, directories) || _find_file("#{tname}.*", directories)
215
+ else
216
+ if format
217
+ _find_file("#{tname}.#{format}.*", directories) or
218
+ _find_file("#{tname}.*", directories, exact_format)
219
+ else
220
+ _find_file("#{tname}.*", directories)
221
+ end
222
+ end
223
+ end
224
+
225
+ # with_one_extension - 'tname.*' matches not only 'tname.erb' but also 'tname.html.erb',
226
+ # with this option enabled it will not match 'tname.html.erb', only 'tname.erb'
227
+ def _find_file pattern, directories, with_one_extension = false
228
+ files = environment.find_files_by_pattern_without_cache pattern, directories
229
+ files = files.select{|f| f !~ /\.[^\.\/]+\.[^\.\/]+$/} if with_one_extension
230
+ raise "multiple templates for '#{pattern}'!" if files.size > 1
231
+ files.first
232
+ end
233
+
234
+ def create_tilt_template path
235
+ template_options = {
236
+ ugly: true,
237
+ outvar: "@output"
238
+ }
239
+ template = Tilt.new(path, nil, template_options){|t| File.read(t.file)}
240
+ end
241
+
242
+ def render_template template, options, &block
243
+ locals = options.locals || {}
244
+ locals[:object] = options.object if options.object?
245
+
246
+ template.render context, locals, &block
247
+ end
248
+ end
249
+ end
250
+ end
@@ -0,0 +1,62 @@
1
+ module Rad
2
+ class TemplateContext
3
+ include Tilt::CompileSite, Tilt::ContextExt
4
+
5
+ #
6
+ # System
7
+ #
8
+ attr_accessor :options, :_tilt_template
9
+
10
+ # for saving :format, :current_dir and others
11
+ # def scope_variables; @scope_variables ||= OpenObject.new end
12
+ attr_accessor :scope_variables
13
+
14
+
15
+ #
16
+ # Helpers
17
+ #
18
+ inject(
19
+ workspace: :workspace,
20
+ router: :router,
21
+ config: :config
22
+ )
23
+
24
+ delegate :render, to: ::Rad::Template
25
+ delegate :url_for, to: :router
26
+
27
+
28
+ def j obj
29
+ obj.to_s.json_escape
30
+ end
31
+
32
+
33
+ #
34
+ # Content Variables
35
+ #
36
+ attr_accessor :content_block
37
+ def content_variables; @content_variables ||= {}.to_openobject end
38
+ def content_for name, content = nil, &block
39
+ content ||= capture(&block)
40
+ (content_variables[name.to_s] ||= "") << content
41
+ nil
42
+ end
43
+ def prepend_to name, content = nil, &block
44
+ content ||= capture(&block)
45
+ (content_variables[name.to_s] ||= "").insert 0, content
46
+ nil
47
+ end
48
+ def wrap_content_for name, &block
49
+ block.must_be.defined
50
+ content = capture((content_variables[name.to_s] || ""), &block)
51
+ content_variables[name.to_s] ||= content
52
+ nil
53
+ end
54
+ def has_content_for? name
55
+ content_variables.include? name.to_s
56
+ end
57
+
58
+ def params
59
+ workspace.params
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,25 @@
1
+ gem "haml"
2
+
3
+ require 'rad/environment'
4
+
5
+ require 'erb'
6
+ require 'haml'
7
+ require 'tilt'
8
+ require 'rad/template/support/tilt'
9
+ require 'rad/template/support/tilt_fixes'
10
+
11
+ [
12
+ 'template',
13
+ 'template_context'
14
+ ].each{|f| require "rad/template/#{f}"}
15
+
16
+ rad_core_dir = "#{__FILE__}/../../../..".dirname
17
+ Rad::Template.paths << "#{rad_core_dir}/views"
18
+
19
+
20
+ #
21
+ # Initialization
22
+ #
23
+ Rad::Config::DEFAULTS.merge!(
24
+ default_template_prefixes: ['', '_']
25
+ )
@@ -0,0 +1,31 @@
1
+ # core gems dependencies
2
+ gem 'i18n', '0.5.0'
3
+ gem 'treetop', '1.4.9'
4
+ gem 'polyglot', '0.3.1'
5
+ gem 'mime-types', '1.16'
6
+
7
+ # core gems
8
+ gem 'activesupport', '3.0.3'
9
+ gem 'builder', '2.1.2'
10
+
11
+ gem 'haml', '3.0.25'
12
+ gem 'tilt', '1.2.1'
13
+
14
+ gem 'json', '1.4.6'
15
+ gem 'addressable', '2.2.2'
16
+ gem 'nokogiri', '1.4.4'
17
+ gem 'rack', '1.2.1'
18
+
19
+ gem 'dictionary', '1.0.0'
20
+
21
+ gem 'rack', '1.2.1'
22
+ gem 'thin', '1.2.7'
23
+
24
+ gem 'mail', '2.2.14'
25
+
26
+ if respond_to? :fake_gem
27
+ fake_gem 'ruby_ext'
28
+ fake_gem 'vfs'
29
+ fake_gem 'micon'
30
+ fake_gem 'class_loader'
31
+ end
data/readme.md ADDED
@@ -0,0 +1,33 @@
1
+ # Rad - Ruby Web Framework inspired by Rails and Spring.
2
+
3
+ It kinda does the same thing as Rails but in different way. The idea is to provide you with an application framework as opened and extensible as the Ruby itself.
4
+
5
+ It's the constructor, built from set of low coupled components. You can start quickly using one of predefined 'opinionated' profiles, or tune and extend it as you wish.
6
+ The same apply for the architecture of your application - instead of to be a monolith it consists of cooperating plugins/gems.
7
+
8
+ Web tier looks almost like Rails and overall architecture is slightly borrowed from Java Spring framework.
9
+ Yes, I know that IoC aren't much popular in Ruby community, but it's not quite ordinary IoC, and it's really handy.
10
+
11
+ *It's under heavy development, and not ready to use.*
12
+
13
+ ## Why did I make another Rails?
14
+ There are many things that I like in Rails:
15
+
16
+ - high productivity
17
+ - simplicity, agility and iterative development
18
+ - excellent and very usefull ruby extensions
19
+ - nice and very handy API and naming conventions
20
+ - no config and fast start with leaning learning curve
21
+
22
+ But, there are some problems
23
+
24
+ - there's only one way - The Rails Way, it's all simple and cool when you are on this way. But if you wanna to step aside and do it in Your way - you'll get big problems, so big that they are almost completely eliminates all the goodness.
25
+ - very hard to extend and customize
26
+ - you forced to build monolithic applications, it's hard to build application as set of modules.
27
+ - weak support of object oriented paradigm, there's really no true inheritance in Controller and Routing scheme.
28
+ - hard to build distributed applications.
29
+
30
+ With Rad I tried to save all the goodness and use API as closed to Rails as possible but also give the developer freedom to choose it's own way and also solve those important problems.
31
+
32
+ ## TODO
33
+ - add link_to! and some_path! to preserve state
@@ -0,0 +1 @@
1
+ <% OperationsOrderSpec.result << :template %>
@@ -0,0 +1,11 @@
1
+ controller: <%= workspace.controller.class.name %>
2
+ controller_name: <%= controller_name %>
3
+
4
+ class: <%= workspace.class.name %>
5
+ method_name: <%= workspace.method_name %>
6
+ action: <%= action_name %>
7
+
8
+ instance_variable: <%= @instance_variable %>
9
+
10
+ params: <%= params.param %>
11
+ format: <%= params.format %>
@@ -0,0 +1,132 @@
1
+ require "controller/spec_helper"
2
+
3
+ describe "AbstractController" do
4
+ with_environment
5
+ with_abstract_controller_spec
6
+ with_view_path "#{spec_dir}/views"
7
+
8
+ before :all do
9
+ AbstractController = Rad::AbstractController
10
+ end
11
+
12
+ after :all do
13
+ remove_constants %w(
14
+ WorkspaceVariablesSpec
15
+ SpecialResultSpec
16
+ RespondToSpec
17
+ ViewVariablesSpec
18
+ OperationsOrderSpec
19
+ NoTemplateSpec
20
+ AbstractController
21
+ )
22
+ end
23
+
24
+ it "should set workspace variables" do
25
+ class ::WorkspaceVariablesSpec
26
+ inherit AbstractController
27
+
28
+ def action; end
29
+ end
30
+
31
+ ccall WorkspaceVariablesSpec, :action
32
+
33
+ workspace.controller.should be_a(WorkspaceVariablesSpec)
34
+ workspace.response.should respond_to("body=")
35
+
36
+ expected_result = {
37
+ params: {},
38
+
39
+ class: WorkspaceVariablesSpec,
40
+ method_name: :action,
41
+ action: :action
42
+ }
43
+ workspace.to_h(true).subset(expected_result.keys).should == expected_result
44
+ end
45
+
46
+ it "should be able to throw :halt_render in controller or view and that result must be assigned as result" do
47
+ class ::SpecialResultSpec
48
+ inherit AbstractController
49
+ def action
50
+ throw :halt_render, 'some content'
51
+ end
52
+ end
53
+
54
+ ccall(SpecialResultSpec, :action).should == "some content"
55
+ end
56
+
57
+ it "respond_to" do
58
+ class ::RespondToSpec
59
+ inherit AbstractController
60
+
61
+ def action
62
+ respond_to do |format|
63
+ format.html{render inline: 'html'}
64
+ format.json{render json: {a: 'b'}}
65
+ end
66
+ end
67
+ end
68
+
69
+ ccall(RespondToSpec, :action, format: 'html').should == 'html'
70
+ ccall(RespondToSpec, :action, format: 'json').should == %({"a":"b"})
71
+ lambda{ccall(RespondToSpec, :action, format: 'js')}.should raise_error(/can't respond to 'js' format/)
72
+ end
73
+
74
+ it "controller's instance variables must be available in view, and also other variables" do
75
+ class ::ViewVariablesSpec
76
+ inherit AbstractController
77
+
78
+ def action
79
+ @instance_variable = "iv value"
80
+ end
81
+ end
82
+
83
+ ccall(ViewVariablesSpec, :action, param: 'param value', format: 'html').should == %(\
84
+ controller: ViewVariablesSpec
85
+ controller_name: ViewVariablesSpec
86
+
87
+ class: ViewVariablesSpec
88
+ method_name: action
89
+ action: action
90
+
91
+ instance_variable: iv value
92
+
93
+ params: param value
94
+ format: html)
95
+ end
96
+
97
+ it "operations order" do
98
+ class ::OperationsOrderSpec
99
+ inherit AbstractController
100
+
101
+ def self.result
102
+ @result ||= []
103
+ end
104
+
105
+ around do |controller, block|
106
+ begin
107
+ OperationsOrderSpec.result << :before
108
+ block.call
109
+ ensure
110
+ OperationsOrderSpec.result << :after
111
+ end
112
+ end
113
+
114
+ def action
115
+ OperationsOrderSpec.result << :action
116
+ end
117
+ end
118
+
119
+ ccall(OperationsOrderSpec, :action)
120
+ OperationsOrderSpec.result.should == [:before, :action, :template, :after]
121
+ end
122
+
123
+ it "should write empty response if no template for action" do
124
+ class NoTemplateSpec
125
+ inherit AbstractController
126
+
127
+ def action; end
128
+ end
129
+
130
+ ccall(NoTemplateSpec, :action).should == ""
131
+ end
132
+ end
@@ -0,0 +1,4 @@
1
+ <% case value %>
2
+ <% when :increase %>
3
+ <% when :decrease %>
4
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <% case value %>
2
+ <% when :decrease %>
3
+ <% end %>
@@ -0,0 +1,123 @@
1
+ require "controller/spec_helper"
2
+
3
+ describe "ControllerContext" do
4
+ with_environment environment: :development
5
+ with_view_path "#{spec_dir}/views"
6
+
7
+ before :all do
8
+ AbstractController = Rad::AbstractController
9
+
10
+ class ItemSpec
11
+ inherit AbstractController
12
+
13
+ def show; end
14
+ def update; end
15
+ def delete; end
16
+ def increase; end
17
+ def decrease; end
18
+ end
19
+
20
+ class PageSpec < ItemSpec
21
+ def show; end
22
+ def increase; end
23
+ end
24
+
25
+ module NamespaceSpec
26
+ class ClassSpec
27
+ inherit AbstractController
28
+
29
+ def show; end
30
+ def update; end
31
+ end
32
+ end
33
+ end
34
+
35
+ after :all do
36
+ remove_constants %w(
37
+ ItemSpec
38
+ PageSpec
39
+ NamespaceSpec
40
+ ItemSpecHelper
41
+ PageSpecHelper
42
+ AbstractController
43
+ )
44
+ end
45
+
46
+ describe "basic" do
47
+ it "should provide template name for non-existing template" do
48
+ ItemSpec.template_name_for(:delete).should == "/ItemSpec/delete"
49
+ PageSpec.template_name_for(:delete).should == "/ItemSpec/delete"
50
+ end
51
+
52
+ it "should provide template name for existing template" do
53
+ ItemSpec.template_name_for(:update).should == "/ItemSpec/update"
54
+ end
55
+
56
+ it "should inherit template name for template existing in parent" do
57
+ PageSpec.template_name_for(:update).should == "/ItemSpec/update"
58
+ end
59
+
60
+ it "should override template name for template existing in both self and parent" do
61
+ ItemSpec.template_name_for(:show).should == "/ItemSpec/show"
62
+ PageSpec.template_name_for(:show).should == "/PageSpec/show"
63
+ end
64
+
65
+ it "should transfer namespaces into folders" do
66
+ NamespaceSpec::ClassSpec.template_name_for(:show).should == "/NamespaceSpec/ClassSpec/show"
67
+ end
68
+ end
69
+
70
+ describe "actions" do
71
+ it "should be able to check for action inside of actions.xxx files" do
72
+ ItemSpec.template_name_for(:increase).should == "/ItemSpec/actions"
73
+ end
74
+
75
+ it "should be able to check for action inside of actions.xxx files" do
76
+ ItemSpec.template_name_for(:increase).should == "/ItemSpec/actions"
77
+ ItemSpec.template_name_for(:decrease).should == "/ItemSpec/actions"
78
+ ItemSpec.template_name_for(:action_not_defined_inside_of_actions_file).should == "/ItemSpec/action_not_defined_inside_of_actions_file"
79
+ end
80
+
81
+ it "should inherit actions.xxx" do
82
+ PageSpec.template_name_for(:increase).should == "/ItemSpec/actions"
83
+ PageSpec.template_name_for(:decrease).should == "/PageSpec/actions"
84
+ end
85
+ end
86
+
87
+ describe "controller_context_class, helper" do
88
+ before :each do
89
+ ItemSpec.instance_variable_set "@controller_context_class", nil
90
+ ItemSpec.instance_variable_set "@controller_context_class", nil
91
+ end
92
+
93
+ it "controller_context_class" do
94
+ ItemSpec.controller_context_class.should == ItemSpec::ItemSpecControllerContext
95
+ PageSpec.controller_context_class.should == PageSpec::PageSpecControllerContext
96
+ PageSpec::PageSpecControllerContext.is?(PageSpec::ItemSpecControllerContext).should be_true
97
+ end
98
+
99
+ it "helper" do
100
+ module ::ItemSpecHelper
101
+ def controller_item; end
102
+ end
103
+
104
+ module ::PageSpecHelper
105
+ def controller_page; end
106
+ end
107
+
108
+ ItemSpec.helper ItemSpecHelper
109
+ PageSpec.helper PageSpecHelper
110
+
111
+ ItemSpec::ItemSpecControllerContext.instance_methods.should include(:controller_item)
112
+
113
+ PageSpec::PageSpecControllerContext.instance_methods.should include(:controller_item)
114
+ PageSpec::PageSpecControllerContext.instance_methods.should include(:controller_page)
115
+ end
116
+ end
117
+
118
+ describe "other" do
119
+ it "should understand underscored paths" do
120
+ NamespaceSpec::ClassSpec.template_name_for(:update).should == "/namespace_spec/class_spec/update"
121
+ end
122
+ end
123
+ end