locomotive_cms 2.0.0.rc4 → 2.0.0.rc5

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 (51) hide show
  1. data/app/assets/images/locomotive/list/icons/toggle.png +0 -0
  2. data/app/assets/images/locomotive/list/icons/toggle_off.png +0 -0
  3. data/app/assets/javascripts/locomotive/application.js.coffee +2 -2
  4. data/app/assets/javascripts/locomotive/models/page.js.coffee +1 -1
  5. data/app/assets/javascripts/locomotive/utils/core_ext.js +2 -2
  6. data/app/assets/javascripts/locomotive/views/content_types/custom_field_entry_view.js.coffee +2 -0
  7. data/app/assets/javascripts/locomotive/views/content_types/edit_view.coffee +0 -1
  8. data/app/assets/javascripts/locomotive/views/editable_elements/long_text_view.js.coffee +30 -2
  9. data/app/assets/javascripts/locomotive/views/editable_elements/short_text_view.js.coffee +7 -19
  10. data/app/assets/javascripts/locomotive/views/inline_editor/application_view.js.coffee +2 -6
  11. data/app/assets/javascripts/locomotive/views/inline_editor/toolbar_view.js.coffee +0 -6
  12. data/app/assets/javascripts/locomotive/views/pages/_form_view.js.coffee +1 -1
  13. data/app/assets/javascripts/locomotive/views/pages/edit_view.js.coffee +6 -3
  14. data/app/assets/javascripts/locomotive/views/shared/form_view.js.coffee +13 -1
  15. data/app/assets/javascripts/locomotive/views/theme_assets/index_view.js.coffee +12 -4
  16. data/app/assets/stylesheets/locomotive/backoffice/application.css.scss +23 -0
  17. data/app/assets/stylesheets/locomotive/backoffice/formtastic_changes.css.scss +15 -0
  18. data/app/assets/stylesheets/locomotive/backoffice/layout.css.scss +1 -1
  19. data/app/mailers/locomotive/notifications.rb +1 -1
  20. data/app/models/locomotive/content_entry.rb +1 -1
  21. data/app/models/locomotive/extensions/site/locales.rb +32 -1
  22. data/app/models/locomotive/extensions/site/subdomain_domains.rb +6 -2
  23. data/app/models/locomotive/page.rb +1 -1
  24. data/app/views/locomotive/notifications/new_content_entry.html.haml +12 -5
  25. data/app/views/locomotive/pages/_form.html.haml +1 -1
  26. data/app/views/locomotive/shared/_form_actions.html.haml +1 -1
  27. data/app/views/locomotive/shared/_head.html.haml +5 -2
  28. data/app/views/locomotive/theme_assets/index.html.haml +1 -1
  29. data/config/initializers/haml.rb +2 -1
  30. data/config/locales/admin_ui.de.yml +1 -0
  31. data/config/locales/admin_ui.en.yml +3 -0
  32. data/config/locales/admin_ui.es.yml +1 -0
  33. data/config/locales/admin_ui.fr.yml +2 -0
  34. data/config/locales/admin_ui.it.yml +1 -0
  35. data/config/locales/admin_ui.nl.yml +1 -0
  36. data/config/locales/admin_ui.no.yml +1 -0
  37. data/config/locales/admin_ui.pt-BR.yml +1 -0
  38. data/config/locales/admin_ui.ru.yml +1 -0
  39. data/config/locales/default.en.yml +2 -0
  40. data/config/locales/default.fr.yml +2 -0
  41. data/lib/generators/locomotive/install/templates/README +2 -2
  42. data/lib/locomotive.rb +1 -0
  43. data/lib/locomotive/action_controller/responder.rb +8 -0
  44. data/lib/locomotive/core_ext.rb +1 -1
  45. data/lib/locomotive/dependencies.rb +1 -0
  46. data/lib/locomotive/haml.rb +32 -0
  47. data/lib/locomotive/render.rb +2 -1
  48. data/lib/locomotive/version.rb +1 -1
  49. data/lib/locomotive_cms.rb +1 -0
  50. data/vendor/assets/javascripts/locomotive/form_submit_notification.js +39 -0
  51. metadata +97 -72
@@ -4,9 +4,9 @@
4
4
  #= require_tree ./views
5
5
 
6
6
  window.Locomotive =
7
- mounted_on: '/locomotive' # default path
7
+ mounted_on: window.Locomotive.mounted_on
8
8
  Models: {}
9
9
  Collections: {}
10
10
  Views: {}
11
11
 
12
- window.Locomotive.Views.Memberships = {}
12
+ window.Locomotive.Views.Memberships = {}
@@ -16,7 +16,7 @@ class Locomotive.Models.Page extends Backbone.Model
16
16
 
17
17
  toJSON: ->
18
18
  _.tap super, (hash) =>
19
- _.each ['content_type_id_text', 'edit_url', 'parent_id_text', 'response_type_text'], (key) => delete hash[key]
19
+ _.each ['fullpath', 'localized_fullpaths', 'templatized_from_parent', 'target_klass_name_text', 'content_type_id_text', 'edit_url', 'parent_id_text', 'response_type_text'], (key) => delete hash[key]
20
20
 
21
21
  delete hash['editable_elements']
22
22
  hash.editable_elements = @get('editable_elements').toJSONForSave() if @get('editable_elements')? && @get('editable_elements').length > 0
@@ -18,9 +18,9 @@
18
18
 
19
19
  String.prototype.slugify = function(sep) {
20
20
  if (typeof sep == 'undefined') sep = '_';
21
- var alphaNumRegexp = new RegExp('[^a-zA-Z0-9\\' + sep + ']', 'g');
21
+ var alphaNumRegexp = new RegExp('[^\\w\\' + sep + ']', 'g');
22
22
  var avoidDuplicateRegexp = new RegExp('[\\' + sep + ']{2,}', 'g');
23
- return this.replace(/\s/g, sep).replace(alphaNumRegexp, '').replace(avoidDuplicateRegexp, sep).toLowerCase()
23
+ return this.replace(/\s/g, sep).replace(alphaNumRegexp, '').replace(avoidDuplicateRegexp, sep).toLowerCase();
24
24
  }
25
25
 
26
26
  window.addParameterToURL = function(key, value, context) { // code from http://stackoverflow.com/questions/486896/adding-a-parameter-to-the-url-with-javascript
@@ -78,8 +78,10 @@ class Locomotive.Views.ContentTypes.CustomFieldEntryView extends Backbone.View
78
78
  form = @$('ol')
79
79
 
80
80
  if form.is(':hidden')
81
+ @$('a.toggle').addClass('open')
81
82
  form.slideDown()
82
83
  else
84
+ @$('a.toggle').removeClass('open')
83
85
  form.slideUp()
84
86
 
85
87
  show_error: (message) ->
@@ -11,5 +11,4 @@ class Locomotive.Views.ContentTypes.EditView extends Locomotive.Views.ContentTyp
11
11
 
12
12
  if custom_field.isNew() # assign an id for each new custom field
13
13
  custom_field.set id: data._id, _id: data._id
14
- console.log(custom_field)
15
14
 
@@ -2,7 +2,35 @@
2
2
 
3
3
  Locomotive.Views.EditableElements ||= {}
4
4
 
5
- class Locomotive.Views.EditableElements.LongTextView extends Locomotive.Views.EditableElements.ShortTextView
5
+ class Locomotive.Views.EditableElements.LongTextView extends Backbone.View
6
+
7
+ tagName: 'li'
8
+
9
+ className: 'text input html'
10
+
11
+ render: ->
12
+ $(@el).html(ich.editable_text_input(@model.toJSON()))
13
+
14
+ return @
15
+
16
+ after_render: ->
17
+ settings = _.extend {}, @tinymce_settings(),
18
+ oninit: ((editor) =>
19
+ $.cmd 'S', (() =>
20
+ @model.set(content: editor.getBody().innerHTML)
21
+ $(@el).parents('form').trigger('submit')
22
+ ), [], ignoreCase: true, document: editor.dom.doc),
23
+ onchange_callback: (editor) =>
24
+ @model.set(content: editor.getBody().innerHTML)
25
+
26
+ @$('textarea').tinymce(settings)
6
27
 
7
28
  tinymce_settings: ->
8
- window.Locomotive.tinyMCE.defaultSettings
29
+ window.Locomotive.tinyMCE.defaultSettings
30
+
31
+ refresh: ->
32
+ # do nothing
33
+
34
+ remove: ->
35
+ @$('textarea').tinymce().destroy()
36
+ super
@@ -4,31 +4,19 @@ class Locomotive.Views.EditableElements.ShortTextView extends Backbone.View
4
4
 
5
5
  tagName: 'li'
6
6
 
7
- className: 'text input html'
7
+ className: 'text input short'
8
8
 
9
9
  render: ->
10
10
  $(@el).html(ich.editable_text_input(@model.toJSON()))
11
11
 
12
+ @$('textarea').bind 'keyup', (event) =>
13
+ input = $(event.target)
14
+ @model.set(content: input.val())
15
+
12
16
  return @
13
17
 
14
18
  after_render: ->
15
- settings = _.extend {}, @tinymce_settings(),
16
- oninit: ((editor) =>
17
- $.cmd 'S', (() =>
18
- @model.set(content: editor.getBody().innerHTML)
19
- $(@el).parents('form').trigger('submit')
20
- ), [], ignoreCase: true, document: editor.dom.doc),
21
- onchange_callback: (editor) =>
22
- @model.set(content: editor.getBody().innerHTML)
23
-
24
- @$('textarea').tinymce(settings)
25
-
26
- tinymce_settings: ->
27
- window.Locomotive.tinyMCE.minimalSettings
28
-
29
- refresh: ->
30
19
  # do nothing
31
20
 
32
- remove: ->
33
- @$('textarea').tinymce().destroy()
34
- super
21
+ refresh: ->
22
+ # do nothing
@@ -26,15 +26,13 @@ class Locomotive.Views.InlinEditor.ApplicationView extends Backbone.View
26
26
  iframe = @iframe
27
27
 
28
28
  iframe.load =>
29
- console.log('iframe loading')
30
-
31
29
  if @_$('meta[name=inline-editor]').size() > 0
32
30
  # bind the resize event. When the iFrame's size changes, update its height
33
- iframe_content = iframe.contents().find('body')
31
+ iframe_content = iframe.contents()
34
32
  iframe_content.resize ->
35
33
  elem = $(this)
36
34
 
37
- if elem.outerHeight(true) > $('body').outerHeight(true) # Resize the iFrame.
35
+ if elem.outerHeight(true) > iframe.outerHeight(true) # Resize the iFrame.
38
36
  iframe.css height: elem.outerHeight(true)
39
37
 
40
38
  # Resize the iFrame immediately.
@@ -46,8 +44,6 @@ class Locomotive.Views.InlinEditor.ApplicationView extends Backbone.View
46
44
  @enhance_iframe_links()
47
45
 
48
46
  set_page: (attributes) ->
49
- console.log('set_page')
50
-
51
47
  @page = new Locomotive.Models.Page(attributes)
52
48
 
53
49
  @toolbar_view.model = @page
@@ -13,8 +13,6 @@ class Locomotive.Views.InlinEditor.ToolbarView extends Backbone.View
13
13
  render: ->
14
14
  super
15
15
 
16
- console.log('render toolbar')
17
-
18
16
  @enable_editing_mode_checkbox()
19
17
 
20
18
  @enable_content_locale_picker()
@@ -22,8 +20,6 @@ class Locomotive.Views.InlinEditor.ToolbarView extends Backbone.View
22
20
  @
23
21
 
24
22
  notify: (aloha_editable) ->
25
- console.log('editable_element has been modified...')
26
-
27
23
  window.bar = aloha_editable
28
24
 
29
25
  element_id = aloha_editable.obj.attr('data-element-id')
@@ -125,8 +121,6 @@ class Locomotive.Views.InlinEditor.ToolbarView extends Backbone.View
125
121
  context.find('span.text').html(values[1])
126
122
 
127
123
  refresh: ->
128
- console.log('refreshing toolbar...')
129
-
130
124
  @$('h1').html(@model.get('title')).removeClass()
131
125
 
132
126
  if @$('.editing-mode input[type=checkbox]').is(':checked')
@@ -116,7 +116,7 @@ class Locomotive.Views.Pages.FormView extends Locomotive.Views.Shared.FormView
116
116
  @$('li#page_slug_input').show()
117
117
  @$('li#page_templatized_input, li#page_target_klass_name_input').hide()
118
118
  else
119
- @$('li#page_templatized_input, li#page_target_klass_name_input').show()
119
+ @$('li#page_templatized_input').show() unless @model.get('redirect')
120
120
 
121
121
  enable_response_type_select: ->
122
122
  @$('li#page_response_type_input').change (event) =>
@@ -5,10 +5,14 @@ class Locomotive.Views.Pages.EditView extends Locomotive.Views.Pages.FormView
5
5
  save: (event) ->
6
6
  event.stopPropagation() & event.preventDefault()
7
7
 
8
+ form = $(event.target).trigger('ajax:beforeSend')
9
+
8
10
  @clear_errors()
9
11
 
10
12
  @model.save {},
11
13
  success: (model, response, xhr) =>
14
+ form.trigger('ajax:complete')
15
+
12
16
  model._normalize()
13
17
 
14
18
  if model.get('template_changed') == true
@@ -17,9 +21,8 @@ class Locomotive.Views.Pages.EditView extends Locomotive.Views.Pages.FormView
17
21
  @refresh_editable_elements()
18
22
 
19
23
  error: (model, xhr) =>
24
+ form.trigger('ajax:complete')
25
+
20
26
  errors = JSON.parse(xhr.responseText)
21
27
 
22
28
  @show_errors errors
23
-
24
-
25
-
@@ -16,6 +16,9 @@ class Locomotive.Views.Shared.FormView extends Backbone.View
16
16
  # allow users to save with CTRL+S or CMD+s
17
17
  @enable_save_with_keys_combination()
18
18
 
19
+ # enable form notifications
20
+ @enable_form_notifications()
21
+
19
22
  return @
20
23
 
21
24
  save: (event) ->
@@ -24,6 +27,8 @@ class Locomotive.Views.Shared.FormView extends Backbone.View
24
27
  save_in_ajax: (event, options) ->
25
28
  event.stopPropagation() & event.preventDefault()
26
29
 
30
+ form = $(event.target).trigger('ajax:beforeSend')
31
+
27
32
  @clear_errors()
28
33
 
29
34
  options ||= { headers: {}, on_success: null, on_error: null }
@@ -33,11 +38,15 @@ class Locomotive.Views.Shared.FormView extends Backbone.View
33
38
  @model.save {},
34
39
  headers: options.headers
35
40
  success: (model, response, xhr) =>
41
+ form.trigger('ajax:complete')
42
+
36
43
  model.attributes = previous_attributes
37
44
 
38
45
  options.on_success(response, xhr) if options.on_success
39
46
 
40
47
  error: (model, xhr) =>
48
+ form.trigger('ajax:complete')
49
+
41
50
  errors = JSON.parse(xhr.responseText)
42
51
 
43
52
  @show_errors errors
@@ -72,7 +81,10 @@ class Locomotive.Views.Shared.FormView extends Backbone.View
72
81
  content.slideUp 100, -> parent.addClass('folded')
73
82
 
74
83
  enable_save_with_keys_combination: ->
75
- $.cmd 'S', (() => @$('form').trigger('submit')), [], ignoreCase: true
84
+ $.cmd 'S', (() => @$('form input[type=submit]').trigger('click')), [], ignoreCase: true
85
+
86
+ enable_form_notifications: ->
87
+ @$('form').formSubmitNotification()
76
88
 
77
89
  after_inputs_fold: ->
78
90
  # overide this method if necessary
@@ -7,7 +7,7 @@ class Locomotive.Views.ThemeAssets.IndexView extends Backbone.View
7
7
  _lists_views: []
8
8
 
9
9
  initialize: ->
10
- _.bindAll(@, 'add_asset')
10
+ _.bindAll(@, 'insert_asset')
11
11
 
12
12
  render: ->
13
13
  @build_uploader()
@@ -29,16 +29,24 @@ class Locomotive.Views.ThemeAssets.IndexView extends Backbone.View
29
29
  input = form.find('input[type=file]')
30
30
  link = form.find('a.new')
31
31
 
32
+ form.formSubmitNotification()
33
+
32
34
  link.bind 'click', (event) ->
33
35
  event.stopPropagation() & event.preventDefault()
34
36
  input.click()
35
37
 
36
38
  input.bind 'change', (event) =>
39
+ form.trigger('ajax:beforeSend')
37
40
  _.each event.target.files, (file) =>
38
41
  asset = new Locomotive.Models.ThemeAsset(source: file)
39
- asset.save {}, success: @add_asset, headers: { 'X-Flash': true }
40
-
41
- add_asset: (model) ->
42
+ asset.save {},
43
+ success: (model, response, xhr) =>
44
+ form.trigger('ajax:complete')
45
+ @insert_asset(model)
46
+ error: (() => form.trigger('ajax:complete'))
47
+ headers: { 'X-Flash': true }
48
+
49
+ insert_asset: (model) ->
42
50
  list_view = @pick_list_view(model.get('content_type'))
43
51
  list_view.collection.add(model)
44
52
 
@@ -314,6 +314,29 @@ ul.list {
314
314
  }
315
315
  }
316
316
 
317
+ /* ___ form notification ___ */
318
+
319
+ #form-submit-notification {
320
+ position: fixed;
321
+ top: 0px;
322
+ right: 0px;
323
+ z-index: 9999;
324
+
325
+ > div {
326
+ padding: 5px 10px;
327
+
328
+ background-color: #fffbe5;
329
+ border-left: 4px solid #efe4a5;
330
+ border-bottom: 4px solid #efe4a5;
331
+
332
+ text-align: center;
333
+ @include single-text-shadow(rgba(255, 255, 255, 1), 0px, 1px, 0px);
334
+ font-weight: bold;
335
+ font-size: 12px;
336
+ color: #aa9a79;
337
+ }
338
+ }
339
+
317
340
  /* ___ paragraph (for help for example) ___ */
318
341
 
319
342
  p span.code {
@@ -157,6 +157,10 @@ form.formtastic {
157
157
  &:hover {
158
158
  background-image: image-url("locomotive/list/icons/toggle.png");
159
159
  }
160
+ &.open {
161
+ @include rotate(180deg);
162
+ }
163
+ @include single-transition(transform, 0.5s);
160
164
  }
161
165
 
162
166
  &.drag {
@@ -291,6 +295,17 @@ form.formtastic {
291
295
  }
292
296
  } // li.string, li.password
293
297
 
298
+ &.text {
299
+
300
+ &.short textarea {
301
+ padding: 5px;
302
+ height: 28px;
303
+ width: 696px;
304
+ overflow-y: hidden;
305
+ }
306
+
307
+ } // li.text
308
+
294
309
  &.locale, &.locales {
295
310
  .list {
296
311
  margin-left: 150px;
@@ -176,7 +176,7 @@ body {
176
176
  }
177
177
  }
178
178
 
179
- input[type=submit] {
179
+ input[type=submit], button[type=submit] {
180
180
  @include light-button;
181
181
  }
182
182
 
@@ -4,7 +4,7 @@ module Locomotive
4
4
  default :from => Locomotive.config.mailer_sender
5
5
 
6
6
  def new_content_entry(account, entry)
7
- @account, @entry, @type = account, entry.to_presenter, entry.content_type
7
+ @account, @entry, @type = account, entry, entry.content_type
8
8
 
9
9
  subject = t('locomotive.notifications.new_content_entry.subject', :type => @type.name, :locale => account.locale)
10
10
 
@@ -146,7 +146,7 @@ module Locomotive
146
146
  return if !self.content_type.public_submission_enabled? || self.content_type.public_submission_accounts.blank?
147
147
 
148
148
  self.site.accounts.each do |account|
149
- next unless self.content_type.public_submission_accounts.include?(account._id)
149
+ next unless self.content_type.public_submission_accounts.map(&:to_s).include?(account._id.to_s)
150
150
 
151
151
  Locomotive::Notifications.new_content_entry(account, self).deliver
152
152
  end
@@ -10,8 +10,12 @@ module Locomotive
10
10
  ## fields ##
11
11
  field :locales, :type => 'RawArray', :default => []
12
12
 
13
+ ## validations ##
14
+ validate :can_not_remove_default_locale
15
+
13
16
  ## callbacks ##
14
- after_validation :add_default_locale
17
+ after_validation :add_default_locale
18
+ before_update :verify_localized_default_pages_integrity
15
19
 
16
20
  end
17
21
 
@@ -48,6 +52,10 @@ module Locomotive
48
52
  self.locales.first || Locomotive.config.site_locales.first
49
53
  end
50
54
 
55
+ def default_locale_was
56
+ self.locales_was.first || Locomotive.config.site_locales.first
57
+ end
58
+
51
59
  def locale_fallbacks(locale)
52
60
  [locale.to_s] + (locales - [locale.to_s])
53
61
  end
@@ -58,6 +66,29 @@ module Locomotive
58
66
  self.locales = [Locomotive.config.site_locales.first] if self.locales.blank?
59
67
  end
60
68
 
69
+ def can_not_remove_default_locale
70
+ if self.persisted? && !self.locales.include?(self.default_locale_was)
71
+ self.errors.add :locales, I18n.t(:default_locale_removed, :scope => [:errors, :messages, :site])
72
+ end
73
+ end
74
+
75
+ def verify_localized_default_pages_integrity
76
+ if self.persisted? && self.locales_changed?
77
+ self.pages.where(:"slug.#{self.default_locale_was}".in => %w(index 404), :depth => 0).each do |page|
78
+ modifications = { 'title' => {}, 'slug' => {} }
79
+
80
+ self.locales.each do |locale|
81
+ slug = page.attributes['slug'][self.default_locale_was]
82
+
83
+ modifications['slug'][locale] = slug
84
+ modifications['title'][locale] = page.attributes['title'][locale] || ::I18n.t("attributes.defaults.pages.#{slug}.title", :locale => locale)
85
+ end
86
+
87
+ page.collection.update({ :_id => page._id }, { '$set' => modifications })
88
+ end
89
+ end
90
+ end
91
+
61
92
  end
62
93
 
63
94
  end