locomotivecms_steam 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +7 -7
  3. data/bin/steam.rb +1 -1
  4. data/lib/locomotive/steam/adapters/filesystem.rb +8 -1
  5. data/lib/locomotive/steam/adapters/filesystem/sanitizers/content_entry.rb +27 -1
  6. data/lib/locomotive/steam/adapters/filesystem/sanitizers/site.rb +51 -0
  7. data/lib/locomotive/steam/adapters/filesystem/yaml_loaders/site.rb +8 -0
  8. data/lib/locomotive/steam/adapters/mongodb.rb +20 -1
  9. data/lib/locomotive/steam/adapters/mongodb/command.rb +8 -0
  10. data/lib/locomotive/steam/adapters/mongodb/query.rb +20 -1
  11. data/lib/locomotive/steam/entities/content_type.rb +1 -0
  12. data/lib/locomotive/steam/entities/content_type_field.rb +2 -1
  13. data/lib/locomotive/steam/entities/site.rb +3 -1
  14. data/lib/locomotive/steam/initializers/sprockets.rb +13 -3
  15. data/lib/locomotive/steam/liquid/drops/content_entry.rb +1 -1
  16. data/lib/locomotive/steam/liquid/drops/metafields.rb +97 -0
  17. data/lib/locomotive/steam/liquid/drops/site.rb +4 -0
  18. data/lib/locomotive/steam/liquid/filters/misc.rb +4 -0
  19. data/lib/locomotive/steam/liquid/tags/consume.rb +17 -6
  20. data/lib/locomotive/steam/liquid/tags/nav.rb +17 -11
  21. data/lib/locomotive/steam/middlewares/helpers.rb +1 -1
  22. data/lib/locomotive/steam/middlewares/page.rb +1 -0
  23. data/lib/locomotive/steam/middlewares/renderer.rb +8 -2
  24. data/lib/locomotive/steam/models/repository.rb +4 -0
  25. data/lib/locomotive/steam/repositories/content_type_field_repository.rb +4 -0
  26. data/lib/locomotive/steam/version.rb +1 -1
  27. data/locomotivecms_steam.gemspec +1 -1
  28. data/spec/fixtures/default/app/content_types/events.yml +1 -0
  29. data/spec/fixtures/default/app/views/pages/basic.liquid.haml +12 -0
  30. data/spec/fixtures/default/app/views/pages/tags/nav.liquid.haml +2 -0
  31. data/spec/fixtures/default/config/metafields_schema.yml +33 -0
  32. data/spec/fixtures/default/config/site.yml +13 -0
  33. data/spec/fixtures/default/data/events.yml +1 -2
  34. data/spec/integration/adapters/mongodb_spec.rb +49 -0
  35. data/spec/integration/repositories/content_entry_repository_spec.rb +26 -0
  36. data/spec/integration/server/metafields_spec.rb +26 -0
  37. data/spec/integration/server/nav_spec.rb +8 -0
  38. data/spec/unit/adapters/filesystem/sanitizers/site_spec.rb +59 -0
  39. data/spec/unit/adapters/filesystem/yaml_loaders/site_spec.rb +12 -2
  40. data/spec/unit/adapters/filesystem_adapter_spec.rb +18 -0
  41. data/spec/unit/adapters/mongodb/query_spec.rb +25 -1
  42. data/spec/unit/entities/content_type_spec.rb +10 -0
  43. data/spec/unit/initializers/sprockets_spec.rb +36 -0
  44. data/spec/unit/liquid/drops/content_entry_spec.rb +3 -1
  45. data/spec/unit/liquid/drops/metafields_spec.rb +81 -0
  46. data/spec/unit/liquid/filters/misc_spec.rb +13 -0
  47. data/spec/unit/liquid/tags/consume_spec.rb +7 -0
  48. data/spec/unit/liquid/tags/nav_spec.rb +9 -1
  49. data/spec/unit/liquid/tags/path_to_spec.rb +1 -1
  50. data/spec/unit/middlewares/helpers_spec.rb +32 -0
  51. data/spec/unit/middlewares/renderer_spec.rb +17 -2
  52. data/spec/unit/repositories/content_entry_repository_spec.rb +11 -11
  53. data/spec/unit/repositories/content_type_field_repository_spec.rb +10 -0
  54. metadata +18 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3624519a192d3e6bd9d76a79309374786f790e16
4
- data.tar.gz: 24ab1580d146b35e87a7d0208a8143b18ddb3f5e
3
+ metadata.gz: 40ab1d48128f72e386a5703b9d7b8714e518a601
4
+ data.tar.gz: 9831bdde9c497e76449501f7311f0aec76d15da6
5
5
  SHA512:
6
- metadata.gz: 1da4b24d96279eaa2db5e4812af1aed83ddfa12df58dec74c903deea1f098e39cd09e8d6561ae9078e5b199b704d2ebb714a61ff0546a1eb45835a8e8d35da1d
7
- data.tar.gz: cb5c389a0355ba13f70b8f3491f706c5999935f0548ec7c912e2a4fc4f07db28ad4a374ee27d37ffc1cc2aa1e879ec4c3794ff0a39c92694450a18b49c93bd8c
6
+ metadata.gz: 011f9a7993651c5d525bc6ee9485007aa271d1c5a7742e2fa9f12f090d617d3fe64f75159d35293e7e1412eabf69e95b3223d5e60ecb8a62b2848b290c8fba64
7
+ data.tar.gz: e18402953d1bbad33d9325a2eb1ed9afbcc2dce76f32116bbc6d3761fefeffa12aa8f98d99b2166dd8e75c821ff5ce531139ff07ef5bdf282f89f97e44a6f530
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- locomotivecms_steam (1.0.0)
4
+ locomotivecms_steam (1.0.1)
5
5
  RedCloth (~> 4.2.9)
6
6
  autoprefixer-rails (~> 6.2.3)
7
7
  chronic (~> 0.10.2)
@@ -17,7 +17,7 @@ PATH
17
17
  mimetype-fu (~> 0.1.2)
18
18
  moneta (~> 0.8.0)
19
19
  morphine (~> 0.1.1)
20
- nokogiri (~> 1.6.7.1)
20
+ nokogiri (~> 1.6.7.2)
21
21
  rack-cache (~> 1.2)
22
22
  rack-rewrite (~> 1.5.1)
23
23
  rack_csrf (~> 2.5.0)
@@ -29,7 +29,7 @@ GEM
29
29
  remote: https://rubygems.org/
30
30
  specs:
31
31
  RedCloth (4.2.9)
32
- activesupport (4.2.5)
32
+ activesupport (4.2.5.1)
33
33
  i18n (~> 0.7)
34
34
  json (~> 1.7, >= 1.7.7)
35
35
  minitest (~> 5.1)
@@ -118,7 +118,7 @@ GEM
118
118
  mime-types (2.6.2)
119
119
  mimetype-fu (0.1.2)
120
120
  mini_portile2 (2.0.0)
121
- minitest (5.8.3)
121
+ minitest (5.8.4)
122
122
  moneta (0.8.0)
123
123
  mongo (2.2.1)
124
124
  bson (~> 4.0)
@@ -126,7 +126,7 @@ GEM
126
126
  multi_json (1.11.2)
127
127
  multi_xml (0.5.5)
128
128
  netrc (0.11.0)
129
- nokogiri (1.6.7.1)
129
+ nokogiri (1.6.7.2)
130
130
  mini_portile2 (~> 2.0.0.rc2)
131
131
  nokogumbo (1.4.7)
132
132
  nokogiri
@@ -140,7 +140,7 @@ GEM
140
140
  pry (~> 0.10)
141
141
  puma (2.15.3)
142
142
  rack (1.6.4)
143
- rack-cache (1.5.1)
143
+ rack-cache (1.6.1)
144
144
  rack (>= 0.4)
145
145
  rack-mini-profiler (0.9.8)
146
146
  rack (>= 1.1.3)
@@ -153,7 +153,7 @@ GEM
153
153
  rake-compiler (0.9.5)
154
154
  rake
155
155
  rb-fsevent (0.9.7)
156
- rb-inotify (0.9.5)
156
+ rb-inotify (0.9.7)
157
157
  ffi (>= 0.5.0)
158
158
  rest-client (1.8.0)
159
159
  http-cookie (>= 1.0.2, < 2.0)
data/bin/steam.rb CHANGED
@@ -82,7 +82,7 @@ Locomotive::Common.configure do |config|
82
82
  config.notifier = Locomotive::Common::Logger.setup(options[:log_file])
83
83
  end
84
84
 
85
- app = Locomotive::Steam::Server.to_app
85
+ app = Locomotive::Steam.to_app
86
86
 
87
87
  # Thin rack handler
88
88
  # Note: alt thin settings (Threaded)
@@ -45,6 +45,13 @@ module Locomotive::Steam
45
45
  entity
46
46
  end
47
47
 
48
+ def inc(mapper, entity, attribute, amount = 1)
49
+ entity.tap do
50
+ entity[attribute] ||= 0
51
+ entity[attribute] += amount
52
+ end
53
+ end
54
+
48
55
  def delete(mapper, scope, entity)
49
56
  # TODO: to be implemented
50
57
  end
@@ -109,7 +116,7 @@ module Locomotive::Steam
109
116
 
110
117
  def build_sanitizers
111
118
  hash = Hash.new { build_klass('Sanitizers', :simple).new }
112
- %i(pages content_types content_entries snippets).inject(hash) do |memo, name|
119
+ %i(sites pages content_types content_entries snippets).inject(hash) do |memo, name|
113
120
  memo[name] = build_klass('Sanitizers', name).new
114
121
  memo
115
122
  end
@@ -16,13 +16,14 @@ module Locomotive::Steam
16
16
  dataset.all.each do |entity|
17
17
  _apply_to_dataset(entity, dataset)
18
18
  end
19
+ clean
19
20
  end
20
21
 
21
22
  def apply_to_entity_with_dataset(entity, dataset)
22
23
  # Note: this statement attaches the site to the entity
23
24
  apply_to_entity(entity)
24
25
 
25
- # make sure it gets an unique slug and an _id
26
+ # make sure it gets an unique slug and an _id + set default values
26
27
  _apply_to_dataset(entity, dataset)
27
28
  end
28
29
 
@@ -31,6 +32,7 @@ module Locomotive::Steam
31
32
  def _apply_to_dataset(entity, dataset)
32
33
  set_slug(entity, dataset)
33
34
  set_id(entity)
35
+ set_default_values(entity)
34
36
  end
35
37
 
36
38
  def add_label(entity)
@@ -52,6 +54,21 @@ module Locomotive::Steam
52
54
  end
53
55
  end
54
56
 
57
+ def set_default_values(entity)
58
+ each_field_with_default(entity) do |field|
59
+ name = field.type == 'select' ? "#{field.name}_id" : field.name
60
+ value = field.localized? ? entity[name][default_locale] : entity[name]
61
+
62
+ return unless value.nil?
63
+
64
+ if field.localized?
65
+ entity[name].translations = field.default
66
+ else
67
+ entity[name] = field.default
68
+ end
69
+ end
70
+ end
71
+
55
72
  def set_slug(entity, dataset)
56
73
  if entity._label.respond_to?(:translations) # localized?
57
74
  entity._label.each do |locale, label|
@@ -78,6 +95,15 @@ module Locomotive::Steam
78
95
  dataset.query(locale) { where(_slug: slug, k(:_id, :ne) => id) }.first.nil?
79
96
  end
80
97
 
98
+ def each_field_with_default(entity, &block)
99
+ @fields_with_default ||= entity.content_type.fields_with_default
100
+ @fields_with_default.each(&block)
101
+ end
102
+
103
+ def clean
104
+ @fields_with_default = nil
105
+ end
106
+
81
107
  end
82
108
 
83
109
  end
@@ -0,0 +1,51 @@
1
+ module Locomotive::Steam
2
+ module Adapters
3
+ module Filesystem
4
+ module Sanitizers
5
+
6
+ class Site
7
+
8
+ include Adapters::Filesystem::Sanitizer
9
+
10
+ def apply_to_entity(entity)
11
+ entity.metafields_schema = clean_metafields_schema(entity.metafields_schema)
12
+ end
13
+
14
+ private
15
+
16
+ def clean_metafields_schema(schema)
17
+ return nil unless schema
18
+
19
+ schema.each_with_index.map do |(namespace, definitions), position|
20
+ {
21
+ name: namespace.to_s,
22
+ label: localized_label(definitions.delete(:label), namespace.to_s), # { default: namespace.to_s }.merge(definitions.delete(:label) || {}),
23
+ fields: parse_metafields(definitions.delete(:fields)),
24
+ position: definitions.delete(:position) || position
25
+ }.merge(definitions)
26
+ end.as_json
27
+ end
28
+
29
+ def parse_metafields(fields)
30
+ fields.each_with_index.map do |(name, attributes), position|
31
+ if attributes # Hash
32
+ attributes[:label] = { default: attributes[:label] } if attributes[:label].is_a?(String)
33
+ attributes[:hint] = { default: attributes[:hint] } if attributes[:hint].is_a?(String)
34
+ end
35
+ { name: name.to_s, position: position }.merge(attributes || {})
36
+ end
37
+ end
38
+
39
+ def localized_label(label, default)
40
+ case label
41
+ when Hash then label
42
+ when String then { default: label }
43
+ else { default: default}
44
+ end
45
+ end
46
+
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -15,9 +15,17 @@ module Locomotive
15
15
 
16
16
  attributes[:picture] = File.expand_path(File.join(site_path, 'icon.png'))
17
17
 
18
+ attributes[:metafields_schema] = load_metafields_schema
19
+
18
20
  [attributes]
19
21
  end
20
22
 
23
+ private
24
+
25
+ def load_metafields_schema
26
+ schema = _load(File.join(site_path, 'config', 'metafields_schema.yml'))
27
+ end
28
+
21
29
  end
22
30
 
23
31
  end
@@ -34,6 +34,10 @@ module Locomotive::Steam
34
34
  command(mapper).insert(entity)
35
35
  end
36
36
 
37
+ def inc(mapper, entity, attribute, amount = 1)
38
+ command(mapper).inc(entity, attribute, amount)
39
+ end
40
+
37
41
  def delete(mapper, scope, entity)
38
42
  command(mapper).delete(entity)
39
43
  end
@@ -55,6 +59,21 @@ module Locomotive::Steam
55
59
  end
56
60
  end
57
61
 
62
+ class << self
63
+
64
+ attr_reader :session
65
+
66
+ def build_session(uri_or_hosts, client_options)
67
+ @session ||= Mongo::Client.new(uri_or_hosts, client_options)
68
+ end
69
+
70
+ def disconnect_session
71
+ @session.try(:close)
72
+ @session = nil
73
+ end
74
+
75
+ end
76
+
58
77
  private
59
78
 
60
79
  def query_klass
@@ -82,7 +101,7 @@ module Locomotive::Steam
82
101
  end
83
102
 
84
103
  def session
85
- Thread.current[:mongo_session] ||= Mongo::Client.new(uri_or_hosts, client_options)
104
+ self.class.build_session(uri_or_hosts, client_options)
86
105
  end
87
106
 
88
107
  def uri_or_hosts
@@ -20,6 +20,14 @@ module Locomotive::Steam
20
20
  entity
21
21
  end
22
22
 
23
+ def inc(entity, attribute, amount = 1)
24
+ entity.tap do
25
+ @collection.find(_id: entity._id).update_one('$inc' => { attribute => amount })
26
+ entity[attribute] ||= 0
27
+ entity[attribute] += amount
28
+ end
29
+ end
30
+
23
31
  def delete(entity)
24
32
  @collection.find(_id: entity._id).delete_one if entity._id
25
33
  end
@@ -25,7 +25,7 @@ module Locomotive::Steam
25
25
 
26
26
  def order_by(*args)
27
27
  self.tap do
28
- @sort = [*args]
28
+ @sort = decode_order_by(*args)
29
29
  end
30
30
  end
31
31
 
@@ -100,6 +100,25 @@ module Locomotive::Steam
100
100
  end
101
101
  end
102
102
 
103
+ def decode_order_by(*spec)
104
+ [*spec].compact.map do |arg|
105
+ _decode_order_by(arg)
106
+ end
107
+ end
108
+
109
+ def _decode_order_by(arg)
110
+ case arg
111
+ when String
112
+ if arg.include?(',')
113
+ _decode_order_by(arg.split(','))
114
+ else
115
+ arg.strip.split(/[\s|.]/)
116
+ end
117
+ when Array then arg.map { |_arg| _decode_order_by(_arg) }
118
+ else arg
119
+ end
120
+ end
121
+
103
122
  end
104
123
 
105
124
  end
@@ -7,6 +7,7 @@ module Locomotive::Steam
7
7
 
8
8
  def_delegator :fields, :associations, :association_fields
9
9
  def_delegator :fields, :selects, :select_fields
10
+ def_delegator :fields, :default, :fields_with_default
10
11
 
11
12
  def initialize(attributes = {})
12
13
  super({
@@ -11,7 +11,8 @@ module Locomotive::Steam
11
11
  type: :string,
12
12
  localized: false,
13
13
  required: false,
14
- unique: false
14
+ unique: false,
15
+ default: nil
15
16
  }.merge(attributes))
16
17
  end
17
18
 
@@ -15,7 +15,9 @@ module Locomotive::Steam
15
15
  redirect_to_first_domain: false,
16
16
  url_redirections: [],
17
17
  private_access: false,
18
- password: nil
18
+ password: nil,
19
+ metafields_schema: {},
20
+ metafields: nil
19
21
  }.merge(attributes))
20
22
  end
21
23
 
@@ -47,10 +47,20 @@ module Locomotive::Steam
47
47
  end
48
48
 
49
49
  def install_autoprefixer
50
- file = File.join(root, '..', 'config', 'autoprefixer.yml')
51
- params = (File.exist?(file) ? ::YAML.load_file(file) : {}).symbolize_keys
50
+ file = File.join(root, '..', 'config', 'autoprefixer.yml')
52
51
 
53
- AutoprefixerRails.install(self, params)
52
+ if File.exists?(file)
53
+ params = (::YAML.load_file(file) || {}).symbolize_keys
54
+ AutoprefixerRails.install(self, params)
55
+
56
+ Locomotive::Common::Logger.info "[Autoprefixer] detected and installed".light_white
57
+
58
+ if ENV['EXECJS_RUNTIME'].blank?
59
+ Locomotive::Common::Logger.warn "[Autoprefixer]".light_white + " [Warning] if you notice bad performance, install NodeJS and run \"export EXECJS_RUNTIME=Node\" in your shell"
60
+ end
61
+
62
+ Locomotive::Common::Logger.info "\n"
63
+ end
54
64
  end
55
65
 
56
66
  def is_java_installed?
@@ -4,7 +4,7 @@ module Locomotive
4
4
  module Drops
5
5
  class ContentEntry < I18nBase
6
6
 
7
- delegate :_slug, :_translated, :seo_title, :meta_keywords, :meta_description, to: :@_source
7
+ delegate :_slug, :_translated, :seo_title, :meta_keywords, :meta_description, :created_at, :updated_at, to: :@_source
8
8
 
9
9
  alias :_permalink :_slug
10
10
 
@@ -0,0 +1,97 @@
1
+ module Locomotive
2
+ module Steam
3
+ module Liquid
4
+ module Drops
5
+
6
+ class MetafieldsNamespace < Base
7
+
8
+ delegate :first, :last, :each, :each_with_index, :empty?, :any?, :size, to: :labels_and_values
9
+
10
+ alias :count :size
11
+ alias :length :size
12
+
13
+ def before_method(meth)
14
+ find_value(meth.to_s)
15
+ end
16
+
17
+ def namespace=(namespace)
18
+ @namespace = namespace
19
+ end
20
+
21
+ protected
22
+
23
+ def find_value(name)
24
+ if field = fields[name]
25
+ t(values[name], field['localized'])
26
+ else
27
+ Locomotive::Common::Logger.warn "[Liquid template] unknown site metafield \"#{name}\" under #{@namespace['name']}"
28
+ nil
29
+ end
30
+ end
31
+
32
+ def values
33
+ @_source.metafields[@namespace['name']] || {}
34
+ end
35
+
36
+ def labels_and_values
37
+ return [] if @namespace['fields'].blank?
38
+
39
+ return @labels_and_values if @labels_and_values
40
+
41
+ ordered_fields = @namespace['fields'].sort { |f| f['position'] }
42
+
43
+ @labels_and_values = ordered_fields.map do |field|
44
+ value, localized = values[field['name']], field['localized']
45
+ {
46
+ 'name' => field['name'],
47
+ 'label' => t(field['label']) || field['name'].humanize,
48
+ 'value' => t(value, localized)
49
+ }
50
+ end
51
+ end
52
+
53
+ def fields
54
+ return @fields if @fields
55
+
56
+ (@fields = {}).tap do
57
+ (@namespace['fields'] || []).each do |field|
58
+ @fields[field['name']] = field
59
+ end
60
+ end
61
+ end
62
+
63
+ def t(value, localized = true)
64
+ key = localized ? @context.registers[:locale] : 'default'
65
+ value = { 'default' => value } unless value.is_a?(Hash)
66
+ value[key]
67
+ end
68
+
69
+ end
70
+
71
+ class Metafields < Base
72
+
73
+ def before_method(meth)
74
+ find_namespace(meth.to_s)
75
+ end
76
+
77
+ private
78
+
79
+ def find_namespace(name)
80
+ if namespace = _find_namespace(name)
81
+ MetafieldsNamespace.new(@_source).tap { |d| d.namespace = namespace }
82
+ else
83
+ Locomotive::Common::Logger.warn "[Liquid template] unknown site metafield namespace \"#{name}\""
84
+ nil
85
+ end
86
+ end
87
+
88
+ def _find_namespace(name)
89
+ @_source.metafields_schema.find { |s| s['name'] == name }
90
+ end
91
+
92
+ end
93
+
94
+ end
95
+ end
96
+ end
97
+ end