locomotivecms_mounter 1.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/lib/locomotive/mounter/config.rb +21 -0
  2. data/lib/locomotive/mounter/engine_api.rb +40 -0
  3. data/lib/locomotive/mounter/exceptions.rb +38 -0
  4. data/lib/locomotive/mounter/extensions/compass.rb +36 -0
  5. data/lib/locomotive/mounter/extensions/httmultiparty.rb +22 -0
  6. data/lib/locomotive/mounter/extensions/tilt/css.rb +31 -0
  7. data/lib/locomotive/mounter/extensions/tilt/haml.rb +27 -0
  8. data/lib/locomotive/mounter/extensions/tilt/liquid.rb +23 -0
  9. data/lib/locomotive/mounter/extensions/tilt/template.rb +11 -0
  10. data/lib/locomotive/mounter/fields.rb +250 -0
  11. data/lib/locomotive/mounter/models/base.rb +41 -0
  12. data/lib/locomotive/mounter/models/content_asset.rb +84 -0
  13. data/lib/locomotive/mounter/models/content_entry.rb +290 -0
  14. data/lib/locomotive/mounter/models/content_field.rb +128 -0
  15. data/lib/locomotive/mounter/models/content_select_option.rb +29 -0
  16. data/lib/locomotive/mounter/models/content_type.rb +217 -0
  17. data/lib/locomotive/mounter/models/editable_element.rb +27 -0
  18. data/lib/locomotive/mounter/models/page.rb +377 -0
  19. data/lib/locomotive/mounter/models/site.rb +27 -0
  20. data/lib/locomotive/mounter/models/snippet.rb +55 -0
  21. data/lib/locomotive/mounter/models/theme_asset.rb +135 -0
  22. data/lib/locomotive/mounter/models/translation.rb +28 -0
  23. data/lib/locomotive/mounter/mounting_point.rb +49 -0
  24. data/lib/locomotive/mounter/reader/api/base.rb +49 -0
  25. data/lib/locomotive/mounter/reader/api/content_assets_reader.rb +40 -0
  26. data/lib/locomotive/mounter/reader/api/content_entries_reader.rb +141 -0
  27. data/lib/locomotive/mounter/reader/api/content_types_reader.rb +74 -0
  28. data/lib/locomotive/mounter/reader/api/pages_reader.rb +174 -0
  29. data/lib/locomotive/mounter/reader/api/site_reader.rb +37 -0
  30. data/lib/locomotive/mounter/reader/api/snippets_reader.rb +59 -0
  31. data/lib/locomotive/mounter/reader/api/theme_assets_reader.rb +42 -0
  32. data/lib/locomotive/mounter/reader/api/translations_reader.rb +28 -0
  33. data/lib/locomotive/mounter/reader/api.rb +49 -0
  34. data/lib/locomotive/mounter/reader/file_system/base.rb +65 -0
  35. data/lib/locomotive/mounter/reader/file_system/content_assets_reader.rb +88 -0
  36. data/lib/locomotive/mounter/reader/file_system/content_entries_reader.rb +101 -0
  37. data/lib/locomotive/mounter/reader/file_system/content_types_reader.rb +88 -0
  38. data/lib/locomotive/mounter/reader/file_system/pages_reader.rb +206 -0
  39. data/lib/locomotive/mounter/reader/file_system/site_reader.rb +24 -0
  40. data/lib/locomotive/mounter/reader/file_system/snippets_reader.rb +78 -0
  41. data/lib/locomotive/mounter/reader/file_system/theme_assets_reader.rb +78 -0
  42. data/lib/locomotive/mounter/reader/file_system/translations_reader.rb +36 -0
  43. data/lib/locomotive/mounter/reader/file_system.rb +42 -0
  44. data/lib/locomotive/mounter/reader/runner.rb +89 -0
  45. data/lib/locomotive/mounter/utils/hash.rb +31 -0
  46. data/lib/locomotive/mounter/utils/string.rb +17 -0
  47. data/lib/locomotive/mounter/utils/yaml.rb +125 -0
  48. data/lib/locomotive/mounter/version.rb +8 -0
  49. data/lib/locomotive/mounter/writer/api/base.rb +323 -0
  50. data/lib/locomotive/mounter/writer/api/content_assets_writer.rb +74 -0
  51. data/lib/locomotive/mounter/writer/api/content_entries_writer.rb +223 -0
  52. data/lib/locomotive/mounter/writer/api/content_types_writer.rb +151 -0
  53. data/lib/locomotive/mounter/writer/api/pages_writer.rb +225 -0
  54. data/lib/locomotive/mounter/writer/api/site_writer.rb +164 -0
  55. data/lib/locomotive/mounter/writer/api/snippets_writer.rb +111 -0
  56. data/lib/locomotive/mounter/writer/api/theme_assets_writer.rb +152 -0
  57. data/lib/locomotive/mounter/writer/api/translations_writer.rb +83 -0
  58. data/lib/locomotive/mounter/writer/api.rb +62 -0
  59. data/lib/locomotive/mounter/writer/file_system/base.rb +61 -0
  60. data/lib/locomotive/mounter/writer/file_system/content_assets_writer.rb +33 -0
  61. data/lib/locomotive/mounter/writer/file_system/content_entries_writer.rb +29 -0
  62. data/lib/locomotive/mounter/writer/file_system/content_types_writer.rb +27 -0
  63. data/lib/locomotive/mounter/writer/file_system/pages_writer.rb +73 -0
  64. data/lib/locomotive/mounter/writer/file_system/site_writer.rb +25 -0
  65. data/lib/locomotive/mounter/writer/file_system/snippets_writer.rb +54 -0
  66. data/lib/locomotive/mounter/writer/file_system/theme_assets_writer.rb +35 -0
  67. data/lib/locomotive/mounter/writer/file_system/translations_writer.rb +22 -0
  68. data/lib/locomotive/mounter/writer/file_system.rb +69 -0
  69. data/lib/locomotive/mounter/writer/runner.rb +68 -0
  70. data/lib/locomotive/mounter.rb +97 -0
  71. metadata +487 -0
@@ -0,0 +1,377 @@
1
+ # encoding: UTF-8
2
+ module Locomotive
3
+ module Mounter
4
+ module Models
5
+
6
+ class Page < Base
7
+
8
+ ## fields ##
9
+ field :parent, association: true
10
+ field :title, localized: true
11
+ field :slug, localized: true
12
+ field :fullpath, localized: true
13
+ field :redirect_url, localized: true
14
+ field :redirect_type, default: 301
15
+ field :template, localized: true
16
+ field :handle
17
+ field :listed
18
+ field :templatized
19
+ field :content_type
20
+ field :published, default: true
21
+ field :cache_strategy
22
+ field :response_type
23
+ field :position
24
+
25
+ field :seo_title, localized: true
26
+ field :meta_keywords, localized: true
27
+ field :meta_description, localized: true
28
+
29
+ field :editable_elements, type: :array, class_name: 'Locomotive::Mounter::Models::EditableElement'
30
+
31
+ ## other accessors ##
32
+ attr_accessor :content_type_id, :parent_id, :children
33
+
34
+ ## aliases ##
35
+ alias :listed? :listed
36
+ alias :published? :published
37
+ alias :templatized? :templatized
38
+
39
+ ## methods ##
40
+
41
+ # Tell if the page is either the index page.
42
+ #
43
+ # @return [ Boolean ] True if index page.
44
+ #
45
+ def index?
46
+ self.depth == 0 && 'index' == self.slug
47
+ end
48
+
49
+ # Tell if the page is either the index or the 404 page.
50
+ #
51
+ # @return [ Boolean ] True if index or 404 page.
52
+ #
53
+ def index_or_404?
54
+ self.depth == 0 && %w(index 404).include?(self.slug)
55
+ end
56
+
57
+ # Return the fullpath dasherized and with the "*" character
58
+ # for the slug of templatized page.
59
+ #
60
+ # @return [ String ] The safe full path or nil if the page is not translated in the current locale
61
+ #
62
+ def safe_fullpath
63
+ return nil unless self.translated_in?(Locomotive::Mounter.locale)
64
+
65
+ # puts "[safe_fullpath] page = #{self.slug.inspect} / #{self.fullpath.inspect} / #{self.parent.inspect}"
66
+
67
+ if self.index_or_404?
68
+ self.slug
69
+ else
70
+ base = self.parent.safe_fullpath
71
+ _slug = self.templatized? ? '*' : self.slug
72
+ (base == 'index' ? _slug : File.join(base, _slug)).dasherize
73
+ end
74
+ end
75
+
76
+ # Return the fullpath in the current locale. If it does not exist,
77
+ # return the one of the main locale.
78
+ #
79
+ # @return [ String ] A non-blank fullpath
80
+ #
81
+ def fullpath_or_default
82
+ self.fullpath || self.fullpath_translations[self.mounting_point.default_locale]
83
+ end
84
+
85
+ # Get the id of the parent page.
86
+ #
87
+ # @return [ String ] The _id attribute of the parent page
88
+ #
89
+ def parent_id
90
+ @parent_id || self.parent.try(:_id)
91
+ end
92
+
93
+ # Force the translations of a page
94
+ #
95
+ # @param [ Array ] locales List of locales (Symbol or String)
96
+ #
97
+ def translated_in=(locales)
98
+ self._locales = locales.map(&:to_sym)
99
+ end
100
+
101
+ # Modified setter in order to set correctly the slug
102
+ #
103
+ # @param [ String ] fullpath The fullpath
104
+ #
105
+ def fullpath_with_setting_slug=(fullpath)
106
+ if fullpath && self.slug.nil?
107
+ self.slug = File.basename(fullpath)
108
+ end
109
+
110
+ self.fullpath_without_setting_slug = fullpath
111
+ end
112
+
113
+ alias_method_chain :fullpath=, :setting_slug
114
+
115
+ # Depth of the page in the site tree.
116
+ # Both the index and 404 pages are 0-depth.
117
+ #
118
+ # @return [ Integer ] The depth
119
+ #
120
+ def depth
121
+ return 0 if %w(index 404).include?(self.fullpath)
122
+ self.fullpath_or_default.split('/').size
123
+ end
124
+
125
+ # Depth and position in the site tree
126
+ #
127
+ # @return [ Integer ] An unique id corresponding to the depth and position
128
+ #
129
+ def depth_and_position
130
+ self.depth * 100 + (self.position || 100)
131
+ end
132
+
133
+ # A layout is a page which the template does
134
+ # not include the extend keyword.
135
+ # If the template is blank then, it is not considered as a layout
136
+ #
137
+ # @return [ Boolean ] True if the template can be a layout.
138
+ #
139
+ def is_layout?
140
+ self.layout.nil?
141
+ end
142
+
143
+ # Return the fullpath of the page which is used
144
+ # as a layout for the current page.
145
+ #
146
+ # @return [ String ] The fullpath to the layout
147
+ #
148
+ def layout
149
+ return false if self.source.nil? || self.source.strip.blank?
150
+
151
+ self.source =~ /\{%\s*extends\s+\'?([[\w|\-|\_]|\/]+)\'?\s*%\}/
152
+ $1
153
+ end
154
+
155
+ # Is it a redirect page ?
156
+ #
157
+ # @return [ Boolean ] True if the redirect_url property is set
158
+ #
159
+ def redirect?
160
+ !self.redirect_url.blank?
161
+ end
162
+
163
+ # Add a child to the page. It also sets the parent of the child
164
+ #
165
+ # @param [ Object ] page The child page
166
+ #
167
+ # @return [ Object ] The child page
168
+ #
169
+ def add_child(page)
170
+ page.parent = self
171
+
172
+ (self.children ||= []) << page
173
+
174
+ self.children.sort! { |a, b| (a.position || 999) <=> (b.position || 999) }
175
+
176
+ page
177
+ end
178
+
179
+ # Build or update the list of editable elements from a hash whose
180
+ # keys are the couple "[block]/[slug]" and the values the content
181
+ # of the editable elements OR an array of attributes
182
+ #
183
+ # @param [ Hash / Array ] attributes The attributes of the editable elements
184
+ #
185
+ def set_editable_elements(attributes)
186
+ return if attributes.blank?
187
+
188
+ self.editable_elements ||= []
189
+
190
+ attributes.to_a.each do |_attributes|
191
+ if _attributes.is_a?(Array) # attributes is maybe a Hash
192
+ block, slug = _attributes.first.split('/')
193
+ block, slug = nil, block if slug.nil?
194
+ _attributes = { 'block' => block, 'slug' => slug, 'content' => _attributes.last }
195
+ end
196
+
197
+ # does an editable element exist with the same couple block/slug ?
198
+ if editable_element = self.find_editable_element(_attributes['block'], _attributes['slug'])
199
+ editable_element.content = _attributes['content']
200
+ else
201
+ self.editable_elements << Locomotive::Mounter::Models::EditableElement.new(_attributes)
202
+ end
203
+ end
204
+ end
205
+
206
+ # Find an editable element from its block and slug (the couple is unique)
207
+ #
208
+ # @param [ String ] block The name of the block
209
+ # @param [ String ] slug The slug of the element
210
+ #
211
+ # @return [ Object ] The editable element or nil if not found
212
+ #
213
+ def find_editable_element(block, slug)
214
+ (self.editable_elements || []).detect do |el|
215
+ el.block.to_s == block.to_s && el.slug.to_s == slug.to_s
216
+ end
217
+ end
218
+
219
+ # Localize the fullpath based on the parent fullpath in the locales
220
+ # passed in parameter.
221
+ #
222
+ # @param [ Array ] locales The list of locales the fullpath will be translated to. Can be nil (will use the locales returned by translated_in)
223
+ #
224
+ def localize_fullpath(locales = nil)
225
+ locales ||= self.translated_in
226
+ _parent_fullpath = self.parent.try(:fullpath)
227
+ _fullpath, _slug = self.fullpath.try(:clone), self.slug.clone
228
+
229
+ locales.each do |locale|
230
+ Locomotive::Mounter.with_locale(locale) do
231
+ if %w(index 404).include?(_slug) && (_fullpath.nil? || _fullpath == _slug)
232
+ self.fullpath = _slug
233
+ self.slug = _slug
234
+ elsif _parent_fullpath == 'index'
235
+ self.fullpath = self.slug || _slug
236
+ else
237
+ self.fullpath = File.join(parent.fullpath || _parent_fullpath, self.slug || _slug)
238
+ end
239
+ end
240
+ end
241
+ end
242
+
243
+ # Assign a default template for each locale which
244
+ # has an empty template. This default template
245
+ # is the one defined in the default locale.
246
+ #
247
+ # @param [ Symbol / String ] default_locale The default locale
248
+ #
249
+ def set_default_template_for_each_locale(default_locale)
250
+ default_template = self.template_translations[default_locale.to_sym]
251
+
252
+ return if default_template.nil? || default_template.data.strip.blank?
253
+
254
+ self.translated_in.each do |locale|
255
+ next if locale.to_s == default_locale.to_s
256
+
257
+ # current template
258
+ _template = self.template_translations[locale]
259
+
260
+ # is it blank ?
261
+ if _template.nil? || _template.data.strip.blank?
262
+ # puts "YOUPI #{self.fullpath} / #{locale} / #{default_template.data}"
263
+ self.template_translations[locale] = default_template
264
+ end
265
+ end
266
+ end
267
+
268
+ # Set the source of the page without any pre-rendering. Used by the API reader.
269
+ #
270
+ # @param [ String ] content The HTML raw template
271
+ #
272
+ def raw_template=(content)
273
+ @source ||= {}
274
+ @source[Locomotive::Mounter.locale] = content
275
+ end
276
+
277
+ # Return the Liquid template based on the raw_template property
278
+ # of the page. If the template is HAML or SLIM, then a pre-rendering to Liquid is done.
279
+ #
280
+ # @return [ String ] The liquid template or nil if not template has been provided
281
+ #
282
+ def source
283
+ @source ||= {}
284
+
285
+ if @source[Locomotive::Mounter.locale]
286
+ @source[Locomotive::Mounter.locale] # memoization
287
+ elsif self.template
288
+ source = self.template.need_for_prerendering? ? self.template.render : self.template.data
289
+ @source[Locomotive::Mounter.locale] = source
290
+ else
291
+ nil
292
+ end
293
+ end
294
+
295
+ # Return the YAML front matters of the page
296
+ #
297
+ # @return [ String ] The YAML version of the page
298
+ #
299
+ def to_yaml
300
+ fields = %w(title slug redirect_url redirect_type handle published listed cache_strategy response_type position)
301
+
302
+ _attributes = self.attributes.delete_if { |k, v| !fields.include?(k.to_s) || v.blank? }.deep_stringify_keys
303
+
304
+ _attributes['editable_elements'] = {}
305
+
306
+ # TODO: templatized / content_type
307
+
308
+ (self.editable_elements || []).each do |editable_element|
309
+ _attributes['editable_elements'].merge!(editable_element.to_yaml)
310
+ end
311
+
312
+ _attributes.delete('editable_elements') if _attributes['editable_elements'].empty?
313
+
314
+ _attributes.delete('slug') if self.depth == 0
315
+
316
+ "#{_attributes.to_yaml}---\n#{self.source}"
317
+ end
318
+
319
+ # Return the params used for the API
320
+ #
321
+ # @return [ Hash ] The params
322
+ #
323
+ def to_params
324
+ params = self.filter_attributes %w(title parent_id slug redirect_url redirect_type handle listed published cache_strategy response_type position templatized)
325
+
326
+ # slug
327
+ params.delete(:slug) if self.depth == 0
328
+
329
+ # redirect_url
330
+ params[:redirect] = true unless self.redirect_url.blank?
331
+
332
+ # parent_id
333
+ params[:parent_id] = self.parent_id unless self.parent_id.blank?
334
+
335
+ # content_type
336
+ params[:target_klass_slug] = self.content_type.slug if self.templatized && self.content_type
337
+
338
+ # editable_elements
339
+ params[:editable_elements] = (self.editable_elements || []).map(&:to_params)
340
+
341
+ # raw_template
342
+ params[:raw_template] = self.source rescue nil
343
+
344
+ params
345
+ end
346
+
347
+ # Return the params used for the API but without all the params.
348
+ # This can be explained by the fact that for instance the update should preserve
349
+ # the content.
350
+ #
351
+ # @return [ Hash ] The safe params
352
+ #
353
+ def to_safe_params
354
+ fields = %w(listed published handle cache_strategy redirect_url response_type templatized content_type_id position)
355
+
356
+ params = self.attributes.delete_if do |k, v|
357
+ !fields.include?(k.to_s) || (!v.is_a?(FalseClass) && v.blank?)
358
+ end.deep_symbolize_keys
359
+
360
+ # redirect_url
361
+ params[:redirect] = true unless self.redirect_url.blank?
362
+
363
+ # raw_template
364
+ params[:raw_template] = self.source rescue nil
365
+
366
+ params
367
+ end
368
+
369
+ def to_s
370
+ self.fullpath_or_default
371
+ end
372
+
373
+ end
374
+
375
+ end
376
+ end
377
+ end
@@ -0,0 +1,27 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Models
4
+
5
+ class Site < Base
6
+
7
+ ## fields ##
8
+ field :name
9
+ field :locales
10
+ field :subdomain
11
+ field :domains
12
+ field :seo_title, localized: true
13
+ field :meta_keywords, localized: true
14
+ field :meta_description, localized: true
15
+ field :robots_txt
16
+
17
+ ## methods ##
18
+
19
+ def to_s
20
+ self.name
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,55 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Models
4
+
5
+ class Snippet < Base
6
+
7
+ ## fields ##
8
+ field :name
9
+ field :slug
10
+
11
+ field :template, localized: true
12
+
13
+ ## methods ##
14
+
15
+ # Return the Liquid template based on the template_filepath property
16
+ # of the snippet. If the template is HAML or SLIM, then a pre-rendering to Liquid is done.
17
+ #
18
+ # @return [ String ] The liquid template
19
+ #
20
+ def source
21
+ @source ||= {}
22
+
23
+ source = if template.respond_to?(:need_for_prerendering?)
24
+ # must be a tilt template with or without prerendering
25
+ self.template.need_for_prerendering? ? self.template.render : self.template.data
26
+ else
27
+ # simple string
28
+ self.template
29
+ end
30
+
31
+ @source[Locomotive::Mounter.locale] = source
32
+ end
33
+
34
+ # Return the params used for the API.
35
+ #
36
+ # @return [ Hash ] The params
37
+ #
38
+ def to_params
39
+ params = self.filter_attributes %w(name slug)
40
+
41
+ # raw_template
42
+ params[:template] = self.source rescue nil
43
+
44
+ params
45
+ end
46
+
47
+ def to_s
48
+ self.name
49
+ end
50
+
51
+ end
52
+
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,135 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Models
4
+
5
+ class ThemeAsset < Base
6
+
7
+ PRECOMPILED_CSS_TYPES = %w(sass scss less)
8
+
9
+ PRECOMPILED_JS_TYPES = %w(coffee)
10
+
11
+ PRECOMPILED_FILE_TYPES = PRECOMPILED_CSS_TYPES + PRECOMPILED_JS_TYPES
12
+
13
+ ## fields ##
14
+ field :folder
15
+
16
+ ## other accessors ##
17
+ attr_accessor :filepath, :uri, :size
18
+
19
+ ## methods ##
20
+
21
+ # Name of the file without any precompiled extensions (.sass, .scss, ...etc)
22
+ #
23
+ # @return [ String ] Name of the file
24
+ #
25
+ def filename
26
+ return @filename if @filename
27
+
28
+ if self.uri
29
+ @filename = File.basename(self.uri.path)
30
+ else
31
+ regexps = PRECOMPILED_FILE_TYPES.map { |ext| "\.#{ext}" }.join('|')
32
+
33
+ @filename = File.basename(self.filepath).gsub(/#{regexps}/, '')
34
+ end
35
+ end
36
+
37
+ # Return the virtual path of the asset
38
+ #
39
+ # @return [ String ] The virtual path of the asset
40
+ #
41
+ def path
42
+ File.join(self.folder, self.filename)
43
+ end
44
+
45
+ # Return the mime type of the file based on the Mime::Types lib.
46
+ #
47
+ # @return [ String ] The mime type of the file or nil if unknown.
48
+ #
49
+ def mime_type
50
+ type = MIME::Types.type_for(self.filename)
51
+ type.empty? ? nil : type.first
52
+ end
53
+
54
+ # Is the asset a stylesheet ?
55
+ #
56
+ # @return [ Boolean ] True if the filename ends with .css
57
+ #
58
+ def stylesheet?
59
+ File.extname(self.filename) == '.css'
60
+ end
61
+
62
+ # Is the asset a javascript ?
63
+ #
64
+ # @return [ Boolean ] True if the filename ends with .js
65
+ #
66
+ def javascript?
67
+ File.extname(self.filename) == '.js'
68
+ end
69
+
70
+ def stylesheet_or_javascript?
71
+ self.stylesheet? || self.javascript?
72
+ end
73
+
74
+ # Give the priority of the asset depending of its type.
75
+ # Javascripts and stylesheets are low priority.
76
+ #
77
+ # @return [ Integer ] The priority (0 -> high, 100 -> lower)
78
+ #
79
+ def priority
80
+ self.stylesheet_or_javascript? ? 100 : 0
81
+ end
82
+
83
+ # Tell if the asset can be precompiled. For instance, less, sass, scss and
84
+ # coffeescript assets have to be precompiled.
85
+ #
86
+ # @return [ Boolean ] True if it has to be precompiled
87
+ #
88
+ def precompiled?
89
+ @extname ||= File.extname(self.filepath)[1..-1]
90
+ PRECOMPILED_FILE_TYPES.include?(@extname)
91
+ end
92
+
93
+ # Content of the asset. Pre-compile it if needed.
94
+ #
95
+ # @return [ String ] The content of the asset
96
+ #
97
+ def content
98
+ return @raw if @raw
99
+
100
+ if self.uri
101
+ @raw = Net::HTTP.get(self.uri)
102
+ elsif self.precompiled?
103
+ template = Tilt.new(self.filepath)
104
+ @raw = template.render
105
+ else
106
+ @raw = File.read(self.filepath)
107
+ end
108
+ end
109
+
110
+ # Get a fresh version of the content of the asset. Pre-compile it if needed.
111
+ #
112
+ # @return [ String ] The content of the asset
113
+ #
114
+ def content!
115
+ @raw = nil # force to reload it
116
+ self.content
117
+ end
118
+
119
+ # Return the params used for the API.
120
+ #
121
+ # @return [ Hash ] The params
122
+ #
123
+ def to_params
124
+ { folder: self.folder }
125
+ end
126
+
127
+ def to_s
128
+ self.path
129
+ end
130
+
131
+ end
132
+
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,28 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Models
4
+
5
+ class Translation < Base
6
+
7
+ ## fields ##
8
+ field :key
9
+ field :values
10
+
11
+ ## methods ##
12
+
13
+ def get(locale)
14
+ self.values[locale.to_s]
15
+ end
16
+
17
+ def to_params
18
+ { key: self.key, values: self.values }
19
+ end
20
+
21
+ def to_s
22
+ self.key
23
+ end
24
+
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,49 @@
1
+ module Locomotive
2
+ module Mounter
3
+
4
+ class MountingPoint
5
+
6
+ attr_accessor :resources, :root_page, :path
7
+
8
+ # Return all the locales defined by the site related to that mounting point.
9
+ #
10
+ # @return [ Array ] The list of the locales
11
+ #
12
+ def locales
13
+ self.site.locales || []
14
+ end
15
+
16
+ # Return the default locale which is the first locale defined for a site.
17
+ # If none, then use the current I18n locale.
18
+ #
19
+ # @return [ Symbol ] The default locale
20
+ #
21
+ def default_locale
22
+ (self.locales.first || Locomotive::Mounter.locale).to_sym
23
+ end
24
+
25
+ # Register a resource (site, pages, content types, ...etc) and its elements.
26
+ # It makes sure that all the elements get a pointer to that mounting point.
27
+ # The elements can be either an array, hash or even a single object (ex: site).
28
+ # For instance, for a page, it will be a hash whose key is the fullpath.
29
+ #
30
+ # @param [ Symbol ] name Name of the resource
31
+ # @param [ Object ] elements Element(s) related to the resource
32
+ #
33
+ def register_resource(name, elements)
34
+ self.resources ||= {}
35
+
36
+ (elements.respond_to?(:values) ? elements.values : [*elements]).each do |element|
37
+ element.mounting_point = self
38
+ end
39
+
40
+ self.resources[name.to_sym] = elements
41
+ end
42
+
43
+ def method_missing(name, *args, &block)
44
+ (self.resources || {})[name.to_sym] || super
45
+ end
46
+
47
+ end
48
+ end
49
+ end