arrow 1.0.7
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.
- data/ChangeLog +1590 -0
- data/LICENSE +28 -0
- data/README +75 -0
- data/Rakefile +366 -0
- data/Rakefile.local +63 -0
- data/data/arrow/applets/TEMPLATE.rb.tpl +53 -0
- data/data/arrow/applets/args.rb +50 -0
- data/data/arrow/applets/config.rb +55 -0
- data/data/arrow/applets/error.rb +63 -0
- data/data/arrow/applets/files.rb +46 -0
- data/data/arrow/applets/inspect.rb +46 -0
- data/data/arrow/applets/nosuchapplet.rb +31 -0
- data/data/arrow/applets/status.rb +92 -0
- data/data/arrow/applets/test.rb +133 -0
- data/data/arrow/applets/tutorial/counter.rb +96 -0
- data/data/arrow/applets/tutorial/dingus.rb +67 -0
- data/data/arrow/applets/tutorial/hello.rb +34 -0
- data/data/arrow/applets/tutorial/hello2.rb +73 -0
- data/data/arrow/applets/tutorial/imgtext.rb +90 -0
- data/data/arrow/applets/tutorial/imgtext2.rb +286 -0
- data/data/arrow/applets/tutorial/index.rb +36 -0
- data/data/arrow/applets/tutorial/logo.rb +98 -0
- data/data/arrow/applets/tutorial/memcache.rb +61 -0
- data/data/arrow/applets/tutorial/missing.rb +37 -0
- data/data/arrow/applets/tutorial/protected.rb +100 -0
- data/data/arrow/applets/tutorial/redirector.rb +52 -0
- data/data/arrow/applets/tutorial/rndimages.rb +159 -0
- data/data/arrow/applets/tutorial/sharenotes.rb +83 -0
- data/data/arrow/applets/tutorial/subclassed-hello.rb +32 -0
- data/data/arrow/applets/tutorial/superhello.rb +72 -0
- data/data/arrow/applets/tutorial/timeclock.rb +78 -0
- data/data/arrow/applets/view-applet.rb +123 -0
- data/data/arrow/applets/view-template.rb +85 -0
- data/data/arrow/applets/wiki.rb +274 -0
- data/data/arrow/templates/TEMPLATE.tmpl.tpl +36 -0
- data/data/arrow/templates/applet-status.tmpl +153 -0
- data/data/arrow/templates/args-display.tmpl +120 -0
- data/data/arrow/templates/config/display-table.tmpl +36 -0
- data/data/arrow/templates/config/display.tmpl +36 -0
- data/data/arrow/templates/counter-deleted.tmpl +33 -0
- data/data/arrow/templates/counter.tmpl +59 -0
- data/data/arrow/templates/dingus.tmpl +55 -0
- data/data/arrow/templates/enumtable.tmpl +8 -0
- data/data/arrow/templates/error-display.tmpl +92 -0
- data/data/arrow/templates/filemap.tmpl +89 -0
- data/data/arrow/templates/hello-world-src.tmpl +34 -0
- data/data/arrow/templates/hello-world.tmpl +60 -0
- data/data/arrow/templates/imgtext/fontlist.tmpl +46 -0
- data/data/arrow/templates/imgtext/form.tmpl +70 -0
- data/data/arrow/templates/imgtext/reload-error.tmpl +40 -0
- data/data/arrow/templates/imgtext/reload.tmpl +55 -0
- data/data/arrow/templates/inspect/display.tmpl +80 -0
- data/data/arrow/templates/loginform.tmpl +64 -0
- data/data/arrow/templates/logout.tmpl +32 -0
- data/data/arrow/templates/memcache/display.tmpl +41 -0
- data/data/arrow/templates/navbar.incl +27 -0
- data/data/arrow/templates/nosuchapplet.tmpl +32 -0
- data/data/arrow/templates/printsource.tmpl +35 -0
- data/data/arrow/templates/protected.tmpl +36 -0
- data/data/arrow/templates/rndimages.tmpl +38 -0
- data/data/arrow/templates/service-response.tmpl +13 -0
- data/data/arrow/templates/sharenotes/display.tmpl +38 -0
- data/data/arrow/templates/status.tmpl +120 -0
- data/data/arrow/templates/templateviewer.tmpl +43 -0
- data/data/arrow/templates/test/harness.tmpl +57 -0
- data/data/arrow/templates/test/list.tmpl +48 -0
- data/data/arrow/templates/test/problem.tmpl +42 -0
- data/data/arrow/templates/tutorial/index.tmpl +37 -0
- data/data/arrow/templates/tutorial/missingapplet.tmpl +29 -0
- data/data/arrow/templates/view-applet-nosuch.tmpl +32 -0
- data/data/arrow/templates/view-applet.tmpl +40 -0
- data/data/arrow/templates/view-template.tmpl +83 -0
- data/data/arrow/templates/wiki/formerror.tmpl +47 -0
- data/data/arrow/templates/wiki/markup_help.incl +6 -0
- data/data/arrow/templates/wiki/new.tmpl +56 -0
- data/data/arrow/templates/wiki/new_system.tmpl +122 -0
- data/data/arrow/templates/wiki/sectionlist.tmpl +43 -0
- data/data/arrow/templates/wiki/show.tmpl +34 -0
- data/docs/manual/layouts/default.page +43 -0
- data/docs/manual/lib/api-filter.rb +81 -0
- data/docs/manual/lib/editorial-filter.rb +64 -0
- data/docs/manual/lib/examples-filter.rb +244 -0
- data/docs/manual/lib/links-filter.rb +117 -0
- data/lib/apache/fakerequest.rb +448 -0
- data/lib/apache/logger.rb +33 -0
- data/lib/arrow.rb +51 -0
- data/lib/arrow/acceptparam.rb +207 -0
- data/lib/arrow/applet.rb +725 -0
- data/lib/arrow/appletmixins.rb +218 -0
- data/lib/arrow/appletregistry.rb +590 -0
- data/lib/arrow/applettestcase.rb +503 -0
- data/lib/arrow/broker.rb +255 -0
- data/lib/arrow/cache.rb +176 -0
- data/lib/arrow/config-loaders/yaml.rb +75 -0
- data/lib/arrow/config.rb +615 -0
- data/lib/arrow/constants.rb +24 -0
- data/lib/arrow/cookie.rb +359 -0
- data/lib/arrow/cookieset.rb +108 -0
- data/lib/arrow/dispatcher.rb +368 -0
- data/lib/arrow/dispatcherloader.rb +50 -0
- data/lib/arrow/exceptions.rb +61 -0
- data/lib/arrow/fallbackhandler.rb +48 -0
- data/lib/arrow/formvalidator.rb +631 -0
- data/lib/arrow/htmltokenizer.rb +343 -0
- data/lib/arrow/logger.rb +488 -0
- data/lib/arrow/logger/apacheoutputter.rb +69 -0
- data/lib/arrow/logger/arrayoutputter.rb +63 -0
- data/lib/arrow/logger/coloroutputter.rb +111 -0
- data/lib/arrow/logger/fileoutputter.rb +96 -0
- data/lib/arrow/logger/htmloutputter.rb +54 -0
- data/lib/arrow/logger/outputter.rb +123 -0
- data/lib/arrow/mixins.rb +425 -0
- data/lib/arrow/monkeypatches.rb +94 -0
- data/lib/arrow/object.rb +117 -0
- data/lib/arrow/path.rb +196 -0
- data/lib/arrow/service.rb +447 -0
- data/lib/arrow/session.rb +289 -0
- data/lib/arrow/session/dbstore.rb +100 -0
- data/lib/arrow/session/filelock.rb +160 -0
- data/lib/arrow/session/filestore.rb +132 -0
- data/lib/arrow/session/id.rb +98 -0
- data/lib/arrow/session/lock.rb +253 -0
- data/lib/arrow/session/md5id.rb +42 -0
- data/lib/arrow/session/nulllock.rb +42 -0
- data/lib/arrow/session/posixlock.rb +166 -0
- data/lib/arrow/session/sha1id.rb +54 -0
- data/lib/arrow/session/store.rb +366 -0
- data/lib/arrow/session/usertrackid.rb +52 -0
- data/lib/arrow/spechelpers.rb +73 -0
- data/lib/arrow/template.rb +713 -0
- data/lib/arrow/template/attr.rb +31 -0
- data/lib/arrow/template/call.rb +31 -0
- data/lib/arrow/template/comment.rb +33 -0
- data/lib/arrow/template/container.rb +118 -0
- data/lib/arrow/template/else.rb +41 -0
- data/lib/arrow/template/elsif.rb +44 -0
- data/lib/arrow/template/escape.rb +53 -0
- data/lib/arrow/template/export.rb +87 -0
- data/lib/arrow/template/for.rb +145 -0
- data/lib/arrow/template/if.rb +78 -0
- data/lib/arrow/template/import.rb +119 -0
- data/lib/arrow/template/include.rb +206 -0
- data/lib/arrow/template/iterator.rb +208 -0
- data/lib/arrow/template/nodes.rb +734 -0
- data/lib/arrow/template/parser.rb +571 -0
- data/lib/arrow/template/prettyprint.rb +53 -0
- data/lib/arrow/template/render.rb +191 -0
- data/lib/arrow/template/selectlist.rb +94 -0
- data/lib/arrow/template/set.rb +87 -0
- data/lib/arrow/template/timedelta.rb +81 -0
- data/lib/arrow/template/unless.rb +78 -0
- data/lib/arrow/template/urlencode.rb +51 -0
- data/lib/arrow/template/yield.rb +139 -0
- data/lib/arrow/templatefactory.rb +125 -0
- data/lib/arrow/testcase.rb +567 -0
- data/lib/arrow/transaction.rb +608 -0
- data/rake/191_compat.rb +26 -0
- data/rake/dependencies.rb +76 -0
- data/rake/documentation.rb +114 -0
- data/rake/helpers.rb +502 -0
- data/rake/hg.rb +282 -0
- data/rake/manual.rb +787 -0
- data/rake/packaging.rb +129 -0
- data/rake/publishing.rb +278 -0
- data/rake/style.rb +62 -0
- data/rake/svn.rb +668 -0
- data/rake/testing.rb +187 -0
- data/rake/verifytask.rb +64 -0
- data/spec/arrow/acceptparam_spec.rb +157 -0
- data/spec/arrow/applet_spec.rb +575 -0
- data/spec/arrow/appletmixins_spec.rb +409 -0
- data/spec/arrow/appletregistry_spec.rb +294 -0
- data/spec/arrow/broker_spec.rb +153 -0
- data/spec/arrow/config_spec.rb +224 -0
- data/spec/arrow/cookieset_spec.rb +164 -0
- data/spec/arrow/dispatcher_spec.rb +137 -0
- data/spec/arrow/dispatcherloader_spec.rb +65 -0
- data/spec/arrow/formvalidator_spec.rb +781 -0
- data/spec/arrow/logger_spec.rb +346 -0
- data/spec/arrow/mixins_spec.rb +120 -0
- data/spec/arrow/service_spec.rb +645 -0
- data/spec/arrow/session_spec.rb +121 -0
- data/spec/arrow/template/iterator_spec.rb +222 -0
- data/spec/arrow/templatefactory_spec.rb +185 -0
- data/spec/arrow/transaction_spec.rb +319 -0
- data/spec/arrow_spec.rb +37 -0
- data/spec/lib/appletmatchers.rb +281 -0
- data/spec/lib/constants.rb +77 -0
- data/spec/lib/helpers.rb +41 -0
- data/spec/lib/matchers.rb +44 -0
- data/tests/cookie.tests.rb +310 -0
- data/tests/path.tests.rb +157 -0
- data/tests/session.tests.rb +111 -0
- data/tests/session_id.tests.rb +82 -0
- data/tests/session_lock.tests.rb +191 -0
- data/tests/session_store.tests.rb +53 -0
- data/tests/template.tests.rb +1360 -0
- metadata +339 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'arrow/exceptions'
|
|
4
|
+
require 'arrow/path'
|
|
5
|
+
require 'arrow/template'
|
|
6
|
+
require 'arrow/template/nodes'
|
|
7
|
+
require 'arrow/template/iterator'
|
|
8
|
+
|
|
9
|
+
# The Arrow::Template::ForDirective class, a derivative of
|
|
10
|
+
# Arrow::Template::BracketingDirective. This is the class which defines the
|
|
11
|
+
# behaviour of the 'for' template directive.
|
|
12
|
+
#
|
|
13
|
+
# == Syntax
|
|
14
|
+
#
|
|
15
|
+
# <?for <arglist> in <obj>?>...<?end for?>
|
|
16
|
+
#
|
|
17
|
+
# This directive iterates over all the items in an Enumerable object (via the
|
|
18
|
+
# #entities method), rendering the contents once for each object. The specified
|
|
19
|
+
# #<em>arglist</em> is similar to Ruby's argument lists: it supports defaults,
|
|
20
|
+
# as well as array (e.g., <tt>*rest</tt>) and hash arguments.
|
|
21
|
+
#
|
|
22
|
+
# While the contents are rendering, a special attribute named <em>iterator</em>
|
|
23
|
+
# is set to an Arrow::Template::Iterator object, which can be used to get
|
|
24
|
+
# information about the iteration itself. This directive doesn't add anything to
|
|
25
|
+
# the output directly, but relies on its subnodes for content.
|
|
26
|
+
#
|
|
27
|
+
# This directive only works with Enumerable objects; for other objects with
|
|
28
|
+
# iterators or blocks, use the <?yield?> directive.
|
|
29
|
+
#
|
|
30
|
+
# === Examples
|
|
31
|
+
#
|
|
32
|
+
# <!-- Iterate over the headers in a request -->
|
|
33
|
+
# <?for name, value in request.headers_in ?>
|
|
34
|
+
# <strong><?attr name?>:</strong> <?attr value?><br/>
|
|
35
|
+
# <?end for?>
|
|
36
|
+
#
|
|
37
|
+
# <!-- Same thing, but this time in a table with alternating styles for each
|
|
38
|
+
# row. -->
|
|
39
|
+
# <table>
|
|
40
|
+
# <?for name, value in request.headers_in ?>
|
|
41
|
+
# <?if iterator.even? ?>
|
|
42
|
+
# <tr class="even-row">
|
|
43
|
+
# <?else?>
|
|
44
|
+
# <tr class="odd-row">
|
|
45
|
+
# <?end if?>
|
|
46
|
+
# <td><?attr name?></td> <td><?attr value?></td>
|
|
47
|
+
# </tr>
|
|
48
|
+
# <?end for?>
|
|
49
|
+
# </table>
|
|
50
|
+
#
|
|
51
|
+
# <!-- Pair up words with their lengths and sort them shortest first, then
|
|
52
|
+
# print them out with their lengths -->
|
|
53
|
+
# <?for word, length in tests.
|
|
54
|
+
# collect {|item| [item, item.length]}.
|
|
55
|
+
# sort_by {|item| item[1]} ?>
|
|
56
|
+
# <?attr word?>: <?attr length?>
|
|
57
|
+
# <?end for?>
|
|
58
|
+
#
|
|
59
|
+
# == Authors
|
|
60
|
+
#
|
|
61
|
+
# * Michael Granger <ged@FaerieMUD.org>
|
|
62
|
+
#
|
|
63
|
+
# Please see the file LICENSE in the top-level directory for licensing details.
|
|
64
|
+
#
|
|
65
|
+
class Arrow::Template::ForDirective < Arrow::Template::BracketingDirective # :nodoc:
|
|
66
|
+
include Arrow::Template::Parser::Patterns
|
|
67
|
+
|
|
68
|
+
# The regexp for matching the 'in' part of the directive
|
|
69
|
+
IN = WHITESPACE + /in/i + WHITESPACE
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
#############################################################
|
|
73
|
+
### I N S T A N C E M E T H O D S
|
|
74
|
+
#############################################################
|
|
75
|
+
|
|
76
|
+
### Create a new Arrow::Template::ForDirective object.
|
|
77
|
+
def initialize( body, parser, state )
|
|
78
|
+
@args = []
|
|
79
|
+
@pureargs = []
|
|
80
|
+
super
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
######
|
|
85
|
+
public
|
|
86
|
+
######
|
|
87
|
+
|
|
88
|
+
# The argument list for the iterator, with sigils and defaults, if any.
|
|
89
|
+
attr_reader :args
|
|
90
|
+
|
|
91
|
+
# The argument list for the iterator, with any sigils and defaults
|
|
92
|
+
# stripped away.
|
|
93
|
+
attr_reader :pureargs
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
#########
|
|
97
|
+
protected
|
|
98
|
+
#########
|
|
99
|
+
|
|
100
|
+
### Parse the contents of the directive.
|
|
101
|
+
def parse_directive_contents( parser, state )
|
|
102
|
+
@args, @pureargs = parser.scan_for_arglist( state )
|
|
103
|
+
return nil unless @args
|
|
104
|
+
|
|
105
|
+
state.scanner.skip( IN ) or
|
|
106
|
+
raise Arrow::ParseError, "no 'in' for 'for'"
|
|
107
|
+
|
|
108
|
+
super
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
### Render the directive's bracketed nodes once for each item in the
|
|
113
|
+
### iterated content.
|
|
114
|
+
def render_subnodes( attribute, template, scope )
|
|
115
|
+
res = []
|
|
116
|
+
|
|
117
|
+
iterator = Arrow::Template::Iterator.new( attribute )
|
|
118
|
+
iterator.each {|iter,*blockArgs|
|
|
119
|
+
#self.log.debug "[FOR] Block args are: %p" % [ blockArgs ]
|
|
120
|
+
|
|
121
|
+
# Make an attributes hash from the pure args of left side of the
|
|
122
|
+
# 'for'.
|
|
123
|
+
attributes = {}
|
|
124
|
+
blockArgs.zip( self.pureargs ) {|pair|
|
|
125
|
+
attributes[ pair[1] ] = pair[0]
|
|
126
|
+
}
|
|
127
|
+
attributes['iterator'] = iter
|
|
128
|
+
|
|
129
|
+
# Process the nodes inside the 'for' block with the args being
|
|
130
|
+
# overridden.
|
|
131
|
+
#self.log.debug " [FOR] calling into new scope with overridden " +
|
|
132
|
+
# "attributes: %p" % [ attributes ]
|
|
133
|
+
template.with_overridden_attributes( scope, attributes ) {|template|
|
|
134
|
+
res << template.render( @subnodes, scope )
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return *res
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
end # class Arrow::Template::ForDirective
|
|
144
|
+
|
|
145
|
+
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'arrow/template'
|
|
4
|
+
require 'arrow/template/nodes'
|
|
5
|
+
|
|
6
|
+
# The Arrow::Template::IfDirective class, a derivative of
|
|
7
|
+
# Arrow::Template::BracketingDirective. Instances of this class represent a
|
|
8
|
+
# section of a template that is rendered conditionally.
|
|
9
|
+
#
|
|
10
|
+
# The formats the directive supports are:
|
|
11
|
+
#
|
|
12
|
+
# <?if <name>?>...<?end if?>
|
|
13
|
+
# <?if <name>.<methodchain>?>...<?end if?>
|
|
14
|
+
# <?if <name> (matches|=~) <regex>?>...<?end if?>
|
|
15
|
+
# <?if <name>.<methodchain> (matches|=~) <regex>?>...<?end if?>
|
|
16
|
+
#
|
|
17
|
+
# Note that this directive does not support all possible Ruby expressions in the
|
|
18
|
+
# conditional, and must have a valid associated identifier (the <em>name</em>
|
|
19
|
+
# bit).
|
|
20
|
+
#
|
|
21
|
+
# == Authors
|
|
22
|
+
#
|
|
23
|
+
# * Michael Granger <ged@FaerieMUD.org>
|
|
24
|
+
#
|
|
25
|
+
# Please see the file LICENSE in the top-level directory for licensing details.
|
|
26
|
+
#
|
|
27
|
+
class Arrow::Template::IfDirective < Arrow::Template::BracketingDirective # :nodoc:
|
|
28
|
+
include Arrow::Template::ConditionalDirective
|
|
29
|
+
|
|
30
|
+
require 'arrow/template/else'
|
|
31
|
+
require 'arrow/template/elsif'
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
#############################################################
|
|
35
|
+
### I N S T A N C E M E T H O D S
|
|
36
|
+
#############################################################
|
|
37
|
+
|
|
38
|
+
#########
|
|
39
|
+
protected
|
|
40
|
+
#########
|
|
41
|
+
|
|
42
|
+
### Render the contents of the conditional if it evaluates to +true+, or
|
|
43
|
+
### the nodes after 'elsif' or 'else' subnodes if their conditions are
|
|
44
|
+
### met.
|
|
45
|
+
def render_contents( template, scope )
|
|
46
|
+
cond = hasBeenTrue = self.evaluate( template, scope )
|
|
47
|
+
|
|
48
|
+
nodes = []
|
|
49
|
+
|
|
50
|
+
# Now splice out the chunk of nodes that should be rendered based on
|
|
51
|
+
# the conditional.
|
|
52
|
+
@subnodes.each do |node|
|
|
53
|
+
case node
|
|
54
|
+
when Arrow::Template::ElsifDirective
|
|
55
|
+
if !hasBeenTrue
|
|
56
|
+
cond = hasBeenTrue = node.evaluate( template, scope )
|
|
57
|
+
else
|
|
58
|
+
cond = false
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
when Arrow::Template::ElseDirective
|
|
62
|
+
if !hasBeenTrue
|
|
63
|
+
cond = hasBeenTrue = true
|
|
64
|
+
else
|
|
65
|
+
cond = false
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
else
|
|
69
|
+
nodes.push( node ) if cond
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
return template.render( nodes, scope )
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
end # class Arrow::Template::IfDirective
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'arrow/template/nodes'
|
|
4
|
+
require 'arrow/template/parser'
|
|
5
|
+
|
|
6
|
+
# The Arrow::Template::ImportDirective class, a derivative of
|
|
7
|
+
# Arrow::Template::Directive. This is the class which defines the behaviour of
|
|
8
|
+
# the 'import' template directive.
|
|
9
|
+
#
|
|
10
|
+
# === Syntax
|
|
11
|
+
#
|
|
12
|
+
# <?import foo?>
|
|
13
|
+
# <?import foo as superfoo?>
|
|
14
|
+
# <?import foo, bar?>
|
|
15
|
+
# <?import foo as superfoo, bar, baz as bazish?>
|
|
16
|
+
#
|
|
17
|
+
# == Authors
|
|
18
|
+
#
|
|
19
|
+
# * Michael Granger <ged@FaerieMUD.org>
|
|
20
|
+
#
|
|
21
|
+
# Please see the file LICENSE in the top-level directory for licensing details.
|
|
22
|
+
#
|
|
23
|
+
class Arrow::Template::ImportDirective < Arrow::Template::Directive # :nodoc:
|
|
24
|
+
include Arrow::Template::Parser::Patterns
|
|
25
|
+
|
|
26
|
+
# SVN Revision
|
|
27
|
+
SVNRev = %q$Rev$
|
|
28
|
+
|
|
29
|
+
# SVN Id
|
|
30
|
+
SVNId = %q$Id$
|
|
31
|
+
|
|
32
|
+
# Various patterns
|
|
33
|
+
SIMPLEIMPORT = CAPTURE[ IDENTIFIER ]
|
|
34
|
+
ALIASIMPORT = CAPTURE[ IDENTIFIER ] + /\s+as\s+/i + CAPTURE[ IDENTIFIER ]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
#############################################################
|
|
38
|
+
### C L A S S M E T H O D S
|
|
39
|
+
#############################################################
|
|
40
|
+
|
|
41
|
+
### Disallow formats
|
|
42
|
+
def self::allows_format?; false; end
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
#############################################################
|
|
46
|
+
### I N S T A N C E M E T H O D S
|
|
47
|
+
#############################################################
|
|
48
|
+
|
|
49
|
+
### Create a new ImportDirective object.
|
|
50
|
+
def initialize( type, parser, state )
|
|
51
|
+
@imports = {}
|
|
52
|
+
super
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
######
|
|
57
|
+
public
|
|
58
|
+
######
|
|
59
|
+
|
|
60
|
+
# An Array of Regexp objects which match the names of attributes to be
|
|
61
|
+
# imported.
|
|
62
|
+
attr_reader :patterns
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
### Add the imported attributes when this node is rendered.
|
|
66
|
+
def render( template, scope )
|
|
67
|
+
imports = []
|
|
68
|
+
|
|
69
|
+
if (( st = template._enclosing_template ))
|
|
70
|
+
@imports.each do |source,dest|
|
|
71
|
+
imports << "%s as %s (%p)" %
|
|
72
|
+
[ source, dest, st._attributes[source] ]
|
|
73
|
+
template._attributes[dest] = st._attributes[source]
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
if template._config[:debuggingComments]
|
|
78
|
+
return template.render_comment( "Importing: " + imports.join(", ") )
|
|
79
|
+
else
|
|
80
|
+
return ''
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
#########
|
|
86
|
+
protected
|
|
87
|
+
#########
|
|
88
|
+
|
|
89
|
+
### Parse the contents of the directive.
|
|
90
|
+
def parse_directive_contents( parser, state )
|
|
91
|
+
super
|
|
92
|
+
|
|
93
|
+
state.scanner.skip( WHITESPACE )
|
|
94
|
+
#self.log.debug "Scanning for tag middle at: '%20s'" % state.scanner.rest
|
|
95
|
+
|
|
96
|
+
body = state.scanner.scan( state.tag_middle ) or return nil
|
|
97
|
+
#self.log.debug "Found body = %p" % body
|
|
98
|
+
|
|
99
|
+
body.strip.split( /\s*,\s*/ ).each do |import|
|
|
100
|
+
#self.log.debug "Parsing import: %p" % import
|
|
101
|
+
case import
|
|
102
|
+
when ALIASIMPORT
|
|
103
|
+
@imports[ $1 ] = $2
|
|
104
|
+
#self.log.debug "Alias import: %s => %s" %
|
|
105
|
+
# [ $1, $2 ]
|
|
106
|
+
|
|
107
|
+
when SIMPLEIMPORT
|
|
108
|
+
@imports[ $1 ] = $1
|
|
109
|
+
#self.log.debug "Simple import: %s" % $1
|
|
110
|
+
|
|
111
|
+
else
|
|
112
|
+
raise Arrow::ParseError, "Failed to parse body: %p" % body
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
return true
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
end # class Arrow::Template::ImportDirective
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'arrow/exceptions'
|
|
4
|
+
require 'arrow/path'
|
|
5
|
+
require 'arrow/template/nodes'
|
|
6
|
+
|
|
7
|
+
# The Arrow::Template::IncludeDirective class, a derivative of
|
|
8
|
+
# Arrow::Template::Directive. This is the class which defines the
|
|
9
|
+
# behaviour of the 'include' template directive.
|
|
10
|
+
#
|
|
11
|
+
# == Syntax
|
|
12
|
+
#
|
|
13
|
+
# <!-- Include a subtemplate directly -->
|
|
14
|
+
# <?include subtemplate.tmpl ?>
|
|
15
|
+
#
|
|
16
|
+
# <!-- Include a subtemplate as a callable sub-entity -->
|
|
17
|
+
# <?include subtemplate.tmpl as sub ?>
|
|
18
|
+
#
|
|
19
|
+
# == Example
|
|
20
|
+
# If 'subtemplate.tmpl' contains:
|
|
21
|
+
# <?attr foo?>
|
|
22
|
+
# and the main template contains:
|
|
23
|
+
# <?include subtemplate.tmpl?>
|
|
24
|
+
# <?include subtemplate.tmpl as sub?>
|
|
25
|
+
# and the code (+template+ is the Template object) looks like:
|
|
26
|
+
# template.foo = "argle"
|
|
27
|
+
# template.sub.foo = "bargle"
|
|
28
|
+
# the template will render as:
|
|
29
|
+
# argle
|
|
30
|
+
# bargle
|
|
31
|
+
#
|
|
32
|
+
# == Authors
|
|
33
|
+
#
|
|
34
|
+
# * Michael Granger <ged@FaerieMUD.org>
|
|
35
|
+
#
|
|
36
|
+
# Please see the file LICENSE in the top-level directory for licensing details.
|
|
37
|
+
#
|
|
38
|
+
class Arrow::Template::IncludeDirective < Arrow::Template::Directive # :nodoc:
|
|
39
|
+
include Arrow::Template::Parser::Patterns
|
|
40
|
+
|
|
41
|
+
# SVN Revision
|
|
42
|
+
SVNRev = %q$Rev$
|
|
43
|
+
|
|
44
|
+
# SVN Id
|
|
45
|
+
SVNId = %q$Id$
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
#############################################################
|
|
50
|
+
### I N S T A N C E M E T H O D S
|
|
51
|
+
#############################################################
|
|
52
|
+
|
|
53
|
+
### Initialize a new IncludeDirective object.
|
|
54
|
+
def initialize( type, parser, state ) # :notnew:
|
|
55
|
+
@nodes = nil
|
|
56
|
+
@identifier = nil
|
|
57
|
+
@subtemplate = nil
|
|
58
|
+
|
|
59
|
+
state[:includeStack] ||= []
|
|
60
|
+
super
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
######
|
|
65
|
+
public
|
|
66
|
+
######
|
|
67
|
+
|
|
68
|
+
# The identifier associated with an include that has an 'as <name>'
|
|
69
|
+
# part.
|
|
70
|
+
attr_accessor :identifier
|
|
71
|
+
alias_method :name, :identifier
|
|
72
|
+
alias_method :name=, :identifier=
|
|
73
|
+
|
|
74
|
+
# The template object associated with an include that has an 'as <name>'
|
|
75
|
+
# part.
|
|
76
|
+
attr_accessor :subtemplate
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
### Add the nodes that were included to the given +template+ object.
|
|
80
|
+
def add_to_template( template )
|
|
81
|
+
#self.log.debug "Installing an include's subnodes"
|
|
82
|
+
|
|
83
|
+
if @identifier
|
|
84
|
+
template.install_node( self )
|
|
85
|
+
template.send( "#{@identifier}=", @subtemplate )
|
|
86
|
+
targetTemplate = @subtemplate
|
|
87
|
+
else
|
|
88
|
+
targetTemplate = template
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
@nodes.each do |node|
|
|
92
|
+
targetTemplate.install_node( node )
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
### Render the include.
|
|
98
|
+
def render( template, scope )
|
|
99
|
+
rary = super
|
|
100
|
+
|
|
101
|
+
# Render the included nodes
|
|
102
|
+
if @subtemplate
|
|
103
|
+
#self.log.debug "Rendering an include's subtemplate"
|
|
104
|
+
rary.push( *(@subtemplate.render) )
|
|
105
|
+
else
|
|
106
|
+
#self.log.debug "Rendering an include's subnodes"
|
|
107
|
+
rary.push( *(template.render( @nodes, scope )) )
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
return rary
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
### Return an HTML fragment that can be used to represent the node
|
|
115
|
+
### symbolically in a web-based introspection interface.
|
|
116
|
+
def to_html
|
|
117
|
+
nodeclass = self.css_class
|
|
118
|
+
|
|
119
|
+
if @subtemplate
|
|
120
|
+
subtree = @subtemplate._syntax_tree
|
|
121
|
+
html = ''
|
|
122
|
+
html << %q{<strong>#%s</strong> } % @identifier
|
|
123
|
+
html <<
|
|
124
|
+
%q{<div class="node-subtemplate %s-node-subtemplate">
|
|
125
|
+
<div class="node-subtemplate-head %s-node-subtemplate-head"
|
|
126
|
+
>Subtemplate</div>%s</div>} % [
|
|
127
|
+
nodeclass, nodeclass,
|
|
128
|
+
subtree.collect {|node| node.to_html}.join(''),
|
|
129
|
+
]
|
|
130
|
+
|
|
131
|
+
super { html }
|
|
132
|
+
else
|
|
133
|
+
super {
|
|
134
|
+
%q{<div class="node-subtree %s-node-subtree">
|
|
135
|
+
<div class="node-subtree-head %s-node-subtree-head"
|
|
136
|
+
>Subnodes</div>%s</div>} % [
|
|
137
|
+
nodeclass, nodeclass,
|
|
138
|
+
@nodes.collect {|node| node.to_html}.join
|
|
139
|
+
]
|
|
140
|
+
}
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
#########
|
|
146
|
+
protected
|
|
147
|
+
#########
|
|
148
|
+
|
|
149
|
+
### Parse the contents of the directive, loading the specified file into
|
|
150
|
+
### the scanner, if possible.
|
|
151
|
+
def parse_directive_contents( parser, state )
|
|
152
|
+
filename = parser.scan_for_pathname( state ) or
|
|
153
|
+
raise Arrow::ParseError, "No filename found for 'include'"
|
|
154
|
+
filename.untaint
|
|
155
|
+
|
|
156
|
+
state.scanner.skip( WHITESPACE )
|
|
157
|
+
if state.scanner.scan( /\bas\b/i )
|
|
158
|
+
@identifier = parser.scan_for_identifier( state )
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Try to do the include. Handle errors ourselves since this happens
|
|
162
|
+
# during parse time.
|
|
163
|
+
begin
|
|
164
|
+
#self.log.debug "Include stack is: ", state[:includeStack]
|
|
165
|
+
|
|
166
|
+
# Catch circular includes
|
|
167
|
+
if state[:includeStack].include?( filename )
|
|
168
|
+
raise Arrow::TemplateError, "Circular include: %s -> %s" %
|
|
169
|
+
[ state[:includeStack].join(" -> "), filename ]
|
|
170
|
+
|
|
171
|
+
# Parse the included file into nodes, passing the state from
|
|
172
|
+
# the current parse into the subparse.
|
|
173
|
+
else
|
|
174
|
+
initialData = state.data.dup
|
|
175
|
+
initialData[:includeStack].push filename
|
|
176
|
+
|
|
177
|
+
load_path = state.template._load_path
|
|
178
|
+
#self.log.debug "Load path from including template is: %p" %
|
|
179
|
+
# load_path
|
|
180
|
+
path = Arrow::Template.find_file( filename, load_path )
|
|
181
|
+
content = File.read( path )
|
|
182
|
+
content.untaint
|
|
183
|
+
|
|
184
|
+
#self.log.debug "initialData is: %p" % initialData
|
|
185
|
+
@nodes = parser.parse( content, state.template, initialData )
|
|
186
|
+
initialData[:includeStack].pop
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Some errors just turn into comment nodes
|
|
190
|
+
# :TODO: Make this configurable somehow?
|
|
191
|
+
rescue Arrow::TemplateError, IOError => err
|
|
192
|
+
msg = "#{err.class.name}: Include #{filename}: #{err.message}"
|
|
193
|
+
@nodes = [ Arrow::Template::CommentNode.new(msg) ]
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# If the directive has an "as <id>" part, create the subtemplate
|
|
197
|
+
# that will be associated with that identifier.
|
|
198
|
+
if @identifier
|
|
199
|
+
@subtemplate = Arrow::Template.new( @nodes, state.template._config )
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
return true
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
end # class Arrow::Template::IncludeDirective
|