campo 0.3.4 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ # Rakefile
2
+
3
+ desc "(Re-) generate documentation and place it in the docs/ dir. Open the index.html file in there to read it."
4
+ task :docs => :"docs:yard"
5
+ namespace :docs do
6
+ require 'yard'
7
+ YARD::Rake::YardocTask.new do |t|
8
+ t.files = ['lib/**/*.rb', 'app/*.rb', 'models/*.rb']
9
+ t.options = ['-odocs/'] # optional
10
+ end
11
+ end
data/campo.gemspec CHANGED
@@ -15,9 +15,10 @@ Gem::Specification.new do |s|
15
15
  s.required_ruby_version = ">= 1.9.2"
16
16
  s.authors = ["Iain Barnett"]
17
17
  s.files = `git ls-files`.split("\n")
18
- s.add_dependency("haml", "~> 3.1.1")
19
- s.email = ["iainspeed @nospam@ gmail.com"]
18
+ s.add_development_dependency("haml", "~> 3.1.1")
19
+ s.add_development_dependency("yard")
20
+ s.add_development_dependency("rake")
21
+ s.homepage = "https://github.com/yb66/Campo"
22
+ s.email = "iainspeed @nospam@ gmail.com"
20
23
  s.test_files = `git ls-files -- {test,spec,features}`.split("\n")
21
- s.signing_key = ENV['HOME'] + '/.ssh/gem-private_key.pem'
22
- s.cert_chain = [ENV['HOME'] + '/.ssh/gem-public_cert.pem']
23
24
  end
data/lib/campo.rb CHANGED
@@ -1,529 +1,12 @@
1
1
  # encoding: UTF-8
2
2
 
3
- module Campo
4
- module Childish
5
- def push=( child )
6
- @fields << child
7
- child.parent = self
8
- self
9
- end
10
3
 
11
- alias :<< :push=
12
-
13
- attr_accessor :parent
14
- end # Childish
15
-
16
- module Iding
17
- def id_tag( val )
18
- val.nil? ? "" : "_#{val}"
19
- end
20
- end # Iding
21
-
22
- module Convenience
23
-
24
-
25
- # @param [optional, Hash] attributes Any attributes you wish to add to the haml element.
26
- # @example Fieldset as a block is easiest to read
27
- # form.fieldset("Your details") do |f|
28
- # f.text( "full_name", size: 60 )
29
- # f.text( "dob", "Date of birth: ", size: 8 )
30
- # end
31
- def fieldset( text, attributes={}, &block )
32
- fieldset = (Fieldset.new(attributes) << Legend.new( text ))
33
- block.call( fieldset ) if block
34
- self << fieldset
35
- fieldset
36
- end
37
-
38
- # @example Add a bit of code to the markup
39
- # form.bit_of_ruby( "= 5 + 1" ) }
40
- def bit_of_ruby( *args, &block )
41
- tag = Campo::Haml_Ruby_Insert.new( *args, &block )
42
- self << tag
43
- tag
44
- end
4
+ require_relative "./campo/plugins.rb"
5
+ require_relative "./campo/plugins/partial.rb"
6
+ require_relative "./campo/plugins/jqueryvalidation.rb"
7
+ require_relative "./campo/plugins/aria.rb"
45
8
 
46
- alias :haml_ruby_insert :bit_of_ruby
9
+ require_relative "./campo/campo.rb"
47
10
 
48
- # @example Output a literal string
49
- # form.literal %Q!%p= "This is a paragraph "!
50
- def literal( *args, &block )
51
- tag = Campo::Literal.new( *args, &block )
52
- self << tag
53
- tag
54
- end
55
-
56
- # @example
57
- # # Select with a block of options
58
- # f.select("teas") do |s|
59
- # s.with_default
60
- # s.option("ceylon")
61
- # s.option("breakfast")
62
- # s.option("earl grey")
63
- # s.option("oolong")
64
- # s.option("sencha")
65
- # end.labelled("Favourite tea:")
66
- #
67
- # # Select using chain of options
68
- # form.select("bands").option("Suede").option("Blur").option("Oasis").option("Echobelly").option("Pulp").option("Supergrass").with_default.labelled("Favourite band:")
69
- #
70
- # @see Select
71
- def select( *args, &block )
72
- select = Campo::Select.new( *args, &block )
73
- self << select
74
- select
75
- end
76
-
77
- # Add an input with type of text
78
- # @param [String] name The name html attribute.
79
- # @param [optional, String, nil] label Give the label a name. Defaults to a capitalised name with _ replaced by spaces.
80
- # @param [optional, Hash] attributes Any attributes you wish to add to the haml element.
81
- # @example
82
- # f.text "full_name", size: 60
83
- # f.text "dob", "Date of birth: ", size: 8
84
- # @return [Input]
85
- # With the attribute `type=text`
86
- def text( name, label=nil, attributes={} )
87
- input( name, :text, label, attributes )
88
- end
89
-
90
-
91
- # @param (see #text)
92
- def password( name, label=nil, attributes={} )
93
- input( name, :password, label, attributes )
94
- end
95
-
96
-
97
- # @param (see #text)
98
- def radio( name, label=nil, attributes={} )
99
- input( name, :radio, label, attributes )
100
- end
101
-
102
- # @param (see #text)
103
- def checkbox( name, label=nil, attributes={} )
104
- input( name, :checkbox, label, attributes )
105
- end
106
-
107
-
108
- # @param (see #text)
109
- # @param [:symbol] type The type html attribute.
110
- def input( name, type, label=nil, attributes={} )
111
- if label.kind_of? Hash
112
- attributes = label
113
- label = nil
114
- end
115
-
116
- field = Campo::Input.new( name, type, attributes ).labelled( label )
117
- self << field
118
- field
119
- end
120
-
121
- # @param [optional,String] name
122
- # @param [optional, Hash] attributes Any attributes you wish to add to the haml element.
123
- def submit( name="Submit", label_inner=nil, attributes={} )
124
- submit = Campo::Input.new( name, :submit, {value: name}.merge(attributes) )
125
- self << submit
126
- submit
127
- end
128
-
129
-
130
- def textarea( *args, &block )
131
- textarea = Campo::Textarea.new( *args )
132
- self << textarea
133
- textarea
134
- end
135
- end # Convenience
136
-
137
- module Helpers
138
-
139
-
140
- # [ [id, lookup, selected || false], ... ]
141
- def self.options_builder( name, opts )
142
- return [] if opts.nil? || opts.empty?
143
-
144
- if opts.respond_to? :each_pair
145
- opts.map do |id, (inner, selected, atts)|
146
- Campo::Option.new( name, id, inner, selected, atts )
147
- end
148
- else
149
- opts.map do |id, inner, selected, atts|
150
- Campo::Option.new( name, id, inner, selected, atts )
151
- end
152
- end
153
- end # def
154
-
155
-
156
- def self.options_outputter( opts=[] )
157
- return "" if opts.nil? || opts.empty?
158
- opts.map{|o| "#{o.output}\n" }.reduce(:+)
159
- end
160
- end # Helpers
161
-
162
- @atts = {}
163
-
164
- class << self
165
- attr_accessor :atts
166
- end
167
-
168
- class Base
169
- include Childish
170
- include Iding
171
- include Convenience
172
-
173
- DEFAULT = { tabindex: nil }
174
-
175
- attr_accessor :attributes, :fields
176
-
177
- def initialize( name, attributes={}, &block )
178
- @attributes = DEFAULT.merge( attributes.merge({name: name}) ).reject{|k,v| v.nil? }
179
- @fields = []
180
- block.call( self ) if block
181
- self
182
- end
183
-
184
- def on_output( &block )
185
- @output_listener = block
186
- end
187
-
188
- def output( n=0, tab=2 )
189
- @output_listener.call n, tab
190
- end
191
-
192
- def labelled( inner=nil )
193
- inner ||= self.attributes[:name].gsub("_"," ").capitalize
194
- parent = self.parent
195
- label = Label.new( %Q!#{@attributes[:name] + id_tag(@attributes[:value]).gsub(/\W/, "_")}!, inner ) << self
196
- retval = if parent.nil?
197
- label
198
- else
199
- parent.fields.delete self
200
- parent << label
201
- label
202
- end
203
-
204
- retval
205
- end # labelled
206
-
207
- def self.unhash( hash, skip=nil )
208
- hash.reject{|k,v| v.nil? }.reject{|k,v| k.to_sym == skip.to_sym unless skip.nil? }.reduce(""){|mem, (k,v)| mem + %Q!#{k}: #{Base.quotable(v)}, !}
209
- end
210
-
211
- # if the string provided begins with a double quote but does not end in one, make it an unquoted string on output
212
- # else, wrap it in quotes
213
- def self.quotable( s )
214
- retval = if s.respond_to?(:start_with?) && s.start_with?( %Q!"! ) &! s.end_with?( %Q!"! )
215
- s[1.. -1] # chop the first character
216
- else
217
- %Q!"#{s}"! # wrap
218
- end
219
- end
220
-
221
-
222
- def self.output( top, so_far="", count=0, tab=2 )
223
- so_far << "#{top.output( count, tab )}\n"
224
- count += 1
225
- if top.respond_to?( :fields ) && top.fields.length >= 1
226
- top.fields.each do |field|
227
- so_far = Base.output( field, so_far, count, tab )
228
- end
229
- end
230
-
231
- so_far
232
- end
233
-
234
- end # Base
235
-
236
- # @see Convenience#literal
237
- def self.literal( *args, &block )
238
- Campo::Literal.new( *args, &block )
239
- end
240
-
241
- # Pass anything but the form for the first argument to *not* have the local variable defaults added to the top
242
- # @example
243
- # Campo.output form # would add the default locals
244
- # # these won't
245
- # Campo.output :partial, input_field
246
- # Campo.output false, label
247
- # Campo.output true, fieldset
248
- def self.output( *args )
249
- s = <<STR
250
- - atts = {} if atts.nil?
251
- - atts.default = {} if atts.default.nil?
252
- - inners = {} if inners.nil?
253
- - inners.default = "" if inners.default.nil?
254
- - i = 0 # for tabindex
255
-
256
- STR
257
-
258
-
259
- # default to true
260
- whole_form = if args.first.kind_of? Campo::Base
261
- true
262
- else
263
- args.shift
264
- false
265
- end
266
-
267
- output = Base.output( *args )
268
- output = s + output if whole_form
269
- output
270
- end # self.output
271
-
272
- # end Campo methods
273
-
274
-
275
-
276
- class Form < Base
277
- DEFAULT = { method: "POST" }
278
-
279
- # @param [String] name The form's name (html) attribute.
280
- # @param [optional, Hash] attributes Html attributes. They can be anything you like. Defaults follow:
281
- # @option attributes [String] :method ("POST")
282
- # @example
283
- # form = Campo::Form.new "example", "/path/to/post/to/" do |form|
284
- # form.text "first_field"
285
- # #... more fields follow
286
- # end
287
- def initialize(name, attributes={} )
288
- attributes[:id] = name.gsub(/\W/, "_") if attributes[:id].nil?
289
- super( name, DEFAULT.merge( attributes ) )
290
- self.on_output do |n=0, tab=2|
291
- %Q!#{" " * n * tab}%form{ atts[:#{name.gsub(/\W/, "_").downcase}], #{Base.unhash( @attributes )} }!
292
- end
293
-
294
- self
295
- end
296
-
297
-
298
- end # Form
299
-
300
- # Generally, the first method you'll call.
301
- # @example
302
- # # Form with a block
303
- # form = Campo.form "form1", action: "/go/for/it/" do |f|
304
- # f.text "Hello"
305
- # #... more fields follow
306
- # end
307
- #
308
- # @param [String] name The form's name (html) attribute.
309
- # @param [optional, Hash] attributes Html attributes. They can be anything you like. Defaults follow:
310
- # @option attributes [String] :method ("POST") The method attribute for the form.
311
- # @see Form#initialize
312
- def self.form( name, attributes={}, &block )
313
- Form.new( name, attributes, &block )
314
- end
315
-
316
-
317
- class Haml_Ruby_Insert < Base
318
- def initialize( s )
319
- raise ArgumentError, "you may only pass a string to Haml_Ruby_Insert/bit_of_ruby" unless s.kind_of?( String )
320
- super( nil ) # no name needed
321
- @s = s.start_with?( '=' ) ? s : "= " + s.to_s
322
-
323
- self.on_output do |n=0, tab=2|
324
- (" " * n * tab) + @s
325
- end
326
- end
327
- end # Haml_Ruby_Insert
328
-
329
-
330
- # add whatever you need to with a literal
331
- class Literal < Base
332
- def initialize( s )
333
- super( nil ) # no name needed
334
- @s = s
335
-
336
- self.on_output do |n=0, tab=2|
337
- (" " * n * tab) + @s
338
- end
339
- self
340
- end
341
- end # Literal
342
-
343
- class Select < Base
344
- def initialize( name, params={} )
345
- opts = params[:opts] || []
346
- attributes = params[:attributes] || {}
347
- haml_insert = params[:haml_insert] || nil
348
-
349
- super( name, { tabindex: %q!#{i += 1}! }.merge(attributes) )
350
-
351
- self.on_output do |n=0, tab=2|
352
- %Q!#{" " * n * tab}%select{ atts[:#{name.gsub(/\W/, "_").downcase}], #{Base.unhash( @attributes )} }!
353
- end
354
-
355
- self.fields += Helpers.options_builder( name, opts ) unless opts.nil? || opts.empty?
356
-
357
- self.fields << Haml_Ruby_Insert.new( haml_insert ) unless haml_insert.nil?
358
-
359
-
360
- self
361
- end # initialize
362
-
363
- # @example (see Convenience#select)
364
- def option( *args )
365
- value = args.shift
366
- inner = args.shift
367
- selected, attributes = *args
368
- inner = value.capitalize if inner.nil?
369
- self << Campo::Option.new( @attributes[:name], value, inner, selected, attributes )
370
- self
371
- end
372
-
373
-
374
- # @example
375
- # As a default:
376
- # form.select("teas").with_default.option("ceylon")
377
- # # output:
378
- # %select{ atts[:teas], tabindex: "#{i += 1}", name: "teas", }
379
- # %option{ value: "", disabled: "disabled", name: "teas", }Choose one:
380
- # %option{ atts[:teas_ceylon], value: "ceylon", id: "teas_ceylon", name: "teas", }Ceylon
381
- #
382
- # form.select("teas").with_default("My fave tea is:").option("ceylon")
383
- # # output:
384
- # %select{ atts[:teas], tabindex: "#{i += 1}", name: "teas", }
385
- # %option{ value: "", disabled: "disabled", name: "teas", }My fave tea is:
386
- # %option{ atts[:teas_ceylon], value: "ceylon", id: "teas_ceylon", name: "teas", }Ceylon
387
- def with_default( inner="Choose one:" )
388
- self.fields.unshift Campo::Option.new( @attributes[:name], "", inner , nil, {disabled: "disabled" } )
389
- self
390
- end
391
-
392
- # def mark_as_selected( val )
393
- # fields.find {|field| field.value == val }.selected = {selected: "selected"}
394
- # end
395
- end # Select
396
-
397
-
398
- class Option < Base
399
-
400
- # @param [String] name
401
- # @param [String] value
402
- def initialize( name, value, inner=nil, selected=nil, attributes={} )
403
- unless inner.nil? || inner.kind_of?( String )
404
- attributes = selected
405
- selected = inner
406
- inner = nil
407
- end
408
-
409
- unless selected.nil? || selected.kind_of?( TrueClass )
410
- if selected.respond_to? :each_pair
411
- attributes = selected
412
- selected = nil
413
- else
414
- selected = true
415
- @selected = true
416
- end
417
- end
418
-
419
- attributes ||= {}
420
-
421
- @inner = (inner || value.gsub("_"," ").capitalize)
422
-
423
- attributes = { id: "#{(name.gsub(/\W/, "_") + id_tag(value).gsub(/\W/, "_")).downcase}" }.merge(attributes) unless value.nil? || value.to_s.empty?
424
-
425
- super( name, {
426
- value: value,
427
- selected: (selected ? "selected" : nil)
428
- }.merge( attributes ) )
429
-
430
- atts_string = "atts[:#{@attributes[:id]}]," unless @attributes[:id].nil?
431
-
432
- self.on_output do |n=0, tab=2|
433
- %Q!#{" " * n * tab}%option{ #{atts_string} #{Base.unhash( @attributes )} }#{@inner}!
434
- end
435
-
436
- end #initialize
437
- end # Option
438
-
439
-
440
- # form << Campo::Input.new( "submit", :submit )
441
- class Input < Base
442
-
443
- #{ type: nil, value: nil, name: nil }
444
- #{ size: nil, maxlength: nil, type: "text" }
445
- #{ size: nil, maxlength: nil, type: "hidden" }
446
- #{ type: "submit" }
447
- def initialize( name, type=:text, attributes={} )
448
- super( name,
449
- { type: type.to_s,
450
- id: "#{name}#{id_tag(attributes[:value]).gsub(/\W/, "_")}",
451
- tabindex: %q!#{i += 1}!,
452
- }.merge( attributes ) )
453
-
454
-
455
- @attributes.delete(:name) if type == :submit
456
-
457
- self.on_output do |n=0, tab=2|
458
- %Q!#{" " * n * tab}%input{ atts[:#{name.gsub(/\W/, "_")}#{id_tag(attributes[:value]).gsub(/\W/, "_")}], #{Base.unhash( @attributes )} }!
459
- end
460
- end
461
- end
462
-
463
- class Fieldset < Base
464
-
465
- def initialize( attributes={} )
466
- super( nil, attributes )
467
- @attributes.delete(:name)
468
-
469
- self.on_output do |n=0, tab=2|
470
- %Q!#{" " * n * tab}%fieldset{ #{Base.unhash( @attributes )} }!
471
- end
472
- end # initialize
473
- end # Fieldset
474
-
475
-
476
- class Legend < Base
477
-
478
- def initialize( inner, attributes={} )
479
- super( nil, attributes )
480
- @attributes.delete(:name)
481
- @inner = inner
482
-
483
- self.on_output do |n=0, tab=2|
484
- %Q!#{" " * n * tab}%legend{ #{Base.unhash( @attributes )} }#{@inner}!
485
- end
486
- end # initialize
487
- end # Fieldset
488
-
489
-
490
- class Label < Base
491
-
492
- DEFAULT = { for: nil }
493
-
494
- attr_reader :attributes, :fields
495
-
496
- def initialize( name, inner=nil, attributes={} )
497
- if inner.kind_of? Hash
498
- attributes = inner
499
- inner = nil
500
- end
501
- super( name, attributes )
502
-
503
- @inner = inner
504
-
505
- self.on_output do |n=0, tab=2|
506
- %Q!#{" " * n * tab}%label{ for: "#{@attributes[:name]}", #{Base.unhash( @attributes, :name )} }\n#{" " * (n + 1) * tab}#{@inner}!
507
- end
508
- end
509
-
510
- end # Label
511
-
512
-
513
- class Textarea < Base
514
- DEFAULT = { cols: 40, rows: 10, tabindex: %q!#{i += 1}! }
515
-
516
- def initialize( name, inner=nil, attributes={} )
517
- if inner.kind_of? Hash
518
- attributes = inner
519
- inner = nil
520
- end
521
- super( name, DEFAULT.merge( attributes ) )
522
- @inner = inner
523
- self.on_output do |n=0, tab=2|
524
- %Q!#{" " * n * tab}%textarea{ atts[:#{name.gsub(/\W/, "_")}], #{Base.unhash( @attributes )} }= inners[:#{name.gsub(/\W/, "_")}] !
525
- end
526
- end
527
- end # Textarea
528
-
529
- end
11
+ Campo.plugin :partial
12
+ Campo.plugin :Aria