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.
Files changed (100) hide show
  1. checksums.yaml +5 -5
  2. data/{pakyow-presenter/CHANGELOG.md → CHANGELOG.md} +0 -5
  3. data/LICENSE +4 -0
  4. data/{pakyow-presenter/README.md → README.md} +1 -2
  5. data/lib/pakyow/generators/presenter/presenter_generator.rb +28 -0
  6. data/lib/pakyow/generators/presenter/templates/presenter.rb.tt +2 -0
  7. data/lib/pakyow/plugin/helpers/rendering.rb +19 -0
  8. data/lib/pakyow/presenter/actions/auto_render.rb +15 -0
  9. data/lib/pakyow/presenter/attributes/attribute.rb +22 -0
  10. data/lib/pakyow/presenter/attributes/boolean.rb +24 -0
  11. data/lib/pakyow/presenter/attributes/hash.rb +89 -0
  12. data/lib/pakyow/presenter/attributes/set.rb +61 -0
  13. data/lib/pakyow/presenter/attributes/string.rb +38 -0
  14. data/lib/pakyow/presenter/attributes.rb +126 -0
  15. data/lib/pakyow/presenter/behavior/config.rb +29 -0
  16. data/lib/pakyow/presenter/behavior/error_rendering.rb +124 -0
  17. data/lib/pakyow/presenter/behavior/exposures.rb +29 -0
  18. data/lib/pakyow/presenter/behavior/implicit_rendering.rb +21 -0
  19. data/lib/pakyow/presenter/behavior/initializing.rb +37 -0
  20. data/lib/pakyow/presenter/behavior/modes.rb +117 -0
  21. data/lib/pakyow/presenter/behavior/versions.rb +71 -0
  22. data/lib/pakyow/presenter/behavior/watching.rb +21 -0
  23. data/lib/pakyow/presenter/binder.rb +115 -0
  24. data/lib/pakyow/presenter/binding_parts.rb +64 -0
  25. data/lib/pakyow/presenter/component.rb +74 -0
  26. data/lib/pakyow/presenter/composers/component.rb +78 -0
  27. data/lib/pakyow/presenter/composers/view.rb +73 -0
  28. data/lib/pakyow/presenter/errors.rb +63 -0
  29. data/lib/pakyow/presenter/framework.rb +203 -0
  30. data/lib/pakyow/presenter/front_matter_parser.rb +42 -0
  31. data/lib/pakyow/presenter/helpers/rendering.rb +18 -0
  32. data/lib/pakyow/presenter/presentable.rb +28 -0
  33. data/lib/pakyow/presenter/presentable_error.rb +19 -0
  34. data/lib/pakyow/presenter/presenter.rb +766 -0
  35. data/lib/pakyow/presenter/presenters/endpoint.rb +158 -0
  36. data/lib/pakyow/presenter/presenters/form.rb +522 -0
  37. data/lib/pakyow/presenter/processor.rb +61 -0
  38. data/lib/pakyow/presenter/renderable.rb +28 -0
  39. data/lib/pakyow/presenter/renderer.rb +269 -0
  40. data/lib/pakyow/presenter/rendering/actions/cleanup_prototype_nodes.rb +21 -0
  41. data/lib/pakyow/presenter/rendering/actions/cleanup_unbound_bindings.rb +35 -0
  42. data/lib/pakyow/presenter/rendering/actions/create_template_nodes.rb +27 -0
  43. data/lib/pakyow/presenter/rendering/actions/insert_prototype_bar.rb +101 -0
  44. data/lib/pakyow/presenter/rendering/actions/install_authenticity.rb +42 -0
  45. data/lib/pakyow/presenter/rendering/actions/place_in_mode.rb +56 -0
  46. data/lib/pakyow/presenter/rendering/actions/render_components.rb +279 -0
  47. data/lib/pakyow/presenter/rendering/actions/set_page_title.rb +35 -0
  48. data/lib/pakyow/presenter/rendering/actions/setup_endpoints.rb +62 -0
  49. data/lib/pakyow/presenter/rendering/actions/setup_forms.rb +174 -0
  50. data/lib/pakyow/presenter/significant_nodes.rb +309 -0
  51. data/lib/pakyow/presenter/templates.rb +229 -0
  52. data/lib/pakyow/presenter/versioned_view.rb +209 -0
  53. data/lib/pakyow/presenter/view.rb +586 -0
  54. data/lib/pakyow/presenter/views/form.rb +58 -0
  55. data/lib/pakyow/presenter/views/layout.rb +32 -0
  56. data/lib/pakyow/presenter/views/page.rb +72 -0
  57. data/lib/pakyow/presenter/views/partial.rb +28 -0
  58. data/lib/pakyow/presenter.rb +33 -0
  59. data/lib/pakyow/views/errors/layouts/development_error.html +102 -0
  60. data/lib/pakyow/views/errors/layouts/production_error.html +27 -0
  61. data/lib/pakyow/views/errors/pages/404.html +12 -0
  62. data/lib/pakyow/views/errors/pages/500.html +12 -0
  63. data/lib/pakyow/views/errors/pages/development/500.html +39 -0
  64. data/lib/string_doc/attributes.rb +109 -0
  65. data/lib/string_doc/meta_attributes.rb +48 -0
  66. data/lib/string_doc/meta_node.rb +328 -0
  67. data/lib/string_doc/node.rb +377 -0
  68. data/lib/string_doc.rb +642 -0
  69. metadata +95 -75
  70. data/pakyow-presenter/LICENSE +0 -20
  71. data/pakyow-presenter/lib/pakyow/presenter/attributes.rb +0 -228
  72. data/pakyow-presenter/lib/pakyow/presenter/base.rb +0 -38
  73. data/pakyow-presenter/lib/pakyow/presenter/binder.rb +0 -116
  74. data/pakyow-presenter/lib/pakyow/presenter/binder_set.rb +0 -94
  75. data/pakyow-presenter/lib/pakyow/presenter/binding_eval.rb +0 -37
  76. data/pakyow-presenter/lib/pakyow/presenter/config/presenter.rb +0 -42
  77. data/pakyow-presenter/lib/pakyow/presenter/container.rb +0 -6
  78. data/pakyow-presenter/lib/pakyow/presenter/doc_helpers.rb +0 -17
  79. data/pakyow-presenter/lib/pakyow/presenter/exceptions.rb +0 -11
  80. data/pakyow-presenter/lib/pakyow/presenter/ext/app.rb +0 -33
  81. data/pakyow-presenter/lib/pakyow/presenter/ext/call_context.rb +0 -28
  82. data/pakyow-presenter/lib/pakyow/presenter/helpers.rb +0 -46
  83. data/pakyow-presenter/lib/pakyow/presenter/page.rb +0 -110
  84. data/pakyow-presenter/lib/pakyow/presenter/partial.rb +0 -6
  85. data/pakyow-presenter/lib/pakyow/presenter/presenter.rb +0 -232
  86. data/pakyow-presenter/lib/pakyow/presenter/string_doc.rb +0 -380
  87. data/pakyow-presenter/lib/pakyow/presenter/string_doc_parser.rb +0 -144
  88. data/pakyow-presenter/lib/pakyow/presenter/string_doc_renderer.rb +0 -18
  89. data/pakyow-presenter/lib/pakyow/presenter/template.rb +0 -51
  90. data/pakyow-presenter/lib/pakyow/presenter/view.rb +0 -541
  91. data/pakyow-presenter/lib/pakyow/presenter/view_collection.rb +0 -330
  92. data/pakyow-presenter/lib/pakyow/presenter/view_composer.rb +0 -237
  93. data/pakyow-presenter/lib/pakyow/presenter/view_context.rb +0 -111
  94. data/pakyow-presenter/lib/pakyow/presenter/view_store.rb +0 -262
  95. data/pakyow-presenter/lib/pakyow/presenter/view_store_loader.rb +0 -43
  96. data/pakyow-presenter/lib/pakyow/presenter/view_version.rb +0 -113
  97. data/pakyow-presenter/lib/pakyow/presenter.rb +0 -8
  98. data/pakyow-presenter/lib/pakyow/views/errors/404.erb +0 -26
  99. data/pakyow-presenter/lib/pakyow/views/errors/500.erb +0 -23
  100. data/pakyow-presenter/lib/pakyow-presenter.rb +0 -1
@@ -1,262 +0,0 @@
1
- module Pakyow
2
- module Presenter
3
- class ViewStore
4
- attr_reader :store_name, :store_paths, :templates
5
-
6
- def initialize(store_path_or_paths, store_name = :default)
7
- @store_name = store_name
8
- @store_paths = Array.ensure(store_path_or_paths)
9
-
10
- load_templates
11
- load_path_info
12
- end
13
-
14
- def at?(view_path)
15
- begin
16
- at_path(view_path)
17
- return true
18
- rescue MissingView
19
- return false
20
- end
21
- end
22
-
23
- def template(name_or_path)
24
- return name_or_path if name_or_path.is_a?(Template)
25
-
26
- if name_or_path.is_a?(Symbol)
27
- return template_with_name(name_or_path)
28
- else
29
- return at_path(name_or_path, :template)
30
- end
31
- end
32
-
33
- def page(view_path)
34
- return view_path if view_path.is_a?(Page)
35
-
36
- raise ArgumentError, "Cannot build page for nil path" if view_path.nil?
37
- return at_path(view_path, :page)
38
- end
39
-
40
- def partials(view_path)
41
- return at_path(view_path, :partials) || {}
42
- end
43
-
44
- def partial(view_path, name)
45
- return partials(view_path)[name.to_sym]
46
- end
47
-
48
- def composer(view_path)
49
- return at_path(view_path, :composer)
50
- end
51
-
52
- def view(view_path)
53
- return composer(view_path).view
54
- end
55
-
56
- # iterations through known views, yielding each
57
- def views
58
- @path_info.each_pair do |path, info|
59
- yield(info[:composer].view, path)
60
- end
61
- end
62
-
63
- def infos
64
- @path_info.each_pair do |path, info|
65
- yield(info, path)
66
- end
67
- end
68
-
69
- def expand_path(view_path)
70
- @store_paths.each do |store_path|
71
- path = File.join(store_path, view_path)
72
-
73
- if File.extname(path).empty?
74
- return path if !Dir.glob(path + '.*').empty?
75
- else
76
- return path if File.exist?(path)
77
- end
78
- end
79
-
80
- nil
81
- end
82
-
83
- # Builds the full path to a partial.
84
- #
85
- # expand_partial_path('path/to/partial')
86
- # # => '{store_path}/path/to/_partial.html'
87
- def expand_partial_path(path)
88
- parts = path.split('/')
89
-
90
- # add underscore
91
- expanded_path = expand_path((parts[0..-2] << "_#{parts[-1]}").join('/'))
92
-
93
- # attempt to find extension
94
- matches = Dir.glob(expanded_path + '.*')
95
- raise MissingPartial, "Could not find partial with any extension at #{expanded_path}" if matches.empty?
96
-
97
- return expanded_path + File.extname(matches[0])
98
- end
99
-
100
- private
101
-
102
- def at_path(view_path, obj = nil)
103
- normalized_path = normalize_path(view_path)
104
- info = @path_info[normalized_path]
105
-
106
- if info.nil?
107
- raise MissingView, "No view at path '#{view_path}'"
108
- else
109
- #TODO need to consider whose responsibility it is to make the dups
110
- view = obj ? info[obj.to_sym] : info
111
- raise MissingView, "No #{obj} at path '#{view_path}'" if view.nil?
112
- return Pakyow::Utils::Dup.deep(view)
113
- end
114
- end
115
-
116
- def template_with_name(name)
117
- load_templates
118
-
119
- unless template = @templates[name.to_sym]
120
- raise MissingTemplate, "No template named '#{name}'"
121
- end
122
-
123
- return template.dup
124
- end
125
-
126
- def load_templates
127
- return if templates_loaded?
128
-
129
- @templates = {}
130
- @store_paths.each do |store_path|
131
- t_path = templates_path(store_path)
132
- next unless File.exists?(t_path)
133
-
134
- Dir.entries(t_path).each do |file|
135
- next if file =~ /^\./
136
-
137
- template = Template.load(File.join(t_path, file))
138
- @templates[template.name] = template
139
- end
140
- end
141
-
142
- @templates_loaded = true
143
- end
144
-
145
- def templates_loaded?
146
- @templates_loaded == true
147
- end
148
-
149
- def templates_path(store_path)
150
- return File.join(store_path, Config.presenter.template_dir(@store_name))
151
- end
152
-
153
- def load_path_info
154
- @path_info = {}
155
-
156
- # for keeping up with pages for previous paths
157
- pages = {}
158
-
159
- @store_paths.each do |store_path|
160
- Dir.walk(store_path) do |path|
161
- # don't include templates
162
- next if path.include?(templates_path(store_path))
163
-
164
- # skip partial files
165
- next if File.basename(path)[0,1] == '_'
166
-
167
- # skip non-empty folders (these files will be picked up)
168
- next unless Dir.glob(File.join(path, 'index.*')).empty?
169
-
170
- normalized_path = normalize_path(path, store_path)
171
-
172
- # if path is a directory we know there's no index page
173
- # so use the previous index page instead. this allows
174
- # partials to be overridden at a path while the same
175
- # page is used
176
- if File.directory?(path)
177
- # gets the path for the previous page
178
- prev_path = normalized_path
179
- until page = pages[prev_path]
180
- break if prev_path.empty?
181
- prev_path = prev_path.split('/')[0..-2].join("/")
182
- end
183
- page = page
184
- else
185
- page = Page.load(path)
186
- pages[normalized_path] = page
187
- end
188
-
189
- unless page.nil?
190
- template = template_with_name(page.info(:template))
191
- end
192
-
193
- #TODO more efficient way of doing this? lot of redundant calls here
194
- partials = partials_at_path(path)
195
-
196
- unless page.nil?
197
- # compose template/page/partials
198
- composer = ViewComposer.from_path(self, normalized_path, template: template, page: page, includes: partials)
199
- end
200
-
201
- info = {
202
- page: page,
203
- template: template,
204
- partials: partials,
205
- composer: composer,
206
- }
207
-
208
- @path_info[normalized_path] = info
209
- end
210
- end
211
-
212
- @path_info = Hash[@path_info.sort { |a, b| a <=> b }]
213
- end
214
-
215
- def normalize_path(path, store_path = nil)
216
- if store_path
217
- relative_path = path.gsub(store_path, '')
218
- else
219
- relative_path = path
220
- @store_paths.each do |store_path|
221
- relative_path = relative_path.gsub(store_path, '')
222
- end
223
- end
224
-
225
- relative_path = relative_path.gsub(File.extname(relative_path), '')
226
- relative_path = relative_path.gsub('index', '')
227
- relative_path = String.normalize_path(relative_path)
228
-
229
- return relative_path
230
- end
231
-
232
- def partials_at_path(view_path)
233
- view_path = File.dirname(view_path) unless File.directory?(view_path)
234
- view_path = normalize_path(view_path)
235
-
236
- partials = {}
237
- @store_paths.each do |store_path|
238
- Dir.walk(store_path) do |path|
239
- # skip non-partials
240
- next unless File.basename(path)[0,1] == '_'
241
-
242
- # skip directories
243
- next if File.directory?(path)
244
-
245
- # skip files not within `view_path`
246
- next unless Dir.within_dir?(normalize_path(File.dirname(path), store_path), view_path)
247
-
248
- name = File.basename(path.split('/')[-1], '.*')[1..-1]
249
- partials[name.to_sym] = path
250
- end
251
- end
252
-
253
- # create instances
254
- partials.each do |name, path|
255
- partials[name] = Partial.load(path)
256
- end
257
-
258
- return partials
259
- end
260
- end
261
- end
262
- end
@@ -1,43 +0,0 @@
1
- module Pakyow
2
- module Presenter
3
- class ViewStoreLoader
4
- include Singleton
5
-
6
- def initialize
7
- @last_mod = {}
8
- end
9
-
10
- def modified?(name, paths)
11
- paths = Array.ensure(paths)
12
-
13
- if !@last_mod.key?(name)
14
- modified(name)
15
- return true
16
- end
17
-
18
- paths.each do |path|
19
- Dir.walk(path) do |p|
20
- next if FileTest.directory?(p)
21
-
22
- if File.mtime(p) > @last_mod[name]
23
- modified(name)
24
- return true
25
- end
26
- end
27
- end
28
-
29
- false
30
- end
31
-
32
- def reset
33
- @last_mod = {}
34
- end
35
-
36
- private
37
-
38
- def modified(name)
39
- @last_mod[name] = Time.now
40
- end
41
- end
42
- end
43
- end
@@ -1,113 +0,0 @@
1
- class Pakyow::Presenter::ViewVersion
2
- attr_reader :default, :empty, :versions
3
-
4
- def initialize(views)
5
- @empty = views.find { |view| view.version == :empty }
6
- @default = views.find { |view| view.doc.attribute?(:'data-default') } || views.find { |view| view.version != :empty }
7
- @versions = views
8
- end
9
-
10
- def initialize_copy(original_view)
11
- super
12
-
13
- @empty = original_view.empty.soft_copy if original_view.empty
14
- @versions = original_view.versions.map { |view| view.soft_copy }
15
- @default = versions.first
16
- end
17
-
18
- def with(&block)
19
- if block.arity == 0
20
- instance_exec(&block)
21
- else
22
- yield(self)
23
- end
24
-
25
- self
26
- end
27
-
28
- def apply(data, bindings: {}, context: nil, &block)
29
- data = Array.ensure(data)
30
-
31
- if data.empty?
32
- @default = @empty
33
- cleanup
34
- self
35
- else
36
- cleanup
37
-
38
- match(data).bind(data, bindings: bindings, context: context, &block)
39
- end
40
- end
41
-
42
- def version(data, &block)
43
- data = Array.ensure(data)
44
- coll = Pakyow::Presenter::ViewCollection.new(@default.scoped_as)
45
-
46
- if data.empty?
47
- @versions.each(&:remove)
48
- else
49
- @empty.remove if @empty
50
- self_dup = self.dup
51
-
52
- view = process_version(self, data.first, &block)
53
- working = view
54
- coll << view
55
-
56
- data[1..-1].inject(coll) { |coll, datum|
57
- duped = self_dup.dup
58
- view = process_version(duped, datum, &block)
59
-
60
- working.after(view)
61
- working = view
62
- coll << view
63
- }
64
-
65
- coll
66
- end
67
- end
68
-
69
- def bind(data, bindings: {}, context: nil, &block)
70
- @versions.each do |view|
71
- view.bind(data, bindings: bindings, context: context, &block)
72
- end
73
- end
74
-
75
- def use(version)
76
- @versions.each do |view|
77
- @default = view if view.version == version
78
- end
79
-
80
- cleanup
81
-
82
- @default
83
- end
84
-
85
- def cleanup
86
- @versions.reject { |view| view == @default }.each(&:remove)
87
- @versions = [@default]
88
- end
89
-
90
- def method_missing(method, *args, &block)
91
- if @default.respond_to?(method)
92
- ret = @default.send(method, *args, &block)
93
-
94
- # because `match` mutates the default view (turning it into a collection), we
95
- # need to set default to this new collection so that things continue to work
96
- @default = ret if method == :match
97
-
98
- ret
99
- end
100
- end
101
-
102
- private
103
-
104
- def process_version(version, datum, &block)
105
- if block.arity == 1
106
- version.instance_exec(datum, &block)
107
- else
108
- block.call(version, datum)
109
- end
110
-
111
- version.default
112
- end
113
- end
@@ -1,8 +0,0 @@
1
- require 'oga'
2
-
3
- require 'pakyow/presenter/base'
4
- require 'pakyow/presenter/presenter'
5
- require 'pakyow/presenter/config/presenter'
6
- require 'pakyow/presenter/helpers'
7
- require 'pakyow/presenter/ext/app'
8
- require 'pakyow/presenter/ext/call_context'
@@ -1,26 +0,0 @@
1
- <%
2
- path = String.normalize_path(request.path)
3
- path = '/' if path.empty?
4
-
5
- view_path = path == '/' ? 'index.html' : "#{path}.html"
6
- %>
7
-
8
- <h1>
9
- Pakyow couldn't find anything to do :(
10
- </h1>
11
-
12
- <p class="lead">
13
- If you want back-end code to execute for this request, create a route in <code>app/lib/routes.rb</code>:
14
- </p>
15
-
16
- <pre>
17
- <code><span class="n">get</span> <span class="s1">'<%=path%>'</span> <span class="k">do</span>
18
- <span class="c1"># your code goes here</span>
19
- <span class="k">end</span></code>
20
- </pre>
21
-
22
- <p class="lead">
23
- But, we recommend you start by creating a view at <code>app/views/<%=view_path%></code>.
24
- The view will be served up automatically without writing any back-end code! This pattern
25
- is called view-first development (you could also call it <em>awesome</em>).
26
- </p>
@@ -1,23 +0,0 @@
1
- <%
2
- nice_source = req.error.backtrace[0].match(/^(.+?):(\d+)(|:in `(.+)')$/)
3
- file = nice_source[1].gsub(File.expand_path(Config.app.root) + '/', '')
4
- line = nice_source[2]
5
- msg = CGI.escapeHTML("#{req.error.class}: #{req.error}")
6
- trace = req.error.backtrace.map { |bt| CGI.escapeHTML(bt) }.join('<br>')
7
- %>
8
-
9
- <h1>
10
- Pakyow found something wrong :(
11
- </h1>
12
-
13
- <p class="lead">
14
- The error originated on line <%=line%> of <code><%=file%></code>.
15
- </p>
16
-
17
- <h5 class="error">
18
- <%=msg%>
19
- </h5>
20
-
21
- <pre>
22
- <code><%=trace%></code>
23
- </pre>
@@ -1 +0,0 @@
1
- require 'pakyow/presenter'