utopia 0.12.6 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -2
  3. data/Gemfile +6 -0
  4. data/README.md +48 -14
  5. data/Rakefile +5 -0
  6. data/bin/utopia +132 -15
  7. data/lib/utopia.rb +13 -10
  8. data/lib/utopia/content.rb +140 -0
  9. data/lib/utopia/content/link.rb +124 -0
  10. data/lib/utopia/content/links.rb +228 -0
  11. data/lib/utopia/content/node.rb +387 -0
  12. data/lib/utopia/content/processor.rb +128 -0
  13. data/lib/utopia/content/tag.rb +102 -0
  14. data/lib/utopia/controller.rb +137 -0
  15. data/lib/utopia/controller/action.rb +112 -0
  16. data/lib/utopia/controller/base.rb +174 -0
  17. data/lib/utopia/{middleware/controller → controller}/variables.rb +36 -38
  18. data/lib/utopia/exception_handler.rb +79 -0
  19. data/lib/utopia/extensions/array.rb +2 -2
  20. data/lib/utopia/localization.rb +143 -0
  21. data/lib/utopia/mail_exceptions.rb +136 -0
  22. data/lib/utopia/middleware.rb +7 -22
  23. data/lib/utopia/path.rb +150 -60
  24. data/lib/utopia/redirector.rb +152 -0
  25. data/lib/utopia/{extensions/hash.rb → session.rb} +4 -6
  26. data/lib/utopia/session/encrypted_cookie.rb +46 -48
  27. data/lib/utopia/{middleware/directory_index.rb → session/lazy_hash.rb} +44 -27
  28. data/lib/utopia/static.rb +255 -0
  29. data/lib/utopia/tags/deferred.rb +12 -8
  30. data/lib/utopia/tags/environment.rb +18 -6
  31. data/lib/utopia/tags/node.rb +12 -8
  32. data/lib/utopia/tags/override.rb +12 -12
  33. data/lib/utopia/version.rb +1 -1
  34. data/setup/.bowerrc +3 -0
  35. data/{lib/utopia/setup → setup}/Gemfile +1 -1
  36. data/setup/Rakefile +4 -0
  37. data/{lib/utopia/setup → setup}/cache/head/readme.txt +0 -0
  38. data/{lib/utopia/setup → setup}/cache/meta/readme.txt +0 -0
  39. data/setup/config.ru +64 -0
  40. data/{lib/utopia/setup → setup}/lib/readme.txt +0 -0
  41. data/{lib/utopia/setup → setup}/pages/_heading.xnode +0 -0
  42. data/{lib/utopia/setup → setup}/pages/_page.xnode +1 -1
  43. data/{lib/utopia/setup → setup}/pages/_static/icon.png +0 -0
  44. data/setup/pages/_static/site.css +70 -0
  45. data/{lib/utopia/setup → setup}/pages/errors/exception.xnode +0 -0
  46. data/{lib/utopia/setup → setup}/pages/errors/file-not-found.xnode +0 -0
  47. data/{lib/utopia/setup → setup}/pages/links.yaml +0 -0
  48. data/setup/pages/welcome/index.xnode +17 -0
  49. data/{lib/utopia/setup → setup}/public/readme.txt +0 -0
  50. data/spec/utopia/content/link_spec.rb +108 -0
  51. data/spec/utopia/content/links/foo/index.xnode +0 -0
  52. data/spec/utopia/content/links/foo/links.yaml +2 -0
  53. data/spec/utopia/content/links/foo/test.de.xnode +0 -0
  54. data/spec/utopia/content/links/foo/test.en.xnode +0 -0
  55. data/spec/utopia/content/links/links.yaml +9 -0
  56. data/spec/utopia/content/links/welcome.xnode +0 -0
  57. data/spec/utopia/content/localized/five/index.en.xnode +0 -0
  58. data/spec/utopia/content/localized/four/index.en.xnode +0 -0
  59. data/spec/utopia/content/localized/four/index.zh.xnode +0 -0
  60. data/spec/utopia/content/localized/four/links.yaml +4 -0
  61. data/spec/utopia/content/localized/links.yaml +16 -0
  62. data/spec/utopia/content/localized/one.xnode +0 -0
  63. data/spec/utopia/content/localized/three/index.xnode +0 -0
  64. data/spec/utopia/content/localized/two.en.xnode +0 -0
  65. data/spec/utopia/content/localized/two.zh.xnode +0 -0
  66. data/spec/utopia/content/node/ordered/first.xnode +0 -0
  67. data/spec/utopia/content/node/ordered/index.xnode +0 -0
  68. data/spec/utopia/content/node/ordered/links.yaml +4 -0
  69. data/spec/utopia/content/node/ordered/second.xnode +0 -0
  70. data/spec/utopia/content/node/related/foo.en.xnode +0 -0
  71. data/spec/utopia/content/node/related/foo.ja.xnode +0 -0
  72. data/spec/utopia/content/node/related/links.yaml +4 -0
  73. data/spec/utopia/content/node_spec.rb +63 -0
  74. data/spec/utopia/{middleware/content_spec.rb → content/processor_spec.rb} +34 -23
  75. data/spec/utopia/content_spec.rb +87 -0
  76. data/spec/utopia/content_spec.ru +10 -0
  77. data/spec/utopia/{middleware/controller_spec.rb → controller_spec.rb} +61 -16
  78. data/spec/utopia/controller_spec.ru +4 -0
  79. data/spec/utopia/extensions_spec.rb +6 -17
  80. data/spec/utopia/localization_spec.rb +60 -0
  81. data/spec/utopia/localization_spec.ru +11 -0
  82. data/{lib/utopia/tags.rb → spec/utopia/middleware_spec.rb} +8 -14
  83. data/spec/utopia/{middleware/content_root → pages}/_heading.xnode +0 -0
  84. data/spec/utopia/pages/content/_show-value.xnode +1 -0
  85. data/spec/utopia/pages/content/test-partial.xnode +1 -0
  86. data/spec/utopia/pages/controller/controller.rb +28 -0
  87. data/spec/utopia/pages/controller/index.xnode +1 -0
  88. data/spec/utopia/pages/controller/nested/controller.rb +4 -0
  89. data/spec/utopia/{middleware/content_root → pages}/index.xnode +0 -0
  90. data/spec/utopia/pages/localized.de.txt +1 -0
  91. data/spec/utopia/pages/localized.en.txt +1 -0
  92. data/spec/utopia/pages/localized.jp.txt +1 -0
  93. data/spec/utopia/pages/node/index.xnode +1 -0
  94. data/spec/utopia/pages/test.txt +1 -0
  95. data/spec/utopia/path_spec.rb +109 -0
  96. data/spec/utopia/rack_spec.rb +2 -0
  97. data/spec/utopia/session_spec.rb +82 -0
  98. data/spec/utopia/session_spec.ru +20 -0
  99. data/spec/utopia/spec_helper.rb +16 -0
  100. data/{lib/utopia/extensions/string.rb → spec/utopia/static_spec.rb} +24 -15
  101. data/spec/utopia/static_spec.ru +4 -0
  102. data/utopia.gemspec +3 -3
  103. metadata +138 -54
  104. data/lib/utopia/extensions/regexp.rb +0 -33
  105. data/lib/utopia/link.rb +0 -288
  106. data/lib/utopia/middleware/all.rb +0 -33
  107. data/lib/utopia/middleware/content.rb +0 -157
  108. data/lib/utopia/middleware/content/node.rb +0 -386
  109. data/lib/utopia/middleware/content/processor.rb +0 -123
  110. data/lib/utopia/middleware/controller.rb +0 -130
  111. data/lib/utopia/middleware/controller/action.rb +0 -121
  112. data/lib/utopia/middleware/controller/base.rb +0 -184
  113. data/lib/utopia/middleware/exception_handler.rb +0 -80
  114. data/lib/utopia/middleware/localization.rb +0 -147
  115. data/lib/utopia/middleware/localization/name.rb +0 -69
  116. data/lib/utopia/middleware/mail_exceptions.rb +0 -138
  117. data/lib/utopia/middleware/redirector.rb +0 -146
  118. data/lib/utopia/middleware/requester.rb +0 -126
  119. data/lib/utopia/middleware/static.rb +0 -295
  120. data/lib/utopia/setup.rb +0 -60
  121. data/lib/utopia/setup/config.ru +0 -47
  122. data/lib/utopia/setup/pages/_static/background.png +0 -0
  123. data/lib/utopia/setup/pages/_static/site.css +0 -48
  124. data/lib/utopia/setup/pages/welcome/index.xnode +0 -7
  125. data/lib/utopia/tag.rb +0 -105
  126. data/lib/utopia/tags/all.rb +0 -34
@@ -1,33 +0,0 @@
1
- # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
20
-
21
- require 'pathname'
22
-
23
- warn "require 'utopia/middleware/all' is deprecated. Require 'utopia' instead."
24
-
25
- Pathname.new(__FILE__).dirname.entries.each do |path|
26
- next unless /\.rb$/ === path.to_s
27
-
28
- name = File.basename(path.to_s, ".rb")
29
-
30
- if name != "all"
31
- require "utopia/middleware/#{name}"
32
- end
33
- end
@@ -1,157 +0,0 @@
1
- # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
20
-
21
- require 'utopia/middleware'
22
- require 'utopia/link'
23
- require 'utopia/path'
24
- require 'utopia/tags'
25
-
26
- require 'utopia/middleware/content/node'
27
- require 'utopia/middleware/content/processor'
28
- require 'trenni/template'
29
-
30
- module Utopia
31
- module Middleware
32
-
33
- class Content
34
- def initialize(app, options = {})
35
- @app = app
36
-
37
- @root = File.expand_path(options[:root] || Utopia::Middleware::default_root)
38
-
39
- # Set to hash to enable caching
40
- @nodes = {}
41
- @files = nil
42
-
43
- @tags = options[:tags] || {}
44
- end
45
-
46
- attr :root
47
- attr :passthrough
48
-
49
- def fetch_xml(path)
50
- read_file = lambda { Trenni::Template.load(path) }
51
-
52
- if @files
53
- @files.fetch(path) do |key|
54
- @files[key] = read_file.call
55
- end
56
- else
57
- read_file.call
58
- end
59
- end
60
-
61
- # Look up a named tag such as <entry />
62
- def lookup_tag(name, parent_path)
63
- if @tags.key? name
64
- return @tags[name]
65
- elsif Utopia::Tags.all.key? name
66
- return Utopia::Tags.all[name]
67
- end
68
-
69
- if String === name && name.index("/")
70
- name = Path.create(name)
71
- end
72
-
73
- if Path === name
74
- name = parent_path + name
75
- name_path = name.components.dup
76
- name_path[-1] += ".xnode"
77
- else
78
- name_path = name + ".xnode"
79
- end
80
-
81
- parent_path.ascend do |dir|
82
- tag_path = File.join(root, dir.components, name_path)
83
-
84
- if File.exist? tag_path
85
- return Node.new(self, dir + name, parent_path + name, tag_path)
86
- end
87
-
88
- if String === name_path
89
- tag_path = File.join(root, dir.components, "_" + name_path)
90
-
91
- if File.exist? tag_path
92
- return Node.new(self, dir + name, parent_path + name, tag_path)
93
- end
94
- end
95
- end
96
-
97
- return nil
98
- end
99
-
100
- def lookup_node(request_path)
101
- name = request_path.basename
102
- name_xnode = name + ".xnode"
103
-
104
- node_path = File.join(@root, request_path.dirname.components, name_xnode)
105
-
106
- if File.exist? node_path
107
- return Node.new(self, request_path.dirname + name, request_path, node_path)
108
- end
109
-
110
- return nil
111
- end
112
-
113
- def call(env)
114
- request = Rack::Request.new(env)
115
- path = Path.create(request.path_info).to_absolute
116
-
117
- # Check if the request is to a non-specific index.
118
- name, extensions = path.basename.split(".", 2)
119
- directory_path = File.join(@root, path.dirname.components, name)
120
-
121
- if File.directory? directory_path
122
- if extensions
123
- index_path = [name, "index.#{extensions}"]
124
- else
125
- index_path = [name, "index"]
126
- end
127
-
128
- return [307, {"Location" => path.dirname.join(index_path).to_s}, []]
129
- end
130
-
131
- # Otherwise look up the node
132
- node = lookup_node(path)
133
-
134
- if node
135
- if request.head?
136
- return [200, {}, []]
137
- else
138
- response = Rack::Response.new
139
-
140
- attributes = {}
141
-
142
- if request.controller
143
- attributes = request.controller.to_hash
144
- end
145
-
146
- node.process!(request, response, attributes)
147
-
148
- return response.finish
149
- end
150
- else
151
- return @app.call(env)
152
- end
153
- end
154
- end
155
-
156
- end
157
- end
@@ -1,386 +0,0 @@
1
- # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
20
-
21
- require 'set'
22
-
23
- require 'utopia/middleware/content/processor'
24
- require 'utopia/link'
25
-
26
- module Utopia
27
-
28
- module Middleware
29
- class Content
30
- class UnbalancedTagError < StandardError
31
- def initialize(tag)
32
- @tag = tag
33
-
34
- super("Unbalanced tag #{tag.name}")
35
- end
36
-
37
- attr :tag
38
- end
39
-
40
- class Transaction
41
- class State
42
- def initialize(tag, node)
43
- @node = node
44
-
45
- @buffer = StringIO.new
46
- @overrides = {}
47
-
48
- @tags = []
49
- @attributes = tag.to_hash
50
-
51
- @content = nil
52
- @deferred = []
53
- end
54
-
55
- attr :attributes
56
- attr :overrides
57
- attr :content
58
- attr :node
59
- attr :tags
60
-
61
- attr :deferred
62
-
63
- def defer(value = nil, &block)
64
- @deferred << block
65
-
66
- Tag.closed("deferred", :id => @deferred.size - 1).to_html
67
- end
68
-
69
- def [](key)
70
- @attributes[key.to_s]
71
- end
72
-
73
- def call(transaction)
74
- @content = @buffer.string
75
- @buffer = StringIO.new
76
-
77
- if node.respond_to? :call
78
- node.call(transaction, self)
79
- else
80
- transaction.parse_xml(@content)
81
- end
82
-
83
- return @buffer.string
84
- end
85
-
86
- def lookup(tag)
87
- if override = @overrides[tag.name]
88
- if override.respond_to? :call
89
- return override.call(tag)
90
- elsif String === override
91
- return Tag.new(override, tag.attributes)
92
- else
93
- return override
94
- end
95
- else
96
- return tag
97
- end
98
- end
99
-
100
- def cdata(text)
101
- @buffer.write(text)
102
- end
103
-
104
- def markup(text)
105
- cdata(text)
106
- end
107
-
108
- def tag_complete(tag)
109
- tag.write_full_html(@buffer)
110
- end
111
-
112
- def tag_begin(tag)
113
- @tags << tag
114
- tag.write_open_html(@buffer)
115
- end
116
-
117
- def tag_end(tag)
118
- raise UnbalancedTagError(tag) unless @tags.pop.name == tag.name
119
-
120
- tag.write_close_html(@buffer)
121
- end
122
- end
123
-
124
- def initialize(request, response)
125
- @begin_tags = []
126
- @end_tags = []
127
-
128
- @request = request
129
- @response = response
130
- end
131
-
132
- def binding
133
- super
134
- end
135
-
136
- def parse_xml(xml_data)
137
- Processor.parse_xml(xml_data, self)
138
- end
139
-
140
- attr :request
141
- attr :response
142
-
143
- # Begin tags represents a list from outer to inner most tag.
144
- # At any point in parsing xml, begin_tags is a list of the inner most tag,
145
- # then the next outer tag, etc. This list is used for doing dependent lookups.
146
- attr :begin_tags
147
-
148
- # End tags represents a list of execution order. This is the order that end tags
149
- # have appeared when evaluating nodes.
150
- attr :end_tags
151
-
152
- def attributes
153
- return current.attributes
154
- end
155
-
156
- def current
157
- @begin_tags[-1]
158
- end
159
-
160
- def content
161
- @end_tags[-1].content
162
- end
163
-
164
- def parent
165
- end_tags[-2]
166
- end
167
-
168
- def first
169
- @begin_tags[0]
170
- end
171
-
172
- def tag(name, attributes = {}, &block)
173
- tag = Tag.new(name, attributes)
174
-
175
- node = tag_begin(tag)
176
-
177
- yield node if block_given?
178
-
179
- tag_end(tag)
180
- end
181
-
182
- def tag_complete(tag, node = nil)
183
- if tag.name == "content"
184
- current.markup(content)
185
- else
186
- node ||= lookup(tag)
187
-
188
- if node
189
- tag_begin(tag, node)
190
- tag_end(tag)
191
- else
192
- current.tag_complete(tag)
193
- end
194
- end
195
- end
196
-
197
- def tag_begin(tag, node = nil)
198
- node ||= lookup(tag)
199
-
200
- if node
201
- state = State.new(tag, node)
202
- @begin_tags << state
203
-
204
- if node.respond_to? :tag_begin
205
- node.tag_begin(self, state)
206
- end
207
-
208
- return node
209
- end
210
-
211
- current.tag_begin(tag)
212
-
213
- return nil
214
- end
215
-
216
- def cdata(text)
217
- current.cdata(text)
218
- end
219
-
220
- def deferred_tag(*args, &block)
221
- if block_given?
222
- current.defer(&block)
223
- else
224
- current.defer do
225
- tag(*args)
226
- end
227
- end
228
- end
229
-
230
- def tag_end(tag = nil)
231
- top = current
232
-
233
- if top.tags.empty?
234
- if top.node.respond_to? :tag_end
235
- top.node.tag_end(self, top)
236
- end
237
-
238
- @end_tags << top
239
- buffer = top.call(self)
240
-
241
- @begin_tags.pop
242
- @end_tags.pop
243
-
244
- if current
245
- current.markup(buffer)
246
- end
247
-
248
- return buffer
249
- else
250
- current.tag_end(tag)
251
- end
252
-
253
- return nil
254
- end
255
-
256
- def render_node(node, attributes = {})
257
- state = State.new(attributes, node)
258
- @begin_tags << state
259
-
260
- return tag_end
261
- end
262
-
263
- # Takes an instance of Tag
264
- def lookup(tag)
265
- result = tag
266
- node = nil
267
-
268
- @begin_tags.reverse_each do |state|
269
- result = state.lookup(result)
270
-
271
- node ||= state.node if state.node.respond_to? :lookup
272
-
273
- return result if Node === result
274
- end
275
-
276
- @end_tags.reverse_each do |state|
277
- return state.node.lookup(result) if state.node.respond_to? :lookup
278
- end
279
-
280
- return nil
281
- end
282
-
283
- def method_missing(name, *args)
284
- @begin_tags.reverse_each do |state|
285
- if state.node.respond_to? name
286
- return state.node.send(name, *args)
287
- end
288
- end
289
-
290
- super
291
- end
292
- end
293
-
294
- class Node
295
- def initialize(controller, uri_path, request_path, file_path)
296
- @controller = controller
297
-
298
- @uri_path = uri_path
299
- @request_path = request_path
300
- @file_path = file_path
301
- end
302
-
303
- attr :request_path
304
- attr :uri_path
305
- attr :file_path
306
-
307
- def link
308
- return Link.new(:file, uri_path)
309
- end
310
-
311
- def lookup_node(path)
312
- @controller.lookup_node(path)
313
- end
314
-
315
- def local_path(path = ".", base = nil)
316
- path = Path.create(path)
317
- root = Pathname.new(@controller.root)
318
-
319
- if path.absolute?
320
- return root.join(*path.components)
321
- else
322
- base ||= uri_path.dirname
323
- return root.join(*(base + path).components)
324
- end
325
- end
326
-
327
- def lookup(tag)
328
- from_path = parent_path
329
-
330
- # If the current node is called 'foo', we can't lookup 'foo' in the current directory or we will likely have infinite recursion.
331
- if tag.name == @uri_path.basename
332
- from_path = from_path.dirname
333
- end
334
-
335
- return @controller.lookup_tag(tag.name, from_path)
336
- end
337
-
338
- def parent_path
339
- uri_path.dirname
340
- end
341
-
342
- def links(path = ".", options = {}, &block)
343
- path = uri_path.dirname + Path.create(path)
344
- links = Links.index(@controller.root, path, options)
345
-
346
- if block_given?
347
- links.each &block
348
- else
349
- links
350
- end
351
- end
352
-
353
- def related_links
354
- name = @uri_path.basename.split(".").first
355
- links = Links.index(@controller.root, uri_path.dirname, :name => name, :indices => true)
356
- end
357
-
358
- def siblings_path
359
- name = @uri_path.basename.split(".").first
360
-
361
- if name == "index"
362
- @uri_path.dirname(2)
363
- else
364
- @uri_path.dirname
365
- end
366
- end
367
-
368
- def sibling_links(options = {})
369
- return Links.index(@controller.root, siblings_path, options)
370
- end
371
-
372
- def call(transaction, state)
373
- xml_data = @controller.fetch_xml(@file_path).result(transaction.binding)
374
-
375
- transaction.parse_xml(xml_data)
376
- end
377
-
378
- def process!(request, response, attributes = {})
379
- transaction = Transaction.new(request, response)
380
- response.write(transaction.render_node(self, attributes))
381
- end
382
- end
383
-
384
- end
385
- end
386
- end