browsercms 4.0.0.alpha → 4.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/bcms/ckeditor.js +1 -0
  3. data/app/assets/javascripts/bcms/{ckeditor_load.js.erb → ckeditor_load.js} +4 -1
  4. data/app/assets/javascripts/bcms/ckeditor_standard_config.js +1 -13
  5. data/app/assets/javascripts/cms/application.js +1 -0
  6. data/app/assets/javascripts/cms/{attachment_manager.js.erb → attachment_manager.js} +19 -13
  7. data/app/assets/javascripts/cms/content_types.js +13 -0
  8. data/app/assets/javascripts/cms/core_library.js.erb +3 -3
  9. data/app/assets/javascripts/cms/form_builder.js +1 -1
  10. data/app/assets/javascripts/cms/page_editor.js +9 -8
  11. data/app/assets/javascripts/cms/sitemap.js +5 -5
  12. data/app/assets/javascripts/cms/user.js +1 -1
  13. data/app/assets/stylesheets/cms/_assets.css.scss +5 -0
  14. data/app/assets/stylesheets/cms/_main-area.css.scss +1 -1
  15. data/app/assets/stylesheets/cms/_sitemap.css.scss +13 -0
  16. data/app/assets/stylesheets/cms/styles/_images.css.scss +11 -0
  17. data/app/controllers/cms/application_controller.rb +0 -1
  18. data/app/controllers/cms/content_controller.rb +3 -0
  19. data/app/controllers/cms/content_types_controller.rb +14 -0
  20. data/app/controllers/cms/inline_content_controller.rb +10 -8
  21. data/app/controllers/cms/passwords_controller.rb +5 -0
  22. data/app/controllers/cms/sites/passwords_controller.rb +5 -0
  23. data/app/helpers/cms/content_types_helper.rb +4 -0
  24. data/app/helpers/cms/form_tag_helper.rb +9 -1
  25. data/app/helpers/cms/page_helper.rb +2 -6
  26. data/app/helpers/cms/path_helper.rb +9 -0
  27. data/app/helpers/cms/section_nodes_helper.rb +1 -1
  28. data/app/inputs/name_input.rb +42 -0
  29. data/app/models/cms/attachment.rb +1 -0
  30. data/app/models/cms/content_type.rb +6 -0
  31. data/app/models/cms/dynamic_view.rb +2 -1
  32. data/app/models/cms/page.rb +6 -0
  33. data/app/models/cms/persistent_user.rb +1 -0
  34. data/app/models/cms/section_node.rb +8 -0
  35. data/app/models/cms/user.rb +9 -0
  36. data/app/portlets/helpers/cms/list_portlet_helper.rb +5 -0
  37. data/app/portlets/list_portlet.rb +40 -0
  38. data/app/views/cms/application/_add_content_modal.html.erb +2 -2
  39. data/app/views/cms/application/_exception.html.erb +1 -1
  40. data/app/views/cms/attachments/_attachment.html.erb +8 -6
  41. data/app/views/cms/attachments/_attachment_manager.html.erb +35 -18
  42. data/app/views/cms/attachments/_attachment_table.html.erb +12 -7
  43. data/app/views/cms/content/editing_frame.html.erb +1 -1
  44. data/app/views/cms/content_block/_sidebar.html.erb +2 -1
  45. data/app/views/cms/content_types/_order_field.html.erb +5 -0
  46. data/app/views/cms/content_types/index.html.erb +3 -0
  47. data/app/views/cms/forms/_form.html.erb +3 -2
  48. data/app/views/cms/pages/_main_form.html.erb +1 -1
  49. data/app/views/cms/passwords/new.html.erb +16 -0
  50. data/app/views/cms/section_nodes/_children.html.erb +2 -0
  51. data/app/views/cms/section_nodes/_row_buttons.html.erb +1 -1
  52. data/app/views/cms/section_nodes/_section_node.html.erb +1 -1
  53. data/app/views/cms/sessions/new.html.erb +10 -11
  54. data/app/views/layouts/cms/application.html.erb +4 -1
  55. data/app/views/portlets/email_page/_form.html.erb +1 -1
  56. data/app/views/portlets/email_page/render.html.erb +1 -1
  57. data/app/views/portlets/list/_form.html.erb +33 -0
  58. data/app/views/portlets/list/_list.html.erb +6 -0
  59. data/app/views/portlets/list/_table.html.erb +13 -0
  60. data/app/views/portlets/list/render.html.erb +1 -0
  61. data/app/views/portlets/tag_cloud/_form.html.erb +1 -1
  62. data/config/routes.rb +10 -5
  63. data/db/browsercms.seeds.rb +10 -8
  64. data/db/migrate/20130327184912_browsercms400.rb +30 -0
  65. data/doc/features/simple_form_refactor.md +2 -2
  66. data/doc/release_notes.md +38 -1
  67. data/lib/cms/acts/cms_user.rb +2 -2
  68. data/lib/cms/authentication/test_password_strategy.rb +10 -1
  69. data/lib/cms/behaviors/connecting.rb +20 -9
  70. data/lib/cms/commands/actions.rb +1 -3
  71. data/lib/cms/configuration.rb +2 -1
  72. data/lib/cms/configure_simple_form_bootstrap.rb +9 -0
  73. data/lib/cms/engine.rb +14 -5
  74. data/lib/cms/route_extensions.rb +2 -0
  75. data/lib/cms/version.rb +1 -1
  76. data/lib/generators/cms/content_block/content_block_generator.rb +21 -0
  77. data/lib/generators/cms/content_block/templates/_form.html.erb +1 -1
  78. data/lib/generators/cms/content_block/templates/application_controller.rb.erb +4 -0
  79. data/lib/generators/cms/content_block/templates/render.html.erb +22 -20
  80. data/lib/generators/cms/portlet/templates/_form.html.erb +3 -3
  81. data/lib/generators/cms/portlet/templates/portlet.rb +2 -0
  82. metadata +25 -15
  83. data/app/inputs/cms_text_field_input.rb +0 -29
  84. data/db/migrate/20131206214021_devise_create_users.rb +0 -47
  85. data/db/migrate/20131211223908_kill_reset_password.rb +0 -5
  86. data/db/migrate/20131218222005_create_cms_external_users.rb +0 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 823840598ca36d83107fe20da64f6385708fc561
4
- data.tar.gz: 14697d04fda45494e9b9f251423b0c2b932f4408
3
+ metadata.gz: 980ba0416e629ef492f4df18bc1900a124c0da63
4
+ data.tar.gz: ca6fa881df98da38d65317d1b3dba252aafe3967
5
5
  SHA512:
6
- metadata.gz: dd83ce37f9b57de888b0dba23da366a13465d3170aceaa0e105e840d04167fddbc88a7d5556cba108af66cc45f8d2de810f095d358bb0240d687a6783ab19d62
7
- data.tar.gz: 72a6338860e4222696725d10f314b4338b0a77c22e18f3f686bc04e81498c674f7d0e507fc0495c5c675fc78fec529cb980e1fdaac327d8899cc8f8f76bdff6b
6
+ metadata.gz: b5cd4fc8aa08543d97a95fc3b2e116eee8b2e0a9e68af42272054670b804fbc4c9b9a61b991cff5c82b4c6c673d18ba575c53f7938404c8bb2234c0218ab0b34
7
+ data.tar.gz: 61c8168049b056485dd0da0e007d685edf03e84dfd269aee17553f03454562f6d0d5436672848fcf50bdaefc313ca7afba533480744244ca26c26a866738f076
@@ -4,4 +4,5 @@
4
4
  //
5
5
  //= require ckeditor-jquery
6
6
  //= require bcms/ckeditor_load
7
+ //= require bcms/ckeditor_standard_config
7
8
 
@@ -41,7 +41,10 @@ function toggleEditor(id, status) {
41
41
  function loadEditor(id) {
42
42
  if (typeof(CKEDITOR) != "undefined") {
43
43
  if (CKEDITOR.instances[id] == null) {
44
- CKEDITOR.replace(id, { customConfig:'<%= asset_path(Rails.application.config.cms.ckeditor.configuration_file) %>' });
44
+ editor = CKEDITOR.replace(id);
45
+ editor.config.toolbar = 'Standard';
46
+ editor.config.width = '100%';
47
+ editor.config.height = 400;
45
48
  }
46
49
  $.cookie('editorEnabled', true, { expires:90, path:'/' });
47
50
  return true;
@@ -3,20 +3,8 @@
3
3
  // As per http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html#.customConfig using a custom config
4
4
  // avoids the need to 'mask' the core default config.js file that CKEDITOR comes packaged with.
5
5
 
6
- CKEDITOR.config.toolbar_CMS = [
6
+ CKEDITOR.config.toolbar_Standard = [
7
7
  ['Source','-','Cut','Copy','Paste','PasteText','PasteFromWord','-','SpellChecker','Scayt','-','Undo','Redo','Find','Replace','RemoveFormat','-','NumberedList','BulletedList','Outdent','Indent','HorizontalRule'],
8
8
  '/',
9
9
  ['Link','Unlink','Anchor','Image','Table','SpecialChar','-','Bold','Italic','Underline','JustifyLeft','JustifyCenter','JustifyRight','JustifyFull','-','TextColor','Styles']
10
10
  ];
11
-
12
- CKEDITOR.config.toolbar_CMSForms = [
13
- ['Source','-','Cut','Copy','Paste','PasteText','PasteFromWord','-','SpellChecker','Scayt','-','Undo','Redo','Find','Replace','RemoveFormat','-','NumberedList','BulletedList','Outdent','Indent','HorizontalRule'],
14
- '/',
15
- ['Link','Unlink','Anchor','Image','Table','SpecialChar','Bold','Italic','Underline','JustifyLeft','JustifyCenter','JustifyRight','JustifyFull','TextColor','Styles'],
16
- '/',
17
- ['TextField','Select','Checkbox','Radio','Textarea','Button','ImageButton','HiddenField']
18
- ];
19
-
20
- CKEDITOR.config.width = '100%';
21
- CKEDITOR.config.height = 400;
22
- CKEDITOR.config.toolbar = 'CMS';
@@ -9,6 +9,7 @@
9
9
  //= require jquery.taglist
10
10
  //= require jquery.ui.all
11
11
  //= require cms/core_library
12
+ //= require cms/content_types
12
13
  //= require cms/attachment_manager
13
14
  //= require cms/form_builder
14
15
  //= require cms/sitemap
@@ -3,12 +3,11 @@
3
3
  $(function () {
4
4
  $.cms.AttachmentManager = {
5
5
  upload:function (file) {
6
- var assetName = $('#asset_types').val()
6
+ var assetName = $('#attachment_attachable_type').val()
7
7
  , attachableClass = $('#asset_attachable_class').val()
8
- , attachableIDField = $('#asset_attachable_id')
9
- , attachableID = attachableIDField.val()
8
+ // , attachableIDField = $('#asset_attachable_id')
9
+ , attachableID = $('#asset_attachable_id').val()
10
10
  , file = $('#asset_add_file')
11
- , clone = file.clone()
12
11
  , form = $('<form target="asset_add_uploader" method="post" action="/cms/attachments" enctype="multipart/form-data" style="visibility:hidden">')
13
12
  , fields = '';
14
13
 
@@ -21,21 +20,24 @@ $(function () {
21
20
  $('body').append(form);
22
21
  form.append(fields);
23
22
  form.append(file);
24
- attachableIDField.after(clone);
23
+ $('label[for="asset_add_file"]').after(file.clone());
25
24
 
26
25
  var inp = $('<input type="file" name="attachment[data]" id="asset_add_file" onchange="$.cms.AttachmentManager.upload(this)" />');
27
26
 
28
- clone.after($('<img>')
29
- .css({position:'static', margin:'5px 0 0 5px', 'verticalAlign':'middle'})
30
- .attr({'id':'file-asset-uploader', 'src':'<%= asset_path 'cms/file-uploading.gif' %>'}));
31
- clone.replaceWith(inp);
32
-
33
27
  form.submit();
34
28
 
35
- $('div.buttons').hide();
36
-
29
+ $('#upload-attachment').modal('hide');
30
+ },
31
+ enableDeleteButtons:function(){
32
+ // Handle delete attachment button
33
+ var delete_attachments_btns = $("a[data-purpose='delete-attachment']");
34
+ if(delete_attachments_btns.exists()){
35
+ delete_attachments_btns.off('click').on('click', function(){
36
+ var id = $(this).data('id');
37
+ $.cms.AttachmentManager.destroy(id);
38
+ });
39
+ }
37
40
  },
38
-
39
41
  // @param [Integer] id The id of the attachment to delete.
40
42
  destroy:function (id) {
41
43
  if (confirm("Are you sure want to delete this attachment?")) {
@@ -78,5 +80,9 @@ $(function () {
78
80
  $('#assets_table > table').append(asset).show();
79
81
  $('div.buttons').show();
80
82
  }
83
+ $('.empty-row').hide();
84
+ $.cms.AttachmentManager.enableDeleteButtons();
81
85
  });
86
+
87
+ $.cms.AttachmentManager.enableDeleteButtons();
82
88
  });
@@ -0,0 +1,13 @@
1
+ // Adds AJAX behavior primarily for List Portlet
2
+
3
+ jQuery(function($){
4
+ var select_tag = $('*[data-role="content_type_selector"]');
5
+ var order_field = $('*[data-role="order-fields"]');
6
+ if(select_tag.exists()){
7
+ select_tag.on('change', function(){
8
+ var selected_option = $( this ).val();
9
+ console.log("Changed to", selected_option );
10
+ order_field.load( '/cms/content_types.js .load > .select', { "content_type": selected_option } )
11
+ });
12
+ }
13
+ });
@@ -113,7 +113,7 @@ jQuery(function($) {
113
113
  // .slug-dest - The input field to set the slug value in.
114
114
  // @options data-prefix An optional prefix (on slug-dest) that should be added in front of autogenerated slugs
115
115
  // (i.e. <input class='slug-dest' data-prefix="/products" />)
116
- $(function() {
116
+ jQuery(function($){
117
117
  if ($('.slug-dest').length && $('.slug-source').length) {
118
118
  $('.slug-source').keyup(function() {
119
119
  var name = $('.slug-source').val();
@@ -134,14 +134,14 @@ $(function() {
134
134
  });
135
135
 
136
136
  // Automatically enable date_picker controls
137
- $(function() {
137
+ jQuery(function($){
138
138
  if ($.datepicker) {
139
139
  $('input.date_picker').datepicker({ changeFirstDay: false, changeMonth: true, changeYear: true, closeText: '', showButtonPanel: true, dateFormat: '<%= Cms::DatePicker.jquery_format %>' });
140
140
  }
141
141
  });
142
142
 
143
143
  // UI Enhancement to suggest paths for uploaded files
144
- $(function() {
144
+ jQuery(function($){
145
145
  var path_input = $('.suggest_file_path');
146
146
  if (path_input.length) {
147
147
  $('select[data-purpose=section_selector], input[data-purpose=cms_file_field]').change(function() {
@@ -241,7 +241,7 @@ FormBuilder.prototype.setupConfirmationBehavior = function() {
241
241
  var formBuilder = new FormBuilder();
242
242
 
243
243
  // Register FormBuilder handlers on page load.
244
- $(function() {
244
+ jQuery(function($){
245
245
  formBuilder.setup();
246
246
 
247
247
 
@@ -1,15 +1,17 @@
1
+ //= require 'jquery'
1
2
  //= require 'jquery_ujs'
2
3
  //= require 'cms/core_library'
3
4
  //= require 'bootstrap/modal'
4
- //= require 'ckeditor-jquery'
5
+ //= require 'bcms/ckeditor'
6
+ //= require 'bcms/ckeditor_inline'
5
7
  //= require 'cms/ajax'
6
8
 
7
9
  // Since we are within the page editing iframe, add a 'target=_top' to all links so they refresh the entire page.
8
- $(function() {
10
+ jQuery(function($){
9
11
  $('a').attr('target', '_top');
10
12
  });
11
13
 
12
- $(function() {
14
+ jQuery(function($){
13
15
  $.cms_editor = {
14
16
  // Returns the widget that a user has currently selected.
15
17
  // @return [JQuery.Element]
@@ -102,7 +104,7 @@ $(function() {
102
104
  content: {}
103
105
  };
104
106
  message["content"][attribute] = data;
105
- var path = '/cms/inline_content/' + content_name + "/" + content_id;
107
+ var path = '/cms/inline_content/' + content_id + "?content_name=" + content_name;
106
108
 
107
109
  $.cms_ajax.put({
108
110
  url: path,
@@ -121,7 +123,7 @@ $(function() {
121
123
  });
122
124
 
123
125
  // On Ready
124
- $(function() {
126
+ jQuery(function($){
125
127
 
126
128
  // Click the 'Add Content' button (PLUS) when editing content.
127
129
  $('.cms-add-content').click(function() {
@@ -136,7 +138,6 @@ $(function() {
136
138
  $("#page_title").each(function() {
137
139
  var id = $(this).attr('id');
138
140
  CKEDITOR.inline(id, {
139
- customConfig: '/assets/bcms/ckeditor_inline.js',
140
141
  toolbar: 'page_title',
141
142
  on: {
142
143
  blur: function(event) {
@@ -149,8 +150,7 @@ $(function() {
149
150
  // Create editors for each content-block on the page.
150
151
  $(".content-block").each(function() {
151
152
  var id = $(this).attr('id');
152
- CKEDITOR.inline(id, {
153
- customConfig: '/assets/bcms/ckeditor_inline.js',
153
+ editor = CKEDITOR.inline(id, {
154
154
  toolbar: 'inline',
155
155
  on: {
156
156
  blur: function(event) {
@@ -158,6 +158,7 @@ $(function() {
158
158
  }
159
159
  }
160
160
  });
161
+
161
162
  });
162
163
 
163
164
 
@@ -95,7 +95,7 @@ Sitemap.prototype.open = function(row, options) {
95
95
  options = options || {}
96
96
  _.defaults(options, {animate: true});
97
97
  this.changeIcon(row, 'icon-folder-open');
98
- var siblings = row.siblings('ul.nav');
98
+ var siblings = row.siblings('.children');
99
99
  if (options.animate) {
100
100
  siblings.slideToggle();
101
101
  }
@@ -114,7 +114,7 @@ Sitemap.prototype.attemptOpen = function(row, options) {
114
114
 
115
115
  Sitemap.prototype.close = function(row) {
116
116
  this.changeIcon(row, 'icon-folder');
117
- row.siblings('ul.nav').slideToggle();
117
+ row.siblings('.children').slideToggle();
118
118
  this.saveAsClosed(row.data('id'));
119
119
  };
120
120
 
@@ -138,7 +138,7 @@ Sitemap.prototype.updateDepth = function(element, newDepth) {
138
138
  var sitemap = new Sitemap();
139
139
 
140
140
  // Enable dragging of items around the sitemap.
141
- $(function() {
141
+ jQuery(function($){
142
142
  if ($('#sitemap').exists()) {
143
143
 
144
144
  $('#sitemap .draggable').draggable({
@@ -188,7 +188,7 @@ $(function() {
188
188
  });
189
189
 
190
190
  // Open/close folders when rows are clicked.
191
- $(function() {
191
+ jQuery(function($){
192
192
  // Ensure this only loads on sitemap page.
193
193
  if ($('#sitemap').exists()) {
194
194
  sitemap.restoreOpenState();
@@ -201,7 +201,7 @@ $(function() {
201
201
  });
202
202
 
203
203
  // Make Sitemap filters show specific content types.
204
- $(function() {
204
+ jQuery(function($){
205
205
  $('#sitemap li[data-nodetype]').hide();
206
206
  $('#filtershow').change(function() {
207
207
  $('#sitemap li[data-nodetype]').slideUp();
@@ -26,7 +26,7 @@ Cms.User.current = function(handler) {
26
26
  };
27
27
 
28
28
  // Default Handler for login portlet. Hide the form, show 'Hello $first_name'
29
- $(function() {
29
+ jQuery(function($){
30
30
  if ($('.login-portlet').exists()) {
31
31
  Cms.User.current({
32
32
  authenticated: function(user) {
@@ -52,4 +52,9 @@
52
52
  }
53
53
  }
54
54
  }
55
+ }
56
+
57
+ // Iframe for attachments
58
+ #asset_add_uploader {
59
+ display: none;
55
60
  }
@@ -1,5 +1,5 @@
1
1
  /* MAIN FORM AREA */
2
- .main-content {
2
+ .main-content, .modal-body {
3
3
  @include rem(margin-top,1rem);
4
4
 
5
5
  .add-link {
@@ -5,8 +5,17 @@
5
5
  border: 1px solid rgba(black,0.1);
6
6
  @include border-radius(5px);
7
7
  @include rem(margin-bottom,1.5rem);
8
+
9
+ .children {
10
+ width: 100%;
11
+ height: 0%;
12
+ &.hide {
13
+ display: none;
14
+ }
15
+ }
8
16
  }
9
17
 
18
+
10
19
  .nav-list {
11
20
  width: 100%;
12
21
  list-style-type: none;
@@ -23,6 +32,10 @@
23
32
  display: none;
24
33
  }
25
34
  .nav-list-item {
35
+ display: block;
36
+ float: left;
37
+ clear: both;
38
+ width: 100%;
26
39
  list-style-type: none;
27
40
  margin: 0;
28
41
  padding: 0;
@@ -4,6 +4,17 @@ img {
4
4
  height: auto;
5
5
  display: inline-block;
6
6
  }
7
+
8
+ // Image blocks viewed within the CMS shouldn't be 100% width.
9
+ img[data-type="image_block"] {
10
+ width: auto;
11
+ max-width: 100%;
12
+ }
13
+
14
+ // For multiple attachments in the table
15
+ img[data-purpose='attachment'] {
16
+ width:60px;
17
+ }
7
18
  .img-rounded {
8
19
  @include border-radius(6px);
9
20
  }
@@ -1,6 +1,5 @@
1
1
  module Cms
2
2
  class ApplicationController < ::ApplicationController
3
3
  include Cms::AdminController
4
-
5
4
  end
6
5
  end
@@ -67,6 +67,9 @@ module Cms
67
67
 
68
68
  def render_editing_frame
69
69
  @page_title = @page.page_title
70
+
71
+ # Adds all provided parameters to the iframe
72
+ @edit_page_path = ActionDispatch::Http::URL.url_for(path: edit_content_path(current_page), params: params.except(:controller, :action, :path), only_path: true)
70
73
  render 'editing_frame', :layout => 'cms/page_editor'
71
74
  end
72
75
 
@@ -0,0 +1,14 @@
1
+ require_dependency "cms/application_controller"
2
+
3
+ module Cms
4
+ class ContentTypesController < ApplicationController
5
+
6
+ def index
7
+ content_type = ContentType.named(params[:content_type]).first
8
+ @attributes = content_type.orderable_attributes.sort()
9
+ respond_to do |format|
10
+ format.js { render :layout => false }
11
+ end
12
+ end
13
+ end
14
+ end
@@ -14,16 +14,18 @@ module Cms
14
14
  status_label = "Published"
15
15
  end
16
16
 
17
- # After a page update, all the connector ids change. So we need to send
17
+ # After a page update, all the connector ids can change. So we need to send
18
18
  # the new move up/down/remove paths to client so they will work after an inline update.
19
- connectors = @page.current_connectors(params[:container].to_sym)
20
19
  routes = []
21
- connectors.each do |c|
22
- routes << {
23
- move_up: cms.move_up_connector_path(c, format: :json),
24
- move_down: cms.move_down_connector_path(c, format: :json),
25
- remove: cms.connector_path(c, format: :json)
26
- }
20
+ if params[:container]
21
+ connectors = @page.current_connectors(params[:container].to_sym)
22
+ connectors.each do |c|
23
+ routes << {
24
+ move_up: cms.move_up_connector_path(c, format: :json),
25
+ move_down: cms.move_down_connector_path(c, format: :json),
26
+ remove: cms.connector_path(c, format: :json)
27
+ }
28
+ end
27
29
  end
28
30
  results = {
29
31
  page_status: page_status,
@@ -8,6 +8,11 @@ module Cms
8
8
  super
9
9
  end
10
10
 
11
+ def create
12
+ use_page_title('Forgot Password')
13
+ super
14
+ end
15
+
11
16
  def edit
12
17
  use_page_title('Change Password')
13
18
  super
@@ -16,6 +16,11 @@ module Cms
16
16
  super
17
17
  end
18
18
 
19
+ def edit
20
+ use_page_title('Reset Password')
21
+ super
22
+ end
23
+
19
24
  protected
20
25
 
21
26
  # @override [Devise::PasswordsController]
@@ -0,0 +1,4 @@
1
+ module Cms
2
+ module ContentTypesHelper
3
+ end
4
+ end