puffer 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,149 @@
1
+ # Puffer - YARAI (Yet Another Rails Admin Interface). Rails 3 only.
2
+
3
+ Puffer was created to help project owner or moderators view and edit all the project`s data models. It is rails 3 only
4
+
5
+ ## Keyfeatures
6
+
7
+ * Full rails integration. Puffer has no configs, just DSL to create interfaces. And this DLS depends on rails convensions.
8
+ * Flexibility. Puffer designed to be as flexible as possible, so you can create your own modules easily.
9
+ * I18n. Surely.
10
+ * Bla bla
11
+
12
+ ## Installation.
13
+
14
+ You can instal puffer as a gem:
15
+ <pre>gem install puffer</pre>
16
+ Or in Gemfile:
17
+ <pre>gem "puffer"</pre>
18
+ Next step is:
19
+ <pre>rails g puffer:install</pre>
20
+ This will install main puffer config file in your initializers and some css/js.
21
+
22
+ ## Introduction.
23
+
24
+ So, you have some data structure of your project. Let it`ll be like this:
25
+
26
+ <pre>
27
+ create_table "users", :force => true do |t|
28
+ t.string "email"
29
+ t.string "password"
30
+ t.datetime "created_at"
31
+ t.datetime "updated_at"
32
+ end
33
+
34
+ create_table "posts", :force => true do |t|
35
+ t.integer "user_id"
36
+ t.string "title"
37
+ t.text "body"
38
+ t.datetime "created_at"
39
+ t.datetime "updated_at"
40
+ end
41
+ </pre>
42
+
43
+ Also, you have two models:
44
+
45
+ <pre>
46
+ class User &lt; ActiveRecord::Base
47
+ has_many :posts
48
+ validates_presence_of :email, :password
49
+ validates_length_of :password, :minimum => 6
50
+ end
51
+ </pre>
52
+
53
+ <pre>
54
+ class Profile &lt; ActiveRecord::Base
55
+ belongs_to :user
56
+ validates_presence_of :name, :surname
57
+ end
58
+ </pre>
59
+
60
+ At first, lets generate puffers controllers:
61
+ <pre>rails g puffer:controller User</pre>
62
+ and
63
+ <pre>rails g puffer:controller Post</pre>
64
+
65
+ This will generate a kind of:
66
+ <pre>
67
+ class Admin::PostsController &lt; Puffer::Base
68
+ before_filter :i_didnt_forget_to_protect_this
69
+
70
+ index do
71
+ field :id
72
+ field :user_id
73
+ field :title
74
+ field :body
75
+ field :created_at
76
+ field :updated_at
77
+ end
78
+
79
+ form do
80
+ field :id
81
+ field :user_id
82
+ field :title
83
+ field :body
84
+ field :created_at
85
+ field :updated_at
86
+ end
87
+ end
88
+ </pre>
89
+
90
+ Puffer controller`s DSL creates all the actions we need. Next step - routing
91
+
92
+ <pre>
93
+ namespace :admin
94
+ resources :users do
95
+ resources :posts
96
+ end
97
+ resources :posts
98
+ end
99
+ </pre>
100
+
101
+ Let me explain this feature. Puffer tracks all the nested resources. So, with this routing structure we can access, for example, only specified user`s posts:
102
+
103
+ <pre>
104
+ /admin/users/1/post
105
+ </pre>
106
+
107
+ Routing nesting defines admin interface resources nesting.
108
+
109
+ ## Advanced usage
110
+
111
+ Puffer can be used in other namespaces, then admin:
112
+
113
+ <pre>rails g puffer:controller moderator/posts</pre>
114
+
115
+ And we`ll get posts controller for moderator:
116
+
117
+ <pre>
118
+ class Moderator::PostsController &lt; Puffer::Base
119
+ before_filter :require_moderator
120
+
121
+ config do
122
+ destroy false
123
+ group :posting
124
+ end
125
+
126
+ index do
127
+ field :user_id
128
+ field :title
129
+ field :body
130
+ end
131
+
132
+ form do
133
+ field :user_id
134
+ field :title
135
+ field :body
136
+ field :created_at
137
+ field :updated_at
138
+ end
139
+ end
140
+ </pre>
141
+
142
+ As you can see, moderators can not destroy posts, also moderator`s posts controller placed at Posting tab of admin interface.
143
+ And don`t forget about routing:
144
+
145
+ <pre>
146
+ namespace :moderator do
147
+ resources :posts
148
+ end
149
+ </pre>
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.6
1
+ 0.0.7
@@ -0,0 +1,21 @@
1
+ module PufferHelper
2
+
3
+ def render_head field
4
+ field.label
5
+ end
6
+
7
+ def render_field field, record
8
+ if field.options[:render]
9
+ case field.options[:render]
10
+ when Symbol then
11
+ res = send(field.options[:render], record)
12
+ when Proc then
13
+ res = field.options[:render].bind(self).call(record)
14
+ else ''
15
+ end
16
+ else
17
+ res = h(record.call_chain(field.name))
18
+ end
19
+ end
20
+
21
+ end
@@ -1,4 +1,4 @@
1
- <ul>
1
+ <ul class="form">
2
2
  <% (action == 'new' ? create_fields : update_fields).each do |field| -%>
3
3
  <li><%= f.puffer_field field %></li>
4
4
  <% end -%>
@@ -1,49 +1,37 @@
1
1
  <% @title = resource.human %>
2
2
  <h1><%= @title %></h1>
3
- <%= will_paginate @records, :url => resource.index_path(:page => '') %>
4
- <div class="columns">
5
- <div class="row">
6
- <div class="column left_column">
7
- <% if @records.empty? %>
8
- <p>Sorry, but there is no records in <%= resource.human %></p>
9
- <% else %>
10
- <table class="list_table">
11
- <thead>
12
- <tr>
13
- <% index_fields.each do |field| -%>
14
- <th><%= render_head field %></th>
15
- <% end -%>
16
- <th class="actions">Actions</th>
17
- </tr>
18
- </thead>
19
- <tbody>
20
- <% @records.each do |record| -%>
21
- <tr>
22
- <% index_fields.each do |field| -%>
23
- <td><%= render_field record, field %></td>
24
- <% end -%>
25
- <td class="actions">
26
- <%= link_to 'show', resource.path(record), :class => 'show_entry' if controller.show_fields || resource_children.present? %>
27
- <%= link_to 'edit', resource.edit_path(record), :class => 'edit_entry' if controller.update_fields || controller.form_fields %>
28
- <%= link_to 'destroy', resource.path(record), :confirm => "Are you sure?", :method => :delete, :class => 'remove_entry' if configuration.destroy %>
29
- <% resource.children(:post_id => record.id).each do |child| %>
30
- <% if child.plural? %>
31
- <p><%= link_to "#{child.human}(#{child.collection.size})", child.index_path %></p>
32
- <% else %>
33
- <p><%= link_to "#{child.member ? 'Edit' : 'Add'} #{child.human}", child.index_path %></p>
34
- <% end %>
35
- <% end %>
36
- </td>
37
- </tr>
38
- <% end -%>
39
- </tbody>
40
- </table>
41
- <% end %>
42
- </div>
43
- </div>
44
- </div>
45
- <%= will_paginate @records, :url => resource.index_path(:page => '') %>
3
+ <%= will_paginate records, :url => resource.index_path(:page => '') %>
4
+ <% if records.present? %>
5
+ <table class="list_table">
6
+ <thead>
7
+ <tr>
8
+ <% index_fields.each do |field| -%>
9
+ <th><%= render_head field %></th>
10
+ <% end -%>
11
+ <th class="actions">Actions</th>
12
+ </tr>
13
+ </thead>
14
+ <tbody>
15
+ <% records.each do |record| -%>
16
+ <tr>
17
+ <% index_fields.each do |field| -%>
18
+ <td><%= render_field field, record %></td>
19
+ <% end -%>
20
+ <td class="actions">
21
+ <%= link_to 'show', resource.path(record), :class => 'show_entry' if show_fields.present? || resource.children.present? %>
22
+ <%= link_to 'edit', resource.edit_path(record), :class => 'edit_entry' if update_fields.present? %>
23
+ <%= link_to 'destroy', resource.path(record), :confirm => "Are you sure?", :method => :delete, :class => 'remove_entry' if configuration.destroy %>
24
+ </td>
25
+ </tr>
26
+ <% end -%>
27
+ </tbody>
28
+ </table>
29
+ <% else %>
30
+ <p>Sorry, but there is no records in <%= resource.human %></p>
31
+ <% end %>
32
+ <%= will_paginate records, :url => resource.index_path(:page => '') %>
46
33
 
34
+ <% if false %>
47
35
  <% content_for :additional_navigation do %>
48
36
  <ul class="buttons">
49
37
  <% resource.ancestors.each do |resource| %>
@@ -53,4 +41,5 @@
53
41
  <%= link_to resource.plural? ? resource.human : resource.member.to_title, resource.index_path %>
54
42
  </ul>
55
43
  <% end %>
44
+ <% end %>
56
45
 
@@ -20,6 +20,12 @@ a:hover
20
20
  text-decoration: none;
21
21
  }
22
22
 
23
+ h1
24
+ {
25
+ font-size: 21px;
26
+ margin-bottom: 10px;
27
+ }
28
+
23
29
  .body
24
30
  {
25
31
  position: relative;
@@ -166,3 +172,118 @@ a:hover
166
172
  background: #fff;
167
173
  padding: 15px;
168
174
  }
175
+
176
+ .list_table
177
+ {
178
+ width: 100%;
179
+ margin: 0;
180
+ line-height: 140%;
181
+ border-collapse: separate;
182
+ border-spacing: 0px;
183
+ border: 1px solid #ddd;
184
+ border-radius: 5px;
185
+ -moz-border-radius: 5px;
186
+ -webkit-border-radius: 5px;
187
+ }
188
+
189
+ .list_table tr
190
+ {
191
+ vertical-align: top;
192
+ }
193
+
194
+ .list_table th.actions
195
+ {
196
+ position: static;
197
+ }
198
+
199
+ .list_table td.actions
200
+ {
201
+ position: static;
202
+ white-space: nowrap;
203
+ width: 100px;
204
+ }
205
+
206
+ .list_table td.actions a
207
+ {
208
+ line-height: 140%;
209
+ }
210
+
211
+ .list_table th
212
+ {
213
+ text-align: left;
214
+ background: #eee;
215
+ white-space: nowrap;
216
+ overflow: hidden;
217
+ max-width: 15px;
218
+ }
219
+
220
+ .list_table th a
221
+ {
222
+ text-decoration: none;
223
+ border-bottom: 1px dotted #333;
224
+ }
225
+
226
+ .list_table th a:hover
227
+ {
228
+ border-bottom: none;
229
+ }
230
+
231
+ .list_table td, .list_table th
232
+ {
233
+ padding: 5px;
234
+ }
235
+
236
+ .list_table td:first-child, .list_table th:first-child
237
+ {
238
+ padding-left: 10px;
239
+ }
240
+
241
+ .list_table td:last-child, .list_table th:last-child
242
+ {
243
+ padding-right: 10px;
244
+ }
245
+ .list_table td
246
+ {
247
+ border-bottom: 1px solid #ddd;
248
+ vertical-align: top;
249
+ }
250
+
251
+ .list_table tr:last-child td
252
+ {
253
+ border: none;
254
+ }
255
+
256
+ .list_table tbody tr:hover
257
+ {
258
+ background: #f4f4f4;
259
+ }
260
+
261
+ .form
262
+ {
263
+ margin-bottom: 30px;
264
+ }
265
+
266
+ .form li
267
+ {
268
+ list-style: none;
269
+ margin-bottom: 8px;
270
+ }
271
+
272
+ .form li label
273
+ {
274
+ display: block;
275
+ font-size: 11pt;
276
+ font-weight: bold;
277
+ }
278
+
279
+ .form li input[type=text], .form li input[type=password], .form li textarea
280
+ {
281
+ border: #ccc solid 1px;
282
+ width: 100%;
283
+ font-size: 12pt;
284
+ }
285
+
286
+ .form li textarea
287
+ {
288
+ height: 60px;
289
+ }
data/lib/puffer/base.rb CHANGED
@@ -40,7 +40,7 @@ module Puffer
40
40
  def destroy
41
41
  @record = resource.member
42
42
  @record.destroy
43
- redirect_to resource.path
43
+ redirect_to (request.referrer || resource.index_path)
44
44
  end
45
45
 
46
46
  end
@@ -9,7 +9,7 @@ module Puffer
9
9
 
10
10
  puffer_class_attribute :group, :default
11
11
  puffer_class_attribute :model
12
- puffer_class_attribute :destroy, false
12
+ puffer_class_attribute :destroy, true
13
13
 
14
14
  helper_method :configuration
15
15
  end
@@ -7,6 +7,7 @@ module Puffer
7
7
  extend ClassMethods
8
8
 
9
9
  layout 'puffer'
10
+ helper 'puffer'
10
11
  helper_method :puffer?
11
12
 
12
13
  self.view_paths = Puffer::PathSet.new view_paths
data/lib/puffer/fields.rb CHANGED
@@ -19,7 +19,7 @@ module Puffer
19
19
  :password if field.name =~ /password/
20
20
  end
21
21
  offer_type do |field|
22
- field.model.reflect_on_association(name.to_sym).macro if field.model.reflect_on_association name.to_sym
22
+ field.model.reflect_on_association(field.name.to_sym).macro if field.model.reflect_on_association field.name.to_sym
23
23
  end
24
24
 
25
25
  def field *args
data/puffer.gemspec CHANGED
@@ -5,15 +5,15 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{puffer}
8
- s.version = "0.0.6"
8
+ s.version = "0.0.7"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["pyromaniac"]
12
- s.date = %q{2011-01-27}
12
+ s.date = %q{2011-01-28}
13
13
  s.description = %q{In Soviet Russia puffer admins you}
14
14
  s.email = %q{kinwizard@gmail.com}
15
15
  s.extra_rdoc_files = [
16
- "README.rdoc"
16
+ "README.md"
17
17
  ]
18
18
  s.files = [
19
19
  ".rspec",
@@ -21,12 +21,13 @@ Gem::Specification.new do |s|
21
21
  "Gemfile",
22
22
  "Gemfile.lock",
23
23
  "MIT-LICENSE",
24
- "README.rdoc",
24
+ "README.md",
25
25
  "Rakefile",
26
26
  "VERSION",
27
27
  "app/cells/puffer/base/additional.html.erb",
28
28
  "app/cells/puffer/base_cell.rb",
29
29
  "app/controllers/admin/dashboard_controller.rb",
30
+ "app/helpers/puffer_helper.rb",
30
31
  "app/views/admin/dashboard/index.html.erb",
31
32
  "app/views/layouts/puffer.html.erb",
32
33
  "app/views/puffer/_form.html.erb",
@@ -20,6 +20,12 @@ a:hover
20
20
  text-decoration: none;
21
21
  }
22
22
 
23
+ h1
24
+ {
25
+ font-size: 21px;
26
+ margin-bottom: 10px;
27
+ }
28
+
23
29
  .body
24
30
  {
25
31
  position: relative;
@@ -166,3 +172,118 @@ a:hover
166
172
  background: #fff;
167
173
  padding: 15px;
168
174
  }
175
+
176
+ .list_table
177
+ {
178
+ width: 100%;
179
+ margin: 0;
180
+ line-height: 140%;
181
+ border-collapse: separate;
182
+ border-spacing: 0px;
183
+ border: 1px solid #ddd;
184
+ border-radius: 5px;
185
+ -moz-border-radius: 5px;
186
+ -webkit-border-radius: 5px;
187
+ }
188
+
189
+ .list_table tr
190
+ {
191
+ vertical-align: top;
192
+ }
193
+
194
+ .list_table th.actions
195
+ {
196
+ position: static;
197
+ }
198
+
199
+ .list_table td.actions
200
+ {
201
+ position: static;
202
+ white-space: nowrap;
203
+ width: 100px;
204
+ }
205
+
206
+ .list_table td.actions a
207
+ {
208
+ line-height: 140%;
209
+ }
210
+
211
+ .list_table th
212
+ {
213
+ text-align: left;
214
+ background: #eee;
215
+ white-space: nowrap;
216
+ overflow: hidden;
217
+ max-width: 15px;
218
+ }
219
+
220
+ .list_table th a
221
+ {
222
+ text-decoration: none;
223
+ border-bottom: 1px dotted #333;
224
+ }
225
+
226
+ .list_table th a:hover
227
+ {
228
+ border-bottom: none;
229
+ }
230
+
231
+ .list_table td, .list_table th
232
+ {
233
+ padding: 5px;
234
+ }
235
+
236
+ .list_table td:first-child, .list_table th:first-child
237
+ {
238
+ padding-left: 10px;
239
+ }
240
+
241
+ .list_table td:last-child, .list_table th:last-child
242
+ {
243
+ padding-right: 10px;
244
+ }
245
+ .list_table td
246
+ {
247
+ border-bottom: 1px solid #ddd;
248
+ vertical-align: top;
249
+ }
250
+
251
+ .list_table tr:last-child td
252
+ {
253
+ border: none;
254
+ }
255
+
256
+ .list_table tbody tr:hover
257
+ {
258
+ background: #f4f4f4;
259
+ }
260
+
261
+ .form
262
+ {
263
+ margin-bottom: 30px;
264
+ }
265
+
266
+ .form li
267
+ {
268
+ list-style: none;
269
+ margin-bottom: 8px;
270
+ }
271
+
272
+ .form li label
273
+ {
274
+ display: block;
275
+ font-size: 11pt;
276
+ font-weight: bold;
277
+ }
278
+
279
+ .form li input[type=text], .form li input[type=password], .form li textarea
280
+ {
281
+ border: #ccc solid 1px;
282
+ width: 100%;
283
+ font-size: 12pt;
284
+ }
285
+
286
+ .form li textarea
287
+ {
288
+ height: 60px;
289
+ }
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puffer
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 17
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 6
10
- version: 0.0.6
9
+ - 7
10
+ version: 0.0.7
11
11
  platform: ruby
12
12
  authors:
13
13
  - pyromaniac
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-01-27 00:00:00 +03:00
18
+ date: 2011-01-28 00:00:00 +03:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -188,19 +188,20 @@ executables: []
188
188
  extensions: []
189
189
 
190
190
  extra_rdoc_files:
191
- - README.rdoc
191
+ - README.md
192
192
  files:
193
193
  - .rspec
194
194
  - .rvmrc
195
195
  - Gemfile
196
196
  - Gemfile.lock
197
197
  - MIT-LICENSE
198
- - README.rdoc
198
+ - README.md
199
199
  - Rakefile
200
200
  - VERSION
201
201
  - app/cells/puffer/base/additional.html.erb
202
202
  - app/cells/puffer/base_cell.rb
203
203
  - app/controllers/admin/dashboard_controller.rb
204
+ - app/helpers/puffer_helper.rb
204
205
  - app/views/admin/dashboard/index.html.erb
205
206
  - app/views/layouts/puffer.html.erb
206
207
  - app/views/puffer/_form.html.erb
data/README.rdoc DELETED
@@ -1,3 +0,0 @@
1
- = Puffer
2
-
3
- This project rocks and uses MIT-LICENSE.