puffer 0.0.6 → 0.0.7

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/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.