tolaria 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (219) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +66 -0
  3. data/.yardopts +4 -0
  4. data/CNAME +1 -0
  5. data/CONTRIBUTING.md +32 -0
  6. data/Gemfile +2 -0
  7. data/LICENSE.md +9 -0
  8. data/README.md +538 -0
  9. data/Rakefile +52 -0
  10. data/app/assets/fonts/admin/fontawesome.eot +0 -0
  11. data/app/assets/fonts/admin/fontawesome.svg +565 -0
  12. data/app/assets/fonts/admin/fontawesome.ttf +0 -0
  13. data/app/assets/fonts/admin/fontawesome.woff +0 -0
  14. data/app/assets/fonts/admin/fontawesome.woff2 +0 -0
  15. data/app/assets/images/admin/columbia_banner.png +0 -0
  16. data/app/assets/images/admin/favicon.ico +0 -0
  17. data/app/assets/images/admin/noise.png +0 -0
  18. data/app/assets/images/admin/select_arrows.svg +1 -0
  19. data/app/assets/javascripts/admin/admin.js +4 -0
  20. data/app/assets/javascripts/admin/base.js +12 -0
  21. data/app/assets/javascripts/admin/lib/backbone.js +1888 -0
  22. data/app/assets/javascripts/admin/lib/jquery.chosen.js +1272 -0
  23. data/app/assets/javascripts/admin/lib/jquery.js +10361 -0
  24. data/app/assets/javascripts/admin/lib/jquery.selection.js +352 -0
  25. data/app/assets/javascripts/admin/lib/moment.js +3103 -0
  26. data/app/assets/javascripts/admin/lib/no.js +6 -0
  27. data/app/assets/javascripts/admin/lib/underscore.js +1570 -0
  28. data/app/assets/javascripts/admin/models/composer_buttons.js +45 -0
  29. data/app/assets/javascripts/admin/models/rails_meta.js +4 -0
  30. data/app/assets/javascripts/admin/views/field_with_errors.js +19 -0
  31. data/app/assets/javascripts/admin/views/fields/attachment_field.js +32 -0
  32. data/app/assets/javascripts/admin/views/fields/has_many.js +64 -0
  33. data/app/assets/javascripts/admin/views/fields/image_association_select.js +31 -0
  34. data/app/assets/javascripts/admin/views/fields/markdown_composer.js +167 -0
  35. data/app/assets/javascripts/admin/views/fields/searchable_select.js +70 -0
  36. data/app/assets/javascripts/admin/views/fields/slug_field.js +38 -0
  37. data/app/assets/javascripts/admin/views/fields/swatch_field.js +55 -0
  38. data/app/assets/javascripts/admin/views/fields/timestamp_field.js +80 -0
  39. data/app/assets/javascripts/admin/views/flash_message.js +18 -0
  40. data/app/assets/javascripts/admin/views/form_orchestrator.js +41 -0
  41. data/app/assets/javascripts/admin/views/navigation.js +20 -0
  42. data/app/assets/javascripts/admin/views/resource_form.js +18 -0
  43. data/app/assets/javascripts/admin/views/search_form.js +20 -0
  44. data/app/assets/javascripts/admin/views/sessions.js +109 -0
  45. data/app/assets/javascripts/admin/views/virtual_form.js +47 -0
  46. data/app/assets/stylesheets/admin/_base.scss +5 -0
  47. data/app/assets/stylesheets/admin/_reset.scss +149 -0
  48. data/app/assets/stylesheets/admin/_root.scss +63 -0
  49. data/app/assets/stylesheets/admin/admin.scss +4 -0
  50. data/app/assets/stylesheets/admin/components/_blank_slate.scss +44 -0
  51. data/app/assets/stylesheets/admin/components/_buttons.scss +82 -0
  52. data/app/assets/stylesheets/admin/components/_flash_message.scss +64 -0
  53. data/app/assets/stylesheets/admin/components/_footer.scss +9 -0
  54. data/app/assets/stylesheets/admin/components/_header.scss +107 -0
  55. data/app/assets/stylesheets/admin/components/_index_table.scss +120 -0
  56. data/app/assets/stylesheets/admin/components/_main.scss +68 -0
  57. data/app/assets/stylesheets/admin/components/_markdown_body.scss +109 -0
  58. data/app/assets/stylesheets/admin/components/_navigation.scss +110 -0
  59. data/app/assets/stylesheets/admin/components/_pagination.scss +36 -0
  60. data/app/assets/stylesheets/admin/components/_pill.scss +11 -0
  61. data/app/assets/stylesheets/admin/components/_resource_form.scss +222 -0
  62. data/app/assets/stylesheets/admin/components/_search_form.scss +36 -0
  63. data/app/assets/stylesheets/admin/components/_sessions.scss +152 -0
  64. data/app/assets/stylesheets/admin/components/_show_table.scss +67 -0
  65. data/app/assets/stylesheets/admin/components/forms/_attachment_field.scss +59 -0
  66. data/app/assets/stylesheets/admin/components/forms/_chosen.scss +478 -0
  67. data/app/assets/stylesheets/admin/components/forms/_image_association_select.scss +20 -0
  68. data/app/assets/stylesheets/admin/components/forms/_markdown_composer.scss +149 -0
  69. data/app/assets/stylesheets/admin/components/forms/_nested_fields.scss +63 -0
  70. data/app/assets/stylesheets/admin/components/forms/_searchable_select.scss +8 -0
  71. data/app/assets/stylesheets/admin/components/forms/_slug_field.scss +20 -0
  72. data/app/assets/stylesheets/admin/components/forms/_swatch_field.scss +47 -0
  73. data/app/assets/stylesheets/admin/components/forms/_timestamp_field.scss +15 -0
  74. data/app/assets/stylesheets/admin/components/help_link.scss +6 -0
  75. data/app/assets/stylesheets/admin/mixins/_clearfix.scss +18 -0
  76. data/app/assets/stylesheets/admin/mixins/_min_max_width.scss +11 -0
  77. data/app/assets/stylesheets/admin/mixins/_rgbb.scss +7 -0
  78. data/app/assets/stylesheets/admin/mixins/_visuallyhidden.scss +33 -0
  79. data/app/assets/stylesheets/admin/settings/_animations.scss +21 -0
  80. data/app/assets/stylesheets/admin/settings/_breakpoints.scss +2 -0
  81. data/app/assets/stylesheets/admin/settings/_colors.scss +32 -0
  82. data/app/assets/stylesheets/admin/settings/_fonts.scss +31 -0
  83. data/app/assets/stylesheets/admin/settings/_icons.scss +1658 -0
  84. data/app/controllers/admin/admin_controller.rb +21 -0
  85. data/app/controllers/admin/sessions_controller.rb +112 -0
  86. data/app/controllers/tolaria/resource_controller.rb +132 -0
  87. data/app/controllers/tolaria/tolaria_controller.rb +40 -0
  88. data/app/helpers/admin/table_helper.rb +175 -0
  89. data/app/helpers/admin/view_helper.rb +76 -0
  90. data/app/mailers/passcode_mailer.rb +11 -0
  91. data/app/models/administrator.rb +146 -0
  92. data/app/views/admin/administrators/_form.html.erb +16 -0
  93. data/app/views/admin/administrators/_index.html.erb +20 -0
  94. data/app/views/admin/administrators/_search.html.erb +5 -0
  95. data/app/views/admin/administrators/_show.html.erb +14 -0
  96. data/app/views/admin/help/help_link.html.erb +16 -0
  97. data/app/views/admin/session/form.html.erb +52 -0
  98. data/app/views/admin/shared/_flash_messages.html.erb +42 -0
  99. data/app/views/admin/shared/_footer.html.erb +8 -0
  100. data/app/views/admin/shared/_head.html.erb +11 -0
  101. data/app/views/admin/shared/_header.html.erb +43 -0
  102. data/app/views/admin/shared/_navigation.html.erb +47 -0
  103. data/app/views/admin/shared/_skiplinks.html.erb +0 -0
  104. data/app/views/admin/shared/forms/_attachment_field.html.erb +17 -0
  105. data/app/views/admin/shared/forms/_has_many.html.erb +14 -0
  106. data/app/views/admin/shared/forms/_has_many_header.html.erb +19 -0
  107. data/app/views/admin/shared/forms/_image_association_select.html.erb +6 -0
  108. data/app/views/admin/shared/forms/_image_field.html.erb +19 -0
  109. data/app/views/admin/shared/forms/_markdown_composer.html.erb +29 -0
  110. data/app/views/admin/shared/forms/_searchable_select.html.erb +3 -0
  111. data/app/views/admin/shared/forms/_slug_field.html.erb +9 -0
  112. data/app/views/admin/shared/forms/_swatch_field.html.erb +4 -0
  113. data/app/views/admin/shared/forms/_timestamp_field.html.erb +19 -0
  114. data/app/views/admin/tolaria_resource/_form_buttons.html.erb +10 -0
  115. data/app/views/admin/tolaria_resource/_index_table.html.erb +73 -0
  116. data/app/views/admin/tolaria_resource/_search_form.html.erb +32 -0
  117. data/app/views/admin/tolaria_resource/_show_buttons.html.erb +13 -0
  118. data/app/views/admin/tolaria_resource/edit.html.erb +34 -0
  119. data/app/views/admin/tolaria_resource/index.html.erb +36 -0
  120. data/app/views/admin/tolaria_resource/new.html.erb +1 -0
  121. data/app/views/admin/tolaria_resource/show.html.erb +52 -0
  122. data/app/views/kaminari/admin/_first_page.html.erb +9 -0
  123. data/app/views/kaminari/admin/_last_page.html.erb +9 -0
  124. data/app/views/kaminari/admin/_next_page.html.erb +9 -0
  125. data/app/views/kaminari/admin/_page.html.erb +17 -0
  126. data/app/views/kaminari/admin/_paginator.html.erb +21 -0
  127. data/app/views/kaminari/admin/_prev_page.html.erb +9 -0
  128. data/app/views/layouts/admin/admin.html.erb +21 -0
  129. data/app/views/layouts/admin/sessions.html.erb +12 -0
  130. data/app/views/passcode_mailer/passcode.text.erb +5 -0
  131. data/lib/generators/tolaria/install/install_generator.rb +21 -0
  132. data/lib/generators/tolaria/install/templates/administrators_migration.rb +31 -0
  133. data/lib/generators/tolaria/install/templates/tolaria_initializer.rb +93 -0
  134. data/lib/tasks/admin.rake +32 -0
  135. data/lib/tolaria.rb +27 -0
  136. data/lib/tolaria/active_record.rb +55 -0
  137. data/lib/tolaria/admin.rb +4 -0
  138. data/lib/tolaria/categories.rb +21 -0
  139. data/lib/tolaria/config.rb +40 -0
  140. data/lib/tolaria/default_config.rb +74 -0
  141. data/lib/tolaria/engine.rb +23 -0
  142. data/lib/tolaria/form_buildable.rb +203 -0
  143. data/lib/tolaria/help_links.rb +78 -0
  144. data/lib/tolaria/introspection.rb +13 -0
  145. data/lib/tolaria/manage.rb +57 -0
  146. data/lib/tolaria/managed_class.rb +90 -0
  147. data/lib/tolaria/markdown.rb +28 -0
  148. data/lib/tolaria/random_tokens.rb +16 -0
  149. data/lib/tolaria/reload.rb +21 -0
  150. data/lib/tolaria/routes.rb +33 -0
  151. data/lib/tolaria/version.rb +13 -0
  152. data/test/demo/Rakefile +4 -0
  153. data/test/demo/app/assets/javascripts/application.js +1 -0
  154. data/test/demo/app/assets/stylesheets/application.scss +1 -0
  155. data/test/demo/app/controllers/application_controller.rb +5 -0
  156. data/test/demo/app/controllers/concerns/.keep +0 -0
  157. data/test/demo/app/controllers/homepage_controller.rb +4 -0
  158. data/test/demo/app/helpers/application_helper.rb +2 -0
  159. data/test/demo/app/mailers/.keep +0 -0
  160. data/test/demo/app/models/.keep +0 -0
  161. data/test/demo/app/models/blog_post.rb +43 -0
  162. data/test/demo/app/models/footnote.rb +5 -0
  163. data/test/demo/app/models/image.rb +19 -0
  164. data/test/demo/app/models/legal_page.rb +24 -0
  165. data/test/demo/app/models/miscellany.rb +12 -0
  166. data/test/demo/app/models/topic.rb +22 -0
  167. data/test/demo/app/models/video.rb +16 -0
  168. data/test/demo/app/views/admin/blog_posts/_form.html.erb +48 -0
  169. data/test/demo/app/views/admin/blog_posts/_search.html.erb +5 -0
  170. data/test/demo/app/views/admin/help/markdown-help.md +95 -0
  171. data/test/demo/app/views/admin/images/_form.html.erb +26 -0
  172. data/test/demo/app/views/admin/legal_pages/_form.html.erb +15 -0
  173. data/test/demo/app/views/admin/topics/_form.html.erb +3 -0
  174. data/test/demo/app/views/admin/videos/_form.html.erb +11 -0
  175. data/test/demo/app/views/homepage/homepage.html.erb +3 -0
  176. data/test/demo/app/views/layouts/application.html.erb +14 -0
  177. data/test/demo/bin/bundle +3 -0
  178. data/test/demo/bin/rails +4 -0
  179. data/test/demo/bin/rake +4 -0
  180. data/test/demo/bin/setup +29 -0
  181. data/test/demo/config.ru +4 -0
  182. data/test/demo/config/application.rb +26 -0
  183. data/test/demo/config/boot.rb +4 -0
  184. data/test/demo/config/database.yml +18 -0
  185. data/test/demo/config/environment.rb +3 -0
  186. data/test/demo/config/environments/development.rb +43 -0
  187. data/test/demo/config/environments/test.rb +44 -0
  188. data/test/demo/config/initializers/assets.rb +11 -0
  189. data/test/demo/config/initializers/cookies_serializer.rb +2 -0
  190. data/test/demo/config/initializers/filter_parameter_logging.rb +3 -0
  191. data/test/demo/config/initializers/inflections.rb +17 -0
  192. data/test/demo/config/initializers/markdown.rb +44 -0
  193. data/test/demo/config/initializers/secret_token.rb +2 -0
  194. data/test/demo/config/initializers/session_store.rb +2 -0
  195. data/test/demo/config/initializers/tolaria.rb +17 -0
  196. data/test/demo/config/initializers/wrap_parameters.rb +14 -0
  197. data/test/demo/config/routes.rb +4 -0
  198. data/test/demo/db/migrate/20150601202901_create_administrators.rb +31 -0
  199. data/test/demo/db/migrate/20150603204006_add_testing_models.rb +27 -0
  200. data/test/demo/db/migrate/20150609232013_create_footnotes.rb +10 -0
  201. data/test/demo/db/migrate/20150610135235_create_additional_demo_objects.rb +50 -0
  202. data/test/demo/db/schema.rb +112 -0
  203. data/test/demo/log/.keep +0 -0
  204. data/test/demo/public/404.html +67 -0
  205. data/test/demo/public/422.html +67 -0
  206. data/test/demo/public/500.html +66 -0
  207. data/test/demo/public/favicon.ico +0 -0
  208. data/test/integration/help_link_test.rb +73 -0
  209. data/test/integration/interface_test.rb +63 -0
  210. data/test/integration/router_test.rb +73 -0
  211. data/test/integration/session_test.rb +88 -0
  212. data/test/test_helper.rb +58 -0
  213. data/test/unit/configuration_test.rb +21 -0
  214. data/test/unit/managed_classes_test.rb +54 -0
  215. data/test/unit/markdown_test.rb +12 -0
  216. data/test/unit/menu_test.rb +32 -0
  217. data/test/unit/random_tokens_test.rb +13 -0
  218. data/tolaria.gemspec +35 -0
  219. metadata +499 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d6bbe4f07c4384a212775e975ce8eb3ebdc9bac7
4
+ data.tar.gz: 7c73d1de0b10a9e9b66245132190eea2c1671287
5
+ SHA512:
6
+ metadata.gz: ef6b210ab9493676b17282ba7f9f15ee1bd072e6f679cda2cfde50fdc7464cc1109ff97d51c7d3486428359869bd1387847cccfa817e9bfed089d093c2fcb6a0
7
+ data.tar.gz: 17f7e9f64856fcd583071c69da4e5ad02ea6ad411758e06bb69c175b49b0a0f580b0fd81c9f9b8198491879f7196a945677aa4da5bab022525d88104dc773e29
@@ -0,0 +1,66 @@
1
+ # Special ignores for this project
2
+
3
+ Gemfile.lock
4
+
5
+ # Ignore local dev only files
6
+
7
+ *.dump
8
+ *.gem
9
+ *.log
10
+ *.rbc
11
+ *.cache
12
+ *.pid
13
+ *.sqlite3
14
+ *.sqlite3-journal
15
+ .bundle
16
+ .config
17
+ .env
18
+ .env.test
19
+ .yardoc
20
+ config/database.yml
21
+ coverage
22
+ export
23
+ InstalledFiles
24
+ lib/bundler/man
25
+ node_modules
26
+ pkg
27
+ public/system/**/*
28
+ rdoc
29
+ doc
30
+ rerun.txt
31
+ spec/reports
32
+ spec/tmp/**/*
33
+ tags
34
+ test/tmp
35
+ test/version_tmp
36
+ vendor/**/*
37
+ vim/.netrwhist
38
+ zeus.json
39
+ _yardoc
40
+
41
+ # Ignore compilation junk
42
+
43
+ **.orig
44
+ *.rbc
45
+ *.sassc
46
+ *.sw[nop]
47
+ .rspec
48
+ .sass-cache
49
+ capybara-*.html
50
+ pickle-email-*.html
51
+ rerun.txt
52
+
53
+ # Ignore filesystem trash
54
+
55
+ *.DS_Store
56
+ *Thumbs.db
57
+ .DS_Store?
58
+ ehthumbs.db
59
+ Thumbs.db
60
+
61
+ # Specifically DO NOT ignore these repo settings
62
+
63
+ !.gitignore
64
+ !.slugignore
65
+ !.ruby-version
66
+ !.yardops
@@ -0,0 +1,4 @@
1
+ --readme README.md
2
+ --charset utf-8
3
+ --markup markdown
4
+ --exclude /test
data/CNAME ADDED
@@ -0,0 +1 @@
1
+ tolaria.threespot.com
@@ -0,0 +1,32 @@
1
+ The Tolaria team welcomes contributions. While contributing, you must adhere to the project [code of conduct](#the-code-of-conduct), so that everyone feels welcome.
2
+
3
+ Here’s how you can make Tolaria better:
4
+
5
+ - Use prerelease versions (`gem install tolaria --pre`)
6
+ - [Report an issue](https://github.com/threespot/tolaria/issues/new) or ask questions
7
+ - [Suggest new features](https://github.com/threespot/tolaria/issues/new)
8
+ - Check, vet, diagnose, or add details to existing issues.
9
+ - Contributing or improving documentation. We’re sure there are still typos or unclear instructions. These are easy wins.
10
+ - Contributing pull requests or bugfixes.
11
+
12
+ **Please note:** Tolaria is not necessarily the team’s full-time gig. Please be patient with us getting back to you.
13
+
14
+ Thanks for helping us make Tolaria better!
15
+
16
+ ### The Code of Conduct
17
+
18
+ Tolaria strongly values contributors from anywhere, regardless of gender, gender expression, sexual orientation, ability, physical appearance, body type, race, age, or religion. As a result, the team has agreed to and enforces this code of conduct in order to provide a harassment-free experience for everyone who participates in the development of Tolaria.
19
+
20
+ Harassment includes offensive comments related to gender, gender expression, sexual orientation, ability, physical appearance, body type, race, age, or religion. It also includes the posting of sexual images, deliberate intimidation, stalking, and unwelcome sexual attention.
21
+
22
+ Further, harassment includes ad-hominem attacks, grandstanding, derogatory comments, trolling, public or private community disruption, insults, or other unprofessional conduct.
23
+
24
+ Harassment is not tolerated in our issue tracker, code, events, chat channels, over emails, or any other way you can communicate with a contributor. Anyone who is asked to cease harassment is expected to comply immediately. Our team is not exempt from this policy.
25
+
26
+ If anyone engages in harassing behavior, we may take appropriate action, up to and including warning the offender, deletion of comments, removal from the project’s codebase and communication systems, and escalation to GitHub support.
27
+
28
+ If you are being harassed, notice that someone else is being harassed, or have any other concerns, please open an issue or contact a team member.
29
+
30
+ ### License
31
+
32
+ This document is published from the United States. To the extent possible under law, Threespot Media has waived all copyright and related or neighboring rights to this document worldwide. The text may be re-used for any purpose and without credit.
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
@@ -0,0 +1,9 @@
1
+ ### The MIT License
2
+
3
+ Copyright (c) 2015 Threespot Media
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,538 @@
1
+ ## Tolaria
2
+
3
+ Tolaria is a [content management system](https://en.wikipedia.org/wiki/Content_management_system) (CMS) framework for [Ruby on Rails](https://en.wikipedia.org/wiki/Ruby_on_Rails). It greatly speeds up the necessary—but repetitive—task of creating useful admin panels, forms, and model workflows for site authors.
4
+
5
+ [![](https://cloud.githubusercontent.com/assets/769083/8262095/ccb2b68e-169d-11e5-9378-0d098eb22c22.png)](https://cloud.githubusercontent.com/assets/769083/7573791/56eda172-f7f6-11e4-8df7-36015cf5cf85.png)
6
+
7
+ [![](https://cloud.githubusercontent.com/assets/769083/8262101/d64a4478-169d-11e5-879e-4927640c5f39.png)](https://cloud.githubusercontent.com/assets/769083/7573968/cc448ebc-f7f7-11e4-8593-c6465d3a8e3c.png)
8
+
9
+ ### Features
10
+
11
+ - Fully responsive (and we think it's beautiful too!)
12
+ - A complete email-based authentication system is included, and there are no passwords to manage.
13
+ - Automatically builds navigation and admin routes for you.
14
+ - Automatically creates simple index screens, show screens, and text search tools, which you can expand.
15
+ - Includes a handful of advanced form fields, notably a fullscreen Markdown editor and searchable select/tag lists.
16
+ - Assists in providing inline help and documentation to your editors.
17
+ - No magic DSL. Work directly in ERB on all admin views.
18
+ - Compartmentalized from the rest of the Rails application, and does not rely on the behavior of `to_param`.
19
+ - Easily overridable on a case-by-case basis.
20
+ - Designed for use on Heroku, in containers, and on websites with TLS.
21
+ - Modest dependencies.
22
+
23
+ ### Browser Support
24
+
25
+ Tolaria supports IE10+, Safari, Chrome, Firefox, iOS, and Chrome for Android. Note that these are the browsers your site editors will need, not the general site audience, which can differ.
26
+
27
+ ### Getting Started
28
+
29
+ Add Tolaria to your project's `Gemfile`:
30
+
31
+ ```ruby
32
+ gem "tolaria"
33
+ ```
34
+
35
+ Then update your bundle.
36
+
37
+ Now run the installation generator. This will create an initializer for Tolaria plus a migration to set up an `administrators` table. Migrate your database.
38
+
39
+ ```shell
40
+ $ rails generate tolaria:install
41
+ $ rake db:migrate
42
+ ```
43
+
44
+ Review all of the settings in `config/initializers/tolaria.rb`.
45
+
46
+ Run this Rake command to create your first administrator account:
47
+
48
+ ```shell
49
+ $ rake admin:create
50
+ ```
51
+
52
+ Now you'll need to add Tolaria's route drawing to the top of your `routes.rb` file like so:
53
+
54
+ ```ruby
55
+ Rails.application.routes.draw do
56
+ Tolaria.draw_routes(self)
57
+ # Your other routes below here
58
+ end
59
+ ```
60
+
61
+ Tolaria needs to be able to dispatch email. You'll need to configure ActionMailer to use an appropriate mail service. Here's an example using [Mailgun on Heroku](https://devcenter.heroku.com/articles/mailgun):
62
+
63
+ ```ruby
64
+ # config/initializers/action_mailer.rb
65
+
66
+ ActionMailer::Base.perform_deliveries = true
67
+ ActionMailer::Base.delivery_method = :smtp
68
+
69
+ ActionMailer::Base.smtp_settings = {
70
+ port: ENV.fetch("MAILGUN_SMTP_PORT"),
71
+ address: ENV.fetch("MAILGUN_SMTP_SERVER"),
72
+ user_name: ENV.fetch("MAILGUN_SMTP_LOGIN"),
73
+ password: ENV.fetch("MAILGUN_SMTP_PASSWORD"),
74
+ domain: "example.org",
75
+ authentication: :login,
76
+ enable_starttls_auto: true,
77
+ }
78
+ ```
79
+
80
+ Now start your Rails server and go to `/admin` to log in!
81
+
82
+ ### Adding Administrator Accounts
83
+
84
+ You can add administrators from the command line using a Rake task. This is particularly useful for creating the very first one.
85
+
86
+ ```shell
87
+ $ rake admin:create
88
+ ```
89
+
90
+ If you are already logged in to Tolaria, you can also simply visit `/admin/administrators` to create a new account using the CMS interface.
91
+
92
+ ### Passcode Authentication
93
+
94
+ Tolaria authenticates editors via email, using a one-time passcode. When an editor wants to sign in, they must type a passcode dispatched to their email address. Passcodes are invalidated after use.
95
+
96
+ You can configure Tolaria's passcode paranoia in the initializer you installed above.
97
+
98
+ ![](https://cloud.githubusercontent.com/assets/769083/8137572/5e81bb1e-1112-11e5-9626-fc7a0010f0c4.png)
99
+
100
+ ### Managing a Model
101
+
102
+ Inside your ActiveRecord definition for your model, call `manage_with_tolaria`, passing configuration in the `using` Hash. [Refer to the documentation for all of the options](#FIXME).
103
+
104
+ The icon system uses [Font Awesome][fa], and you'll need to pass one of [the icon names][fa] for the `icon` key.
105
+
106
+ [fa]: http://fontawesome.io/icons/
107
+
108
+ **Important:** you'll need to provide the options to pass to `params.permit` here for the admin system. Your form won't work without it!
109
+
110
+ ```ruby
111
+ class BlogPost < ActiveRecord::Base
112
+ manage_with_tolaria using: {
113
+ icon: "file-o",
114
+ category: "Settings",
115
+ priority: 5,
116
+ permit_params: [
117
+ :title,
118
+ :body,
119
+ :author_id,
120
+ ]
121
+ }
122
+ end
123
+ ```
124
+
125
+ ### Customizing Indexes
126
+
127
+ By default, Tolaria will build a simple index screen for each model. You'll likely want to replace it for complicated models, or to allow administrators to sort the columns.
128
+
129
+ If your model was `BlogPost`, you'll need to create a file in your project at: `app/views/admin/blog_posts/_index.html.erb`.
130
+
131
+ See the [TableHelper documentation](#FIXME) for more information.
132
+
133
+ ```erb
134
+ <% # app/views/admin/blog_posts/_index.html.erb %>
135
+
136
+ <%= index_table do %>
137
+ <thead>
138
+ <tr>
139
+ <%= index_th :id %>
140
+ <%= index_th :title %>
141
+ <%= index_th "Author", sort: false %>
142
+ <%= actions_th %>
143
+ </tr>
144
+ </thead>
145
+ <tbody>
146
+ <% @resources.each do |blog_post| %>
147
+ <tr>
148
+ <%= index_td blog_post, :id %>
149
+ <%= index_td blog_post, :title %>
150
+ <%= index_td blog_post, blog_post.author.name, image:blog_post.author.portrait_uri %>
151
+ <%= actions_td blog_post %>
152
+ </tr>
153
+ <% end %>
154
+ </tbody>
155
+ <% end %>
156
+ ```
157
+
158
+ ### Customizing The Inspect Screen
159
+
160
+ Tolaria provides a very basic show/inspect screen for models. You'll want to provide your own for complex models.
161
+
162
+ If your model was `BlogPost`, you'll need to create a file in your project at: `app/views/admin/blog_posts/_show.html.erb`.
163
+
164
+ See the [TableHelper documentation](#FIXME) for more information.
165
+
166
+ ```erb
167
+ <% # app/views/admin/blog_posts/_show.html.erb %>
168
+
169
+ <%= show_table do %>
170
+
171
+ <thead>
172
+ <%= show_thead_tr %>
173
+ </thead>
174
+ <tbody>
175
+ <%= show_tr :title %>
176
+ <%= show_tr "Author", @resource.author.name %>
177
+ <%= show_tr :body %>
178
+ </tbody>
179
+
180
+ <% end %>
181
+ ```
182
+
183
+ ### Adding Model Forms
184
+
185
+ Tolaria does not build editing forms for you, but it attempts to help speed up your work by providing a wrapper.
186
+
187
+ If your model was `BlogPost`, you'll need to create a file in your project at `app/views/admin/blog_posts/_form.html.erb`. You'll provide the form code that would appear inside the `form_for` block, excluding the submit buttons. The builder variable is `f`.
188
+
189
+ ```erb
190
+ <% # app/views/admin/blog_posts/_form.html.erb %>
191
+
192
+ <%= f.label :title %>
193
+ <%= f.text_field :title, placeholder:"Post title" %>
194
+ <%= f.hint "The title of this post. A good title is both summarizing and enticing, much like a newspaper headline." %>
195
+
196
+ <%= f.label :author_id, "Author" %>
197
+ <%= f.searchable_select :author_id, Author.all, :id, :name, include_blank:false %>
198
+ <%= f.hint "Select the person who wrote this post." %>
199
+
200
+ <%= f.label :body %>
201
+ <%= f.markdown_composer :body %>
202
+ <%= f.hint "The body of this post. You can use Markdown!"
203
+ ```
204
+
205
+ ### Has-many Nested Forms
206
+
207
+ If you want to provide an interface for a `has_many` + `accepts_nested_attributes_for` relationship, you can use the `has_many` helper. The UI allows slating persisted objects for removal when the form is saved.
208
+
209
+ **Important**: You need to include `f.has_many_header` to create the form headers and turn on or off the destruction controls with `allow_destroy`.
210
+
211
+ ```erb
212
+ <%= f.has_many :footnotes do |f| %>
213
+
214
+ <%= f.has_many_header allow_destroy:true %>
215
+
216
+ <%= f.label :description %>
217
+ <%= f.text_field :description %>
218
+ <%= f.hint "The name or other description of this reference" %>
219
+
220
+ <%= f.label :url, "URL" %>
221
+ <%= f.text_field :url, class:"monospace" %>
222
+ <%= f.hint "A full URL to the source or reference material" %>
223
+
224
+ <% end %>
225
+ ```
226
+
227
+ ![](https://cloud.githubusercontent.com/assets/769083/8117475/50e5d0e2-1056-11e5-87a6-07bc7458da1e.png)
228
+
229
+ Don't forget that you also need to change `permit_params` so that you include your nested attributes:
230
+
231
+ ```ruby
232
+ class BlogPost < ActiveRecord::Base
233
+ manage_with_tolaria using: {
234
+ icon: "file-o",
235
+ category: "Settings",
236
+ priority: 5,
237
+ permit_params: [
238
+ :title,
239
+ :body,
240
+ :author_id,
241
+ :footnotes_attributes: [
242
+ :id,
243
+ :_destroy,
244
+ :url,
245
+ :description,
246
+ ]
247
+ ]
248
+ }
249
+ end
250
+ ```
251
+
252
+ ### Customizing The Search Form
253
+
254
+ By default, Tolaria provides a single search field that searches over all of the text or character columns of a model. You can expand the search tool to include other facets.
255
+
256
+ **Important:** This system uses the [Ransack gem][ransack], which you'll need to familiarize yourself with.
257
+
258
+ If your model was `BlogPost`, you'll need to create a file in your project at `app/views/admin/blog_posts/_search.html.erb`. You'll provide the form code that would appear inside the `search_form_for` block, excluding the submit buttons. The builder variable is `f`.
259
+
260
+ ```erb
261
+ <% # app/views/admin/blog_posts/_search.html.erb %>
262
+
263
+ <%= f.label :title_cont, "Title contains" %>
264
+ <%= f.search_field :title_cont, placeholder:"Anything" %>
265
+
266
+ <%= f.label :author_name_cont, "Author is" %>
267
+ <%= f.searchable_select :author_name_cont, Author.all, :name, :name, prompt:"Any author" %>
268
+
269
+ <%= f.label :body_cont, "Body contains" %>
270
+ <%= f.search_field :body_cont, placeholder:"Anything" %>
271
+ ```
272
+
273
+ [ransack]: https://github.com/activerecord-hackery/ransack
274
+
275
+ ### Provided Form Fields
276
+
277
+ You can use all of the Rails-provided fields on your forms, but Tolaria also comes with a set of advanced, JavaScript-backed fields. Make sure to [review the documentation for the form builder](#FIXME) to get all the details.
278
+
279
+ #### Markdown Composer
280
+
281
+ The [`markdown_composer` helper](#FIXME) will generate a very fancy Markdown editor, which includes text snippet tools and a fullscreen mode with live previewing.
282
+
283
+ **Important:** You cannot use this field properly if you do not set up `Tolaria.config.markdown_renderer`. Without it, the live preview will only use `simple_format`!
284
+
285
+ ```
286
+ <%= f.label :body %>
287
+ <%= f.markdown_composer :body %>
288
+ <%= f.hint "The body of this post. You can use Markdown!" %>
289
+ ```
290
+
291
+ ![markdown_composer](https://cloud.githubusercontent.com/assets/769083/7888521/407d0116-0607-11e5-91fe-a046c22ea777.png)
292
+
293
+ #### Searchable Select
294
+
295
+ The [`searchable_select` helper](#FIXME) displays a [Chosen select field](http://harvesthq.github.io/chosen/) that authors can filter by typing.
296
+
297
+ ```
298
+ <%= f.label :title, "Topics" %>
299
+ <%= f.searchable_select :topic_ids, Topic.order("label ASC"), :id, :label, multiple:true %>
300
+ <%= f.hint "Select each topic that applies to this blog post" %>
301
+ ```
302
+
303
+ ![searchable_select](https://cloud.githubusercontent.com/assets/769083/7888524/41aba54c-0607-11e5-9c5f-483b5ecf5ea9.png)
304
+
305
+ #### Image Association Select
306
+
307
+ The [`image_association_select` helper](#FIXME) displays a `searchable_select` that provides an instant preview of the currently selected model as an image.
308
+
309
+ ```erb
310
+ <%= f.label :featured_image_id, "Featured Image" %>
311
+ <%= f.image_association_select :featured_image_id, Image.order("title ASC"), :id, :title, :preview_uri %>
312
+ <%= f.hint "Select a featured image for this blog post." %>
313
+ ```
314
+
315
+ ![](https://cloud.githubusercontent.com/assets/769083/8119314/a83565c2-1062-11e5-92e6-5a6bcd1bb5ea.png)
316
+
317
+ #### Timestamp Field
318
+
319
+ The [`timestamp_field` helper](#FIXME) displays a text field that validates a provided timestamp and recovers to a template if blanked.
320
+
321
+ ```erb
322
+ <%= f.label :published_at, "Publishing Date" %>
323
+ <%= f.timestamp_field :published_at %>
324
+ <%= f.hint "The date this post should be published." %>
325
+ ```
326
+
327
+ ![timestamp_field](https://cloud.githubusercontent.com/assets/769083/7888528/4487a9b4-0607-11e5-9298-bc26116b59f0.png)
328
+
329
+ #### Slug Field
330
+
331
+ The [`slug_field` helper](#FIXME) allows you to show the parameterized value of a field in a given pattern preview.
332
+
333
+ ```erb
334
+ <%= f.label :title %>
335
+ <%= f.slug_field :title, placeholder:"Post title", pattern:"/blog/255-*" %>
336
+ <%= f.hint "The title of this post." %>
337
+ ```
338
+
339
+ ![slug_field](https://cloud.githubusercontent.com/assets/769083/7888526/42ac965e-0607-11e5-9be6-0300f0f0f04d.png)
340
+
341
+ #### Swatch Field
342
+
343
+ The [`swatch_field` helper](#FIXME) validates and displays a given hexadecimal color.
344
+
345
+ ```erb
346
+ <%= f.label :color %>
347
+ <%= f.swatch_field :color, placeholder:"#CC0000" %>
348
+ <%= f.hint "Choose a background color for this campaign">
349
+ ```
350
+
351
+ ![swatch_field](https://cloud.githubusercontent.com/assets/769083/7888518/3e2e1828-0607-11e5-8bca-79bdfa3b6a06.png)
352
+
353
+ #### Image Field
354
+
355
+ The [`image_field` helper](#FIXME) displays a button that makes uploading an image a little more pleasant than a regular `file_field`.
356
+
357
+ ```erb
358
+ <%= f.label :portrait %>
359
+ <%= f.image_field :portrait, preview_url:@resource.portrait.url(:preview) %>
360
+ <%= f.hint "Attach a portrait of this author, at least 600×600 pixels in size. The subject should be centered." %>
361
+ ```
362
+
363
+ ![image_field](https://cloud.githubusercontent.com/assets/769083/7888520/3f700750-0607-11e5-952a-e81edbb58017.png)
364
+
365
+ #### Attachment Field
366
+
367
+ The [`attachment_field` helper](#FIXME) displays a button that makes uploading an arbirary file a little more pleasant than a regular `file_field`.
368
+
369
+ ```erb
370
+ <%= f.label :portrait %>
371
+ <%= f.attachment_field :portrait %>
372
+ <%= f.hint "Attach a portrait of this author, at least 600×600 pixels in size. The subject should be centered." %>
373
+ ```
374
+
375
+ ![attachment_field](https://cloud.githubusercontent.com/assets/769083/7888501/2c5d3160-0607-11e5-8b44-9c8affaa1f8d.png)
376
+
377
+ #### Field Clusters (Checkboxes and 2+ Selects)
378
+
379
+ If you need to run two or more `select` controls together (like for `date_select`), or you need to group a set of checkboxes together (like for `collection_checkboxes`), you'll need to wrap the form field in `<div class="field-cluster">`:
380
+
381
+ ```erb
382
+ <%= f.label :published_at, "Publishing Date" %>
383
+ <div class="field-cluster"><%= f.date_select :published_at %></div>
384
+ <%= f.hint "The date this post should be published." %>
385
+
386
+ <%= f.label :title, "Topics" %>
387
+ <div class="field-cluster"><%= f.collection_check_boxes :topic_ids, Topic.order("label ASC"), :id, :label %></div>
388
+ <%= f.hint "Choose each topic that applies to this blog post" %>
389
+ ```
390
+
391
+ ![](https://cloud.githubusercontent.com/assets/769083/8138732/774630c2-111b-11e5-8024-bdec00ed18c4.png)
392
+
393
+ #### Hints
394
+
395
+ [Inline help](#FIXME) is useful for reminding administrators about what should be provided for each field. Use `f.hint` to present a hint for a field.
396
+
397
+ ![hint](https://cloud.githubusercontent.com/assets/769083/7888576/8d20f8a6-0607-11e5-80ea-2c8f66ad7449.png)
398
+
399
+ ### Customizing the Menu
400
+
401
+ When you call `manage_with_tolaria`, you can provide a category and a priority like below. Items in the same category will be grouped together in the navigation menu. Items are sorted priority ascending in their group.
402
+
403
+ ```ruby
404
+ class BlogPost < ActiveRecord::Base
405
+ manage_with_tolaria using:{
406
+ category: "Prose",
407
+ priority: 5,
408
+ }
409
+ end
410
+ ```
411
+
412
+ If you want to re-order the groups, you need to set an array of menu titles ahead of time in `Tolaria.config.menu_categories`:
413
+
414
+ ```ruby
415
+ # config/initializers/tolaria.rb
416
+ Tolaria.configure do |config|
417
+ config.menu_categories = [
418
+ "Prose",
419
+ "Animals",
420
+ "Settings",
421
+ ]
422
+ end
423
+ ```
424
+
425
+ ### Adding Documentation Links
426
+
427
+ You can provide documentation links in the interface header by appending to `Tolaria.config.help_links`. Add hashes to the array, with these keys:
428
+
429
+ To render a Markdown file, provide a `:title`, the URL fragment `:slug`, and a `:markdown_file` path to your Markdown document. The system will automatically draw a route to this view for you and present your file, using the renderer configured in `Tolaria.config.markdown_renderer`.
430
+
431
+ To link to an arbitrary route or URL, provide a `:title` and a `:link_to`. Examples below:
432
+
433
+ ```ruby
434
+ # config/initializers/tolaria.rb
435
+
436
+ Tolaria.configure do |config|
437
+
438
+ config.help_links << {
439
+ title: "Markdown Reference"
440
+ slug: "markdown-reference",
441
+ markdown_file: "/path/to/your/file.md"
442
+ }
443
+
444
+ config.help_links << {
445
+ title: "Style Guide"
446
+ link_to: "http://example.org/styleguide"
447
+ }
448
+
449
+ end
450
+ ```
451
+
452
+ ### Patching a Controller
453
+
454
+ Tolaria dynamically creates controllers for managed models, named as you would expect. If you want to replace or add to controller functionality, create the file in your parent application and patch away:
455
+
456
+ If your model was `BlogPost`, you should create `app/controllers/admin/blog_posts_controller.rb`
457
+
458
+ ```ruby
459
+ # app/controllers/admin/blog_posts_controller.rb
460
+ class Admin::BlogPostsController < Tolaria::ResourceController
461
+ def another_method
462
+ # do stuff
463
+ # render a template
464
+ end
465
+ end
466
+ ```
467
+
468
+ You might want to [check out what we've done in the base ResourceController](https://github.com/Threespot/tolaria/blob/master/app/controllers/tolaria/resource_controller.rb) file so that you know what you're patching. If you override any of the existing methods, you're on your own to handle everything correctly.
469
+
470
+ ### Adding Your Own Styles or JavaScript
471
+
472
+ If you want to add additional Sass or JavaScript to the admin system, you can create these files and then append to them as you need. Make sure that you import the base styles and JavaScript so you inherit what's already been done.
473
+
474
+ `app/assets/stylesheets/admin/admin.scss`:
475
+
476
+ ```sass
477
+ @import "admin/base";
478
+ // Your code goes here
479
+ ```
480
+
481
+ `app/assets/javascripts/admin/admin.js`:
482
+
483
+ ```javascript
484
+ //= require admin/base
485
+ // Your code goes here
486
+ ```
487
+
488
+ ### Testing and Running the Demo Server
489
+
490
+ Tolaria comes with a test suite and a demo server that the test suite exercises.
491
+
492
+ To run tests, first clone the repo:
493
+
494
+ ```shell
495
+ $ git clone -o github git@github.com:threespot/tolaria.git
496
+ $ cd tolaria
497
+ ```
498
+
499
+ Install the development dependencies:
500
+
501
+ ```
502
+ $ bundle install
503
+ ```
504
+
505
+ Now in the project root, you have several `rake` tasks available:
506
+
507
+ ```shell
508
+ $ rake test # Run the tests
509
+ $ rake admin:create # Create an admin in the demo development database
510
+ $ rake console # Start a Rails console with Tolaria loaded
511
+ $ rake server # Start a Rails Webrick server with Tolaria and some example models loaded
512
+ ```
513
+
514
+ ### Miscellaneous Technical Details
515
+
516
+ - Tolaria is not designed for use on a production site without TLS/HTTPS configured. You must protect Tolaria sessions and cookies with TLS. Do not allow users to connect to your administrator panel over plain HTTP.
517
+ - If you are using `Content-Security-Policy`, you will need to add `https://secure.gravatar.com` to the allowed image sources in order to display administrator avatars. All other assets bundled with Tolaria are served by the Rails asset pipeline.
518
+ - The constant and module name `Admin` is reserved for Tolaria's use. If you add to this namespace, be sure you are not colliding with a Tolaria-provided constant.
519
+ - The route space `/admin/**/*` is reserved for Tolaria's use. If you add routes here, be sure you are not colliding with a Tolaria-generated route.
520
+
521
+ ### License
522
+
523
+ Tolaria is free software, and may be redistributed under the terms of the [MIT license](https://github.com/Threespot/tolaria/blob/master/LICENSE.md). If Tolaria works great for your project, [we'd love to hear about it](http://twitter.com/threespot)!
524
+
525
+ ### Thanks
526
+
527
+ Our work stands on the shoulders of giants, and we're very thankful to the many people that made Tolaria possible either by publishing code we used, or by being an inspiration for this project.
528
+
529
+ - [The ActiveAdmin team](https://github.com/activeadmin/activeadmin/graphs/contributors)
530
+ - [The jQuery Foundation](https://jquery.org)
531
+ - [Jeremy Ashkenas](https://twitter.com/jashkenas)
532
+ - [The Harvest Team](https://www.getharvest.com/about/meet-the-team)
533
+
534
+ ### About Threespot
535
+
536
+ Threespot is a design and development agency from Washington, DC. We work for organizations that we believe are making a positive change in the world. Find out more [about us](https://www.threespot.com), [our projects](https://www.threespot.com/work) or [hire us](https://www.threespot.com/agency/hire-us)!
537
+
538
+ [![](https://avatars3.githubusercontent.com/u/370822?v=3&s=100)](https://www.threespot.com)