pakyow-presenter 0.11.3 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|