quirkey-qadmin 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/History.txt +5 -0
  2. data/LICENSE +20 -0
  3. data/Manifest.txt +20 -12
  4. data/PostInstall.txt +1 -1
  5. data/README.rdoc +4 -29
  6. data/Rakefile +5 -3
  7. data/lib/qadmin.rb +4 -2
  8. data/lib/qadmin/assets/form_builder.rb +36 -0
  9. data/lib/qadmin/configuration.rb +48 -0
  10. data/lib/qadmin/controller.rb +64 -34
  11. data/lib/qadmin/form_builder.rb +23 -0
  12. data/lib/qadmin/helper.rb +46 -15
  13. data/lib/qadmin/option_set.rb +48 -0
  14. data/lib/qadmin/overlay.rb +31 -0
  15. data/lib/qadmin/page_titles.rb +34 -0
  16. data/lib/qadmin/templates.rb +52 -0
  17. data/lib/qadmin/views/content_forms/_attachments_form.erb +0 -0
  18. data/lib/qadmin/views/content_forms/_photos_form.erb +4 -0
  19. data/lib/qadmin/views/content_forms/_videos_form.erb +0 -0
  20. data/lib/qadmin/views/default/edit.erb +12 -0
  21. data/lib/qadmin/views/default/index.erb +9 -0
  22. data/lib/qadmin/views/default/new.erb +12 -0
  23. data/lib/qadmin/views/default/show.erb +7 -0
  24. data/rails/init.rb +2 -1
  25. data/rails_generators/qadmin/qadmin_generator.rb +36 -19
  26. data/rails_generators/qadmin/templates/_form.html.erb +7 -0
  27. data/rails_generators/qadmin/templates/_instance.html.erb +8 -0
  28. data/rails_generators/qadmin/templates/controller.rb +1 -1
  29. data/rails_generators/qadmin/templates/functional_test.rb +102 -65
  30. data/rails_generators/qadmin/templates/images/{icon_up.gif → icon_asc.gif} +0 -0
  31. data/rails_generators/qadmin/templates/images/{icon_down.gif → icon_desc.gif} +0 -0
  32. data/rails_generators/qadmin/templates/layout.html.erb +45 -0
  33. data/test/test_helper.rb +8 -0
  34. data/test/test_qadmin_controller.rb +16 -6
  35. data/test/test_qadmin_generator.rb +17 -2
  36. data/test/test_qadmin_option_set.rb +86 -0
  37. metadata +46 -14
  38. data/rails_generators/qadmin/templates/shoulda_functional_test.rb +0 -33
  39. data/script/console +0 -10
  40. data/script/destroy +0 -14
  41. data/script/generate +0 -14
  42. data/script/txt2html +0 -71
@@ -1,3 +1,8 @@
1
+ == 0.2.0 2009-03-20
2
+
3
+ * 1 major enhancement:
4
+ * First full release
5
+
1
6
  == 0.0.1 2009-01-07
2
7
 
3
8
  * 1 major enhancement:
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Aaron Quint, Quirkey NYC, LLC
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.
@@ -1,24 +1,37 @@
1
1
  History.txt
2
+ LICENSE
2
3
  Manifest.txt
3
4
  PostInstall.txt
4
5
  README.rdoc
5
6
  Rakefile
6
7
  init.rb
7
8
  lib/qadmin.rb
9
+ lib/qadmin/assets/form_builder.rb
10
+ lib/qadmin/configuration.rb
8
11
  lib/qadmin/controller.rb
12
+ lib/qadmin/form_builder.rb
9
13
  lib/qadmin/helper.rb
10
- lib/qadmin/views/edit.html.erb
11
- lib/qadmin/views/index.html.erb
12
- lib/qadmin/views/new.html.erb
13
- lib/qadmin/views/show.html.erb
14
+ lib/qadmin/option_set.rb
15
+ lib/qadmin/overlay.rb
16
+ lib/qadmin/page_titles.rb
17
+ lib/qadmin/templates.rb
18
+ lib/qadmin/views/content_forms/_attachments_form.erb
19
+ lib/qadmin/views/content_forms/_photos_form.erb
20
+ lib/qadmin/views/content_forms/_videos_form.erb
21
+ lib/qadmin/views/default/edit.erb
22
+ lib/qadmin/views/default/index.erb
23
+ lib/qadmin/views/default/new.erb
24
+ lib/qadmin/views/default/show.erb
14
25
  rails/init.rb
15
26
  rails_generators/qadmin/USAGE
16
27
  rails_generators/qadmin/qadmin_generator.rb
17
28
  rails_generators/qadmin/templates/_form.html.erb
29
+ rails_generators/qadmin/templates/_instance.html.erb
18
30
  rails_generators/qadmin/templates/controller.rb
19
31
  rails_generators/qadmin/templates/functional_test.rb
32
+ rails_generators/qadmin/templates/images/icon_asc.gif
33
+ rails_generators/qadmin/templates/images/icon_desc.gif
20
34
  rails_generators/qadmin/templates/images/icon_destroy.png
21
- rails_generators/qadmin/templates/images/icon_down.gif
22
35
  rails_generators/qadmin/templates/images/icon_edit.png
23
36
  rails_generators/qadmin/templates/images/icon_export.png
24
37
  rails_generators/qadmin/templates/images/icon_find.png
@@ -29,16 +42,11 @@ rails_generators/qadmin/templates/images/icon_next.gif
29
42
  rails_generators/qadmin/templates/images/icon_prev.gif
30
43
  rails_generators/qadmin/templates/images/icon_show.png
31
44
  rails_generators/qadmin/templates/images/icon_sort.png
32
- rails_generators/qadmin/templates/images/icon_up.gif
33
45
  rails_generators/qadmin/templates/images/indicator_medium.gif
34
46
  rails_generators/qadmin/templates/layout.html.erb
35
- rails_generators/qadmin/templates/shoulda_functional_test.rb
36
47
  rails_generators/qadmin/templates/style.css
37
- script/console
38
- script/destroy
39
- script/generate
40
- script/txt2html
41
48
  test/test_generator_helper.rb
42
49
  test/test_helper.rb
43
50
  test/test_qadmin_controller.rb
44
- test/test_qadmin_generator.rb
51
+ test/test_qadmin_generator.rb
52
+ test/test_qadmin_option_set.rb
@@ -1 +1 @@
1
- For more information on qadmin, see http://github.com/quirkey/qadmin
1
+ For more information on qadmin, see http://code.quirkey.com/qadmin
@@ -6,7 +6,7 @@ http://github.com/quirkey/qadmin
6
6
 
7
7
  An [almost] one command solution for adding admin interfaces/resources to a Rails app.
8
8
 
9
- == FEATURES/PROBLEMS:
9
+ == SYNOPSIS:
10
10
 
11
11
  Qadmin is a partial extraction of 2+ years of building Rails admin systems. A lot of the code comes from a Rails plugin I wrote (private) called quirkey_tools.
12
12
 
@@ -14,13 +14,9 @@ The system consists currently of two parts: a generator, and a set of macros.
14
14
 
15
15
  The generator is =~ the Rails resource generator, but instead of plopping all the code for the different standard resource actions into the controller and templates, it uses the #qadmin macro to include the standard resource actions.
16
16
 
17
- == SYNOPSIS:
18
-
19
- (Coming soon)
20
-
21
- == REQUIREMENTS:
17
+ For full details and usage please see the website at:
22
18
 
23
- Right now, a rails app, but the eventual goal is to make it framework agnostic (work with Sinatra, etc, too)..
19
+ http://code.quirkey.com/qadmin
24
20
 
25
21
  == INSTALL:
26
22
 
@@ -40,25 +36,4 @@ Then in your config/environment.rb
40
36
 
41
37
  == LICENSE:
42
38
 
43
- (The MIT License)
44
-
45
- Copyright (c) 2009 Aaron Quint, Quirkey NYC, LLC
46
-
47
- Permission is hereby granted, free of charge, to any person obtaining
48
- a copy of this software and associated documentation files (the
49
- 'Software'), to deal in the Software without restriction, including
50
- without limitation the rights to use, copy, modify, merge, publish,
51
- distribute, sublicense, and/or sell copies of the Software, and to
52
- permit persons to whom the Software is furnished to do so, subject to
53
- the following conditions:
54
-
55
- The above copyright notice and this permission notice shall be
56
- included in all copies or substantial portions of the Software.
57
-
58
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
59
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
60
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
61
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
62
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
63
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
64
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
39
+ MIT-LICENSE - See LICENSE
data/Rakefile CHANGED
@@ -8,12 +8,14 @@ $hoe = Hoe.new('qadmin', Qadmin::VERSION) do |p|
8
8
  p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
9
9
  p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
10
10
  p.rubyforge_name = 'quirkey'
11
+ p.summary = p.description = "An [almost] one command solution for adding admin interfaces/resources to a Rails app."
11
12
  p.extra_deps = [
12
- ['activesupport','>= 2.2.0'],
13
- ['restful_query','>= 0.1.0']
13
+ ['activesupport','>= 2.3.2'],
14
+ ['restful_query','>= 0.2.0']
14
15
  ]
15
16
  p.extra_dev_deps = [
16
- ['newgem', ">= #{::Newgem::VERSION}"]
17
+ ['newgem', ">= #{::Newgem::VERSION}"],
18
+ ['Shoulda', ">= 1.2.0"]
17
19
  ]
18
20
 
19
21
  p.clean_globs |= %w[**/.DS_Store tmp *.log]
@@ -6,13 +6,15 @@ unless defined?(ActiveSupport)
6
6
  end
7
7
 
8
8
  module Qadmin
9
- VERSION = '0.1.1'
9
+ VERSION = '0.2.0'
10
10
  end
11
11
 
12
12
  %w{
13
- options
13
+ option_set
14
+ configuration
14
15
  helper
15
16
  overlay
17
+ page_titles
16
18
  templates
17
19
  controller
18
20
  }.each {|lib| require "qadmin/#{lib}" }
@@ -0,0 +1,36 @@
1
+ module Qadmin
2
+ module Assets
3
+ module FormBuilder
4
+
5
+ def asset_selector(method, options = {})
6
+
7
+ id = "#{object_name}_#{method}"
8
+ form_name = "#{object_name}[#{method}]"
9
+
10
+ options.reverse_merge!({
11
+ :id => id,
12
+ :form_name => form_name,
13
+ :name => object_name,
14
+ :method => method,
15
+ :object => object,
16
+ :current => object.send(method),
17
+ :label => false,
18
+ :resize_type => object_name.tableize,
19
+ :multiple => true
20
+ })
21
+ @template.render(:partial => 'assets/asset_selector', :locals => options)
22
+ end
23
+
24
+ def asset_browser(id, options = {})
25
+ options.reverse_merge!({
26
+ :id => id,
27
+ :label => false,
28
+ :resize_type => ''
29
+ })
30
+ @template.render(:partial => 'shared/file_browser', :locals => options)
31
+ end
32
+
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,48 @@
1
+ module Qadmin
2
+ class Configuration
3
+
4
+ attr_accessor :controller_klass,
5
+ :model_name,
6
+ :model_instance_name,
7
+ :model_collection_name,
8
+ :model_human_name,
9
+ :available_actions,
10
+ :display_columns,
11
+ :column_headers,
12
+ :multipart_forms,
13
+ :default_scope,
14
+ :ports,
15
+ :controls
16
+
17
+ def initialize(options = {})
18
+ extract_model_from_options(options)
19
+ self.available_actions = Qadmin::OptionSet.new([:index, :show, :new, :create, :edit, :update, :destroy], options[:available_actions] || {})
20
+ self.display_columns = Qadmin::OptionSet.new(model_column_names, options[:display_columns] || {})
21
+ self.multipart_forms = options[:multipart_forms] || false
22
+ self.default_scope = options[:default_scope] || false
23
+ self.ports = options[:ports] || false
24
+ self.controls = options[:controls] || []
25
+ self.column_headers = HashWithIndifferentAccess.new(options[:column_headers] || {})
26
+ end
27
+
28
+ def model_klass
29
+ self.model_name.constantize
30
+ end
31
+
32
+ protected
33
+ def extract_model_from_options(options = {})
34
+ self.controller_klass = options[:controller_klass]
35
+ self.model_name = options[:model_name] || controller_klass.to_s.demodulize.gsub(/Controller/,'').singularize
36
+ self.model_instance_name = options[:model_instance_name] || model_name.underscore
37
+ self.model_collection_name = options[:model_collection_name] || model_instance_name.pluralize
38
+ self.model_human_name = options[:model_human_name] || model_instance_name.humanize
39
+ end
40
+
41
+ def model_column_names
42
+ model_klass.column_names
43
+ rescue
44
+ []
45
+ end
46
+
47
+ end
48
+ end
@@ -5,25 +5,29 @@ module Qadmin
5
5
 
6
6
 
7
7
  def qadmin(options = {})
8
- extend ::Qadmin::Options
9
- self.cattr_accessor :model_name, :model_instance_name, :model_collection_name, :model_human_name, :available_actions
10
- self.available_actions = [:index, :show, :new, :create, :edit, :update, :destroy]
11
- self.available_actions = [options[:only]].flatten if options[:only]
12
- self.available_actions -= [options[:exclude]].flatten if options[:exclude]
13
- self.extract_model_from_options(options)
14
- self.append_view_path(File.join(File.dirname(__FILE__), 'views'))
8
+ self.cattr_accessor :qadmin_configuration
9
+ self.qadmin_configuration = Qadmin::Configuration.new({:controller_klass => self}.merge(options))
10
+ self.delegate :model_name, :model_klass, :model_collection_name, :model_instance_name, :model_human_name, :to => lambda { self.class.qadmin_configuration }
11
+ yield(self.qadmin_configuration) if block_given?
15
12
  include Qadmin::Templates
16
13
  include Qadmin::Overlay
17
- define_admin_actions(available_actions, options)
14
+ self.append_view_path(File.join(File.dirname(__FILE__), 'views'))
15
+ define_admin_actions(qadmin_configuration.available_actions, options)
18
16
  end
19
17
 
20
18
  private
21
19
 
22
20
  def define_admin_actions(actions, options = {})
21
+ config = self.qadmin_configuration
23
22
  action_method_code = {
24
23
  :index => %{
25
24
  def index
26
- @model_collection = @#{model_collection_name} = #{model_name}.paginate(:page => (params[:page] || 1))
25
+ logger.info 'Qadmin: Default /index'
26
+ scope = qadmin_configuration.model_klass
27
+ scope = scope.send(qadmin_configuration.default_scope) if qadmin_configuration.default_scope
28
+ scope = scope.restful_query(params[:query]) if #{config.model_name}.can_query?
29
+ @model_collection = @#{config.model_collection_name} = scope.paginate(:page => (params[:page] || 1), :per_page => (params[:per_page] || 25))
30
+ logger.warn 'controller params:' + params.inspect
27
31
  respond_to do |format|
28
32
  format.html { render_template_for_section }
29
33
  format.xml
@@ -32,65 +36,75 @@ module Qadmin
32
36
  },
33
37
  :show => %{
34
38
  def show
35
- @model_instance = @#{model_instance_name} = #{model_name}.find(params[:id])
39
+ logger.info 'Qadmin: Default /show'
40
+ @model_instance = @#{config.model_instance_name} = #{config.model_name}.find(params[:id])
36
41
  respond_to do |format|
37
- format.html
42
+ format.html { render_template_for_section }
38
43
  format.xml
39
44
  end
40
45
  end
41
46
  },
42
47
  :new => %{
43
48
  def new
44
- @model_instance = @#{model_instance_name} = #{model_name}.new
49
+ logger.info 'Qadmin: Default /new'
50
+ @model_instance = @#{config.model_instance_name} = #{config.model_name}.new
45
51
  respond_to do |format|
46
- format.html # new.html.erb
47
- format.xml { render :xml => @#{model_instance_name} }
52
+ format.html { render_template_for_section }
53
+ format.xml { render :xml => @#{config.model_instance_name} }
48
54
  end
49
55
  end
50
56
  },
51
57
  :create => %{
52
58
  def create
53
- @model_instance = @#{model_instance_name} = #{model_name}.new(params[:#{model_instance_name}])
59
+ logger.info 'Qadmin: Default /create'
60
+ @model_instance = @#{config.model_instance_name} = #{config.model_name}.new(params[:#{config.model_instance_name}])
54
61
  respond_to do |format|
55
- if @#{model_instance_name}.save
56
- flash[:message] = '#{model_human_name} was successfully created.'
57
- format.html { redirect_to(#{model_instance_name}_path(@#{model_instance_name})) }
58
- format.xml { render :xml => @#{model_instance_name}, :status => :created, :location => @#{model_instance_name} }
62
+ if @#{config.model_instance_name}.save
63
+ flash[:message] = '#{config.model_human_name} was successfully created.'
64
+ format.html { redirect_to(#{config.model_instance_name}_path(@#{config.model_instance_name})) }
65
+ format.xml { render :xml => @#{config.model_instance_name}, :status => :created, :location => @#{config.model_instance_name} }
59
66
  else
60
- format.html { render :action => "new" }
61
- format.xml { render :xml => @#{model_instance_name}.errors }
67
+ format.html { render_template_for_section('new') }
68
+ format.xml { render :xml => @#{config.model_instance_name}.errors }
62
69
  end
63
70
  end
64
71
  end
65
72
  },
66
73
  :edit => %{
67
74
  def edit
68
- @model_instance = @#{model_instance_name} = #{model_name}.find(params[:id])
75
+ logger.info 'Qadmin: Default /edit'
76
+ @model_instance = @#{config.model_instance_name} = #{config.model_name}.find(params[:id])
77
+ respond_to do |format|
78
+ format.html { render_template_for_section }
79
+ format.xml { redirect_to #{config.model_instance_name}_path(@#{config.model_instance_name}) }
80
+ end
69
81
  end
70
82
  },
71
83
  :update => %{
72
84
  def update
73
- @model_instance = @#{model_instance_name} = #{model_name}.find(params[:id])
85
+ logger.info 'Qadmin: Default /update'
86
+ @model_instance = @#{config.model_instance_name} = #{config.model_name}.find(params[:id])
74
87
 
75
88
  respond_to do |format|
76
- if @#{model_instance_name}.update_attributes(params[:#{model_instance_name}])
77
- flash[:message] = '#{model_human_name} was successfully updated.'
78
- format.html { redirect_to(#{model_instance_name}_path(@#{model_instance_name})) }
89
+ if @#{config.model_instance_name}.update_attributes(params[:#{config.model_instance_name}])
90
+ flash[:message] = '#{config.model_human_name} was successfully updated.'
91
+ format.html { redirect_to(#{config.model_instance_name}_path(@#{config.model_instance_name})) }
79
92
  format.xml { head :ok }
80
93
  else
81
- format.html { render :action => "edit" }
82
- format.xml { render :xml => @#{model_instance_name}.errors }
94
+ format.html { render_template_for_section("edit") }
95
+ format.xml { render :xml => @#{config.model_instance_name}.errors }
83
96
  end
84
97
  end
85
98
  end
86
99
  },
87
100
  :destroy => %{
88
101
  def destroy
89
- @model_instance = @#{model_instance_name} = #{model_name}.find(params[:id])
90
- @#{model_instance_name}.destroy
91
- flash[:message] = "#{model_human_name} \#{@#{model_instance_name}} was deleted"
102
+ logger.info 'Qadmin: Default /destroy'
103
+ @model_instance = @#{config.model_instance_name} = #{config.model_name}.find(params[:id])
104
+ @#{config.model_instance_name}.destroy
105
+ flash[:message] = "#{config.model_human_name} \#{@#{config.model_instance_name}} was deleted"
92
106
  respond_to do |format|
93
- format.html { redirect_to(#{model_collection_name}_path) }
107
+ format.html { redirect_to(#{config.model_collection_name}_path) }
94
108
  format.xml { head :ok }
95
109
  end
96
110
  end
@@ -98,9 +112,25 @@ module Qadmin
98
112
  }
99
113
  action_code = actions.collect {|a| action_method_code[a.to_sym] }.join("\n")
100
114
  helper_methods = %{
101
- helper_method :model_name, :model_instance_name, :model_collection_name, :model_human_name, :model_klass, :available_actions
115
+ delegate :model_name, :model_klass, :model_collection_name, :model_instance_name, :model_human_name, :to => :qadmin_configuration
116
+ helper_method :qadmin_configuration, :model_name, :model_instance_name, :model_collection_name, :model_human_name, :available_actions
117
+ }
118
+ additional_methods = %{
119
+ def add_form
120
+ @origin_div = params[:from]
121
+ @num = params[:num]
122
+ @content_type = params[:content_type] || model_instance_name
123
+ obj = @origin_div.to_s.singularize
124
+ respond_to do |format|
125
+ format.js {
126
+ render :update do |page|
127
+ page.insert_html :bottom, @origin_div, :partial => "content_forms/\#{obj}_form", :locals => {obj => nil, :index => @num, :content_type => @content_type}
128
+ end
129
+ }
130
+ end
131
+ end
102
132
  }
103
- action_code = helper_methods << action_code
133
+ action_code = helper_methods << action_code << additional_methods
104
134
  self.class_eval(action_code)
105
135
  end
106
136
  end
@@ -0,0 +1,23 @@
1
+ module Qadmin
2
+ class FormBuilder < ::ActionView::Helpers::FormBuilder
3
+ include Qadmin::Assets::FormBuilder
4
+
5
+ def content_form(form_name, options = {})
6
+ locals = options.reverse_merge({:content_type => object_name, :content => object, :f => self, :options => options})
7
+ @template.render(:partial => "content_forms/#{form_name}_form", :locals => locals)
8
+ end
9
+
10
+ def text_field_with_hint(method, options = {})
11
+ if object.send(method).blank?
12
+ options[:class] = if options[:class]
13
+ options[:class] << ' hinted'
14
+ else
15
+ 'hinted'
16
+ end
17
+ options[:value] = options.delete(:hint)
18
+ end
19
+ text_field(method, options)
20
+ end
21
+
22
+ end
23
+ end