campo 0.3.4 → 0.9.0

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/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