dobro 0.1.0alpha3
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/.gitignore +7 -0
- data/Gemfile +3 -0
- data/HISTORY +2 -0
- data/LICENCE +20 -0
- data/README.textile +70 -0
- data/Rakefile +11 -0
- data/app/assets/images/icons/pencil.png +0 -0
- data/app/assets/images/icons/plus.png +0 -0
- data/app/assets/images/icons/x.png +0 -0
- data/app/assets/images/input-shade-focus.gif +0 -0
- data/app/assets/images/input-shade.gif +0 -0
- data/app/assets/images/ridge-border.gif +0 -0
- data/app/assets/stylesheets/dobro.css.scss.erb +421 -0
- data/app/assets/stylesheets/dobro/_colours.css.scss +3 -0
- data/app/assets/stylesheets/dobro/_fonts.css.scss +4 -0
- data/app/assets/stylesheets/dobro/_reset.css.scss +22 -0
- data/app/controllers/dobro/application_controller.rb +51 -0
- data/app/views/dobro/application/_form.html.erb +14 -0
- data/app/views/dobro/application/_show.html.erb +6 -0
- data/app/views/dobro/application/delete.html.erb +5 -0
- data/app/views/dobro/application/edit.html.erb +1 -0
- data/app/views/dobro/application/index.html.erb +0 -0
- data/app/views/dobro/application/new.html.erb +1 -0
- data/app/views/dobro/application/show.html.erb +16 -0
- data/app/views/layouts/dobro.html.erb +59 -0
- data/config.ru +7 -0
- data/dobro.gemspec +31 -0
- data/lib/dobro.rb +24 -0
- data/lib/dobro/engine.rb +7 -0
- data/lib/dobro/file_system_resolver.rb +14 -0
- data/lib/dobro/routes.rb +23 -0
- data/lib/dobro/version.rb +3 -0
- data/spec/acceptance/custom_actions_spec.rb +18 -0
- data/spec/acceptance/custom_views_spec.rb +33 -0
- data/spec/acceptance/standard_namespace_spec.rb +51 -0
- data/spec/internal/app/controllers/tasks_controller.rb +6 -0
- data/spec/internal/app/models/page.rb +5 -0
- data/spec/internal/app/models/task.rb +5 -0
- data/spec/internal/app/models/widget.rb +5 -0
- data/spec/internal/app/views/dobro/widgets/_form.html.erb +12 -0
- data/spec/internal/app/views/dobro/widgets/show.html.erb +16 -0
- data/spec/internal/app/views/tasks/_show.html.erb +8 -0
- data/spec/internal/app/views/tasks/approving.html.erb +5 -0
- data/spec/internal/config/database.yml +3 -0
- data/spec/internal/config/routes.rb +11 -0
- data/spec/internal/db/schema.rb +17 -0
- data/spec/internal/log/.gitignore +1 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/spec_helper.rb +20 -0
- metadata +194 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td {
|
2
|
+
margin: 0;
|
3
|
+
padding: 0;
|
4
|
+
font-size: 100%;
|
5
|
+
vertical-align: baseline;
|
6
|
+
border: 0;
|
7
|
+
outline: 0;
|
8
|
+
background: transparent;
|
9
|
+
}
|
10
|
+
|
11
|
+
blockquote, q {
|
12
|
+
quotes: none;
|
13
|
+
}
|
14
|
+
|
15
|
+
:focus {
|
16
|
+
outline: 0;
|
17
|
+
}
|
18
|
+
|
19
|
+
table {
|
20
|
+
border-collapse: collapse;
|
21
|
+
border-spacing: 0;
|
22
|
+
}
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class Dobro::ApplicationController < Dobro.controller_base
|
2
|
+
layout 'dobro'
|
3
|
+
|
4
|
+
expose(:resource) { default_resource.to_sym }
|
5
|
+
expose(:singular_class) { singular_reference.capitalize.constantize }
|
6
|
+
expose(:plural_class) { resource.to_s.capitalize }
|
7
|
+
expose(:singular_reference) { resource.to_s.singularize }
|
8
|
+
expose(:records) { singular_class.all }
|
9
|
+
expose(:current_record) {
|
10
|
+
if params[:id]
|
11
|
+
singular_class.find params[:id]
|
12
|
+
else
|
13
|
+
singular_class.new params[singular_reference]
|
14
|
+
end
|
15
|
+
}
|
16
|
+
|
17
|
+
before_filter :prepend_view_paths
|
18
|
+
|
19
|
+
def create
|
20
|
+
if current_record.save
|
21
|
+
redirect_to current_record
|
22
|
+
else
|
23
|
+
render 'new'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def update
|
28
|
+
if current_record.update_attributes(params[singular_reference])
|
29
|
+
redirect_to current_record
|
30
|
+
else
|
31
|
+
render 'edit'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def destroy
|
36
|
+
current_record.destroy
|
37
|
+
redirect_to resource
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def default_resource
|
43
|
+
params[:resource] || Dobro.resources.first
|
44
|
+
end
|
45
|
+
|
46
|
+
def prepend_view_paths
|
47
|
+
view_paths.dup.each do |path|
|
48
|
+
prepend_view_path Dobro::FileSystemResolver.new(path.to_s, resource)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<%= form_for current_record do |f| %>
|
2
|
+
<fieldset>
|
3
|
+
<% singular_class.column_names.each do |column| %>
|
4
|
+
<p>
|
5
|
+
<%= f.label column.to_sym %>
|
6
|
+
<%= f.text_field column.to_sym %>
|
7
|
+
</p>
|
8
|
+
<% end %>
|
9
|
+
</fieldset>
|
10
|
+
|
11
|
+
<fieldset>
|
12
|
+
<%= f.submit "Save #{singular_class}" %>
|
13
|
+
</fieldset>
|
14
|
+
<% end %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render :partial => 'form' %>
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render :partial => 'form' %>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<header class="h2">
|
2
|
+
<h2><%= current_record.identifier %></h2>
|
3
|
+
|
4
|
+
<nav>
|
5
|
+
<ul>
|
6
|
+
<li>
|
7
|
+
<%= link_to 'Edit', [:edit, current_record], :class => 'edit' %>
|
8
|
+
</li>
|
9
|
+
<li>
|
10
|
+
<%= link_to 'Delete', [:delete, current_record], :class => 'cancel' %>
|
11
|
+
</li>
|
12
|
+
</ul>
|
13
|
+
</nav>
|
14
|
+
</header>
|
15
|
+
|
16
|
+
<%= render 'show' %>
|
@@ -0,0 +1,59 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Dobro</title>
|
5
|
+
<%= stylesheet_link_tag 'dobro' %>
|
6
|
+
<%= csrf_meta_tag %>
|
7
|
+
</head>
|
8
|
+
|
9
|
+
<body>
|
10
|
+
<header id="h1">
|
11
|
+
<h1><%= link_to 'Dobro', root_path %></h1>
|
12
|
+
</header>
|
13
|
+
|
14
|
+
<section class="body">
|
15
|
+
<section class="selector">
|
16
|
+
<header class="h3">
|
17
|
+
<h3>Sections</h3>
|
18
|
+
</header>
|
19
|
+
|
20
|
+
<ul class="records">
|
21
|
+
<% Dobro.resources.each do |res| %>
|
22
|
+
<li class="record">
|
23
|
+
<%= link_to res, :class => (resource == res && 'selected') do %>
|
24
|
+
<h4><%= res.to_s.titleize %></h4>
|
25
|
+
<% end %>
|
26
|
+
</li>
|
27
|
+
<% end %>
|
28
|
+
</ul>
|
29
|
+
</section>
|
30
|
+
|
31
|
+
<section class="selector">
|
32
|
+
<header class="h3">
|
33
|
+
<h3><%= plural_class.titleize %></h3>
|
34
|
+
<nav>
|
35
|
+
<ul>
|
36
|
+
<li><%= link_to "New #{singular_class}", [:new, singular_reference.to_sym], :class => 'new' %></li>
|
37
|
+
</ul>
|
38
|
+
</nav>
|
39
|
+
</header>
|
40
|
+
|
41
|
+
<ul class="records">
|
42
|
+
<% records.each do |record| %>
|
43
|
+
<li class="record"><h5><%= link_to record.identifier, record %></h5></li>
|
44
|
+
<% end %>
|
45
|
+
</ul>
|
46
|
+
</section>
|
47
|
+
|
48
|
+
<section class="view">
|
49
|
+
<div class="action">
|
50
|
+
<%= yield %>
|
51
|
+
</div>
|
52
|
+
</section>
|
53
|
+
</section>
|
54
|
+
|
55
|
+
<footer>
|
56
|
+
<p>Dobro</p>
|
57
|
+
</footer>
|
58
|
+
</body>
|
59
|
+
</html>
|
data/config.ru
ADDED
data/dobro.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "dobro/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'dobro'
|
7
|
+
s.version = Dobro::VERSION
|
8
|
+
s.authors = ['Brian Flanagan', 'Paul Campbell', 'Pat Allan']
|
9
|
+
s.email = ['pat@freelancing-gods.com']
|
10
|
+
s.homepage = 'http://github.com/hypertiny/dobro'
|
11
|
+
s.summary = %q{Simple, clean Rails admin interface}
|
12
|
+
s.description = %q{A Rails Engine that provides a simple yet effective interface, perfect for admin management.}
|
13
|
+
|
14
|
+
s.rubyforge_project = 'dobro'
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f|
|
19
|
+
File.basename(f)
|
20
|
+
}
|
21
|
+
s.require_paths = ['lib']
|
22
|
+
|
23
|
+
s.add_runtime_dependency 'rails', '~> 3.1.0rc1'
|
24
|
+
s.add_runtime_dependency 'decent_exposure', '~> 1.0'
|
25
|
+
s.add_runtime_dependency 'sass-rails', '~> 3.1.0.rc'
|
26
|
+
|
27
|
+
s.add_development_dependency 'rspec-rails', '~> 2.6.1'
|
28
|
+
s.add_development_dependency 'capybara', '~> 1.0.0'
|
29
|
+
s.add_development_dependency 'combustion', '~> 0.1.1'
|
30
|
+
s.add_development_dependency 'sqlite3', '~> 1.3.4'
|
31
|
+
end
|
data/lib/dobro.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require 'action_controller'
|
3
|
+
require 'decent_exposure'
|
4
|
+
|
5
|
+
module Dobro
|
6
|
+
@resources = []
|
7
|
+
def self.resources
|
8
|
+
@resources
|
9
|
+
end
|
10
|
+
|
11
|
+
@controller_base = ::ActionController::Base
|
12
|
+
def self.controller_base
|
13
|
+
@controller_base
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.controller_base=(value)
|
17
|
+
@controller_base = value
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'dobro/engine'
|
22
|
+
require 'dobro/file_system_resolver'
|
23
|
+
require 'dobro/routes'
|
24
|
+
require 'dobro/version'
|
data/lib/dobro/engine.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
class Dobro::FileSystemResolver < ActionView::FileSystemResolver
|
2
|
+
attr_reader :resource
|
3
|
+
|
4
|
+
def initialize(path, resource)
|
5
|
+
@resource = resource
|
6
|
+
|
7
|
+
super path
|
8
|
+
end
|
9
|
+
|
10
|
+
def find_templates(name, prefix, partial, details)
|
11
|
+
prefix = "dobro/#{resource}" if prefix == 'dobro/application'
|
12
|
+
super name, prefix, partial, details
|
13
|
+
end
|
14
|
+
end
|
data/lib/dobro/routes.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
class ActionDispatch::Routing::Mapper
|
2
|
+
def dobro_for(*resources)
|
3
|
+
options = resources.extract_options!
|
4
|
+
|
5
|
+
resources.each do |res|
|
6
|
+
Dobro.resources << res
|
7
|
+
|
8
|
+
self.resources res, dobro_options_for(res).merge(options) do
|
9
|
+
member { get :delete }
|
10
|
+
yield if block_given?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def dobro_options_for(resource)
|
18
|
+
{
|
19
|
+
:controller => 'dobro/application',
|
20
|
+
:defaults => {:resource => resource}
|
21
|
+
}
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'custom controller and actions' do
|
4
|
+
before :each do
|
5
|
+
Task.create :description => 'Test first', :approved => false
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'can use custom routes to approve a task' do
|
9
|
+
visit tasks_path
|
10
|
+
|
11
|
+
click_link 'Test first'
|
12
|
+
click_link 'Approve'
|
13
|
+
click_button 'Confirm'
|
14
|
+
|
15
|
+
first(:xpath, "//dd[preceding-sibling::dt[.='Approved']]").text.
|
16
|
+
should == 'true'
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'custom views', :driver => :rack_test do
|
4
|
+
before :each do
|
5
|
+
Widget.create! :name => 'Thing'
|
6
|
+
end
|
7
|
+
|
8
|
+
it "uses the custom show template" do
|
9
|
+
visit widgets_path
|
10
|
+
click_link 'Thing'
|
11
|
+
|
12
|
+
page.should have_content('Widget Name: Thing')
|
13
|
+
end
|
14
|
+
|
15
|
+
it "uses the custom form partial as part of the new view" do
|
16
|
+
visit widgets_path
|
17
|
+
|
18
|
+
click_link 'New Widget'
|
19
|
+
|
20
|
+
page.should have_content('Name')
|
21
|
+
page.should_not have_content('Created at')
|
22
|
+
end
|
23
|
+
|
24
|
+
it "uses the custom form partial as part of the edit view" do
|
25
|
+
visit widgets_path
|
26
|
+
|
27
|
+
click_link 'Thing'
|
28
|
+
click_link 'Edit'
|
29
|
+
|
30
|
+
page.should have_content('Name')
|
31
|
+
page.should_not have_content('Created at')
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'standard setup', :driver => :rack_test do
|
4
|
+
before :each do
|
5
|
+
Page.create :name => 'About Us', :content => 'All you need to know'
|
6
|
+
Page.create :name => 'FAQ', :content => 'All you need to ask'
|
7
|
+
end
|
8
|
+
|
9
|
+
it "lists the pages" do
|
10
|
+
visit pages_path
|
11
|
+
|
12
|
+
page.should have_content('Pages')
|
13
|
+
page.should have_content('About Us')
|
14
|
+
page.should have_content('FAQ')
|
15
|
+
end
|
16
|
+
|
17
|
+
it "creates a new page" do
|
18
|
+
visit pages_path
|
19
|
+
|
20
|
+
click_link 'New Page'
|
21
|
+
|
22
|
+
fill_in 'Name', :with => 'Contact Us'
|
23
|
+
fill_in 'Content', :with => 'A phone number or some such'
|
24
|
+
click_button 'Save Page'
|
25
|
+
|
26
|
+
page.should have_content('Contact Us')
|
27
|
+
end
|
28
|
+
|
29
|
+
it "edits an existing page" do
|
30
|
+
visit pages_path
|
31
|
+
|
32
|
+
click_link 'FAQ'
|
33
|
+
click_link 'Edit'
|
34
|
+
|
35
|
+
fill_in 'Name', :with => 'Common Questions'
|
36
|
+
click_button 'Save Page'
|
37
|
+
|
38
|
+
page.should have_content('Common Questions')
|
39
|
+
end
|
40
|
+
|
41
|
+
it "deletes pages" do
|
42
|
+
visit pages_path
|
43
|
+
|
44
|
+
click_link 'FAQ'
|
45
|
+
click_link 'Delete'
|
46
|
+
click_button 'Confirm'
|
47
|
+
|
48
|
+
page.should have_content('About Us')
|
49
|
+
page.should have_no_content('FAQ')
|
50
|
+
end
|
51
|
+
end
|