quirkey-qadmin 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/Manifest.txt +44 -0
- data/PostInstall.txt +1 -0
- data/README.rdoc +64 -0
- data/Rakefile +28 -0
- data/init.rb +1 -0
- data/lib/qadmin/controller.rb +121 -0
- data/lib/qadmin/helper.rb +59 -0
- data/lib/qadmin/views/edit.html.erb +12 -0
- data/lib/qadmin/views/index.html.erb +31 -0
- data/lib/qadmin/views/new.html.erb +12 -0
- data/lib/qadmin/views/show.html.erb +14 -0
- data/lib/qadmin.rb +13 -0
- data/rails/init.rb +4 -0
- data/rails_generators/qadmin/USAGE +5 -0
- data/rails_generators/qadmin/qadmin_generator.rb +94 -0
- data/rails_generators/qadmin/templates/_form.html.erb +7 -0
- data/rails_generators/qadmin/templates/controller.rb +6 -0
- data/rails_generators/qadmin/templates/functional_test.rb +77 -0
- data/rails_generators/qadmin/templates/images/icon_destroy.png +0 -0
- data/rails_generators/qadmin/templates/images/icon_down.gif +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/icon_up.gif +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/shoulda_functional_test.rb +33 -0
- data/rails_generators/qadmin/templates/style.css +683 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +71 -0
- data/test/test_generator_helper.rb +29 -0
- data/test/test_helper.rb +70 -0
- data/test/test_qadmin_controller.rb +138 -0
- data/test/test_qadmin_generator.rb +61 -0
- metadata +130 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
PostInstall.txt
|
4
|
+
README.rdoc
|
5
|
+
Rakefile
|
6
|
+
init.rb
|
7
|
+
lib/qadmin.rb
|
8
|
+
lib/qadmin/controller.rb
|
9
|
+
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
|
+
rails/init.rb
|
15
|
+
rails_generators/qadmin/USAGE
|
16
|
+
rails_generators/qadmin/qadmin_generator.rb
|
17
|
+
rails_generators/qadmin/templates/_form.html.erb
|
18
|
+
rails_generators/qadmin/templates/controller.rb
|
19
|
+
rails_generators/qadmin/templates/functional_test.rb
|
20
|
+
rails_generators/qadmin/templates/images/icon_destroy.png
|
21
|
+
rails_generators/qadmin/templates/images/icon_down.gif
|
22
|
+
rails_generators/qadmin/templates/images/icon_edit.png
|
23
|
+
rails_generators/qadmin/templates/images/icon_export.png
|
24
|
+
rails_generators/qadmin/templates/images/icon_find.png
|
25
|
+
rails_generators/qadmin/templates/images/icon_import.png
|
26
|
+
rails_generators/qadmin/templates/images/icon_list.png
|
27
|
+
rails_generators/qadmin/templates/images/icon_new.png
|
28
|
+
rails_generators/qadmin/templates/images/icon_next.gif
|
29
|
+
rails_generators/qadmin/templates/images/icon_prev.gif
|
30
|
+
rails_generators/qadmin/templates/images/icon_show.png
|
31
|
+
rails_generators/qadmin/templates/images/icon_sort.png
|
32
|
+
rails_generators/qadmin/templates/images/icon_up.gif
|
33
|
+
rails_generators/qadmin/templates/images/indicator_medium.gif
|
34
|
+
rails_generators/qadmin/templates/layout.html.erb
|
35
|
+
rails_generators/qadmin/templates/shoulda_functional_test.rb
|
36
|
+
rails_generators/qadmin/templates/style.css
|
37
|
+
script/console
|
38
|
+
script/destroy
|
39
|
+
script/generate
|
40
|
+
script/txt2html
|
41
|
+
test/test_generator_helper.rb
|
42
|
+
test/test_helper.rb
|
43
|
+
test/test_qadmin_controller.rb
|
44
|
+
test/test_qadmin_generator.rb
|
data/PostInstall.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
For more information on qadmin, see http://github.com/quirkey/qadmin
|
data/README.rdoc
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
= qadmin
|
2
|
+
|
3
|
+
http://github.com/quirkey/qadmin
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
An [almost] one command solution for adding admin interfaces/resources to a Rails app.
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
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
|
+
|
13
|
+
The system consists currently of two parts: a generator, and a set of macros.
|
14
|
+
|
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
|
+
|
17
|
+
== SYNOPSIS:
|
18
|
+
|
19
|
+
(Coming soon)
|
20
|
+
|
21
|
+
== REQUIREMENTS:
|
22
|
+
|
23
|
+
Right now, a rails app, but the eventual goal is to make it framework agnostic (work with Sinatra, etc, too)..
|
24
|
+
|
25
|
+
== INSTALL:
|
26
|
+
|
27
|
+
Qadmin can be installed as a gem or a plugin.
|
28
|
+
|
29
|
+
=== As a gem
|
30
|
+
|
31
|
+
sudo gem install qadmin --source=http://gems.github.com
|
32
|
+
|
33
|
+
Then in your config/environment.rb
|
34
|
+
|
35
|
+
config.gem 'qadmin'
|
36
|
+
|
37
|
+
=== As a plugin
|
38
|
+
|
39
|
+
./script/plugin install git://github.com/quirkey/qadmin.git
|
40
|
+
|
41
|
+
== LICENSE:
|
42
|
+
|
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.
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
%w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
|
2
|
+
require File.dirname(__FILE__) + '/lib/qadmin'
|
3
|
+
|
4
|
+
# Generate all the Rake tasks
|
5
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
6
|
+
$hoe = Hoe.new('qadmin', Qadmin::VERSION) do |p|
|
7
|
+
p.developer('Aaron Quint', 'aaron@quirkey.com')
|
8
|
+
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
9
|
+
p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
|
10
|
+
p.rubyforge_name = 'quirkey'
|
11
|
+
p.extra_deps = [
|
12
|
+
['activesupport','>= 2.2.0']
|
13
|
+
]
|
14
|
+
p.extra_dev_deps = [
|
15
|
+
['newgem', ">= #{::Newgem::VERSION}"]
|
16
|
+
]
|
17
|
+
|
18
|
+
p.clean_globs |= %w[**/.DS_Store tmp *.log]
|
19
|
+
path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
|
20
|
+
p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
|
21
|
+
p.rsync_args = '-av --delete --ignore-errors'
|
22
|
+
end
|
23
|
+
|
24
|
+
require 'newgem/tasks' # load /tasks/*.rake
|
25
|
+
Dir['tasks/**/*.rake'].each { |t| load t }
|
26
|
+
|
27
|
+
# TODO - want other tests/tasks run by default? Add them to the list
|
28
|
+
# task :default => [:spec, :features]
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "rails", "init")
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module Qadmin
|
2
|
+
module Controller
|
3
|
+
|
4
|
+
module Macros
|
5
|
+
|
6
|
+
def qadmin(options = {})
|
7
|
+
self.cattr_accessor :model_name, :model_instance_name, :model_collection_name, :model_human_name, :available_actions
|
8
|
+
self.available_actions = [:index, :show, :new, :create, :edit, :update, :destroy]
|
9
|
+
self.available_actions = [options[:only]].flatten if options[:only]
|
10
|
+
self.available_actions -= [options[:exclude]].flatten if options[:exclude]
|
11
|
+
self.model_name = self.to_s.demodulize.gsub(/Controller/,'').singularize
|
12
|
+
self.model_instance_name = model_name.underscore
|
13
|
+
self.model_collection_name = model_instance_name.pluralize
|
14
|
+
self.model_human_name = model_instance_name.humanize
|
15
|
+
self.append_view_paths(File.join(File.dirname(__FILE__), 'views'))
|
16
|
+
define_admin_actions(available_actions, options)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def define_admin_actions(actions, options = {})
|
21
|
+
action_method_code = {
|
22
|
+
:index => %{
|
23
|
+
def index
|
24
|
+
@#{model_collection_name} = #{model_name}.paginate(:page => (params[:page] || 1))
|
25
|
+
respond_to do |format|
|
26
|
+
format.html
|
27
|
+
format.xml
|
28
|
+
end
|
29
|
+
end
|
30
|
+
},
|
31
|
+
:show => %{
|
32
|
+
def show
|
33
|
+
@#{model_instance_name} = #{model_name}.find(params[:id])
|
34
|
+
respond_to do |format|
|
35
|
+
format.html
|
36
|
+
format.xml
|
37
|
+
end
|
38
|
+
end
|
39
|
+
},
|
40
|
+
:new => %{
|
41
|
+
def new
|
42
|
+
@#{model_instance_name} = #{model_name}.new
|
43
|
+
|
44
|
+
respond_to do |format|
|
45
|
+
format.html # new.html.erb
|
46
|
+
format.xml { render :xml => @#{model_instance_name} }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
},
|
50
|
+
:create => %{
|
51
|
+
def create
|
52
|
+
@#{model_instance_name} = #{model_name}.new(params[:#{model_instance_name}])
|
53
|
+
respond_to do |format|
|
54
|
+
if @#{model_instance_name}.save
|
55
|
+
flash[:message] = '#{model_human_name} was successfully created.'
|
56
|
+
format.html { redirect_to(#{model_instance_name}_path(@#{model_instance_name})) }
|
57
|
+
format.xml { render :xml => @#{model_instance_name}, :status => :created, :location => @#{model_instance_name} }
|
58
|
+
else
|
59
|
+
format.html { render :action => "new" }
|
60
|
+
format.xml { render :xml => @#{model_instance_name}.errors }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
},
|
65
|
+
:edit => %{
|
66
|
+
def edit
|
67
|
+
@#{model_instance_name} = #{model_name}.find(params[:id])
|
68
|
+
end
|
69
|
+
},
|
70
|
+
:update => %{
|
71
|
+
def update
|
72
|
+
@#{model_instance_name} = #{model_name}.find(params[:id])
|
73
|
+
|
74
|
+
respond_to do |format|
|
75
|
+
if @#{model_instance_name}.update_attributes(params[:#{model_instance_name}])
|
76
|
+
flash[:message] = '#{model_human_name} was successfully updated.'
|
77
|
+
format.html { redirect_to(#{model_instance_name}_path(@#{model_instance_name})) }
|
78
|
+
format.xml { head :ok }
|
79
|
+
else
|
80
|
+
format.html { render :action => "edit" }
|
81
|
+
format.xml { render :xml => @#{model_instance_name}.errors }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
},
|
86
|
+
:destroy => %{
|
87
|
+
def destroy
|
88
|
+
@#{model_instance_name} = #{model_name}.find(params[:id])
|
89
|
+
@#{model_instance_name}.destroy
|
90
|
+
flash[:message] = "#{model_human_name} \#{@#{model_instance_name}} was deleted"
|
91
|
+
respond_to do |format|
|
92
|
+
format.html { redirect_to(#{model_collection_name}_path) }
|
93
|
+
format.xml { head :ok }
|
94
|
+
end
|
95
|
+
end
|
96
|
+
}
|
97
|
+
}
|
98
|
+
action_code = actions.collect {|a| action_method_code[a.to_sym] }.join("\n")
|
99
|
+
self.class_eval(action_code)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
# GET /<%= controller_file_path %>/new
|
105
|
+
# GET /<%= controller_file_path %>/new.xml
|
106
|
+
|
107
|
+
# GET /<%= controller_file_path %>/1/edit
|
108
|
+
|
109
|
+
# POST /<%= controller_file_path %>
|
110
|
+
# POST /<%= controller_file_path %>.xml
|
111
|
+
|
112
|
+
# PUT /<%= controller_file_path %>/1
|
113
|
+
# PUT /<%= controller_file_path %>/1.xml
|
114
|
+
|
115
|
+
|
116
|
+
# DELETE /<%= controller_file_path %>/1
|
117
|
+
# DELETE /<%= controller_file_path %>/1.xml
|
118
|
+
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Qadmin
|
2
|
+
module Helper
|
3
|
+
|
4
|
+
def fieldset(legend = nil, options = {}, &block)
|
5
|
+
content_tag(:fieldset, options) do
|
6
|
+
content_tag(:legend, legend) if legend
|
7
|
+
yield
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def admin_controls(name, options = {}, &block)
|
12
|
+
return if respond_to?(:overlay?) && overlay?
|
13
|
+
controller = options[:controller] || name.to_s.tableize
|
14
|
+
assumed_object = self.instance_variable_get "@#{name}"
|
15
|
+
obj = options[:object] || assumed_object || nil
|
16
|
+
parent = options[:parent] || false
|
17
|
+
|
18
|
+
parent_link_attributes = parent ? {parent.class.to_s.foreign_key => parent.id} : {}
|
19
|
+
general_link_attributes = {:controller => controller}.merge(parent_link_attributes)
|
20
|
+
|
21
|
+
control_links = {
|
22
|
+
:index => link_to(image_tag('admin/icon_list.png') + " Back to List", general_link_attributes.merge(:action => 'index')),
|
23
|
+
:new => link_to(image_tag('admin/icon_new.png') + " New", general_link_attributes.merge(:action => 'new')),
|
24
|
+
:edit => link_to(image_tag('admin/icon_edit.png') + " Edit", general_link_attributes.merge(:action => 'edit', :id => obj)),
|
25
|
+
:show => link_to(image_tag('admin/icon_show.png') + " View", general_link_attributes.merge(:action => 'show', :id => obj)),
|
26
|
+
:destroy => link_to(image_tag('admin/icon_destroy.png') + " Delete", general_link_attributes.merge(:action => 'destroy', :id => obj), :confirm => 'Are you sure?', :method => :delete),
|
27
|
+
:ports => link_to(image_tag('admin/icon_export.png') + " Import/Export", general_link_attributes.merge(:action => 'ports'))
|
28
|
+
}
|
29
|
+
|
30
|
+
control_sets = {
|
31
|
+
:index => [:new],
|
32
|
+
:new => [:index],
|
33
|
+
:edit => [:index,:new,:show,:destroy],
|
34
|
+
:show => [:index,:new,:edit,:destroy]
|
35
|
+
}
|
36
|
+
|
37
|
+
control_set = (options[:for] ? control_sets[options[:for]] : options[:controls])
|
38
|
+
control_set << :ports if options[:ports]
|
39
|
+
controls = Array(control_set).collect {|c| control_links[c] }.compact
|
40
|
+
|
41
|
+
html = ""
|
42
|
+
html << %{<ul class="admin_controls">}
|
43
|
+
controls.each {|control| html << li(control) }
|
44
|
+
if block_given?
|
45
|
+
html << capture(&block)
|
46
|
+
html << %{</ul>}
|
47
|
+
concat(html,block.binding)
|
48
|
+
else
|
49
|
+
html << %{</ul>}
|
50
|
+
html
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def alt_rows
|
55
|
+
%{class="#{cycle('alt', '')}"}
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<h2>Editing <%= singular_name.humanize.capitalize %></h2>
|
2
|
+
|
3
|
+
<%%= admin_controls :<%= table_name %>, :for => :edit, :object => @<%= singular_name %> %>
|
4
|
+
|
5
|
+
<%%= error_messages_for :<%= singular_name %> %>
|
6
|
+
|
7
|
+
<%% form_for(@<%= singular_name %>) do |f| %>
|
8
|
+
<%%= render :partial => 'form', :locals => {:f => f, :<%= singular_name %> => @<%= singular_name %>} %>
|
9
|
+
<p><%%= f.submit "Update" %></p>
|
10
|
+
<%% end %>
|
11
|
+
|
12
|
+
<%%= admin_controls :<%= table_name %>, :for => :edit, :object => @<%= singular_name %> %>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<h2><%= plural_name.humanize.capitalize %></h2>
|
2
|
+
|
3
|
+
<%%= admin_controls :<%= table_name %>, :for => :index %>
|
4
|
+
|
5
|
+
<%%= will_paginate(@<%= plural_name %>) %>
|
6
|
+
<table>
|
7
|
+
<tr>
|
8
|
+
<% attributes.each_with_index do |attribute, i| -%>
|
9
|
+
<th<% if i == 0 -%> class="first_col"<% end -%>><%%= sorterable_link :<%= attribute.name -%> %></th>
|
10
|
+
<% end -%>
|
11
|
+
<th>View</th>
|
12
|
+
<th>Edit</th>
|
13
|
+
<th>Delete</th>
|
14
|
+
</tr>
|
15
|
+
|
16
|
+
<%% @<%= plural_name %>.each do |<%= singular_name %>| %>
|
17
|
+
<tr id="<%%= dom_id(<%= singular_name %>) %>" <%%= alt_rows %>>
|
18
|
+
<% attributes.each_with_index do |attribute, i| -%>
|
19
|
+
<% if i == 0 -%><td class="first_col"><%%= link_to <%= singular_name %>.<%= attribute.name %>, <%= table_name.singularize %>_path(<%= singular_name %>) %></td><%- else -%>
|
20
|
+
<td><%%= h <%= singular_name %>.<%= attribute.name %> %></td>
|
21
|
+
<%- end -%>
|
22
|
+
<% end -%>
|
23
|
+
<td><%%= link_to image_tag('admin/icon_show.png'), <%= table_name.singularize %>_path(<%= singular_name %>) %></td>
|
24
|
+
<td><%%= link_to image_tag('admin/icon_edit.png'), edit_<%= table_name.singularize %>_path(<%= singular_name %>) %></td>
|
25
|
+
<td><%%= link_to image_tag('admin/icon_destroy.png'), <%= table_name.singularize %>_path(<%= singular_name %>), :confirm => 'Are you sure?', :method => :delete %></td>
|
26
|
+
</tr>
|
27
|
+
<%% end %>
|
28
|
+
</table>
|
29
|
+
<%%= will_paginate(@<%= plural_name %>) %>
|
30
|
+
|
31
|
+
<%%= admin_controls :<%= table_name %>, :for => :index %>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<h2><%= singular_name.humanize.capitalize %>: New</h2>
|
2
|
+
|
3
|
+
<%%= admin_controls :<%= table_name %>, :for => :new %>
|
4
|
+
|
5
|
+
<%%= error_messages_for :<%= singular_name %> %>
|
6
|
+
|
7
|
+
<%% form_for(@<%= singular_name %>) do |f| %>
|
8
|
+
<%%= render :partial => 'form', :locals => {:f => f, :<%= singular_name %> => @<%= singular_name %>} %>
|
9
|
+
<p><%%= f.submit "Create" %></p>
|
10
|
+
<%% end %>
|
11
|
+
|
12
|
+
<%%= admin_controls :<%= table_name %>, :for => :new %>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<h2><%= plural_name.humanize.capitalize %>: <%%= @<%= singular_name %>.to_s %></h2>
|
2
|
+
|
3
|
+
<%%= admin_controls :<%= table_name %>, :for => :show, :object => @<%= singular_name %> %>
|
4
|
+
|
5
|
+
<div id="<%%= dom_id(@<%= singular_name %>) %>">
|
6
|
+
<div class="fields_group">
|
7
|
+
<% attributes.each do |attribute| -%>
|
8
|
+
<h5><%= attribute.human_name %>:</h5>
|
9
|
+
<%%=h @<%= singular_name %>.<%= attribute.name %> %>
|
10
|
+
<% end -%>
|
11
|
+
</div>
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<%%= admin_controls :<%= table_name %>, :for => :show, :object => @<%= singular_name %> %>
|
data/lib/qadmin.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
unless defined?(ActiveSupport)
|
5
|
+
require 'active_support'
|
6
|
+
end
|
7
|
+
|
8
|
+
module Qadmin
|
9
|
+
VERSION = '0.1.0'
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'qadmin/helper'
|
13
|
+
require 'qadmin/controller'
|
data/rails/init.rb
ADDED
@@ -0,0 +1,94 @@
|
|
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
|
+
def initialize(runtime_args, runtime_options = {})
|
14
|
+
super
|
15
|
+
|
16
|
+
@controller_name = @args.shift || @name.pluralize
|
17
|
+
|
18
|
+
base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name)
|
19
|
+
@controller_class_name_without_nesting, @controller_singular_name, @controller_plural_name = inflect_names(base_name)
|
20
|
+
|
21
|
+
if @controller_class_nesting.empty?
|
22
|
+
@controller_class_name = @controller_class_name_without_nesting
|
23
|
+
else
|
24
|
+
@controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def manifest
|
29
|
+
record do |m|
|
30
|
+
klass # checks for class definition
|
31
|
+
# Check for class naming collisions.
|
32
|
+
m.class_collisions(controller_class_path, "#{controller_class_name}Controller")
|
33
|
+
|
34
|
+
# Controller, helper, views, and test directories.
|
35
|
+
m.directory(File.join('app','controllers', controller_class_path))
|
36
|
+
m.directory(File.join('app', 'helpers', controller_class_path))
|
37
|
+
m.directory(File.join('app', 'views', controller_class_path, controller_file_name))
|
38
|
+
m.directory(File.join('test', 'functional', controller_class_path))
|
39
|
+
m.directory(File.join('public','images','admin'))
|
40
|
+
|
41
|
+
#copy form over too
|
42
|
+
m.template("_form.html.erb",File.join('app','views', controller_class_path, controller_file_name, "_form.html.erb"))
|
43
|
+
|
44
|
+
# Layout and stylesheet.
|
45
|
+
m.template('layout.html.erb', File.join('app','views','layouts', "admin.html.erb"))
|
46
|
+
m.template('style.css', 'public/stylesheets/admin.css')
|
47
|
+
|
48
|
+
m.template(
|
49
|
+
'controller.rb', File.join('app','controllers', controller_class_path, "#{controller_file_name}_controller.rb")
|
50
|
+
)
|
51
|
+
|
52
|
+
m.template('shoulda_functional_test.rb', File.join('test','functional', controller_class_path, "#{controller_file_name}_controller_test.rb"))
|
53
|
+
|
54
|
+
m.route_resources controller_file_name
|
55
|
+
|
56
|
+
# Copy Icons
|
57
|
+
Dir[File.join(File.dirname(__FILE__),'templates','images/*')].each do |image|
|
58
|
+
m.file File.join('images',File.basename(image)), File.join('public','images','admin',File.basename(image))
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
protected
|
65
|
+
# Override with your own usage banner.
|
66
|
+
def banner
|
67
|
+
"Usage: #{$0} qadmin ModelName"
|
68
|
+
end
|
69
|
+
|
70
|
+
def scaffold_views
|
71
|
+
%w[ index show new edit ]
|
72
|
+
end
|
73
|
+
|
74
|
+
def model_name
|
75
|
+
class_name.demodulize
|
76
|
+
end
|
77
|
+
|
78
|
+
def klass
|
79
|
+
begin
|
80
|
+
require "#{file_name}" unless defined?(model_name.constantize)
|
81
|
+
rescue
|
82
|
+
raise "You must define the class #{model_name} before running qscaffold"
|
83
|
+
end
|
84
|
+
model_name.constantize
|
85
|
+
end
|
86
|
+
|
87
|
+
def attributes
|
88
|
+
klass.content_columns
|
89
|
+
end
|
90
|
+
|
91
|
+
def ignore_attributes
|
92
|
+
%w{created_at updated_at}.push klass.protected_attributes
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require File.dirname(__FILE__) + '<%= '/..' * controller_class_nesting_depth %>/../test_helper'
|
2
|
+
require '<%= controller_file_path %>_controller'
|
3
|
+
|
4
|
+
# Re-raise errors caught by the controller.
|
5
|
+
class <%= controller_class_name %>Controller; def rescue_action(e) raise e end; end
|
6
|
+
|
7
|
+
class <%= controller_class_name %>ControllerTest < Test::Unit::TestCase
|
8
|
+
fixtures :<%= model_name.tableize %>#, :users
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@controller = <%= controller_class_name %>Controller.new
|
12
|
+
@request = ActionController::TestRequest.new
|
13
|
+
@response = ActionController::TestResponse.new
|
14
|
+
#login_as(:aaron)
|
15
|
+
@<%= file_name %> = <%= model_name.tableize %>(!!FIXTURENAME)
|
16
|
+
end
|
17
|
+
|
18
|
+
# def test_should_require_login
|
19
|
+
# logout
|
20
|
+
# get :index
|
21
|
+
# assert_redirected_to_login
|
22
|
+
# end
|
23
|
+
|
24
|
+
def test_should_get_index
|
25
|
+
get :index
|
26
|
+
assert_response :success
|
27
|
+
assert assigns(:<%= model_name.tableize %>)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_should_get_new
|
31
|
+
get :new
|
32
|
+
assert_response :success
|
33
|
+
assert_select 'form'
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_should_create_<%= file_name %>
|
37
|
+
assert_difference '<%= model_name %>.count' do
|
38
|
+
post :create, :<%= file_name %> => <%= file_name %>_params
|
39
|
+
assert_redirected_to <%= table_name.singularize %>_path(assigns(:<%= file_name %>))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_should_show_<%= file_name %>
|
44
|
+
get :show, :id => @<%= file_name %>.id
|
45
|
+
assert_response :success
|
46
|
+
assert assigns(:<%= file_name %>)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_should_get_edit
|
50
|
+
get :edit, :id => @<%= file_name %>.id
|
51
|
+
assert_response :success
|
52
|
+
assert assigns(:<%= file_name %>)
|
53
|
+
assert_select 'form'
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_should_update_<%= file_name %>
|
57
|
+
assert_no_difference '<%= model_name %>.count' do
|
58
|
+
put :update, :id => @<%= file_name %>.id, :<%= file_name %> => <%= file_name %>_params
|
59
|
+
assert_redirected_to <%= table_name.singularize %>_path(assigns(:<%= file_name %>))
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_should_destroy_<%= file_name %>
|
64
|
+
assert_difference '<%= model_name %>.count', -1 do
|
65
|
+
delete :destroy, :id => @<%= file_name %>.id
|
66
|
+
assert_redirected_to <%= table_name %>_path
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
protected
|
72
|
+
def <%= file_name %>_params(options = {})
|
73
|
+
{
|
74
|
+
<%= attributes.collect { |a| ":#{a.name} => #{a.default}" }.join(', ') %>
|
75
|
+
}.update(options)
|
76
|
+
end
|
77
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|