character 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (173) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -1
  3. data/.rspec +1 -0
  4. data/README.md +185 -14
  5. data/Rakefile +8 -1
  6. data/app/assets/images/character/logo.jpg +0 -0
  7. data/app/assets/javascripts/character.coffee +134 -0
  8. data/app/assets/javascripts/character/dashboard/_visitors.coffee +27 -0
  9. data/app/assets/javascripts/character/dashboard/layout.coffee +156 -0
  10. data/app/assets/javascripts/character/dashboard/module.coffee +51 -0
  11. data/app/assets/javascripts/character/generic/details.coffee +233 -0
  12. data/app/assets/javascripts/character/generic/helpers/compact_object.coffee +7 -0
  13. data/app/assets/javascripts/character/generic/helpers/data_inputs.coffee +21 -0
  14. data/app/assets/javascripts/character/generic/helpers/date_select.coffee +45 -0
  15. data/app/assets/javascripts/character/generic/helpers/editor.coffee +11 -0
  16. data/app/assets/javascripts/character/generic/helpers/redactor.coffee +38 -0
  17. data/app/assets/javascripts/character/generic/helpers/reorder.coffee +36 -0
  18. data/app/assets/javascripts/character/generic/layout.coffee +40 -0
  19. data/app/assets/javascripts/character/generic/list.coffee +214 -0
  20. data/app/assets/javascripts/character/generic/model.coffee +135 -0
  21. data/app/assets/javascripts/character/generic/module.coffee +157 -0
  22. data/app/assets/javascripts/character/images/module.coffee +148 -0
  23. data/app/assets/javascripts/character/pages/module.coffee +43 -0
  24. data/app/assets/javascripts/character/posts/module.coffee +113 -0
  25. data/app/assets/javascripts/character/settings/_admins.coffee +61 -0
  26. data/app/assets/javascripts/character/settings/_authors.coffee +56 -0
  27. data/app/assets/javascripts/character/settings/_categories.coffee +61 -0
  28. data/app/assets/javascripts/character/settings/_layout.coffee +7 -0
  29. data/app/assets/javascripts/character/settings/_redirects.coffee +56 -0
  30. data/app/assets/javascripts/character/settings/_website.coffee +7 -0
  31. data/app/assets/javascripts/character/settings/details.coffee +16 -0
  32. data/app/assets/javascripts/character/settings/layout.coffee +46 -0
  33. data/app/assets/javascripts/character/settings/module.coffee +78 -0
  34. data/app/assets/stylesheets/character.scss +37 -0
  35. data/app/assets/stylesheets/character/_admins.scss +30 -0
  36. data/app/assets/stylesheets/character/_authors.scss +30 -0
  37. data/app/assets/stylesheets/character/_categories.scss +32 -0
  38. data/app/assets/stylesheets/character/_dashboard.scss +143 -0
  39. data/app/assets/stylesheets/character/_posts.scss +93 -0
  40. data/app/assets/stylesheets/character/_redirects.scss +35 -0
  41. data/app/assets/stylesheets/character/base.scss +967 -0
  42. data/app/assets/stylesheets/character/typography.scss +29 -0
  43. data/app/controllers/character/api_controller.rb +170 -0
  44. data/app/controllers/character/application_controller.rb +37 -0
  45. data/app/controllers/character/settings_controller.rb +72 -0
  46. data/app/controllers/concerns/character/auth_concern.rb +41 -0
  47. data/app/controllers/concerns/character/instance_concern.rb +31 -0
  48. data/app/controllers/concerns/character/json_object_concern.rb +32 -0
  49. data/app/controllers/concerns/character/model_class_concern.rb +28 -0
  50. data/app/controllers/concerns/character/params_concern.rb +33 -0
  51. data/app/controllers/concerns/character/templates_concern.rb +32 -0
  52. data/app/controllers/concerns/not_found.rb +18 -0
  53. data/app/controllers/concerns/website_settings.rb +18 -0
  54. data/app/controllers/pages_controller.rb +8 -0
  55. data/app/controllers/posts_controller.rb +43 -0
  56. data/app/helpers/character_helper.rb +8 -0
  57. data/app/helpers/page_helper.rb +67 -0
  58. data/app/inputs/foundation_string_input.rb +44 -0
  59. data/app/inputs/foundation_switch_input.rb +35 -0
  60. data/app/models/character/image.rb +12 -0
  61. data/app/models/character/page.rb +21 -0
  62. data/app/models/character/post.rb +32 -12
  63. data/app/models/character/post_author.rb +22 -0
  64. data/app/models/character/post_category.rb +21 -0
  65. data/app/models/character/redirect.rb +15 -0
  66. data/app/models/character/settings/variable.rb +23 -0
  67. data/app/models/character/sitemap/sitemap_generator_helper.rb +15 -0
  68. data/app/models/character/user.rb +29 -0
  69. data/app/models/concerns/created_ago.rb +12 -0
  70. data/app/models/concerns/hideable.rb +27 -0
  71. data/app/models/concerns/orderable.rb +8 -0
  72. data/app/models/concerns/report.rb +11 -0
  73. data/app/models/concerns/report_daily.rb +32 -0
  74. data/app/models/concerns/report_monthly.rb +18 -0
  75. data/app/models/concerns/report_weekly.rb +19 -0
  76. data/app/models/concerns/updated_ago.rb +12 -0
  77. data/app/models/reports/analytics_daily.rb +26 -0
  78. data/app/models/reports/analytics_monthly.rb +16 -0
  79. data/app/models/reports/analytics_weekly.rb +16 -0
  80. data/app/services/google_analytics.rb +43 -0
  81. data/app/uploaders/character/image_uploader.rb +22 -0
  82. data/app/uploaders/character/settings/file_uploader.rb +5 -0
  83. data/app/views/character/character.html.erb +67 -0
  84. data/app/views/character/generic/form.html.erb +8 -0
  85. data/app/views/character/pages/form.html.erb +28 -0
  86. data/app/views/character/posts/form.html.erb +38 -0
  87. data/app/views/character/settings/admins.html.erb +29 -0
  88. data/app/views/character/settings/post_authors.html.erb +28 -0
  89. data/app/views/character/settings/post_categories.html.erb +31 -0
  90. data/app/views/character/settings/redirects.html.erb +30 -0
  91. data/app/views/character/settings/settings_group.html.erb +67 -0
  92. data/app/views/errors/not_found.html.erb +157 -0
  93. data/app/views/pages/_default.html.erb +3 -0
  94. data/app/views/pages/_redactor.html.erb +3 -0
  95. data/app/views/pages/show.html.erb +5 -0
  96. data/app/views/posts/_post.html.erb +17 -0
  97. data/app/views/posts/author.html.erb +18 -0
  98. data/app/views/posts/category.html.erb +18 -0
  99. data/app/views/posts/index.html.erb +18 -0
  100. data/app/views/posts/rss.builder +19 -0
  101. data/app/views/posts/show.html.erb +14 -0
  102. data/app/views/shared/_google_analytics.html.erb +13 -0
  103. data/character.gemspec +48 -5
  104. data/doc/README_old.md +161 -0
  105. data/doc/generic_app.md +19 -0
  106. data/doc/img/demo-1.jpg +0 -0
  107. data/doc/img/demo-2.jpg +0 -0
  108. data/doc/img/demo-3.jpg +0 -0
  109. data/doc/img/demo-4.jpg +0 -0
  110. data/doc/img/demo-5.jpg +0 -0
  111. data/doc/instances.md +39 -0
  112. data/doc/settings.md +1 -0
  113. data/lib/character.rb +29 -1
  114. data/lib/character/engine.rb +33 -1
  115. data/lib/character/generators/bootstrap_generator.rb +51 -0
  116. data/lib/character/instance.rb +59 -0
  117. data/lib/character/routing.rb +42 -5
  118. data/lib/character/settings.rb +101 -0
  119. data/lib/character/templates/admin.coffee +15 -0
  120. data/lib/character/templates/admin.scss +3 -0
  121. data/lib/character/templates/application.html.erb +44 -0
  122. data/lib/character/templates/application.scss +12 -0
  123. data/lib/character/templates/assets.rb +1 -0
  124. data/lib/character/templates/initializer.rb +5 -0
  125. data/lib/character/templates/settings.scss +11 -0
  126. data/lib/character/templates/settings.yml +67 -0
  127. data/lib/character/templates/typography.scss +13 -0
  128. data/lib/character/version.rb +2 -2
  129. data/lib/mongoid/carrierwave_serialization_patch.rb +9 -0
  130. data/lib/tasks/analytics.rake +52 -0
  131. data/test/config/application.rb +65 -0
  132. data/test/config/mongoid.yml +12 -0
  133. data/test/config/secrets.yml +22 -0
  134. data/test/controllers/character/api_controller_test.rb +94 -0
  135. data/test/factories/product_factory.rb +5 -0
  136. data/test/lib/character/engine_test.rb +33 -0
  137. data/test/lib/character/routing_test.rb +31 -0
  138. data/test/test_helper.rb +48 -0
  139. data/vendor/assets/javascripts/backbone.js +944 -794
  140. data/vendor/assets/javascripts/jquery.fileupload.js +1426 -0
  141. data/vendor/assets/javascripts/jquery.form.js +1278 -0
  142. data/vendor/assets/javascripts/jquery.iframe-transport.js +214 -0
  143. data/vendor/assets/javascripts/raphael.js +8117 -0
  144. data/vendor/assets/javascripts/raphael.morris.js +1885 -0
  145. data/vendor/assets/javascripts/underscore.inflection.js +177 -0
  146. data/vendor/assets/javascripts/underscore.string.js +1 -1
  147. data/vendor/assets/stylesheets/csspinner.css +361 -0
  148. data/vendor/assets/stylesheets/normalize.css +423 -0
  149. metadata +499 -49
  150. data/app/controllers/character/posts_controller.rb +0 -27
  151. data/lib/generators/character/install_generator.rb +0 -42
  152. data/lib/generators/character/templates/README +0 -1
  153. data/lib/generators/character/templates/admin/character.rb +0 -3
  154. data/vendor/assets/fonts/general_foundicons.eot +0 -0
  155. data/vendor/assets/fonts/general_foundicons.svg +0 -15
  156. data/vendor/assets/fonts/general_foundicons.ttf +0 -0
  157. data/vendor/assets/fonts/general_foundicons.woff +0 -0
  158. data/vendor/assets/javascripts/character/index.js.coffee +0 -53
  159. data/vendor/assets/javascripts/character/models/post.js.coffee +0 -39
  160. data/vendor/assets/javascripts/character/views/app.js.coffee +0 -81
  161. data/vendor/assets/javascripts/character/views/editor.js.coffee +0 -231
  162. data/vendor/assets/javascripts/character/views/editor_settings.js.coffee +0 -44
  163. data/vendor/assets/javascripts/character/views/index.js.coffee +0 -116
  164. data/vendor/assets/javascripts/character/views/preview.js.coffee +0 -49
  165. data/vendor/assets/javascripts/jquery.smartresize.js +0 -30
  166. data/vendor/assets/javascripts/lodash.js +0 -4258
  167. data/vendor/assets/javascripts/showdown.js +0 -62
  168. data/vendor/assets/stylesheets/character/_base.css.scss +0 -84
  169. data/vendor/assets/stylesheets/character/_icons.css.scss.erb +0 -96
  170. data/vendor/assets/stylesheets/character/_view_editor.css.scss +0 -115
  171. data/vendor/assets/stylesheets/character/_view_index.css.scss +0 -73
  172. data/vendor/assets/stylesheets/character/_view_preview.css.scss +0 -49
  173. data/vendor/assets/stylesheets/character/index.css.scss +0 -32
@@ -0,0 +1,18 @@
1
+ <% set_meta_tags title: "#{ @author.name } | #{ @title }",
2
+ description: @description, # use same description as website
3
+ canonical: "http://#{ @domain }#{ posts_author_path(@author) }",
4
+ open_graph: { type: 'blog',
5
+ title: "#{ @author.name } | #{ @title }",
6
+ description: @description, # use same description as website
7
+ url: "http://#{ @domain }#{ posts_author_path(@author) }" } %>
8
+
9
+ <% @posts.each do |p| %>
10
+ <%= render partial: 'post', locals: { post: p } %>
11
+ <% end %>
12
+
13
+ <nav class='pagination'>
14
+ <div class='container'>
15
+ <%= link_to_previous_page @posts, 'Newer Posts', params: @kaminari_params %>
16
+ <%= link_to_next_page @posts, 'Older Posts', params: @kaminari_params %>
17
+ </div>
18
+ </nav>
@@ -0,0 +1,18 @@
1
+ <% set_meta_tags title: "#{ @category.title } | #{ @title }",
2
+ description: @description, # use same description as website
3
+ canonical: "http://#{ @domain }#{ posts_category_path(@category) }",
4
+ open_graph: { type: 'blog',
5
+ title: "#{ @category.title } | #{ @title }",
6
+ description: @description, # use same description as website
7
+ url: "http://#{ @domain }#{ posts_category_path(@category) }" } %>
8
+
9
+ <% @posts.each do |p| %>
10
+ <%= render partial: 'post', locals: { post: p } %>
11
+ <% end %>
12
+
13
+ <nav class='pagination'>
14
+ <div class='container'>
15
+ <%= link_to_previous_page @posts, 'Newer Posts', params: @kaminari_params %>
16
+ <%= link_to_next_page @posts, 'Older Posts', params: @kaminari_params %>
17
+ </div>
18
+ </nav>
@@ -0,0 +1,18 @@
1
+ <% set_meta_tags title: @title,
2
+ description: @description,
3
+ canonical: "http://#{ @domain }#{ posts_index_path }",
4
+ open_graph: { type: 'blog',
5
+ title: @title,
6
+ description: @description,
7
+ url: "http://#{ @domain }#{ posts_index_path }" } %>
8
+
9
+ <% @posts.each do |p| %>
10
+ <%= render partial: 'post', locals: { post: p } %>
11
+ <% end %>
12
+
13
+ <nav class='pagination'>
14
+ <div class='container'>
15
+ <%= link_to_previous_page @posts, 'Newer Posts', params: @kaminari_params %>
16
+ <%= link_to_next_page @posts, 'Older Posts', params: @kaminari_params %>
17
+ </div>
18
+ </nav>
@@ -0,0 +1,19 @@
1
+ xml.instruct! :xml, :version => "1.0"
2
+ xml.rss "xmlns:dc" => "http://purl.org/dc/elements/1.1/", :version => "2.0" do
3
+ xml.channel do
4
+ xml.title @title
5
+ xml.description @description
6
+ xml.link 'http://' + @domain + posts_index_path
7
+
8
+ for post in @posts
9
+ xml.item do
10
+ xml.title post.title
11
+ xml.description post.subtitle
12
+ xml.pubDate post.published_at.to_s(:rfc822)
13
+ xml.link 'http://' + @domain + posts_show_path(post)
14
+ xml.guid 'http://' + @domain + posts_show_path(post.id.to_s)
15
+ xml.category post.category.title if post.category
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ <% set_meta_tags title: @post.title,
2
+ description: @post.subtitle,
3
+ canonical: "http://#{ @domain }#{ posts_show_path(@post) }",
4
+ open_graph: { type: 'article',
5
+ title: @post.title,
6
+ description: @post.subtitle,
7
+ url: "http://#{ @domain }#{ posts_show_path(@post) }",
8
+ image: @post.featured_image_url.empty? ? '' : "http:#{ @post.featured_image_url }" } %>
9
+
10
+ <%= render partial: 'post', locals: { post: @post } %>
11
+
12
+ <nav class='navigation'>
13
+ <%= link_to 'Blog Home', posts_index_path %>
14
+ </nav>
@@ -0,0 +1,13 @@
1
+ <% if Rails.env.production? %>
2
+ <% if not @ga_id.empty? %>
3
+ <script>
4
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
5
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
6
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
7
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
8
+
9
+ ga('create', '<%= @ga_id %>', '<%= @ga_domain %>');
10
+ ga('send', 'pageview');
11
+ </script>
12
+ <% end %>
13
+ <% end %>
@@ -4,13 +4,13 @@ require File.expand_path('../lib/character/version', __FILE__)
4
4
  Gem::Specification.new do |gem|
5
5
  gem.name = 'character'
6
6
  gem.version = Character::VERSION
7
- gem.summary = 'Blogging app on the top of activeadmin and mongoid.'
8
- gem.description = ''
7
+ gem.summary = 'Admin framework for rails + mongoid web applications.'
9
8
  gem.license = 'MIT'
9
+ gem.description = ''
10
10
 
11
- gem.authors = ['Alex Kravets']
12
- gem.email = 'santyor@gmail.com'
13
- gem.homepage = 'https://github.com/alexkravets/character-rails'
11
+ gem.authors = [ 'Alexander Kravets', 'Roman Lupiichuk', 'Maksym Melnyk', 'Anthony Blackwell' ]
12
+ gem.email = 'alex@slatestudio.com'
13
+ gem.homepage = 'https://github.com/slate-studio/character'
14
14
 
15
15
  gem.require_paths = ['lib']
16
16
  gem.files = `git ls-files`.split($\)
@@ -20,5 +20,48 @@ Gem::Specification.new do |gem|
20
20
  # Supress the warning about no rubyforge project
21
21
  gem.rubyforge_project = 'nowarning'
22
22
 
23
+
24
+ # automated tests
25
+ gem.add_development_dependency 'rails', '~> 4.1.0'
26
+ gem.add_development_dependency 'database_cleaner'
27
+ gem.add_development_dependency 'factory_girl_rails'
28
+ gem.add_development_dependency 'minitest-reporters'
29
+ gem.add_development_dependency 'minitest-focus'
30
+
31
+ # javascript
32
+ gem.add_runtime_dependency 'underscore-rails'
33
+ gem.add_runtime_dependency 'marionette-rails', '~> 2.0.0'
34
+ gem.add_runtime_dependency 'jquery-ui-rails'
35
+ gem.add_runtime_dependency 'momentjs-rails'
36
+ gem.add_runtime_dependency 'character_editor'
37
+ gem.add_runtime_dependency 'modernizr-rails'
38
+
39
+ # css
40
+ gem.add_runtime_dependency 'rhythm'
23
41
  gem.add_runtime_dependency 'compass-rails'
42
+ gem.add_runtime_dependency 'font-awesome-rails'
43
+ gem.add_runtime_dependency 'simple_form_scss'
44
+
45
+ # authentication
46
+ gem.add_runtime_dependency 'browserid-auth-rails', '~> 0.5.7'
47
+
48
+ # orm
49
+ gem.add_runtime_dependency 'mongoid', '~> 4.0.0'
50
+
51
+ # forms
52
+ gem.add_runtime_dependency 'simple_form'
53
+ gem.add_runtime_dependency 'nested_form'
54
+
55
+ # pagination
56
+ gem.add_runtime_dependency 'kaminari'
57
+
58
+ # blog
59
+ # gem.add_runtime_dependency 'mongoid' <- for now you have to pick github version manually for Rails 4
60
+ gem.add_runtime_dependency 'mongoid_slug'
61
+ gem.add_runtime_dependency 'mongoid_search'
62
+ gem.add_runtime_dependency 'mini_magick'
63
+ gem.add_runtime_dependency 'meta-tags'
64
+
65
+ # analytics
66
+ gem.add_runtime_dependency 'google-api-client'
24
67
  end
@@ -0,0 +1,161 @@
1
+ # Character
2
+
3
+ Character is an admin framework for **rails + mongoid** web applications. It has clean user interface and written with CoffeeScript. Character is very similar to [Django](http://djangoproject.com) admin or [Active Admin](http://www.activeadmin.info) but is much easier to extend. It is built on the top of:
4
+
5
+ * Back-end: [Rails](http://rubyonrails.org)
6
+ * Front-end Javascript: [Backbone.js](http://backbonejs.org) + [Marionette.js](https://github.com/marionettejs/backbone.marionette)
7
+ * Front-end CSS: [Foundation 5](http://foundation.zurb.com)
8
+
9
+ ![Character Demo](https://raw.github.com/slate-studio/character/master/doc/img/demo-1.jpg)
10
+
11
+ ## Content
12
+
13
+ * [New Project](#new-project)
14
+ * [Authentification](#authentification)
15
+ * [Mozilla Persona](#mozilla-persona)
16
+ * [Login Background](#login-background)
17
+ * [Generic App](#generic-app)
18
+ * [Model Admin](#model-admin)
19
+ * [Forms](#forms)
20
+ * [Instances](#instances)
21
+ * [Settings](#settings)
22
+ * [Tests](#tests)
23
+ * [TODO](#todo)
24
+
25
+
26
+ ## New Project
27
+
28
+ Start new Rails 4 project:
29
+
30
+ rails new ProjectName -T -O
31
+
32
+ Add following gems to the ```Gemfile```:
33
+
34
+ # ORM
35
+ gem 'mongoid', github: 'mongoid/mongoid'
36
+ gem 'bson_ext'
37
+
38
+ # File uploader
39
+ gem 'carrierwave-mongoid', github: 'carrierwaveuploader/carrierwave-mongoid', require: 'carrierwave/mongoid'
40
+ gem 'mongoid-grid_fs', github: 'ahoward/mongoid-grid_fs'
41
+
42
+ gem 'character', github: 'slate-studio/character'
43
+ gem 'character_redactor', github: 'slate-studio/character_redactor'
44
+
45
+ Run ```bundle``` from projects root.
46
+
47
+ Create mongo database config, initialize Foundation (not required if it's not used in the project) and install Character assets:
48
+
49
+ rails g mongoid:config ; rails g foundation:install ; rails g character:install
50
+
51
+ Run local Rails server:
52
+
53
+ rails s
54
+
55
+ Done! Open [http://localhost:3000/admin](http://localhost:3000/admin) in the browser.
56
+
57
+ Character generator does:
58
+
59
+ 1. Mount character in the ```config/routes.rb``` with ```mount_character()``` command
60
+ 2. Create ```app/assets/javascript/admin.coffee``` and ```app/assets/stylesheets/admin.scss```
61
+ 3. Remove ```//= require_tree .``` and ```*= require_tree .``` string from ```app/assets/javascripts/application.js``` and ```app/assets/stylesheets/application.js``` — to do not include admin assets in the application assets
62
+ 4. Add character & foundation javascript assets to production environment in ```config/environment/production.rb```: ```config.assets.precompile += %w( admin.js admin.css foundation.js vendor/modernizr.js )```
63
+ 5. Create character initializer ```config/initializers/character.rb```
64
+
65
+
66
+ ### Blog
67
+
68
+ Character includes basic blog application. To install blog please install character admin using instructions above. And then run blog generator:
69
+
70
+ rails g character:blog:install
71
+
72
+ Done! Open [http://localhost:3000/](http://localhost:3000/) in the browser.
73
+
74
+ ## Authentification
75
+
76
+
77
+ #### Mozilla Persona
78
+
79
+ Character is using [Mozilla Persona](https://login.persona.org/about) as main authentification system. This one chosen as it is very easy to setup and allows us to do not create administrative accounts from one project to another.
80
+
81
+ While logging to Character for the first time, first administrative account is created. Add other accounts via console or using Character / Settings / Admins tab.
82
+
83
+
84
+ #### Login Background
85
+
86
+ Default login background could be changed using ```config.login_background_image``` option in Character configuration file ```config/initializers/character.rb```.
87
+
88
+ ![Character Default Login](https://raw.github.com/slate-studio/character/master/doc/img/demo-3.jpg)
89
+
90
+
91
+ ## Generic App
92
+
93
+ Generic application is a main type of Character apps. It provides a way to setup administrative application for any [Mongoid](http://mongoid.org/en/mongoid/index.html) model in no time.
94
+
95
+ [Generic Application API Reference](https://github.com/slate-studio/character/blob/master/doc/generic_app.md)
96
+
97
+ ![Character Generic Application Demo](https://raw.github.com/slate-studio/character/master/doc/img/demo-2.jpg)
98
+
99
+
100
+ #### Model Admin
101
+
102
+ Here is an example of adding character admin app for ```Project``` model from the screenshot above. All model setups are added to ```app/assets/javascripts/admin.coffee```:
103
+
104
+ new CharacterApp 'Project',
105
+ icon: 'rocket'
106
+ reorder: true
107
+ scopes:
108
+ default:
109
+ order_by: '_position:desc'
110
+
111
+ Projects app added to character with ```rocket``` menu icon from [Fontawesome Icons](http://fontawesome.io/icons/), default sort order uses ```_position``` model field, and items are reorderable in the list with drag'n'drop to make it possible to reorder projects from the portfolio page.
112
+
113
+
114
+ #### Forms
115
+
116
+ By default object forms are autogenerated, [here](https://github.com/slate-studio/character/blob/master/app/views/character/generic_form.html.erb) is a template with is used to do that. At this point it's very simple generator and we have a plan to make more sophisticated. So you might want to customize objects form and it's pretty easy to do this.
117
+
118
+ Character looks for forms templates at ```app/views/character/[pluralized_model_name]/form.html.erb```, so in the example above form should be placed at: ```app/views/character/projects/form.html.erb```. Generic template is good to start customization with:
119
+
120
+ <%= simple_form_for @object, url: @form_action_url do |f| %>
121
+ <div class='row'>
122
+ <% @form_fields.each do |name| %>
123
+ <%= f.input name, wrapper_class: 'small-12 columns' %>
124
+ <% end %>
125
+ </div>
126
+ <% end %>
127
+
128
+ [Simple Form](https://github.com/plataformatec/simple_form) and [Nested Form](https://github.com/ryanb/nested_form) could be used for building forms.
129
+
130
+ [Nested Form](https://github.com/ryanb/nested_form) is a very handy gem to expand forms with editable inlines. It plays very nice with Character. Customized form could include nested forms. Following screenshot shows part of the Project form -- editable list of embeded images into the Project model handled by [Nested Form](https://github.com/ryanb/nested_form).
131
+
132
+ ![Character Nested Forms Demo](https://raw.github.com/slate-studio/character/master/doc/img/demo-4.jpg)
133
+
134
+
135
+ ## Instances
136
+
137
+ Instances allow you to use several independent character app instances for one website. Each of them will be using separate configuration, styles and templates.
138
+
139
+ [See instances section for details](https://github.com/slate-studio/character/blob/master/doc/instances.md)
140
+
141
+
142
+ ## Settings
143
+
144
+ Settings application provides a generic way of expanding admin with editable sets of parameters (objects) or editable collections. One of good examples of usage of settings app is an admin application which allows to add/remove admin users:
145
+
146
+ ![Character Nested Forms Demo](https://raw.github.com/slate-studio/character/master/doc/img/demo-5.jpg)
147
+
148
+ Settings could be used to provide a simple way of editing CTAs, webpage editable content, etc. Read more on Character Settings [here](https://github.com/slate-studio/character/blob/master/doc/settings.md).
149
+
150
+
151
+ ## Tests
152
+
153
+ To run the tests use the following command in the gem's root directory:
154
+
155
+ $ rspec
156
+
157
+
158
+ --
159
+ * [Олександр Кравець](http://www.akravets.com) @ [Slate](http://www.slatestudio.com) - January 23, 2014
160
+ * Роман Лупійчук @ [Slate](http://www.slatestudio.com) - August 9, 2013
161
+ * Мельник Максим @ [Slate](http://www.slatestudio.com) - October 23, 2013
@@ -0,0 +1,19 @@
1
+ ## Generic App
2
+
3
+ [Documentation Index](https://github.com/slate-studio/character/blob/master/README.md)
4
+
5
+ ### API
6
+
7
+ API url endpoint for model: ```/admin/<ModelName>?```
8
+
9
+ Parameters:
10
+
11
+ * ```order_by``` -- sort order for result list, e.g. ```order_by=report_date:asc```
12
+ * ```fields_to_include``` -- comma separated list of field names to be returned, e.g. ```fields_to_include=report_date,revenue,tax,shipping```
13
+ * ```search_query```
14
+ * ```page``` --
15
+ * ```per_page``` --
16
+ * ```__title``` --
17
+ * ```__meta``` --
18
+ * ```reorderable``` -- true/false
19
+
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,39 @@
1
+ ## Instances
2
+
3
+ Instances allow you to use several independent admins for one website. Each of them will be using separate configuration, styles and templates.
4
+
5
+ ### Configuration
6
+
7
+ Example of configuration for two character instances, this must be included in `config/initializers` folder.
8
+
9
+ ```ruby
10
+ Character.configure do |config|
11
+ config.instance 'producers' do |instance|
12
+ instance.title = 'Producer Cabinet'
13
+ instance.user_model = 'Producer'
14
+
15
+ instance.permissions_filter = proc do
16
+ %w(Producer Videos).include? model_class.name
17
+ end
18
+ end
19
+
20
+ config.instance 'admin' do |instance|
21
+ instance.title = 'Admin'
22
+ end
23
+ end
24
+ ```
25
+
26
+ List of all available options.
27
+
28
+ | Option | Description | Default |
29
+ | ------------------------ | ----------------------------- | --------- |
30
+ | title | Title of the instance | |
31
+ | user_model | Model to authenticate users, must be [browserid](https://github.com/alexkravets/browserid-auth-rails) compatible | Character::User |
32
+ | javascript_filename | JavaScript configuration file | Name of instance |
33
+ | stylesheet_filename | Stylesheet file | Name of instance |
34
+ | logo_image | See main doc for details | |
35
+ | login_background_image | See main doc for details | |
36
+
37
+ ### Templates
38
+
39
+ Each instance has its own templates. They must live under `character/#{ instance name }` folder. E.g. under `character/admin` & `character/producers` for configuration from "Configuration" section.
@@ -0,0 +1 @@
1
+ ## Settings
@@ -1,3 +1,31 @@
1
+ # frontend assets
2
+ require 'compass-rails'
3
+ require 'font-awesome-rails'
4
+ require 'jquery-ui-rails'
5
+ require 'underscore-rails'
6
+ require 'marionette-rails'
7
+ require 'momentjs-rails'
8
+ require 'character_editor'
9
+ require 'rhythm'
10
+ require 'simple_form_scss'
11
+ require 'modernizr-rails'
12
+
13
+ # backend
14
+ require 'browserid-rails'
15
+ require 'simple_form'
16
+ require 'nested_form'
17
+ require 'kaminari'
18
+ require 'mongoid'
19
+ require 'mongoid_slug'
20
+ require 'mongoid_search'
21
+ require 'meta_tags'
22
+ require 'mini_magick'
23
+ require 'mongoid/carrierwave_serialization_patch'
24
+
25
+ # character
26
+ require 'character/settings'
27
+ require 'character/instance'
1
28
  require 'character/version'
2
29
  require 'character/engine'
3
- require "character/routing"
30
+ require 'character/routing'
31
+ require 'character/generators/bootstrap_generator'
@@ -1,5 +1,37 @@
1
1
  module Character
2
+ class << self
3
+ attr_writer :instances
4
+
5
+ def instances
6
+ if @instances.blank?
7
+ @instances = { Instance::DEFAULT_NAME => Instance.new }
8
+ else
9
+ @instances
10
+ end
11
+ end
12
+
13
+ def configure(&block)
14
+ block.call(self)
15
+ end
16
+
17
+ def instance(name, &block)
18
+ @custom_instance_name_used = true
19
+ raise StandardError.new("Please don't mix character instance configuration & default character configuration.") if @default_instance_name_used
20
+
21
+ block.call( @instances[name] ||= Instance.new(name) )
22
+ end
23
+
24
+ def method_missing(method, *args)
25
+ @default_instance_name_used = true
26
+ raise StandardError.new("Please don't mix character instance configuration & default character configuration.") if @custom_instance_name_used
27
+
28
+ ( @instances[Instance::DEFAULT_NAME] ||= Instance.new ).send method, *args
29
+ end
30
+ end
31
+
2
32
  class Engine < ::Rails::Engine
3
- isolate_namespace Character
33
+ config.before_configuration do
34
+ Character.instances = {}
35
+ end
4
36
  end
5
37
  end