utopia 2.14.0 → 2.16.2

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 (261) hide show
  1. checksums.yaml +4 -4
  2. data/bake/utopia/{yarn.rb → node.rb} +11 -5
  3. data/lib/utopia/command.rb +2 -2
  4. data/lib/utopia/command/site.rb +1 -1
  5. data/lib/utopia/content.rb +7 -5
  6. data/lib/utopia/content/markup.rb +1 -1
  7. data/lib/utopia/content/node.rb +2 -2
  8. data/lib/utopia/content/response.rb +3 -3
  9. data/lib/utopia/controller.rb +0 -17
  10. data/lib/utopia/controller/base.rb +27 -3
  11. data/lib/utopia/controller/respond.rb +50 -107
  12. data/lib/utopia/extensions/array_split.rb +2 -2
  13. data/lib/utopia/http.rb +3 -3
  14. data/lib/utopia/middleware.rb +2 -2
  15. data/lib/utopia/path.rb +13 -5
  16. data/lib/utopia/redirection.rb +0 -2
  17. data/lib/utopia/responder.rb +76 -0
  18. data/lib/utopia/version.rb +1 -1
  19. data/setup/site/.gitignore +8 -7
  20. metadata +71 -396
  21. data/.codeclimate.yml +0 -5
  22. data/.github/workflows/development.yml +0 -62
  23. data/.gitignore +0 -8
  24. data/.rspec +0 -4
  25. data/.yardopts +0 -2
  26. data/Gemfile +0 -28
  27. data/README.md +0 -90
  28. data/benchmark/call_vs_check.rb +0 -38
  29. data/benchmark/const_vs_hash.rb +0 -35
  30. data/benchmark/hash_vs_openstruct.rb +0 -54
  31. data/benchmark/string_vs_symbol.rb +0 -14
  32. data/benchmark/struct_vs_class.rb +0 -91
  33. data/docs/.nojekyll +0 -0
  34. data/docs/_components/jquery-litebox/jquery.litebox.css +0 -23
  35. data/docs/_components/jquery-litebox/jquery.litebox.gallery.css +0 -48
  36. data/docs/_components/jquery-litebox/jquery.litebox.js +0 -30
  37. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.apache.css +0 -12
  38. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.applescript.css +0 -5
  39. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.assembly.css +0 -8
  40. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.bash-script.css +0 -6
  41. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.bash.css +0 -4
  42. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.clang.css +0 -6
  43. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.css.css +0 -14
  44. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.diff.css +0 -16
  45. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.html.css +0 -5
  46. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.ocaml.css +0 -3
  47. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.protobuf.css +0 -2
  48. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.python.css +0 -6
  49. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.ruby.css +0 -2
  50. data/docs/_components/jquery-syntax/base/jquery.syntax.brush.xml.css +0 -18
  51. data/docs/_components/jquery-syntax/base/jquery.syntax.core.css +0 -58
  52. data/docs/_components/jquery-syntax/base/jquery.syntax.editor.css +0 -6
  53. data/docs/_components/jquery-syntax/base/theme.js +0 -1
  54. data/docs/_components/jquery-syntax/bright/jquery.syntax.core.css +0 -27
  55. data/docs/_components/jquery-syntax/bright/theme.js +0 -1
  56. data/docs/_components/jquery-syntax/jquery.syntax.brush.apache.js +0 -3
  57. data/docs/_components/jquery-syntax/jquery.syntax.brush.applescript.js +0 -5
  58. data/docs/_components/jquery-syntax/jquery.syntax.brush.assembly.js +0 -3
  59. data/docs/_components/jquery-syntax/jquery.syntax.brush.bash-script.js +0 -4
  60. data/docs/_components/jquery-syntax/jquery.syntax.brush.bash.js +0 -2
  61. data/docs/_components/jquery-syntax/jquery.syntax.brush.basic.js +0 -5
  62. data/docs/_components/jquery-syntax/jquery.syntax.brush.clang.js +0 -5
  63. data/docs/_components/jquery-syntax/jquery.syntax.brush.csharp.js +0 -4
  64. data/docs/_components/jquery-syntax/jquery.syntax.brush.css.js +0 -5
  65. data/docs/_components/jquery-syntax/jquery.syntax.brush.diff.js +0 -2
  66. data/docs/_components/jquery-syntax/jquery.syntax.brush.go.js +0 -3
  67. data/docs/_components/jquery-syntax/jquery.syntax.brush.haskell.js +0 -3
  68. data/docs/_components/jquery-syntax/jquery.syntax.brush.html.js +0 -4
  69. data/docs/_components/jquery-syntax/jquery.syntax.brush.io.js +0 -3
  70. data/docs/_components/jquery-syntax/jquery.syntax.brush.java.js +0 -4
  71. data/docs/_components/jquery-syntax/jquery.syntax.brush.javascript.js +0 -3
  72. data/docs/_components/jquery-syntax/jquery.syntax.brush.kai.js +0 -2
  73. data/docs/_components/jquery-syntax/jquery.syntax.brush.lisp.js +0 -2
  74. data/docs/_components/jquery-syntax/jquery.syntax.brush.lua.js +0 -3
  75. data/docs/_components/jquery-syntax/jquery.syntax.brush.nginx.js +0 -2
  76. data/docs/_components/jquery-syntax/jquery.syntax.brush.ocaml.js +0 -4
  77. data/docs/_components/jquery-syntax/jquery.syntax.brush.ooc.js +0 -4
  78. data/docs/_components/jquery-syntax/jquery.syntax.brush.pascal.js +0 -4
  79. data/docs/_components/jquery-syntax/jquery.syntax.brush.perl5.js +0 -3
  80. data/docs/_components/jquery-syntax/jquery.syntax.brush.php-script.js +0 -4
  81. data/docs/_components/jquery-syntax/jquery.syntax.brush.php.js +0 -2
  82. data/docs/_components/jquery-syntax/jquery.syntax.brush.plain.js +0 -2
  83. data/docs/_components/jquery-syntax/jquery.syntax.brush.protobuf.js +0 -3
  84. data/docs/_components/jquery-syntax/jquery.syntax.brush.python.js +0 -5
  85. data/docs/_components/jquery-syntax/jquery.syntax.brush.ruby.js +0 -5
  86. data/docs/_components/jquery-syntax/jquery.syntax.brush.scala.js +0 -4
  87. data/docs/_components/jquery-syntax/jquery.syntax.brush.smalltalk.js +0 -2
  88. data/docs/_components/jquery-syntax/jquery.syntax.brush.sql.js +0 -4
  89. data/docs/_components/jquery-syntax/jquery.syntax.brush.super-collider.js +0 -3
  90. data/docs/_components/jquery-syntax/jquery.syntax.brush.swift.js +0 -3
  91. data/docs/_components/jquery-syntax/jquery.syntax.brush.trenni.js +0 -2
  92. data/docs/_components/jquery-syntax/jquery.syntax.brush.xml.js +0 -4
  93. data/docs/_components/jquery-syntax/jquery.syntax.brush.yaml.js +0 -2
  94. data/docs/_components/jquery-syntax/jquery.syntax.cache.js +0 -7
  95. data/docs/_components/jquery-syntax/jquery.syntax.core.js +0 -34
  96. data/docs/_components/jquery-syntax/jquery.syntax.editor.js +0 -11
  97. data/docs/_components/jquery-syntax/jquery.syntax.js +0 -8
  98. data/docs/_components/jquery-syntax/jquery.syntax.min.js +0 -13
  99. data/docs/_components/jquery-syntax/paper/jquery.syntax.core.css +0 -31
  100. data/docs/_components/jquery-syntax/paper/theme.js +0 -1
  101. data/docs/_components/jquery/jquery.js +0 -10872
  102. data/docs/_components/jquery/jquery.min.js +0 -2
  103. data/docs/_components/jquery/jquery.min.map +0 -1
  104. data/docs/_components/jquery/jquery.slim.js +0 -8777
  105. data/docs/_components/jquery/jquery.slim.min.js +0 -2
  106. data/docs/_components/jquery/jquery.slim.min.map +0 -1
  107. data/docs/_static/icon.png +0 -0
  108. data/docs/_static/site.css +0 -191
  109. data/docs/development-environment-setup/index.html +0 -54
  110. data/docs/faq/what-is-xnode/index.html +0 -73
  111. data/docs/index.html +0 -86
  112. data/docs/javascript/index.html +0 -108
  113. data/docs/middleware/content/index.html +0 -58
  114. data/docs/middleware/controller/actions/index.html +0 -111
  115. data/docs/middleware/controller/index.html +0 -98
  116. data/docs/middleware/controller/rewrite/index.html +0 -105
  117. data/docs/middleware/localization/index.html +0 -53
  118. data/docs/middleware/redirection/index.html +0 -55
  119. data/docs/middleware/session/index.html +0 -65
  120. data/docs/middleware/static/index.html +0 -51
  121. data/docs/server-setup/index.html +0 -87
  122. data/docs/testing/index.html +0 -53
  123. data/docs/updating-utopia/index.html +0 -102
  124. data/docs/your-first-page/index.html +0 -74
  125. data/materials/utopia.png +0 -0
  126. data/materials/utopia.svg +0 -1
  127. data/setup/site/.yarnrc +0 -1
  128. data/spec/mock_node.rb +0 -16
  129. data/spec/spec_helper.rb +0 -13
  130. data/spec/utopia/command_spec.rb +0 -164
  131. data/spec/utopia/content/document_spec.rb +0 -60
  132. data/spec/utopia/content/links/bar/index.xnode +0 -0
  133. data/spec/utopia/content/links/bar/parent/child/index.en.xnode +0 -0
  134. data/spec/utopia/content/links/bar/parent/child/index.ja.xnode +0 -0
  135. data/spec/utopia/content/links/bar/parent/links.yaml +0 -2
  136. data/spec/utopia/content/links/foo/index.xnode +0 -0
  137. data/spec/utopia/content/links/foo/links.yaml +0 -2
  138. data/spec/utopia/content/links/foo/test.de.xnode +0 -0
  139. data/spec/utopia/content/links/foo/test.en.xnode +0 -0
  140. data/spec/utopia/content/links/index.xnode +0 -0
  141. data/spec/utopia/content/links/links.yaml +0 -18
  142. data/spec/utopia/content/links/redirect/links.yaml +0 -2
  143. data/spec/utopia/content/links/welcome.xnode +0 -0
  144. data/spec/utopia/content/links_spec.rb +0 -218
  145. data/spec/utopia/content/localized/five/index.en.xnode +0 -0
  146. data/spec/utopia/content/localized/four/index.en.xnode +0 -0
  147. data/spec/utopia/content/localized/four/index.zh.xnode +0 -0
  148. data/spec/utopia/content/localized/four/links.yaml +0 -4
  149. data/spec/utopia/content/localized/links.yaml +0 -13
  150. data/spec/utopia/content/localized/one.xnode +0 -0
  151. data/spec/utopia/content/localized/three/index.xnode +0 -0
  152. data/spec/utopia/content/localized/two.en.xnode +0 -0
  153. data/spec/utopia/content/localized/two.zh.xnode +0 -0
  154. data/spec/utopia/content/markup_spec.rb +0 -96
  155. data/spec/utopia/content/namespace_spec.rb +0 -45
  156. data/spec/utopia/content/node/lookup/content.xnode +0 -1
  157. data/spec/utopia/content/node/lookup/index.xnode +0 -1
  158. data/spec/utopia/content/node/ordered/first.xnode +0 -0
  159. data/spec/utopia/content/node/ordered/index.xnode +0 -0
  160. data/spec/utopia/content/node/ordered/links.yaml +0 -4
  161. data/spec/utopia/content/node/ordered/second.xnode +0 -0
  162. data/spec/utopia/content/node/related/foo.en.xnode +0 -0
  163. data/spec/utopia/content/node/related/foo.ja.xnode +0 -0
  164. data/spec/utopia/content/node/related/links.yaml +0 -4
  165. data/spec/utopia/content/node_spec.rb +0 -97
  166. data/spec/utopia/content/response_spec.rb +0 -54
  167. data/spec/utopia/content/tags_spec.rb +0 -82
  168. data/spec/utopia/content_spec.rb +0 -100
  169. data/spec/utopia/content_spec.ru +0 -6
  170. data/spec/utopia/content_spec/_heading.xnode +0 -1
  171. data/spec/utopia/content_spec/content/_show-value.xnode +0 -1
  172. data/spec/utopia/content_spec/content/links.yaml +0 -2
  173. data/spec/utopia/content_spec/content/test-partial.xnode +0 -1
  174. data/spec/utopia/content_spec/index.xnode +0 -1
  175. data/spec/utopia/content_spec/node/index.xnode +0 -1
  176. data/spec/utopia/content_spec/test.xnode +0 -10
  177. data/spec/utopia/controller/actions_spec.rb +0 -62
  178. data/spec/utopia/controller/middleware_spec.rb +0 -88
  179. data/spec/utopia/controller/middleware_spec.ru +0 -6
  180. data/spec/utopia/controller/middleware_spec/controller/controller.rb +0 -27
  181. data/spec/utopia/controller/middleware_spec/controller/index.xnode +0 -1
  182. data/spec/utopia/controller/middleware_spec/controller/nested/controller.rb +0 -7
  183. data/spec/utopia/controller/middleware_spec/empty/controller.rb +0 -0
  184. data/spec/utopia/controller/middleware_spec/redirect/controller.rb +0 -12
  185. data/spec/utopia/controller/middleware_spec/redirect/test/controller.rb +0 -9
  186. data/spec/utopia/controller/respond_spec.rb +0 -174
  187. data/spec/utopia/controller/respond_spec.ru +0 -12
  188. data/spec/utopia/controller/respond_spec/api/controller.rb +0 -28
  189. data/spec/utopia/controller/respond_spec/errors/controller.rb +0 -14
  190. data/spec/utopia/controller/respond_spec/errors/file-not-found.xnode +0 -8
  191. data/spec/utopia/controller/respond_spec/html/controller.rb +0 -11
  192. data/spec/utopia/controller/respond_spec/rewrite/controller.rb +0 -13
  193. data/spec/utopia/controller/rewrite_spec.rb +0 -80
  194. data/spec/utopia/controller/sequence_spec.rb +0 -135
  195. data/spec/utopia/controller/variables_spec.rb +0 -59
  196. data/spec/utopia/controller/websocket_spec.rb +0 -68
  197. data/spec/utopia/controller/websocket_spec.ru +0 -5
  198. data/spec/utopia/controller/websocket_spec/server/controller.rb +0 -11
  199. data/spec/utopia/exceptions/handler_spec.rb +0 -47
  200. data/spec/utopia/exceptions/handler_spec.ru +0 -8
  201. data/spec/utopia/exceptions/handler_spec/controller.rb +0 -19
  202. data/spec/utopia/exceptions/mailer_spec.rb +0 -43
  203. data/spec/utopia/exceptions/mailer_spec.ru +0 -10
  204. data/spec/utopia/extensions_spec.rb +0 -73
  205. data/spec/utopia/http/status_spec.rb +0 -44
  206. data/spec/utopia/locale_spec.rb +0 -58
  207. data/spec/utopia/localization_spec.rb +0 -92
  208. data/spec/utopia/localization_spec.ru +0 -15
  209. data/spec/utopia/localization_spec/controller.rb +0 -21
  210. data/spec/utopia/localization_spec/localized.de.txt +0 -1
  211. data/spec/utopia/localization_spec/localized.en.txt +0 -1
  212. data/spec/utopia/localization_spec/localized.ja.txt +0 -1
  213. data/spec/utopia/localization_spec/test.txt +0 -1
  214. data/spec/utopia/middleware_spec.rb +0 -31
  215. data/spec/utopia/path/matcher_spec.rb +0 -66
  216. data/spec/utopia/path_spec.rb +0 -207
  217. data/spec/utopia/performance_spec.rb +0 -92
  218. data/spec/utopia/performance_spec/cache/head/readme.txt +0 -1
  219. data/spec/utopia/performance_spec/cache/meta/readme.txt +0 -1
  220. data/spec/utopia/performance_spec/config.ru +0 -35
  221. data/spec/utopia/performance_spec/lib/readme.txt +0 -1
  222. data/spec/utopia/performance_spec/pages/_heading.xnode +0 -2
  223. data/spec/utopia/performance_spec/pages/_page.xnode +0 -26
  224. data/spec/utopia/performance_spec/pages/api/controller.rb +0 -8
  225. data/spec/utopia/performance_spec/pages/errors/exception.xnode +0 -5
  226. data/spec/utopia/performance_spec/pages/errors/file-not-found.xnode +0 -5
  227. data/spec/utopia/performance_spec/pages/links.yaml +0 -2
  228. data/spec/utopia/performance_spec/pages/welcome/index.xnode +0 -17
  229. data/spec/utopia/rack_helper.rb +0 -32
  230. data/spec/utopia/redirection_spec.rb +0 -77
  231. data/spec/utopia/redirection_spec.ru +0 -27
  232. data/spec/utopia/session_spec.rb +0 -189
  233. data/spec/utopia/session_spec.ru +0 -24
  234. data/spec/utopia/setup_spec.rb +0 -56
  235. data/spec/utopia/static_spec.rb +0 -49
  236. data/spec/utopia/static_spec.ru +0 -5
  237. data/spec/utopia/static_spec/test.txt +0 -1
  238. data/utopia.gemspec +0 -52
  239. data/wiki/Gemfile +0 -9
  240. data/wiki/config.ru +0 -7
  241. data/wiki/pages/development-environment-setup/index.md +0 -16
  242. data/wiki/pages/faq/links.yaml +0 -2
  243. data/wiki/pages/faq/what-is-xnode/index.md +0 -37
  244. data/wiki/pages/faq/what-is-xnode/links.yaml +0 -2
  245. data/wiki/pages/index.md +0 -35
  246. data/wiki/pages/javascript/index.md +0 -77
  247. data/wiki/pages/javascript/links.yaml +0 -2
  248. data/wiki/pages/links.yaml +0 -2
  249. data/wiki/pages/middleware/content/index.md +0 -21
  250. data/wiki/pages/middleware/controller/actions/index.md +0 -76
  251. data/wiki/pages/middleware/controller/index.md +0 -62
  252. data/wiki/pages/middleware/controller/links.yaml +0 -4
  253. data/wiki/pages/middleware/controller/rewrite/index.md +0 -69
  254. data/wiki/pages/middleware/localization/index.md +0 -16
  255. data/wiki/pages/middleware/redirection/index.md +0 -17
  256. data/wiki/pages/middleware/session/index.md +0 -29
  257. data/wiki/pages/middleware/static/index.md +0 -13
  258. data/wiki/pages/server-setup/index.md +0 -52
  259. data/wiki/pages/testing/index.md +0 -15
  260. data/wiki/pages/updating-utopia/index.md +0 -63
  261. data/wiki/pages/your-first-page/index.md +0 -38
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a3a6b8f885af36532a896ea9ec0a781c2c9771e6a700a1387beaa6451de494cf
4
- data.tar.gz: d67a5a7f1d2e4f83680b4216f10d2d52a9828021cddf08f3471e32a11465e513
3
+ metadata.gz: f1833aabc2d72234952e6ee164138d234cafc5d0d2015b64edcb28cead480c95
4
+ data.tar.gz: d6e9675b9921ae290547c25b11c8b5974860256393c65147705d0dd1472ba851
5
5
  SHA512:
6
- metadata.gz: a5cdd9fda1b6eb6337948b89d6af6d5db3cbf74c74d767d3935612bf0015935e896f1ed1f3e350aa60b8d8af665c93a225df3f9aabbdb2ecd5eb41041c83b061
7
- data.tar.gz: c731147ffd698996509a00b7502588975b7cf9fbb9abc9942fc1c93b0687b63c70c3f259e31ea343afe5fd79dfd98b5c299dbeca65997e0a0eaf929c2b7b904a
6
+ metadata.gz: cd8ee2bdd633f9bcd10be1bd18db664299e9cc8c16169ad7d84d934ba8abb301037d0a0f459608087204cd43ac51eb155e88c4af2e988d03b2c29859df5fc2a3
7
+ data.tar.gz: 4a16550958bc3ddf8fc37760f8436cc450d3e84ee2178ba6f194ce557869e0e20bfee0f3412eb6f2364c7f5ccc831da2b8f440fce11a81e8fc7f436914d64dde
@@ -6,12 +6,18 @@ def update
6
6
  require 'utopia/path'
7
7
 
8
8
  root = Pathname.new(context.root)
9
- yarn_package_root = root + "lib/components"
10
- yarn_install_root = root + "public/_components"
9
+ package_root = root + "node_modules"
11
10
 
12
- yarn_package_root.children.select(&:directory?).collect(&:basename).each do |package_directory|
13
- install_path = yarn_install_root + package_directory
14
- package_path = yarn_package_root + package_directory
11
+ # This is a legacy path:
12
+ unless package_root.directory?
13
+ package_root = root + "lib/components"
14
+ end
15
+
16
+ install_root = root + "public/_components"
17
+
18
+ package_root.children.select(&:directory?).collect(&:basename).each do |package_directory|
19
+ install_path = install_root + package_directory
20
+ package_path = package_root + package_directory
15
21
 
16
22
  dist_path = package_path + 'dist'
17
23
 
@@ -28,8 +28,8 @@ require_relative 'command/environment'
28
28
 
29
29
  module Utopia
30
30
  module Command
31
- def self.call(*args)
32
- Top.call(*args)
31
+ def self.call(*arguments)
32
+ Top.call(*arguments)
33
33
  end
34
34
 
35
35
  # The top level utopia command.
@@ -33,7 +33,7 @@ module Utopia
33
33
  # Local site setup commands.
34
34
  class Site < Samovar::Command
35
35
  # Configuration files which should be installed/updated:
36
- CONFIGURATION_FILES = ['.yarnrc', '.gitignore', 'config.ru', 'config/environment.rb', 'falcon.rb', 'Gemfile', 'Guardfile', 'bake.rb', 'spec/spec_helper.rb', 'spec/website_context.rb', 'spec/website_spec.rb']
36
+ CONFIGURATION_FILES = ['.gitignore', 'config.ru', 'config/environment.rb', 'falcon.rb', 'Gemfile', 'Guardfile', 'bake.rb', 'spec/spec_helper.rb', 'spec/website_context.rb', 'spec/website_spec.rb']
37
37
 
38
38
  # Directories that should exist:
39
39
  DIRECTORIES = ["config", "lib", "pages", "public", "tasks", "spec"]
@@ -177,17 +177,19 @@ module Utopia
177
177
  end
178
178
 
179
179
  def content_tag(name, node)
180
- parent_path = node.parent_path
180
+ full_path = node.parent_path + name
181
+
182
+ name = full_path.pop
181
183
 
182
184
  # If the current node is called 'foo', we can't lookup 'foo' in the current directory or we will have infinite recursion.
183
- if name == node.name
184
- parent_path = parent_path.dirname
185
+ while full_path.last == name
186
+ full_path.pop
185
187
  end
186
188
 
187
- cache_key = parent_path + name
189
+ cache_key = full_path + name
188
190
 
189
191
  @node_cache.fetch_or_store(cache_key) do
190
- lookup_content(name, parent_path)
192
+ lookup_content(name, full_path)
191
193
  end
192
194
  end
193
195
  end
@@ -40,7 +40,7 @@ module Utopia
40
40
  super key.to_sym, value
41
41
  end
42
42
 
43
- def fetch(key, *args, &block)
43
+ def fetch(key, *arguments, &block)
44
44
  key = key.to_sym
45
45
 
46
46
  super
@@ -128,12 +128,12 @@ module Utopia
128
128
 
129
129
  # This is a special context in which a limited set of well defined methods are exposed in the content view.
130
130
  Context = Struct.new(:document, :state) do
131
- def partial(*args, &block)
131
+ def partial(*arguments, &block)
132
132
  if block_given?
133
133
  state.defer(&block)
134
134
  else
135
135
  state.defer do |document|
136
- document.tag(*args)
136
+ document.tag(*arguments)
137
137
  end
138
138
  end
139
139
  end
@@ -23,9 +23,9 @@
23
23
  module Utopia
24
24
  class Content
25
25
  # Compatibility with older versions of rack:
26
- EXPIRES = 'Expires'.freeze
27
- CACHE_CONTROL = 'Cache-Control'.freeze
28
- CONTENT_TYPE = 'Content-Type'.freeze
26
+ EXPIRES = 'expires'.freeze
27
+ CACHE_CONTROL = 'cache-control'.freeze
28
+ CONTENT_TYPE = 'content-type'.freeze
29
29
  NO_CACHE = 'no-cache'.freeze
30
30
 
31
31
  # A basic content response, including useful defaults for typical HTML5 content.
@@ -33,20 +33,6 @@ require_relative 'controller/actions'
33
33
  require 'concurrent/map'
34
34
 
35
35
  module Utopia
36
- # A container for controller classes which are loaded from disk.
37
- module Controllers
38
- def self.class_name_for_controller(controller)
39
- controller.uri_path.to_a.collect{|_| _.capitalize}.join + "_#{controller.object_id}"
40
- end
41
-
42
- def self.define(klass)
43
- self.const_set(
44
- class_name_for_controller(klass),
45
- klass,
46
- )
47
- end
48
- end
49
-
50
36
  # A middleware which loads controller classes and invokes functionality based on the requested path.
51
37
  class Controller
52
38
  # The controller filename.
@@ -105,9 +91,6 @@ module Utopia
105
91
 
106
92
  klass.class_eval(File.read(controller_path), controller_path)
107
93
 
108
- # Give the controller a useful name:
109
- # Controllers.define(klass)
110
-
111
94
  # We lock down the controller class to prevent unsafe modifications:
112
95
  klass.freeze
113
96
 
@@ -24,8 +24,14 @@ require_relative '../http'
24
24
 
25
25
  module Utopia
26
26
  class Controller
27
+ CONTENT_TYPE = HTTP::CONTENT_TYPE
28
+
27
29
  # The base implementation of a controller class.
28
30
  class Base
31
+ URI_PATH = nil
32
+ BASE_PATH = nil
33
+ CONTROLLER = nil
34
+
29
35
  # A string which is the full path to the directory which contains the controller.
30
36
  def self.base_path
31
37
  self.const_get(:BASE_PATH)
@@ -41,6 +47,24 @@ module Utopia
41
47
  self.const_get(:CONTROLLER)
42
48
  end
43
49
 
50
+ def self.inspect
51
+ "#{super}#{self.uri_path}"
52
+ end
53
+
54
+ def self.to_s
55
+ self.inspect
56
+ end
57
+
58
+ def to_s
59
+ "\#<#{self.class}>"
60
+ end
61
+
62
+ def inspect
63
+ details = self.instance_variables.map{|name| " #{name}=#{self.instance_variable_get(name)}"}
64
+
65
+ "\#<#{self.class}#{details.join}>"
66
+ end
67
+
44
68
  class << self
45
69
  def freeze
46
70
  # This ensures that all class variables are frozen.
@@ -116,11 +140,11 @@ module Utopia
116
140
  end
117
141
 
118
142
  # Succeed the request and immediately respond.
119
- def succeed!(status: 200, headers: {}, **options)
143
+ def succeed!(status: 200, headers: {}, type: nil, **options)
120
144
  status = HTTP::Status.new(status, 200...300)
121
145
 
122
- if options[:type]
123
- headers[Rack::CONTENT_TYPE] = options[:type].to_s
146
+ if type
147
+ headers[CONTENT_TYPE] = type.to_s
124
148
  end
125
149
 
126
150
  body = body_for(status, headers, options)
@@ -21,7 +21,7 @@
21
21
  # THE SOFTWARE.
22
22
 
23
23
  require_relative '../http'
24
- require_relative '../path/matcher'
24
+ require_relative '../responder'
25
25
 
26
26
  module Utopia
27
27
  class Controller
@@ -31,139 +31,82 @@ module Utopia
31
31
  base.extend(ClassMethods)
32
32
  end
33
33
 
34
- module Converter
35
- def self.update_response(response, updated_headers)
36
- status, headers, body = response
34
+ module Handlers
35
+ module JSON
36
+ APPLICATION_JSON = HTTP::Accept::ContentType.new('application', 'json').freeze
37
37
 
38
- # Generate a new body:
39
- body = body.collect{|content| yield content}
40
-
41
- # Update the headers with the requested content type:
42
- headers = headers.merge(updated_headers)
43
-
44
- return [status, headers, body]
45
- end
46
-
47
- Callback = Struct.new(:content_type, :block) do
48
- def headers
49
- {HTTP::CONTENT_TYPE => self.content_type}
38
+ def self.split(*arguments)
39
+ APPLICATION_JSON.split(*arguments)
50
40
  end
51
41
 
52
- def split(*args)
53
- self.content_type.split(*args)
54
- end
55
-
56
- def call(context, response, media_range)
57
- Converter.update_response(response, headers) do |content|
58
- context.instance_exec(content, media_range, &block)
42
+ def self.call(context, request, media_range, object, **options)
43
+ if version = media_range.parameters['version']
44
+ options[:version] = version.to_s
59
45
  end
46
+
47
+ context.succeed! content: object.to_json(options), type: APPLICATION_JSON
60
48
  end
61
49
  end
62
50
 
63
- def self.new(*args)
64
- Callback.new(*args)
65
- end
66
-
67
- # To accept incoming requests with content-type JSON (e.g. POST with JSON data), consider using `Rack::PostBodyContentTypeParser`.
68
- module ToJSON
69
- APPLICATION_JSON = HTTP::Accept::ContentType.new('application', 'json', charset: 'utf-8').freeze
70
- HEADERS = {HTTP::CONTENT_TYPE => APPLICATION_JSON.to_s}.freeze
51
+ module Passthrough
52
+ WILDCARD = HTTP::Accept::MediaTypes::MediaRange.new('*', '*').freeze
71
53
 
72
- def self.content_type
73
- APPLICATION_JSON
54
+ def self.split(*arguments)
55
+ WILDCARD.split(*arguments)
74
56
  end
75
57
 
76
- def self.split(*args)
77
- self.content_type.split(*args)
78
- end
79
-
80
- def self.serialize(content, media_range)
81
- options = {}
82
-
83
- if version = media_range.parameters['version']
84
- options[:version] = version.to_s
85
- end
86
-
87
- return content.to_json(options)
88
- end
89
-
90
- def self.call(context, response, media_range)
91
- Converter.update_response(response, HEADERS) do |content|
92
- self.serialize(content, media_range)
93
- end
58
+ def self.call(context, request, media_range, object, **options)
59
+ # Do nothing.
94
60
  end
95
61
  end
96
62
  end
97
63
 
98
- module Passthrough
99
- WILDCARD = HTTP::Accept::MediaTypes::MediaRange.new('*', '*').freeze
100
-
101
- def self.split(*args)
102
- self.media_range.split(*args)
64
+ class Responder < Utopia::Responder
65
+ def with_json
66
+ @handlers << Handlers::JSON
103
67
  end
104
68
 
105
- def self.media_range
106
- WILDCARD
69
+ def with_passthrough
70
+ @handlers << Handlers::Passthrough
107
71
  end
108
72
 
109
- def self.call(context, response, media_range)
110
- return nil
73
+ def with(content_type, &block)
74
+ handle(content_type, &block)
111
75
  end
112
76
  end
113
77
 
114
- class Responder
115
- HTTP_ACCEPT = 'HTTP_ACCEPT'.freeze
116
- NOT_ACCEPTABLE_RESPONSE = [406, {}, []].freeze
117
-
118
- def initialize
119
- @converters = HTTP::Accept::MediaTypes::Map.new
78
+ module ClassMethods
79
+ def responds
80
+ @responder ||= Responder.new
120
81
  end
121
82
 
122
- def freeze
123
- @converters.freeze
124
-
125
- super
126
- end
83
+ alias respond responds
127
84
 
128
- # Add a converter for the specified content type. Call the block with the response content if the request accepts the specified content_type.
129
- def with(content_type, &block)
130
- @converters << Converter::Callback.new(content_type, block)
85
+ def respond_to(context, request)
86
+ @responder&.respond_to(context, request)
131
87
  end
132
88
 
133
- def with_passthrough
134
- @converters << Passthrough
135
- end
136
-
137
- # Add a converter for JSON when requests accept 'application/json'
138
- def with_json
139
- @converters << Converter::ToJSON
140
- end
141
-
142
- def call(context, request, path, response)
143
- # Parse the list of browser preferred content types and return ordered by priority:
144
- media_types = HTTP::Accept::MediaTypes.browser_preferred_media_types(request.env)
145
-
146
- converter, media_range = @converters.for(media_types)
147
-
148
- if converter
149
- converter.call(context, response, media_range)
150
- else
151
- NOT_ACCEPTABLE_RESPONSE
152
- end
89
+ def response_for(context, request, response)
90
+ @responder&.respond_to(context, request).with(*response[2])
153
91
  end
154
92
  end
155
93
 
156
- module ClassMethods
157
- def respond
158
- @responder ||= Responder.new
94
+ def respond_to(request)
95
+ self.class.respond_to(self, request)
96
+ end
97
+
98
+ def response_for(request, original_response)
99
+ response = catch(:response) do
100
+ self.class.response_for(self, request, original_response)
101
+
102
+ # If the above code did not throw a new response, we return the original:
103
+ return original_response
159
104
  end
160
105
 
161
- def response_for(context, request, path, response)
162
- if @responder
163
- @responder.call(context, request, path, response)
164
- else
165
- response
166
- end
106
+ # If the user called {Base#ignore!}, it's possible response is nil:
107
+ if response
108
+ # There was an updated response so merge it:
109
+ return [original_response[0], original_response[1].merge(response[1]), response[2] || original_response[2]]
167
110
  end
168
111
  end
169
112
 
@@ -173,11 +116,11 @@ module Utopia
173
116
  headers = response[1]
174
117
 
175
118
  # Don't try to convert the response if a content type was explicitly specified.
176
- unless headers[Rack::CONTENT_TYPE]
177
- response = self.class.response_for(self, request, path, response)
119
+ if headers[HTTP::CONTENT_TYPE]
120
+ return response
121
+ else
122
+ return self.response_for(request, response)
178
123
  end
179
-
180
- response
181
124
  end
182
125
  end
183
126
  end
@@ -23,8 +23,8 @@
23
23
  module Utopia
24
24
  module Extensions
25
25
  module ArraySplit
26
- def split_at(*args, &block)
27
- if middle = index(*args, &block)
26
+ def split_at(*arguments, &block)
27
+ if middle = index(*arguments, &block)
28
28
  [self[0...middle], self[middle], self[middle+1..-1]]
29
29
  else
30
30
  [[], nil, []]
@@ -90,9 +90,9 @@ module Utopia
90
90
  503 => 'Service Unavailable'.freeze
91
91
  }.merge(Rack::Utils::HTTP_STATUS_CODES)
92
92
 
93
- CONTENT_TYPE = 'Content-Type'.freeze
94
- LOCATION = 'Location'.freeze
95
- CACHE_CONTROL = 'Cache-Control'.freeze
93
+ CONTENT_TYPE = 'content-type'.freeze
94
+ LOCATION = 'location'.freeze
95
+ CACHE_CONTROL = 'cache-control'.freeze
96
96
 
97
97
  # A small HTTP status wrapper that verifies the status code within a given range.
98
98
  class Status
@@ -39,7 +39,7 @@ module Utopia
39
39
 
40
40
  # The same as {default_root} but returns an instance of {Path}.
41
41
  # @return [Path] The path as requested.
42
- def self.default_path(*args)
43
- Path[default_root(*args)]
42
+ def self.default_path(*arguments)
43
+ Path[default_root(*arguments)]
44
44
  end
45
45
  end