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.
- checksums.yaml +4 -4
- data/bake/utopia/{yarn.rb → node.rb} +11 -5
- data/lib/utopia/command.rb +2 -2
- data/lib/utopia/command/site.rb +1 -1
- data/lib/utopia/content.rb +7 -5
- data/lib/utopia/content/markup.rb +1 -1
- data/lib/utopia/content/node.rb +2 -2
- data/lib/utopia/content/response.rb +3 -3
- data/lib/utopia/controller.rb +0 -17
- data/lib/utopia/controller/base.rb +27 -3
- data/lib/utopia/controller/respond.rb +50 -107
- data/lib/utopia/extensions/array_split.rb +2 -2
- data/lib/utopia/http.rb +3 -3
- data/lib/utopia/middleware.rb +2 -2
- data/lib/utopia/path.rb +13 -5
- data/lib/utopia/redirection.rb +0 -2
- data/lib/utopia/responder.rb +76 -0
- data/lib/utopia/version.rb +1 -1
- data/setup/site/.gitignore +8 -7
- metadata +71 -396
- data/.codeclimate.yml +0 -5
- data/.github/workflows/development.yml +0 -62
- data/.gitignore +0 -8
- data/.rspec +0 -4
- data/.yardopts +0 -2
- data/Gemfile +0 -28
- data/README.md +0 -90
- data/benchmark/call_vs_check.rb +0 -38
- data/benchmark/const_vs_hash.rb +0 -35
- data/benchmark/hash_vs_openstruct.rb +0 -54
- data/benchmark/string_vs_symbol.rb +0 -14
- data/benchmark/struct_vs_class.rb +0 -91
- data/docs/.nojekyll +0 -0
- data/docs/_components/jquery-litebox/jquery.litebox.css +0 -23
- data/docs/_components/jquery-litebox/jquery.litebox.gallery.css +0 -48
- data/docs/_components/jquery-litebox/jquery.litebox.js +0 -30
- data/docs/_components/jquery-syntax/base/jquery.syntax.brush.apache.css +0 -12
- data/docs/_components/jquery-syntax/base/jquery.syntax.brush.applescript.css +0 -5
- data/docs/_components/jquery-syntax/base/jquery.syntax.brush.assembly.css +0 -8
- data/docs/_components/jquery-syntax/base/jquery.syntax.brush.bash-script.css +0 -6
- data/docs/_components/jquery-syntax/base/jquery.syntax.brush.bash.css +0 -4
- data/docs/_components/jquery-syntax/base/jquery.syntax.brush.clang.css +0 -6
- data/docs/_components/jquery-syntax/base/jquery.syntax.brush.css.css +0 -14
- data/docs/_components/jquery-syntax/base/jquery.syntax.brush.diff.css +0 -16
- data/docs/_components/jquery-syntax/base/jquery.syntax.brush.html.css +0 -5
- data/docs/_components/jquery-syntax/base/jquery.syntax.brush.ocaml.css +0 -3
- data/docs/_components/jquery-syntax/base/jquery.syntax.brush.protobuf.css +0 -2
- data/docs/_components/jquery-syntax/base/jquery.syntax.brush.python.css +0 -6
- data/docs/_components/jquery-syntax/base/jquery.syntax.brush.ruby.css +0 -2
- data/docs/_components/jquery-syntax/base/jquery.syntax.brush.xml.css +0 -18
- data/docs/_components/jquery-syntax/base/jquery.syntax.core.css +0 -58
- data/docs/_components/jquery-syntax/base/jquery.syntax.editor.css +0 -6
- data/docs/_components/jquery-syntax/base/theme.js +0 -1
- data/docs/_components/jquery-syntax/bright/jquery.syntax.core.css +0 -27
- data/docs/_components/jquery-syntax/bright/theme.js +0 -1
- data/docs/_components/jquery-syntax/jquery.syntax.brush.apache.js +0 -3
- data/docs/_components/jquery-syntax/jquery.syntax.brush.applescript.js +0 -5
- data/docs/_components/jquery-syntax/jquery.syntax.brush.assembly.js +0 -3
- data/docs/_components/jquery-syntax/jquery.syntax.brush.bash-script.js +0 -4
- data/docs/_components/jquery-syntax/jquery.syntax.brush.bash.js +0 -2
- data/docs/_components/jquery-syntax/jquery.syntax.brush.basic.js +0 -5
- data/docs/_components/jquery-syntax/jquery.syntax.brush.clang.js +0 -5
- data/docs/_components/jquery-syntax/jquery.syntax.brush.csharp.js +0 -4
- data/docs/_components/jquery-syntax/jquery.syntax.brush.css.js +0 -5
- data/docs/_components/jquery-syntax/jquery.syntax.brush.diff.js +0 -2
- data/docs/_components/jquery-syntax/jquery.syntax.brush.go.js +0 -3
- data/docs/_components/jquery-syntax/jquery.syntax.brush.haskell.js +0 -3
- data/docs/_components/jquery-syntax/jquery.syntax.brush.html.js +0 -4
- data/docs/_components/jquery-syntax/jquery.syntax.brush.io.js +0 -3
- data/docs/_components/jquery-syntax/jquery.syntax.brush.java.js +0 -4
- data/docs/_components/jquery-syntax/jquery.syntax.brush.javascript.js +0 -3
- data/docs/_components/jquery-syntax/jquery.syntax.brush.kai.js +0 -2
- data/docs/_components/jquery-syntax/jquery.syntax.brush.lisp.js +0 -2
- data/docs/_components/jquery-syntax/jquery.syntax.brush.lua.js +0 -3
- data/docs/_components/jquery-syntax/jquery.syntax.brush.nginx.js +0 -2
- data/docs/_components/jquery-syntax/jquery.syntax.brush.ocaml.js +0 -4
- data/docs/_components/jquery-syntax/jquery.syntax.brush.ooc.js +0 -4
- data/docs/_components/jquery-syntax/jquery.syntax.brush.pascal.js +0 -4
- data/docs/_components/jquery-syntax/jquery.syntax.brush.perl5.js +0 -3
- data/docs/_components/jquery-syntax/jquery.syntax.brush.php-script.js +0 -4
- data/docs/_components/jquery-syntax/jquery.syntax.brush.php.js +0 -2
- data/docs/_components/jquery-syntax/jquery.syntax.brush.plain.js +0 -2
- data/docs/_components/jquery-syntax/jquery.syntax.brush.protobuf.js +0 -3
- data/docs/_components/jquery-syntax/jquery.syntax.brush.python.js +0 -5
- data/docs/_components/jquery-syntax/jquery.syntax.brush.ruby.js +0 -5
- data/docs/_components/jquery-syntax/jquery.syntax.brush.scala.js +0 -4
- data/docs/_components/jquery-syntax/jquery.syntax.brush.smalltalk.js +0 -2
- data/docs/_components/jquery-syntax/jquery.syntax.brush.sql.js +0 -4
- data/docs/_components/jquery-syntax/jquery.syntax.brush.super-collider.js +0 -3
- data/docs/_components/jquery-syntax/jquery.syntax.brush.swift.js +0 -3
- data/docs/_components/jquery-syntax/jquery.syntax.brush.trenni.js +0 -2
- data/docs/_components/jquery-syntax/jquery.syntax.brush.xml.js +0 -4
- data/docs/_components/jquery-syntax/jquery.syntax.brush.yaml.js +0 -2
- data/docs/_components/jquery-syntax/jquery.syntax.cache.js +0 -7
- data/docs/_components/jquery-syntax/jquery.syntax.core.js +0 -34
- data/docs/_components/jquery-syntax/jquery.syntax.editor.js +0 -11
- data/docs/_components/jquery-syntax/jquery.syntax.js +0 -8
- data/docs/_components/jquery-syntax/jquery.syntax.min.js +0 -13
- data/docs/_components/jquery-syntax/paper/jquery.syntax.core.css +0 -31
- data/docs/_components/jquery-syntax/paper/theme.js +0 -1
- data/docs/_components/jquery/jquery.js +0 -10872
- data/docs/_components/jquery/jquery.min.js +0 -2
- data/docs/_components/jquery/jquery.min.map +0 -1
- data/docs/_components/jquery/jquery.slim.js +0 -8777
- data/docs/_components/jquery/jquery.slim.min.js +0 -2
- data/docs/_components/jquery/jquery.slim.min.map +0 -1
- data/docs/_static/icon.png +0 -0
- data/docs/_static/site.css +0 -191
- data/docs/development-environment-setup/index.html +0 -54
- data/docs/faq/what-is-xnode/index.html +0 -73
- data/docs/index.html +0 -86
- data/docs/javascript/index.html +0 -108
- data/docs/middleware/content/index.html +0 -58
- data/docs/middleware/controller/actions/index.html +0 -111
- data/docs/middleware/controller/index.html +0 -98
- data/docs/middleware/controller/rewrite/index.html +0 -105
- data/docs/middleware/localization/index.html +0 -53
- data/docs/middleware/redirection/index.html +0 -55
- data/docs/middleware/session/index.html +0 -65
- data/docs/middleware/static/index.html +0 -51
- data/docs/server-setup/index.html +0 -87
- data/docs/testing/index.html +0 -53
- data/docs/updating-utopia/index.html +0 -102
- data/docs/your-first-page/index.html +0 -74
- data/materials/utopia.png +0 -0
- data/materials/utopia.svg +0 -1
- data/setup/site/.yarnrc +0 -1
- data/spec/mock_node.rb +0 -16
- data/spec/spec_helper.rb +0 -13
- data/spec/utopia/command_spec.rb +0 -164
- data/spec/utopia/content/document_spec.rb +0 -60
- data/spec/utopia/content/links/bar/index.xnode +0 -0
- data/spec/utopia/content/links/bar/parent/child/index.en.xnode +0 -0
- data/spec/utopia/content/links/bar/parent/child/index.ja.xnode +0 -0
- data/spec/utopia/content/links/bar/parent/links.yaml +0 -2
- data/spec/utopia/content/links/foo/index.xnode +0 -0
- data/spec/utopia/content/links/foo/links.yaml +0 -2
- data/spec/utopia/content/links/foo/test.de.xnode +0 -0
- data/spec/utopia/content/links/foo/test.en.xnode +0 -0
- data/spec/utopia/content/links/index.xnode +0 -0
- data/spec/utopia/content/links/links.yaml +0 -18
- data/spec/utopia/content/links/redirect/links.yaml +0 -2
- data/spec/utopia/content/links/welcome.xnode +0 -0
- data/spec/utopia/content/links_spec.rb +0 -218
- data/spec/utopia/content/localized/five/index.en.xnode +0 -0
- data/spec/utopia/content/localized/four/index.en.xnode +0 -0
- data/spec/utopia/content/localized/four/index.zh.xnode +0 -0
- data/spec/utopia/content/localized/four/links.yaml +0 -4
- data/spec/utopia/content/localized/links.yaml +0 -13
- data/spec/utopia/content/localized/one.xnode +0 -0
- data/spec/utopia/content/localized/three/index.xnode +0 -0
- data/spec/utopia/content/localized/two.en.xnode +0 -0
- data/spec/utopia/content/localized/two.zh.xnode +0 -0
- data/spec/utopia/content/markup_spec.rb +0 -96
- data/spec/utopia/content/namespace_spec.rb +0 -45
- data/spec/utopia/content/node/lookup/content.xnode +0 -1
- data/spec/utopia/content/node/lookup/index.xnode +0 -1
- data/spec/utopia/content/node/ordered/first.xnode +0 -0
- data/spec/utopia/content/node/ordered/index.xnode +0 -0
- data/spec/utopia/content/node/ordered/links.yaml +0 -4
- data/spec/utopia/content/node/ordered/second.xnode +0 -0
- data/spec/utopia/content/node/related/foo.en.xnode +0 -0
- data/spec/utopia/content/node/related/foo.ja.xnode +0 -0
- data/spec/utopia/content/node/related/links.yaml +0 -4
- data/spec/utopia/content/node_spec.rb +0 -97
- data/spec/utopia/content/response_spec.rb +0 -54
- data/spec/utopia/content/tags_spec.rb +0 -82
- data/spec/utopia/content_spec.rb +0 -100
- data/spec/utopia/content_spec.ru +0 -6
- data/spec/utopia/content_spec/_heading.xnode +0 -1
- data/spec/utopia/content_spec/content/_show-value.xnode +0 -1
- data/spec/utopia/content_spec/content/links.yaml +0 -2
- data/spec/utopia/content_spec/content/test-partial.xnode +0 -1
- data/spec/utopia/content_spec/index.xnode +0 -1
- data/spec/utopia/content_spec/node/index.xnode +0 -1
- data/spec/utopia/content_spec/test.xnode +0 -10
- data/spec/utopia/controller/actions_spec.rb +0 -62
- data/spec/utopia/controller/middleware_spec.rb +0 -88
- data/spec/utopia/controller/middleware_spec.ru +0 -6
- data/spec/utopia/controller/middleware_spec/controller/controller.rb +0 -27
- data/spec/utopia/controller/middleware_spec/controller/index.xnode +0 -1
- data/spec/utopia/controller/middleware_spec/controller/nested/controller.rb +0 -7
- data/spec/utopia/controller/middleware_spec/empty/controller.rb +0 -0
- data/spec/utopia/controller/middleware_spec/redirect/controller.rb +0 -12
- data/spec/utopia/controller/middleware_spec/redirect/test/controller.rb +0 -9
- data/spec/utopia/controller/respond_spec.rb +0 -174
- data/spec/utopia/controller/respond_spec.ru +0 -12
- data/spec/utopia/controller/respond_spec/api/controller.rb +0 -28
- data/spec/utopia/controller/respond_spec/errors/controller.rb +0 -14
- data/spec/utopia/controller/respond_spec/errors/file-not-found.xnode +0 -8
- data/spec/utopia/controller/respond_spec/html/controller.rb +0 -11
- data/spec/utopia/controller/respond_spec/rewrite/controller.rb +0 -13
- data/spec/utopia/controller/rewrite_spec.rb +0 -80
- data/spec/utopia/controller/sequence_spec.rb +0 -135
- data/spec/utopia/controller/variables_spec.rb +0 -59
- data/spec/utopia/controller/websocket_spec.rb +0 -68
- data/spec/utopia/controller/websocket_spec.ru +0 -5
- data/spec/utopia/controller/websocket_spec/server/controller.rb +0 -11
- data/spec/utopia/exceptions/handler_spec.rb +0 -47
- data/spec/utopia/exceptions/handler_spec.ru +0 -8
- data/spec/utopia/exceptions/handler_spec/controller.rb +0 -19
- data/spec/utopia/exceptions/mailer_spec.rb +0 -43
- data/spec/utopia/exceptions/mailer_spec.ru +0 -10
- data/spec/utopia/extensions_spec.rb +0 -73
- data/spec/utopia/http/status_spec.rb +0 -44
- data/spec/utopia/locale_spec.rb +0 -58
- data/spec/utopia/localization_spec.rb +0 -92
- data/spec/utopia/localization_spec.ru +0 -15
- data/spec/utopia/localization_spec/controller.rb +0 -21
- data/spec/utopia/localization_spec/localized.de.txt +0 -1
- data/spec/utopia/localization_spec/localized.en.txt +0 -1
- data/spec/utopia/localization_spec/localized.ja.txt +0 -1
- data/spec/utopia/localization_spec/test.txt +0 -1
- data/spec/utopia/middleware_spec.rb +0 -31
- data/spec/utopia/path/matcher_spec.rb +0 -66
- data/spec/utopia/path_spec.rb +0 -207
- data/spec/utopia/performance_spec.rb +0 -92
- data/spec/utopia/performance_spec/cache/head/readme.txt +0 -1
- data/spec/utopia/performance_spec/cache/meta/readme.txt +0 -1
- data/spec/utopia/performance_spec/config.ru +0 -35
- data/spec/utopia/performance_spec/lib/readme.txt +0 -1
- data/spec/utopia/performance_spec/pages/_heading.xnode +0 -2
- data/spec/utopia/performance_spec/pages/_page.xnode +0 -26
- data/spec/utopia/performance_spec/pages/api/controller.rb +0 -8
- data/spec/utopia/performance_spec/pages/errors/exception.xnode +0 -5
- data/spec/utopia/performance_spec/pages/errors/file-not-found.xnode +0 -5
- data/spec/utopia/performance_spec/pages/links.yaml +0 -2
- data/spec/utopia/performance_spec/pages/welcome/index.xnode +0 -17
- data/spec/utopia/rack_helper.rb +0 -32
- data/spec/utopia/redirection_spec.rb +0 -77
- data/spec/utopia/redirection_spec.ru +0 -27
- data/spec/utopia/session_spec.rb +0 -189
- data/spec/utopia/session_spec.ru +0 -24
- data/spec/utopia/setup_spec.rb +0 -56
- data/spec/utopia/static_spec.rb +0 -49
- data/spec/utopia/static_spec.ru +0 -5
- data/spec/utopia/static_spec/test.txt +0 -1
- data/utopia.gemspec +0 -52
- data/wiki/Gemfile +0 -9
- data/wiki/config.ru +0 -7
- data/wiki/pages/development-environment-setup/index.md +0 -16
- data/wiki/pages/faq/links.yaml +0 -2
- data/wiki/pages/faq/what-is-xnode/index.md +0 -37
- data/wiki/pages/faq/what-is-xnode/links.yaml +0 -2
- data/wiki/pages/index.md +0 -35
- data/wiki/pages/javascript/index.md +0 -77
- data/wiki/pages/javascript/links.yaml +0 -2
- data/wiki/pages/links.yaml +0 -2
- data/wiki/pages/middleware/content/index.md +0 -21
- data/wiki/pages/middleware/controller/actions/index.md +0 -76
- data/wiki/pages/middleware/controller/index.md +0 -62
- data/wiki/pages/middleware/controller/links.yaml +0 -4
- data/wiki/pages/middleware/controller/rewrite/index.md +0 -69
- data/wiki/pages/middleware/localization/index.md +0 -16
- data/wiki/pages/middleware/redirection/index.md +0 -17
- data/wiki/pages/middleware/session/index.md +0 -29
- data/wiki/pages/middleware/static/index.md +0 -13
- data/wiki/pages/server-setup/index.md +0 -52
- data/wiki/pages/testing/index.md +0 -15
- data/wiki/pages/updating-utopia/index.md +0 -63
- 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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f1833aabc2d72234952e6ee164138d234cafc5d0d2015b64edcb28cead480c95
|
|
4
|
+
data.tar.gz: d6e9675b9921ae290547c25b11c8b5974860256393c65147705d0dd1472ba851
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
-
|
|
10
|
-
yarn_install_root = root + "public/_components"
|
|
9
|
+
package_root = root + "node_modules"
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
|
data/lib/utopia/command.rb
CHANGED
data/lib/utopia/command/site.rb
CHANGED
|
@@ -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 = ['.
|
|
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"]
|
data/lib/utopia/content.rb
CHANGED
|
@@ -177,17 +177,19 @@ module Utopia
|
|
|
177
177
|
end
|
|
178
178
|
|
|
179
179
|
def content_tag(name, node)
|
|
180
|
-
|
|
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
|
-
|
|
184
|
-
|
|
185
|
+
while full_path.last == name
|
|
186
|
+
full_path.pop
|
|
185
187
|
end
|
|
186
188
|
|
|
187
|
-
cache_key =
|
|
189
|
+
cache_key = full_path + name
|
|
188
190
|
|
|
189
191
|
@node_cache.fetch_or_store(cache_key) do
|
|
190
|
-
lookup_content(name,
|
|
192
|
+
lookup_content(name, full_path)
|
|
191
193
|
end
|
|
192
194
|
end
|
|
193
195
|
end
|
data/lib/utopia/content/node.rb
CHANGED
|
@@ -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(*
|
|
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(*
|
|
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 = '
|
|
27
|
-
CACHE_CONTROL = '
|
|
28
|
-
CONTENT_TYPE = '
|
|
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.
|
data/lib/utopia/controller.rb
CHANGED
|
@@ -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
|
|
123
|
-
headers[
|
|
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 '../
|
|
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
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
module Handlers
|
|
35
|
+
module JSON
|
|
36
|
+
APPLICATION_JSON = HTTP::Accept::ContentType.new('application', 'json').freeze
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
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
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
64
|
-
|
|
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.
|
|
73
|
-
|
|
54
|
+
def self.split(*arguments)
|
|
55
|
+
WILDCARD.split(*arguments)
|
|
74
56
|
end
|
|
75
57
|
|
|
76
|
-
def self.
|
|
77
|
-
|
|
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
|
-
|
|
99
|
-
|
|
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
|
|
106
|
-
|
|
69
|
+
def with_passthrough
|
|
70
|
+
@handlers << Handlers::Passthrough
|
|
107
71
|
end
|
|
108
72
|
|
|
109
|
-
def
|
|
110
|
-
|
|
73
|
+
def with(content_type, &block)
|
|
74
|
+
handle(content_type, &block)
|
|
111
75
|
end
|
|
112
76
|
end
|
|
113
77
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
-
|
|
123
|
-
@converters.freeze
|
|
124
|
-
|
|
125
|
-
super
|
|
126
|
-
end
|
|
83
|
+
alias respond responds
|
|
127
84
|
|
|
128
|
-
|
|
129
|
-
|
|
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
|
|
134
|
-
@
|
|
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
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
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
|
-
|
|
177
|
-
|
|
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(*
|
|
27
|
-
if middle = index(*
|
|
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, []]
|
data/lib/utopia/http.rb
CHANGED
|
@@ -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 = '
|
|
94
|
-
LOCATION = '
|
|
95
|
-
CACHE_CONTROL = '
|
|
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
|
data/lib/utopia/middleware.rb
CHANGED
|
@@ -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(*
|
|
43
|
-
Path[default_root(*
|
|
42
|
+
def self.default_path(*arguments)
|
|
43
|
+
Path[default_root(*arguments)]
|
|
44
44
|
end
|
|
45
45
|
end
|