locomotivecms_mounter_pull_19 1.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +4 -0
  5. data/Gemfile +7 -0
  6. data/Gemfile.lock +131 -0
  7. data/MIT-LICENSE +20 -0
  8. data/NOTES +4 -0
  9. data/README.md +26 -0
  10. data/Rakefile +37 -0
  11. data/TODO +82 -0
  12. data/init.rb +2 -0
  13. data/lib/locomotive/mounter.rb +106 -0
  14. data/lib/locomotive/mounter/config.rb +21 -0
  15. data/lib/locomotive/mounter/engine_api.rb +205 -0
  16. data/lib/locomotive/mounter/exceptions.rb +44 -0
  17. data/lib/locomotive/mounter/extensions/compass.rb +38 -0
  18. data/lib/locomotive/mounter/extensions/httmultiparty.rb +22 -0
  19. data/lib/locomotive/mounter/extensions/sprockets.rb +46 -0
  20. data/lib/locomotive/mounter/extensions/tilt/css.rb +31 -0
  21. data/lib/locomotive/mounter/fields.rb +254 -0
  22. data/lib/locomotive/mounter/models/base.rb +42 -0
  23. data/lib/locomotive/mounter/models/content_asset.rb +84 -0
  24. data/lib/locomotive/mounter/models/content_entry.rb +372 -0
  25. data/lib/locomotive/mounter/models/content_field.rb +190 -0
  26. data/lib/locomotive/mounter/models/content_select_option.rb +29 -0
  27. data/lib/locomotive/mounter/models/content_type.rb +274 -0
  28. data/lib/locomotive/mounter/models/editable_element.rb +27 -0
  29. data/lib/locomotive/mounter/models/page.rb +442 -0
  30. data/lib/locomotive/mounter/models/site.rb +28 -0
  31. data/lib/locomotive/mounter/models/snippet.rb +55 -0
  32. data/lib/locomotive/mounter/models/theme_asset.rb +148 -0
  33. data/lib/locomotive/mounter/models/translation.rb +28 -0
  34. data/lib/locomotive/mounter/mounting_point.rb +65 -0
  35. data/lib/locomotive/mounter/reader/api.rb +64 -0
  36. data/lib/locomotive/mounter/reader/api/base.rb +67 -0
  37. data/lib/locomotive/mounter/reader/api/content_assets_reader.rb +39 -0
  38. data/lib/locomotive/mounter/reader/api/content_entries_reader.rb +142 -0
  39. data/lib/locomotive/mounter/reader/api/content_types_reader.rb +76 -0
  40. data/lib/locomotive/mounter/reader/api/pages_reader.rb +192 -0
  41. data/lib/locomotive/mounter/reader/api/site_reader.rb +42 -0
  42. data/lib/locomotive/mounter/reader/api/snippets_reader.rb +61 -0
  43. data/lib/locomotive/mounter/reader/api/theme_assets_reader.rb +42 -0
  44. data/lib/locomotive/mounter/reader/api/translations_reader.rb +30 -0
  45. data/lib/locomotive/mounter/reader/file_system.rb +43 -0
  46. data/lib/locomotive/mounter/reader/file_system/base.rb +65 -0
  47. data/lib/locomotive/mounter/reader/file_system/content_assets_reader.rb +90 -0
  48. data/lib/locomotive/mounter/reader/file_system/content_entries_reader.rb +97 -0
  49. data/lib/locomotive/mounter/reader/file_system/content_types_reader.rb +88 -0
  50. data/lib/locomotive/mounter/reader/file_system/pages_reader.rb +211 -0
  51. data/lib/locomotive/mounter/reader/file_system/site_reader.rb +27 -0
  52. data/lib/locomotive/mounter/reader/file_system/snippets_reader.rb +115 -0
  53. data/lib/locomotive/mounter/reader/file_system/theme_assets_reader.rb +83 -0
  54. data/lib/locomotive/mounter/reader/file_system/translations_reader.rb +36 -0
  55. data/lib/locomotive/mounter/reader/runner.rb +89 -0
  56. data/lib/locomotive/mounter/utils/hash.rb +31 -0
  57. data/lib/locomotive/mounter/utils/output.rb +124 -0
  58. data/lib/locomotive/mounter/utils/string.rb +40 -0
  59. data/lib/locomotive/mounter/utils/yaml.rb +125 -0
  60. data/lib/locomotive/mounter/utils/yaml_front_matters_template.rb +45 -0
  61. data/lib/locomotive/mounter/version.rb +8 -0
  62. data/lib/locomotive/mounter/writer/api.rb +74 -0
  63. data/lib/locomotive/mounter/writer/api/base.rb +172 -0
  64. data/lib/locomotive/mounter/writer/api/content_assets_writer.rb +74 -0
  65. data/lib/locomotive/mounter/writer/api/content_entries_writer.rb +227 -0
  66. data/lib/locomotive/mounter/writer/api/content_types_writer.rb +151 -0
  67. data/lib/locomotive/mounter/writer/api/pages_writer.rb +250 -0
  68. data/lib/locomotive/mounter/writer/api/site_writer.rb +125 -0
  69. data/lib/locomotive/mounter/writer/api/snippets_writer.rb +111 -0
  70. data/lib/locomotive/mounter/writer/api/theme_assets_writer.rb +201 -0
  71. data/lib/locomotive/mounter/writer/api/translations_writer.rb +85 -0
  72. data/lib/locomotive/mounter/writer/file_system.rb +44 -0
  73. data/lib/locomotive/mounter/writer/file_system/base.rb +70 -0
  74. data/lib/locomotive/mounter/writer/file_system/content_assets_writer.rb +38 -0
  75. data/lib/locomotive/mounter/writer/file_system/content_entries_writer.rb +33 -0
  76. data/lib/locomotive/mounter/writer/file_system/content_types_writer.rb +32 -0
  77. data/lib/locomotive/mounter/writer/file_system/pages_writer.rb +93 -0
  78. data/lib/locomotive/mounter/writer/file_system/site_writer.rb +30 -0
  79. data/lib/locomotive/mounter/writer/file_system/snippets_writer.rb +59 -0
  80. data/lib/locomotive/mounter/writer/file_system/theme_assets_writer.rb +72 -0
  81. data/lib/locomotive/mounter/writer/file_system/translations_writer.rb +29 -0
  82. data/lib/locomotive/mounter/writer/runner.rb +73 -0
  83. data/locomotivecms_mounter.gemspec +64 -0
  84. metadata +539 -0
@@ -0,0 +1,45 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Utils
4
+
5
+ # YAML Front-matters for HAML/Liquid templates
6
+ class YAMLFrontMattersTemplate
7
+
8
+ attr_accessor :filepath, :attributes, :raw_source, :line_offset
9
+
10
+ def initialize(filepath)
11
+ self.filepath = filepath
12
+ self.line_offset = 0
13
+
14
+ self.fetch_attributes_and_raw_source(File.read(self.filepath))
15
+ end
16
+
17
+ def source
18
+ return @source if @source
19
+
20
+ @source = if self.filepath.ends_with?('.haml')
21
+ Haml::Engine.new(self.raw_source).render
22
+ else
23
+ self.raw_source
24
+ end
25
+ end
26
+
27
+ protected
28
+
29
+ def fetch_attributes_and_raw_source(data)
30
+ if data =~ /^(---\s*\n.*?\n?)^(---\s*$\n?)(.*)/m
31
+ self.line_offset = $1.count("\n") + 1
32
+ self.attributes = YAML.load($1)
33
+ self.raw_source = $3
34
+ else
35
+ self.attributes = nil
36
+ self.raw_source = data
37
+ end
38
+
39
+ self.raw_source = self.raw_source.force_encoding('utf-8')
40
+ end
41
+
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+ module Locomotive
3
+ module Mounter #:nodoc
4
+
5
+ VERSION = '1.5.4'
6
+
7
+ end
8
+ end
@@ -0,0 +1,74 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Writer
4
+ module Api
5
+
6
+ # Build a singleton instance of the Runner class.
7
+ #
8
+ # @return [ Object ] A singleton instance of the Runner class
9
+ #
10
+ def self.instance
11
+ @@instance ||= Runner.new(:api)
12
+ end
13
+
14
+ def self.teardown
15
+ @@instance = nil
16
+ end
17
+
18
+ class Runner < Locomotive::Mounter::Writer::Runner
19
+
20
+ attr_accessor :uri
21
+
22
+ # Call the LocomotiveCMS engine to get a token for
23
+ # the next API calls
24
+ def prepare
25
+ # by default, do not push data (content entries and editable elements)
26
+ self.parameters[:data] ||= false
27
+
28
+ credentials = self.parameters.select { |k, _| %w(uri email password api_key).include?(k.to_s) }
29
+ ssl_version = self.parameters[:ssl_version] ? self.parameters[:ssl_version].to_sym : :TLSv1_2
30
+ self.uri = credentials[:uri]
31
+
32
+ begin
33
+ Locomotive::Mounter::EngineApi.ssl_version(ssl_version)
34
+ Locomotive::Mounter::EngineApi.set_token(credentials)
35
+ rescue Exception => e
36
+ raise Locomotive::Mounter::WriterException.new("unable to get an API token: #{e.message}")
37
+ end
38
+ end
39
+
40
+ # Ordered list of atomic writers
41
+ #
42
+ # @return [ Array ] List of classes
43
+ #
44
+ def writers
45
+ [SiteWriter, SnippetsWriter, ContentTypesWriter, ContentEntriesWriter, TranslationsWriter, PagesWriter, ThemeAssetsWriter].tap do |_writers|
46
+ # modify the list depending on the parameters
47
+ if self.parameters
48
+ if self.parameters[:data] == false && !(self.parameters[:only].try(:include?, 'content_entries'))
49
+ _writers.delete(ContentEntriesWriter)
50
+ end
51
+
52
+ if self.parameters[:translations] == false && !(self.parameters[:only].try(:include?, 'translations'))
53
+ _writers.delete(TranslationsWriter)
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ # Get the writer to push content assets
60
+ #
61
+ # @return [ Object ] A memoized instance of the content assets writer
62
+ #
63
+ def content_assets_writer
64
+ @content_assets_writer ||= ContentAssetsWriter.new(self.mounting_point, self).tap do |writer|
65
+ writer.prepare
66
+ end
67
+ end
68
+
69
+ end
70
+
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,172 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Writer
4
+ module Api
5
+
6
+ class Base
7
+
8
+ include Locomotive::Mounter::Utils::Output
9
+
10
+ attr_accessor :mounting_point, :runner
11
+
12
+ delegate :default_locale, :locales, :site, :sprockets, to: :mounting_point
13
+
14
+ delegate :content_assets_writer, to: :runner
15
+
16
+ delegate :force?, to: :runner
17
+
18
+ def initialize(mounting_point, runner)
19
+ self.mounting_point = mounting_point
20
+ self.runner = runner
21
+ end
22
+
23
+ # A write may have to do some work before being launched.
24
+ # By default, it displays to the output the resource being pushed.
25
+ #
26
+ def prepare
27
+ self.output_title
28
+ end
29
+
30
+ # By setting the data option to true, user content (content entries and
31
+ # editable elements from page) can be pushed too.
32
+ # By default, its value is false.
33
+ #
34
+ # @return [ Boolean ] True if the data option has been set to true
35
+ #
36
+ def data?
37
+ self.runner.parameters[:data] || false
38
+ end
39
+
40
+ # Get remote resource(s) from the API
41
+ #
42
+ # @param [ String ] resource_name The path to the resource (usually, the resource name)
43
+ # @param [ String ] locale The locale for the request
44
+ # @param [ Boolean ] dont_filter_attributes False if the we want to only keep the attributes defined by the safe_attributes method
45
+ #
46
+ # @return [ Object] The object or a collection of objects.
47
+ #
48
+ def get(resource_name, locale = nil, dont_filter_attributes = false)
49
+ attribute_names = dont_filter_attributes ? nil : self.safe_attributes
50
+
51
+ begin
52
+ Locomotive::Mounter::EngineApi.fetch(resource_name, {}, locale, attribute_names)
53
+ rescue ApiReadException => e
54
+ raise WriterException.new(e.message)
55
+ end
56
+ end
57
+
58
+ # Create a resource from the API.
59
+ #
60
+ # @param [ String ] resource_name The path to the resource (usually, the resource name)
61
+ # @param [ Hash ] attributes The attributes of the resource
62
+ # @param [ String ] locale The locale for the request
63
+ # @param [ Boolean ] raw True if the result has to be filtered in order to keep only the attributes defined by the safe_attributes method
64
+ #
65
+ # @return [ Object] The response of the API or nil if an error occurs
66
+ #
67
+ def post(resource_name, attributes, locale = nil, dont_filter_attributes = false)
68
+ attribute_names = dont_filter_attributes ? nil : self.safe_attributes
69
+
70
+ begin
71
+ Locomotive::Mounter::EngineApi.create(resource_name, attributes, locale, attribute_names)
72
+ rescue ApiWriteException => e
73
+ message = e.message
74
+ message = message.map do |attribute, errors|
75
+ " #{attribute} => #{[*errors].join(', ')}\n".colorize(color: :red)
76
+ end.join("\n") if message.respond_to?(:keys)
77
+
78
+ raise WriterException.new(message)
79
+ end
80
+ end
81
+
82
+ # Update a resource from the API.
83
+ #
84
+ # @param [ String ] resource_name The path to the resource (usually, the resource name)
85
+ # @param [ Hash ] attributes The attributes of the resource
86
+ # @param [ Hash ] params The attributes of the resource
87
+ # @param [ String ] locale The locale for the request
88
+ #
89
+ # @return [ Object] The response of the API
90
+ #
91
+ def put(resource_name, id, attributes, locale = nil)
92
+ begin
93
+ Locomotive::Mounter::EngineApi.update(resource_name, id, attributes, locale, self.safe_attributes)
94
+ rescue ApiWriteException => e
95
+ message = e.message
96
+ message = message.map do |attribute, errors|
97
+ " #{attribute} => #{[*errors].join(', ')}\n".colorize(color: :red)
98
+ end.join("\n") if message.respond_to?(:keys)
99
+
100
+ raise WriterException.new(message)
101
+
102
+ # self.log "\n"
103
+ # data.each do |attribute, errors|
104
+ # self.log " #{attribute} => #{[*errors].join(', ')}\n".colorize(color: :red)
105
+ # end if data.respond_to?(:keys)
106
+ # nil # DEBUG
107
+ end
108
+ end
109
+
110
+ def safe_attributes
111
+ %w(_id)
112
+ end
113
+
114
+ # Loop on each locale of the mounting point and
115
+ # change the current locale at the same time.
116
+ def each_locale(&block)
117
+ self.mounting_point.locales.each do |locale|
118
+ Locomotive::Mounter.with_locale(locale) do
119
+ block.call(locale)
120
+ end
121
+ end
122
+ end
123
+
124
+ # Return the absolute path from a relative path
125
+ # pointing to an asset within the public folder
126
+ #
127
+ # @param [ String ] path The path to the file within the public folder
128
+ #
129
+ # @return [ String ] The absolute path
130
+ #
131
+ def absolute_path(path)
132
+ File.join(self.mounting_point.path, 'public', path)
133
+ end
134
+
135
+ # Take a path and convert it to a File object if possible
136
+ #
137
+ # @param [ String ] path The path to the file within the public folder
138
+ #
139
+ # @return [ Object ] The file
140
+ #
141
+ def path_to_file(path)
142
+ File.new(self.absolute_path(path))
143
+ end
144
+
145
+ # Take in the source the assets whose url begins by "/samples",
146
+ # upload them to the engine and replace them by their remote url.
147
+ #
148
+ # @param [ String ] source The source text
149
+ #
150
+ # @return [ String ] The source with remote urls
151
+ #
152
+ def replace_content_assets!(source)
153
+ return source if source.blank?
154
+
155
+ source.to_s.gsub(/\/samples\/\S*\.[a-zA-Z0-9]+/) do |match|
156
+ url = self.content_assets_writer.write(match)
157
+ url || match
158
+ end
159
+ end
160
+
161
+ protected
162
+
163
+ def response_to_status(response)
164
+ response ? :success : :error
165
+ end
166
+
167
+ end
168
+
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,74 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Writer
4
+ module Api
5
+
6
+ # Push content assets to a remote LocomotiveCMS engine.
7
+ #
8
+ # The assets come from editable content blocks, for instance, in a
9
+ # the text fields of content entries or within editable_***_text.
10
+ # If an asset with the same filename already exists in the engine,
11
+ # the local version will not pushed unless the :force_assets option is passed
12
+ #
13
+ class ContentAssetsWriter < Base
14
+
15
+ attr_accessor :remote_assets
16
+
17
+ def prepare
18
+ self.remote_assets = {}
19
+
20
+ # assign an _id to a local content type if possible
21
+ self.get(:content_assets, nil, true).each do |attributes|
22
+ self.remote_assets[attributes['full_filename']] = attributes
23
+ end
24
+ end
25
+
26
+ def write(local_path)
27
+ status = :skipped
28
+ asset = self.build_asset(local_path)
29
+ response = self.remote_assets[asset.filename]
30
+
31
+ asset._id = response['_id'] if response
32
+
33
+ self.output_resource_op asset
34
+
35
+ if !asset.exists?
36
+ status = :error
37
+ elsif asset.persisted?
38
+ if asset.size != response['size'].to_i && self.force_assets?
39
+ # update it
40
+ response = self.put :content_assets, asset._id, asset.to_params
41
+ status = self.response_to_status(response)
42
+ end
43
+ else
44
+ # create it
45
+ response = self.post :content_assets, asset.to_params, nil, true
46
+ status = self.response_to_status(response)
47
+
48
+ self.remote_assets[response['full_filename']] = response
49
+ end
50
+
51
+ self.output_resource_op_status asset, status
52
+
53
+ [:success, :skipped].include?(status) ? response['url'] : nil
54
+ end
55
+
56
+ protected
57
+
58
+ def build_asset(local_path)
59
+ Locomotive::Mounter::Models::ContentAsset.new(filepath: self.absolute_path(local_path))
60
+ end
61
+
62
+ def force_assets?
63
+ self.runner.parameters[:force_assets] || false
64
+ end
65
+
66
+ def resource_message(resource)
67
+ " #{super}"
68
+ end
69
+
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,227 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Writer
4
+ module Api
5
+
6
+ # Push content entries to a remote LocomotiveCMS engine.
7
+ #
8
+ # TODO: They get created or changed only if the
9
+ # :data option has been passed.
10
+ #
11
+ class ContentEntriesWriter < Base
12
+
13
+ attr_accessor :with_relationships
14
+
15
+ def prepare
16
+ return unless self.data?
17
+
18
+ super
19
+
20
+ # initialize the list storing all the entries including relationships
21
+ self.with_relationships = []
22
+
23
+ # assign an _id to a local content entry if possible
24
+ self.content_types.each do |slug, content_type|
25
+ entries = self.get("content_types/#{slug}/entries", nil, true)
26
+
27
+ entries.each do |attributes|
28
+ content_entry = content_type.find_entry(attributes['_slug'])
29
+
30
+ if content_entry
31
+ self.apply_response(content_entry, attributes)
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ def write
38
+ return unless self.data?
39
+
40
+ self.each_locale do |locale|
41
+ self.output_locale
42
+
43
+ self.content_types.each do |slug, content_type|
44
+ (content_type.entries || []).each do |entry|
45
+ next unless entry.translated_in?(locale)
46
+
47
+ if entry.persisted?
48
+ self.update_content_entry(slug, entry)
49
+ else
50
+ self.create_content_entry(slug, entry)
51
+ end
52
+
53
+ self.register_relationships(slug, entry)
54
+ end # content entries
55
+ end # content type
56
+ end # locale
57
+
58
+ self.persist_content_entries_with_relationships
59
+ end
60
+
61
+ protected
62
+
63
+ # Persist a content entry by calling the API. It is enhanced then
64
+ # by the response if no errors occured.
65
+ #
66
+ # @param [ String ] content_type The slug of the content type
67
+ # @param [ Object ] content_entry The content entry to create
68
+ #
69
+ def create_content_entry(content_type, content_entry)
70
+ # log before
71
+ self.output_resource_op content_entry
72
+
73
+ # get the params
74
+ params = self.buffer_log { self.content_entry_to_params(content_entry) }
75
+
76
+ # send the request
77
+ response = self.post "content_types/#{content_type}/entries", params, nil, true
78
+
79
+ self.apply_response(content_entry, response)
80
+
81
+ status = self.response_to_status(response)
82
+
83
+ # log after
84
+ self.output_resource_op_status content_entry, status
85
+ self.flush_log_buffer
86
+ end
87
+
88
+ # Update a content entry by calling the API.
89
+ #
90
+ # @param [ String ] content_type The slug of the content type
91
+ # @param [ Object ] content_entry The content entry to update
92
+ #
93
+ def update_content_entry(content_type, content_entry)
94
+ locale = Locomotive::Mounter.locale
95
+
96
+ # log before
97
+ self.output_resource_op content_entry
98
+
99
+ # get the params
100
+ params = self.buffer_log { self.content_entry_to_params(content_entry) }
101
+
102
+ # send the request
103
+ response = self.put "content_types/#{content_type}/entries", content_entry._id, params, locale
104
+
105
+ status = self.response_to_status(response)
106
+
107
+ # log after
108
+ self.output_resource_op_status content_entry, status
109
+ self.flush_log_buffer
110
+ end
111
+
112
+ # Save to the remote engine the content entries owning
113
+ # a relationship field. This can be done once ALL the
114
+ # the content entries have been first created.
115
+ #
116
+ def persist_content_entries_with_relationships
117
+ unless self.with_relationships.empty?
118
+ self.log "\n setting relationships for all the content entries\n"
119
+
120
+ updates = self.content_entries_with_relationships_to_hash
121
+
122
+ updates.each do |params|
123
+ _id, slug = params.delete(:_id), params.delete(:slug)
124
+ self.put "content_types/#{slug}/entries", _id, params
125
+ end
126
+ end
127
+ end
128
+
129
+ # Build hash storing the values of the relationships (belongs_to and has_many).
130
+ # The key is the id of the content entry
131
+ #
132
+ # @return [ Hash ] The updates to process
133
+ #
134
+ def content_entries_with_relationships_to_hash
135
+ [].tap do |updates|
136
+ self.with_relationships.each do |(slug, content_entry)|
137
+ changes = {}
138
+
139
+ content_entry.content_type.fields.each do |field|
140
+ case field.type.to_sym
141
+ when :belongs_to
142
+ if target_id = content_entry.dynamic_getter(field.name).try(:_id)
143
+ changes["#{field.name}_id"] = target_id
144
+ end
145
+ when :many_to_many
146
+ target_ids = content_entry.dynamic_getter(field.name).map(&:_id).compact
147
+ unless target_ids.empty?
148
+ changes["#{field.name}_ids"] = target_ids
149
+ end
150
+ end
151
+ end
152
+
153
+ updates << { _id: content_entry._id, slug: slug }.merge(changes)
154
+ end
155
+ end
156
+ end
157
+
158
+ # Return the list of content types
159
+ #
160
+ # @return [ Array ] List of content types
161
+ #
162
+ def content_types
163
+ self.mounting_point.content_types
164
+ end
165
+
166
+ # Take a content entry and get the params related to that content entry.
167
+ #
168
+ # @param [ Object ] entry The content entry
169
+ #
170
+ # @return [ Hash ] The params
171
+ #
172
+ def content_entry_to_params(entry)
173
+ params = entry.to_params
174
+
175
+ entry.each_dynamic_field do |field, value|
176
+ unless field.is_relationship?
177
+ case field.type.to_sym
178
+ when :string, :text
179
+ params[field.name] = self.replace_content_assets!(value)
180
+ when :file
181
+ if value =~ %r(^http://)
182
+ params[field.name] = value
183
+ elsif value && self.mounting_point.path
184
+ path = File.join(self.mounting_point.path, 'public', value)
185
+ params[field.name] = File.new(path)
186
+ end
187
+ else
188
+ params[field.name] = value
189
+ end
190
+ end
191
+ end
192
+
193
+ params
194
+ end
195
+
196
+ # Keep track of both the content entries which
197
+ # includes a relationship field and also
198
+ # the selection options.
199
+ #
200
+ # @param [ String ] slug The slug of the content type
201
+ # @param [ Object ] entry The content entry
202
+ #
203
+ def register_relationships(slug, entry)
204
+ entry.each_dynamic_field do |field, value|
205
+ if %w(belongs_to many_to_many).include?(field.type.to_s)
206
+ self.with_relationships << [slug, entry]
207
+ return # no need to go further and avoid duplicate entries
208
+ end
209
+ end
210
+ end
211
+
212
+ # Enhance the content entry with the information returned by an API call.
213
+ #
214
+ # @param [ Object ] content_entry The content entry instance
215
+ # @param [ Hash ] response The API response
216
+ #
217
+ def apply_response(content_entry, response)
218
+ return if content_entry.nil? || response.nil?
219
+
220
+ content_entry._id = response['_id']
221
+ end
222
+
223
+ end
224
+ end
225
+ end
226
+ end
227
+ end