locomotivecms_steam 1.0.0.pre.beta.3 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +16 -11
  5. data/Rakefile +14 -2
  6. data/lib/locomotive/steam/adapters/filesystem/yaml_loader.rb +13 -3
  7. data/lib/locomotive/steam/adapters/filesystem/yaml_loaders/content_type.rb +10 -5
  8. data/lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb +9 -0
  9. data/lib/locomotive/steam/adapters/filesystem.rb +3 -1
  10. data/lib/locomotive/steam/adapters/memory.rb +6 -1
  11. data/lib/locomotive/steam/adapters/mongodb.rb +3 -1
  12. data/lib/locomotive/steam/decorators/i18n_decorator.rb +16 -0
  13. data/lib/locomotive/steam/entities/content_entry.rb +23 -2
  14. data/lib/locomotive/steam/entities/content_type.rb +9 -0
  15. data/lib/locomotive/steam/entities/content_type_field.rb +9 -0
  16. data/lib/locomotive/steam/entities/editable_element.rb +6 -2
  17. data/lib/locomotive/steam/entities/page.rb +4 -0
  18. data/lib/locomotive/steam/entities/site.rb +11 -3
  19. data/lib/locomotive/steam/liquid/drops/base.rb +4 -0
  20. data/lib/locomotive/steam/liquid/drops/content_entry.rb +23 -0
  21. data/lib/locomotive/steam/liquid/drops/content_entry_collection.rb +7 -1
  22. data/lib/locomotive/steam/liquid/drops/content_types.rb +6 -10
  23. data/lib/locomotive/steam/liquid/filters/json.rb +21 -14
  24. data/lib/locomotive/steam/liquid/tags/editable/base.rb +14 -2
  25. data/lib/locomotive/steam/liquid/tags/editable/text.rb +15 -1
  26. data/lib/locomotive/steam/liquid/tags/google_analytics.rb +8 -12
  27. data/lib/locomotive/steam/middlewares/default_env.rb +3 -1
  28. data/lib/locomotive/steam/middlewares/entry_submission.rb +1 -1
  29. data/lib/locomotive/steam/middlewares/favicon.rb +3 -1
  30. data/lib/locomotive/steam/middlewares/helpers.rb +2 -2
  31. data/lib/locomotive/steam/middlewares/logging.rb +3 -1
  32. data/lib/locomotive/steam/middlewares/page.rb +2 -0
  33. data/lib/locomotive/steam/middlewares/path.rb +4 -2
  34. data/lib/locomotive/steam/middlewares/renderer.rb +1 -1
  35. data/lib/locomotive/steam/middlewares/robots.rb +3 -1
  36. data/lib/locomotive/steam/middlewares/sitemap.rb +1 -1
  37. data/lib/locomotive/steam/middlewares/{threadsafe.rb → thread_safe.rb} +2 -1
  38. data/lib/locomotive/steam/middlewares.rb +1 -1
  39. data/lib/locomotive/steam/models/concerns/to_json.rb +31 -0
  40. data/lib/locomotive/steam/models/entity.rb +1 -0
  41. data/lib/locomotive/steam/models/i18n_field.rb +11 -0
  42. data/lib/locomotive/steam/models.rb +1 -0
  43. data/lib/locomotive/steam/repositories.rb +3 -1
  44. data/lib/locomotive/steam/server.rb +1 -1
  45. data/lib/locomotive/steam/services/asset_host_service.rb +3 -1
  46. data/lib/locomotive/steam/services/csrf_protection_service.rb +3 -1
  47. data/lib/locomotive/steam/services/editable_element_service.rb +3 -1
  48. data/lib/locomotive/steam/services/entry_submission_service.rb +4 -2
  49. data/lib/locomotive/steam/services/image_resizer_service.rb +3 -1
  50. data/lib/locomotive/steam/services/liquid_parser_service.rb +3 -1
  51. data/lib/locomotive/steam/services/page_finder_service.rb +3 -1
  52. data/lib/locomotive/steam/services/site_finder_service.rb +3 -1
  53. data/lib/locomotive/steam/services/snippet_finder_service.rb +3 -1
  54. data/lib/locomotive/steam/services/theme_asset_url_service.rb +3 -1
  55. data/lib/locomotive/steam/services/translator_service.rb +3 -1
  56. data/lib/locomotive/steam/services/url_builder_service.rb +3 -1
  57. data/lib/locomotive/steam/services.rb +4 -2
  58. data/lib/locomotive/steam/version.rb +1 -1
  59. data/locomotivecms_steam.gemspec +3 -3
  60. data/spec/fixtures/default/README +11 -0
  61. data/spec/fixtures/default/app/views/pages/layouts/simple.liquid +14 -0
  62. data/spec/fixtures/default/config/deploy.yml +4 -3
  63. data/spec/fixtures/default/config/site.yml +1 -1
  64. data/spec/fixtures/mongodb/locomotive_accounts.bson +0 -0
  65. data/spec/fixtures/mongodb/locomotive_accounts.metadata.json +1 -1
  66. data/spec/fixtures/mongodb/locomotive_activities.bson +0 -0
  67. data/spec/fixtures/mongodb/locomotive_activities.metadata.json +1 -0
  68. data/spec/fixtures/mongodb/locomotive_content_assets.bson +0 -0
  69. data/spec/fixtures/mongodb/locomotive_content_assets.metadata.json +1 -1
  70. data/spec/fixtures/mongodb/locomotive_content_entries.bson +0 -0
  71. data/spec/fixtures/mongodb/locomotive_content_entries.metadata.json +1 -1
  72. data/spec/fixtures/mongodb/locomotive_content_types.bson +0 -0
  73. data/spec/fixtures/mongodb/locomotive_content_types.metadata.json +1 -1
  74. data/spec/fixtures/mongodb/locomotive_pages.bson +0 -0
  75. data/spec/fixtures/mongodb/locomotive_pages.metadata.json +1 -1
  76. data/spec/fixtures/mongodb/locomotive_sites.bson +0 -0
  77. data/spec/fixtures/mongodb/locomotive_sites.metadata.json +1 -1
  78. data/spec/fixtures/mongodb/locomotive_snippets.bson +0 -0
  79. data/spec/fixtures/mongodb/locomotive_snippets.metadata.json +1 -1
  80. data/spec/fixtures/mongodb/locomotive_theme_assets.bson +0 -0
  81. data/spec/fixtures/mongodb/locomotive_theme_assets.metadata.json +1 -1
  82. data/spec/fixtures/mongodb/locomotive_translations.bson +0 -0
  83. data/spec/fixtures/mongodb/locomotive_translations.metadata.json +1 -1
  84. data/spec/fixtures/mongodb/system.indexes.bson +0 -0
  85. data/spec/integration/liquid/tags/paginate_spec.rb +1 -1
  86. data/spec/integration/repositories/content_entry_repository_spec.rb +2 -2
  87. data/spec/integration/repositories/content_type_repository_spec.rb +1 -1
  88. data/spec/integration/repositories/page_repository_spec.rb +3 -3
  89. data/spec/integration/repositories/site_repository_spec.rb +3 -3
  90. data/spec/integration/repositories/snippet_repository_spec.rb +1 -1
  91. data/spec/integration/repositories/theme_asset_repository_spec.rb +3 -3
  92. data/spec/integration/repositories/translation_repository_spec.rb +1 -1
  93. data/spec/integration/server/contact_form_spec.rb +1 -1
  94. data/spec/integration/server/sitemap_spec.rb +17 -1
  95. data/spec/support/helpers.rb +4 -0
  96. data/spec/support/liquid.rb +5 -1
  97. data/spec/unit/adapters/filesystem/yaml_loaders/content_type_spec.rb +1 -0
  98. data/spec/unit/adapters/filesystem/yaml_loaders/page_spec.rb +7 -4
  99. data/spec/unit/adapters/filesystem/yaml_loaders/site_spec.rb +1 -1
  100. data/spec/unit/decorators/i18n_decorator_spec.rb +9 -0
  101. data/spec/unit/entities/content_entry_spec.rb +29 -0
  102. data/spec/unit/entities/content_type_field_spec.rb +41 -0
  103. data/spec/unit/entities/content_type_spec.rb +10 -0
  104. data/spec/unit/entities/page_spec.rb +24 -0
  105. data/spec/unit/entities/site_spec.rb +44 -6
  106. data/spec/unit/liquid/drops/content_entry_spec.rb +16 -0
  107. data/spec/unit/liquid/filters/json_spec.rb +26 -3
  108. data/spec/unit/liquid/tags/editable/control_spec.rb +1 -1
  109. data/spec/unit/liquid/tags/editable/file_spec.rb +1 -1
  110. data/spec/unit/liquid/tags/editable/model_spec.rb +1 -1
  111. data/spec/unit/liquid/tags/editable/text_spec.rb +32 -6
  112. data/spec/unit/liquid/tags/extends_spec.rb +1 -1
  113. data/spec/unit/liquid/tags/google_analytics_spec.rb +2 -1
  114. data/spec/unit/liquid/tags/inherited_block_spec.rb +1 -1
  115. data/spec/unit/middlewares/locale_redirection_spec.rb +1 -1
  116. data/spec/unit/middlewares/renderer_spec.rb +1 -1
  117. data/spec/unit/middlewares/site_spec.rb +1 -1
  118. data/spec/unit/models/concerns/to_json_spec.rb +81 -0
  119. data/spec/unit/services/asset_host_service_spec.rb +15 -0
  120. data/spec/unit/services/entry_submission_service_spec.rb +9 -1
  121. data/spec/unit/services/translator_service_spec.rb +1 -1
  122. metadata +18 -13
  123. data/spec/fixtures/mongodb/sessions.bson +0 -0
  124. data/spec/fixtures/mongodb/sessions.metadata.json +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: afc4338f5582de4d66788ef18ebb8d1d8d3d024d
4
- data.tar.gz: 457d04823de496fc46c507f64d3b1e1313c7a6dd
3
+ metadata.gz: c15327d7b834e6a45dc9c631bf3f7aca7320d2e0
4
+ data.tar.gz: 7480937c0e40dee146c4b10684671f0da1bb638c
5
5
  SHA512:
6
- metadata.gz: 38071d83a98a7e53dd81591d58f7a3b035ac244b563e2077b115ba939cddbb4b55a54ee77e60f361dde5352fe5fd14cf8547229a95116416b43189999cb9619d
7
- data.tar.gz: 7378ea6a8eeda23d69bac0991d430dcaa4abed935598aca30294ba5f6a60097058b7e8f0e20a727f18c61814447a47f426278b68c249c0525e20b3c71cb204e1
6
+ metadata.gz: cf0538f565ffd72f18d96ae008189df3256639ba5124c260a76cdf24e5654968525acfeee2cb57c190a80b6edd3abb99b3a58928b5de9231e1f7b695958b1d57
7
+ data.tar.gz: d60744e27708a5af594454722bcbe13da873de4fd3c2f61624259529620710c830ae16449eb70a5f4b5c5fba7974531fb490bb3d2d17ee03fb309e38a3668f7b
data/.travis.yml CHANGED
@@ -2,7 +2,7 @@ language: ruby
2
2
  services: mongodb
3
3
  before_script: ./script/ci/before_build.sh
4
4
  rvm:
5
- - 2.2.0
5
+ - 2.2.2
6
6
  env:
7
7
  - CODECLIMATE_REPO_TOKEN=3fa74f2ade25037fccd7261090acbdeae232639c3a83aafb80ee428ec16b8cf9
8
8
  addons:
data/Gemfile CHANGED
@@ -34,5 +34,5 @@ group :test do
34
34
  end
35
35
 
36
36
  platform :ruby do
37
- ruby '2.2.0'
37
+ ruby '2.2.2'
38
38
  end
data/Gemfile.lock CHANGED
@@ -1,17 +1,17 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- locomotivecms_steam (1.0.0.pre.beta.3)
4
+ locomotivecms_steam (1.0.0.rc1)
5
5
  RedCloth (~> 4.2.9)
6
6
  chronic (~> 0.10.2)
7
7
  coffee-script (~> 2.4.1)
8
8
  compass (~> 1.0.3)
9
- dragonfly (~> 1.0.10)
9
+ dragonfly (~> 1.0.12)
10
10
  haml (~> 4.0.6)
11
- httparty (~> 0.13.5)
11
+ httparty (~> 0.13.6)
12
12
  kramdown (~> 1.8.0)
13
13
  locomotivecms-solid (~> 4.0.0.alpha2)
14
- locomotivecms_common (~> 0.0.4)
14
+ locomotivecms_common (~> 0.0.5)
15
15
  mime-types (~> 2.6.1)
16
16
  mimetype-fu (~> 0.1.2)
17
17
  moneta (~> 0.8.0)
@@ -35,6 +35,7 @@ GEM
35
35
  thread_safe (~> 0.3, >= 0.3.4)
36
36
  tzinfo (~> 1.1)
37
37
  addressable (2.3.8)
38
+ attr_extras (4.4.0)
38
39
  bson (3.1.0)
39
40
  byebug (4.0.5)
40
41
  columnize (= 0.9.0)
@@ -74,7 +75,7 @@ GEM
74
75
  docile (1.1.5)
75
76
  domain_name (0.5.24)
76
77
  unf (>= 0.0.5, < 1.0.0)
77
- dragonfly (1.0.10)
78
+ dragonfly (1.0.12)
78
79
  addressable (~> 2.3)
79
80
  multi_json (~> 1.0)
80
81
  rack (>= 1.3.0)
@@ -90,7 +91,7 @@ GEM
90
91
  hike (1.2.3)
91
92
  http-cookie (1.0.2)
92
93
  domain_name (~> 0.5)
93
- httparty (0.13.5)
94
+ httparty (0.13.7)
94
95
  json (~> 1.8)
95
96
  multi_xml (>= 0.5.2)
96
97
  i18n (0.7.0)
@@ -108,8 +109,9 @@ GEM
108
109
  locomotivecms-liquid (4.0.0.alpha2)
109
110
  locomotivecms-solid (4.0.0.alpha2)
110
111
  locomotivecms-liquid (~> 4.0.0.alpha2)
111
- locomotivecms_common (0.0.4)
112
+ locomotivecms_common (0.0.5)
112
113
  activesupport (~> 4.2.1)
114
+ attr_extras (~> 4.4.0)
113
115
  colorize
114
116
  stringex (~> 2.5.2)
115
117
  memory_profiler (0.9.4)
@@ -117,7 +119,7 @@ GEM
117
119
  mime-types (2.6.1)
118
120
  mimetype-fu (0.1.2)
119
121
  mini_portile (0.6.2)
120
- minitest (5.8.0)
122
+ minitest (5.8.1)
121
123
  moneta (0.8.0)
122
124
  moped (2.0.6)
123
125
  bson (~> 3.0)
@@ -142,7 +144,7 @@ GEM
142
144
  pry (~> 0.10)
143
145
  puma (2.12.3)
144
146
  rack (1.6.1)
145
- rack-cache (1.2)
147
+ rack-cache (1.5.0)
146
148
  rack (>= 0.4)
147
149
  rack-mini-profiler (0.9.7)
148
150
  rack (>= 1.1.3)
@@ -154,7 +156,7 @@ GEM
154
156
  rake (10.4.2)
155
157
  rake-compiler (0.9.5)
156
158
  rake
157
- rb-fsevent (0.9.5)
159
+ rb-fsevent (0.9.6)
158
160
  rb-inotify (0.9.5)
159
161
  ffi (>= 0.5.0)
160
162
  rest-client (1.8.0)
@@ -178,7 +180,7 @@ GEM
178
180
  crass (~> 1.0.2)
179
181
  nokogiri (>= 1.4.4)
180
182
  nokogumbo (= 1.4.1)
181
- sass (3.4.18)
183
+ sass (3.4.19)
182
184
  simplecov (0.10.0)
183
185
  docile (~> 1.1.0)
184
186
  json (~> 1.8)
@@ -235,3 +237,6 @@ DEPENDENCIES
235
237
  stackprof
236
238
  timecop (~> 0.7.4)
237
239
  yui-compressor (~> 0.12.0)
240
+
241
+ BUNDLED WITH
242
+ 1.10.6
data/Rakefile CHANGED
@@ -17,9 +17,21 @@ namespace :mongodb do
17
17
  namespace :test do
18
18
  desc 'Seed the MongoDB database with the dump of the Sample website'
19
19
  task :seed do
20
- path = File.join(File.expand_path(File.dirname(__FILE__)), 'spec', 'fixtures', 'mongodb')
20
+ root_path = File.expand_path(File.dirname(__FILE__))
21
+ db_path = File.join(root_path, 'spec', 'fixtures', 'mongodb')
22
+
23
+ if database = ENV['DATABASE']
24
+ dump_path = File.join(root_path, 'dump', database)
25
+
26
+ `rm -rf #{db_path}`
27
+ `mongodump --db #{database}`
28
+ `mv #{dump_path} #{db_path}`
29
+ end
30
+
21
31
  `mongo steam_test --eval "db.dropDatabase()"`
22
- `mongorestore -d steam_test #{path}`
32
+ `mongorestore -d steam_test #{db_path}`
33
+
34
+ puts "Done! Update now the spec/support/helpers.rb file by setting the new id of the site returned by the mongodb_site_id method"
23
35
  end
24
36
  end
25
37
  end
@@ -27,15 +27,25 @@ module Locomotive::Steam
27
27
  yaml, template = match[:yaml], match[:template]
28
28
  end
29
29
 
30
- HashConverter.to_sym(YAML.load(yaml)).tap do |attributes|
31
- block.call(attributes, template) if block_given?
32
- end
30
+ safe_yaml_load(yaml, template, path, &block)
33
31
  else
34
32
  Locomotive::Common::Logger.error "No #{path} file found"
35
33
  {}
36
34
  end
37
35
  end
38
36
 
37
+ def safe_yaml_load(yaml, template, path, &block)
38
+ return {} if yaml.blank?
39
+
40
+ begin
41
+ HashConverter.to_sym(YAML.load(yaml)).tap do |attributes|
42
+ block.call(attributes, template) if block_given?
43
+ end
44
+ rescue Exception => e
45
+ raise "Malformed YAML in this file #{path}, error: #{e.message}"
46
+ end
47
+ end
48
+
39
49
  def template_extensions
40
50
  @extensions ||= %w(liquid haml)
41
51
  end
@@ -26,20 +26,25 @@ module Locomotive
26
26
  end
27
27
 
28
28
  def build_fields(list)
29
- list.map do |attributes|
30
- build_field(attributes.keys.first, attributes.values.first)
29
+ list.each_with_index.map do |attributes, index|
30
+ build_field(attributes.keys.first, attributes.values.first, index)
31
31
  end
32
32
  end
33
33
 
34
- def build_field(name, attributes)
34
+ def build_field(name, attributes, position)
35
35
  attributes.tap do |attributes|
36
- attributes[:name] = name.to_s
37
- attributes[:type] = (attributes[:type] || 'string').to_s.downcase
36
+ attributes[:name] = name.to_s
37
+ attributes[:type] = (attributes[:type] || 'string').to_s.downcase
38
+ attributes[:position] ||= position
38
39
 
39
40
  if attributes[:label].blank?
40
41
  attributes[:label] = name.to_s.humanize
41
42
  end
42
43
 
44
+ if %w(belongs_to has_many many_to_many).include?(attributes[:type])
45
+ attributes[:localized] = false
46
+ end
47
+
43
48
  if select_options = attributes.delete(:select_options)
44
49
  attributes[:select_options] = build_select_options(select_options)
45
50
  end
@@ -80,6 +80,9 @@ module Locomotive
80
80
 
81
81
  # trick to use the template of the default locale (if available)
82
82
  attributes[:template_path] = false if template.blank?
83
+
84
+ # page under layouts/ should be treated differently
85
+ set_layout_attributes(attributes) if fullpath.split('/').first == 'layouts'
83
86
  end
84
87
  end
85
88
  end
@@ -158,6 +161,12 @@ module Locomotive
158
161
  { block: block, slug: slug, content: { locale => content } }
159
162
  end
160
163
 
164
+ def set_layout_attributes(attributes)
165
+ attributes[:is_layout] = true if attributes[:is_layout].nil?
166
+ attributes[:listed] = false
167
+ attributes[:published] = false
168
+ end
169
+
161
170
  end
162
171
 
163
172
  end
@@ -10,11 +10,13 @@ require_relative_all 'filesystem/sanitizers'
10
10
 
11
11
  module Locomotive::Steam
12
12
 
13
- class FilesystemAdapter < Struct.new(:options)
13
+ class FilesystemAdapter
14
14
 
15
15
  include Morphine
16
16
  include Locomotive::Steam::Adapters::Concerns::Key
17
17
 
18
+ attr_accessor_initialize :options
19
+
18
20
  register :cache do
19
21
  Locomotive::Steam::Adapters::Filesystem::SimpleCacheStore.new
20
22
  end
@@ -6,7 +6,12 @@ require_relative 'memory/dataset'
6
6
 
7
7
  module Locomotive::Steam
8
8
 
9
- class MemoryAdapter < Struct.new(:collection)
9
+ module Memory
10
+ end
11
+
12
+ class MemoryAdapter
13
+
14
+ attr_accessor_initialize :collection
10
15
 
11
16
  include Locomotive::Steam::Adapters::Concerns::Key
12
17
 
@@ -8,7 +8,9 @@ require_relative 'mongodb/command'
8
8
 
9
9
  module Locomotive::Steam
10
10
 
11
- class MongoDBAdapter < Struct.new(:options)
11
+ class MongoDBAdapter
12
+
13
+ attr_accessor_initialize :options
12
14
 
13
15
  def all(mapper, query)
14
16
  dataset(mapper, query)
@@ -84,6 +84,22 @@ module Locomotive
84
84
  end
85
85
  end
86
86
 
87
+ def to_hash
88
+ __getobj__.to_hash.tap do |hash|
89
+ @__localized_attributes__.keys.each do |name|
90
+ hash[name.to_s] = __get_localized_value__(name)
91
+ end
92
+ end
93
+ end
94
+
95
+ def as_json(options = nil)
96
+ to_hash.as_json(options)
97
+ end
98
+
99
+ def to_json
100
+ as_json.to_json
101
+ end
102
+
87
103
  #:nocov:
88
104
  def inspect
89
105
  "[Decorated #{__getobj__.class.name}][I18n] attributes exist? " +
@@ -17,6 +17,8 @@ module Locomotive::Steam
17
17
  }.merge(attributes))
18
18
  end
19
19
 
20
+ def _id; self[:_id] || self[:id]; end
21
+
20
22
  def _visible?; !!self[:_visible]; end
21
23
  alias :visible? :_visible?
22
24
 
@@ -73,6 +75,19 @@ module Locomotive::Steam
73
75
  super.merge(content_type_id: content_type_id)
74
76
  end
75
77
 
78
+ def to_hash
79
+ # default attributes
80
+ _attributes = %i(_id _slug _label _visible _position content_type_slug created_at updated_at)
81
+
82
+ # dynamic attributes
83
+ _attributes += content_type.persisted_field_names
84
+
85
+ _attributes.inject({}) do |hash, name|
86
+ hash[name.to_s] = send(name)
87
+ hash
88
+ end
89
+ end
90
+
76
91
  def to_liquid
77
92
  Locomotive::Steam::Liquid::Drops::ContentEntry.new(self)
78
93
  end
@@ -112,7 +127,7 @@ module Locomotive::Steam
112
127
 
113
128
  def _cast_file(field)
114
129
  _cast_convertor(field.name) do |value|
115
- FileField.new(value, base_url, self.updated_at)
130
+ value.respond_to?(:url) ? value : FileField.new(value, self.base_url, self.updated_at)
116
131
  end
117
132
  end
118
133
 
@@ -146,13 +161,19 @@ module Locomotive::Steam
146
161
  end
147
162
 
148
163
  # Represent a file
149
- class FileField < Struct.new(:filename, :base, :updated_at)
164
+ class FileField
165
+
166
+ attr_accessor_initialize :filename, :base, :updated_at
150
167
 
151
168
  def url
152
169
  return if filename.blank?
153
170
  base.blank? ? filename : "#{base}/#{filename}"
154
171
  end
155
172
 
173
+ def to_json
174
+ url
175
+ end
176
+
156
177
  def to_liquid
157
178
  Locomotive::Steam::Liquid::Drops::UploadedFile.new(self)
158
179
  end
@@ -31,6 +31,15 @@ module Locomotive::Steam
31
31
  fields.localized_names + select_fields.map(&:name)
32
32
  end
33
33
 
34
+ def persisted_field_names
35
+ [].tap do |names|
36
+ fields_by_name.each do |name, field|
37
+ _name = field.persisted_name
38
+ names << _name if _name
39
+ end
40
+ end
41
+ end
42
+
34
43
  def label_field_name
35
44
  (self[:label_field_name] || fields.first.name).to_sym
36
45
  end
@@ -59,6 +59,15 @@ module Locomotive::Steam
59
59
  %i(belongs_to has_many many_to_many).include?(self.type)
60
60
  end
61
61
 
62
+ def persisted_name
63
+ case type
64
+ when :belongs_to, :select then "#{name}_id"
65
+ when :many_to_many then "#{name.singularize}_ids"
66
+ when :has_many then nil
67
+ else name
68
+ end
69
+ end
70
+
62
71
  class SelectOption
63
72
 
64
73
  include Locomotive::Steam::Models::Entity
@@ -8,8 +8,8 @@ module Locomotive::Steam
8
8
 
9
9
  def initialize(attributes = {})
10
10
  super({
11
- content: nil,
12
- source: nil,
11
+ content: nil,
12
+ source: nil,
13
13
  inline_editing: true
14
14
  }.merge(attributes))
15
15
  end
@@ -18,6 +18,10 @@ module Locomotive::Steam
18
18
  self[:source].blank? ? self.content : self[:source]
19
19
  end
20
20
 
21
+ def format
22
+ self[:format] || 'html' # only editable_text elements
23
+ end
24
+
21
25
  def default_content?
22
26
  self.content.blank?
23
27
  end
@@ -12,13 +12,16 @@ module Locomotive::Steam
12
12
  listed: false,
13
13
  published: true,
14
14
  templatized: false,
15
+ cache_enabled: true,
15
16
  fullpath: {},
17
+ response_type: nil,
16
18
  content_type: nil,
17
19
  target_klass_name: nil,
18
20
  position: 99,
19
21
  raw_template: nil,
20
22
  source: nil,
21
23
  editable_elements: {},
24
+ redirect: false,
22
25
  redirect_url: {},
23
26
  redirect_type: nil,
24
27
  parent_id: nil,
@@ -30,6 +33,7 @@ module Locomotive::Steam
30
33
  def listed?; !!listed; end
31
34
  def published?; !!published; end
32
35
  def templatized?; !!templatized; end
36
+ def redirect?; redirect.nil? ? redirect_url.present? : redirect; end
33
37
 
34
38
  def content_type_id
35
39
  self.target_klass_name =~ Locomotive::Steam::CONTENT_ENTRY_ENGINE_CLASS_NAME
@@ -6,7 +6,11 @@ module Locomotive::Steam
6
6
 
7
7
  def initialize(attributes = {})
8
8
  super({
9
- prefix_default_locale: false
9
+ cache_enabled: false,
10
+ prefix_default_locale: false,
11
+ updated_at: nil,
12
+ content_version: nil,
13
+ template_version: nil
10
14
  }.merge(attributes))
11
15
  end
12
16
 
@@ -15,11 +19,11 @@ module Locomotive::Steam
15
19
  end
16
20
 
17
21
  def default_locale
18
- locales.try(:first) || :en
22
+ locales.first || :en
19
23
  end
20
24
 
21
25
  def locales
22
- self[:locales].map(&:to_sym)
26
+ (self[:locales] || [:en]).map(&:to_sym)
23
27
  end
24
28
 
25
29
  def timezone_name
@@ -30,6 +34,10 @@ module Locomotive::Steam
30
34
  @timezone ||= ActiveSupport::TimeZone.new(timezone_name)
31
35
  end
32
36
 
37
+ def last_modified_at
38
+ [self.content_version, self.template_version].compact.sort.last || self.updated_at
39
+ end
40
+
33
41
  def to_liquid
34
42
  Locomotive::Steam::Liquid::Drops::Site.new(self)
35
43
  end
@@ -28,6 +28,10 @@ module Locomotive
28
28
  records
29
29
  end
30
30
 
31
+ def as_json(options = nil)
32
+ @_source.as_json(options)
33
+ end
34
+
31
35
  protected
32
36
 
33
37
  def liquify(*records, &block)
@@ -56,8 +56,31 @@ module Locomotive
56
56
  end
57
57
  end
58
58
 
59
+ def to_hash
60
+ @_source.to_hash.tap do |hash|
61
+ hash['id'] = hash['_id']
62
+
63
+ @_source.content_type.fields_by_name.each do |name, field|
64
+ case field.type
65
+ when :file
66
+ hash[name] = hash["#{name}_url"] = file_field_to_url(hash[name.to_s]) if hash[name.to_s].present?
67
+ when :select
68
+ hash[name] = @_source.send(name) if hash["#{name}_id"].present?
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ def as_json(options = nil)
75
+ self.to_hash.as_json(options)
76
+ end
77
+
59
78
  protected
60
79
 
80
+ def file_field_to_url(field)
81
+ field.to_liquid.tap { |drop| drop.context = @context }.url
82
+ end
83
+
61
84
  def repository(entry)
62
85
  repository = @context.registers[:services].repositories.content_entry
63
86
  repository.with(entry.content_type)
@@ -13,7 +13,13 @@ module Locomotive
13
13
  end
14
14
 
15
15
  def all
16
- collection
16
+ collection.map do |entry|
17
+ entry.to_liquid.tap do |drop|
18
+ if drop && drop.respond_to?(:context=)
19
+ drop.context = @context
20
+ end
21
+ end
22
+ end
17
23
  end
18
24
 
19
25
  def count
@@ -5,7 +5,11 @@ module Locomotive
5
5
  class ContentTypes < ::Liquid::Drop
6
6
 
7
7
  def before_method(meth)
8
- fetch_content_type(meth.to_s)
8
+ if content_type = fetch_content_type(meth.to_s)
9
+ ContentEntryCollection.new(content_type)
10
+ else
11
+ nil
12
+ end
9
13
  end
10
14
 
11
15
  private
@@ -18,20 +22,12 @@ module Locomotive
18
22
  @content_type_map ||= {}
19
23
 
20
24
  if !@content_type_map.include?(slug)
21
- @content_type_map[slug] = _fetch_content_type(slug)
25
+ @content_type_map[slug] = repository.by_slug(slug)
22
26
  end
23
27
 
24
28
  @content_type_map[slug]
25
29
  end
26
30
 
27
- def _fetch_content_type(slug)
28
- if content_type = repository.by_slug(slug)
29
- ContentEntryCollection.new(content_type)
30
- else
31
- nil
32
- end
33
- end
34
-
35
31
  end
36
32
 
37
33
  end
@@ -4,32 +4,39 @@ module Locomotive
4
4
  module Filters
5
5
  module Json
6
6
 
7
- def json(input, fields = nil)
7
+ def json(input, fields = [])
8
8
  if fields && fields.is_a?(String)
9
9
  fields = fields.split(',').map(&:strip)
10
10
  end
11
11
 
12
- if fields.blank?
13
- input.to_json
14
- elsif input.respond_to?(:each)
15
- if fields.size == 1
16
- input.map { |object| object[fields.first].to_json }.join(',')
17
- else
18
- input.map { |object| "{" + object_to_json(object, fields) + "}" }.join(',')
19
- end
12
+ if input.respond_to?(:each)
13
+ '[' + input.map do |object|
14
+ fields.size == 1 ? object[fields.first].to_json : object_to_json(object, fields)
15
+ end.join(',') + ']'
20
16
  else
21
17
  object_to_json(input, fields)
22
18
  end
23
19
  end
24
20
 
21
+ # without the leading and trailing braces/brackets
22
+ # useful to add a prperty to an object or an element to an array
23
+ def open_json(input)
24
+ if input =~ /\A[\{\[](.*)[\}\]]\Z/m
25
+ $1
26
+ else
27
+ input
28
+ end
29
+ end
30
+
25
31
  protected
26
32
 
27
33
  def object_to_json(input, fields)
28
- [].tap do |output|
29
- fields.each do |field|
30
- output << %("#{field}":#{input[field].to_json})
31
- end
32
- end.join(',')
34
+ if input.respond_to?(:as_json)
35
+ options = fields.blank? ? {} : { only: fields }
36
+ input.as_json(options).to_json
37
+ else
38
+ input.to_json
39
+ end
33
40
  end
34
41
 
35
42
  end
@@ -11,6 +11,7 @@ module Locomotive
11
11
 
12
12
  def initialize(tag_name, markup, options)
13
13
  if markup =~ Syntax
14
+ @page_fullpath = options[:page].fullpath
14
15
  @slug = $1.gsub(/[\"\']/, '')
15
16
  @element_options = { fixed: false, inline_editing: true }
16
17
  markup.scan(::Liquid::TagAttributes) { |key, value| @element_options[key.to_sym] = value.gsub(/^[\"\']/, '').gsub(/[\"\']$/, '') }
@@ -31,19 +32,30 @@ module Locomotive
31
32
 
32
33
  def render(context)
33
34
  service = context.registers[:services].editable_element
34
- page = context.registers[:page]
35
+ page = fetch_page(context)
35
36
  block = @element_options[:block] || context['block'].try(:name)
36
37
 
37
38
  if element = service.find(page, block, @slug)
38
39
  render_element(context, element)
39
40
  else
40
- # Locomotive::Common::Logger.error "[#{page.fullpath}] missing #{@tag_name} \"#{@slug}\" (#{context['block'].try(:name) || 'default'})"
41
+ Locomotive::Common::Logger.error "[#{page.fullpath}] missing #{@tag_name} \"#{@slug}\" (#{context['block'].try(:name) || 'default'})"
41
42
  super
42
43
  end
43
44
  end
44
45
 
45
46
  protected
46
47
 
48
+ def fetch_page(context)
49
+ page = context.registers[:page]
50
+
51
+ return page if !@element_options[:fixed] || page.fullpath == @page_fullpath
52
+
53
+ pages = context.registers[:pages] ||= {}
54
+ service = context.registers[:services].page_finder
55
+
56
+ pages[@page_fullpath] ||= service.find(@page_fullpath)
57
+ end
58
+
47
59
  def default_element_attributes
48
60
  {
49
61
  block: self.current_inherited_block_name,