pakyow-presenter 0.11.3 → 1.0.0.rc1
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 +5 -5
- data/{pakyow-presenter/CHANGELOG.md → CHANGELOG.md} +0 -5
- data/LICENSE +4 -0
- data/{pakyow-presenter/README.md → README.md} +1 -2
- data/lib/pakyow/generators/presenter/presenter_generator.rb +28 -0
- data/lib/pakyow/generators/presenter/templates/presenter.rb.tt +2 -0
- data/lib/pakyow/plugin/helpers/rendering.rb +19 -0
- data/lib/pakyow/presenter/actions/auto_render.rb +15 -0
- data/lib/pakyow/presenter/attributes/attribute.rb +22 -0
- data/lib/pakyow/presenter/attributes/boolean.rb +24 -0
- data/lib/pakyow/presenter/attributes/hash.rb +89 -0
- data/lib/pakyow/presenter/attributes/set.rb +61 -0
- data/lib/pakyow/presenter/attributes/string.rb +38 -0
- data/lib/pakyow/presenter/attributes.rb +126 -0
- data/lib/pakyow/presenter/behavior/config.rb +29 -0
- data/lib/pakyow/presenter/behavior/error_rendering.rb +124 -0
- data/lib/pakyow/presenter/behavior/exposures.rb +29 -0
- data/lib/pakyow/presenter/behavior/implicit_rendering.rb +21 -0
- data/lib/pakyow/presenter/behavior/initializing.rb +37 -0
- data/lib/pakyow/presenter/behavior/modes.rb +117 -0
- data/lib/pakyow/presenter/behavior/versions.rb +71 -0
- data/lib/pakyow/presenter/behavior/watching.rb +21 -0
- data/lib/pakyow/presenter/binder.rb +115 -0
- data/lib/pakyow/presenter/binding_parts.rb +64 -0
- data/lib/pakyow/presenter/component.rb +74 -0
- data/lib/pakyow/presenter/composers/component.rb +78 -0
- data/lib/pakyow/presenter/composers/view.rb +73 -0
- data/lib/pakyow/presenter/errors.rb +63 -0
- data/lib/pakyow/presenter/framework.rb +203 -0
- data/lib/pakyow/presenter/front_matter_parser.rb +42 -0
- data/lib/pakyow/presenter/helpers/rendering.rb +18 -0
- data/lib/pakyow/presenter/presentable.rb +28 -0
- data/lib/pakyow/presenter/presentable_error.rb +19 -0
- data/lib/pakyow/presenter/presenter.rb +766 -0
- data/lib/pakyow/presenter/presenters/endpoint.rb +158 -0
- data/lib/pakyow/presenter/presenters/form.rb +522 -0
- data/lib/pakyow/presenter/processor.rb +61 -0
- data/lib/pakyow/presenter/renderable.rb +28 -0
- data/lib/pakyow/presenter/renderer.rb +269 -0
- data/lib/pakyow/presenter/rendering/actions/cleanup_prototype_nodes.rb +21 -0
- data/lib/pakyow/presenter/rendering/actions/cleanup_unbound_bindings.rb +35 -0
- data/lib/pakyow/presenter/rendering/actions/create_template_nodes.rb +27 -0
- data/lib/pakyow/presenter/rendering/actions/insert_prototype_bar.rb +101 -0
- data/lib/pakyow/presenter/rendering/actions/install_authenticity.rb +42 -0
- data/lib/pakyow/presenter/rendering/actions/place_in_mode.rb +56 -0
- data/lib/pakyow/presenter/rendering/actions/render_components.rb +279 -0
- data/lib/pakyow/presenter/rendering/actions/set_page_title.rb +35 -0
- data/lib/pakyow/presenter/rendering/actions/setup_endpoints.rb +62 -0
- data/lib/pakyow/presenter/rendering/actions/setup_forms.rb +174 -0
- data/lib/pakyow/presenter/significant_nodes.rb +309 -0
- data/lib/pakyow/presenter/templates.rb +229 -0
- data/lib/pakyow/presenter/versioned_view.rb +209 -0
- data/lib/pakyow/presenter/view.rb +586 -0
- data/lib/pakyow/presenter/views/form.rb +58 -0
- data/lib/pakyow/presenter/views/layout.rb +32 -0
- data/lib/pakyow/presenter/views/page.rb +72 -0
- data/lib/pakyow/presenter/views/partial.rb +28 -0
- data/lib/pakyow/presenter.rb +33 -0
- data/lib/pakyow/views/errors/layouts/development_error.html +102 -0
- data/lib/pakyow/views/errors/layouts/production_error.html +27 -0
- data/lib/pakyow/views/errors/pages/404.html +12 -0
- data/lib/pakyow/views/errors/pages/500.html +12 -0
- data/lib/pakyow/views/errors/pages/development/500.html +39 -0
- data/lib/string_doc/attributes.rb +109 -0
- data/lib/string_doc/meta_attributes.rb +48 -0
- data/lib/string_doc/meta_node.rb +328 -0
- data/lib/string_doc/node.rb +377 -0
- data/lib/string_doc.rb +642 -0
- metadata +95 -75
- data/pakyow-presenter/LICENSE +0 -20
- data/pakyow-presenter/lib/pakyow/presenter/attributes.rb +0 -228
- data/pakyow-presenter/lib/pakyow/presenter/base.rb +0 -38
- data/pakyow-presenter/lib/pakyow/presenter/binder.rb +0 -116
- data/pakyow-presenter/lib/pakyow/presenter/binder_set.rb +0 -94
- data/pakyow-presenter/lib/pakyow/presenter/binding_eval.rb +0 -37
- data/pakyow-presenter/lib/pakyow/presenter/config/presenter.rb +0 -42
- data/pakyow-presenter/lib/pakyow/presenter/container.rb +0 -6
- data/pakyow-presenter/lib/pakyow/presenter/doc_helpers.rb +0 -17
- data/pakyow-presenter/lib/pakyow/presenter/exceptions.rb +0 -11
- data/pakyow-presenter/lib/pakyow/presenter/ext/app.rb +0 -33
- data/pakyow-presenter/lib/pakyow/presenter/ext/call_context.rb +0 -28
- data/pakyow-presenter/lib/pakyow/presenter/helpers.rb +0 -46
- data/pakyow-presenter/lib/pakyow/presenter/page.rb +0 -110
- data/pakyow-presenter/lib/pakyow/presenter/partial.rb +0 -6
- data/pakyow-presenter/lib/pakyow/presenter/presenter.rb +0 -232
- data/pakyow-presenter/lib/pakyow/presenter/string_doc.rb +0 -380
- data/pakyow-presenter/lib/pakyow/presenter/string_doc_parser.rb +0 -144
- data/pakyow-presenter/lib/pakyow/presenter/string_doc_renderer.rb +0 -18
- data/pakyow-presenter/lib/pakyow/presenter/template.rb +0 -51
- data/pakyow-presenter/lib/pakyow/presenter/view.rb +0 -541
- data/pakyow-presenter/lib/pakyow/presenter/view_collection.rb +0 -330
- data/pakyow-presenter/lib/pakyow/presenter/view_composer.rb +0 -237
- data/pakyow-presenter/lib/pakyow/presenter/view_context.rb +0 -111
- data/pakyow-presenter/lib/pakyow/presenter/view_store.rb +0 -262
- data/pakyow-presenter/lib/pakyow/presenter/view_store_loader.rb +0 -43
- data/pakyow-presenter/lib/pakyow/presenter/view_version.rb +0 -113
- data/pakyow-presenter/lib/pakyow/presenter.rb +0 -8
- data/pakyow-presenter/lib/pakyow/views/errors/404.erb +0 -26
- data/pakyow-presenter/lib/pakyow/views/errors/500.erb +0 -23
- data/pakyow-presenter/lib/pakyow-presenter.rb +0 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 1bd0c274a2f3fdcfc17a93a8390f6e785280815105100977f2e57770d44b3bb3
|
|
4
|
+
data.tar.gz: 270e993fbfd4ff58aac7ad070ab050e8b21029204e6a356ebf0fc82cd268aa25
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 30cd88cf117723d9800598412000b59b1a4d825a3a6766250209ba5e7ac902c579273f0160ddc055e2339342e0d7fa96e6ff91474e73d3273d7666e8bf4581e0
|
|
7
|
+
data.tar.gz: aef3ab5a380c55076f59e6947096a7c4e92c7c630263ca96627a1cd78cd9d99f11b870db904f169d109804346a81944593b4f0da818d45c99a2c1e793b7d7562
|
data/LICENSE
ADDED
|
@@ -16,8 +16,7 @@ Source code can be downloaded as part of the Pakyow project on Github:
|
|
|
16
16
|
|
|
17
17
|
# License
|
|
18
18
|
|
|
19
|
-
Pakyow Presenter is
|
|
20
|
-
License](http://opensource.org/licenses/MIT).
|
|
19
|
+
Pakyow Presenter is free and open-source under the [LGPLv3 license](https://choosealicense.com/licenses/lgpl-3.0/).
|
|
21
20
|
|
|
22
21
|
# Support
|
|
23
22
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "pakyow/generator"
|
|
4
|
+
|
|
5
|
+
module Pakyow
|
|
6
|
+
# @api private
|
|
7
|
+
module Generators
|
|
8
|
+
class Presenter < Generator
|
|
9
|
+
def self.source_root
|
|
10
|
+
File.expand_path("../", __FILE__)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
argument :app
|
|
14
|
+
argument :name
|
|
15
|
+
argument :view_path
|
|
16
|
+
|
|
17
|
+
def create_presenter
|
|
18
|
+
template("templates/presenter.rb.tt", File.join(app.config.src, "presenters/#{name}_presenter.rb"))
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
protected
|
|
22
|
+
|
|
23
|
+
def normalized_view_path
|
|
24
|
+
File.join("/", view_path)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "pakyow/support/extension"
|
|
4
|
+
|
|
5
|
+
module Pakyow
|
|
6
|
+
class Plugin
|
|
7
|
+
module Helpers
|
|
8
|
+
module Rendering
|
|
9
|
+
extend Support::Extension
|
|
10
|
+
|
|
11
|
+
prepend_methods do
|
|
12
|
+
def render(path = @connection.get(:__endpoint_path) || @connection.path, *args)
|
|
13
|
+
super(File.join(@connection.app.class.mount_path, path), *args)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pakyow
|
|
4
|
+
module Presenter
|
|
5
|
+
module Actions
|
|
6
|
+
# Renders a view in the case a controller wasn't called.
|
|
7
|
+
#
|
|
8
|
+
class AutoRender
|
|
9
|
+
def call(connection)
|
|
10
|
+
connection.app.isolated(:Renderer).render_implicitly(connection)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pakyow
|
|
4
|
+
module Presenter
|
|
5
|
+
class Attributes
|
|
6
|
+
# @api private
|
|
7
|
+
class Attribute
|
|
8
|
+
def initialize(value)
|
|
9
|
+
@value = value
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def initialize_copy(_)
|
|
13
|
+
@value = @value.dup
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def ==(other)
|
|
17
|
+
@value == other
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "pakyow/presenter/attributes/string"
|
|
4
|
+
|
|
5
|
+
module Pakyow
|
|
6
|
+
module Presenter
|
|
7
|
+
class Attributes
|
|
8
|
+
# Boolean is an odd attribute, since we ultimately want it to behave in this way:
|
|
9
|
+
#
|
|
10
|
+
# view.attrs[:checked] = true
|
|
11
|
+
# => <input checked="checked" ...>
|
|
12
|
+
#
|
|
13
|
+
# view.attrs[:checked] = false
|
|
14
|
+
# => <input ...>
|
|
15
|
+
#
|
|
16
|
+
# To support this, +Attributes+ manages setting / removing the value on the
|
|
17
|
+
# underlying object; all we do is behave like a String.
|
|
18
|
+
#
|
|
19
|
+
# @api private
|
|
20
|
+
class Boolean < String
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "forwardable"
|
|
4
|
+
|
|
5
|
+
require "pakyow/support/safe_string"
|
|
6
|
+
|
|
7
|
+
require "pakyow/presenter/attributes/attribute"
|
|
8
|
+
|
|
9
|
+
module Pakyow
|
|
10
|
+
module Presenter
|
|
11
|
+
class Attributes
|
|
12
|
+
# Wraps the value for a hash-type view attribute (e.g. style).
|
|
13
|
+
#
|
|
14
|
+
# Behaves just like a normal +Hash+.
|
|
15
|
+
#
|
|
16
|
+
class Hash < Attribute
|
|
17
|
+
VALUE_SEPARATOR = ":".freeze
|
|
18
|
+
PAIR_SEPARATOR = ";".freeze
|
|
19
|
+
|
|
20
|
+
WRITE_VALUE_SEPARATOR = ": ".freeze
|
|
21
|
+
WRITE_PAIR_SEPARATOR = "; ".freeze
|
|
22
|
+
|
|
23
|
+
extend Forwardable
|
|
24
|
+
def_delegators :@value, :any?, :empty?, :clear
|
|
25
|
+
|
|
26
|
+
include Support::SafeStringHelpers
|
|
27
|
+
|
|
28
|
+
def include?(key)
|
|
29
|
+
@value.include?(key.to_s)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def value?(value)
|
|
33
|
+
@value.value?(value.to_s)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def [](key)
|
|
37
|
+
@value[key.to_s]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def []=(key, value)
|
|
41
|
+
@value[ensure_html_safety(key)] = ensure_html_safety(value)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def delete(key)
|
|
45
|
+
@value.delete(key.to_s)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def to_s
|
|
49
|
+
string = ::String.new
|
|
50
|
+
first = true
|
|
51
|
+
@value.each do |key, value|
|
|
52
|
+
unless first
|
|
53
|
+
string << WRITE_PAIR_SEPARATOR
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
string << key
|
|
57
|
+
string << WRITE_VALUE_SEPARATOR
|
|
58
|
+
string << value
|
|
59
|
+
first = false
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
unless string.empty?
|
|
63
|
+
string = string + PAIR_SEPARATOR
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
string
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
class << self
|
|
70
|
+
include Support::SafeStringHelpers
|
|
71
|
+
|
|
72
|
+
def parse(value)
|
|
73
|
+
if value.is_a?(::Hash)
|
|
74
|
+
new(::Hash[value.map { |k, v| [ensure_html_safety(k), ensure_html_safety(v.to_s)]}])
|
|
75
|
+
elsif value.respond_to?(:to_s)
|
|
76
|
+
new(value.to_s.split(PAIR_SEPARATOR).each_with_object({}) { |style, attributes|
|
|
77
|
+
key, value = style.split(VALUE_SEPARATOR)
|
|
78
|
+
next unless key && value
|
|
79
|
+
attributes[ensure_html_safety(key.strip)] = ensure_html_safety(value.strip)
|
|
80
|
+
})
|
|
81
|
+
else
|
|
82
|
+
raise ArgumentError.new("expected value to be a Hash or String")
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "forwardable"
|
|
4
|
+
require "set"
|
|
5
|
+
|
|
6
|
+
require "pakyow/support/safe_string"
|
|
7
|
+
|
|
8
|
+
require "pakyow/presenter/attributes/attribute"
|
|
9
|
+
|
|
10
|
+
module Pakyow
|
|
11
|
+
module Presenter
|
|
12
|
+
class Attributes
|
|
13
|
+
# Wraps the value for a set-type view attribute (e.g. class).
|
|
14
|
+
#
|
|
15
|
+
# Behaves just like a normal +Set+.
|
|
16
|
+
#
|
|
17
|
+
class Set < Attribute
|
|
18
|
+
VALUE_SEPARATOR = " ".freeze
|
|
19
|
+
|
|
20
|
+
extend Forwardable
|
|
21
|
+
def_delegators :@value, :to_a, :any?, :empty?, :clear
|
|
22
|
+
|
|
23
|
+
include Support::SafeStringHelpers
|
|
24
|
+
|
|
25
|
+
def include?(value)
|
|
26
|
+
@value.include?(value.to_s)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def <<(value)
|
|
30
|
+
@value << ensure_html_safety(value)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def add(value)
|
|
34
|
+
@value.add(ensure_html_safety(value))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def delete(value)
|
|
38
|
+
@value.delete(value.to_s)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def to_s
|
|
42
|
+
@value.to_a.join(VALUE_SEPARATOR)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
class << self
|
|
46
|
+
include Support::SafeStringHelpers
|
|
47
|
+
|
|
48
|
+
def parse(value)
|
|
49
|
+
if value.is_a?(Array) || value.is_a?(::Set)
|
|
50
|
+
new(::Set.new(value.map { |v| ensure_html_safety(v) }))
|
|
51
|
+
elsif value.respond_to?(:to_s)
|
|
52
|
+
new(::Set.new(value.to_s.split(VALUE_SEPARATOR).map { |v| ensure_html_safety(v) }))
|
|
53
|
+
else
|
|
54
|
+
raise ArgumentError.new("expected value to be an Array, Set, or String")
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "forwardable"
|
|
4
|
+
|
|
5
|
+
require "pakyow/support/safe_string"
|
|
6
|
+
|
|
7
|
+
require "pakyow/presenter/attributes/attribute"
|
|
8
|
+
|
|
9
|
+
module Pakyow
|
|
10
|
+
module Presenter
|
|
11
|
+
class Attributes
|
|
12
|
+
# Wraps the value for a string-type view attribute (e.g. href).
|
|
13
|
+
#
|
|
14
|
+
# Behaves just like a normal +String+.
|
|
15
|
+
#
|
|
16
|
+
class String < Attribute
|
|
17
|
+
extend Forwardable
|
|
18
|
+
def_delegators :@value, :empty?, :include?
|
|
19
|
+
|
|
20
|
+
def to_s
|
|
21
|
+
@value
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def to_str
|
|
25
|
+
to_s
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
class << self
|
|
29
|
+
include Support::SafeStringHelpers
|
|
30
|
+
|
|
31
|
+
def parse(value)
|
|
32
|
+
new(ensure_html_safety(value.to_s))
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "forwardable"
|
|
4
|
+
|
|
5
|
+
require "pakyow/support/safe_string"
|
|
6
|
+
|
|
7
|
+
require "pakyow/presenter/attributes/boolean"
|
|
8
|
+
require "pakyow/presenter/attributes/hash"
|
|
9
|
+
require "pakyow/presenter/attributes/set"
|
|
10
|
+
require "pakyow/presenter/attributes/string"
|
|
11
|
+
|
|
12
|
+
module Pakyow
|
|
13
|
+
module Presenter
|
|
14
|
+
class Attributes
|
|
15
|
+
class << self
|
|
16
|
+
def typed_value_for_attribute_with_name(value, name)
|
|
17
|
+
type = type_of_attribute(name.to_sym)
|
|
18
|
+
|
|
19
|
+
if value.is_a?(type)
|
|
20
|
+
value
|
|
21
|
+
else
|
|
22
|
+
type.parse(value)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def type_of_attribute(attribute)
|
|
27
|
+
ATTRIBUTE_TYPES[attribute.to_sym] || ATTRIBUTE_TYPE_DEFAULT
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def default_value_for_attribute(attribute)
|
|
31
|
+
type = type_of_attribute(attribute.to_sym)
|
|
32
|
+
if type == ATTRIBUTE_TYPE_SET
|
|
33
|
+
::Set.new
|
|
34
|
+
elsif type == ATTRIBUTE_TYPE_HASH
|
|
35
|
+
::Hash.new
|
|
36
|
+
elsif type == ATTRIBUTE_TYPE_BOOLEAN
|
|
37
|
+
false
|
|
38
|
+
else
|
|
39
|
+
::String.new
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Object for hash attributes
|
|
45
|
+
ATTRIBUTE_TYPE_HASH = Attributes::Hash
|
|
46
|
+
# Object for set attributes
|
|
47
|
+
ATTRIBUTE_TYPE_SET = Attributes::Set
|
|
48
|
+
# Object for boolean attributes
|
|
49
|
+
ATTRIBUTE_TYPE_BOOLEAN = Attributes::Boolean
|
|
50
|
+
# Default attribute object
|
|
51
|
+
ATTRIBUTE_TYPE_DEFAULT = Attributes::String
|
|
52
|
+
|
|
53
|
+
# Maps non-default attributes to their type
|
|
54
|
+
ATTRIBUTE_TYPES = {
|
|
55
|
+
class: ATTRIBUTE_TYPE_SET,
|
|
56
|
+
style: ATTRIBUTE_TYPE_HASH,
|
|
57
|
+
selected: ATTRIBUTE_TYPE_BOOLEAN,
|
|
58
|
+
checked: ATTRIBUTE_TYPE_BOOLEAN,
|
|
59
|
+
disabled: ATTRIBUTE_TYPE_BOOLEAN,
|
|
60
|
+
readonly: ATTRIBUTE_TYPE_BOOLEAN,
|
|
61
|
+
multiple: ATTRIBUTE_TYPE_BOOLEAN,
|
|
62
|
+
}.freeze
|
|
63
|
+
|
|
64
|
+
extend Forwardable
|
|
65
|
+
|
|
66
|
+
include Support::SafeStringHelpers
|
|
67
|
+
|
|
68
|
+
# @!method keys
|
|
69
|
+
# Returns keys from {@attributes}.
|
|
70
|
+
#
|
|
71
|
+
# @!method []
|
|
72
|
+
# Returns value of key from {@attributes}.
|
|
73
|
+
#
|
|
74
|
+
# @!method []=
|
|
75
|
+
# Returns sets value for key on {@attributes}.
|
|
76
|
+
#
|
|
77
|
+
# @!method delete
|
|
78
|
+
# Deletes key by name from {@attributes}.
|
|
79
|
+
#
|
|
80
|
+
def_delegators :@attributes, :keys, :delete, :each
|
|
81
|
+
|
|
82
|
+
# Wraps a hash of view attributes
|
|
83
|
+
#
|
|
84
|
+
# @param attributes [Hash]
|
|
85
|
+
#
|
|
86
|
+
def initialize(attributes)
|
|
87
|
+
attributes.wrap do |value, name|
|
|
88
|
+
Attributes.typed_value_for_attribute_with_name(value, name)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
@attributes = attributes
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def [](attribute)
|
|
95
|
+
attribute = attribute.to_sym
|
|
96
|
+
attribute_type = self.class.type_of_attribute(attribute)
|
|
97
|
+
|
|
98
|
+
if attribute_type == ATTRIBUTE_TYPE_BOOLEAN
|
|
99
|
+
@attributes.key?(attribute)
|
|
100
|
+
else
|
|
101
|
+
@attributes[attribute] ||= attribute_type.new(self.class.default_value_for_attribute(attribute))
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def []=(attribute, value)
|
|
106
|
+
attribute = ensure_html_safety(attribute.to_s).to_sym
|
|
107
|
+
|
|
108
|
+
if value.nil?
|
|
109
|
+
@attributes.delete(attribute)
|
|
110
|
+
elsif self.class.type_of_attribute(attribute) == ATTRIBUTE_TYPE_BOOLEAN
|
|
111
|
+
if value
|
|
112
|
+
@attributes[attribute] = self.class.typed_value_for_attribute_with_name(attribute, attribute)
|
|
113
|
+
else
|
|
114
|
+
@attributes.delete(attribute)
|
|
115
|
+
end
|
|
116
|
+
else
|
|
117
|
+
@attributes[attribute] = self.class.typed_value_for_attribute_with_name(value, attribute)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def has?(attribute)
|
|
122
|
+
@attributes.key?(attribute.to_sym)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "pakyow/support/extension"
|
|
4
|
+
require "pakyow/support/path_version"
|
|
5
|
+
|
|
6
|
+
module Pakyow
|
|
7
|
+
module Presenter
|
|
8
|
+
module Behavior
|
|
9
|
+
module Config
|
|
10
|
+
extend Support::Extension
|
|
11
|
+
|
|
12
|
+
apply_extension do
|
|
13
|
+
configurable :presenter do
|
|
14
|
+
setting :path do
|
|
15
|
+
File.join(config.root, "frontend")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
setting :embed_authenticity_token, true
|
|
19
|
+
setting :version
|
|
20
|
+
|
|
21
|
+
configurable :features do
|
|
22
|
+
setting :streaming, false
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cgi"
|
|
4
|
+
|
|
5
|
+
require "redcarpet"
|
|
6
|
+
|
|
7
|
+
require "pakyow/support/bindable"
|
|
8
|
+
require "pakyow/support/extension"
|
|
9
|
+
|
|
10
|
+
require "pakyow/error"
|
|
11
|
+
|
|
12
|
+
module Pakyow
|
|
13
|
+
module Presenter
|
|
14
|
+
module Behavior
|
|
15
|
+
module ErrorRendering
|
|
16
|
+
extend Support::Extension
|
|
17
|
+
|
|
18
|
+
def self.render_error(error, context)
|
|
19
|
+
context.respond_to :html do
|
|
20
|
+
if Pakyow.env?(:production)
|
|
21
|
+
context.render "/500"
|
|
22
|
+
else
|
|
23
|
+
unless error.is_a?(Pakyow::Error)
|
|
24
|
+
error = Pakyow::Error.build(error)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
error.extend Support::Bindable
|
|
28
|
+
context.expose :pw_error, error
|
|
29
|
+
context.render "/development/500"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
apply_extension do
|
|
35
|
+
handle 404 do
|
|
36
|
+
respond_to :html do
|
|
37
|
+
render "/404"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
handle 500 do |error|
|
|
42
|
+
ErrorRendering.render_error(error, self)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
handle UnknownPage, as: 404 do |error|
|
|
46
|
+
if Pakyow.env?(:production)
|
|
47
|
+
trigger 404
|
|
48
|
+
else
|
|
49
|
+
ErrorRendering.render_error(error, self)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
handle ImplicitRenderingError, as: 404 do |error|
|
|
54
|
+
if Pakyow.env?(:production)
|
|
55
|
+
trigger 404
|
|
56
|
+
else
|
|
57
|
+
ErrorRendering.render_error(error, self)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
binder :pw_error do
|
|
62
|
+
def message
|
|
63
|
+
html_safe(markdown.render(format(object.message)))
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def contextual_message
|
|
67
|
+
if object.respond_to?(:contextual_message)
|
|
68
|
+
html_safe(markdown.render(format(object.contextual_message)))
|
|
69
|
+
else
|
|
70
|
+
nil
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def details
|
|
75
|
+
html_safe(markdown.render(format(object.details)))
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def backtrace
|
|
79
|
+
html_safe(object.condensed_backtrace.to_a.map { |line|
|
|
80
|
+
CGI.escape_html(line)
|
|
81
|
+
}.join("<br>"))
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def link
|
|
85
|
+
part :href do
|
|
86
|
+
object.url
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
part :content do
|
|
90
|
+
object.url
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
private
|
|
95
|
+
|
|
96
|
+
def markdown
|
|
97
|
+
@markdown ||= Redcarpet::Markdown.new(
|
|
98
|
+
Redcarpet::Render::HTML.new({})
|
|
99
|
+
)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def format(string)
|
|
103
|
+
string = string.dup
|
|
104
|
+
|
|
105
|
+
# Replace `foo' with `foo` to render as inline code.
|
|
106
|
+
#
|
|
107
|
+
string.dup.scan(/`([^']*)'/).each do |match|
|
|
108
|
+
string.gsub!("`#{match[0]}'", "`#{match[0]}`")
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Format object references as inline code.
|
|
112
|
+
#
|
|
113
|
+
string.dup.scan(/#<(.*)>/).each do |match|
|
|
114
|
+
string.gsub!("#<#{match[0]}>", "`#<#{match[0]}>`")
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
string
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "pakyow/support/extension"
|
|
4
|
+
|
|
5
|
+
module Pakyow
|
|
6
|
+
module Presenter
|
|
7
|
+
module Behavior
|
|
8
|
+
module Exposures
|
|
9
|
+
extend Support::Extension
|
|
10
|
+
|
|
11
|
+
apply_extension do
|
|
12
|
+
unless ancestors.include?(Plugin)
|
|
13
|
+
# Copy exposures from the plugin renderer.
|
|
14
|
+
#
|
|
15
|
+
after "load.plugins" do
|
|
16
|
+
plugs.each do |plug|
|
|
17
|
+
plug.isolated(:Renderer).__expose_fns.each do |fn|
|
|
18
|
+
isolated(:Renderer).send(:expose) do |connection|
|
|
19
|
+
fn.call(connection, plug)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "pakyow/support/extension"
|
|
4
|
+
|
|
5
|
+
module Pakyow
|
|
6
|
+
module Presenter
|
|
7
|
+
module Behavior
|
|
8
|
+
# Performs a render if a controller is called but doesn't explicitly render.
|
|
9
|
+
#
|
|
10
|
+
module ImplicitRendering
|
|
11
|
+
extend Support::Extension
|
|
12
|
+
|
|
13
|
+
apply_extension do
|
|
14
|
+
after :dispatch, :implicit_render do
|
|
15
|
+
connection.app.isolated(:Renderer).render_implicitly(connection)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|