bowtie 0.5.2 → 0.5.4
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/bowtie.gemspec +2 -2
- data/lib/bowtie/adapters/datamapper.rb +50 -43
- data/lib/bowtie/adapters/mongomapper.rb +42 -37
- data/lib/bowtie/admin.rb +1 -1
- data/lib/bowtie/core_extensions.rb +10 -6
- data/lib/bowtie/helpers.rb +4 -0
- data/lib/bowtie/public/css/bowtie.css +15 -0
- data/lib/bowtie/views/index.erb +1 -1
- data/lib/bowtie/views/show.erb +10 -0
- metadata +7 -5
data/bowtie.gemspec
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = %q{bowtie}
|
3
|
-
s.version = "0.5.
|
3
|
+
s.version = "0.5.4"
|
4
4
|
|
5
5
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
6
6
|
s.authors = ["Tomás Pollak"]
|
7
7
|
s.email = %q{tomas@forkhq.com}
|
8
|
-
s.date = %q{2012-04-
|
8
|
+
s.date = %q{2012-04-18}
|
9
9
|
s.description = %q{Simple admin scaffold for MongoMapper and DataMapper models.}
|
10
10
|
s.rubyforge_project = %q{bowtie}
|
11
11
|
s.summary = %q{MongoMapper & DataMapper admin interface}
|
@@ -22,6 +22,8 @@ module Bowtie
|
|
22
22
|
|
23
23
|
def self.create(model, params)
|
24
24
|
model.create(params)
|
25
|
+
rescue DataObjects::IntegrityError
|
26
|
+
model.new(params)
|
25
27
|
end
|
26
28
|
|
27
29
|
def self.get_associated(model, params)
|
@@ -71,69 +73,74 @@ module Bowtie
|
|
71
73
|
end
|
72
74
|
|
73
75
|
def show_pager(resources, path)
|
74
|
-
|
76
|
+
q = request.path["/search"] ? "?model=#{params[:model]}&q=#{params[:q]}" : ""
|
77
|
+
s = resources.pager.to_html(base_path + path + q) if resources.respond_to?(:pager)
|
75
78
|
end
|
76
79
|
|
77
80
|
end
|
78
81
|
|
79
|
-
|
82
|
+
module ClassMethods
|
80
83
|
|
81
|
-
|
84
|
+
def primary_key
|
85
|
+
key.first.name
|
86
|
+
end
|
82
87
|
|
83
|
-
|
84
|
-
|
85
|
-
|
88
|
+
def model_associations
|
89
|
+
return [] if relationships.nil? or relationships.empty?
|
90
|
+
if relationships.first.is_a?(Array)
|
91
|
+
return relationships
|
92
|
+
else
|
93
|
+
h = {}
|
94
|
+
relationships.map {|r| h[r.name] = r }
|
95
|
+
return h
|
96
|
+
end
|
97
|
+
end
|
86
98
|
|
87
|
-
|
88
|
-
|
89
|
-
|
99
|
+
def field_names
|
100
|
+
self.properties.collect{|p| p.name }
|
101
|
+
end
|
90
102
|
|
91
|
-
|
103
|
+
def boolean_fields
|
104
|
+
self.properties.map{|a| a.name if a.class == DataMapper::Property::Boolean}.compact
|
105
|
+
end
|
92
106
|
|
93
|
-
|
107
|
+
def searchable_fields
|
108
|
+
self.properties.map{|a| a.name if a.class == DataMapper::Property::String}.compact
|
109
|
+
end
|
94
110
|
|
95
|
-
|
96
|
-
|
97
|
-
|
111
|
+
def subtypes
|
112
|
+
begin
|
113
|
+
self.validators.first.last.map{|a,b| b = {a.field_name => a.options[:set]} if a.class == DataMapper::Validate::WithinValidator}.compact
|
114
|
+
rescue NoMethodError
|
115
|
+
# puts ' -- dm-validations gem not included. Cannot check subtypes for class.'
|
116
|
+
[]
|
117
|
+
end
|
118
|
+
end
|
98
119
|
|
99
|
-
|
100
|
-
|
101
|
-
if relationships.first.is_a?(Array)
|
102
|
-
return relationships
|
103
|
-
else
|
104
|
-
h = {}
|
105
|
-
relationships.map {|r| h[r.name] = r }
|
106
|
-
return h
|
120
|
+
def options_for_subtype(field)
|
121
|
+
self.validators.first.last.map{|a| a.options[:set] if a.class == DataMapper::Validate::WithinValidator && a.field_name == field}.compact.reduce
|
107
122
|
end
|
108
|
-
end
|
109
123
|
|
110
|
-
|
111
|
-
|
112
|
-
|
124
|
+
def relation_keys_include?(property)
|
125
|
+
self.relationships.map {|rel| true if property.to_sym == rel[1].child_key.first.name}.reduce
|
126
|
+
end
|
113
127
|
|
114
|
-
def boolean_fields
|
115
|
-
self.properties.map{|a| a.name if a.class == DataMapper::Property::Boolean}.compact
|
116
128
|
end
|
117
129
|
|
118
|
-
|
119
|
-
self.properties.map{|a| a.name if a.class == DataMapper::Property::String}.compact
|
120
|
-
end
|
130
|
+
end
|
121
131
|
|
122
|
-
|
123
|
-
begin
|
124
|
-
self.validators.first.last.map{|a,b| b = {a.field_name => a.options[:set]} if a.class == DataMapper::Validate::WithinValidator}.compact
|
125
|
-
rescue NoMethodError
|
126
|
-
# puts ' -- dm-validations gem not included. Cannot check subtypes for class.'
|
127
|
-
[]
|
128
|
-
end
|
129
|
-
end
|
132
|
+
module DataMapper::Resource
|
130
133
|
|
131
|
-
def
|
132
|
-
self.
|
134
|
+
def primary_key
|
135
|
+
send(self.class.primary_key)
|
133
136
|
end
|
134
137
|
|
135
|
-
def
|
136
|
-
|
138
|
+
def to_json
|
139
|
+
attributes.to_json
|
137
140
|
end
|
138
141
|
|
139
142
|
end
|
143
|
+
|
144
|
+
Bowtie.models.each do |mod|
|
145
|
+
mod.extend Bowtie::ClassMethods
|
146
|
+
end
|
@@ -9,7 +9,7 @@ module Bowtie
|
|
9
9
|
def self.search(model, q, page)
|
10
10
|
res = []
|
11
11
|
model.searchable_fields.each do |field|
|
12
|
-
res = res + model.
|
12
|
+
res = res + add_paging(model.where(field.to_sym => /#{q}/i), page).all
|
13
13
|
end
|
14
14
|
res.uniq
|
15
15
|
end
|
@@ -62,8 +62,9 @@ module Bowtie
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def get_page(counter)
|
65
|
+
str = request.path["/search"] ? "&model=#{params[:model]}&q=#{params[:q]}" : ""
|
65
66
|
i = (params[:page].to_i || 0) + counter
|
66
|
-
i == 0 ?
|
67
|
+
i == 0 ? str : "?page=#{i}#{str}"
|
67
68
|
end
|
68
69
|
|
69
70
|
def show_pager(resources, path)
|
@@ -76,54 +77,58 @@ module Bowtie
|
|
76
77
|
|
77
78
|
end
|
78
79
|
|
79
|
-
|
80
|
+
module ClassMethods
|
80
81
|
|
81
|
-
|
82
|
+
def primary_key
|
83
|
+
'id'
|
84
|
+
end
|
82
85
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
+
def model_associations
|
87
|
+
associations
|
88
|
+
end
|
86
89
|
|
87
|
-
|
90
|
+
def field_names
|
91
|
+
self.keys.keys.collect { |f| f.to_sym }
|
92
|
+
end
|
88
93
|
|
89
|
-
|
94
|
+
def boolean_fields
|
95
|
+
s = []
|
96
|
+
self.keys.each {|k,v| s << k if v.type == Boolean}
|
97
|
+
s.compact
|
98
|
+
end
|
90
99
|
|
91
|
-
|
92
|
-
|
93
|
-
|
100
|
+
def searchable_fields
|
101
|
+
s = []
|
102
|
+
self.keys.each {|k,v| s << k if v.type == String && k != "_type"}
|
103
|
+
s.compact
|
104
|
+
end
|
94
105
|
|
95
|
-
|
96
|
-
|
97
|
-
|
106
|
+
def subtypes
|
107
|
+
s = []
|
108
|
+
self.keys.each {|k,v| s << k if v.type.class == Array}
|
109
|
+
s.compact
|
110
|
+
end
|
98
111
|
|
99
|
-
|
100
|
-
|
101
|
-
|
112
|
+
def options_for_subtype(field)
|
113
|
+
self.keys[field].type
|
114
|
+
end
|
102
115
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
s.compact
|
107
|
-
end
|
116
|
+
def relation_keys_include?(key)
|
117
|
+
self.associations.map {|rel| true if key.to_sym == rel[0]}.reduce
|
118
|
+
end
|
108
119
|
|
109
|
-
def searchable_fields
|
110
|
-
s = []
|
111
|
-
self.keys.each {|k,v| s << k if v.type == String && k != "_type"}
|
112
|
-
s.compact
|
113
120
|
end
|
114
121
|
|
115
|
-
|
116
|
-
s = []
|
117
|
-
self.keys.each {|k,v| s << k if v.type.class == Array}
|
118
|
-
s.compact
|
119
|
-
end
|
122
|
+
end
|
120
123
|
|
121
|
-
|
122
|
-
self.keys[field].type
|
123
|
-
end
|
124
|
+
module MongoMapper::Document
|
124
125
|
|
125
|
-
def
|
126
|
-
self.
|
126
|
+
def primary_key
|
127
|
+
send(self.class.primary_key)
|
127
128
|
end
|
128
129
|
|
129
130
|
end
|
131
|
+
|
132
|
+
Bowtie.models.each do |mod|
|
133
|
+
mod.extend Bowtie::ClassMethods
|
134
|
+
end
|
data/lib/bowtie/admin.rb
CHANGED
@@ -71,7 +71,7 @@ module Bowtie
|
|
71
71
|
res = Bowtie.get_associated(model, params)
|
72
72
|
|
73
73
|
@model = get_model_class(params[:association])
|
74
|
-
redirect
|
74
|
+
redirect referer + '?error=doesnt+exist' if res.nil? or (res.is_a?(Array) and res.empty?)
|
75
75
|
|
76
76
|
if res.is_a?(Array)
|
77
77
|
@resources = Bowtie.add_paging(res, params[:page])
|
@@ -1,7 +1,15 @@
|
|
1
1
|
# if we have active support, lets use it
|
2
2
|
# otherwise add the few needed methods to avoid loading it
|
3
3
|
|
4
|
-
|
4
|
+
begin
|
5
|
+
|
6
|
+
require 'active_support/inflections'
|
7
|
+
|
8
|
+
class String
|
9
|
+
include ActiveSupport::Inflections
|
10
|
+
end
|
11
|
+
|
12
|
+
rescue
|
5
13
|
|
6
14
|
class String
|
7
15
|
|
@@ -9,10 +17,6 @@ unless defined?(ActiveSupport::Inflector)
|
|
9
17
|
self.capitalize.gsub('_',' ')
|
10
18
|
end
|
11
19
|
|
12
|
-
def singularize
|
13
|
-
self.gsub(/ies/,'y').gsub(/s$/, '')
|
14
|
-
end
|
15
|
-
|
16
20
|
def pluralize
|
17
21
|
self.gsub(/y$/,'ie') + "s"
|
18
22
|
end
|
@@ -49,7 +53,7 @@ class Class
|
|
49
53
|
end
|
50
54
|
|
51
55
|
def pluralize
|
52
|
-
|
56
|
+
self.to_s.pluralize
|
53
57
|
end
|
54
58
|
|
55
59
|
end
|
data/lib/bowtie/helpers.rb
CHANGED
@@ -30,6 +30,10 @@ module Bowtie
|
|
30
30
|
def redirect(uri, *args)
|
31
31
|
super base_path + uri.downcase, *args
|
32
32
|
end
|
33
|
+
|
34
|
+
def referer
|
35
|
+
URI.parse(@env['HTTP_REFERER']).path.sub("#{base_path}", '')
|
36
|
+
end
|
33
37
|
|
34
38
|
def clean_params
|
35
39
|
@env['rack.request.query_hash'].delete_if{|a,b| %w(model page notice error q).include?(a) }
|
@@ -287,6 +287,21 @@ table tr:hover td{
|
|
287
287
|
background: #ffffed;
|
288
288
|
}
|
289
289
|
|
290
|
+
|
291
|
+
/* show resource
|
292
|
+
-------------------------------------------------------------*/
|
293
|
+
|
294
|
+
#assocs{
|
295
|
+
float: right;
|
296
|
+
font-size: 1.2em;
|
297
|
+
border: 1px solid #333;
|
298
|
+
padding: 5px 10px;
|
299
|
+
margin-top: 15px;
|
300
|
+
-moz-border-radius: 5px;
|
301
|
+
-webkit-border-radius: 5px;
|
302
|
+
background-color: #fafafa;
|
303
|
+
}
|
304
|
+
|
290
305
|
/* forms
|
291
306
|
-------------------------------------------------------------*/
|
292
307
|
|
data/lib/bowtie/views/index.erb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
<%= partial(:search) %>
|
4
4
|
<a class="edit-button" href="#" title="Enables in-place editing of editable fields" onclick="Bowtie.toggleEditableMode(this); return false;">Edit Mode OFF</a>
|
5
5
|
|
6
|
-
<h1><%= total_entries(@resources) %> <%= @title || @model.name.pluralize %> <a href="<%= model_path %>/new">(new)</a></h1>
|
6
|
+
<h1><%= total_entries(@resources) %> <%= @title || @model.name.pluralize %> <%= "containing '#{params[:q]}'" if params[:q] %> <a href="<%= model_path %>/new">(new)</a></h1>
|
7
7
|
|
8
8
|
<% if @resources.any? %>
|
9
9
|
|
data/lib/bowtie/views/show.erb
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
|
2
|
+
<div id="assocs">
|
3
|
+
|
4
|
+
<% @model.model_associations.each do |rel_name, assoc| %>
|
5
|
+
<%= rel_name %>: <strong><%= render_assoc_row(@resource, rel_name, assoc) %></strong>
|
6
|
+
<% end %>
|
7
|
+
|
8
|
+
</div><!-- /assocs -->
|
9
|
+
|
10
|
+
|
1
11
|
<h1><%= @title || @model.name + ':' + @resource.id.to_s %></h1>
|
2
12
|
|
3
13
|
<form class="big destroy" method="post" action="<%= model_path(@resource.class) %>/<%= @resource.id %>" onsubmit="return confirm('Are you sure?');">
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bowtie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 3
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 5
|
9
|
-
-
|
10
|
-
version: 0.5.
|
9
|
+
- 4
|
10
|
+
version: 0.5.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- "Tom\xC3\xA1s Pollak"
|
@@ -15,7 +15,8 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-04-
|
18
|
+
date: 2012-04-18 00:00:00 -04:00
|
19
|
+
default_executable:
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
21
22
|
name: sinatra
|
@@ -69,6 +70,7 @@ files:
|
|
69
70
|
- lib/bowtie/public/js/bowtie.js
|
70
71
|
- lib/bowtie/public/js/jquery.tablesorter.pack.js
|
71
72
|
- lib/bowtie/public/js/jquery.jeditable.pack.js
|
73
|
+
has_rdoc: true
|
72
74
|
homepage: http://github.com/tomas/bowtie
|
73
75
|
licenses: []
|
74
76
|
|
@@ -104,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
106
|
requirements: []
|
105
107
|
|
106
108
|
rubyforge_project: bowtie
|
107
|
-
rubygems_version: 1.
|
109
|
+
rubygems_version: 1.5.2
|
108
110
|
signing_key:
|
109
111
|
specification_version: 3
|
110
112
|
summary: MongoMapper & DataMapper admin interface
|