representations 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.
- data/.document +5 -0
- data/LICENSE.txt +22 -0
- data/README.markdown +44 -0
- data/Rakefile +62 -0
- data/VERSION +1 -0
- data/init.rb +3 -0
- data/lib/representations.rb +203 -0
- data/lib/view_helpers.rb +9 -0
- data/rails/init.rb +2 -0
- data/representations.gemspec +48 -0
- metadata +69 -0
data/.document
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2009 Łukasz Piestrzeniewicz, Adam Sokolnicki
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
22
|
+
|
data/README.markdown
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# Resouce Representations
|
2
|
+
|
3
|
+
Rails helpers, including form builders are great to allow rapid development of applications and views.
|
4
|
+
|
5
|
+
They are procedural in nature and have hard time to adapt to complex models. They also live in a single namespace making it difficult to find which helpers apply to which models.
|
6
|
+
|
7
|
+
Resource representations change syntax to object oriented and model specific.
|
8
|
+
|
9
|
+
## Example usage
|
10
|
+
|
11
|
+
Rails helpers:
|
12
|
+
|
13
|
+
- form_for(user) do |f|
|
14
|
+
login:
|
15
|
+
= h(user.login)
|
16
|
+
= f.label(:email, "Email")
|
17
|
+
= f.text_field(:email)
|
18
|
+
- if user.profile
|
19
|
+
- fields_for(user.profile) do |p|
|
20
|
+
Full name:
|
21
|
+
= h(full_name(p))
|
22
|
+
= f.label(:first_name, "First name")
|
23
|
+
= f.text_field(:first_name)
|
24
|
+
= f.label(:last_name, "Last name")
|
25
|
+
= f.text_field(:last_name)
|
26
|
+
= f.radio_button(:eye_color, 'blue')
|
27
|
+
= f.label(:eye_color_blue, "Blue")
|
28
|
+
= f.submit("Submit")
|
29
|
+
|
30
|
+
Resource Representations
|
31
|
+
|
32
|
+
- r(user).form do
|
33
|
+
login:
|
34
|
+
= user.login
|
35
|
+
= user.email.label
|
36
|
+
= user.email.text_field
|
37
|
+
- user.profile do |p|
|
38
|
+
= full_name(p)
|
39
|
+
= p.first_name.label
|
40
|
+
= p.first_name.text_field
|
41
|
+
= p.last_name.label
|
42
|
+
= p.last_name.text_field
|
43
|
+
= p.eye_color.radio_button('blue')
|
44
|
+
= p.eye_color.radio_button_label('blue', 'Blue')
|
data/Rakefile
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gemspec|
|
7
|
+
gemspec.name = "representations"
|
8
|
+
gemspec.summary = "Changes syntax of rails helpers and form builders to object oriented and model specific"
|
9
|
+
gemspec.description = "Rails helpers, including form builders are great to allow rapid development of applications and views.
|
10
|
+
They are procedural in nature and have hard time to adapt to complex models. They also live in a single namespace making it difficult to find which helpers apply to which models.
|
11
|
+
Resource representations change syntax to object oriented and model specific."
|
12
|
+
gemspec.email = "skimos00@gmail.com"
|
13
|
+
gemspec.homepage = "http://github.com/bragi/representations"
|
14
|
+
gemspec.authors = ["Łukasz Piestrzeniewicz", "Adam Sokolnicki"]
|
15
|
+
gemspec.files = [
|
16
|
+
".document",
|
17
|
+
"LICENSE.txt",
|
18
|
+
"README.markdown",
|
19
|
+
"Rakefile",
|
20
|
+
"VERSION",
|
21
|
+
"init.rb",
|
22
|
+
"lib/representations.rb",
|
23
|
+
"lib/view_helpers.rb",
|
24
|
+
"rails/init.rb",
|
25
|
+
"representations.gemspec"
|
26
|
+
]
|
27
|
+
gemspec.test_files.exclude('spec/**/*')
|
28
|
+
end
|
29
|
+
Jeweler::GemcutterTasks.new
|
30
|
+
rescue LoadError
|
31
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
32
|
+
end
|
33
|
+
|
34
|
+
require 'spec/rake/spectask'
|
35
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
36
|
+
spec.libs << 'lib' << 'spec'
|
37
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
38
|
+
end
|
39
|
+
|
40
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
41
|
+
spec.libs << 'lib' << 'spec'
|
42
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
43
|
+
spec.rcov = true
|
44
|
+
end
|
45
|
+
|
46
|
+
task :spec => :check_dependencies
|
47
|
+
|
48
|
+
task :default => :spec
|
49
|
+
|
50
|
+
require 'rake/rdoctask'
|
51
|
+
Rake::RDocTask.new do |rdoc|
|
52
|
+
if File.exist?('VERSION')
|
53
|
+
version = File.read('VERSION')
|
54
|
+
else
|
55
|
+
version = ""
|
56
|
+
end
|
57
|
+
|
58
|
+
rdoc.rdoc_dir = 'rdoc'
|
59
|
+
rdoc.title = "representations #{version}"
|
60
|
+
rdoc.rdoc_files.include('README*')
|
61
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
62
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/init.rb
ADDED
@@ -0,0 +1,203 @@
|
|
1
|
+
module Representations
|
2
|
+
#Creates Representation for object passed as a paremeter, type of the representation
|
3
|
+
#depends on the type of the object
|
4
|
+
def representation_for(object, template, name=nil, parent=nil)
|
5
|
+
representation_class = if object.is_a?(ActiveRecord::Base)
|
6
|
+
ActiveRecordRepresentation
|
7
|
+
else
|
8
|
+
"Representations::#{object.class.to_s.demodulize}Representation".constantize rescue DefaultRepresentation
|
9
|
+
end
|
10
|
+
representation_class.new(object, template, name, parent)
|
11
|
+
end
|
12
|
+
|
13
|
+
module_function :representation_for
|
14
|
+
|
15
|
+
class Representation
|
16
|
+
|
17
|
+
#value - object for which the representation is created
|
18
|
+
#template - template view
|
19
|
+
#name - the actuall name of the method that was called on the parent object of the object that is initialize
|
20
|
+
def initialize(value, template, name=nil, parent=nil)
|
21
|
+
@value = value
|
22
|
+
@name = name
|
23
|
+
@template = template
|
24
|
+
@parent = parent
|
25
|
+
end
|
26
|
+
|
27
|
+
def id
|
28
|
+
@value
|
29
|
+
end
|
30
|
+
#returns escaped string from the object's to_s method
|
31
|
+
def to_s
|
32
|
+
ERB::Util::h(@value.to_s)
|
33
|
+
end
|
34
|
+
#Call the passed block (if any)
|
35
|
+
def with_block(&block)
|
36
|
+
yield self if block_given?
|
37
|
+
end
|
38
|
+
#returns html label tag for the representation
|
39
|
+
def label(value, html_options = {})
|
40
|
+
tree = get_parents_tree
|
41
|
+
for_attr_value = tree.join('_')
|
42
|
+
tags = get_tags(html_options, {:for => for_attr_value})
|
43
|
+
value = ERB::Util::h(@name.humanize) if value.nil?
|
44
|
+
%Q{<label #{tags}>#{value}</label>}
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
#returns array of Represantation objects which are linked together by @parent field
|
49
|
+
def get_parents_tree
|
50
|
+
children_names = Array.new
|
51
|
+
parent = @parent
|
52
|
+
children_names.push(@name)
|
53
|
+
while parent.nil? == false do #iterate parent tree
|
54
|
+
children_names.push(parent.instance_variable_get(:@name))
|
55
|
+
parent = parent.instance_variable_get(:@parent)
|
56
|
+
end #children_names now looks something like that [name, profile, user]
|
57
|
+
children_names.reverse
|
58
|
+
end
|
59
|
+
#creates value of the html name attribute according to passed tree of objects
|
60
|
+
def get_html_name_attribute_value(tree)
|
61
|
+
root_name = tree.delete_at(0)
|
62
|
+
name = Array.new
|
63
|
+
tree.each_index do |idx|
|
64
|
+
name[idx] = if idx < tree.length - 1
|
65
|
+
"[" + tree[idx] + "_attributes]"
|
66
|
+
else
|
67
|
+
"[" + tree[idx] + "]"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
name.unshift(root_name)
|
71
|
+
end
|
72
|
+
#Returns string of merged two hashes of html options passed as an argument
|
73
|
+
def get_tags(user_options, base_options)
|
74
|
+
base_options.merge!(user_options)
|
75
|
+
base_options.stringify_keys!
|
76
|
+
base_options.map{ |key, value| %(#{key}="#{value}" ) }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class DefaultRepresentation < Representation
|
81
|
+
|
82
|
+
#not tested in the view
|
83
|
+
#Returns string with html check box tag
|
84
|
+
def check_box(checked_value = "1", unchecked_value = "0", html_options = {})
|
85
|
+
tree = get_parents_tree
|
86
|
+
id_attr_value = tree.join('_')
|
87
|
+
name_attr_value = get_html_name_attribute_value(tree)
|
88
|
+
tags = get_tags(html_options, {:value => checked_value, :id => id_attr_value, :name=>name_attr_value})
|
89
|
+
%Q{<input type="checkbox" #{tags}/>\n<input type="hidden" value="#{unchecked_value}" id="#{id_attr_value}" name="#{name_attr_value}"/>}
|
90
|
+
end
|
91
|
+
#not tested in the view
|
92
|
+
#Returns string with html file field tag
|
93
|
+
def file_field(html_options = {})
|
94
|
+
tree = get_parents_tree
|
95
|
+
id_attr_value = tree.join('_')
|
96
|
+
tags = get_tags(html_options, {:value => to_s, :id => id_attr_value, :name=>get_html_name_attribute_value(tree)})
|
97
|
+
%Q{<input type="file" #{tags}/>}
|
98
|
+
end
|
99
|
+
#not tested in the view
|
100
|
+
#Returns string with html hidden input tag
|
101
|
+
def hidden_field(html_options = {})
|
102
|
+
tree = get_parents_tree
|
103
|
+
id_attr_value = tree.join('_')
|
104
|
+
tags = get_tags(html_options, {:value => to_s, :id => id_attr_value, :name=>get_html_name_attribute_value(tree)})
|
105
|
+
%Q{<input type="hidden" #{tags}/>}
|
106
|
+
end
|
107
|
+
#Returns string with html text input tag
|
108
|
+
def text_field(html_options = {})
|
109
|
+
tree = get_parents_tree
|
110
|
+
id_attr_value = tree.join('_')
|
111
|
+
tags = get_tags(html_options, {:value => to_s, :id => id_attr_value, :name=>get_html_name_attribute_value(tree)})
|
112
|
+
%Q{<input type="text" #{tags}/>}
|
113
|
+
end
|
114
|
+
#Returns string with html text area tag
|
115
|
+
def text_area(html_options = {})
|
116
|
+
tree = get_parents_tree
|
117
|
+
id_attr_value = tree.join('_')
|
118
|
+
tags = get_tags(html_options, {:id => id_attr_value, :name => get_html_name_attribute_value(tree)})
|
119
|
+
%Q{<textarea #{tags}>\n#{to_s}\n</textarea>}
|
120
|
+
end
|
121
|
+
#Returns string with html password tag
|
122
|
+
def password_field(html_options = {})
|
123
|
+
tree = get_parents_tree
|
124
|
+
id_attr_value = tree.join('_')
|
125
|
+
tags = get_tags(html_options, {:value => to_s, :id => id_attr_value, :name=>get_html_name_attribute_value(tree)})
|
126
|
+
%Q{<input type="password" #{tags}/>}
|
127
|
+
end
|
128
|
+
#Returns string with html radio button tag
|
129
|
+
def radio_button(value, html_options = {})
|
130
|
+
tree = get_parents_tree
|
131
|
+
id_attr_value = tree.join('_') + "_#{value}"
|
132
|
+
name_attr_value = get_html_name_attribute_value(tree)
|
133
|
+
tags = get_tags(html_options, {:name => name_attr_value, :value=>value, :id=>id_attr_value, :checked=>"#{@value.capitalize==value.capitalize}"})
|
134
|
+
%Q{<input type="radio" #{tags}/>}
|
135
|
+
end
|
136
|
+
#Returns string with html label tag with for attribute set to the radio button of this object
|
137
|
+
def radio_button_label(radio_button_value, value = nil, html_options = {})
|
138
|
+
tree = get_parents_tree
|
139
|
+
for_attr_value = tree.join('_') + "_#{radio_button_value}"
|
140
|
+
value = radio_button_value.capitalize if value.nil?
|
141
|
+
tags = get_tags(html_options, {:for => for_attr_value})
|
142
|
+
%Q{<label #{tags}>#{ERB::Util::h(value)}</label>}
|
143
|
+
end
|
144
|
+
end
|
145
|
+
#Representation for objects which are nil
|
146
|
+
class NilClassRepresentation < Representation
|
147
|
+
#Returns self so the calls:
|
148
|
+
#nil_object.not_defined_method.another_not_defined_method
|
149
|
+
#want raise an error
|
150
|
+
def method_missing(method_name, *args)
|
151
|
+
return self
|
152
|
+
end
|
153
|
+
#Passed block shouldn't be called
|
154
|
+
def with_block(&block)
|
155
|
+
end
|
156
|
+
#Returns blank string
|
157
|
+
def to_s
|
158
|
+
return ''
|
159
|
+
end
|
160
|
+
end
|
161
|
+
#Representation for ActiveRecord::Base object's
|
162
|
+
class ActiveRecordRepresentation < Representation
|
163
|
+
#Form builder
|
164
|
+
def form(&block)
|
165
|
+
raise "You need to provide block to form representation" unless block_given?
|
166
|
+
content = @template.capture(self, &block)
|
167
|
+
@template.concat(@template.form_tag(@value))
|
168
|
+
@template.concat(content)
|
169
|
+
@template.concat("</form>")
|
170
|
+
self
|
171
|
+
end
|
172
|
+
#Forwards ActiveRecord invocation and wraps result in apropriate Representation
|
173
|
+
#Suppose that User extends ActiveRecord::Base :
|
174
|
+
#ar_user = User.new
|
175
|
+
#ar_user.nick = 'foo'
|
176
|
+
#user = r(ar_user) #user is now ActiveRecordRepresentation
|
177
|
+
#user.nick.text_field #method_missing will be called on user with method_name = 'nick' in which new method for user will be created and will be called. The newly created method will create new DefaultRepresentation with @value set to the string 'foo'. Next the text_field will be called on the newly created DefauleRepresentation
|
178
|
+
#
|
179
|
+
def method_missing(method_name, *args, &block)
|
180
|
+
method = <<-EOF
|
181
|
+
def #{method_name}(*args, &block)
|
182
|
+
@__#{method_name} ||= Representations.representation_for(@value.#{method_name}, @template, "#{method_name}", self)
|
183
|
+
@__#{method_name}.with_block(&block)
|
184
|
+
@__#{method_name} if block.nil?
|
185
|
+
end
|
186
|
+
EOF
|
187
|
+
::Representations::ActiveRecordRepresentation.class_eval(method, __FILE__, __LINE__)
|
188
|
+
|
189
|
+
self.__send__(method_name, &block)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
#Representation for TimeWithZone object
|
193
|
+
class TimeWithZoneRepresentation < Representation
|
194
|
+
def select(passed_options = {}, html_options = {})
|
195
|
+
options = {:defaults => {:day => @value.day, :month => @value.month, :year => @value.year}}
|
196
|
+
options.merge!(passed_options)
|
197
|
+
tree = get_parents_tree
|
198
|
+
tree.pop
|
199
|
+
name = get_html_name_attribute_value(tree)
|
200
|
+
@template.date_select(name, @name, options, html_options)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
data/lib/view_helpers.rb
ADDED
data/rails/init.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
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{representations}
|
8
|
+
s.version = "0.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["\305\201ukasz Piestrzeniewicz", "Adam Sokolnicki"]
|
12
|
+
s.date = %q{2009-10-17}
|
13
|
+
s.description = %q{Rails helpers, including form builders are great to allow rapid development of applications and views.
|
14
|
+
They are procedural in nature and have hard time to adapt to complex models. They also live in a single namespace making it difficult to find which helpers apply to which models.
|
15
|
+
Resource representations change syntax to object oriented and model specific.}
|
16
|
+
s.email = %q{skimos00@gmail.com}
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE.txt",
|
19
|
+
"README.markdown"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".document",
|
23
|
+
"LICENSE.txt",
|
24
|
+
"README.markdown",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"init.rb",
|
28
|
+
"lib/representations.rb",
|
29
|
+
"lib/view_helpers.rb",
|
30
|
+
"rails/init.rb",
|
31
|
+
"representations.gemspec"
|
32
|
+
]
|
33
|
+
s.homepage = %q{http://github.com/bragi/representations}
|
34
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
35
|
+
s.require_paths = ["lib"]
|
36
|
+
s.rubygems_version = %q{1.3.5}
|
37
|
+
s.summary = %q{Changes syntax of rails helpers and form builders to object oriented and model specific}
|
38
|
+
|
39
|
+
if s.respond_to? :specification_version then
|
40
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
41
|
+
s.specification_version = 3
|
42
|
+
|
43
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
44
|
+
else
|
45
|
+
end
|
46
|
+
else
|
47
|
+
end
|
48
|
+
end
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: representations
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- "\xC5\x81ukasz Piestrzeniewicz"
|
8
|
+
- Adam Sokolnicki
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2009-10-17 00:00:00 +02:00
|
14
|
+
default_executable:
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: |-
|
18
|
+
Rails helpers, including form builders are great to allow rapid development of applications and views.
|
19
|
+
They are procedural in nature and have hard time to adapt to complex models. They also live in a single namespace making it difficult to find which helpers apply to which models.
|
20
|
+
Resource representations change syntax to object oriented and model specific.
|
21
|
+
email: skimos00@gmail.com
|
22
|
+
executables: []
|
23
|
+
|
24
|
+
extensions: []
|
25
|
+
|
26
|
+
extra_rdoc_files:
|
27
|
+
- LICENSE.txt
|
28
|
+
- README.markdown
|
29
|
+
files:
|
30
|
+
- .document
|
31
|
+
- LICENSE.txt
|
32
|
+
- README.markdown
|
33
|
+
- Rakefile
|
34
|
+
- VERSION
|
35
|
+
- init.rb
|
36
|
+
- lib/representations.rb
|
37
|
+
- lib/view_helpers.rb
|
38
|
+
- rails/init.rb
|
39
|
+
- representations.gemspec
|
40
|
+
has_rdoc: true
|
41
|
+
homepage: http://github.com/bragi/representations
|
42
|
+
licenses: []
|
43
|
+
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options:
|
46
|
+
- --charset=UTF-8
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "0"
|
60
|
+
version:
|
61
|
+
requirements: []
|
62
|
+
|
63
|
+
rubyforge_project:
|
64
|
+
rubygems_version: 1.3.5
|
65
|
+
signing_key:
|
66
|
+
specification_version: 3
|
67
|
+
summary: Changes syntax of rails helpers and form builders to object oriented and model specific
|
68
|
+
test_files: []
|
69
|
+
|