inversion 0.0.1

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.
Files changed (78) hide show
  1. data.tar.gz.sig +2 -0
  2. data/.gemtest +0 -0
  3. data/ChangeLog +836 -0
  4. data/History.md +4 -0
  5. data/Manifest.txt +74 -0
  6. data/README.rdoc +171 -0
  7. data/Rakefile +55 -0
  8. data/bin/inversion +276 -0
  9. data/lib/inversion.rb +98 -0
  10. data/lib/inversion/exceptions.rb +21 -0
  11. data/lib/inversion/mixins.rb +236 -0
  12. data/lib/inversion/monkeypatches.rb +20 -0
  13. data/lib/inversion/renderstate.rb +337 -0
  14. data/lib/inversion/sinatra.rb +35 -0
  15. data/lib/inversion/template.rb +250 -0
  16. data/lib/inversion/template/attrtag.rb +120 -0
  17. data/lib/inversion/template/calltag.rb +16 -0
  18. data/lib/inversion/template/codetag.rb +164 -0
  19. data/lib/inversion/template/commenttag.rb +54 -0
  20. data/lib/inversion/template/conditionaltag.rb +49 -0
  21. data/lib/inversion/template/configtag.rb +60 -0
  22. data/lib/inversion/template/containertag.rb +45 -0
  23. data/lib/inversion/template/elsetag.rb +62 -0
  24. data/lib/inversion/template/elsiftag.rb +49 -0
  25. data/lib/inversion/template/endtag.rb +55 -0
  26. data/lib/inversion/template/escapetag.rb +26 -0
  27. data/lib/inversion/template/fortag.rb +120 -0
  28. data/lib/inversion/template/iftag.rb +69 -0
  29. data/lib/inversion/template/importtag.rb +70 -0
  30. data/lib/inversion/template/includetag.rb +51 -0
  31. data/lib/inversion/template/node.rb +102 -0
  32. data/lib/inversion/template/parser.rb +297 -0
  33. data/lib/inversion/template/pptag.rb +28 -0
  34. data/lib/inversion/template/publishtag.rb +72 -0
  35. data/lib/inversion/template/subscribetag.rb +88 -0
  36. data/lib/inversion/template/tag.rb +150 -0
  37. data/lib/inversion/template/textnode.rb +43 -0
  38. data/lib/inversion/template/unlesstag.rb +60 -0
  39. data/lib/inversion/template/uriencodetag.rb +30 -0
  40. data/lib/inversion/template/yieldtag.rb +51 -0
  41. data/lib/inversion/tilt.rb +82 -0
  42. data/lib/inversion/utils.rb +235 -0
  43. data/spec/data/sinatra/hello.inversion +1 -0
  44. data/spec/inversion/mixins_spec.rb +177 -0
  45. data/spec/inversion/monkeypatches_spec.rb +35 -0
  46. data/spec/inversion/renderstate_spec.rb +291 -0
  47. data/spec/inversion/sinatra_spec.rb +59 -0
  48. data/spec/inversion/template/attrtag_spec.rb +216 -0
  49. data/spec/inversion/template/calltag_spec.rb +30 -0
  50. data/spec/inversion/template/codetag_spec.rb +51 -0
  51. data/spec/inversion/template/commenttag_spec.rb +84 -0
  52. data/spec/inversion/template/configtag_spec.rb +105 -0
  53. data/spec/inversion/template/containertag_spec.rb +54 -0
  54. data/spec/inversion/template/elsetag_spec.rb +105 -0
  55. data/spec/inversion/template/elsiftag_spec.rb +87 -0
  56. data/spec/inversion/template/endtag_spec.rb +78 -0
  57. data/spec/inversion/template/escapetag_spec.rb +59 -0
  58. data/spec/inversion/template/fortag_spec.rb +98 -0
  59. data/spec/inversion/template/iftag_spec.rb +241 -0
  60. data/spec/inversion/template/importtag_spec.rb +106 -0
  61. data/spec/inversion/template/includetag_spec.rb +108 -0
  62. data/spec/inversion/template/node_spec.rb +81 -0
  63. data/spec/inversion/template/parser_spec.rb +170 -0
  64. data/spec/inversion/template/pptag_spec.rb +51 -0
  65. data/spec/inversion/template/publishtag_spec.rb +69 -0
  66. data/spec/inversion/template/subscribetag_spec.rb +60 -0
  67. data/spec/inversion/template/tag_spec.rb +97 -0
  68. data/spec/inversion/template/textnode_spec.rb +86 -0
  69. data/spec/inversion/template/unlesstag_spec.rb +84 -0
  70. data/spec/inversion/template/uriencodetag_spec.rb +49 -0
  71. data/spec/inversion/template/yieldtag_spec.rb +54 -0
  72. data/spec/inversion/template_spec.rb +269 -0
  73. data/spec/inversion/tilt_spec.rb +47 -0
  74. data/spec/inversion_spec.rb +95 -0
  75. data/spec/lib/constants.rb +9 -0
  76. data/spec/lib/helpers.rb +160 -0
  77. metadata +316 -0
  78. metadata.gz.sig +0 -0
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env rspec -cfd -b
2
+ # vim: set noet nosta sw=4 ts=4 :
3
+
4
+ BEGIN {
5
+ require 'pathname'
6
+ basedir = Pathname( __FILE__ ).dirname.parent.parent.parent
7
+ libdir = basedir + 'lib'
8
+
9
+ $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
10
+ $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
11
+ }
12
+
13
+ require 'rspec'
14
+ require 'spec/lib/helpers'
15
+ require 'inversion/template/calltag'
16
+
17
+ describe Inversion::Template::CallTag do
18
+
19
+ before( :all ) do
20
+ setup_logging( :fatal )
21
+ end
22
+
23
+ after( :all ) do
24
+ reset_logging()
25
+ end
26
+
27
+ # Since call is just an alias, the attrtag_spec already tests all of
28
+ # this.
29
+
30
+ end
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env rspec -cfd -b
2
+ # vim: set noet nosta sw=4 ts=4 :
3
+
4
+ BEGIN {
5
+ require 'pathname'
6
+ basedir = Pathname( __FILE__ ).dirname.parent.parent.parent
7
+ libdir = basedir + 'lib'
8
+
9
+ $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
10
+ $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
11
+ }
12
+
13
+ require 'rspec'
14
+ require 'spec/lib/helpers'
15
+ require 'inversion/template/codetag'
16
+
17
+ describe Inversion::Template::CodeTag do
18
+
19
+ before( :all ) do
20
+ setup_logging( :fatal )
21
+ end
22
+
23
+ after( :all ) do
24
+ reset_logging()
25
+ end
26
+
27
+
28
+ it "is an abstract class" do
29
+ Inversion::Template::Tag.should < Inversion::AbstractClass
30
+ end
31
+
32
+
33
+ describe "subclasses" do
34
+
35
+ it "can declare a format for tags using a declarative" do
36
+ subclass = Class.new( Inversion::Template::CodeTag ) do
37
+ tag_pattern "$(ident)" do |tag, match|
38
+ :foo
39
+ end
40
+
41
+ end
42
+
43
+ subclass.tag_patterns.should have( 1 ).member
44
+ subclass.tag_patterns.first[0].
45
+ should be_an_instance_of( Inversion::Template::CodeTag::TokenPattern )
46
+ subclass.tag_patterns.first[1].call( :dummy, :king_dummy ).should == :foo
47
+ end
48
+
49
+ end
50
+
51
+ end
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env rspec -cfd -b
2
+ # vim: set noet nosta sw=4 ts=4 :
3
+
4
+ BEGIN {
5
+ require 'pathname'
6
+ basedir = Pathname( __FILE__ ).dirname.parent.parent.parent
7
+ libdir = basedir + 'lib'
8
+
9
+ $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
10
+ $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
11
+ }
12
+
13
+ require 'rspec'
14
+ require 'spec/lib/helpers'
15
+ require 'inversion/template/commenttag'
16
+ require 'inversion/template/attrtag'
17
+ require 'inversion/template/textnode'
18
+ require 'inversion/renderstate'
19
+
20
+ describe Inversion::Template::CommentTag do
21
+
22
+ before( :all ) do
23
+ setup_logging( :fatal )
24
+ end
25
+
26
+ after( :all ) do
27
+ reset_logging()
28
+ end
29
+
30
+
31
+ it "allows any free-form text in its body" do
32
+ # <?comment Disabled for now ?>...<?end?>
33
+ Inversion::Template::CommentTag.new( 'Disabled for now' ).
34
+ should be_a( Inversion::Template::CommentTag )
35
+ end
36
+
37
+ it "allows an empty body" do
38
+ # <?comment ?>...<?end?>
39
+ Inversion::Template::CommentTag.new( '' ).
40
+ should be_a( Inversion::Template::CommentTag )
41
+ end
42
+
43
+
44
+ it "includes information about its subnodes when rendered as a comment" do
45
+ tag = Inversion::Template::CommentTag.new( '' )
46
+
47
+ # - <?attr foo ?> -
48
+ tag << Inversion::Template::TextNode.new( '- ', 1, 7 )
49
+ tag << Inversion::Template::AttrTag.new( 'foo', 1, 9 )
50
+ tag << Inversion::Template::TextNode.new( ' -', 1, 12 )
51
+
52
+ tag.as_comment_body.should == 'Commented out 3 nodes on line 1'
53
+ end
54
+
55
+
56
+ it "multiline comments include information about its subnodes when rendered as a comment" do
57
+ tag = Inversion::Template::CommentTag.new( "We couldn't have done it without me" )
58
+
59
+ # - <?attr foo ?> -
60
+ tag << Inversion::Template::TextNode.new( '- ', 2, 0 )
61
+ tag << Inversion::Template::AttrTag.new( 'foo', 3, 0 )
62
+ tag << Inversion::Template::TextNode.new( '- ', 4, 0 )
63
+
64
+ tag.as_comment_body.should == "Commented out 3 nodes from line 2 to 4: " +
65
+ "We couldn't have done it without me"
66
+ end
67
+
68
+
69
+ it "prevents its subnodes from being rendered" do
70
+ render_state = Inversion::RenderState.new( :plaque => %w[ten years] )
71
+ tag = Inversion::Template::CommentTag.new( '' )
72
+
73
+ # - <?attr foo ?> -
74
+ tag << Inversion::Template::TextNode.new( '- ' )
75
+ tag << Inversion::Template::AttrTag.new( 'foo' )
76
+ tag << Inversion::Template::TextNode.new( ' -' )
77
+
78
+ tag.render( render_state ).should == ''
79
+ end
80
+
81
+ end
82
+
83
+
84
+
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env rspec -cfd -b
2
+ # vim: set noet nosta sw=4 ts=4 :
3
+
4
+ BEGIN {
5
+ require 'pathname'
6
+ basedir = Pathname( __FILE__ ).dirname.parent.parent.parent
7
+ libdir = basedir + 'lib'
8
+
9
+ $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
10
+ $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
11
+ }
12
+
13
+ require 'rspec'
14
+ require 'spec/lib/helpers'
15
+ require 'inversion/template/configtag'
16
+
17
+ describe Inversion::Template::ConfigTag do
18
+
19
+ before( :all ) do
20
+ setup_logging( :fatal )
21
+ end
22
+
23
+ after( :all ) do
24
+ reset_logging()
25
+ end
26
+
27
+
28
+ # <?config comment_start: /* ?>
29
+ # <?config comment_end: */ ?>
30
+ it "can contain a single configuration setting" do
31
+ tag = Inversion::Template::ConfigTag.new( 'comment_start: /*' )
32
+ tag.options.should == { :comment_start => '/*' }
33
+ end
34
+
35
+ # <?config
36
+ # on_render_error: propagate
37
+ # debugging_comments: true
38
+ # comment_start: /*
39
+ # comment_end: */
40
+ # ?>
41
+ it "can contain multiple configuration settings using a YAML document" do
42
+ yaml = <<-YAML
43
+ on_render_error: propagate
44
+ debugging_comments: true
45
+ comment_start: "/*"
46
+ comment_end: "*/"
47
+ YAML
48
+ tag = Inversion::Template::ConfigTag.new( yaml )
49
+ tag.options.should == {
50
+ :on_render_error => 'propagate',
51
+ :debugging_comments => true,
52
+ :comment_start => '/*',
53
+ :comment_end => '*/'
54
+ }
55
+ end
56
+
57
+ # <?config { comment_start: "/*", comment_end: "*/" } ?>
58
+ it "can contain multiple configuration settings using an inline hash" do
59
+ tag = Inversion::Template::ConfigTag.new( '{ comment_start: "/*", comment_end: "*/" }' )
60
+ tag.options.should == { :comment_start => '/*', :comment_end => '*/' }
61
+ end
62
+
63
+ it "renders invisibly" do
64
+ tag = Inversion::Template::ConfigTag.new( 'comment_start: /*' )
65
+ state = Inversion::RenderState.new
66
+ tag.render( state ).should == nil
67
+ end
68
+
69
+ it "raises an error on an empty body" do
70
+ expect {
71
+ Inversion::Template::ConfigTag.new( '' )
72
+ }.to raise_exception( Inversion::ParseError, /empty config settings/i )
73
+ end
74
+
75
+
76
+ it "can change the strictness of the parser as it's parsing the template" do
77
+ source = <<-TEMPLATE
78
+ <?hooooowhat ?>
79
+ <?config ignore_unknown_tags: false ?>
80
+ something
81
+ <?what ?>
82
+ something else
83
+ TEMPLATE
84
+ expect {
85
+ Inversion::Template.new( source, :ignore_unknown_tags => true )
86
+ }.to raise_exception( Inversion::ParseError, /unknown tag "what"/i )
87
+ end
88
+
89
+ it "can change the strictness of the parser as it's parsing the template" do
90
+ source = <<-TEMPLATE
91
+ <?hooooowhat ?>
92
+ <?config ignore_unknown_tags: false ?>
93
+ something
94
+ <?what ?>
95
+ something else
96
+ TEMPLATE
97
+ expect {
98
+ Inversion::Template.new( source, :ignore_unknown_tags => true )
99
+ }.to raise_exception( Inversion::ParseError, /unknown tag "what"/i )
100
+ end
101
+
102
+ end
103
+
104
+
105
+
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env rspec -cfd -b
2
+ # vim: set noet nosta sw=4 ts=4 :
3
+
4
+ BEGIN {
5
+ require 'pathname'
6
+ basedir = Pathname( __FILE__ ).dirname.parent.parent.parent
7
+ libdir = basedir + 'lib'
8
+
9
+ $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
10
+ $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
11
+ }
12
+
13
+ require 'rspec'
14
+ require 'spec/lib/helpers'
15
+ require 'inversion/template/containertag'
16
+
17
+ describe Inversion::Template::ContainerTag do
18
+
19
+ before( :all ) do
20
+ setup_logging( :fatal )
21
+ end
22
+
23
+ after( :all ) do
24
+ reset_logging()
25
+ end
26
+
27
+ context "instances of including classes" do
28
+
29
+ before( :each ) do
30
+ @including_class = Class.new( Inversion::Template::Tag ) do
31
+ include Inversion::Template::ContainerTag
32
+ end
33
+ @tag = @including_class.new( 'a body' )
34
+ end
35
+
36
+ it "are container tags" do
37
+ @tag.should be_a_container()
38
+ end
39
+
40
+ it "contain a subnodes array" do
41
+ @tag.subnodes.should be_an( Array )
42
+ end
43
+
44
+ it "can have other nodes appended to them" do
45
+ other_node = Inversion::Template::TextNode.new( "foom" )
46
+ @tag << other_node
47
+ @tag.subnodes.should include( other_node )
48
+ end
49
+
50
+ end
51
+ end
52
+
53
+
54
+
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env rspec -cfd -b
2
+ # vim: set noet nosta sw=4 ts=4 :
3
+
4
+ BEGIN {
5
+ require 'pathname'
6
+ basedir = Pathname( __FILE__ ).dirname.parent.parent.parent
7
+ libdir = basedir + 'lib'
8
+
9
+ $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
10
+ $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
11
+ }
12
+
13
+ require 'rspec'
14
+ require 'spec/lib/helpers'
15
+ require 'inversion/template/iftag'
16
+ require 'inversion/template/elsetag'
17
+ require 'inversion/template/unlesstag'
18
+ require 'inversion/template/commenttag'
19
+ require 'inversion/template/fortag'
20
+ require 'inversion/renderstate'
21
+
22
+ describe Inversion::Template::ElseTag do
23
+
24
+ before( :all ) do
25
+ setup_logging( :fatal )
26
+ end
27
+
28
+ after( :all ) do
29
+ reset_logging()
30
+ end
31
+
32
+ it "handles a non-existant body" do
33
+ Inversion::Template::ElseTag.new( nil )
34
+ end
35
+
36
+ it "can be appended to an 'if' tag" do
37
+ template = double( "template object" )
38
+ parserstate = Inversion::Template::Parser::State.new( template )
39
+ iftag = Inversion::Template::IfTag.new( 'foo' )
40
+ elsetag = Inversion::Template::ElseTag.new
41
+ endtag = Inversion::Template::EndTag.new
42
+
43
+ parserstate << iftag << elsetag << endtag
44
+
45
+ parserstate.tree.should == [ iftag, endtag ]
46
+ end
47
+
48
+ it "can be appended to an 'unless' tag" do
49
+ template = double( "template object" )
50
+ parserstate = Inversion::Template::Parser::State.new( template )
51
+ unlesstag = Inversion::Template::UnlessTag.new( 'foo' )
52
+ elsetag = Inversion::Template::ElseTag.new
53
+ endtag = Inversion::Template::EndTag.new
54
+
55
+ parserstate << unlesstag << elsetag << endtag
56
+
57
+ parserstate.tree.should == [ unlesstag, endtag ]
58
+ unlesstag.subnodes.should include( elsetag )
59
+ end
60
+
61
+ it "can be appended to a 'comment' tag" do
62
+ template = double( "template object" )
63
+ parserstate = Inversion::Template::Parser::State.new( template )
64
+ commenttag = Inversion::Template::CommentTag.new( 'else section for later' )
65
+ elsetag = Inversion::Template::ElseTag.new
66
+ endtag = Inversion::Template::EndTag.new
67
+
68
+ parserstate << commenttag << elsetag << endtag
69
+
70
+ parserstate.tree.should == [ commenttag, endtag ]
71
+ commenttag.subnodes.should include( elsetag )
72
+ end
73
+
74
+ it "raises an error if it's about to be appended to anything other than an 'if', 'unless', " +
75
+ "or 'comment' tag" do
76
+ template = double( "template object" )
77
+ parserstate = Inversion::Template::Parser::State.new( template )
78
+ parserstate << Inversion::Template::ForTag.new( 'foo in bar' )
79
+
80
+ expect {
81
+ parserstate << Inversion::Template::ElseTag.new
82
+ }.to raise_exception( Inversion::ParseError, /'for' tags can't have 'else' clauses/i )
83
+ end
84
+
85
+
86
+ it "raises an error if it's about to be appended without an opening 'if' or 'unless'" do
87
+ template = double( "template object" )
88
+ parserstate = Inversion::Template::Parser::State.new( template )
89
+
90
+ expect {
91
+ parserstate << Inversion::Template::ElseTag.new
92
+ }.to raise_exception( Inversion::ParseError, /orphaned 'else' tag/i )
93
+ end
94
+
95
+
96
+ it "doesn't render as anything by itself" do
97
+ renderstate = Inversion::RenderState.new
98
+ tag = Inversion::Template::ElseTag.new
99
+ tag.render( renderstate ).should be_nil()
100
+ end
101
+
102
+ end
103
+
104
+
105
+
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env rspec -cfd -b
2
+ # vim: set noet nosta sw=4 ts=4 :
3
+
4
+ BEGIN {
5
+ require 'pathname'
6
+ basedir = Pathname( __FILE__ ).dirname.parent.parent.parent
7
+ libdir = basedir + 'lib'
8
+
9
+ $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
10
+ $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
11
+ }
12
+
13
+ require 'rspec'
14
+ require 'spec/lib/helpers'
15
+ require 'inversion/template/iftag'
16
+ require 'inversion/template/elsiftag'
17
+ require 'inversion/template/unlesstag'
18
+ require 'inversion/template/textnode'
19
+ require 'inversion/renderstate'
20
+
21
+ describe Inversion::Template::ElsifTag do
22
+
23
+ before( :all ) do
24
+ setup_logging( :fatal )
25
+ end
26
+
27
+ after( :all ) do
28
+ reset_logging()
29
+ end
30
+
31
+
32
+ it "can be appended to an 'if' tag" do
33
+ template = double( "template object" )
34
+ parserstate = Inversion::Template::Parser::State.new( template )
35
+ iftag = Inversion::Template::IfTag.new( 'foo' )
36
+ elsetag = Inversion::Template::ElsifTag.new( 'bar' )
37
+ endtag = Inversion::Template::EndTag.new
38
+
39
+ parserstate << iftag << elsetag << endtag
40
+
41
+ parserstate.tree.should == [ iftag, endtag ]
42
+ end
43
+
44
+ it "can be appended to a 'comment' tag" do
45
+ template = double( "template object" )
46
+ parserstate = Inversion::Template::Parser::State.new( template )
47
+ commenttag = Inversion::Template::CommentTag.new( 'else section for later' )
48
+ elsetag = Inversion::Template::ElsifTag.new( 'bar' )
49
+ endtag = Inversion::Template::EndTag.new
50
+
51
+ parserstate << commenttag << elsetag << endtag
52
+
53
+ parserstate.tree.should == [ commenttag, endtag ]
54
+ commenttag.subnodes.should include( elsetag )
55
+ end
56
+
57
+ it "raises an error if it's about to be appended to anything other than an 'if' or 'comment' tag" do
58
+ template = double( "template object" )
59
+ parserstate = Inversion::Template::Parser::State.new( template )
60
+ parserstate << Inversion::Template::UnlessTag.new( 'foo in bar' )
61
+
62
+ expect {
63
+ parserstate << Inversion::Template::ElsifTag.new( 'bar' )
64
+ }.to raise_exception( Inversion::ParseError, /'unless' tags can't have 'elsif' clauses/i )
65
+ end
66
+
67
+
68
+ it "raises an error if it's about to be appended without an opening 'if'" do
69
+ template = double( "template object" )
70
+ parserstate = Inversion::Template::Parser::State.new( template )
71
+
72
+ expect {
73
+ parserstate << Inversion::Template::ElsifTag.new( 'bar' )
74
+ }.to raise_exception( Inversion::ParseError, /orphaned 'elsif' tag/i )
75
+ end
76
+
77
+
78
+ it "renders as its attribute value if it's a simple attribute" do
79
+ renderstate = Inversion::RenderState.new( :bar => :the_attribute_value )
80
+ tag = Inversion::Template::ElsifTag.new( 'bar' )
81
+ tag.render( renderstate ).should == :the_attribute_value
82
+ end
83
+
84
+ end
85
+
86
+
87
+