partializer 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "http://rubygems.org"
2
+
3
+ # gem 'active_support', '>= 3.0.0'
4
+ gem 'hashie'
5
+ gem 'rails', '>= 3.0.0'
6
+
7
+ group :development do
8
+ gem "rspec", ">= 2.8.0"
9
+ gem "rdoc", ">= 3.12"
10
+ gem "bundler", ">= 1.0.0"
11
+ gem "jeweler", "~> 1.8.4"
12
+ gem "simplecov", ">= 0.5"
13
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,111 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ actionmailer (3.2.8)
5
+ actionpack (= 3.2.8)
6
+ mail (~> 2.4.4)
7
+ actionpack (3.2.8)
8
+ activemodel (= 3.2.8)
9
+ activesupport (= 3.2.8)
10
+ builder (~> 3.0.0)
11
+ erubis (~> 2.7.0)
12
+ journey (~> 1.0.4)
13
+ rack (~> 1.4.0)
14
+ rack-cache (~> 1.2)
15
+ rack-test (~> 0.6.1)
16
+ sprockets (~> 2.1.3)
17
+ activemodel (3.2.8)
18
+ activesupport (= 3.2.8)
19
+ builder (~> 3.0.0)
20
+ activerecord (3.2.8)
21
+ activemodel (= 3.2.8)
22
+ activesupport (= 3.2.8)
23
+ arel (~> 3.0.2)
24
+ tzinfo (~> 0.3.29)
25
+ activeresource (3.2.8)
26
+ activemodel (= 3.2.8)
27
+ activesupport (= 3.2.8)
28
+ activesupport (3.2.8)
29
+ i18n (~> 0.6)
30
+ multi_json (~> 1.0)
31
+ arel (3.0.2)
32
+ builder (3.0.0)
33
+ diff-lcs (1.1.3)
34
+ erubis (2.7.0)
35
+ git (1.2.5)
36
+ hashie (1.2.0)
37
+ hike (1.2.1)
38
+ i18n (0.6.0)
39
+ jeweler (1.8.4)
40
+ bundler (~> 1.0)
41
+ git (>= 1.2.5)
42
+ rake
43
+ rdoc
44
+ journey (1.0.4)
45
+ json (1.7.5)
46
+ mail (2.4.4)
47
+ i18n (>= 0.4.0)
48
+ mime-types (~> 1.16)
49
+ treetop (~> 1.4.8)
50
+ mime-types (1.19)
51
+ multi_json (1.3.6)
52
+ polyglot (0.3.3)
53
+ rack (1.4.1)
54
+ rack-cache (1.2)
55
+ rack (>= 0.4)
56
+ rack-ssl (1.3.2)
57
+ rack
58
+ rack-test (0.6.1)
59
+ rack (>= 1.0)
60
+ rails (3.2.8)
61
+ actionmailer (= 3.2.8)
62
+ actionpack (= 3.2.8)
63
+ activerecord (= 3.2.8)
64
+ activeresource (= 3.2.8)
65
+ activesupport (= 3.2.8)
66
+ bundler (~> 1.0)
67
+ railties (= 3.2.8)
68
+ railties (3.2.8)
69
+ actionpack (= 3.2.8)
70
+ activesupport (= 3.2.8)
71
+ rack-ssl (~> 1.3.2)
72
+ rake (>= 0.8.7)
73
+ rdoc (~> 3.4)
74
+ thor (>= 0.14.6, < 2.0)
75
+ rake (0.9.2.2)
76
+ rdoc (3.12)
77
+ json (~> 1.4)
78
+ rspec (2.11.0)
79
+ rspec-core (~> 2.11.0)
80
+ rspec-expectations (~> 2.11.0)
81
+ rspec-mocks (~> 2.11.0)
82
+ rspec-core (2.11.1)
83
+ rspec-expectations (2.11.2)
84
+ diff-lcs (~> 1.1.3)
85
+ rspec-mocks (2.11.2)
86
+ simplecov (0.6.4)
87
+ multi_json (~> 1.0)
88
+ simplecov-html (~> 0.5.3)
89
+ simplecov-html (0.5.3)
90
+ sprockets (2.1.3)
91
+ hike (~> 1.2)
92
+ rack (~> 1.0)
93
+ tilt (~> 1.1, != 1.3.0)
94
+ thor (0.16.0)
95
+ tilt (1.3.3)
96
+ treetop (1.4.10)
97
+ polyglot
98
+ polyglot (>= 0.3.1)
99
+ tzinfo (0.3.33)
100
+
101
+ PLATFORMS
102
+ ruby
103
+
104
+ DEPENDENCIES
105
+ bundler (>= 1.0.0)
106
+ hashie
107
+ jeweler (~> 1.8.4)
108
+ rails (>= 3.0.0)
109
+ rdoc (>= 3.12)
110
+ rspec (>= 2.8.0)
111
+ simplecov (>= 0.5)
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Kristian Mandrup
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.md ADDED
@@ -0,0 +1,204 @@
1
+ ## Partializer
2
+
3
+ Structure your partials in Rails 3+
4
+
5
+ ## Installation
6
+
7
+ ```ruby
8
+ # Gemfile
9
+ gem 'partializer'
10
+ ```
11
+
12
+ Console, run:
13
+
14
+ `$ bundle`
15
+
16
+ ## Requirements
17
+
18
+ Only tested on Ruby 1.9.3 and Rails 3.2.
19
+
20
+ ## Why?
21
+
22
+ In a Rails project I notices this reoccuring pattern and thought it would be nice to encapsulate it better ;)
23
+
24
+ ```haml
25
+ #communication.column
26
+ - [:upper :lower].each do |name|
27
+ = render partial: "properties/show/main/#{name}"
28
+ ```
29
+
30
+ ```haml
31
+ #lower.column
32
+ - [:communication :description].each do |name|
33
+ = render partial: "properties/show/main/lower/#{name}"
34
+ ```
35
+
36
+ ```haml
37
+ #communication.column
38
+ - [:profile, :contact_requests, :social, :favorite, :comments].each do |name|
39
+ = render partial: "properties/show/main/lower/communication/#{name}"
40
+ ```
41
+
42
+ Note also that all the partial paths are hardcoded here. If I move a folder, all the partials withing this folder have to be reconfigured to the new location! Argh!
43
+
44
+ ## With partialized partials :)
45
+
46
+ Imagine you have a `properties/show/_main` partial. Then you can render all its subpartials like this:
47
+
48
+ ```haml
49
+ #main.column
50
+ = render_partials partialize('properties#show', 'main')
51
+ ```
52
+
53
+ For the `properties/show/main/_lower` partial, simply:
54
+
55
+ ```haml
56
+ #lower.column
57
+ = render_partials partialize(partializer, 'lower')
58
+ ```
59
+
60
+ And for the `properties/show/main/lower/_communication` partial, simply:
61
+
62
+ ```haml
63
+ #communication.column
64
+ = render_partials partialize(partializer, 'communication')
65
+ ```
66
+
67
+ Since the partializer (with previous context) will be passed down as a local and used by `partialize` to resolve the context (partial path). Sleek :)
68
+
69
+ ### The REAL power!
70
+
71
+ Since the Partializer is class based, you can use simple inheritance and include to mixin partial configurations for other contexts, override, call `super` etc.
72
+
73
+ Another great advantage is, that if you pass the "context" down the partial hierarchy, changing the top level context will take effect on all the partials in the call hierarchy. One change fix!
74
+
75
+ ## Configuration
76
+
77
+ Note: This should be improved with even better DSL and perhaps loading from YAML file or similar? Maybe even supplying a hash directly and using Hashie::Mash?
78
+
79
+ Structure your partial groupings like this:
80
+
81
+ ```ruby
82
+ module Partializers
83
+ class Properties < Partializer
84
+ class Show < Partializer
85
+ partials_for :main, [{upper: :gallery}, :lower]
86
+
87
+ partials_for :side, [:basic_info, :cost, :more_info, :period]
88
+
89
+ partializer :lower do
90
+ partializer :communication do
91
+ partialize :profile, :contact_requests, :social, :favorite, :priority_subscription, :free_subscription, :comments
92
+ end
93
+
94
+ partialize :_communication, :description
95
+ end
96
+
97
+ partials_for :my_main, [{upper: :gallery}, :_lower]
98
+ end
99
+ end
100
+ end
101
+ ```
102
+
103
+ Alternatively using Classes and methods (sth like):
104
+
105
+ ```ruby
106
+ module Partializers
107
+ class Properties < Partializer
108
+ class Show < Partializer
109
+ def main
110
+ partials_for :main, [{upper: :gallery}, :lower]
111
+ end
112
+
113
+ def side
114
+ partials_for :side, [:basic_info, :cost, :more_info, :period]
115
+ end
116
+
117
+ class Lower < Partializer
118
+ class Communication < Partializer
119
+ def partials
120
+ partials_for [
121
+ :profile, :contact_requests, :social,
122
+ :favorite, :priority_subscription,
123
+ :free_subscription, :comments
124
+ ]
125
+ end
126
+ end
127
+
128
+ def partials
129
+ partials_for [:_communication, :description]
130
+ end
131
+ end
132
+
133
+ def my_main
134
+ partials_for [{upper: :gallery}, :_lower]
135
+ end
136
+ end
137
+ end
138
+ end
139
+ ```
140
+
141
+ This will likely be optimized in the near future. No need for the `partials_for` method call in the instance methods. Can be auto-resolved when the Partializer resolves itself into a nested `Partializer::Collections` structure.
142
+
143
+ ## Special Conventions
144
+
145
+ A Symbol prefixed with underscore will nest down the hierarchy, see fx `:_lower`vs `:lower`. In this case, the class must have been defined, since it uses a constant lookup on the class and instantiates it.
146
+
147
+ It might make sense to drop this `_` convention and simply always attempt nested resolution?
148
+
149
+ ## Usage in Views and Partials
150
+
151
+ Now you can use the Partializers in your views!
152
+
153
+ ```haml
154
+ #communication.column
155
+ = render_partials partialize('properties#show', 'main')
156
+ ```
157
+
158
+ This will render fx `properties/show/main/upper` and `properties/show/main/lower`.
159
+ The partial called will have the partializer passed in as a local.
160
+
161
+ This allows you to continue calling like this, which will effectively be a shorthand for calling:
162
+
163
+ `= render_partials partialize('properties#show', 'main.lower')`
164
+
165
+ ```haml
166
+ #main.column
167
+ = render_partials partialize(partializer, 'lower')
168
+ ```
169
+
170
+ ## Hidden Rails feature
171
+
172
+ I'm taking advantage of this little hidden 'gem' in Rails :)
173
+
174
+ [hidden-features-in-rails-3-2](http://blog.plataformatec.com.br/2012/01/my-five-favorite-hidden-features-in-rails-3-2/)
175
+
176
+ Now, you can solve this problem by defining `to_partial_path` (part of the ActiveModel API) and can be implemented in any object.
177
+
178
+ ```ruby
179
+ class Activity
180
+ def to_partial_path
181
+ "activities/#{kind}"
182
+ end
183
+ end
184
+ ```
185
+
186
+ And then invoking:
187
+
188
+ `render :partial => @activities, :as => :activity`
189
+
190
+ ## Contributing to partializer
191
+
192
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
193
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
194
+ * Fork the project.
195
+ * Start a feature/bugfix branch.
196
+ * Commit and push until you are happy with your contribution.
197
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
198
+ * 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.
199
+
200
+ ## Copyright
201
+
202
+ Copyright (c) 2012 Kristian Mandrup. See LICENSE.txt for
203
+ further details.
204
+
data/Rakefile ADDED
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "partializer"
18
+ gem.homepage = "http://github.com/kristianmandrup/partializer"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Partialize your Rails partials for easy management and rendering}
21
+ gem.description = %Q{Makes it easy to render the subpartials of any partial}
22
+ gem.email = "kmandrup@gmail.com"
23
+ gem.authors = ["Kristian Mandrup"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
35
+ spec.pattern = 'spec/**/*_spec.rb'
36
+ spec.rcov = true
37
+ end
38
+
39
+ task :default => :spec
40
+
41
+ require 'rdoc/task'
42
+ Rake::RDocTask.new do |rdoc|
43
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
44
+
45
+ rdoc.rdoc_dir = 'rdoc'
46
+ rdoc.title = "partializer #{version}"
47
+ rdoc.rdoc_files.include('README*')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,91 @@
1
+ # require 'active_support/core_ext/string'
2
+ # require 'active_support/inflector'
3
+ require 'rails'
4
+ require 'hashie'
5
+
6
+ require 'partializer/view_helper'
7
+ require 'partializer/engine' if defined?(::Rails::Engine)
8
+
9
+ class Partializer
10
+ autoload :Collection, 'partializer/collection'
11
+ autoload :Resolver, 'partializer/resolver'
12
+ autoload :Partials, 'partializer/partials'
13
+
14
+
15
+ def partials_for name, *args
16
+ hash = args.flatten.inject({}) do |res, arg|
17
+ key = arg.kind_of?(Hash) ? arg.keys.first : arg
18
+ res[key.to_sym] = self.class.resolve(arg)
19
+ res
20
+ end
21
+ Partializer::Collection.new name, hash.keys, hash
22
+ end
23
+
24
+ class << self
25
+ def partialize *args, &block
26
+ name = self.name.to_s.underscore
27
+
28
+ hashie = args.flatten.inject({}) do |res, arg|
29
+ item = resolve_value(arg)
30
+ res.merge! Hashie::Mash.new arg.to_sym => item
31
+ end
32
+
33
+ collection = Partializer::Collection.new name, args, hashie
34
+
35
+ define_method :partials do
36
+ @partials ||= collection # Partializer::Collection.new hashie, partials
37
+ end
38
+ end
39
+
40
+ def partializer name, options = {}, &block
41
+ default_parent = ::Partializer
42
+
43
+ parent = options[:parent] || default_parent
44
+ raise ArgumentError, "Parent must have a partialize method, was: #{parent}" unless parent.respond_to? :partialize
45
+
46
+ clazz_name = name.to_s.camelize
47
+ context = self.kind_of?(Class) ? self : self.class
48
+
49
+ clazz = parent ? Class.new(parent) : Class.new
50
+ context.const_set clazz_name, clazz
51
+ clazz = context.const_get(clazz_name)
52
+
53
+ clazz.instance_eval(&block) if block_given?
54
+ clazz
55
+ end
56
+
57
+ def partials_for name, *args
58
+ hash = args.flatten.inject({}) do |res, arg|
59
+ key = arg.kind_of?(Hash) ? arg.keys.first : arg
60
+ res[key.to_sym] = resolve(arg)
61
+ res
62
+ end
63
+ define_method name do
64
+ Partializer::Collection.new name, hash.keys, hash
65
+ end
66
+ end
67
+
68
+
69
+ protected
70
+
71
+ include Resolver
72
+
73
+ def partialize_item_of hash
74
+ matching?(hash) ? hash.values.first.to_sym : hash
75
+ end
76
+
77
+ def matching? hash
78
+ hash.keys.first.to_sym == hash.values.first.to_sym
79
+ end
80
+
81
+ end
82
+
83
+ protected
84
+
85
+ include Resolver
86
+
87
+ def method_missing meth_name, *args, &block
88
+ instance = create_partializer(meth_name)
89
+ instance.respond_to?(:partials) ? instance.partials : instance
90
+ end
91
+ end
@@ -0,0 +1,96 @@
1
+ class Partializer
2
+ class Collection
3
+ include Enumerable
4
+
5
+ attr_reader :hashie, :name, :ns, :action
6
+
7
+ def initialize name, *items
8
+ hash = items.extract_options!
9
+ partials << partial_keys(items)
10
+ self.name = name.to_s
11
+ @hashie = Hashie::Mash.new resolve(hash) unless hash.empty?
12
+ set_names unless hashie.nil?
13
+ end
14
+
15
+ def each &block
16
+ partials.each {|partial| yield partial }
17
+ end
18
+
19
+ def partials
20
+ @partials ||= Partializer::Partials.new
21
+ end
22
+
23
+ def path
24
+ [ns, action, name.gsub('.', '/')].compact.join('/')
25
+ end
26
+ alias_method :to_partial_path, :path
27
+
28
+
29
+ def set_context ns, action
30
+ @ns, @action = [ns, action]
31
+ partials.list.each {|p| p.send :set_context, ns, action }
32
+ end
33
+
34
+ protected
35
+
36
+ def name= name
37
+ @name = name
38
+ partials.list.each do |p|
39
+ p.path = name
40
+ end
41
+ end
42
+
43
+ def set_names
44
+ hashie.keys.each do |key|
45
+ if key.kind_of?(String)
46
+ h = hashie.send(key)
47
+ if h.kind_of? Partializer::Collection
48
+ h.send :name=, "#{name}.#{key}"
49
+ h.set_names unless h.hashie.nil?
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ def resolve hash
56
+ hash.inject({}) do |res, pair|
57
+ key = pair.first
58
+ item = pair.last
59
+ key = key.to_s.sub(/^_/, '').to_sym
60
+
61
+ value = resolve_value key, item
62
+
63
+ res[key.to_s.sub(/^_/, '').to_sym] = value
64
+ res
65
+ end
66
+ end
67
+
68
+ def resolve_value key, item
69
+ case item
70
+ when Partializer::Collection
71
+ item.hashie ? item.send(key) : item
72
+ when Symbol, String
73
+ Partializer::Collection.new('noname', item)
74
+ when Hash
75
+ item.values.first
76
+ else
77
+ raise ArgumentError, "cant resolve: #{item.inspect}"
78
+ end
79
+ end
80
+
81
+ def partial_keys *args
82
+ args.flatten.map do |item|
83
+ case item
84
+ when Hash
85
+ item.keys.map(&:to_sym)
86
+ when String, Symbol
87
+ item.to_s.sub(/^_/, '').to_sym
88
+ end
89
+ end.flatten.compact.uniq
90
+ end
91
+
92
+ def method_missing meth_name, *args, &block
93
+ hashie.send(meth_name)
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,9 @@
1
+ class Partializer
2
+ module Rails
3
+ class Engine < ::Rails::Engine
4
+ initializer 'partializer' do
5
+ ActionView::Base.send :include, ::Partializer::ViewHelper
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,43 @@
1
+ class Partializer
2
+ class Partial
3
+ attr_reader :path, :name, :ns, :action
4
+
5
+ def initialize path, name
6
+ @path = path unless path.blank?
7
+ self.name = name
8
+ end
9
+
10
+ def path= path_name
11
+ raise ArgumentError, "Path is blank" if path_name.blank?
12
+ @path = path_name.gsub /\\./, '/'
13
+ normalize!
14
+ end
15
+
16
+ def name= name
17
+ @name = name
18
+ normalize!
19
+ end
20
+
21
+ def view_path
22
+ [ns, action, path, name].compact.join('/')
23
+ end
24
+
25
+ def to_partial_path
26
+ view_path.gsub('.', '/')
27
+ end
28
+
29
+ protected
30
+
31
+ def set_context ns, action
32
+ @ns, @action = [ns, action]
33
+ self
34
+ end
35
+
36
+ def normalize!
37
+ if path =~ /\.#{name}$/
38
+ norm = path.split('.')[0..-2].join('.')
39
+ @path = norm unless norm.blank?
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,39 @@
1
+ require 'partializer/partial'
2
+
3
+ class Partializer
4
+ class Partials
5
+ include Enumerable
6
+
7
+ attr_reader :name
8
+
9
+ def initializer list
10
+ @list = list
11
+ end
12
+
13
+ def << *partials
14
+ @list ||= []
15
+ partials.flatten.each do |partial_name|
16
+ partial = Partializer::Partial.new(path, partial_name)
17
+ @list << partial
18
+ end
19
+ end
20
+
21
+ alias_method :path, :name
22
+
23
+ def to_partial_path
24
+ path.gsub('.', '/')
25
+ end
26
+
27
+ def list
28
+ @list ||= []
29
+ end
30
+
31
+ def each &block
32
+ list.each {|item| yield item.name }
33
+ end
34
+
35
+ def set_context ns, action
36
+ list.each {|p| p.send :set_context, ns, action }
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,52 @@
1
+ class Partializer
2
+ module Resolver
3
+ def create_partializer name
4
+ context = self.kind_of?(Class) ? self : self.class
5
+ clazz = "#{context.name}::#{name.to_s.camelize}".constantize
6
+ clazz.new
7
+ end
8
+
9
+ def resolve arg
10
+ case arg
11
+ when Hash
12
+ resolve_hash(arg)
13
+ when String, Symbol
14
+ resolve_sym(arg)
15
+ when Partializer::Collection
16
+ arg
17
+ else
18
+ raise ArgumentError, "Could not partialize: #{arg}"
19
+ end
20
+ end
21
+
22
+ def resolve_hash hash
23
+ Partializer::Collection.new 'hash', hash.keys, hash
24
+ end
25
+
26
+ # Creates a Collection from a Symbol
27
+ # :gallery
28
+ # gallery -> :gallery
29
+ # partials: [:gallery]
30
+ def resolve_sym arg
31
+ value = resolve_value arg
32
+ arg = arg.to_s.sub(/^_/, '')
33
+ if value.to_s == arg.to_s
34
+ Partializer::Collection.new 'sym', arg
35
+ else
36
+ Partializer::Collection.new 'sym', arg, {arg.to_sym => value}
37
+ end
38
+ end
39
+
40
+ # a Partializer or a sym!
41
+ def resolve_value arg
42
+ arg = arg.to_s
43
+ arg[0] == '_' ? resolve_partializer(arg) : arg.to_sym
44
+ end
45
+
46
+ def resolve_partializer arg
47
+ arg.sub!(/^_/, '')
48
+ instance = create_partializer(arg)
49
+ {instance.class.name.to_s.demodulize.underscore => instance.partials}
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,61 @@
1
+ class Partializer
2
+ module ViewHelper
3
+ def partialize subject, path, &block
4
+ parts = case subject
5
+ when String
6
+ subject.split('#')
7
+ when Partializer::Collection
8
+ [subject.ns, subject.action]
9
+ end
10
+
11
+ name = parts.first
12
+ action = parts.last
13
+ try_clazzes = [name.to_s.camelize, "Partializers::#{name.to_s.camelize}"]
14
+
15
+ clazz = try_clazzes.select do |clazz|
16
+ begin
17
+ clazz.constantize
18
+ rescue NameError
19
+ nil
20
+ end
21
+ end.first
22
+
23
+ unless clazz
24
+ raise ArgumentError, "No Partializer could be found for: #{subject} in: #{try_clazzes}"
25
+ end
26
+
27
+ instance = clazz.constantize.new
28
+ instance = instance.send(action)
29
+
30
+ path.split('.').each do |meth|
31
+ instance = instance.send(meth)
32
+ end
33
+ instance.set_context *parts
34
+ instance
35
+ end
36
+
37
+ def render_partials subject, options = {}
38
+ partials = case subject
39
+ when Partializer::Collection
40
+ subject.partials
41
+ else
42
+ subject
43
+ end
44
+
45
+ unless partials.kind_of? Partializer::Partials
46
+ raise ArgumentError, "Must be a Partializer::Collection or Partializer::Partials, was: #{collection}"
47
+ end
48
+
49
+ # make partializer available as object in partial called
50
+ locals_opts = {locals: {:partializer => subject}}.merge(options[:locals] || {})
51
+ options.merge! locals_opts
52
+
53
+ # render options.merge(:partial => partials)
54
+ partials.list.inject("") do |res, partial|
55
+ opts = {:partial => partial.to_partial_path}.merge(options)
56
+ res += raw(render opts)
57
+ # res += "#{opts.inspect} ------- "
58
+ end.html_safe
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,80 @@
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 = "partializer"
8
+ s.version = "0.1.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Kristian Mandrup"]
12
+ s.date = "2012-08-29"
13
+ s.description = "Makes it easy to render the subpartials of any partial"
14
+ s.email = "kmandrup@gmail.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "LICENSE.txt",
25
+ "README.md",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "lib/partializer.rb",
29
+ "lib/partializer/collection.rb",
30
+ "lib/partializer/engine.rb",
31
+ "lib/partializer/partial.rb",
32
+ "lib/partializer/partials.rb",
33
+ "lib/partializer/resolver.rb",
34
+ "lib/partializer/view_helper.rb",
35
+ "partializer.gemspec",
36
+ "spec/partializer/collection_spec.rb",
37
+ "spec/partializer/partial_spec.rb",
38
+ "spec/partializer/resolver_spec.rb",
39
+ "spec/partializer/view_helper_spec.rb",
40
+ "spec/partializer_spec.rb",
41
+ "spec/spec_helper.rb",
42
+ "spec/support/properties.rb"
43
+ ]
44
+ s.homepage = "http://github.com/kristianmandrup/partializer"
45
+ s.licenses = ["MIT"]
46
+ s.require_paths = ["lib"]
47
+ s.rubygems_version = "1.8.24"
48
+ s.summary = "Partialize your Rails partials for easy management and rendering"
49
+
50
+ if s.respond_to? :specification_version then
51
+ s.specification_version = 3
52
+
53
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
54
+ s.add_runtime_dependency(%q<hashie>, [">= 0"])
55
+ s.add_runtime_dependency(%q<rails>, [">= 3.0.0"])
56
+ s.add_development_dependency(%q<rspec>, [">= 2.8.0"])
57
+ s.add_development_dependency(%q<rdoc>, [">= 3.12"])
58
+ s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
59
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
60
+ s.add_development_dependency(%q<simplecov>, [">= 0.5"])
61
+ else
62
+ s.add_dependency(%q<hashie>, [">= 0"])
63
+ s.add_dependency(%q<rails>, [">= 3.0.0"])
64
+ s.add_dependency(%q<rspec>, [">= 2.8.0"])
65
+ s.add_dependency(%q<rdoc>, [">= 3.12"])
66
+ s.add_dependency(%q<bundler>, [">= 1.0.0"])
67
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
68
+ s.add_dependency(%q<simplecov>, [">= 0.5"])
69
+ end
70
+ else
71
+ s.add_dependency(%q<hashie>, [">= 0"])
72
+ s.add_dependency(%q<rails>, [">= 3.0.0"])
73
+ s.add_dependency(%q<rspec>, [">= 2.8.0"])
74
+ s.add_dependency(%q<rdoc>, [">= 3.12"])
75
+ s.add_dependency(%q<bundler>, [">= 1.0.0"])
76
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
77
+ s.add_dependency(%q<simplecov>, [">= 0.5"])
78
+ end
79
+ end
80
+
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe Partializer::Collection do
4
+ include Partializer::Resolver
5
+
6
+ let(:clazz) { Partializer::Collection }
7
+
8
+ describe '#initialize' do
9
+ subject { clazz.new 'hash', hash.keys, hash }
10
+
11
+ let(:args) { [{upper: :gallery}, :lower] }
12
+
13
+ let(:hash) do
14
+ args.flatten.inject({}) do |res, arg|
15
+ key = arg.kind_of?(Hash) ? arg.keys.first : arg
16
+ res[key.to_sym] = resolve(arg)
17
+ res
18
+ end
19
+ end
20
+
21
+ specify do
22
+ subject.name.should == 'hash'
23
+ end
24
+
25
+ specify do
26
+ subject.partials.should be_a Partializer::Partials
27
+ end
28
+
29
+ specify do
30
+ subject.partials.should include(:upper)
31
+ end
32
+
33
+ specify do
34
+ subject.upper.partials.should include(:gallery)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Partializer::Partial do
4
+ subject { clazz.new 'main', 'lower'}
5
+
6
+ let(:clazz) { Partializer::Partial }
7
+
8
+ describe '#initialize' do
9
+ its(:view_path) { should == 'main/lower'}
10
+ end
11
+
12
+ describe '#path=' do
13
+ before :all do
14
+ subject.path = 'go'
15
+ end
16
+
17
+ its(:view_path) { should == 'go/lower'}
18
+ end
19
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ class Resolve
4
+ include Partializer::Resolver
5
+ end
6
+
7
+ describe Partializer::Resolver do
8
+ subject { Resolve.new }
9
+
10
+ describe '#resolve_sym' do
11
+ specify do
12
+ subject.resolve_sym(:gallery).partials.should include(:gallery)
13
+ end
14
+
15
+ specify do
16
+ expect { subject.resolve_sym(:gallery).gallery }.to raise_error
17
+ end
18
+ end
19
+
20
+ describe '#resolve_hash' do
21
+ let(:hash) do
22
+ {:com => :gallery}
23
+ end
24
+
25
+ specify do
26
+ subject.resolve_hash(hash).partials.should include(:com)
27
+ end
28
+
29
+ specify do
30
+ subject.resolve_hash(hash).com.partials.should include(:gallery)
31
+ end
32
+ end
33
+
34
+ # describe '#resolve' do
35
+ # describe 'hash' do
36
+ # let(:hash) do
37
+ # {:com => :gallery}
38
+ # end
39
+
40
+ # specify do
41
+ # subject.resolve(hash).partials.should include(:com)
42
+ # end
43
+
44
+ # specify do
45
+ # subject.resolve(hash).com.partials.should include(:gallery)
46
+ # end
47
+ # end
48
+
49
+ # describe 'symbol' do
50
+ # specify do
51
+ # subject.resolve(:gallery).partials.should include(:gallery)
52
+ # end
53
+
54
+ # specify do
55
+ # expect { subject.resolve(:gallery).gallery }.to raise_error
56
+ # end
57
+ # end
58
+ # end
59
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe Partializer::ViewHelper do
4
+ include Partializer::ViewHelper
5
+
6
+ let(:main_partializer) { partialize('properties#show', 'main') }
7
+ let(:my_main_partializer) { partialize('properties#show', 'my_main') }
8
+
9
+ describe '#initialize' do
10
+ subject { main_partializer }
11
+
12
+ its(:name) { should == 'main'}
13
+ its(:path) { should == 'properties/show/main' }
14
+ its(:to_partial_path) { should == 'properties/show/main' }
15
+
16
+ specify do
17
+ subject.partials.should include(:upper, :lower)
18
+ end
19
+
20
+ # see view_helper.rb: res += "#{partial.view_path}:"
21
+ specify do
22
+ # puts render_partials(subject)
23
+ render_partials(subject).should match /main\/upper/
24
+ end
25
+ end
26
+
27
+ describe 'nested partializing' do
28
+ subject { partialize my_main_partializer, 'lower'}
29
+
30
+ its(:name) { should == 'my_main.lower'}
31
+ its(:path) { should == 'properties/show/my_main/lower' }
32
+ end
33
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe Partializer do
4
+ subject { properties }
5
+
6
+ its(:show) { should be_a Partializers::Properties::Show }
7
+
8
+ let(:properties) { Partializers::Properties.new }
9
+
10
+ describe 'show' do
11
+ subject { properties.show }
12
+
13
+ specify do
14
+ subject.side.partials.should include(:basic_info)
15
+ end
16
+
17
+ specify do
18
+ subject.main.partials.should include(:upper, :lower)
19
+ end
20
+
21
+ specify do
22
+ subject.main.upper.partials.should include(:gallery)
23
+ subject.main.upper.name.should == 'main.upper'
24
+ end
25
+
26
+ specify do
27
+ subject.main.lower.partials.should include(:lower)
28
+ subject.main.lower.name.should == 'main.lower'
29
+ end
30
+
31
+ specify do
32
+ subject.my_main.lower.partials.should include(:description)
33
+ end
34
+
35
+ specify do
36
+ subject.my_main.lower.communication.partials.should include(:profile)
37
+ subject.my_main.lower.communication.name.should == 'my_main.lower.communication'
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,10 @@
1
+ require 'rspec'
2
+ require 'partializer'
3
+
4
+ # Requires supporting files with custom matchers and macros, etc,
5
+ # in ./support/ and its subdirectories.
6
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
7
+
8
+ RSpec.configure do |config|
9
+
10
+ end
@@ -0,0 +1,19 @@
1
+ module Partializers
2
+ class Properties < Partializer
3
+ class Show < Partializer
4
+ partials_for :main, [{upper: :gallery}, :lower]
5
+
6
+ partials_for :side, [:basic_info, :cost, :more_info, :period, :similar_properties]
7
+
8
+ partializer :lower do
9
+ partializer :communication do
10
+ partialize :profile, :contact_requests, :social, :favorite, :priority_subscription, :free_subscription, :comments
11
+ end
12
+
13
+ partialize :_communication, :description
14
+ end
15
+
16
+ partials_for :my_main, [{upper: :gallery}, :_lower]
17
+ end
18
+ end
19
+ end
metadata ADDED
@@ -0,0 +1,185 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: partializer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Kristian Mandrup
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-29 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: hashie
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rails
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 3.0.0
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 3.0.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: 2.8.0
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 2.8.0
62
+ - !ruby/object:Gem::Dependency
63
+ name: rdoc
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '3.12'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '3.12'
78
+ - !ruby/object:Gem::Dependency
79
+ name: bundler
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: 1.0.0
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: 1.0.0
94
+ - !ruby/object:Gem::Dependency
95
+ name: jeweler
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: 1.8.4
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 1.8.4
110
+ - !ruby/object:Gem::Dependency
111
+ name: simplecov
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0.5'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0.5'
126
+ description: Makes it easy to render the subpartials of any partial
127
+ email: kmandrup@gmail.com
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files:
131
+ - LICENSE.txt
132
+ - README.md
133
+ files:
134
+ - .document
135
+ - .rspec
136
+ - Gemfile
137
+ - Gemfile.lock
138
+ - LICENSE.txt
139
+ - README.md
140
+ - Rakefile
141
+ - VERSION
142
+ - lib/partializer.rb
143
+ - lib/partializer/collection.rb
144
+ - lib/partializer/engine.rb
145
+ - lib/partializer/partial.rb
146
+ - lib/partializer/partials.rb
147
+ - lib/partializer/resolver.rb
148
+ - lib/partializer/view_helper.rb
149
+ - partializer.gemspec
150
+ - spec/partializer/collection_spec.rb
151
+ - spec/partializer/partial_spec.rb
152
+ - spec/partializer/resolver_spec.rb
153
+ - spec/partializer/view_helper_spec.rb
154
+ - spec/partializer_spec.rb
155
+ - spec/spec_helper.rb
156
+ - spec/support/properties.rb
157
+ homepage: http://github.com/kristianmandrup/partializer
158
+ licenses:
159
+ - MIT
160
+ post_install_message:
161
+ rdoc_options: []
162
+ require_paths:
163
+ - lib
164
+ required_ruby_version: !ruby/object:Gem::Requirement
165
+ none: false
166
+ requirements:
167
+ - - ! '>='
168
+ - !ruby/object:Gem::Version
169
+ version: '0'
170
+ segments:
171
+ - 0
172
+ hash: 3003520417573953991
173
+ required_rubygems_version: !ruby/object:Gem::Requirement
174
+ none: false
175
+ requirements:
176
+ - - ! '>='
177
+ - !ruby/object:Gem::Version
178
+ version: '0'
179
+ requirements: []
180
+ rubyforge_project:
181
+ rubygems_version: 1.8.24
182
+ signing_key:
183
+ specification_version: 3
184
+ summary: Partialize your Rails partials for easy management and rendering
185
+ test_files: []