garterbelt 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +38 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +21 -0
- data/Rakefile +46 -0
- data/TODO +3 -0
- data/VERSION +1 -0
- data/garterbelt.gemspec +165 -0
- data/lib/garterbelt.rb +23 -0
- data/lib/page.rb +46 -0
- data/lib/renderers/cache.rb +35 -0
- data/lib/renderers/closed_tag.rb +60 -0
- data/lib/renderers/comment.rb +14 -0
- data/lib/renderers/content_rendering.rb +41 -0
- data/lib/renderers/content_tag.rb +36 -0
- data/lib/renderers/doctype.rb +24 -0
- data/lib/renderers/renderer.rb +33 -0
- data/lib/renderers/text.rb +28 -0
- data/lib/renderers/xml.rb +9 -0
- data/lib/stocking.rb +11 -0
- data/lib/support/string.rb +165 -0
- data/lib/view.rb +341 -0
- data/spec/benchmark/templates/erector.rb +37 -0
- data/spec/benchmark/templates/garterbelt.rb +37 -0
- data/spec/benchmark/vs_erector.rb +53 -0
- data/spec/garterbelt_spec.rb +49 -0
- data/spec/integration/expectations/general_view.html +17 -0
- data/spec/integration/expectations/variables/view_with_user_and_params.html +23 -0
- data/spec/integration/expectations/variables/view_with_user_email.html +23 -0
- data/spec/integration/expectations/view_partial_nest.html +24 -0
- data/spec/integration/expectations/view_with_tags.html +19 -0
- data/spec/integration/templates/view_partial_nest.rb +22 -0
- data/spec/integration/templates/view_with_cache.rb +30 -0
- data/spec/integration/templates/view_with_partial.rb +36 -0
- data/spec/integration/templates/view_with_partial_2.rb +36 -0
- data/spec/integration/templates/view_with_tags.rb +26 -0
- data/spec/integration/templates/view_with_vars.rb +32 -0
- data/spec/integration/view_spec.rb +57 -0
- data/spec/page_spec.rb +99 -0
- data/spec/renderers/cache_spec.rb +85 -0
- data/spec/renderers/closed_tag_spec.rb +172 -0
- data/spec/renderers/comment_spec.rb +68 -0
- data/spec/renderers/content_tag_spec.rb +150 -0
- data/spec/renderers/doctype_spec.rb +46 -0
- data/spec/renderers/text_spec.rb +68 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/support/mock_view.rb +14 -0
- data/spec/support/puters.rb +10 -0
- data/spec/view/view_basics_spec.rb +106 -0
- data/spec/view/view_caching_spec.rb +132 -0
- data/spec/view/view_partial_spec.rb +63 -0
- data/spec/view/view_rails_type_helpers.rb +148 -0
- data/spec/view/view_render_spec.rb +408 -0
- data/spec/view/view_variables_spec.rb +159 -0
- metadata +367 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem 'ru_pol', '0.1.2'
|
4
|
+
gem 'activesupport', ">=2.3.8"
|
5
|
+
gem 'moneta', '>=0.6.0'
|
6
|
+
|
7
|
+
# Add dependencies to develop your gem here.
|
8
|
+
# Include everything needed to run rake, tests, features, etc.
|
9
|
+
group :development do
|
10
|
+
gem "hashie", "~>1.0"
|
11
|
+
gem "rspec", "~> 2.3.0"
|
12
|
+
gem "yard", "~> 0.6.0"
|
13
|
+
gem "bundler", "~> 1.0.0"
|
14
|
+
gem "jeweler", "~> 1.5.2"
|
15
|
+
gem "rcov", ">= 0"
|
16
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activesupport (3.0.4)
|
5
|
+
diff-lcs (1.1.2)
|
6
|
+
git (1.2.5)
|
7
|
+
hashie (1.0.0)
|
8
|
+
jeweler (1.5.2)
|
9
|
+
bundler (~> 1.0.0)
|
10
|
+
git (>= 1.2.5)
|
11
|
+
rake
|
12
|
+
moneta (0.6.0)
|
13
|
+
rake (0.8.7)
|
14
|
+
rcov (0.9.9)
|
15
|
+
rspec (2.3.0)
|
16
|
+
rspec-core (~> 2.3.0)
|
17
|
+
rspec-expectations (~> 2.3.0)
|
18
|
+
rspec-mocks (~> 2.3.0)
|
19
|
+
rspec-core (2.3.1)
|
20
|
+
rspec-expectations (2.3.0)
|
21
|
+
diff-lcs (~> 1.1.2)
|
22
|
+
rspec-mocks (2.3.0)
|
23
|
+
ru_pol (0.1.2)
|
24
|
+
yard (0.6.5)
|
25
|
+
|
26
|
+
PLATFORMS
|
27
|
+
ruby
|
28
|
+
|
29
|
+
DEPENDENCIES
|
30
|
+
activesupport (>= 2.3.8)
|
31
|
+
bundler (~> 1.0.0)
|
32
|
+
hashie (~> 1.0)
|
33
|
+
jeweler (~> 1.5.2)
|
34
|
+
moneta (>= 0.6.0)
|
35
|
+
rcov
|
36
|
+
rspec (~> 2.3.0)
|
37
|
+
ru_pol (= 0.1.2)
|
38
|
+
yard (~> 0.6.0)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Kane Baccigalupi
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
= garterbelt
|
2
|
+
|
3
|
+
Garterbelt is a Ruby HTML/XML markup framework inspired by Erector and Markaby. Garterbelt maps html tags to methods allowing the intuitive construction of HTML pages using nothing but Ruby. And because it is all Ruby all the time, views benefit from the dryness of inheritance, modules and all the meta magic that Ruby can imagine. Stockings not included.
|
4
|
+
|
5
|
+
More docs coming soon!
|
6
|
+
|
7
|
+
== Contributing to garterbelt
|
8
|
+
|
9
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
10
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
11
|
+
* Fork the project
|
12
|
+
* Start a feature/bugfix branch
|
13
|
+
* Commit and push until you are happy with your contribution
|
14
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
15
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
16
|
+
|
17
|
+
== Copyright
|
18
|
+
|
19
|
+
Copyright (c) 2011 Kane Baccigalupi. See LICENSE.txt for
|
20
|
+
further details.
|
21
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "garterbelt"
|
16
|
+
gem.homepage = "http://github.com/baccigalupi/garterbelt"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{Garterbelt is a Ruby HTML/XML markup framework. It is san DSL. Just all Ruby, all the time.}
|
19
|
+
gem.description = %Q{Garterbelt is a Ruby HTML/XML markup framework inspired by Erector and Markaby. Garterbelt maps html tags to methods allowing the intuitive construction of HTML pages using nothing but Ruby. And because it is all Ruby all the time, views benefit from the dryness of inheritance, modules and all the meta magic that Ruby can imagine. Stockings not included.}
|
20
|
+
gem.email = "baccigalupi@gmail.com"
|
21
|
+
gem.authors = ["Kane Baccigalupi"]
|
22
|
+
|
23
|
+
gem.add_development_dependency 'hashie', '~>1.0'
|
24
|
+
gem.add_development_dependency 'rbench'
|
25
|
+
|
26
|
+
gem.add_runtime_dependency 'ru_pol', '>=0.1.2'
|
27
|
+
gem.add_runtime_dependency 'activesupport', '>=2.3.8'
|
28
|
+
gem.add_runtime_dependency 'moneta', '>=0.6.0'
|
29
|
+
end
|
30
|
+
Jeweler::RubygemsDotOrgTasks.new
|
31
|
+
|
32
|
+
require 'rspec/core'
|
33
|
+
require 'rspec/core/rake_task'
|
34
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
35
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
36
|
+
end
|
37
|
+
|
38
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
39
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
40
|
+
spec.rcov = true
|
41
|
+
end
|
42
|
+
|
43
|
+
task :default => :spec
|
44
|
+
|
45
|
+
require 'yard'
|
46
|
+
YARD::Rake::YardocTask.new
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.2
|
data/garterbelt.gemspec
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{garterbelt}
|
8
|
+
s.version = "0.0.2"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Kane Baccigalupi"]
|
12
|
+
s.date = %q{2011-04-12}
|
13
|
+
s.description = %q{Garterbelt is a Ruby HTML/XML markup framework inspired by Erector and Markaby. Garterbelt maps html tags to methods allowing the intuitive construction of HTML pages using nothing but Ruby. And because it is all Ruby all the time, views benefit from the dryness of inheritance, modules and all the meta magic that Ruby can imagine. Stockings not included.}
|
14
|
+
s.email = %q{baccigalupi@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.rdoc",
|
18
|
+
"TODO"
|
19
|
+
]
|
20
|
+
s.files = [
|
21
|
+
".document",
|
22
|
+
".rspec",
|
23
|
+
"Gemfile",
|
24
|
+
"Gemfile.lock",
|
25
|
+
"LICENSE.txt",
|
26
|
+
"README.rdoc",
|
27
|
+
"Rakefile",
|
28
|
+
"TODO",
|
29
|
+
"VERSION",
|
30
|
+
"garterbelt.gemspec",
|
31
|
+
"lib/garterbelt.rb",
|
32
|
+
"lib/page.rb",
|
33
|
+
"lib/renderers/cache.rb",
|
34
|
+
"lib/renderers/closed_tag.rb",
|
35
|
+
"lib/renderers/comment.rb",
|
36
|
+
"lib/renderers/content_rendering.rb",
|
37
|
+
"lib/renderers/content_tag.rb",
|
38
|
+
"lib/renderers/doctype.rb",
|
39
|
+
"lib/renderers/renderer.rb",
|
40
|
+
"lib/renderers/text.rb",
|
41
|
+
"lib/renderers/xml.rb",
|
42
|
+
"lib/stocking.rb",
|
43
|
+
"lib/support/string.rb",
|
44
|
+
"lib/view.rb",
|
45
|
+
"spec/benchmark/templates/erector.rb",
|
46
|
+
"spec/benchmark/templates/garterbelt.rb",
|
47
|
+
"spec/benchmark/vs_erector.rb",
|
48
|
+
"spec/garterbelt_spec.rb",
|
49
|
+
"spec/integration/expectations/general_view.html",
|
50
|
+
"spec/integration/expectations/variables/view_with_user_and_params.html",
|
51
|
+
"spec/integration/expectations/variables/view_with_user_email.html",
|
52
|
+
"spec/integration/expectations/view_partial_nest.html",
|
53
|
+
"spec/integration/expectations/view_with_tags.html",
|
54
|
+
"spec/integration/templates/view_partial_nest.rb",
|
55
|
+
"spec/integration/templates/view_with_cache.rb",
|
56
|
+
"spec/integration/templates/view_with_partial.rb",
|
57
|
+
"spec/integration/templates/view_with_partial_2.rb",
|
58
|
+
"spec/integration/templates/view_with_tags.rb",
|
59
|
+
"spec/integration/templates/view_with_vars.rb",
|
60
|
+
"spec/integration/view_spec.rb",
|
61
|
+
"spec/page_spec.rb",
|
62
|
+
"spec/renderers/cache_spec.rb",
|
63
|
+
"spec/renderers/closed_tag_spec.rb",
|
64
|
+
"spec/renderers/comment_spec.rb",
|
65
|
+
"spec/renderers/content_tag_spec.rb",
|
66
|
+
"spec/renderers/doctype_spec.rb",
|
67
|
+
"spec/renderers/text_spec.rb",
|
68
|
+
"spec/spec_helper.rb",
|
69
|
+
"spec/support/mock_view.rb",
|
70
|
+
"spec/support/puters.rb",
|
71
|
+
"spec/view/view_basics_spec.rb",
|
72
|
+
"spec/view/view_caching_spec.rb",
|
73
|
+
"spec/view/view_partial_spec.rb",
|
74
|
+
"spec/view/view_rails_type_helpers.rb",
|
75
|
+
"spec/view/view_render_spec.rb",
|
76
|
+
"spec/view/view_variables_spec.rb"
|
77
|
+
]
|
78
|
+
s.homepage = %q{http://github.com/baccigalupi/garterbelt}
|
79
|
+
s.licenses = ["MIT"]
|
80
|
+
s.require_paths = ["lib"]
|
81
|
+
s.rubygems_version = %q{1.3.7}
|
82
|
+
s.summary = %q{Garterbelt is a Ruby HTML/XML markup framework. It is san DSL. Just all Ruby, all the time.}
|
83
|
+
s.test_files = [
|
84
|
+
"spec/benchmark/templates/erector.rb",
|
85
|
+
"spec/benchmark/templates/garterbelt.rb",
|
86
|
+
"spec/benchmark/vs_erector.rb",
|
87
|
+
"spec/garterbelt_spec.rb",
|
88
|
+
"spec/integration/templates/view_partial_nest.rb",
|
89
|
+
"spec/integration/templates/view_with_cache.rb",
|
90
|
+
"spec/integration/templates/view_with_partial.rb",
|
91
|
+
"spec/integration/templates/view_with_partial_2.rb",
|
92
|
+
"spec/integration/templates/view_with_tags.rb",
|
93
|
+
"spec/integration/templates/view_with_vars.rb",
|
94
|
+
"spec/integration/view_spec.rb",
|
95
|
+
"spec/page_spec.rb",
|
96
|
+
"spec/renderers/cache_spec.rb",
|
97
|
+
"spec/renderers/closed_tag_spec.rb",
|
98
|
+
"spec/renderers/comment_spec.rb",
|
99
|
+
"spec/renderers/content_tag_spec.rb",
|
100
|
+
"spec/renderers/doctype_spec.rb",
|
101
|
+
"spec/renderers/text_spec.rb",
|
102
|
+
"spec/spec_helper.rb",
|
103
|
+
"spec/support/mock_view.rb",
|
104
|
+
"spec/support/puters.rb",
|
105
|
+
"spec/view/view_basics_spec.rb",
|
106
|
+
"spec/view/view_caching_spec.rb",
|
107
|
+
"spec/view/view_partial_spec.rb",
|
108
|
+
"spec/view/view_rails_type_helpers.rb",
|
109
|
+
"spec/view/view_render_spec.rb",
|
110
|
+
"spec/view/view_variables_spec.rb"
|
111
|
+
]
|
112
|
+
|
113
|
+
if s.respond_to? :specification_version then
|
114
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
115
|
+
s.specification_version = 3
|
116
|
+
|
117
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
118
|
+
s.add_runtime_dependency(%q<ru_pol>, ["= 0.1.2"])
|
119
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 2.3.8"])
|
120
|
+
s.add_runtime_dependency(%q<moneta>, [">= 0.6.0"])
|
121
|
+
s.add_development_dependency(%q<hashie>, ["~> 1.0"])
|
122
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
|
123
|
+
s.add_development_dependency(%q<yard>, ["~> 0.6.0"])
|
124
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
125
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
126
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
127
|
+
s.add_development_dependency(%q<hashie>, ["~> 1.0"])
|
128
|
+
s.add_development_dependency(%q<rbench>, [">= 0"])
|
129
|
+
s.add_runtime_dependency(%q<ru_pol>, [">= 0.1.2"])
|
130
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 2.3.8"])
|
131
|
+
s.add_runtime_dependency(%q<moneta>, [">= 0.6.0"])
|
132
|
+
else
|
133
|
+
s.add_dependency(%q<ru_pol>, ["= 0.1.2"])
|
134
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.8"])
|
135
|
+
s.add_dependency(%q<moneta>, [">= 0.6.0"])
|
136
|
+
s.add_dependency(%q<hashie>, ["~> 1.0"])
|
137
|
+
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
138
|
+
s.add_dependency(%q<yard>, ["~> 0.6.0"])
|
139
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
140
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
141
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
142
|
+
s.add_dependency(%q<hashie>, ["~> 1.0"])
|
143
|
+
s.add_dependency(%q<rbench>, [">= 0"])
|
144
|
+
s.add_dependency(%q<ru_pol>, [">= 0.1.2"])
|
145
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.8"])
|
146
|
+
s.add_dependency(%q<moneta>, [">= 0.6.0"])
|
147
|
+
end
|
148
|
+
else
|
149
|
+
s.add_dependency(%q<ru_pol>, ["= 0.1.2"])
|
150
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.8"])
|
151
|
+
s.add_dependency(%q<moneta>, [">= 0.6.0"])
|
152
|
+
s.add_dependency(%q<hashie>, ["~> 1.0"])
|
153
|
+
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
154
|
+
s.add_dependency(%q<yard>, ["~> 0.6.0"])
|
155
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
156
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
157
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
158
|
+
s.add_dependency(%q<hashie>, ["~> 1.0"])
|
159
|
+
s.add_dependency(%q<rbench>, [">= 0"])
|
160
|
+
s.add_dependency(%q<ru_pol>, [">= 0.1.2"])
|
161
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.8"])
|
162
|
+
s.add_dependency(%q<moneta>, [">= 0.6.0"])
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
data/lib/garterbelt.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
stocking_dir = File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require 'active_support/core_ext/string/output_safety'
|
4
|
+
require stocking_dir + '/support/string'
|
5
|
+
|
6
|
+
require 'ru_pol'
|
7
|
+
require 'moneta'
|
8
|
+
require 'moneta/memory'
|
9
|
+
|
10
|
+
require stocking_dir + '/stocking'
|
11
|
+
|
12
|
+
require stocking_dir + '/renderers/renderer'
|
13
|
+
require stocking_dir + '/renderers/content_rendering'
|
14
|
+
require stocking_dir + '/renderers/closed_tag'
|
15
|
+
require stocking_dir + '/renderers/content_tag'
|
16
|
+
require stocking_dir + '/renderers/cache'
|
17
|
+
require stocking_dir + '/renderers/text'
|
18
|
+
require stocking_dir + '/renderers/comment'
|
19
|
+
require stocking_dir + '/renderers/doctype'
|
20
|
+
require stocking_dir + '/renderers/xml'
|
21
|
+
|
22
|
+
require stocking_dir + '/view'
|
23
|
+
require stocking_dir + '/page'
|
data/lib/page.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
module Garterbelt
|
2
|
+
class Page < View
|
3
|
+
# CLASS LEVEL CONFIGURATION --------------------------------------
|
4
|
+
|
5
|
+
class << self
|
6
|
+
attr_writer :doctype, :html_attributes
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.superclassed?
|
10
|
+
superclass.ancestors.include?(Garterbelt::Page)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.doctype
|
14
|
+
@doctype ||= superclassed? ? superclass.doctype : :transitional
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.html_attributes
|
18
|
+
@html_attributes ||= superclassed? ? superclass.html_attributes : {}
|
19
|
+
end
|
20
|
+
|
21
|
+
# THE CONTENT ----------------------------------------------------
|
22
|
+
|
23
|
+
def body_attributes
|
24
|
+
{}
|
25
|
+
end
|
26
|
+
|
27
|
+
def content
|
28
|
+
doctype self.class.doctype
|
29
|
+
html( self.class.html_attributes ) do
|
30
|
+
tag(:head) do
|
31
|
+
head
|
32
|
+
end
|
33
|
+
|
34
|
+
tag(:body, body_attributes) do
|
35
|
+
body
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def head
|
41
|
+
end
|
42
|
+
|
43
|
+
def body
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Garterbelt
|
2
|
+
class Cache < Renderer
|
3
|
+
include ContentRendering
|
4
|
+
|
5
|
+
attr_accessor :key, :cache_output, :view_output
|
6
|
+
|
7
|
+
def initialize(opts, &block)
|
8
|
+
super
|
9
|
+
self.key = opts[:key]
|
10
|
+
raise ArgumentError, ":key option required" unless key
|
11
|
+
self.content = block if block_given?
|
12
|
+
raise_unless_block_content
|
13
|
+
self.cache_output = ""
|
14
|
+
end
|
15
|
+
|
16
|
+
def head
|
17
|
+
self.view_output = output
|
18
|
+
self.output = cache_output
|
19
|
+
end
|
20
|
+
|
21
|
+
def foot
|
22
|
+
view_output << cache_output
|
23
|
+
self.output = view_output
|
24
|
+
end
|
25
|
+
|
26
|
+
def render_content
|
27
|
+
if cached = view.cache_store[key]
|
28
|
+
self.output << cached
|
29
|
+
else
|
30
|
+
super # renders block to the diverted output
|
31
|
+
view.cache_store[key] = cache_output # set the cache
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Garterbelt
|
2
|
+
class ClosedTag < Renderer
|
3
|
+
include RuPol::Swimsuit
|
4
|
+
max_pool_size 10000
|
5
|
+
|
6
|
+
attr_accessor :type, :attributes, :css_class
|
7
|
+
|
8
|
+
def initialize(opts)
|
9
|
+
super
|
10
|
+
self.type = opts[:type] || raise(ArgumentError, ":type required in initialization options")
|
11
|
+
self.attributes = opts[:attributes] || {}
|
12
|
+
|
13
|
+
css_class = attributes.delete(:class)
|
14
|
+
self.css_class = if css_class
|
15
|
+
css_class.is_a?(Array) ? css_class : [css_class]
|
16
|
+
else
|
17
|
+
[]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Convenience method chaining ---------------------------
|
22
|
+
|
23
|
+
def id(identifier)
|
24
|
+
raise ArgumentError, "Id must be a String or Symbol" unless [String, Symbol].include?(identifier.class)
|
25
|
+
self.attributes[:id] = identifier
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def c(*args)
|
30
|
+
self.css_class += args
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
# Rendering -----------------------------------------------
|
35
|
+
|
36
|
+
def rendered_attributes
|
37
|
+
str = ""
|
38
|
+
str << " class=\"#{css_class.join(' ')}\"" unless css_class.empty?
|
39
|
+
keys = attributes.keys.sort{|a, b| a.to_s <=> b.to_s}
|
40
|
+
keys.each do |key|
|
41
|
+
value = attributes[key]
|
42
|
+
if value
|
43
|
+
value = value.to_s.gsub('"', '\'')
|
44
|
+
str << " #{key}=\"#{value}\""
|
45
|
+
end
|
46
|
+
end
|
47
|
+
str
|
48
|
+
end
|
49
|
+
|
50
|
+
def template
|
51
|
+
"#{indent}<#{type}#{rendered_attributes}>\n"
|
52
|
+
end
|
53
|
+
|
54
|
+
def render
|
55
|
+
str = template
|
56
|
+
self.output << str
|
57
|
+
str
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Garterbelt
|
2
|
+
module ContentRendering
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval <<-RUBY
|
5
|
+
attr_accessor :content
|
6
|
+
|
7
|
+
include InstanceMethods
|
8
|
+
RUBY
|
9
|
+
end
|
10
|
+
|
11
|
+
module InstanceMethods
|
12
|
+
def render
|
13
|
+
head
|
14
|
+
render_content
|
15
|
+
foot
|
16
|
+
output
|
17
|
+
end
|
18
|
+
|
19
|
+
def head
|
20
|
+
view.level += 1
|
21
|
+
end
|
22
|
+
|
23
|
+
def foot
|
24
|
+
view.level -= 1
|
25
|
+
end
|
26
|
+
|
27
|
+
def render_content
|
28
|
+
if content.is_a?(Proc)
|
29
|
+
content.call
|
30
|
+
else
|
31
|
+
view.buffer << Text.new(:view => view, :content => content) if content
|
32
|
+
end
|
33
|
+
view.render_buffer
|
34
|
+
end
|
35
|
+
|
36
|
+
def raise_unless_block_content
|
37
|
+
raise ArgumentError, "Block content required" unless self.content && self.content.is_a?(Proc)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Garterbelt
|
2
|
+
class ContentTag < ClosedTag
|
3
|
+
include ContentRendering
|
4
|
+
|
5
|
+
def initialize(opts, &block)
|
6
|
+
super
|
7
|
+
if block_given?
|
8
|
+
self.content = block
|
9
|
+
else
|
10
|
+
self.content = opts[:content]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def id(identifier, &block)
|
15
|
+
super(identifier)
|
16
|
+
self.content = block if block_given?
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def c(*classes, &block)
|
21
|
+
super(*classes)
|
22
|
+
self.content = block if block_given?
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def head
|
27
|
+
self.output << "#{indent}<#{type}#{rendered_attributes}>\n"
|
28
|
+
super
|
29
|
+
end
|
30
|
+
|
31
|
+
def foot
|
32
|
+
super
|
33
|
+
self.output << "#{indent}</#{type}>\n"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Garterbelt
|
2
|
+
class Doctype < ClosedTag
|
3
|
+
max_pool_size 1000
|
4
|
+
|
5
|
+
ATTRIBUTES = {
|
6
|
+
:transitional => "html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"",
|
7
|
+
:strict => 'html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"',
|
8
|
+
:frameset => 'html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"',
|
9
|
+
:html5 => 'html',
|
10
|
+
:html1_1 => 'html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"',
|
11
|
+
:basic => 'html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd"',
|
12
|
+
:mobile => 'html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd"',
|
13
|
+
:rdfa => 'html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd"'
|
14
|
+
}
|
15
|
+
|
16
|
+
def rendered_attributes
|
17
|
+
ATTRIBUTES[type] || ATTRIBUTES[:transitional]
|
18
|
+
end
|
19
|
+
|
20
|
+
def template
|
21
|
+
"#{indent}<!DOCTYPE #{rendered_attributes}>\n"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Garterbelt
|
2
|
+
class Renderer
|
3
|
+
include RuPol::Swimsuit
|
4
|
+
max_pool_size 10000
|
5
|
+
|
6
|
+
attr_accessor :view
|
7
|
+
|
8
|
+
def initialize(opts)
|
9
|
+
self.view = opts[:view] || raise(ArgumentError, ":view required in initialization options")
|
10
|
+
end
|
11
|
+
|
12
|
+
# Rendering -----------------------------------------------
|
13
|
+
def output
|
14
|
+
view.output
|
15
|
+
end
|
16
|
+
|
17
|
+
def output=(alt_output)
|
18
|
+
view.output = alt_output
|
19
|
+
end
|
20
|
+
|
21
|
+
def level
|
22
|
+
view.level
|
23
|
+
end
|
24
|
+
|
25
|
+
def indent
|
26
|
+
' '*level*2
|
27
|
+
end
|
28
|
+
|
29
|
+
def render
|
30
|
+
raise NotImplementedError, "Subclasses must implement #render"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Garterbelt
|
2
|
+
class Text < Renderer
|
3
|
+
attr_accessor :content
|
4
|
+
|
5
|
+
def initialize(opts)
|
6
|
+
super
|
7
|
+
raise ArgumentError, ":content option required for #{self.class} initialization" unless opts[:content]
|
8
|
+
self.content = opts[:content]
|
9
|
+
end
|
10
|
+
|
11
|
+
def raise_with_block_content
|
12
|
+
raise ArgumentError, "#{self.class} does not take block content" if self.content.is_a?(Proc)
|
13
|
+
end
|
14
|
+
|
15
|
+
def render
|
16
|
+
raise_with_block_content
|
17
|
+
output << "#{indent}#{escaped_content}\n"
|
18
|
+
end
|
19
|
+
|
20
|
+
def escaped_content
|
21
|
+
escape? ? ERB::Util.h(content) : content
|
22
|
+
end
|
23
|
+
|
24
|
+
def escape?
|
25
|
+
!!view.escape
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|