inversion 1.3.1 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/Examples.md +134 -0
- data/GettingStarted.md +50 -0
- data/Guide.md +14 -0
- data/{History.rdoc → History.md} +59 -43
- data/{README.rdoc → README.md} +43 -34
- data/Tags.md +555 -0
- data/bin/inversion +4 -8
- data/lib/inversion/cli/api.rb +75 -0
- data/lib/inversion/cli/tagtokens.rb +34 -0
- data/lib/inversion/cli/tree.rb +70 -0
- data/lib/inversion/cli.rb +406 -0
- data/lib/inversion/exceptions.rb +0 -1
- data/lib/inversion/mixins.rb +10 -11
- data/lib/inversion/parser.rb +5 -6
- data/lib/inversion/refinements.rb +18 -0
- data/lib/inversion/renderstate.rb +24 -25
- data/lib/inversion/sinatra.rb +0 -1
- data/lib/inversion/template/attrtag.rb +7 -5
- data/lib/inversion/template/begintag.rb +0 -1
- data/lib/inversion/template/calltag.rb +0 -1
- data/lib/inversion/template/codetag.rb +37 -28
- data/lib/inversion/template/commenttag.rb +0 -1
- data/lib/inversion/template/configtag.rb +3 -4
- data/lib/inversion/template/containertag.rb +1 -2
- data/lib/inversion/template/defaulttag.rb +1 -2
- data/lib/inversion/template/elsetag.rb +0 -1
- data/lib/inversion/template/elsiftag.rb +0 -1
- data/lib/inversion/template/endtag.rb +2 -3
- data/lib/inversion/template/escapetag.rb +1 -2
- data/lib/inversion/template/fortag.rb +2 -3
- data/lib/inversion/template/fragmenttag.rb +1 -2
- data/lib/inversion/template/iftag.rb +3 -1
- data/lib/inversion/template/importtag.rb +2 -3
- data/lib/inversion/template/includetag.rb +1 -2
- data/lib/inversion/template/node.rb +4 -5
- data/lib/inversion/template/pptag.rb +1 -2
- data/lib/inversion/template/publishtag.rb +2 -3
- data/lib/inversion/template/rescuetag.rb +1 -2
- data/lib/inversion/template/subscribetag.rb +3 -4
- data/lib/inversion/template/tag.rb +3 -4
- data/lib/inversion/template/textnode.rb +1 -2
- data/lib/inversion/template/timedeltatag.rb +1 -2
- data/lib/inversion/template/unlesstag.rb +0 -1
- data/lib/inversion/template/uriencodetag.rb +1 -2
- data/lib/inversion/template/yieldtag.rb +0 -1
- data/lib/inversion/template.rb +18 -22
- data/lib/inversion/tilt.rb +1 -2
- data/lib/inversion.rb +2 -3
- data/lib/roda/plugins/inversion.rb +225 -0
- data/spec/helpers.rb +19 -13
- data/spec/inversion/mixins_spec.rb +1 -1
- data/spec/inversion/parser_spec.rb +1 -1
- data/spec/inversion/refinements_spec.rb +22 -0
- data/spec/inversion/renderstate_spec.rb +1 -1
- data/spec/inversion/sinatra_spec.rb +1 -1
- data/spec/inversion/template/attrtag_spec.rb +1 -1
- data/spec/inversion/template/begintag_spec.rb +1 -1
- data/spec/inversion/template/calltag_spec.rb +1 -1
- data/spec/inversion/template/codetag_spec.rb +24 -1
- data/spec/inversion/template/commenttag_spec.rb +1 -1
- data/spec/inversion/template/configtag_spec.rb +1 -1
- data/spec/inversion/template/containertag_spec.rb +1 -1
- data/spec/inversion/template/defaulttag_spec.rb +1 -1
- data/spec/inversion/template/elsetag_spec.rb +1 -1
- data/spec/inversion/template/elsiftag_spec.rb +1 -1
- data/spec/inversion/template/endtag_spec.rb +1 -1
- data/spec/inversion/template/escapetag_spec.rb +1 -1
- data/spec/inversion/template/fortag_spec.rb +1 -1
- data/spec/inversion/template/fragmenttag_spec.rb +1 -1
- data/spec/inversion/template/iftag_spec.rb +1 -1
- data/spec/inversion/template/importtag_spec.rb +1 -1
- data/spec/inversion/template/includetag_spec.rb +1 -1
- data/spec/inversion/template/node_spec.rb +1 -1
- data/spec/inversion/template/pptag_spec.rb +1 -1
- data/spec/inversion/template/publishtag_spec.rb +1 -1
- data/spec/inversion/template/rescuetag_spec.rb +1 -1
- data/spec/inversion/template/subscribetag_spec.rb +1 -1
- data/spec/inversion/template/tag_spec.rb +1 -1
- data/spec/inversion/template/textnode_spec.rb +1 -1
- data/spec/inversion/template/timedeltatag_spec.rb +1 -1
- data/spec/inversion/template/unlesstag_spec.rb +1 -1
- data/spec/inversion/template/uriencodetag_spec.rb +1 -1
- data/spec/inversion/template/yieldtag_spec.rb +1 -1
- data/spec/inversion/template_spec.rb +1 -1
- data/spec/inversion/tilt_spec.rb +1 -1
- data/spec/inversion_spec.rb +1 -1
- data/spec/roda/plugins/inversion_spec.rb +91 -0
- data.tar.gz.sig +0 -0
- metadata +90 -58
- metadata.gz.sig +0 -0
- data/Examples.rdoc +0 -134
- data/GettingStarted.rdoc +0 -44
- data/Guide.rdoc +0 -47
- data/Manifest.txt +0 -86
- data/Rakefile +0 -7
- data/Tags.rdoc +0 -560
- data/lib/inversion/command.rb +0 -278
- data/lib/inversion/monkeypatches.rb +0 -21
- data/spec/inversion/monkeypatches_spec.rb +0 -25
@@ -1,5 +1,4 @@
|
|
1
1
|
# -*- ruby -*-
|
2
|
-
# frozen_string_literal: true
|
3
2
|
# vim: set noet nosta sw=4 ts=4 :
|
4
3
|
|
5
4
|
require 'inversion/template' unless defined?( Inversion::Template )
|
@@ -31,7 +30,7 @@ class Inversion::Template::PublishTag < Inversion::Template::Tag
|
|
31
30
|
include Inversion::Template::ContainerTag
|
32
31
|
|
33
32
|
|
34
|
-
### Create a new PublishTag with the given
|
33
|
+
### Create a new PublishTag with the given `body`.
|
35
34
|
def initialize( body, line=nil, column=nil )
|
36
35
|
super
|
37
36
|
|
@@ -50,7 +49,7 @@ class Inversion::Template::PublishTag < Inversion::Template::Tag
|
|
50
49
|
attr_reader :key
|
51
50
|
|
52
51
|
|
53
|
-
### Render the published subnodes in the context of the given
|
52
|
+
### Render the published subnodes in the context of the given `renderstate`, but
|
54
53
|
### save them for publication after the render is done.
|
55
54
|
def render( renderstate )
|
56
55
|
self.log.debug "Publishing %d nodes as %s" % [ self.subnodes.length, self.key ]
|
@@ -1,5 +1,4 @@
|
|
1
1
|
# -*- ruby -*-
|
2
|
-
# frozen_string_literal: true
|
3
2
|
# vim: set noet nosta sw=4 ts=4 :
|
4
3
|
|
5
4
|
require 'inversion/template' unless defined?( Inversion::Template )
|
@@ -72,7 +71,7 @@ class Inversion::Template::RescueTag < Inversion::Template::Tag
|
|
72
71
|
private
|
73
72
|
#######
|
74
73
|
|
75
|
-
### Parse one or more exception classes from the given
|
74
|
+
### Parse one or more exception classes from the given `rescuespec` and return them.
|
76
75
|
def parse_exception_types( rescuespec )
|
77
76
|
return [ ::RuntimeError ] if rescuespec.nil? || rescuespec == ''
|
78
77
|
|
@@ -1,5 +1,4 @@
|
|
1
1
|
# -*- ruby -*-
|
2
|
-
# frozen_string_literal: true
|
3
2
|
# vim: set noet nosta sw=4 ts=4 :
|
4
3
|
|
5
4
|
require 'inversion/template' unless defined?( Inversion::Template )
|
@@ -29,7 +28,7 @@ require 'inversion/template/tag'
|
|
29
28
|
#
|
30
29
|
class Inversion::Template::SubscribeTag < Inversion::Template::Tag
|
31
30
|
|
32
|
-
### Create a new SubscribeTag with the given
|
31
|
+
### Create a new SubscribeTag with the given `body`.
|
33
32
|
def initialize( body, line=nil, column=nil )
|
34
33
|
super
|
35
34
|
|
@@ -60,7 +59,7 @@ class Inversion::Template::SubscribeTag < Inversion::Template::Tag
|
|
60
59
|
attr_reader :content
|
61
60
|
|
62
61
|
|
63
|
-
### Tell the
|
62
|
+
### Tell the `renderstate` that this tag is interested in nodes that are published with
|
64
63
|
### its key.
|
65
64
|
def before_rendering( renderstate )
|
66
65
|
@content.clear
|
@@ -74,7 +73,7 @@ class Inversion::Template::SubscribeTag < Inversion::Template::Tag
|
|
74
73
|
end
|
75
74
|
|
76
75
|
|
77
|
-
### Pub/sub callback. Called from the RenderState when a PublishTag publishes
|
76
|
+
### Pub/sub callback. Called from the RenderState when a PublishTag publishes `nodes`
|
78
77
|
### with the same key as the current tag.
|
79
78
|
def publish( *nodes )
|
80
79
|
self.log.debug "Adding published nodes %p to %p" % [ nodes, @content ]
|
@@ -1,5 +1,4 @@
|
|
1
1
|
# -*- ruby -*-
|
2
|
-
# frozen_string_literal: true
|
3
2
|
# vim: set noet nosta sw=4 ts=4 :
|
4
3
|
|
5
4
|
require 'loggability'
|
@@ -105,7 +104,7 @@ class Inversion::Template::Tag < Inversion::Template::Node
|
|
105
104
|
end
|
106
105
|
|
107
106
|
|
108
|
-
### Safely load the specified
|
107
|
+
### Safely load the specified `tagfile`.
|
109
108
|
def self::load( tagfile )
|
110
109
|
tagrequire = tagfile[ %r{inversion/template/\w+tag} ] or
|
111
110
|
raise "tag file %p doesn't look like a tag plugin" % [ tagfile ]
|
@@ -118,7 +117,7 @@ class Inversion::Template::Tag < Inversion::Template::Node
|
|
118
117
|
end
|
119
118
|
|
120
119
|
|
121
|
-
### Create a new Inversion::Template::Tag from the specified
|
120
|
+
### Create a new Inversion::Template::Tag from the specified `tagname` and `body`.
|
122
121
|
def self::create( tagname, body, linenum=nil, colnum=nil )
|
123
122
|
tagname =~ /^(\w+)$/i or raise ArgumentError, "invalid tag name %p" % [ tagname ]
|
124
123
|
tagtype = $1.downcase
|
@@ -137,7 +136,7 @@ class Inversion::Template::Tag < Inversion::Template::Node
|
|
137
136
|
### I N S T A N C E M E T H O D S
|
138
137
|
########################################################################
|
139
138
|
|
140
|
-
### Create a new Inversion::Template::Tag with the specified
|
139
|
+
### Create a new Inversion::Template::Tag with the specified `body`.
|
141
140
|
def initialize( body, linenum=nil, colnum=nil )
|
142
141
|
super
|
143
142
|
@body = body.to_s.strip
|
@@ -1,5 +1,4 @@
|
|
1
1
|
# -*- ruby -*-
|
2
|
-
# frozen_string_literal: true
|
3
2
|
# vim: set noet nosta sw=4 ts=4 :
|
4
3
|
|
5
4
|
require 'inversion/template' unless defined?( Inversion::Template )
|
@@ -8,7 +7,7 @@ require 'inversion/template/node'
|
|
8
7
|
# Inversion text node class -- container for static content in templates between tags.
|
9
8
|
class Inversion::Template::TextNode < Inversion::Template::Node
|
10
9
|
|
11
|
-
### Create a new TextNode with the specified
|
10
|
+
### Create a new TextNode with the specified `source`.
|
12
11
|
def initialize( body, linenum=nil, colnum=nil )
|
13
12
|
@body = body
|
14
13
|
super
|
@@ -1,5 +1,4 @@
|
|
1
1
|
# -*- ruby -*-
|
2
|
-
# frozen_string_literal: true
|
3
2
|
# vim: set noet nosta sw=4 ts=4 :
|
4
3
|
|
5
4
|
require 'uri'
|
@@ -74,7 +73,7 @@ class Inversion::Template::TimeDeltaTag < Inversion::Template::AttrTag
|
|
74
73
|
private
|
75
74
|
#######
|
76
75
|
|
77
|
-
### Return a string describing
|
76
|
+
### Return a string describing `seconds` as an approximate interval of time.
|
78
77
|
def timeperiod( seconds )
|
79
78
|
return case
|
80
79
|
when seconds < MINUTES - 5
|
@@ -1,5 +1,4 @@
|
|
1
1
|
# -*- ruby -*-
|
2
|
-
# frozen_string_literal: true
|
3
2
|
# vim: set noet nosta sw=4 ts=4 :
|
4
3
|
|
5
4
|
require 'uri'
|
@@ -19,7 +18,7 @@ class Inversion::Template::UriencodeTag < Inversion::Template::AttrTag
|
|
19
18
|
include Inversion::Escaping
|
20
19
|
|
21
20
|
|
22
|
-
### Render the method chains against the attributes of the specified
|
21
|
+
### Render the method chains against the attributes of the specified `render_state`
|
23
22
|
### and return them.
|
24
23
|
def render( render_state )
|
25
24
|
raw = super
|
data/lib/inversion/template.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# -*- ruby -*-
|
2
|
-
# frozen_string_literal: true
|
3
2
|
# vim: set noet nosta sw=4 ts=4 :
|
4
3
|
|
5
4
|
require 'loggability'
|
@@ -28,23 +27,23 @@ end
|
|
28
27
|
#
|
29
28
|
# == Template Options
|
30
29
|
#
|
31
|
-
# Inversion supports the
|
32
|
-
# API, and registers itself with the
|
33
|
-
# a
|
30
|
+
# Inversion supports the [Configurability](http://rubygems.org/gems/configurability)
|
31
|
+
# API, and registers itself with the `templates` key. This means you can either add
|
32
|
+
# a `templates` section to your Configurability config, or call
|
34
33
|
# ::configure yourself with a config Hash (or something that quacks like one).
|
35
34
|
#
|
36
35
|
# To set options on a per-template basis, you can pass an options hash to either
|
37
36
|
# Inversion::Template::load or Inversion::Template::new, or set them from within the template
|
38
|
-
# itself using the
|
37
|
+
# itself using the [config tag](rdoc-ref:Tags@config).
|
39
38
|
#
|
40
39
|
# The available options are:
|
41
40
|
#
|
42
41
|
# [:ignore_unknown_tags]
|
43
42
|
# Setting to false causes unknown tags used in templates to raise an
|
44
|
-
# Inversion::ParseError. Defaults to
|
43
|
+
# Inversion::ParseError. Defaults to `true`.
|
45
44
|
#
|
46
45
|
# [:on_render_error]
|
47
|
-
# Dictates the behavior of exceptions during rendering. Defaults to
|
46
|
+
# Dictates the behavior of exceptions during rendering. Defaults to `:comment`.
|
48
47
|
#
|
49
48
|
# [:ignore]
|
50
49
|
# Exceptions are silently ignored.
|
@@ -55,7 +54,7 @@ end
|
|
55
54
|
#
|
56
55
|
#
|
57
56
|
# [:debugging_comments]
|
58
|
-
# Insert various Inversion parse and render statements while rendering. Defaults to
|
57
|
+
# Insert various Inversion parse and render statements while rendering. Defaults to `false`.
|
59
58
|
#
|
60
59
|
# [:comment_start]
|
61
60
|
# When rendering debugging comments, the comment is started with these characters.
|
@@ -71,16 +70,16 @@ end
|
|
71
70
|
# last checked member of this. Defaults to <code>[]</code>.
|
72
71
|
#
|
73
72
|
# [:escape_format]
|
74
|
-
# The escaping used by tags such as
|
73
|
+
# The escaping used by tags such as `escape` and `pp`. Default: `:html`.
|
75
74
|
#
|
76
75
|
# [:strip_tag_lines]
|
77
76
|
# If a tag's presence introduces a blank line into the output, this option
|
78
|
-
# removes it. Defaults to
|
77
|
+
# removes it. Defaults to `true`.
|
79
78
|
#
|
80
79
|
# [:stat_delay]
|
81
80
|
# Templates know when they've been altered on disk, and can dynamically
|
82
81
|
# reload themselves in long running applications. Setting this option creates
|
83
|
-
# a purposeful delay between reloads for busy servers. Defaults to
|
82
|
+
# a purposeful delay between reloads for busy servers. Defaults to `0`
|
84
83
|
# (disabled).
|
85
84
|
#
|
86
85
|
# [:strict_attributes]
|
@@ -111,9 +110,6 @@ class Inversion::Template
|
|
111
110
|
require 'inversion/template/tag'
|
112
111
|
require 'inversion/renderstate'
|
113
112
|
|
114
|
-
# Alias to maintain backward compatibility with <0.2.0 code
|
115
|
-
Parser = Inversion::Parser
|
116
|
-
|
117
113
|
# Valid actions for 'on_render_error'
|
118
114
|
VALID_ERROR_ACTIONS = [
|
119
115
|
:ignore,
|
@@ -165,7 +161,7 @@ class Inversion::Template
|
|
165
161
|
end
|
166
162
|
|
167
163
|
|
168
|
-
### Read a template object from the specified
|
164
|
+
### Read a template object from the specified `path`.
|
169
165
|
def self::load( path, parsestate=nil, opts={} )
|
170
166
|
|
171
167
|
# Shift the options hash over if there isn't a parse state
|
@@ -210,10 +206,10 @@ class Inversion::Template
|
|
210
206
|
end
|
211
207
|
|
212
208
|
|
213
|
-
### Add one or more extension
|
209
|
+
### Add one or more extension `modules` to Inversion::Template. This allows tags to decorate
|
214
210
|
### the template class with new functionality.
|
215
211
|
###
|
216
|
-
### Each one of the given
|
212
|
+
### Each one of the given `modules` will be included as a mixin, and if it also
|
217
213
|
### contains a constant called ClassMethods and/or PrependedMethods, it will
|
218
214
|
### also be extended/prepended (respectively) with it.
|
219
215
|
###
|
@@ -260,7 +256,7 @@ class Inversion::Template
|
|
260
256
|
end
|
261
257
|
|
262
258
|
|
263
|
-
### Create a new Inversion:Template with the given
|
259
|
+
### Create a new Inversion:Template with the given `source`.
|
264
260
|
def initialize( source, parsestate=nil, opts={} )
|
265
261
|
if parsestate.is_a?( Hash )
|
266
262
|
# self.log.debug "Shifting template options: %p" % [ parsestate ]
|
@@ -325,7 +321,7 @@ class Inversion::Template
|
|
325
321
|
end
|
326
322
|
|
327
323
|
|
328
|
-
### Returns
|
324
|
+
### Returns `true` if the template was loaded from a file and the file's mtime
|
329
325
|
### is after the time the template was created.
|
330
326
|
def changed?
|
331
327
|
return false unless file = self.source_file
|
@@ -408,7 +404,7 @@ class Inversion::Template
|
|
408
404
|
end
|
409
405
|
|
410
406
|
|
411
|
-
### Parse the given
|
407
|
+
### Parse the given `source` into the template node tree.
|
412
408
|
def parse( source, parsestate=nil )
|
413
409
|
opts = self.class.config.merge( self.options )
|
414
410
|
parser = Inversion::Parser.new( self, opts )
|
@@ -442,7 +438,7 @@ class Inversion::Template
|
|
442
438
|
end
|
443
439
|
|
444
440
|
|
445
|
-
### Add attributes for the given
|
441
|
+
### Add attributes for the given `node`'s identifiers.
|
446
442
|
def add_attributes_from_node( node )
|
447
443
|
if node.respond_to?( :identifiers )
|
448
444
|
node.identifiers.each do |id|
|
@@ -453,7 +449,7 @@ class Inversion::Template
|
|
453
449
|
end
|
454
450
|
|
455
451
|
|
456
|
-
### Install reader and writer methods for the attribute associated with the specified
|
452
|
+
### Install reader and writer methods for the attribute associated with the specified `key`.
|
457
453
|
def install_accessors( key )
|
458
454
|
reader, writer = self.make_attribute_accessors( key )
|
459
455
|
|
data/lib/inversion/tilt.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# -*- ruby -*-
|
2
|
-
# frozen_string_literal: true
|
3
2
|
# vim: set noet nosta sw=4 ts=4 :
|
4
3
|
|
5
4
|
require 'tilt'
|
@@ -36,7 +35,7 @@ if defined?( ::Tilt )
|
|
36
35
|
self.evaluate( *args )
|
37
36
|
end
|
38
37
|
|
39
|
-
### Tilt::Template API: render the template with the given
|
38
|
+
### Tilt::Template API: render the template with the given `scope`, `locals`, and `block`.
|
40
39
|
def evaluate( scope, locals, &block )
|
41
40
|
@template.attributes.merge!( scope.to_h ) if scope.respond_to?( :to_h )
|
42
41
|
@template.attributes.merge!( locals )
|
data/lib/inversion.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# -*- ruby -*-
|
2
|
-
# frozen_string_literal: true
|
3
2
|
# vim: set noet nosta sw=4 ts=4 :
|
4
3
|
|
5
4
|
require 'loggability'
|
@@ -26,7 +25,7 @@ module Inversion
|
|
26
25
|
warn ">>> Inversion requires Ruby 2.4.0 or later. <<<" if RUBY_VERSION < '2.4.0'
|
27
26
|
|
28
27
|
# Library version constant
|
29
|
-
VERSION = '1.
|
28
|
+
VERSION = '1.5.0'
|
30
29
|
|
31
30
|
# Version-control revision constant
|
32
31
|
REVISION = %q$Revision$
|
@@ -40,8 +39,8 @@ module Inversion
|
|
40
39
|
end
|
41
40
|
|
42
41
|
require 'inversion/exceptions'
|
42
|
+
require 'inversion/refinements'
|
43
43
|
require 'inversion/mixins'
|
44
|
-
require 'inversion/monkeypatches'
|
45
44
|
require 'inversion/template'
|
46
45
|
|
47
46
|
end # module Inversion
|
@@ -0,0 +1,225 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
# vim: set nosta noet ts=4 sw=4 ft=ruby:
|
3
|
+
|
4
|
+
require 'inversion'
|
5
|
+
require 'loggability'
|
6
|
+
|
7
|
+
class Roda
|
8
|
+
module RodaPlugins
|
9
|
+
|
10
|
+
# A templated content-generation plugin for Roda Apps. It uses the
|
11
|
+
# Inversion[http://deveiate.org/projects/Inversion] templating system.
|
12
|
+
#
|
13
|
+
# It adds:
|
14
|
+
#
|
15
|
+
# * a preloaded/cached template table
|
16
|
+
# * a mechanism for fetching templates from the table
|
17
|
+
# * a global layout template which is automatically wrapped around responses
|
18
|
+
#
|
19
|
+
# Note: This is based almost entirely off the Strelka plugin of identical
|
20
|
+
# function.
|
21
|
+
#
|
22
|
+
# == Usage
|
23
|
+
#
|
24
|
+
# To use it, just load the <tt>:inversion</tt> plugin in your app:
|
25
|
+
#
|
26
|
+
# plugin :inversion, '/path/to/templates/directory'
|
27
|
+
#
|
28
|
+
# You can specify more than one templates directory; they'll be searched in the order
|
29
|
+
# you specify for the named template and the first match wins:
|
30
|
+
#
|
31
|
+
# plugin :inversion '/more/specific/templates', '/generic/app/templates'
|
32
|
+
#
|
33
|
+
# Then declare one or more templates that your application will use:
|
34
|
+
#
|
35
|
+
# templates console: 'views/console.tmpl',
|
36
|
+
# proctable: 'partials/proctable.tmpl'
|
37
|
+
#
|
38
|
+
# Then, inside your app, you can fetch a copy of one or more of the templates and
|
39
|
+
# return it as the response:
|
40
|
+
#
|
41
|
+
# r.root do
|
42
|
+
# tmpl = template( :console )
|
43
|
+
# tmpl.message = "Everything's up."
|
44
|
+
# tmpl.proctable = proctable
|
45
|
+
# return tmpl
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
#
|
49
|
+
# You can also just return the template if you don't need to do anything else to the
|
50
|
+
# response.
|
51
|
+
#
|
52
|
+
# When returning a template, either in the body of the response or directly, it will
|
53
|
+
# automatically set a few attributes for commonly-used objects:
|
54
|
+
#
|
55
|
+
# request :: The current Roda::Request
|
56
|
+
# response :: The current Roda::Response
|
57
|
+
# app :: The application object (Roda::App instance).
|
58
|
+
#
|
59
|
+
# If your app will *only* be loading and returning a template without doing anything
|
60
|
+
# with it, you can return just its name:
|
61
|
+
#
|
62
|
+
# r.root do
|
63
|
+
# return :console
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# It will be loaded, set as the response body, and the above common objects added to it.
|
67
|
+
#
|
68
|
+
#
|
69
|
+
# === Layouts
|
70
|
+
#
|
71
|
+
# Very often, you'll want all or most of the views in your app to share a common page
|
72
|
+
# layout. To accomplish this, you can declare a layout template:
|
73
|
+
#
|
74
|
+
# layout 'layout.tmpl'
|
75
|
+
#
|
76
|
+
# Any template that you return will be set as the 'body' attribute of this layout
|
77
|
+
# template (which you'd place into the layout with <tt><?attr body ?></tt>) and the
|
78
|
+
# layout rendered as the body of the response.
|
79
|
+
#
|
80
|
+
# Note that if you want any of the "common objects" from above with a layout template,
|
81
|
+
# they'll be set on it since it's the top-level template, but you can still access them
|
82
|
+
# using the <tt><?import ?></tt> directive:
|
83
|
+
#
|
84
|
+
# <?import request, app ?>
|
85
|
+
#
|
86
|
+
#
|
87
|
+
# == Template Locations
|
88
|
+
#
|
89
|
+
# Inversion looks for templates in a load path much like Ruby does for libraries that
|
90
|
+
# you 'require'. It contains just the current working directory by default. You can add
|
91
|
+
# your own template directories via the config file (under +template_paths+ in
|
92
|
+
# the +templates+ section), or programmatically from your application.
|
93
|
+
#
|
94
|
+
module Inversion
|
95
|
+
|
96
|
+
### Add the specified +template_paths+ to Inversion.
|
97
|
+
def self::configure( app, *template_paths )
|
98
|
+
::Inversion::Template.template_paths.concat( template_paths )
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
module ClassMethods
|
103
|
+
|
104
|
+
### Add this Gem's template location to the Inversion search path.
|
105
|
+
def self::extended( subclass )
|
106
|
+
subclass.instance_variable_set( :@template_map, {} )
|
107
|
+
subclass.instance_variable_set( :@layout_template, nil )
|
108
|
+
|
109
|
+
super
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
# The map of template names to template file paths.
|
114
|
+
attr_reader :template_map
|
115
|
+
|
116
|
+
# An optional layout/wrap template.
|
117
|
+
attr_accessor :layout_template
|
118
|
+
|
119
|
+
|
120
|
+
### Load instances for all the template paths specified in the App's class
|
121
|
+
### and return them in a hash keyed by name (Symbol).
|
122
|
+
def templates( hash )
|
123
|
+
@template_map = hash.each_with_object( {} ) do |(name, path), map|
|
124
|
+
enc = Encoding.default_internal || Encoding::UTF_8
|
125
|
+
map[ name ] = ::Inversion::Template.load( path, encoding: enc )
|
126
|
+
map
|
127
|
+
end
|
128
|
+
|
129
|
+
return self.template_map
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
### Load an Inversion::Template for the layout template.
|
134
|
+
def layout( tmpl )
|
135
|
+
enc = Encoding.default_internal || Encoding::UTF_8
|
136
|
+
self.layout_template = ::Inversion::Template.load( tmpl, encoding: enc )
|
137
|
+
return self.layout_template
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
module InstanceMethods
|
143
|
+
|
144
|
+
### Return a previously declared template object.
|
145
|
+
def template( tmpl )
|
146
|
+
template = self.class.template_map[ tmpl ] or
|
147
|
+
raise ArgumentError, "no %p template registered!" % [ tmpl ]
|
148
|
+
template.reload if template.changed?
|
149
|
+
return template.dup
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
module RequestMethods
|
155
|
+
|
156
|
+
### Hook block results for template rendering.
|
157
|
+
def block_result_body( result )
|
158
|
+
if ( template = self.extract_template_from_result( result ) )
|
159
|
+
|
160
|
+
# Wrap the template in a layout if there is one
|
161
|
+
template = self.wrap_in_layout( template )
|
162
|
+
|
163
|
+
# Set some default stuff on the top-level template
|
164
|
+
self.set_common_attributes( template )
|
165
|
+
|
166
|
+
return template.render
|
167
|
+
else
|
168
|
+
super
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
|
173
|
+
#########
|
174
|
+
protected
|
175
|
+
#########
|
176
|
+
|
177
|
+
### Fetch the template from the +result+ (if there is one) and return it.
|
178
|
+
def extract_template_from_result( result )
|
179
|
+
templates = self.scope.class.template_map
|
180
|
+
|
181
|
+
# Result is a template name.
|
182
|
+
if result.is_a?( Symbol ) && templates.key?( result )
|
183
|
+
return scope.template( result )
|
184
|
+
|
185
|
+
# Result is a template object.
|
186
|
+
elsif result.respond_to?( :render )
|
187
|
+
return result
|
188
|
+
end
|
189
|
+
|
190
|
+
# Not templated; returned as-is
|
191
|
+
return nil
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
### Wrap the specified +content+ template in the layout template and
|
196
|
+
### return it. If there isn't a layout declared, just return +content+ as-is.
|
197
|
+
def wrap_in_layout( content )
|
198
|
+
layout = self.scope.class.layout_template or return content
|
199
|
+
|
200
|
+
layout.reload if layout.changed?
|
201
|
+
l_template = layout.dup
|
202
|
+
l_template.body = content
|
203
|
+
|
204
|
+
return l_template
|
205
|
+
end
|
206
|
+
|
207
|
+
|
208
|
+
### Set some default values from the request in the given top-level +template+.
|
209
|
+
def set_common_attributes( template )
|
210
|
+
template.request = self
|
211
|
+
template.response = self.scope.response
|
212
|
+
template.app = self.scope
|
213
|
+
end
|
214
|
+
|
215
|
+
end
|
216
|
+
|
217
|
+
end # module Inversion
|
218
|
+
|
219
|
+
|
220
|
+
# Hook: Inform Roda that we exist.
|
221
|
+
register_plugin :inversion, Inversion
|
222
|
+
|
223
|
+
end # module RodaPlugins
|
224
|
+
end # class Roda
|
225
|
+
|
data/spec/helpers.rb
CHANGED
@@ -11,7 +11,7 @@ require 'loggability/spechelpers'
|
|
11
11
|
|
12
12
|
require 'inversion'
|
13
13
|
|
14
|
-
Inversion::Template::Tag.load_all
|
14
|
+
# Inversion::Template::Tag.load_all
|
15
15
|
|
16
16
|
|
17
17
|
### RSpec helper functions.
|
@@ -21,14 +21,14 @@ module Inversion::SpecHelpers
|
|
21
21
|
module_function
|
22
22
|
###############
|
23
23
|
|
24
|
-
### Make an easily-comparable version vector out of
|
24
|
+
### Make an easily-comparable version vector out of `ver` and return it.
|
25
25
|
def vvec( ver )
|
26
26
|
return ver.split('.').collect {|char| char.to_i }.pack('N*')
|
27
27
|
end
|
28
28
|
|
29
29
|
|
30
|
-
### Create a string containing an XML Processing Instruction with the given
|
31
|
-
### and
|
30
|
+
### Create a string containing an XML Processing Instruction with the given `name`
|
31
|
+
### and `data`.
|
32
32
|
def create_pi( name, data )
|
33
33
|
return "<?#{name} #{data} ?>"
|
34
34
|
end
|
@@ -37,19 +37,25 @@ end
|
|
37
37
|
|
38
38
|
|
39
39
|
### Mock with RSpec
|
40
|
-
RSpec.configure do |
|
40
|
+
RSpec.configure do |config|
|
41
41
|
|
42
|
-
|
43
|
-
c.filter_run :focus
|
44
|
-
c.order = 'random'
|
45
|
-
c.mock_with( :rspec ) do |mock|
|
42
|
+
config.mock_with( :rspec ) do |mock|
|
46
43
|
mock.syntax = :expect
|
47
44
|
end
|
48
|
-
c.wait_timeout = 3
|
49
|
-
c.example_status_persistence_file_path = 'spec/.state'
|
50
45
|
|
51
|
-
|
52
|
-
|
46
|
+
config.disable_monkey_patching!
|
47
|
+
config.example_status_persistence_file_path = "spec/.status"
|
48
|
+
config.filter_run :focus
|
49
|
+
config.filter_run_when_matching :focus
|
50
|
+
config.order = :random
|
51
|
+
config.profile_examples = 5
|
52
|
+
config.run_all_when_everything_filtered = true
|
53
|
+
config.shared_context_metadata_behavior = :apply_to_host_groups
|
54
|
+
config.wait_timeout = 3
|
55
|
+
# config.warnings = true
|
56
|
+
|
57
|
+
config.include( Inversion::SpecHelpers )
|
58
|
+
config.include( Loggability::SpecHelpers )
|
53
59
|
end
|
54
60
|
|
55
61
|
# vim: set nosta noet ts=4 sw=4:
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env rspec -cfd -b
|
2
|
+
# vim: set noet nosta sw=4 ts=4 :
|
3
|
+
|
4
|
+
|
5
|
+
require_relative '../helpers'
|
6
|
+
|
7
|
+
require 'ripper'
|
8
|
+
require 'inversion/refinements'
|
9
|
+
|
10
|
+
|
11
|
+
RSpec.describe Inversion, "refinements" do
|
12
|
+
|
13
|
+
using Inversion::Refinements
|
14
|
+
|
15
|
+
it "exposes the Ripper::TokenPattern::MatchData's #tokens array" do
|
16
|
+
tagpattern = Ripper::TokenPattern.compile( '$(ident) $(sp) $(ident)' )
|
17
|
+
matchdata = tagpattern.match( "foo bar" )
|
18
|
+
expect( matchdata.tokens.map {|tok| tok[1]} ).to eq([ :on_ident, :on_sp, :on_ident ])
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
@@ -11,7 +11,7 @@ require 'inversion/template/fragmenttag'
|
|
11
11
|
require 'inversion/template/subscribetag'
|
12
12
|
require 'inversion/template/publishtag'
|
13
13
|
|
14
|
-
describe Inversion::RenderState do
|
14
|
+
RSpec.describe Inversion::RenderState do
|
15
15
|
|
16
16
|
|
17
17
|
it "provides access to the block it was constructed with if there was one" do
|