fix issue: site.metafields iteration has different order (locomotivecms/wagon#296)

did committed Mar 07, 2016
commit 80daca938f72c68f4e0347b9b706e5549571b90c
Showing 5 changed files with 48 additions and 4 deletions
locomotive/steam/adapters/filesystem/sanitizers/site.rb b/lib/locomotive/steam/adapters/filesystem/sanitizers/site.rb +3 -0
@@ @@ -28,10 +28,13 @@ module Locomotive::Steam
def parse_metafields(fields)
fields.each_with_index.map do |(name, attributes), position|
+ name, attributes = name.to_a[0] if name.is_a?(Hash) # ordered list of fields
+
if attributes # Hash
attributes[:label] = { default: attributes[:label] } if attributes[:label].is_a?(String)
attributes[:hint] = { default: attributes[:hint] } if attributes[:hint].is_a?(String)
end
+
{ name: name.to_s, position: position }.merge(attributes || {})
end
end
locomotive/steam/adapters/filesystem/yaml_loaders/site.rb b/lib/locomotive/steam/adapters/filesystem/yaml_loaders/site.rb +1 -1
@@ @@ -23,7 +23,7 @@ module Locomotive
private
def load_metafields_schema
- schema = _load(File.join(site_path, 'config', 'metafields_schema.yml'))
+ _load(File.join(site_path, 'config', 'metafields_schema.yml'))
end
end
locomotive/steam/liquid/drops/metafields.rb b/lib/locomotive/steam/liquid/drops/metafields.rb +1 -1
@@ @@ -38,7 +38,7 @@ module Locomotive
return @labels_and_values if @labels_and_values
- ordered_fields = @namespace['fields'].sort { |f| f['position'] }
+ ordered_fields = @namespace['fields'].sort { |a, b| a['position'] <=> b['position'] }
@labels_and_values = ordered_fields.map do |field|
value, localized = values[field['name']], field['localized']
spec/unit/adapters/filesystem/sanitizers/site_spec.rb +26 -1
@@ @@ -26,7 +26,26 @@ describe Locomotive::Steam::Adapters::Filesystem::Sanitizers::Site do
describe 'with a schema' do
# see the metafields_schema.yml in the fixtures folder
- let(:schema) { {:social=>{:label=>{:fr=>"Social (FR)"}, :position=>1, :fields=>["facebook_id", "google_id"]}, :github=>{:position=>0, :fields=>{:api_url=>{:label=>"API Url", :type=>"string", :hint=>"API endpoint"}, :expires_in=>{:label=>{:en=>"Expires in", :fr=>"Expire dans"}, :hint=>{:en=>"Cache - In milliseconds", :fr=>"Cache - En millisecondes"}, :type=>"integer", :min=>0, :max=>3600}}}} }
+ let(:schema) { {
+ :social => {
+ :label => { :fr=>"Social (FR)" },
+ :position => 1,
+ :fields => ["facebook_id", "google_id"]
+ },
+ :github => {
+ :position => 0,
+ :fields => {
+ :api_url => { :label => "API Url", :type => "string", :hint => "API endpoint" },
+ :expires_in => { :label => { :en => "Expires in", :fr => "Expire dans" }, :hint => { :en => "Cache - In milliseconds", :fr => "Cache - En millisecondes" }, :type => "integer", :min => 0, :max => 3600 }
+ }
+ },
+ :theme => {
+ :fields => [
+ { :color => { :label => 'Color', type: 'color' } },
+ { :header => { :label => 'Header image', type: 'image' } }
+ ]
+ }
+ } }
it 'loads the full schema' do
# First namespace
@@ @@ -40,6 +59,12 @@ describe Locomotive::Steam::Adapters::Filesystem::Sanitizers::Site do
expect(subject[1]['position']).to eq 0
expect(subject[1]['fields'].count).to eq 2
expect(subject[1]['fields'][0]).to eq('name' => 'api_url', 'position' => 0, 'label' => { 'default' => 'API Url' }, 'type' => 'string', 'hint' => { 'default' => 'API endpoint' })
+
+ # Third namespace
+ expect(subject[2]['label']).to eq('default' => 'theme')
+ expect(subject[2]['fields'].count).to eq 2
+ expect(subject[2]['fields'][0]).to eq('name' => 'color', 'position' => 0, 'label' => { 'default' => 'Color' }, 'type' => 'color')
+ expect(subject[2]['fields'][1]).to eq('name' => 'header', 'position' => 1, 'label' => { 'default' => 'Header image' }, 'type' => 'image')
end
context 'label is a string instead of a hash' do
spec/unit/liquid/drops/metafields_spec.rb +17 -1
@@ @@ -3,11 +3,27 @@ require 'spec_helper'
describe Locomotive::Steam::Liquid::Drops::Metafields do
let(:metafields) { { 'my_namespace' => { 'analytics_id' => { 'default' => '42' }, 'street' => { 'en' => '7 Albert Camus Alley', 'fr' => '7 allée Albert Camus' } } } }
- let(:schema) { [ { 'name' => 'my_namespace', fields: [{ name: 'analytics_id' }, { name: 'street', localized: true }, { name: 'country' }] }].as_json }
+ let(:schema) { [ { 'name' => 'my_namespace', fields: [{ name: 'analytics_id', position: 1 }, { name: 'street', localized: true, position: 0 }, { name: 'country', :position => 2 }] }].as_json }
let(:site) { instance_double('Site', metafields: metafields, metafields_schema: schema) }
let(:context) { ::Liquid::Context.new({}, {}, { locale: 'en' }) }
let(:drop) { described_class.new(site).tap { |d| d.context = context } }
+ describe 'fields' do
+
+ let(:namespace) { drop.before_method(:my_namespace).tap { |d| d.context = context } }
+
+ it 'gives the number of the fields' do
+ expect(namespace.size).to eq 3
+ end
+
+ it 'iterates over the fields and keeps the order' do
+ list = []
+ namespace.each { |el| list << el['name'] }
+ expect(list).to eq(['street', 'analytics_id', 'country'])
+ end
+
+ end
+
describe 'calling a metafield' do
context 'unknown namespace' do