rear 0.2.0

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.
Files changed (121) hide show
  1. checksums.yaml +15 -0
  2. data/.travis.yml +7 -0
  3. data/CHANGELOG.md +7 -0
  4. data/Gemfile +20 -0
  5. data/LICENSE +19 -0
  6. data/README.md +101 -0
  7. data/Rakefile +79 -0
  8. data/assets/api.js +307 -0
  9. data/assets/bootstrap-datetimepicker/css/bootstrap-datetimepicker.min.css +8 -0
  10. data/assets/bootstrap-datetimepicker/js/bootstrap-datetimepicker.min.js +26 -0
  11. data/assets/bootstrap/css/bootstrap-responsive.min.css +9 -0
  12. data/assets/bootstrap/css/bootstrap.min.css +9 -0
  13. data/assets/bootstrap/img/glyphicons-halflings-white.png +0 -0
  14. data/assets/bootstrap/img/glyphicons-halflings.png +0 -0
  15. data/assets/bootstrap/js/bootstrap.min.js +6 -0
  16. data/assets/jquery.js +5 -0
  17. data/assets/noty/jquery.noty.js +520 -0
  18. data/assets/noty/layouts/top.js +34 -0
  19. data/assets/noty/layouts/topRight.js +43 -0
  20. data/assets/noty/promise.js +432 -0
  21. data/assets/noty/themes/default.js +156 -0
  22. data/assets/select2-bootstrap.css +86 -0
  23. data/assets/select2/select2-spinner.gif +0 -0
  24. data/assets/select2/select2.css +652 -0
  25. data/assets/select2/select2.min.js +22 -0
  26. data/assets/select2/select2.png +0 -0
  27. data/assets/select2/select2x2.png +0 -0
  28. data/assets/ui.css +75 -0
  29. data/assets/xhr.js +4 -0
  30. data/bin/rear +65 -0
  31. data/docs/Assocs.md +100 -0
  32. data/docs/Columns.md +404 -0
  33. data/docs/Deploy.md +62 -0
  34. data/docs/FileManager.md +75 -0
  35. data/docs/Filters.md +341 -0
  36. data/docs/Setup.md +201 -0
  37. data/lib/rear.rb +13 -0
  38. data/lib/rear/actions.rb +98 -0
  39. data/lib/rear/constants.rb +61 -0
  40. data/lib/rear/controller_setup.rb +249 -0
  41. data/lib/rear/helpers.rb +17 -0
  42. data/lib/rear/helpers/class.rb +46 -0
  43. data/lib/rear/helpers/columns.rb +68 -0
  44. data/lib/rear/helpers/filters.rb +147 -0
  45. data/lib/rear/helpers/generic.rb +73 -0
  46. data/lib/rear/helpers/order.rb +47 -0
  47. data/lib/rear/helpers/pager.rb +35 -0
  48. data/lib/rear/helpers/render.rb +37 -0
  49. data/lib/rear/home_controller.rb +10 -0
  50. data/lib/rear/input.rb +341 -0
  51. data/lib/rear/orm.rb +73 -0
  52. data/lib/rear/rear.rb +74 -0
  53. data/lib/rear/setup.rb +9 -0
  54. data/lib/rear/setup/associations.rb +33 -0
  55. data/lib/rear/setup/columns.rb +109 -0
  56. data/lib/rear/setup/filters.rb +314 -0
  57. data/lib/rear/setup/generic.rb +59 -0
  58. data/lib/rear/setup/menu.rb +39 -0
  59. data/lib/rear/templates/editor/ace.slim +7 -0
  60. data/lib/rear/templates/editor/assocs.slim +10 -0
  61. data/lib/rear/templates/editor/boolean.slim +5 -0
  62. data/lib/rear/templates/editor/bulk_edit.slim +75 -0
  63. data/lib/rear/templates/editor/checkbox.slim +5 -0
  64. data/lib/rear/templates/editor/ckeditor.slim +7 -0
  65. data/lib/rear/templates/editor/date.slim +9 -0
  66. data/lib/rear/templates/editor/datetime.slim +9 -0
  67. data/lib/rear/templates/editor/layout.slim +103 -0
  68. data/lib/rear/templates/editor/password.slim +1 -0
  69. data/lib/rear/templates/editor/radio.slim +5 -0
  70. data/lib/rear/templates/editor/select.slim +3 -0
  71. data/lib/rear/templates/editor/string.slim +1 -0
  72. data/lib/rear/templates/editor/text.slim +1 -0
  73. data/lib/rear/templates/editor/time.slim +9 -0
  74. data/lib/rear/templates/error.slim +36 -0
  75. data/lib/rear/templates/filters/boolean.slim +10 -0
  76. data/lib/rear/templates/filters/checkbox.slim +15 -0
  77. data/lib/rear/templates/filters/date.slim +10 -0
  78. data/lib/rear/templates/filters/datetime.slim +10 -0
  79. data/lib/rear/templates/filters/layout.slim +26 -0
  80. data/lib/rear/templates/filters/radio.slim +14 -0
  81. data/lib/rear/templates/filters/select.slim +9 -0
  82. data/lib/rear/templates/filters/string.slim +3 -0
  83. data/lib/rear/templates/filters/text.slim +3 -0
  84. data/lib/rear/templates/filters/time.slim +10 -0
  85. data/lib/rear/templates/home.slim +0 -0
  86. data/lib/rear/templates/layout.slim +78 -0
  87. data/lib/rear/templates/pager.slim +22 -0
  88. data/lib/rear/templates/pane/ace.slim +2 -0
  89. data/lib/rear/templates/pane/assocs.slim +62 -0
  90. data/lib/rear/templates/pane/boolean.slim +2 -0
  91. data/lib/rear/templates/pane/checkbox.slim +5 -0
  92. data/lib/rear/templates/pane/ckeditor.slim +2 -0
  93. data/lib/rear/templates/pane/date.slim +2 -0
  94. data/lib/rear/templates/pane/datetime.slim +2 -0
  95. data/lib/rear/templates/pane/layout.slim +111 -0
  96. data/lib/rear/templates/pane/password.slim +2 -0
  97. data/lib/rear/templates/pane/quickview.slim +21 -0
  98. data/lib/rear/templates/pane/radio.slim +5 -0
  99. data/lib/rear/templates/pane/select.slim +5 -0
  100. data/lib/rear/templates/pane/string.slim +2 -0
  101. data/lib/rear/templates/pane/text.slim +2 -0
  102. data/lib/rear/templates/pane/time.slim +2 -0
  103. data/lib/rear/utils.rb +288 -0
  104. data/rear.gemspec +27 -0
  105. data/test/helpers.rb +33 -0
  106. data/test/models/ar.rb +52 -0
  107. data/test/models/dm.rb +53 -0
  108. data/test/models/sq.rb +58 -0
  109. data/test/setup.rb +4 -0
  110. data/test/templates/adhoc/book/editor/name.slim +1 -0
  111. data/test/templates/adhoc/book/editor/string.slim +1 -0
  112. data/test/templates/adhoc/book/pane/name.slim +1 -0
  113. data/test/templates/adhoc/book/pane/string.slim +1 -0
  114. data/test/templates/shared/shared-templates/editor/string.slim +1 -0
  115. data/test/templates/shared/shared-templates/pane/string.slim +1 -0
  116. data/test/test__assocs.rb +249 -0
  117. data/test/test__columns.rb +269 -0
  118. data/test/test__crud.rb +81 -0
  119. data/test/test__custom_templates.rb +147 -0
  120. data/test/test__filters.rb +228 -0
  121. metadata +220 -0
data/docs/Deploy.md ADDED
@@ -0,0 +1,62 @@
1
+
2
+ **Rear** can run in standalone mode or can be integrated/mounted into any `Espresso` application.
3
+
4
+ ## Running a standalone application:
5
+
6
+ `$ cat config.ru`
7
+ ```ruby
8
+ require 'rear'
9
+
10
+ # model
11
+ class Page < ActiveRecord::Base
12
+ # ...
13
+ end
14
+
15
+ # controller
16
+ Rear.register Page do
17
+ # some setups, if any
18
+ end
19
+
20
+ run Rear
21
+ ```
22
+
23
+ Then `$ rackup -s ServerName -p PortNumber` to start it.
24
+
25
+
26
+ ## Integrating Rear into existing Espresso application:
27
+
28
+ ```ruby
29
+ # models
30
+ class Page < ActiveRecord::Base
31
+ # ...
32
+ end
33
+
34
+ # backend controllers
35
+ Rear.register Page
36
+
37
+ # frontend controllers
38
+ module Frontend
39
+ class Pages < E
40
+ map '/'
41
+ # ...
42
+ end
43
+ end
44
+
45
+ # Espresso application
46
+ app = E.new
47
+
48
+ # mounting frontend controllers into root URL
49
+ app.mount Frontend, '/'
50
+
51
+ # mounting backend controllers into /admin URL
52
+ app.mount Rear.controllers, '/admin'
53
+
54
+ # starting app
55
+ app.run :server => ServerName, :port => PortNumber
56
+ ```
57
+
58
+ So basically mount **Rear.controllers** wherever you need.
59
+
60
+
61
+ **[ [contents &uarr;](https://github.com/espresso/rear#tutorial) ]**
62
+
@@ -0,0 +1,75 @@
1
+
2
+ When you need a web file manager simply create a controller
3
+ and set path to managed folder via `fm_root`:
4
+
5
+ ```ruby
6
+ class FileManager < E
7
+ include Rear
8
+ fm_root 'path/to/files/'
9
+ end
10
+ ```
11
+
12
+ That's all. Now you have a *FileManager* menu entry. Click on it to manage your files.
13
+
14
+ ## Text Editor
15
+
16
+ When you are dealing with files containing source code you need a specialized editor.
17
+
18
+ For now, Rear is offering support for [CKEditor](http://ckeditor.com) and [Ace](http://ace.ajax.org) editors.
19
+
20
+ Before using editors you'll have to install and load corresponding gems.
21
+
22
+ See [`rear-ckeditor`](https://github.com/espresso/rear-ckeditor) and
23
+ [`rear-ace`](https://github.com/espresso/rear-ace) for instructions.
24
+
25
+ After installed and loaded, simply use `fm_editor` to set desired editor:
26
+
27
+ ```ruby
28
+ class FileManager < E
29
+ include Rear
30
+ fm_root 'path/to/files/'
31
+
32
+ fm_editor :ace
33
+ # or
34
+ fm_editor :ckeditor
35
+ end
36
+ ```
37
+
38
+
39
+ ## Menu Label
40
+
41
+ If *FileManager* label is not suitable, use `label` to set custom menu label:
42
+
43
+ ```ruby
44
+ class FileManager < E
45
+ include Rear
46
+ fm_root '../public/images'
47
+
48
+ label :Images
49
+ end
50
+ ```
51
+ now it will display *Images* in menu.
52
+
53
+ ## Multiple
54
+
55
+ If you have multiple folders to manage, create a controller for each one.
56
+
57
+ Optionally you can put all file managers under same menu entry by using menu grouping:
58
+
59
+ ```ruby
60
+ class Templates < E
61
+ include Rear
62
+ fm_root '../views/'
63
+
64
+ menu_group :FileManager
65
+ end
66
+
67
+ class Images < E
68
+ include Rear
69
+ fm_root '../public/images'
70
+
71
+ menu_group :FileManager
72
+ end
73
+ ```
74
+ now you have *FileManager* menu entry that will reveal *Templates* and *Images* links on hover.
75
+
data/docs/Filters.md ADDED
@@ -0,0 +1,341 @@
1
+
2
+ By default **Rear** will add only the ability to filter by primary key.
3
+
4
+ To add more filters, use `filter`, `quick_filter` and `decorative_filter` methods.
5
+
6
+ The simplest case:
7
+
8
+ ```ruby
9
+ class Photo
10
+ include DataMapper::Resource
11
+ # ...
12
+ end
13
+
14
+ Rear.register Photo do
15
+ filter :name
16
+ end
17
+ ```
18
+
19
+
20
+ ## Filter Types
21
+
22
+ **Rear** supports following filter types:
23
+
24
+ - :string/:text
25
+ - :select
26
+ - :radio
27
+ - :checkbox
28
+ - :date
29
+ - :datetime
30
+ - :time
31
+ - :boolean
32
+
33
+ Filter type should be passed as second argument and should be a downcase symbol:
34
+
35
+ ```ruby
36
+
37
+ filter :created_at, :date
38
+
39
+ ```
40
+
41
+ If no type given, **it will be inherited** from a column with same name, if any:
42
+
43
+ ```ruby
44
+ class Page
45
+ include DataMapper::Resource
46
+ # ...
47
+ property :created_at, Date
48
+ end
49
+
50
+ Rear.register Page do
51
+ filter :created_at # type inherited automatically
52
+ end
53
+ ```
54
+
55
+ So, laziness is a virtue... sometimes...
56
+
57
+ **[ [contents &uarr;](https://github.com/espresso/rear#tutorial) ]**
58
+
59
+
60
+ ## Comparison Functions
61
+
62
+ `:string/:text` filters will use `:like` comparison function by default,
63
+ so `filter :name` will generate a SQL like:
64
+
65
+ ```
66
+ ... WHERE name LIKE '%VALUE%' ...
67
+ ```
68
+
69
+ `:checkbox` filters will use `:in` comparison function by default:
70
+
71
+ ```
72
+ ... WHERE column IN ('VALUE1', 'VALUE2') ...
73
+ ```
74
+
75
+ If you use a custom "cmp" function with a `:checkbox` filter,
76
+ filter's column will be compared to each selected value:
77
+
78
+ ```
79
+ ... WHERE (column LIKE '%VALUE1%' OR column LIKE '%VALUE2%') ...
80
+ ```
81
+
82
+ Filters of any other type will use equality for comparison function,
83
+ so a filter like `filter :created_at, :date` will generate an SQL like:
84
+
85
+ ```
86
+ ... WHERE created_at = 'VALUE' ...
87
+ ```
88
+
89
+ To use a custom comparison function pass it via `:cmp` option:
90
+
91
+ ```ruby
92
+
93
+ filter :created_at, cmp: :like
94
+
95
+ ```
96
+
97
+ Supported comparison functions:
98
+
99
+ - :eql # equal
100
+ - :not # not equal
101
+
102
+ - :gt # greater than
103
+ - :gte # greater than or equal
104
+ - :lt # less than
105
+ - :lte # less than or equal
106
+
107
+ - :like # uses left and right wildcards - "column LIKE '%VALUE%'"
108
+ - :unlike # - "column NOT LIKE '%VALUE%'"
109
+
110
+ - :_like # use only left wildcard, exact match for end of line - "column LIKE '%VALUE'"
111
+ - :_unlike # - "column NOT LIKE '%VALUE'"
112
+
113
+ - :like_ # use only right wildcard, exact match for beginning of line - "column LIKE 'VALUE%'"
114
+ - :unlike_ # - "column NOT LIKE 'VALUE%'"
115
+
116
+ **[ [contents &uarr;](https://github.com/espresso/rear#tutorial) ]**
117
+
118
+
119
+ ## Optioned Filters
120
+
121
+ `:radio`, `:checkbox` and `:select` filters requires a block to run.
122
+
123
+ Block should return an Array or Hash.
124
+
125
+ Arrays used when stored keys are the same as displayed values:
126
+
127
+ ```ruby
128
+
129
+ filter :color do
130
+ %w[Red Green Blue]
131
+ end
132
+
133
+ ```
134
+
135
+ If stored keys differs from displayed values, a `Hash` should be used:
136
+
137
+ ```ruby
138
+
139
+ filter :color do
140
+ {'r' => 'Red', 'g' => 'Green', 'b' => 'Blue'}
141
+ end
142
+
143
+ ```
144
+
145
+ In example above 'r', 'g' and 'b' are db values and 'Red', 'Green', 'Blue' are displayed values.
146
+
147
+ If no block given, **Rear** will search for a column with same name and inherit options from there.
148
+
149
+ So if you have say a `:checkbox` column named `:colors` with defined options,
150
+ you only need to do `filter :colors`, without specifying type and options,
151
+ cause type and options will be inherited from earlier defined column:
152
+
153
+
154
+ ```ruby
155
+
156
+ input :colors, :checkbox do
157
+ options 'Red', 'Green', 'Blue'
158
+ end
159
+
160
+ filter :colors # type and options inherited from :colors column
161
+
162
+ ```
163
+
164
+ So, laziness is definitely a virtue...
165
+
166
+ **[ [contents &uarr;](https://github.com/espresso/rear#tutorial) ]**
167
+
168
+
169
+ ## Decorative Filters
170
+
171
+ Sometimes you need to filter by some value that has too much options.
172
+
173
+ For ex. you want to filter pages by author and there are about 1000 authors in db.
174
+
175
+ Displaying all authors within a single dropdown filter is kinda cumbersome.
176
+
177
+ Decorative filters allow to narrow down the options displayed on other filters.
178
+
179
+ In example below authors will not be loaded until a letter selected:
180
+
181
+ ```ruby
182
+
183
+ decorative_filter :letter, :select do
184
+ ('A'..'Z').to_a
185
+ end
186
+
187
+ filter :author_id, :select do
188
+ if letter = filter?(:letter) # use the name of decorative filter with `filter?` method
189
+ authors = {}
190
+ model.all(name: /^#{letter}/).each |a|
191
+ authors[a.id] = a.name
192
+ end
193
+ authors
194
+ else
195
+ {"" => "Select a letter please"}
196
+ end
197
+ end
198
+
199
+ ```
200
+
201
+ A decorative filter will update filters every time new option selected and `filter?(:decorative_filter_name)` will return the selected option.
202
+
203
+ Worth to note that decorative filters will not actually query the db,
204
+ so you can name then as you want.
205
+
206
+ Also, decorative filters does not use/support custom comparison functions.
207
+
208
+ **[ [contents &uarr;](https://github.com/espresso/rear#tutorial) ]**
209
+
210
+
211
+ ## Quick Filters
212
+
213
+
214
+ A.k.a Button Filters, allows to filter through items by simply clicking a button.
215
+
216
+ For ex. you need to quickly display active items.
217
+
218
+ A standard filter will require from user to select some value then click "Search" button.
219
+
220
+ Quick filters instead will create an "Active" button that will display only active items when clicked.
221
+
222
+ As per standard filters, when stored keys are the same as values, use an `Array`.
223
+
224
+ ```ruby
225
+
226
+ quick_filter :color, 'Red', 'Green', 'Blue'
227
+
228
+ ```
229
+
230
+ This will create three grouped buttons that will display corresponding items on click.
231
+
232
+
233
+ And when keys are different, use a `Hash`:
234
+
235
+ ```ruby
236
+
237
+ quick_filter :color, 'r' => 'Red', 'g' => 'Green', 'b' => 'Blue'
238
+
239
+ ```
240
+
241
+ This will create three buttons - Red, Green, Blue - that on click will display items with color equal to 'r', 'g', 'b' respectively.
242
+
243
+ And of course, as per standard filters, if you do not provide options, they will be inherited from a column with same name, if any:
244
+
245
+ ```ruby
246
+ class Photo < ActiveRecord::Base
247
+ # ...
248
+ end
249
+
250
+ Rear.register Photo do
251
+
252
+ input :gamma, :checkbox do
253
+ options "Red", "Green", "Blue"
254
+ end
255
+
256
+ quick_filter :gamma # options are inherited from `:gamma` column
257
+ end
258
+ ```
259
+
260
+ By default, quick filters will use equality for comparison function.
261
+
262
+ To use a custom comparison function, set it via `:cmp` option:
263
+
264
+ ```ruby
265
+
266
+ quick_filter :color, 'Red', 'Green', 'Blue', cmp: :like
267
+
268
+ ```
269
+
270
+ **Hint** - if you need to filter through a column that has "cmp" as db value,
271
+ pass db value as string and cmp function as symbol:
272
+
273
+ ```ruby
274
+ quick_filter :action, 'cmp' => 'Compare', 'snd' => 'Send', cmp: :like
275
+ ```
276
+
277
+ It is also possible to use per filter comparison function:
278
+
279
+ ```ruby
280
+ quick_filter :color, [:like, 'r'] => 'Red', 'g' => 'Green', 'b' => 'Blue'
281
+ # when Red clicked, LIKE comparison function will be used.
282
+ # on Green and Blue, equality will be used.
283
+ ```
284
+
285
+ **[ [contents &uarr;](https://github.com/espresso/rear#tutorial) ]**
286
+
287
+
288
+ ## Internal Filters
289
+
290
+ Used when you need fine-tuned control over displayed items.
291
+
292
+ Internal filters wont render any inputs, they will work under the hood.
293
+
294
+ `internal_filter` requires a block that should return a list of matching items.
295
+
296
+ **Example:** Display only articles newer than 2010:
297
+
298
+ ```ruby
299
+ class Article
300
+ include DataMapper::Resource
301
+
302
+ property :id, Serial
303
+ # ...
304
+ property :created_at, Date, index: true
305
+ end
306
+
307
+ Rear.register Article do
308
+ # ...
309
+
310
+ internal_filter do
311
+ Article.all(:created_at.gt => Date.new(2010))
312
+ end
313
+ end
314
+ ```
315
+
316
+ **Example:** Filter articles by category:
317
+
318
+ ```ruby
319
+ class Article < ActiveRecord::Base
320
+ belongs_to :category
321
+ end
322
+
323
+ Rear.register Article do
324
+
325
+ # firstly lets render a decorative filter
326
+ # that will render a list of categories to choose from
327
+ decorative_filter :Category do
328
+ Hash[ Category.all.map {|c| [c.id, c.name]} ]
329
+ end
330
+
331
+ # then we using internal_filter
332
+ # to yield selected category and filter articles
333
+ internal_filter do
334
+ if category_id = filter?(:Category)
335
+ Article.all(category_id: category_id.to_i)
336
+ end
337
+ end
338
+ end
339
+ ```
340
+
341
+ **[ [contents &uarr;](https://github.com/espresso/rear#tutorial) ]**