qadmin 0.2.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/History.txt +9 -0
- data/LICENSE +20 -0
- data/Manifest.txt +52 -0
- data/PostInstall.txt +1 -0
- data/README.rdoc +39 -0
- data/Rakefile +31 -0
- data/init.rb +1 -0
- data/lib/qadmin.rb +20 -0
- data/lib/qadmin/assets/form_builder.rb +36 -0
- data/lib/qadmin/configuration.rb +48 -0
- data/lib/qadmin/controller.rb +139 -0
- data/lib/qadmin/form_builder.rb +23 -0
- data/lib/qadmin/helper.rb +128 -0
- data/lib/qadmin/option_set.rb +48 -0
- data/lib/qadmin/overlay.rb +31 -0
- data/lib/qadmin/page_titles.rb +34 -0
- data/lib/qadmin/templates.rb +52 -0
- data/lib/qadmin/views/content_forms/_attachments_form.erb +0 -0
- data/lib/qadmin/views/content_forms/_photos_form.erb +4 -0
- data/lib/qadmin/views/content_forms/_videos_form.erb +0 -0
- data/lib/qadmin/views/default/edit.erb +12 -0
- data/lib/qadmin/views/default/index.erb +9 -0
- data/lib/qadmin/views/default/new.erb +12 -0
- data/lib/qadmin/views/default/show.erb +7 -0
- data/rails/init.rb +5 -0
- data/rails_generators/qadmin/USAGE +5 -0
- data/rails_generators/qadmin/qadmin_generator.rb +111 -0
- data/rails_generators/qadmin/templates/_form.html.erb +7 -0
- data/rails_generators/qadmin/templates/_instance.html.erb +8 -0
- data/rails_generators/qadmin/templates/controller.rb +6 -0
- data/rails_generators/qadmin/templates/functional_test.rb +114 -0
- data/rails_generators/qadmin/templates/images/icon_asc.gif +0 -0
- data/rails_generators/qadmin/templates/images/icon_desc.gif +0 -0
- data/rails_generators/qadmin/templates/images/icon_destroy.png +0 -0
- data/rails_generators/qadmin/templates/images/icon_edit.png +0 -0
- data/rails_generators/qadmin/templates/images/icon_export.png +0 -0
- data/rails_generators/qadmin/templates/images/icon_find.png +0 -0
- data/rails_generators/qadmin/templates/images/icon_import.png +0 -0
- data/rails_generators/qadmin/templates/images/icon_list.png +0 -0
- data/rails_generators/qadmin/templates/images/icon_new.png +0 -0
- data/rails_generators/qadmin/templates/images/icon_next.gif +0 -0
- data/rails_generators/qadmin/templates/images/icon_prev.gif +0 -0
- data/rails_generators/qadmin/templates/images/icon_show.png +0 -0
- data/rails_generators/qadmin/templates/images/icon_sort.png +0 -0
- data/rails_generators/qadmin/templates/images/indicator_medium.gif +0 -0
- data/rails_generators/qadmin/templates/layout.html.erb +45 -0
- data/rails_generators/qadmin/templates/style.css +683 -0
- data/test/test_generator_helper.rb +29 -0
- data/test/test_helper.rb +83 -0
- data/test/test_qadmin_controller.rb +148 -0
- data/test/test_qadmin_generator.rb +76 -0
- data/test/test_qadmin_option_set.rb +86 -0
- 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
|
File without changes
|
File without changes
|
@@ -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 %>
|
data/rails/init.rb
ADDED
@@ -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,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
|