locomotivecms 3.0.0.pre.beta.1 → 3.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (175) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -3
  3. data/app/api/locomotive/api.rb +1 -0
  4. data/app/api/locomotive/api/entities/page_entity.rb +1 -1
  5. data/app/api/locomotive/api/entities/site_entity.rb +9 -1
  6. data/app/api/locomotive/api/exception_rescuers.rb +3 -5
  7. data/app/api/locomotive/api/forms/page_form.rb +1 -1
  8. data/app/api/locomotive/api/forms/site_form.rb +1 -2
  9. data/app/api/locomotive/api/helpers/authentication_helper.rb +6 -1
  10. data/app/api/locomotive/api/helpers/locales_helper.rb +15 -0
  11. data/app/api/locomotive/api/helpers/params_helper.rb +13 -0
  12. data/app/api/locomotive/api/middlewares/locale_middleware.rb +6 -1
  13. data/app/api/locomotive/api/resources/content_entry_resource.rb +2 -0
  14. data/app/api/locomotive/api/resources/content_type_resource.rb +2 -2
  15. data/app/api/locomotive/api/resources/current_site_resource.rb +2 -1
  16. data/app/api/locomotive/api/resources/membership_resource.rb +0 -4
  17. data/app/api/locomotive/api/resources/page_resource.rb +6 -1
  18. data/app/api/locomotive/api/resources/site_resource.rb +4 -2
  19. data/app/assets/javascripts/locomotive.js +1 -0
  20. data/app/assets/javascripts/locomotive/utils/nprogress.js.coffee +3 -1
  21. data/app/assets/javascripts/locomotive/views/editable_elements/index_view.js.coffee +10 -3
  22. data/app/assets/javascripts/locomotive/views/inputs/markdown_view.js.coffee +82 -0
  23. data/app/assets/javascripts/locomotive/views/inputs/rte/file_view.js.coffee +1 -1
  24. data/app/assets/javascripts/locomotive/views/inputs/rte/link_view.js.coffee +1 -1
  25. data/app/assets/javascripts/locomotive/views/inputs/rte_view.js.coffee.erb +1 -1
  26. data/app/assets/javascripts/locomotive/views/inputs/text_view.js.coffee +4 -1
  27. data/app/assets/javascripts/locomotive/views/pages/list_view.js.coffee +3 -0
  28. data/app/assets/javascripts/locomotive/views/shared/form_view.js.coffee +22 -1
  29. data/app/assets/javascripts/locomotive/views/shared/header_view.js.coffee +2 -2
  30. data/app/assets/stylesheets/locomotive/application.scss +2 -0
  31. data/app/assets/stylesheets/locomotive/base/_form.scss +2 -0
  32. data/app/assets/stylesheets/locomotive/base/form/_api_key.scss +0 -1
  33. data/app/assets/stylesheets/locomotive/base/form/_array_input.scss +2 -0
  34. data/app/assets/stylesheets/locomotive/base/form/_base.scss +13 -2
  35. data/app/assets/stylesheets/locomotive/base/form/_color_input.scss +12 -0
  36. data/app/assets/stylesheets/locomotive/base/form/_markdown.scss +292 -0
  37. data/app/assets/stylesheets/locomotive/base/form/_popover.scss +22 -0
  38. data/app/assets/stylesheets/locomotive/base/form/_rte.scss +2 -1
  39. data/app/assets/stylesheets/locomotive/components/_activity_feed.scss +1 -0
  40. data/app/assets/stylesheets/locomotive/components/_dashboard.scss +29 -0
  41. data/app/assets/stylesheets/locomotive/components/_live_editing.scss +13 -1
  42. data/app/assets/stylesheets/locomotive/components/_main.scss +1 -1
  43. data/app/assets/stylesheets/locomotive/components/_transitions.scss +24 -3
  44. data/app/assets/stylesheets/locomotive/components/sidebar/_base.scss +1 -0
  45. data/app/assets/stylesheets/locomotive/globals/_bootstrap.scss +2 -2
  46. data/app/assets/stylesheets/locomotive/globals/_variables.scss +4 -3
  47. data/app/assets/stylesheets/locomotive/layouts/_live_editing.scss +4 -0
  48. data/app/controllers/locomotive/concerns/locale_helpers_controller.rb +1 -0
  49. data/app/controllers/locomotive/content_entries_controller.rb +10 -2
  50. data/app/controllers/locomotive/pages_controller.rb +2 -1
  51. data/app/controllers/locomotive/passwords_controller.rb +17 -1
  52. data/app/helpers/locomotive/base_helper.rb +19 -0
  53. data/app/helpers/locomotive/content_types_helper.rb +2 -1
  54. data/app/helpers/locomotive/custom_fields_helper.rb +14 -1
  55. data/app/helpers/locomotive/dashboard_helper.rb +12 -0
  56. data/app/helpers/locomotive/editable_elements_helper.rb +9 -4
  57. data/app/helpers/locomotive/pages_helper.rb +1 -14
  58. data/app/helpers/locomotive/shared/pages_helper.rb +17 -0
  59. data/app/helpers/locomotive/translations_helper.rb +0 -14
  60. data/app/inputs/locomotive/color_input.rb +18 -0
  61. data/app/inputs/locomotive/markdown_input.rb +19 -0
  62. data/app/models/locomotive/account.rb +2 -1
  63. data/app/models/locomotive/concerns/content_entry/file_size.rb +27 -0
  64. data/app/models/locomotive/concerns/content_type/group_by.rb +3 -1
  65. data/app/models/locomotive/concerns/page/layout.rb +63 -19
  66. data/app/models/locomotive/concerns/shared/site_scope.rb +37 -0
  67. data/app/models/locomotive/concerns/site/cache.rb +32 -0
  68. data/app/models/locomotive/concerns/theme_asset/plain_text.rb +85 -0
  69. data/app/models/locomotive/content_entry.rb +7 -7
  70. data/app/models/locomotive/content_type.rb +12 -6
  71. data/app/models/locomotive/page.rb +12 -14
  72. data/app/models/locomotive/site.rb +9 -3
  73. data/app/models/locomotive/snippet.rb +6 -4
  74. data/app/models/locomotive/theme_asset.rb +8 -73
  75. data/app/models/locomotive/translation.rb +6 -5
  76. data/app/policies/locomotive/site_policy.rb +2 -2
  77. data/app/services/locomotive/content_entry_service.rb +7 -6
  78. data/app/services/locomotive/site_service.rb +1 -0
  79. data/app/views/locomotive/content_entries/_entry.html.slim +1 -0
  80. data/app/views/locomotive/content_entries/edit.html.slim +1 -1
  81. data/app/views/locomotive/content_entries/new.html.slim +1 -1
  82. data/app/views/locomotive/current_site/_membership.html.slim +1 -0
  83. data/app/views/locomotive/current_site/edit.html.slim +1 -1
  84. data/app/views/locomotive/current_site/form/_access_points.html.slim +1 -1
  85. data/app/views/locomotive/current_site/form/_advanced.html.slim +2 -0
  86. data/app/views/locomotive/dashboard/_activity.html.slim +26 -0
  87. data/app/views/locomotive/dashboard/_url.html.slim +9 -0
  88. data/app/views/locomotive/dashboard/show.html.slim +3 -21
  89. data/app/views/locomotive/devise_mailer/reset_password_instructions.html.slim +1 -1
  90. data/app/views/locomotive/editable_elements/_edit.html.slim +8 -1
  91. data/app/views/locomotive/editable_elements/_form.html.slim +1 -1
  92. data/app/views/locomotive/editable_elements/index_without_preview.html.slim +24 -17
  93. data/app/views/locomotive/layouts/application.html.slim +6 -4
  94. data/app/views/locomotive/layouts/live_editing.html.slim +9 -0
  95. data/app/views/locomotive/layouts/not_logged_in.html.slim +1 -1
  96. data/app/views/locomotive/layouts/without_site.html.slim +2 -0
  97. data/app/views/locomotive/memberships/edit.html.slim +1 -1
  98. data/app/views/locomotive/memberships/new.html.slim +1 -1
  99. data/app/views/locomotive/my_account/edit.html.slim +7 -5
  100. data/app/views/locomotive/pages/_header.html.slim +7 -0
  101. data/app/views/locomotive/pages/edit.html.slim +2 -4
  102. data/app/views/locomotive/pages/form/_main.html.slim +4 -1
  103. data/app/views/locomotive/pages/form/_tabs.html.slim +4 -3
  104. data/app/views/locomotive/public_submission_accounts/_account.html.slim +1 -1
  105. data/app/views/locomotive/public_submission_accounts/edit.html.slim +1 -1
  106. data/app/views/locomotive/shared/_header.html.slim +25 -22
  107. data/app/views/locomotive/shared/_locale_picker_link.html.slim +3 -0
  108. data/app/views/locomotive/shared/_main_app_header.html.slim +1 -1
  109. data/app/views/locomotive/shared/_sidebar.html.slim +15 -11
  110. data/app/views/locomotive/shared/rte/_markdown_toolbar.html.slim +42 -0
  111. data/config/locales/admin_ui.en.yml +9 -4
  112. data/config/locales/default.en.yml +4 -0
  113. data/config/locales/devise.en.yml +1 -0
  114. data/config/locales/simple_form.en.yml +6 -2
  115. data/lib/locomotive/action_controller/responder.rb +5 -0
  116. data/lib/locomotive/engine.rb +5 -0
  117. data/lib/locomotive/middlewares/site.rb +39 -21
  118. data/lib/locomotive/simple_form.rb +3 -31
  119. data/lib/locomotive/steam/middlewares/cache.rb +62 -0
  120. data/lib/locomotive/steam/middlewares/page_editing.rb +9 -3
  121. data/lib/locomotive/steam/services/api_entry_submission_service.rb +6 -3
  122. data/lib/locomotive/steam/services/liquid_parser_with_cache_service.rb +74 -0
  123. data/lib/locomotive/steam_adaptor.rb +7 -1
  124. data/lib/locomotive/version.rb +1 -1
  125. data/lib/tasks/development.rake +4 -0
  126. data/lib/tasks/locomotive.rake +14 -0
  127. data/spec/lib/locomotive/steam/services/api_entry_submission_service_spec.rb +10 -1
  128. data/spec/lib/locomotive/steam/services/liquid_parser_with_cache_service_spec.rb +53 -0
  129. data/spec/models/locomotive/concerns/content_entry/file_size_spec.rb +40 -0
  130. data/spec/models/locomotive/concerns/page/layout_spec.rb +122 -17
  131. data/spec/models/locomotive/concerns/site/cache_spec.rb +60 -0
  132. data/spec/models/locomotive/content_entry_spec.rb +7 -0
  133. data/spec/models/locomotive/content_type_spec.rb +18 -11
  134. data/spec/models/locomotive/page_spec.rb +32 -8
  135. data/spec/models/locomotive/snippet_spec.rb +13 -4
  136. data/spec/models/locomotive/theme_asset_spec.rb +10 -3
  137. data/spec/models/locomotive/translation_spec.rb +28 -0
  138. data/spec/requests/locomotive/steam/cache_spec.rb +83 -0
  139. data/spec/requests/site_spec.rb +24 -0
  140. data/spec/support/capybara.rb +5 -13
  141. data/spec/support/factories.rb +9 -0
  142. data/spec/support/features/session_helpers.rb +19 -3
  143. data/spec/support/features/site_helpers.rb +27 -0
  144. data/spec/support/shared_examples/site_scope_examples.rb +27 -0
  145. data/vendor/assets/images/locomotive/bootstrap-colorpicker/alpha-horizontal.png +0 -0
  146. data/vendor/assets/images/locomotive/bootstrap-colorpicker/alpha.png +0 -0
  147. data/vendor/assets/images/locomotive/bootstrap-colorpicker/hue-horizontal.png +0 -0
  148. data/vendor/assets/images/locomotive/bootstrap-colorpicker/hue.png +0 -0
  149. data/vendor/assets/images/locomotive/bootstrap-colorpicker/saturation.png +0 -0
  150. data/vendor/assets/javascripts/locomotive/bootstrap-colorpicker.js +1 -0
  151. data/vendor/assets/javascripts/locomotive/datepicker_i18n.js.erb +6 -6
  152. data/vendor/assets/javascripts/locomotive/kramed.min.js +11 -0
  153. data/vendor/assets/stylesheets/locomotive/bootstrap-colorpicker.scss +9 -0
  154. metadata +59 -44
  155. data/app/controllers/locomotive/api/accounts_controller.rb +0 -60
  156. data/app/controllers/locomotive/api/base_controller.rb +0 -35
  157. data/app/controllers/locomotive/api/content_assets_controller.rb +0 -51
  158. data/app/controllers/locomotive/api/content_entries_controller.rb +0 -71
  159. data/app/controllers/locomotive/api/content_types_controller.rb +0 -52
  160. data/app/controllers/locomotive/api/current_site_controller.rb +0 -34
  161. data/app/controllers/locomotive/api/memberships_controller.rb +0 -52
  162. data/app/controllers/locomotive/api/my_account_controller.rb +0 -46
  163. data/app/controllers/locomotive/api/pages_controller.rb +0 -53
  164. data/app/controllers/locomotive/api/sites_controller.rb +0 -58
  165. data/app/controllers/locomotive/api/snippets_controller.rb +0 -52
  166. data/app/controllers/locomotive/api/theme_assets_controller.rb +0 -51
  167. data/app/controllers/locomotive/api/tokens_controller.rb +0 -36
  168. data/app/controllers/locomotive/api/translations_controller.rb +0 -51
  169. data/app/controllers/locomotive/api/version_controller.rb +0 -11
  170. data/spec/models/locomotive/editable_control_spec.rb +0 -79
  171. data/spec/models/locomotive/editable_file_spec.rb +0 -94
  172. data/spec/models/locomotive/editable_text_spec.rb +0 -219
  173. data/vendor/assets/images/select2-spinner.gif +0 -0
  174. data/vendor/assets/images/select2.png +0 -0
  175. data/vendor/assets/images/select2x2.png +0 -0
@@ -2,6 +2,23 @@ module Locomotive
2
2
  module Shared
3
3
  module PagesHelper
4
4
 
5
+ def preview_page_path(page)
6
+ _path = params[:preview_path] || current_site.localized_page_fullpath(page, current_content_locale)
7
+ _path = 'index' if _path.blank?
8
+
9
+ _path += response_type_name(page)
10
+
11
+ truncate('/' + _path, length: 50)
12
+ end
13
+
14
+ def response_type_name(page)
15
+ if page.default_response_type?
16
+ ''
17
+ else
18
+ '.' + (MIME::Types[page.response_type.to_s].first.try(:preferred_extension) || 'html')
19
+ end
20
+ end
21
+
5
22
  def render_pages
6
23
  tree = build_page_tree
7
24
  nodes = tree.map { |page, children| Node.new(page, children, controller) }
@@ -9,19 +9,5 @@ module Locomotive
9
9
  end) + '-done'
10
10
  end
11
11
 
12
- # def untranslated_locales(site, translation)
13
- # list = site.locales.inject([]) do |memo,locale|
14
- # translation.values[locale].present? ? memo : memo << I18n.t("locomotive.locales.#{locale}")
15
- # end
16
-
17
- # if list.empty?
18
- # ''
19
- # else
20
- # haml_tag :span, class: 'untranslated' do
21
- # haml_tag :em, I18n.t('locomotive.translations.untranslated', list: list.to_sentence)
22
- # end
23
- # end
24
- # end
25
-
26
12
  end
27
13
  end
@@ -0,0 +1,18 @@
1
+ module Locomotive
2
+ class ColorInput < ::SimpleForm::Inputs::StringInput
3
+
4
+ def input(wrapper_options)
5
+ <<-HTML
6
+ <div class="input-group">
7
+ #{super}
8
+ <span class="input-group-addon"><i></i></span>
9
+ </div>
10
+ HTML
11
+ end
12
+
13
+ def html5?
14
+ false
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ module Locomotive
2
+ class MarkdownInput < Locomotive::RteInput
3
+
4
+ def input(wrapper_options)
5
+ input_html_options[:class] << 'form-control'
6
+ toolbar_html + @builder.text_area(attribute_name, input_html_options)
7
+ end
8
+
9
+ def toolbar_html
10
+ template.render(
11
+ partial: 'locomotive/shared/rte/markdown_toolbar',
12
+ locals: {
13
+ wysihtml5_prefix: wysihtml5_prefix,
14
+ image_popover: image_popover,
15
+ })
16
+ end
17
+
18
+ end
19
+ end
@@ -32,9 +32,10 @@ module Locomotive
32
32
  validates_presence_of :name
33
33
 
34
34
  ## associations ##
35
+ has_many :created_sites, class_name: 'Locomotive::Site', validate: false, autosave: false
35
36
 
36
37
  ## callbacks ##
37
- before_destroy :remove_memberships!
38
+ before_destroy :remove_memberships!
38
39
 
39
40
  ## scopes ##
40
41
  scope :ordered, -> { order_by(name: :asc) }
@@ -0,0 +1,27 @@
1
+ module Locomotive
2
+ module Concerns
3
+ module ContentEntry
4
+ module FileSize
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+
10
+ ## fields ##
11
+ field :_file_size, type: Integer, default: 0
12
+
13
+ ## callbacks ##
14
+ before_save :sync_file_size
15
+
16
+ end
17
+
18
+ private
19
+
20
+ def sync_file_size
21
+ self._file_size = self.file_custom_fields.inject(0) { |sum,field| send(field).size + sum }
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -22,7 +22,9 @@ module Locomotive
22
22
  target = self.class_name_to_content_type(field.class_name)
23
23
  label = target.label_field_name.to_sym
24
24
 
25
- target.ordered_entries.only(:_id, label).map do |entry|
25
+ # FIXME: applying "only" with _id and label sounds like a good option for performance
26
+ # but it fails because of Mongoid and its way of dealing with localized attributes.
27
+ target.ordered_entries.map do |entry|
26
28
  { _id: entry._id, name: entry.send(label) }
27
29
  end
28
30
  end
@@ -5,6 +5,13 @@ module Locomotive
5
5
 
6
6
  extend ActiveSupport::Concern
7
7
 
8
+ IS_LAYOUT_REGEX = /^layouts($|\/)/o.freeze
9
+ EXTENDS_REGEX = /\{%\s+extends\s/o.freeze
10
+ EXTENDS_PARENT_REGEX = /\{%\s+extends\s"?parent"?\s%}/o.freeze
11
+ EXTENDS_FULLPATH_REGEX = /\{%\s+extends\s"?(\S+)"?\s%}/o.freeze
12
+ BLOCK_REGEX = /\{%\s+block\s/o.freeze
13
+
14
+
8
15
  included do
9
16
 
10
17
  ## fields ##
@@ -16,7 +23,12 @@ module Locomotive
16
23
  has_many :layout_children, class_name: 'Locomotive::Page', inverse_of: :layout
17
24
 
18
25
  ## callbacks ##
19
- before_validation :set_default_raw_template
26
+ before_validation :valid_allow_layout_consistency
27
+ before_validation :set_raw_template_on_create, if: :new_record?
28
+ before_validation :set_raw_template_on_update, unless: :new_record?
29
+
30
+ ## validations ##
31
+ validate :index_can_not_extend_parent
20
32
 
21
33
  ## scopes ##
22
34
  scope :layouts, -> { where(is_layout: true) }
@@ -24,34 +36,66 @@ module Locomotive
24
36
  end
25
37
 
26
38
  def is_layout_or_related?
27
- !(self.fullpath =~ /^layouts($|\/)/).nil?
39
+ !(self.fullpath =~ IS_LAYOUT_REGEX).nil?
28
40
  end
29
41
 
30
- private
42
+ # The layout is also defined in the raw_template. The UI
43
+ # needs it in order to select the layout in the layouts dropdown menu
44
+ def find_layout
45
+ return if !self.allow_layout? || self.layout_id
31
46
 
32
- def set_default_raw_template
33
- if self.allow_layout?
34
- set_default_raw_template_if_layout
35
- else
36
- set_default_raw_template_if_no_layout
47
+ if self.raw_template =~ EXTENDS_FULLPATH_REGEX
48
+ # first in the current locale
49
+ if (page = self.site.pages.fullpath($1).first).nil? && !self.site.is_default_locale?(::Mongoid::Fields::I18n.locale)
50
+ # give it a try in the default locale too
51
+ page = self.site.with_default_locale { self.site.pages.fullpath($1).first }
52
+ end
53
+
54
+ self.layout_id = page.try(:_id)
37
55
  end
38
56
  end
39
57
 
40
- def set_default_raw_template_if_layout
41
- if self.layout
42
- self.raw_template = %({% extends "#{self.layout.fullpath}" %})
43
- elsif self.layout_id == 'parent'
44
- self.raw_template = "{% extends 'parent' %}"
58
+ private
59
+
60
+ # Even if the allow_layout attribute is true in a first time, we need
61
+ # to make sure the the raw_template includes only the "extends" liquid tag
62
+ # without any other code.
63
+ def valid_allow_layout_consistency
64
+ if allow_layout && raw_template.present? && raw_template =~ EXTENDS_REGEX
65
+ self.allow_layout = (raw_template =~ BLOCK_REGEX).nil?
45
66
  end
67
+ true
46
68
  end
47
69
 
48
- def set_default_raw_template_if_no_layout
49
- return true if self.raw_template.present?
70
+ def set_raw_template_on_create
71
+ set_raw_template
72
+ true
73
+ end
74
+
75
+ def set_raw_template_on_update
76
+ set_raw_template if allow_layout? && layout_id_changed?
77
+ true
78
+ end
79
+
80
+ def set_raw_template
81
+ return unless site
82
+
83
+ site.with_default_locale do
84
+ if layout_id == 'parent'
85
+ self.raw_template = '{% extends parent %}'
86
+ elsif layout
87
+ self.raw_template = %({% extends "#{self.layout.fullpath}" %})
88
+ elsif raw_template.blank? && !index?
89
+ self.raw_template = '{% extends parent %}'
90
+ end
91
+ end
92
+ # needed it by Steam to get the template from the default locale
93
+ site.each_locale(false) { self.raw_template = '' }
94
+ end
50
95
 
51
- self.raw_template = if self.index? || !self.site.is_default_locale?(::Mongoid::Fields::I18n.locale)
52
- '' # need it by Steam to get the template in the default locale
53
- else
54
- "{% extends 'parent' %}"
96
+ def index_can_not_extend_parent
97
+ if index? && raw_template =~ EXTENDS_PARENT_REGEX
98
+ self.errors.add(:layout_id, :index_can_not_extend_parent)
55
99
  end
56
100
  end
57
101
 
@@ -0,0 +1,37 @@
1
+ module Locomotive
2
+ module Concerns
3
+ module Shared
4
+ module SiteScope
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+
10
+ ## associations ##
11
+ belongs_to :site, class_name: 'Locomotive::Site', validate: false, autosave: false, touch: :true
12
+
13
+ ## validations ##
14
+ validates_presence_of :site
15
+
16
+ ## indexes ##
17
+ index site_id: 1
18
+
19
+ # Redefine the auto-generated method by the Mongoid Touchable module
20
+ # in order to touch another field of the site object.
21
+ def touch_site_after_create_or_destroy
22
+ without_autobuild do
23
+ _site = __send__(:site)
24
+ _site.touch(touch_site_attribute) if _site
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ def touch_site_attribute
31
+ nil
32
+ end
33
+
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,32 @@
1
+ module Locomotive
2
+ module Concerns
3
+ module Site
4
+ module Cache
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+
10
+ ## fields ##
11
+ field :cache_enabled, type: Boolean, default: false
12
+ field :template_version, type: DateTime
13
+ field :content_version, type: DateTime
14
+
15
+ ## callbacks ##
16
+ before_save :touch_content_version
17
+
18
+ def touch_content_version
19
+ touch(:content_version)
20
+ true
21
+ end
22
+
23
+ end
24
+
25
+ def last_modified_at
26
+ [self.content_version, self.template_version].compact.sort.last || self.updated_at
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,85 @@
1
+ module Locomotive
2
+ module Concerns
3
+ module ThemeAsset
4
+ module PlainText
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+
10
+ ## validations ##
11
+ validates_presence_of :plain_text_name, if: Proc.new { |a| a.performing_plain_text? }
12
+
13
+ ## callbacks ##
14
+ before_validation :store_plain_text
15
+
16
+ ## accessors ##
17
+ attr_accessor :plain_text_name, :plain_text, :plain_text_type, :performing_plain_text
18
+
19
+ end
20
+
21
+ def plain_text_name
22
+ if not @plain_text_name_changed
23
+ @plain_text_name ||= self.safe_source_filename
24
+ end
25
+ @plain_text_name.gsub(/(\.[a-z0-9A-Z]+)$/, '') rescue nil
26
+ end
27
+
28
+ def plain_text_name=(name)
29
+ @plain_text_name_changed = true
30
+ @plain_text_name = name
31
+ end
32
+
33
+ def plain_text
34
+ # only for ruby >= 1.9.x. Forget about ruby 1.8
35
+ @plain_text ||= (self.source.read.force_encoding('UTF-8') rescue nil)
36
+ end
37
+
38
+ def plain_text_type
39
+ @plain_text_type || (stylesheet_or_javascript? ? self.content_type : nil)
40
+ end
41
+
42
+ def performing_plain_text?
43
+ Boolean.set(self.performing_plain_text) || false
44
+ end
45
+
46
+ def store_plain_text
47
+ return if self.persisted? && !self.stylesheet_or_javascript?
48
+
49
+ self.content_type ||= @plain_text_type if self.performing_plain_text?
50
+
51
+ data = self.performing_plain_text? ? self.plain_text : self.source.read
52
+
53
+ return if !self.stylesheet_or_javascript? || self.plain_text_name.blank? || data.blank?
54
+
55
+ sanitized_source = self.escape_shortcut_urls(data)
56
+
57
+ self.source = ::CarrierWave::SanitizedFile.new({
58
+ tempfile: StringIO.new(sanitized_source),
59
+ filename: "#{self.plain_text_name}.#{self.stylesheet? ? 'css' : 'js'}"
60
+ })
61
+
62
+ @plain_text = sanitized_source # no need to reset the plain_text instance variable to have the last version
63
+ end
64
+
65
+ def escape_shortcut_urls(text)
66
+ return if text.blank?
67
+
68
+ text.gsub(/[("'](\/(stylesheets|javascripts|images|media|fonts|pdfs|others)\/(([^;.]+)\/)*([a-zA-Z_\-0-9]+)\.[a-z]{2,4})(\?[0-9]+)?[)"']/) do |path|
69
+
70
+ sanitized_path = path.gsub(/[("')]/, '').gsub(/^\//, '').gsub(/\?[0-9]+$/, '')
71
+
72
+ if asset = self.site.theme_assets.where(local_path: sanitized_path).first
73
+ timestamp = self.updated_at.to_i
74
+ "#{path.first}#{asset.source.url}?#{timestamp}#{path.last}"
75
+ else
76
+ path
77
+ end
78
+ end
79
+ end
80
+
81
+ end
82
+ end
83
+ end
84
+ end
85
+
@@ -5,12 +5,14 @@ module Locomotive
5
5
 
6
6
  ## extensions ##
7
7
  include ::CustomFields::Target
8
+ include Concerns::Shared::SiteScope
8
9
  include Concerns::Shared::Seo
9
10
  include Concerns::Shared::Userstamp
10
11
  include Concerns::ContentEntry::Slug
11
12
  include Concerns::ContentEntry::Csv
12
13
  include Concerns::ContentEntry::Localized
13
14
  include Concerns::ContentEntry::Counter
15
+ include Concerns::ContentEntry::FileSize
14
16
  include Concerns::ContentEntry::NextPrevious
15
17
 
16
18
  ## fields ##
@@ -23,11 +25,10 @@ module Locomotive
23
25
  validates_uniqueness_of :_slug, scope: :content_type_id, allow_blank: true
24
26
 
25
27
  ## associations ##
26
- belongs_to :site, class_name: 'Locomotive::Site', validate: false, autosave: false
27
28
  belongs_to :content_type, class_name: 'Locomotive::ContentType', inverse_of: :entries, custom_fields_parent_klass: true
28
29
 
29
30
  ## callbacks ##
30
- before_save :set_site
31
+ before_validation :set_site
31
32
  before_save :set_visibility
32
33
  before_create :add_to_list_bottom
33
34
 
@@ -40,8 +41,8 @@ module Locomotive
40
41
  scope :by_ids_or_slugs, ->(ids_or_slugs) { all.any_of({ :_slug.in => [*ids_or_slugs] }, { :_id.in => [*ids_or_slugs] }) }
41
42
 
42
43
  ## indexes ##
43
- index site_id: 1
44
44
  index _type: 1
45
+ index site_id: 1, updated_at: 1
45
46
  index content_type_id: 1
46
47
  Locomotive.config.site_locales.each do |locale|
47
48
  index _type: 1, "_slug.#{locale}" => 1
@@ -117,11 +118,10 @@ module Locomotive
117
118
 
118
119
  def to_liquid(type = nil)
119
120
  (type || self.content_type).to_steam_entry(self).to_liquid
121
+ end
120
122
 
121
- # repositories = Locomotive::Steam::Services.build_instance.repositories
122
- # _content_type = repositories.content_type.build(content_type.attributes.symbolize_keys)
123
-
124
- # repositories.content_entry.with(_content_type).build(self.attributes.symbolize_keys).to_liquid
123
+ def touch_site_attribute
124
+ :content_version
125
125
  end
126
126
 
127
127
  protected