lperichon-formtastic 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,88 @@
1
+ # coding: utf-8
2
+ require 'rubygems'
3
+ require 'rake'
4
+ require 'rake/rdoctask'
5
+
6
+ gem 'rspec-rails', '>= 1.0.0'
7
+ require 'spec/rake/spectask'
8
+
9
+ begin
10
+ GEM = "formtastic"
11
+ AUTHOR = "Justin French / Luis Perichon"
12
+ EMAIL = "info@luisperichon.com.ar"
13
+ SUMMARY = "A Rails form builder plugin/gem with semantically rich and accessible markup"
14
+ HOMEPAGE = "http://github.com/lperichon/formtastic"
15
+ INSTALL_MESSAGE = %q{
16
+ ========================================================================
17
+
18
+ Thanks for installing Formtastic!
19
+
20
+ You can now (optionally) run the generater to copy some stylesheets and
21
+ a config initializer into your application:
22
+
23
+ ./script/generate formtastic
24
+
25
+ The following files will be added:
26
+
27
+ RAILS_ROOT/public/stylesheets/formtastic.css
28
+ RAILS_ROOT/public/stylesheets/formtastic_changes.css
29
+ RAILS_ROOT/config/initializers/formtastic.rb
30
+
31
+ Find out more and get involved:
32
+
33
+ http://github.com/justinfrench/formtastic
34
+ http://groups.google.com.au/group/formtastic
35
+
36
+ ========================================================================
37
+ }
38
+
39
+ gem 'jeweler', '>= 1.0.0'
40
+ require 'jeweler'
41
+
42
+ Jeweler::Tasks.new do |s|
43
+ s.name = GEM
44
+ s.summary = SUMMARY
45
+ s.email = EMAIL
46
+ s.homepage = HOMEPAGE
47
+ s.description = SUMMARY
48
+ s.author = AUTHOR
49
+ s.post_install_message = INSTALL_MESSAGE
50
+
51
+ s.require_path = 'lib'
52
+ s.autorequire = GEM
53
+ s.files = %w(MIT-LICENSE README.textile Rakefile) + Dir.glob("{rails,lib,generators,spec}/**/*")
54
+ end
55
+ rescue LoadError
56
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
57
+ end
58
+
59
+ desc 'Default: run unit specs.'
60
+ task :default => :spec
61
+
62
+ desc 'Test the formtastic plugin.'
63
+ Spec::Rake::SpecTask.new('spec') do |t|
64
+ t.spec_files = FileList['spec/**/*_spec.rb']
65
+ t.spec_opts = ["-c"]
66
+ end
67
+
68
+ desc 'Test the formtastic plugin with specdoc formatting and colors'
69
+ Spec::Rake::SpecTask.new('specdoc') do |t|
70
+ t.spec_files = FileList['spec/**/*_spec.rb']
71
+ t.spec_opts = ["--format specdoc", "-c"]
72
+ end
73
+
74
+ desc 'Generate documentation for the formtastic plugin.'
75
+ Rake::RDocTask.new(:rdoc) do |rdoc|
76
+ rdoc.rdoc_dir = 'rdoc'
77
+ rdoc.title = 'Formtastic'
78
+ rdoc.options << '--line-numbers' << '--inline-source'
79
+ rdoc.rdoc_files.include('README.textile')
80
+ rdoc.rdoc_files.include('lib/**/*.rb')
81
+ end
82
+
83
+ desc "Run all examples with RCov"
84
+ Spec::Rake::SpecTask.new('examples_with_rcov') do |t|
85
+ t.spec_files = FileList['spec/**/*_spec.rb']
86
+ t.rcov = true
87
+ t.rcov_opts = ['--exclude', 'spec,Library']
88
+ end
@@ -0,0 +1,15 @@
1
+ NAME
2
+ form - Formtastic form generator.
3
+
4
+ DESCRIPTION
5
+ Generates formtastic form code based on an existing model. By default the generated code will be printed out directly in the terminal, and also copied to clipboard. Can optionally be saved into partial directly.
6
+
7
+ Required:
8
+ ExistingModelName - The name of an existing model for which the generator should generate form code.
9
+
10
+ Options:
11
+ --haml Generate HAML instead of ERB.
12
+ --partial Generate a form partial in the model views path, i.e. "_form.html.erb" or _form.html.haml".
13
+
14
+ EXAMPLE
15
+ ./script/generate form ExistingModelName [--haml] [--partial]
@@ -0,0 +1,114 @@
1
+ # coding: utf-8
2
+ # Get current OS - needed for clipboard functionality
3
+ case RUBY_PLATFORM
4
+ when /darwin/ then
5
+ CURRENT_OS = :osx
6
+ when /win32/
7
+ CURRENT_OS = :win
8
+ begin
9
+ require 'win32/clipboard'
10
+ rescue LoadError
11
+ # Do nothing
12
+ end
13
+ else
14
+ CURRENT_OS = :x
15
+ end
16
+
17
+ class FormGenerator < Rails::Generator::NamedBase
18
+
19
+ default_options :haml => false,
20
+ :partial => false
21
+
22
+ VIEWS_PATH = File.join('app', 'views').freeze
23
+ IGNORED_COLUMNS = [:updated_at, :created_at].freeze
24
+
25
+ attr_reader :controller_file_name,
26
+ :controller_class_path,
27
+ :controller_class_nesting,
28
+ :controller_class_nesting_depth,
29
+ :controller_class_name,
30
+ :template_type
31
+
32
+ def initialize(runtime_args, runtime_options = {})
33
+ super
34
+ base_name, @controller_class_path = extract_modules(@name.pluralize)
35
+ controller_class_name_without_nesting, @controller_file_name = inflect_names(base_name)
36
+ @template_type = options[:haml] ? :haml : :erb
37
+ end
38
+
39
+ def manifest
40
+ record do |m|
41
+ if options[:partial]
42
+ # Ensure directory exists.
43
+ m.directory File.join(VIEWS_PATH, controller_class_path, controller_file_name)
44
+ # Create a form partial for the model as "_form" in it's views path.
45
+ m.template "view__form.html.#{template_type}", File.join(VIEWS_PATH, controller_file_name, "_form.html.#{template_type}")
46
+ else
47
+ # Load template file, and render without saving to file
48
+ template = File.read(File.join(source_root, "view__form.html.#{template_type}"))
49
+ erb = ERB.new(template, nil, '-')
50
+ generated_code = erb.result(binding).strip rescue nil
51
+
52
+ # Print the result, and copy to clipboard
53
+ puts "# ---------------------------------------------------------"
54
+ puts "# GENERATED FORMTASTIC CODE"
55
+ puts "# ---------------------------------------------------------"
56
+ puts
57
+ puts generated_code || " Nothing could be generated - model exists?"
58
+ puts
59
+ puts "# ---------------------------------------------------------"
60
+ puts " Copied to clipboard - just paste it!" if save_to_clipboard(generated_code)
61
+ end
62
+ end
63
+ end
64
+
65
+ protected
66
+
67
+ # Save to lipboard with multiple OS support.
68
+ def save_to_clipboard(data)
69
+ return unless data
70
+ begin
71
+ case CURRENT_OS
72
+ when :osx
73
+ `echo "#{data}" | pbcopy`
74
+ when :win
75
+ ::Win32::Clipboard.data = data
76
+ else # :linux/:unix
77
+ `echo "#{data}" | xsel --clipboard` || `echo "#{data}" | xclip`
78
+ end
79
+ rescue
80
+ false
81
+ else
82
+ true
83
+ end
84
+ end
85
+
86
+ # Add additional model attributes if specified in args - probably not that common scenario.
87
+ def attributes
88
+ # Get columns for the requested model
89
+ existing_attributes = @class_name.constantize.content_columns.reject { |column| IGNORED_COLUMNS.include?(column.name.to_sym) }
90
+ @args = super + existing_attributes
91
+ end
92
+
93
+ def add_options!(opt)
94
+ opt.separator ''
95
+ opt.separator 'Options:'
96
+
97
+ # Allow option to generate HAML views instead of ERB.
98
+ opt.on('--haml',
99
+ "Generate HAML output instead of the default ERB.") do |v|
100
+ options[:haml] = v
101
+ end
102
+
103
+ # Allow option to generate to partial in model's views path, instead of printing out in terminal.
104
+ opt.on('--partial',
105
+ "Save generated output directly to a form partial (app/views/{resource}/_form.html.*).") do |v|
106
+ options[:partial] = v
107
+ end
108
+ end
109
+
110
+ def banner
111
+ "Usage: #{$0} form ExistingModelName [--haml] [--partial]"
112
+ end
113
+
114
+ end
@@ -0,0 +1,5 @@
1
+ <%% form.inputs do %>
2
+ <% attributes.each do |attribute| -%>
3
+ <%%= form.input :<%= attribute.name %>, :label => '<%= attribute.name.humanize %>' %>
4
+ <% end -%>
5
+ <%% end %>
@@ -0,0 +1,4 @@
1
+ - form.inputs do
2
+ <% attributes.each do |attribute| -%>
3
+ = form.input :<%= attribute.name %>, :label => '<%= attribute.name.humanize %>'
4
+ <% end -%>
@@ -0,0 +1,24 @@
1
+ class FormtasticGenerator < Rails::Generator::Base
2
+
3
+ def initialize(*runtime_args)
4
+ super
5
+ end
6
+
7
+ def manifest
8
+ record do |m|
9
+ m.directory File.join('config', 'initializers')
10
+ m.template 'formtastic.rb', File.join('config', 'initializers', 'formtastic.rb')
11
+
12
+ m.directory File.join('public', 'stylesheets')
13
+ m.template 'formtastic.css', File.join('public', 'stylesheets', 'formtastic.css')
14
+ m.template 'formtastic_changes.css', File.join('public', 'stylesheets', 'formtastic_changes.css')
15
+ end
16
+ end
17
+
18
+ protected
19
+
20
+ def banner
21
+ %{Usage: #{$0} #{spec.name}\nCopies formtastic.css and formtastic_changes.css to public/stylesheets/ and a config initializer to config/initializers/formtastic.rb}
22
+ end
23
+
24
+ end
@@ -0,0 +1,137 @@
1
+ /* -------------------------------------------------------------------------------------------------
2
+
3
+ It's *strongly* suggested that you don't modify this file. Instead, load a new stylesheet after
4
+ this one in your layouts (eg formtastic_changes.css) and override the styles to suit your needs.
5
+ This will allow you to update formtastic.css with new releases without clobbering your own changes.
6
+
7
+ This stylesheet forms part of the Formtastic Rails Plugin
8
+ (c) 2008 Justin French
9
+
10
+ --------------------------------------------------------------------------------------------------*/
11
+
12
+
13
+ /* NORMALIZE AND RESET - obviously inspired by Yahoo's reset.css, but scoped to just form.formtastic
14
+ --------------------------------------------------------------------------------------------------*/
15
+ form.formtastic, form.formtastic ul, form.formtastic ol, form.formtastic li, form.formtastic fieldset, form.formtastic legend, form.formtastic input, form.formtastic textarea, form.formtastic select, form.formtastic p { margin:0; padding:0; }
16
+ form.formtastic fieldset { border:0; }
17
+ form.formtastic em, form.formtastic strong { font-style:normal; font-weight:normal; }
18
+ form.formtastic ol, form.formtastic ul { list-style:none; }
19
+ form.formtastic abbr, form.formtastic acronym { border:0; font-variant:normal; }
20
+ form.formtastic input, form.formtastic textarea, form.formtastic select { font-family:inherit; font-size:inherit; font-weight:inherit; }
21
+ form.formtastic input, form.formtastic textarea, form.formtastic select { font-size:100%; }
22
+ form.formtastic legend { color:#000; }
23
+
24
+
25
+ /* FIELDSETS & LISTS
26
+ --------------------------------------------------------------------------------------------------*/
27
+ form.formtastic fieldset { }
28
+ form.formtastic fieldset.inputs { }
29
+ form.formtastic fieldset.buttons { padding-left:25%; }
30
+ form.formtastic fieldset ol { }
31
+ form.formtastic fieldset.buttons li { float:left; padding-right:0.5em; }
32
+
33
+ /* clearfixing the fieldsets */
34
+ form.formtastic fieldset { display: inline-block; }
35
+ form.formtastic fieldset:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
36
+ html[xmlns] form.formtastic fieldset { display: block; }
37
+ * html form.formtastic fieldset { height: 1%; }
38
+
39
+
40
+ /* INPUT LIs
41
+ --------------------------------------------------------------------------------------------------*/
42
+ form.formtastic fieldset ol li { margin-bottom:1.5em; }
43
+
44
+ /* clearfixing the li's */
45
+ form.formtastic fieldset ol li { display: inline-block; }
46
+ form.formtastic fieldset ol li:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
47
+ html[xmlns] form.formtastic fieldset ol li { display: block; }
48
+ * html form.formtastic fieldset ol li { height: 1%; }
49
+
50
+ form.formtastic fieldset ol li.required { }
51
+ form.formtastic fieldset ol li.optional { }
52
+ form.formtastic fieldset ol li.error { }
53
+
54
+
55
+ /* LABELS
56
+ --------------------------------------------------------------------------------------------------*/
57
+ form.formtastic fieldset ol li label { display:block; width:25%; float:left; padding-top:.2em; }
58
+ form.formtastic fieldset ol li li label { line-height:100%; padding-top:0; }
59
+ form.formtastic fieldset ol li li label input { line-height:100%; vertical-align:middle; margin-top:-0.1em;}
60
+
61
+
62
+ /* NESTED FIELDSETS AND LEGENDS (radio, check boxes and date/time inputs use nested fieldsets)
63
+ --------------------------------------------------------------------------------------------------*/
64
+ form.formtastic fieldset ol li fieldset { position:relative; }
65
+ form.formtastic fieldset ol li fieldset legend { position:absolute; width:25%; padding-top:0.1em; }
66
+ form.formtastic fieldset ol li fieldset legend span { position:absolute; }
67
+ form.formtastic fieldset ol li fieldset ol { float:left; width:74%; margin:0; padding:0 0 0 25%; }
68
+ form.formtastic fieldset ol li fieldset ol li { padding:0; border:0; }
69
+
70
+
71
+ /* INLINE HINTS
72
+ --------------------------------------------------------------------------------------------------*/
73
+ form.formtastic fieldset ol li p.inline-hints { color:#666; margin:0.5em 0 0 25%; }
74
+
75
+
76
+ /* INLINE ERRORS
77
+ --------------------------------------------------------------------------------------------------*/
78
+ form.formtastic fieldset ol li p.inline-errors { color:#cc0000; margin:0.5em 0 0 25%; }
79
+ form.formtastic fieldset ol li ul.errors { color:#cc0000; margin:0.5em 0 0 25%; list-style:square; }
80
+ form.formtastic fieldset ol li ul.errors li { padding:0; border:none; display:list-item; }
81
+
82
+
83
+ /* STRING & NUMERIC OVERRIDES
84
+ --------------------------------------------------------------------------------------------------*/
85
+ form.formtastic fieldset ol li.string input { width:74%; }
86
+ form.formtastic fieldset ol li.password input { width:74%; }
87
+ form.formtastic fieldset ol li.numeric input { width:74%; }
88
+
89
+
90
+ /* TEXTAREA OVERRIDES
91
+ --------------------------------------------------------------------------------------------------*/
92
+ form.formtastic fieldset ol li.text textarea { width:74%; }
93
+
94
+
95
+ /* HIDDEN OVERRIDES
96
+ --------------------------------------------------------------------------------------------------*/
97
+ form.formtastic fieldset ol li.hidden { display:none; }
98
+
99
+
100
+ /* BOOLEAN OVERRIDES
101
+ --------------------------------------------------------------------------------------------------*/
102
+ form.formtastic fieldset ol li.boolean label { padding-left:25%; width:auto; }
103
+ form.formtastic fieldset ol li.boolean label input { margin:0 0.5em 0 0.2em; }
104
+
105
+
106
+ /* RADIO OVERRIDES
107
+ --------------------------------------------------------------------------------------------------*/
108
+ form.formtastic fieldset ol li.radio { }
109
+ form.formtastic fieldset ol li.radio fieldset ol { margin-bottom:-0.6em; }
110
+ form.formtastic fieldset ol li.radio fieldset ol li { margin:0.1em 0 0.5em 0; }
111
+ form.formtastic fieldset ol li.radio fieldset ol li label { float:none; width:100%; }
112
+ form.formtastic fieldset ol li.radio fieldset ol li label input { margin-right:0.2em; }
113
+
114
+
115
+ /* CHECK BOXES (COLLECTION) OVERRIDES
116
+ --------------------------------------------------------------------------------------------------*/
117
+ form.formtastic fieldset ol li.check_boxes { }
118
+ form.formtastic fieldset ol li.check_boxes fieldset ol { margin-bottom:-0.6em; }
119
+ form.formtastic fieldset ol li.check_boxes fieldset ol li { margin:0.1em 0 0.5em 0; }
120
+ form.formtastic fieldset ol li.check_boxes fieldset ol li label { float:none; width:100%; }
121
+ form.formtastic fieldset ol li.check_boxes fieldset ol li label input { margin-right:0.2em; }
122
+
123
+
124
+
125
+ /* DATE & TIME OVERRIDES
126
+ --------------------------------------------------------------------------------------------------*/
127
+ form.formtastic fieldset ol li.date fieldset ol li,
128
+ form.formtastic fieldset ol li.time fieldset ol li,
129
+ form.formtastic fieldset ol li.datetime fieldset ol li { float:left; width:auto; margin:0 .3em 0 0; }
130
+
131
+ form.formtastic fieldset ol li.date fieldset ol li label,
132
+ form.formtastic fieldset ol li.time fieldset ol li label,
133
+ form.formtastic fieldset ol li.datetime fieldset ol li label { display:none; }
134
+
135
+ form.formtastic fieldset ol li.date fieldset ol li label input,
136
+ form.formtastic fieldset ol li.time fieldset ol li label input,
137
+ form.formtastic fieldset ol li.datetime fieldset ol li label input { display:inline; margin:0; padding:0; }
@@ -0,0 +1,51 @@
1
+ # Set the default text field size when input is a string. Default is 50.
2
+ # Formtastic::SemanticFormBuilder.default_text_field_size = 50
3
+
4
+ # Should all fields be considered "required" by default?
5
+ # Defaults to true, see ValidationReflection notes below.
6
+ # Formtastic::SemanticFormBuilder.all_fields_required_by_default = true
7
+
8
+ # Should select fields have a blank option/prompt by default?
9
+ # Defaults to true.
10
+ # Formtastic::SemanticFormBuilder.include_blank_for_select_by_default = true
11
+
12
+ # Set the string that will be appended to the labels/fieldsets which are required
13
+ # It accepts string or procs and the default is a localized version of
14
+ # '<abbr title="required">*</abbr>'. In other words, if you configure formtastic.required
15
+ # in your locale, it will replace the abbr title properly. But if you don't want to use
16
+ # abbr tag, you can simply give a string as below
17
+ # Formtastic::SemanticFormBuilder.required_string = "(required)"
18
+
19
+ # Set the string that will be appended to the labels/fieldsets which are optional
20
+ # Defaults to an empty string ("") and also accepts procs (see required_string above)
21
+ # Formtastic::SemanticFormBuilder.optional_string = "(optional)"
22
+
23
+ # Set the way inline errors will be displayed.
24
+ # Defaults to :sentence, valid options are :sentence, :list and :none
25
+ # Formtastic::SemanticFormBuilder.inline_errors = :sentence
26
+
27
+ # Set the method to call on label text to transform or format it for human-friendly
28
+ # reading when formtastic is user without object. Defaults to :humanize.
29
+ # Formtastic::SemanticFormBuilder.label_str_method = :humanize
30
+
31
+ # Set the array of methods to try calling on parent objects in :select and :radio inputs
32
+ # for the text inside each @<option>@ tag or alongside each radio @<input>@. The first method
33
+ # that is found on the object will be used.
34
+ # Defaults to ["to_label", "display_name", "full_name", "name", "title", "username", "login", "value", "to_s"]
35
+ # Formtastic::SemanticFormBuilder.collection_label_methods = [
36
+ # "to_label", "display_name", "full_name", "name", "title", "username", "login", "value", "to_s"]
37
+
38
+ # Formtastic by default renders inside li tags the input, hints and then
39
+ # errors messages. Sometimes you want the hints to be rendered first than
40
+ # the input, in the following order: hints, input and errors. You can
41
+ # customize it doing just as below:
42
+ # Formtastic::SemanticFormBuilder.inline_order = [:input, :hints, :errors]
43
+
44
+ # Specifies if labels/hints for input fields automatically be looked up using I18n.
45
+ # Default value: false. Overridden for specific fields by setting value to true,
46
+ # i.e. :label => true, or :hint => true (or opposite depending on initialized value)
47
+ # Formtastic::SemanticFormBuilder.i18n_lookups_by_default = false
48
+
49
+ # You can add custom inputs or override parts of Formtastic by subclassing SemanticFormBuilder and
50
+ # specifying that class here. Defaults to SemanticFormBuilder.
51
+ # Formtastic::SemanticFormHelper.builder = MyCustomBuilder