building-blocks 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source :gemcutter
2
+
3
+ # Rails 3.0
4
+ gem 'rails'
5
+ gem 'rspec'
6
+ gem 'jeweler'
7
+ gem 'rcov'
data/Gemfile.lock ADDED
@@ -0,0 +1,96 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ abstract (1.0.0)
5
+ actionmailer (3.0.0.beta3)
6
+ actionpack (= 3.0.0.beta3)
7
+ mail (~> 2.2.0)
8
+ text-format (~> 1.0.0)
9
+ actionpack (3.0.0.beta3)
10
+ activemodel (= 3.0.0.beta3)
11
+ activesupport (= 3.0.0.beta3)
12
+ erubis (~> 2.6.5)
13
+ rack (~> 1.1.0)
14
+ rack-mount (~> 0.6.0)
15
+ rack-test (~> 0.5.0)
16
+ activemodel (3.0.0.beta3)
17
+ activesupport (= 3.0.0.beta3)
18
+ activerecord (3.0.0.beta3)
19
+ activemodel (= 3.0.0.beta3)
20
+ activesupport (= 3.0.0.beta3)
21
+ arel (~> 0.3.3)
22
+ activeresource (3.0.0.beta3)
23
+ activemodel (= 3.0.0.beta3)
24
+ activesupport (= 3.0.0.beta3)
25
+ activesupport (3.0.0.beta3)
26
+ builder (~> 2.1.2)
27
+ i18n (~> 0.3.6)
28
+ memcache-client (>= 1.7.5)
29
+ tzinfo (~> 0.3.16)
30
+ arel (0.3.3)
31
+ activesupport (>= 3.0.0.beta)
32
+ builder (2.1.2)
33
+ erubis (2.6.6)
34
+ abstract (>= 1.0.0)
35
+ git (1.2.5)
36
+ i18n (0.3.7)
37
+ jeweler (1.6.0)
38
+ bundler (~> 1.0.0)
39
+ git (>= 1.2.5)
40
+ rake
41
+ mail (2.2.7)
42
+ activesupport (>= 2.3.6)
43
+ mime-types
44
+ treetop (>= 1.4.5)
45
+ memcache-client (1.8.5)
46
+ mime-types (1.16)
47
+ mysql (2.8.1)
48
+ polyglot (0.3.1)
49
+ rack (1.1.2)
50
+ rack-mount (0.6.14)
51
+ rack (>= 1.0.0)
52
+ rack-test (0.5.7)
53
+ rack (>= 1.0)
54
+ rails (3.0.0.beta3)
55
+ actionmailer (= 3.0.0.beta3)
56
+ actionpack (= 3.0.0.beta3)
57
+ activerecord (= 3.0.0.beta3)
58
+ activeresource (= 3.0.0.beta3)
59
+ activesupport (= 3.0.0.beta3)
60
+ bundler (>= 0.9.19)
61
+ railties (= 3.0.0.beta3)
62
+ railties (3.0.0.beta3)
63
+ actionpack (= 3.0.0.beta3)
64
+ activesupport (= 3.0.0.beta3)
65
+ rake (>= 0.8.3)
66
+ thor (~> 0.13.4)
67
+ rake (0.8.7)
68
+ rcov (0.9.9)
69
+ rspec (2.0.0.beta.8)
70
+ rspec-core (= 2.0.0.beta.8)
71
+ rspec-expectations (= 2.0.0.beta.8)
72
+ rspec-mocks (= 2.0.0.beta.8)
73
+ rspec-core (2.0.0.beta.8)
74
+ rspec-expectations (2.0.0.beta.8)
75
+ rspec-mocks (2.0.0.beta.8)
76
+ sqlite3 (1.3.3)
77
+ sqlite3-ruby (1.3.3)
78
+ sqlite3 (>= 1.3.3)
79
+ text-format (1.0.0)
80
+ text-hyphen (~> 1.0.0)
81
+ text-hyphen (1.0.2)
82
+ thor (0.13.8)
83
+ treetop (1.4.9)
84
+ polyglot (>= 0.3.1)
85
+ tzinfo (0.3.27)
86
+
87
+ PLATFORMS
88
+ ruby
89
+
90
+ DEPENDENCIES
91
+ jeweler
92
+ mysql
93
+ rails (= 3.0.0.beta3)
94
+ rcov
95
+ rspec (= 2.0.0.beta.8)
96
+ sqlite3-ruby
data/README.rdoc ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1,59 @@
1
+ begin
2
+ # Rspec 1.3.0
3
+ require 'spec/rake/spectask'
4
+
5
+ desc 'Default: run specs'
6
+ task :default => :spec
7
+ Spec::Rake::SpecTask.new do |t|
8
+ t.spec_files = FileList["spec/**/*_spec.rb"]
9
+ end
10
+
11
+ Spec::Rake::SpecTask.new('rcov') do |t|
12
+ t.spec_files = FileList["spec/**/*_spec.rb"]
13
+ t.rcov = true
14
+ t.rcov_opts = ['--exclude', 'spec']
15
+ end
16
+
17
+ rescue LoadError
18
+ # Rspec 2.0
19
+ require 'rspec/core/rake_task'
20
+
21
+ desc 'Default: run specs'
22
+ task :default => :spec
23
+ Rspec::Core::RakeTask.new do |t|
24
+ t.pattern = "spec/**/*_spec.rb"
25
+ end
26
+
27
+ Rspec::Core::RakeTask.new('rcov') do |t|
28
+ t.pattern = "spec/**/*_spec.rb"
29
+ t.rcov = true
30
+ t.rcov_opts = ['--exclude', 'spec']
31
+ end
32
+
33
+ rescue LoadError
34
+ puts "Rspec not available. Install it with: gem install rspec"
35
+ end
36
+
37
+ namespace 'rails2.3' do
38
+ task :spec do
39
+ gemfile = File.join(File.dirname(__FILE__), 'lib', 'has_relationship', 'compatibility', 'Gemfile')
40
+ ENV['BUNDLE_GEMFILE'] = gemfile
41
+ Rake::Task['spec'].invoke
42
+ end
43
+ end
44
+
45
+ begin
46
+ require 'jeweler'
47
+ Jeweler::Tasks.new do |gemspec|
48
+ gemspec.name = "building-blocks"
49
+ gemspec.summary = ""
50
+ gemspec.description = ""
51
+ gemspec.email = "hunterae@gmail.com"
52
+ gemspec.homepage = "http://github.com/hunterae/building-blocks"
53
+ gemspec.authors = ["Andrew Hunter"]
54
+ gemspec.files = FileList["[A-Z]*", "{lib,spec,rails}/**/*"] - FileList["**/*.log"]
55
+ end
56
+ Jeweler::GemcutterTasks.new
57
+ rescue LoadError
58
+ puts "Jeweler not available. Install it with: gem install jeweler"
59
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,13 @@
1
+ require "action_view"
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
4
+
5
+ require "building_blocks/building_blocks"
6
+ require "building_blocks/container"
7
+ require "building_blocks/helper_methods"
8
+
9
+ $LOAD_PATH.shift
10
+
11
+ if defined?(ActionView::Base)
12
+ ActionView::Base.send :include, BuildingBlocks::HelperMethods
13
+ end
@@ -0,0 +1,236 @@
1
+ module BuildingBlocks
2
+ class Base
3
+
4
+ attr_accessor :view, :blocks, :block_positions, :anonymous_block_number,
5
+ :start_rendering_blocks, :block_groups, :shared_options
6
+
7
+ def defined?(name)
8
+ !blocks[name.to_sym].nil?
9
+ end
10
+
11
+ def define(name, options={}, &block)
12
+ block_container = BuildingBlocks::Container.new
13
+ block_container.name = name
14
+ block_container.options = options
15
+ block_container.block = block
16
+
17
+ blocks[name.to_sym] = block_container if blocks[name.to_sym].nil?
18
+
19
+ nil
20
+ end
21
+
22
+ def replace(name, options={}, &block)
23
+ block_container = BuildingBlocks::Container.new
24
+ block_container.name = name
25
+ block_container.options = options
26
+ block_container.block = block
27
+
28
+ blocks[name.to_sym] = block_container
29
+
30
+ nil
31
+ end
32
+
33
+ def use(*args, &block)
34
+ options = args.extract_options!
35
+
36
+ # If the user doesn't specify a block name, we generate an anonymous block name to assure other
37
+ # anonymous blocks don't override its definition
38
+ name = args.first ? args.shift : self.anonymous_block_name
39
+
40
+ block_container = BuildingBlocks::Container.new
41
+ block_container.name = name
42
+ block_container.options = options
43
+ block_container.block = block
44
+
45
+ blocks[name.to_sym] = block_container if !name.is_a?(BuildingBlocks::Container) and blocks[name.to_sym].nil? and block
46
+
47
+ if start_rendering_blocks
48
+ render_block name, args, options
49
+ else
50
+ # Delays rendering this block until the partial has been rendered and all the blocks have had a chance to be defined
51
+ self.block_positions << block_container
52
+ end
53
+
54
+ nil
55
+ end
56
+
57
+ def render
58
+ self.start_rendering_blocks = false
59
+
60
+ shared_options[:captured_block] = view.capture(self, &shared_options[:block]) if shared_options[:block]
61
+
62
+ self.start_rendering_blocks = true
63
+
64
+ view.render shared_options[:template], shared_options
65
+ end
66
+
67
+ def before(name, options={}, &block)
68
+ name = "before_#{name.to_s}".to_sym
69
+
70
+ block_container = BuildingBlocks::Container.new
71
+ block_container.name = name
72
+ block_container.options = options
73
+ block_container.block = block
74
+
75
+ if view.blocks.blocks[name].nil?
76
+ view.blocks.blocks[name] = [block_container]
77
+ else
78
+ view.blocks.blocks[name] << block_container
79
+ end
80
+
81
+ nil
82
+ end
83
+ alias prepend before
84
+
85
+ def after(name, options={}, &block)
86
+ name = "after_#{name.to_s}".to_sym
87
+
88
+ block_container = BuildingBlocks::Container.new
89
+ block_container.name = name
90
+ block_container.options = options
91
+ block_container.block = block
92
+
93
+ if view.blocks.blocks[name].nil?
94
+ view.blocks.blocks[name] = [block_container]
95
+ else
96
+ view.blocks.blocks[name] << block_container
97
+ end
98
+
99
+ nil
100
+ end
101
+ alias append after
102
+
103
+ # If a method is missing, we'll assume the user is starting a new block group by that missing method name
104
+ def method_missing(m, options={}, &block)
105
+ # If the specified block group has already been defined, it is simply returned here for iteration.
106
+ # It will consist of all the blocks used in this block group that have yet to be rendered,
107
+ # as the call for their use occurred before the template was rendered (where their definitions likely occurred)
108
+ return self.block_groups[m] unless self.block_groups[m].nil?
109
+
110
+ # Allows for nested block groups, store the current block positions array and start a new one
111
+ original_block_positions = self.block_positions
112
+ self.block_positions = []
113
+ self.block_groups[m] = self.block_positions
114
+
115
+ # Capture the contents of the block group (this will only capture block definitions and block uses)
116
+ view.capture(shared_options.merge(options), &block) if block_given?
117
+
118
+ # restore the original block positions array
119
+ self.block_positions = original_block_positions
120
+ nil
121
+ end
122
+
123
+ protected
124
+
125
+ def initialize(options)
126
+ self.view = options[:view]
127
+ self.shared_options = options
128
+
129
+ options[options[:variable] ? options[:variable].to_sym : :blocks] = self
130
+ options[:templates_folder] = "blocks" if options[:templates_folder].nil?
131
+
132
+ self.block_positions = []
133
+ self.blocks = {}
134
+ self.anonymous_block_number = 0
135
+ self.block_groups = {}
136
+ self.start_rendering_blocks = true
137
+ end
138
+
139
+ def anonymous_block_name
140
+ self.anonymous_block_number = self.anonymous_block_number + 1
141
+ "block_#{anonymous_block_number}"
142
+ end
143
+
144
+ def render_block(name_or_container, args, options={})
145
+ render_options = options
146
+
147
+ if (name_or_container.is_a?(BuildingBlocks::Container))
148
+ name = name_or_container.name.to_sym
149
+ render_options = render_options.merge(name_or_container.options)
150
+ else
151
+ name = name_or_container.to_sym
152
+ end
153
+
154
+ view.concat(render_before_blocks(name, options))
155
+
156
+ if blocks[name]
157
+ block_container = blocks[name]
158
+
159
+ args.push(shared_options.merge(block_container.options).merge(render_options))
160
+
161
+ # If the block is taking more than one parameter, we can use *args
162
+ if block_container.block.arity > 1
163
+ view.concat(view.capture *args, &block_container.block)
164
+
165
+ # However, if the block only takes a single parameter, we do not want ruby to try to cram the args list into that parameter
166
+ # as an array
167
+ else
168
+ view.concat(view.capture args.first, &block_container.block)
169
+ end
170
+ elsif view.blocks.blocks[name]
171
+ block_container = view.blocks.blocks[name]
172
+
173
+ args.push(shared_options.merge(block_container.options).merge(render_options))
174
+
175
+ # If the block is taking more than one parameter, we can use *args
176
+ if block_container.block.arity > 1
177
+ view.concat(view.capture *args, &block_container.block)
178
+
179
+ # However, if the block only takes a single parameter, we do not want ruby to try to cram the args list into that parameter
180
+ # as an array
181
+ else
182
+ view.concat(view.capture args.first, &block_container.block)
183
+ end
184
+ else
185
+ begin
186
+ begin
187
+ view.concat(view.render "#{name.to_s}", shared_options.merge(render_options))
188
+ rescue ActionView::MissingTemplate
189
+ # This partial did not exist in the current controller's view directory; now checking in the default templates folder
190
+ view.concat(view.render "#{shared_options[:templates_folder]}/#{name.to_s}", shared_options.merge(render_options))
191
+ end
192
+ rescue ActionView::MissingTemplate
193
+ # This block does not exist and no partial can be found to satify it
194
+ end
195
+ end
196
+
197
+ view.concat(render_after_blocks(name, options))
198
+ end
199
+
200
+ def render_before_blocks(name, options={})
201
+ name = "before_#{name.to_s}".to_sym
202
+
203
+ unless blocks[name].nil?
204
+ blocks[name].each do |block_container|
205
+ view.concat(view.capture shared_options.merge(block_container.options).merge(options), &block_container.block)
206
+ end
207
+ end
208
+
209
+ unless view.blocks.blocks[name].nil? || view.blocks.blocks == blocks
210
+ view.blocks.blocks[name].each do |block_container|
211
+ view.concat(view.capture shared_options.merge(block_container.options).merge(options), &block_container.block)
212
+ end
213
+ end
214
+
215
+ nil
216
+ end
217
+
218
+ def render_after_blocks(name, options={})
219
+ name = "after_#{name.to_s}".to_sym
220
+
221
+ unless blocks[name].nil?
222
+ blocks[name].each do |block_container|
223
+ view.concat(view.capture shared_options.merge(block_container.options).merge(options), &block_container.block)
224
+ end
225
+ end
226
+
227
+ unless view.blocks.blocks[name].nil? || view.blocks.blocks == blocks
228
+ view.blocks.blocks[name].each do |block_container|
229
+ view.concat(view.capture shared_options.merge(block_container.options).merge(options), &block_container.block)
230
+ end
231
+ end
232
+
233
+ nil
234
+ end
235
+ end
236
+ end
@@ -0,0 +1,5 @@
1
+ module BuildingBlocks
2
+ class Container
3
+ attr_accessor :name, :options, :block
4
+ end
5
+ end
@@ -0,0 +1,10 @@
1
+ module BuildingBlocks
2
+ module HelperMethods
3
+ def blocks
4
+ options = {}
5
+ options[:view] = self
6
+
7
+ @blocks ||= Base.new(options)
8
+ end
9
+ end
10
+ end
data/rails/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'building-blocks'
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: building-blocks
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Andrew Hunter
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-05-03 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ prerelease: false
23
+ type: :runtime
24
+ name: rails
25
+ version_requirements: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ hash: 3
31
+ segments:
32
+ - 0
33
+ version: "0"
34
+ requirement: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ prerelease: false
37
+ type: :runtime
38
+ name: rspec
39
+ version_requirements: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 3
45
+ segments:
46
+ - 0
47
+ version: "0"
48
+ requirement: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ prerelease: false
51
+ type: :runtime
52
+ name: jeweler
53
+ version_requirements: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ hash: 3
59
+ segments:
60
+ - 0
61
+ version: "0"
62
+ requirement: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ prerelease: false
65
+ type: :runtime
66
+ name: rcov
67
+ version_requirements: &id004 !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ hash: 3
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ requirement: *id004
77
+ description: ""
78
+ email: hunterae@gmail.com
79
+ executables: []
80
+
81
+ extensions: []
82
+
83
+ extra_rdoc_files:
84
+ - README.rdoc
85
+ files:
86
+ - Gemfile
87
+ - Gemfile.lock
88
+ - README.rdoc
89
+ - Rakefile
90
+ - VERSION
91
+ - lib/building-blocks.rb
92
+ - lib/building_blocks/building_blocks.rb
93
+ - lib/building_blocks/container.rb
94
+ - lib/building_blocks/helper_methods.rb
95
+ - rails/init.rb
96
+ has_rdoc: true
97
+ homepage: http://github.com/hunterae/building-blocks
98
+ licenses: []
99
+
100
+ post_install_message:
101
+ rdoc_options: []
102
+
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ hash: 3
111
+ segments:
112
+ - 0
113
+ version: "0"
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ hash: 3
120
+ segments:
121
+ - 0
122
+ version: "0"
123
+ requirements: []
124
+
125
+ rubyforge_project:
126
+ rubygems_version: 1.3.7
127
+ signing_key:
128
+ specification_version: 3
129
+ summary: ""
130
+ test_files: []
131
+