danwrong-liquid-inheritance 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.
data/CHANGELOG ADDED
@@ -0,0 +1 @@
1
+ v0.1 Initial release
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2009 Dan Webb
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
data/Manifest ADDED
@@ -0,0 +1,10 @@
1
+ CHANGELOG
2
+ lib/liquid_inheritance.rb
3
+ lib/tags/block.rb
4
+ lib/tags/extends.rb
5
+ LICENSE
6
+ liquid-inheritance.gemspec
7
+ Manifest
8
+ Rakefile
9
+ README.textile
10
+ test/liquid_inheritance_test.rb
data/README.textile ADDED
@@ -0,0 +1,15 @@
1
+ h1. Liquid Inheritance
2
+
3
+ (C) Dan Webb 2009 under and MIT License (see LICENSE)
4
+
5
+ This gem adds Django-style template inheritance to the "Liquid":http://www.liquidmarkup.org/ templating language.
6
+
7
+ h2. Usage
8
+
9
+ Simply install the gem then in your project:
10
+
11
+ @require 'liquid-inheritance'@
12
+
13
+ You then have access to the extends and block tags just like you do in Django. It works identically so for more info "read the Django docs on template inheritance":http://docs.djangoproject.com/en/dev/topics/templates/#template-inheritance
14
+
15
+ That's all folks.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'echoe'
2
+
3
+ Echoe.new("liquid-inheritance") do |p|
4
+ p.author = "Dan Webb"
5
+ p.email = 'dan@danwebb.net'
6
+ p.summary = "Adds Django style template inheritance to Liquid"
7
+ p.url = "http://github.com/danwrong/liquid-inheritance/"
8
+ p.runtime_dependencies = ["liquid >= 1.9.0"]
9
+ p.retain_gemspec = true
10
+ end
@@ -0,0 +1,9 @@
1
+ require 'liquid'
2
+
3
+ module LiquidInheritance
4
+ autoload :Extends, 'tags/extends'
5
+ autoload :Block, 'tags/block'
6
+ end
7
+
8
+ Liquid::Template.register_tag(:extends, LiquidInheritance::Extends)
9
+ Liquid::Template.register_tag(:block, LiquidInheritance::Block)
data/lib/tags/block.rb ADDED
@@ -0,0 +1,56 @@
1
+ module LiquidInheritance
2
+
3
+ class BlockDrop < ::Liquid::Drop
4
+ def initialize(block)
5
+ @block = block
6
+ end
7
+
8
+ def super
9
+ @block.call_super(@context)
10
+ end
11
+ end
12
+
13
+ class Block < ::Liquid::Block
14
+ Syntax = /(\w)+/
15
+
16
+ attr_accessor :parent
17
+ attr_reader :name
18
+
19
+ def initialize(tag_name, markup, tokens)
20
+ if markup =~ Syntax
21
+ @name = $1
22
+ else
23
+ raise Liquid::SyntaxError.new("Syntax Error in 'block' - Valid syntax: block [name]")
24
+ end
25
+
26
+ super if tokens
27
+ end
28
+
29
+ def render(context)
30
+ context.stack do
31
+ context['block'] = BlockDrop.new(self)
32
+
33
+ render_all(@nodelist, context)
34
+ end
35
+ end
36
+
37
+ def add_parent(nodelist)
38
+ if parent
39
+ parent.add_parent(nodelist)
40
+ else
41
+ self.parent = Block.new(@tag_name, @name, nil)
42
+ parent.nodelist = nodelist
43
+ end
44
+ end
45
+
46
+ def call_super(context)
47
+ if parent
48
+ parent.render(context)
49
+ else
50
+ ''
51
+ end
52
+ end
53
+
54
+ end
55
+
56
+ end
@@ -0,0 +1,101 @@
1
+ module LiquidInheritance
2
+
3
+ class Extends < ::Liquid::Block
4
+ Syntax = /(#{Liquid::QuotedFragment})/
5
+
6
+ def initialize(tag_name, markup, tokens)
7
+ if markup =~ Syntax
8
+ @template_name = $1
9
+ else
10
+ raise Liquid::SyntaxError.new("Syntax Error in 'extends' - Valid syntax: extends [template]")
11
+ end
12
+
13
+ super
14
+
15
+ @blocks = @nodelist.inject({}) do |m, node|
16
+ m[node.name] = node if node.is_a?(::LiquidInheritance::Block); m
17
+ end
18
+ end
19
+
20
+ def parse(tokens)
21
+ parse_all(tokens)
22
+ end
23
+
24
+ def render(context)
25
+ template = load_template(context)
26
+ parent_blocks = find_blocks(template.root)
27
+
28
+ @blocks.each do |name, block|
29
+ if pb = parent_blocks[name]
30
+ pb.parent = block.parent
31
+ pb.add_parent(pb.nodelist)
32
+ pb.nodelist = block.nodelist
33
+ else
34
+ if is_extending?(template)
35
+ template.root.nodelist << block
36
+ end
37
+ end
38
+ end
39
+
40
+ template.render(context)
41
+ end
42
+
43
+ private
44
+
45
+ def parse_all(tokens)
46
+ @nodelist ||= []
47
+ @nodelist.clear
48
+
49
+ while token = tokens.shift
50
+ case token
51
+ when /^#{Liquid::TagStart}/
52
+ if token =~ /^#{Liquid::TagStart}\s*(\w+)\s*(.*)?#{Liquid::TagEnd}$/
53
+ # fetch the tag from registered blocks
54
+ if tag = Liquid::Template.tags[$1]
55
+ @nodelist << tag.new($1, $2, tokens)
56
+ else
57
+ # this tag is not registered with the system
58
+ # pass it to the current block for special handling or error reporting
59
+ unknown_tag($1, $2, tokens)
60
+ end
61
+ else
62
+ raise Liquid::SyntaxError, "Tag '#{token}' was not properly terminated with regexp: #{TagEnd.inspect} "
63
+ end
64
+ when /^#{Liquid::VariableStart}/
65
+ @nodelist << create_variable(token)
66
+ when ''
67
+ # pass
68
+ else
69
+ @nodelist << token
70
+ end
71
+ end
72
+ end
73
+
74
+ def load_template(context)
75
+ source = Liquid::Template.file_system.read_template_file(context[@template_name])
76
+ Liquid::Template.parse(source)
77
+ end
78
+
79
+ def find_blocks(node, blocks={})
80
+ if node.respond_to?(:nodelist)
81
+ node.nodelist.inject(blocks) do |b, node|
82
+ if node.is_a?(LiquidInheritance::Block)
83
+ b[node.name] = node
84
+ else
85
+ find_blocks(node, b)
86
+ end
87
+
88
+ b
89
+ end
90
+ end
91
+
92
+ blocks
93
+ end
94
+
95
+ def is_extending?(template)
96
+ template.root.nodelist.any? { |node| node.is_a?(Extends) }
97
+ end
98
+
99
+ end
100
+
101
+ end
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{liquid-inheritance}
5
+ s.version = "0.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Dan Webb"]
9
+ s.date = %q{2009-04-09}
10
+ s.description = %q{Adds Django style template inheritance to Liquid}
11
+ s.email = %q{dan@danwebb.net}
12
+ s.extra_rdoc_files = ["CHANGELOG", "lib/liquid_inheritance.rb", "lib/tags/block.rb", "lib/tags/extends.rb", "LICENSE", "README.textile"]
13
+ s.files = ["CHANGELOG", "lib/liquid_inheritance.rb", "lib/tags/block.rb", "lib/tags/extends.rb", "LICENSE", "liquid-inheritance.gemspec", "Manifest", "Rakefile", "README.textile", "test/liquid_inheritance_test.rb"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://github.com/danwrong/liquid-inheritance/}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Liquid-inheritance", "--main", "README.textile"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{liquid-inheritance}
19
+ s.rubygems_version = %q{1.3.1}
20
+ s.summary = %q{Adds Django style template inheritance to Liquid}
21
+ s.test_files = ["test/liquid_inheritance_test.rb"]
22
+
23
+ if s.respond_to? :specification_version then
24
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
+ s.specification_version = 2
26
+
27
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
+ s.add_runtime_dependency(%q<liquid>, [">= 0", "= 1.9.0"])
29
+ else
30
+ s.add_dependency(%q<liquid>, [">= 0", "= 1.9.0"])
31
+ end
32
+ else
33
+ s.add_dependency(%q<liquid>, [">= 0", "= 1.9.0"])
34
+ end
35
+ end
@@ -0,0 +1,173 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '../lib'))
2
+
3
+ require 'rubygems'
4
+ require 'test/unit'
5
+ require 'shoulda'
6
+ require 'redgreen' rescue nil
7
+
8
+ require 'liquid_inheritance'
9
+
10
+ class TestFileSystem
11
+
12
+ def read_template_file(path)
13
+ if path == 'simple'
14
+ 'test'
15
+ elsif path == 'complex'
16
+ %{
17
+ beginning
18
+
19
+ {% block thing %}
20
+ rarrgh
21
+ {% endblock %}
22
+
23
+ {% block another %}
24
+ bum
25
+ {% endblock %}
26
+
27
+ end
28
+ }
29
+ elsif 'nested'
30
+ %{
31
+ {% extends 'complex' %}
32
+
33
+ {% block thing %}
34
+ from nested
35
+ {% endblock %}
36
+
37
+ {% block another %}
38
+ from nested (another)
39
+ {% endblock %}
40
+ }
41
+ else
42
+ %{
43
+ {% extends 'complex' %}
44
+
45
+ {% block thing %}
46
+ from nested
47
+ {% endblock %}
48
+ }
49
+ end
50
+ end
51
+
52
+ end
53
+
54
+ class LiquidInheritanceTest < Test::Unit::TestCase
55
+ context 'given a template with an extends tag' do
56
+ setup do
57
+ Liquid::Template.file_system = TestFileSystem.new
58
+ end
59
+
60
+ should 'output the contents of the extended template' do
61
+ template = Liquid::Template.parse %{
62
+ {% extends 'simple' %}
63
+
64
+ {% block thing %}
65
+ yeah
66
+ {% endblock %}
67
+ }
68
+
69
+ assert_contains(template.render, /test/)
70
+ end
71
+
72
+ should 'render original content of block if no child block given' do
73
+ template = Liquid::Template.parse %{
74
+ {% extends 'complex' %}
75
+ }
76
+
77
+ assert_contains(template.render, /rarrgh/)
78
+ assert_contains(template.render, /bum/)
79
+ end
80
+
81
+ should 'render child content of block if child block given' do
82
+ template = Liquid::Template.parse %{
83
+ {% extends 'complex' %}
84
+
85
+ {% block thing %}
86
+ booyeah
87
+ {% endblock %}
88
+ }
89
+
90
+ assert_contains(template.render, /booyeah/)
91
+ assert_contains(template.render, /bum/)
92
+ end
93
+
94
+ should 'render child content of blocks if multiple child blocks given' do
95
+ template = Liquid::Template.parse %{
96
+ {% extends 'complex' %}
97
+
98
+ {% block thing %}
99
+ booyeah
100
+ {% endblock %}
101
+
102
+ {% block another %}
103
+ blurb
104
+ {% endblock %}
105
+ }
106
+
107
+ assert_contains(template.render, /booyeah/)
108
+ assert_contains(template.render, /blurb/)
109
+ end
110
+
111
+ should 'should remember context of child template' do
112
+ template = Liquid::Template.parse %{
113
+ {% extends 'complex' %}
114
+
115
+ {% block thing %}
116
+ booyeah
117
+ {% endblock %}
118
+
119
+ {% block another %}
120
+ {{ a }}
121
+ {% endblock %}
122
+ }
123
+
124
+ res = template.render 'a' => 1234
125
+
126
+ assert_contains(res, /booyeah/)
127
+ assert_contains(res, /1234/)
128
+ end
129
+
130
+ should 'should work with nested templates' do
131
+ template = Liquid::Template.parse %{
132
+ {% extends 'nested' %}
133
+
134
+ {% block thing %}
135
+ booyeah
136
+ {% endblock %}
137
+ }
138
+
139
+ res = template.render 'a' => 1234
140
+
141
+ assert_contains(res, /booyeah/)
142
+ assert_contains(res, /from nested/)
143
+ end
144
+
145
+ should 'should work with nested templates if middle template skips a block' do
146
+ template = Liquid::Template.parse %{
147
+ {% extends 'nested2' %}
148
+
149
+ {% block another %}
150
+ win
151
+ {% endblock %}
152
+ }
153
+
154
+ res = template.render
155
+
156
+ assert_contains(res, /win/)
157
+ end
158
+
159
+ should 'should render parent for block.super' do
160
+ template = Liquid::Template.parse %{
161
+ {% extends 'complex' %}
162
+
163
+ {% block thing %}
164
+ {{ block.super }}
165
+ {% endblock %}
166
+ }
167
+
168
+ res = template.render 'a' => 1234
169
+
170
+ assert_contains(res, /rarrgh/)
171
+ end
172
+ end
173
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: danwrong-liquid-inheritance
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - Dan Webb
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-04-09 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: liquid
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ - - "="
25
+ - !ruby/object:Gem::Version
26
+ version: 1.9.0
27
+ version:
28
+ description: Adds Django style template inheritance to Liquid
29
+ email: dan@danwebb.net
30
+ executables: []
31
+
32
+ extensions: []
33
+
34
+ extra_rdoc_files:
35
+ - CHANGELOG
36
+ - lib/liquid_inheritance.rb
37
+ - lib/tags/block.rb
38
+ - lib/tags/extends.rb
39
+ - LICENSE
40
+ - README.textile
41
+ files:
42
+ - CHANGELOG
43
+ - lib/liquid_inheritance.rb
44
+ - lib/tags/block.rb
45
+ - lib/tags/extends.rb
46
+ - LICENSE
47
+ - liquid-inheritance.gemspec
48
+ - Manifest
49
+ - Rakefile
50
+ - README.textile
51
+ - test/liquid_inheritance_test.rb
52
+ has_rdoc: true
53
+ homepage: http://github.com/danwrong/liquid-inheritance/
54
+ post_install_message:
55
+ rdoc_options:
56
+ - --line-numbers
57
+ - --inline-source
58
+ - --title
59
+ - Liquid-inheritance
60
+ - --main
61
+ - README.textile
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ version:
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: "1.2"
75
+ version:
76
+ requirements: []
77
+
78
+ rubyforge_project: liquid-inheritance
79
+ rubygems_version: 1.2.0
80
+ signing_key:
81
+ specification_version: 2
82
+ summary: Adds Django style template inheritance to Liquid
83
+ test_files:
84
+ - test/liquid_inheritance_test.rb