qadmin 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/History.txt +9 -0
  2. data/LICENSE +20 -0
  3. data/Manifest.txt +52 -0
  4. data/PostInstall.txt +1 -0
  5. data/README.rdoc +39 -0
  6. data/Rakefile +31 -0
  7. data/init.rb +1 -0
  8. data/lib/qadmin.rb +20 -0
  9. data/lib/qadmin/assets/form_builder.rb +36 -0
  10. data/lib/qadmin/configuration.rb +48 -0
  11. data/lib/qadmin/controller.rb +139 -0
  12. data/lib/qadmin/form_builder.rb +23 -0
  13. data/lib/qadmin/helper.rb +128 -0
  14. data/lib/qadmin/option_set.rb +48 -0
  15. data/lib/qadmin/overlay.rb +31 -0
  16. data/lib/qadmin/page_titles.rb +34 -0
  17. data/lib/qadmin/templates.rb +52 -0
  18. data/lib/qadmin/views/content_forms/_attachments_form.erb +0 -0
  19. data/lib/qadmin/views/content_forms/_photos_form.erb +4 -0
  20. data/lib/qadmin/views/content_forms/_videos_form.erb +0 -0
  21. data/lib/qadmin/views/default/edit.erb +12 -0
  22. data/lib/qadmin/views/default/index.erb +9 -0
  23. data/lib/qadmin/views/default/new.erb +12 -0
  24. data/lib/qadmin/views/default/show.erb +7 -0
  25. data/rails/init.rb +5 -0
  26. data/rails_generators/qadmin/USAGE +5 -0
  27. data/rails_generators/qadmin/qadmin_generator.rb +111 -0
  28. data/rails_generators/qadmin/templates/_form.html.erb +7 -0
  29. data/rails_generators/qadmin/templates/_instance.html.erb +8 -0
  30. data/rails_generators/qadmin/templates/controller.rb +6 -0
  31. data/rails_generators/qadmin/templates/functional_test.rb +114 -0
  32. data/rails_generators/qadmin/templates/images/icon_asc.gif +0 -0
  33. data/rails_generators/qadmin/templates/images/icon_desc.gif +0 -0
  34. data/rails_generators/qadmin/templates/images/icon_destroy.png +0 -0
  35. data/rails_generators/qadmin/templates/images/icon_edit.png +0 -0
  36. data/rails_generators/qadmin/templates/images/icon_export.png +0 -0
  37. data/rails_generators/qadmin/templates/images/icon_find.png +0 -0
  38. data/rails_generators/qadmin/templates/images/icon_import.png +0 -0
  39. data/rails_generators/qadmin/templates/images/icon_list.png +0 -0
  40. data/rails_generators/qadmin/templates/images/icon_new.png +0 -0
  41. data/rails_generators/qadmin/templates/images/icon_next.gif +0 -0
  42. data/rails_generators/qadmin/templates/images/icon_prev.gif +0 -0
  43. data/rails_generators/qadmin/templates/images/icon_show.png +0 -0
  44. data/rails_generators/qadmin/templates/images/icon_sort.png +0 -0
  45. data/rails_generators/qadmin/templates/images/indicator_medium.gif +0 -0
  46. data/rails_generators/qadmin/templates/layout.html.erb +45 -0
  47. data/rails_generators/qadmin/templates/style.css +683 -0
  48. data/test/test_generator_helper.rb +29 -0
  49. data/test/test_helper.rb +83 -0
  50. data/test/test_qadmin_controller.rb +148 -0
  51. data/test/test_qadmin_generator.rb +76 -0
  52. data/test/test_qadmin_option_set.rb +86 -0
  53. metadata +162 -0
@@ -0,0 +1,48 @@
1
+ module Qadmin
2
+ class OptionSet < Array
3
+
4
+ def initialize(*args)
5
+ first = args.shift
6
+ if first.is_a?(Array)
7
+ self.default = first
8
+ options = args.shift
9
+ else
10
+ options = first
11
+ end
12
+ if options.is_a?(Hash)
13
+ options.each do |option, value|
14
+ self.send("#{option}=", value)
15
+ end
16
+ end
17
+ end
18
+
19
+ def current
20
+ [self].flatten.dup
21
+ end
22
+
23
+ [:exclude, :only, :default].each do |meth|
24
+ class_eval <<-EOT
25
+ def #{meth}
26
+ @#{meth} ||= []
27
+ end
28
+
29
+ def #{meth}=(#{meth})
30
+ @#{meth} = [#{meth}].flatten if #{meth}
31
+ reset_current
32
+ end
33
+ EOT
34
+ end
35
+ alias_method :except, :exclude
36
+ alias_method :except=, :exclude=
37
+
38
+ protected
39
+ def reset_current
40
+ new_current = if !only.empty?
41
+ only
42
+ else
43
+ default - exclude
44
+ end
45
+ self.replace(new_current)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,31 @@
1
+ module Qadmin
2
+ module Overlay
3
+
4
+ def self.included(other)
5
+ other.module_eval do
6
+ helper_method :overlay?
7
+ end
8
+ end
9
+
10
+ protected
11
+ def layout_or_overlay(options = {})
12
+ @_overlay = false
13
+ fallback_layout = options[:default] || 'admin'
14
+ if (options[:only] && !Array(options[:only]).include?(action_name)) || (options[:except] && Array(options[:except]).include?(action_name))
15
+ return fallback_layout
16
+ end
17
+ if params[:_overlay]
18
+ @_overlay = true
19
+ false
20
+ else
21
+ fallback_layout
22
+ end
23
+ end
24
+
25
+ #
26
+ def overlay?
27
+ @_overlay && @_overlay == true
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,34 @@
1
+ module Qadmin
2
+ module PageTitles
3
+
4
+ def self.included(other)
5
+ other.module_eval do
6
+ include ControllerMethods
7
+ extend MacroMethods
8
+ helper_method :get_page_title, :set_page_title
9
+ end
10
+ end
11
+
12
+ module MacroMethods
13
+ def page_title(add_title)
14
+ before_filter do |controller|
15
+ controller.set_page_title(add_title)
16
+ end
17
+ end
18
+ end
19
+
20
+ module ControllerMethods
21
+
22
+ def get_page_title(delimeter = ' : ')
23
+ @page_title ||= []
24
+ @page_title.join(delimeter)
25
+ end
26
+
27
+
28
+ def set_page_title(add_this)
29
+ get_page_title
30
+ @page_title << "#{add_this}"
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,52 @@
1
+ module Qadmin
2
+ module Templates
3
+
4
+ def self.included(klass)
5
+ if klass.respond_to?(:helper_method)
6
+ klass.module_eval do
7
+ helper_method :template_for_section, :partial_for_section
8
+ end
9
+ end
10
+ end
11
+
12
+ protected
13
+ def render_template_for_section(action = nil, options = {})
14
+ action ||= action_name
15
+ render({:template => template_for_section(action)}.merge(options))
16
+ end
17
+
18
+ def template_for_section(template_name, file_name = nil, options = {})
19
+ file_name ||= template_name
20
+ section_specific_template?(file_name, options) ? section_specific_template(template_name, options) : default_section_template(template_name, options)
21
+ end
22
+
23
+ def partial_for_section(partial_name, options = {})
24
+ template_for_section(partial_name, "_#{partial_name}", options)
25
+ end
26
+
27
+ def section_specific_template?(template_name, options = {})
28
+ template_exists?(section_specific_template(template_name, options))
29
+ end
30
+
31
+ def section_specific_template(template_name, options = {})
32
+ "#{current_section_name(options)}/#{template_name}"
33
+ end
34
+
35
+ def default_section_template(template_name, options = {})
36
+ "default/#{template_name}"
37
+ end
38
+
39
+ def current_section_name(options = {})
40
+ options[:section_name] ? options[:section_name] : (@section ? @section.name : controller_name)
41
+ end
42
+
43
+ def template_exists?(template_path)
44
+ logger.info "Checking for template: #{template_path}"
45
+ self.view_paths.find_template(template_path)
46
+ rescue ActionView::MissingTemplate
47
+ logger.info "Template not found: #{template_path}"
48
+ false
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,4 @@
1
+ <fieldset>
2
+ <legend>Photos</legend>
3
+ <%= f.asset_selector(:photos, options) %>
4
+ </fieldset>
@@ -0,0 +1,12 @@
1
+ <h2><%= model_human_name %>: Edit</h2>
2
+
3
+ <%= admin_controls model_collection_name, :for => :edit %>
4
+
5
+ <%= error_messages_for model_instance_name %>
6
+
7
+ <% form_for(@model_instance, :html => {:multipart => qadmin_configuration.multipart_forms}) do |f| %>
8
+ <%= render :partial => 'form', :locals => {:f => f, model_instance_name.to_sym => @model_instance} %>
9
+ <p><%= f.submit "Update" %></p>
10
+ <% end %>
11
+
12
+ <%= admin_controls model_collection_name, :for => :edit %>
@@ -0,0 +1,9 @@
1
+ <h2><%= model_human_name.pluralize %></h2>
2
+
3
+ <%= admin_controls model_collection_name, :for => :index, :ports => qadmin_configuration.ports, :controls => qadmin_configuration.controls %>
4
+
5
+ <%= will_paginate(@model_collection) %>
6
+ <%= admin_table(@model_collection) %>
7
+ <%= will_paginate(@model_collection) %>
8
+
9
+ <%= admin_controls model_collection_name, :for => :index, :ports => qadmin_configuration.ports, :controls => qadmin_configuration.controls %>
@@ -0,0 +1,12 @@
1
+ <h2><%= model_human_name %>: New</h2>
2
+
3
+ <%= admin_controls model_collection_name, :for => :new %>
4
+
5
+ <%= error_messages_for model_instance_name %>
6
+
7
+ <% form_for(@model_instance, :html => {:multipart => qadmin_configuration.multipart_forms}) do |f| %>
8
+ <%= render :partial => 'form', :locals => {:f => f, model_instance_name.to_sym => @model_instance} %>
9
+ <p><%= f.submit "Create" %></p>
10
+ <% end %>
11
+
12
+ <%= admin_controls model_collection_name, :for => :new %>
@@ -0,0 +1,7 @@
1
+ <h2><%= model_human_name.pluralize %>: <%= @model_instance.to_s %></h2>
2
+
3
+ <%= admin_controls model_collection_name, :for => :show, :object => @model_instance %>
4
+
5
+ <%= render :partial => model_instance_name, :object => @model_instance %>
6
+
7
+ <%= admin_controls model_collection_name, :for => :show, :object => @model_instance %>
@@ -0,0 +1,5 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'qadmin')
2
+
3
+ ActionController::Base.send(:extend, Qadmin::Controller::Macros)
4
+ ActionView::Base.send(:include, Qadmin::Helper)
5
+ ActionView::Base.default_form_builder = Qadmin::FormBuilder
@@ -0,0 +1,5 @@
1
+ Description:
2
+
3
+
4
+ Usage:
5
+
@@ -0,0 +1,111 @@
1
+ class QadminGenerator < Rails::Generator::NamedBase
2
+ attr_reader :controller_name,
3
+ :controller_class_path,
4
+ :controller_file_path,
5
+ :controller_class_nesting,
6
+ :controller_class_nesting_depth,
7
+ :controller_class_name,
8
+ :controller_singular_name,
9
+ :controller_plural_name
10
+ alias_method :controller_file_name, :controller_singular_name
11
+ alias_method :controller_table_name, :controller_plural_name
12
+
13
+ attr_accessor :after_scaffold
14
+
15
+ def initialize(runtime_args, runtime_options = {})
16
+ super
17
+
18
+ @controller_name = @args.shift || @name.pluralize
19
+
20
+ base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name)
21
+ @controller_class_name_without_nesting, @controller_singular_name, @controller_plural_name = inflect_names(base_name)
22
+
23
+ if @controller_class_nesting.empty?
24
+ @controller_class_name = @controller_class_name_without_nesting
25
+ else
26
+ @controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
27
+ end
28
+ extract_options
29
+ end
30
+
31
+ def manifest
32
+ record do |m|
33
+ klass # checks for class definition
34
+ # Check for class naming collisions.
35
+ m.class_collisions(controller_class_path, "#{controller_class_name}Controller")
36
+
37
+ # Controller, helper, views, and test directories.
38
+ if !after_scaffold
39
+ m.directory(File.join('app','controllers', controller_class_path))
40
+ m.directory(File.join('app', 'helpers', controller_class_path))
41
+ m.directory(File.join('public','images','admin'))
42
+ end
43
+
44
+ m.directory(File.join('app', 'views', controller_class_path, controller_file_name))
45
+ m.directory(File.join('test', 'functional', controller_class_path))
46
+
47
+ #copy form over too
48
+ m.template("_form.html.erb",File.join('app','views', controller_class_path, controller_file_name, "_form.html.erb"))
49
+ m.template("_instance.html.erb", File.join('app','views', controller_class_path, controller_file_name, "_#{file_name}.html.erb"))
50
+
51
+ if !after_scaffold
52
+ # Layout and stylesheet.
53
+ m.template('layout.html.erb', File.join('app','views','layouts', "admin.erb"))
54
+ m.template('style.css', 'public/stylesheets/admin.css')
55
+
56
+ m.template('controller.rb', File.join('app','controllers', controller_class_path, "#{controller_file_name}_controller.rb"))
57
+ end
58
+
59
+ m.template('functional_test.rb', File.join('test','functional', controller_class_path, "#{controller_file_name}_controller_test.rb"))
60
+
61
+ if !after_scaffold
62
+ m.route_resources controller_file_name
63
+
64
+ # Copy Icons
65
+ Dir[File.join(File.dirname(__FILE__),'templates','images/*')].each do |image|
66
+ m.file File.join('images',File.basename(image)), File.join('public','images','admin',File.basename(image))
67
+ end
68
+ end
69
+
70
+ end
71
+ end
72
+
73
+ protected
74
+ # Override with your own usage banner.
75
+ def banner
76
+ "Usage: #{$0} qadmin ModelName"
77
+ end
78
+
79
+ def scaffold_views
80
+ %w[ index show new edit ]
81
+ end
82
+
83
+ def model_name
84
+ class_name.demodulize
85
+ end
86
+
87
+ def klass
88
+ begin
89
+ require "#{file_name}" unless defined?(model_name.constantize)
90
+ rescue
91
+ raise "You must define the class #{model_name} before running qscaffold"
92
+ end
93
+ model_name.constantize
94
+ end
95
+
96
+ def attributes
97
+ klass.content_columns
98
+ end
99
+
100
+ def ignore_attributes
101
+ %w{created_at updated_at}.push klass.protected_attributes
102
+ end
103
+
104
+ def add_options!(opts)
105
+ opts.on('--after-scaffold', "For use after generating a scaffold, generates the _form and the functional test") {|o| options[:after_scaffold] = o }
106
+ end
107
+
108
+ def extract_options
109
+ self.after_scaffold = options[:after_scaffold]
110
+ end
111
+ end
@@ -0,0 +1,7 @@
1
+ <%% fieldset do %>
2
+ <% attributes.each do |attribute| -%>
3
+ <% unless ignore_attributes.include?(attribute.name) -%>
4
+ <p><label><%= attribute.human_name %></label><%%= f.text_field :<%= attribute.name %> %></p>
5
+ <% end -%>
6
+ <% end -%>
7
+ <%% end %>
@@ -0,0 +1,8 @@
1
+ <div id="<%%= dom_id(@<%= file_name %>) %>">
2
+ <div class="fields_group">
3
+ <% attributes.each do |attribute| -%>
4
+ <h5><%= attribute.human_name %>:</h5>
5
+ <%%= h @<%= singular_name %>.<%= attribute.name %> %>
6
+ <% end -%>
7
+ </div>
8
+ </div>
@@ -0,0 +1,6 @@
1
+ class <%= controller_class_name %>Controller < ApplicationController
2
+ #before_filter :login_required
3
+ layout 'admin'
4
+ qadmin
5
+
6
+ end
@@ -0,0 +1,114 @@
1
+ require 'test_helper'
2
+
3
+ class <%= controller_class_name %>ControllerTest < ActionController::TestCase
4
+
5
+ context "<%= controller_class_name %>" do
6
+ setup do
7
+ @<%= file_name %> = <%= table_name %>(!!FIXTURE_NAME)
8
+ @<%= file_name %>_params = {
9
+ <%= attributes.collect { |a| ":#{a.name} => '#{a.default}'" }.join(",\n\t") %>
10
+ }
11
+ end
12
+
13
+ context "html" do
14
+ context "GET index" do
15
+ setup do
16
+ get :index
17
+ end
18
+
19
+ should_respond_with :success
20
+
21
+ should "load paginated collection of <%= table_name %>" do
22
+ assert assigns(:<%= table_name %>)
23
+ assert assigns(:<%= table_name %>).respond_to?(:next_page)
24
+ end
25
+
26
+ should "display <%= file_name %>" do
27
+ assert_select "#<%= file_name %>_#{@<%= file_name %>.id}"
28
+ end
29
+ end
30
+
31
+ context "GET show" do
32
+ setup do
33
+ get :show, :id => @<%= file_name %>.id
34
+ end
35
+
36
+ should_respond_with :success
37
+ should_assign_to :<%= file_name %>
38
+
39
+ should "load <%= file_name %>" do
40
+ assert_equal @<%= file_name %>, assigns(:<%= file_name %>)
41
+ end
42
+
43
+ should "display <%= file_name %>" do
44
+ assert_select "#<%= file_name %>_#{@<%= file_name %>.id}"
45
+ end
46
+ end
47
+
48
+ context "GET new" do
49
+ setup do
50
+ get :new
51
+ end
52
+
53
+ should_respond_with :success
54
+ should_assign_to :<%= file_name %>
55
+
56
+ should "display form" do
57
+ assert_select 'form'
58
+ end
59
+ end
60
+
61
+ context "POST create with valid <%= file_name %>" do
62
+ setup do
63
+ post :create, :<%= file_name %> => @<%= file_name %>_params
64
+ end
65
+
66
+ should_change '<%= model_name %>.count', :by => 1
67
+ should_redirect_to "<%= file_name %>_path(@<%= file_name %>)"
68
+ should_assign_to :<%= file_name %>
69
+ end
70
+
71
+ context "GET edit" do
72
+ setup do
73
+ get :edit, :id => @<%= file_name %>.id
74
+ end
75
+
76
+ should_respond_with :success
77
+ should_assign_to :<%= file_name %>
78
+
79
+ should "load <%= file_name %>" do
80
+ assert_equal @<%= file_name %>, assigns(:<%= file_name %>)
81
+ end
82
+
83
+ should "display form" do
84
+ assert_select 'form'
85
+ end
86
+ end
87
+
88
+ context "PUT update" do
89
+ setup do
90
+ put :update, :id => @<%= file_name %>.id, :<%= file_name %> => @<%= file_name %>_params
91
+ end
92
+
93
+ should_not_change '<%= model_name %>.count'
94
+ should_redirect_to "<%= file_name %>_path(@<%= file_name %>)"
95
+ should_assign_to :<%= file_name %>
96
+
97
+ should "load <%= file_name %>" do
98
+ assert_equal @<%= file_name %>, assigns(:<%= file_name %>)
99
+ end
100
+ end
101
+
102
+ context "DELETE destroy" do
103
+ setup do
104
+ delete :destroy, :id => @<%= file_name %>.id
105
+ end
106
+
107
+ should_change '<%= model_name %>.count', :by => -1
108
+ should_redirect_to "<%= table_name %>_path"
109
+ should_assign_to :<%= file_name %>
110
+ end
111
+ end
112
+ end
113
+
114
+ end