site metafields are now available in the liquid template

did committed Jan 24, 2016
commit c4302cb3d9119638dea8ca7fd3c99d1b9a6d6c2d
Showing 11 changed files with 185 additions and 26 deletions
locomotive/steam/adapters/filesystem.rb b/lib/locomotive/steam/adapters/filesystem.rb +1 -1
@@ @@ -116,7 +116,7 @@ module Locomotive::Steam
def build_sanitizers
hash = Hash.new { build_klass('Sanitizers', :simple).new }
- %i(site pages content_types content_entries snippets).inject(hash) do |memo, name|
+ %i(sites pages content_types content_entries snippets).inject(hash) do |memo, name|
memo[name] = build_klass('Sanitizers', name).new
memo
end
locomotive/steam/adapters/filesystem/sanitizers/site.rb b/lib/locomotive/steam/adapters/filesystem/sanitizers/site.rb +5 -7
@@ @@ -18,21 +18,19 @@ module Locomotive::Steam
schema.map do |namespace, definitions|
{
- name: { default: namespace.to_s }.merge(definitions.delete(:name) || {}),
+ label: { default: namespace.to_s }.merge(definitions.delete(:label) || {}),
fields: parse_metafields(definitions.delete(:fields))
}.merge(definitions)
- end
+ end.as_json
end
def parse_metafields(fields)
fields.map do |name, attributes|
if attributes # Hash
- attributes[:hint] = { default: attributes[:hint] } if attributes[:hint].is_a?(String)
-
- { name: { default: name.to_s }.merge(attributes.delete(:name)) }.merge(attributes)
- else # Array
- { name: { default: name.to_s } }
+ 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 }.merge(attributes || {})
end
end
locomotive/steam/liquid/drops/metafields.rb b/lib/locomotive/steam/liquid/drops/metafields.rb +47 -0
@@ @@ -0,0 +1,47 @@
+ module Locomotive
+ module Steam
+ module Liquid
+ module Drops
+
+ class Metafields < Base
+
+ def before_method(meth)
+ if field = fields[meth.to_s]
+ find_value(meth.to_s, field)
+ else
+ Locomotive::Common::Logger.warn "[Liquid template] unknown site metafield \"#{meth.to_s}\""
+ nil
+ end
+ end
+
+ private
+
+ def find_value(name, field)
+ value = @_source.metafields[name]
+
+ return nil if value.blank?
+
+ key = field['localized'] ? @context.registers[:locale] : 'default'
+ value = { 'default' => value } unless value.is_a?(Hash)
+
+ value[key]
+ end
+
+ def fields
+ return @schema if @schema
+
+ (@schema = {}).tap do
+ @_source.metafields_schema.each do |definition|
+ definition['fields'].each do |field|
+ @schema[field['name']] = field
+ end
+ end
+ end
+ end
+
+ end
+
+ end
+ end
+ end
+ end
locomotive/steam/liquid/drops/site.rb b/lib/locomotive/steam/liquid/drops/site.rb +4 -0
@@ @@ -14,6 +14,10 @@ module Locomotive
liquify(*self.scoped_pages)
end
+ def metafields
+ @metafields ||= Metafields.new(@_source)
+ end
+
protected
def repository
spec/fixtures/default/app/views/pages/basic.liquid.haml +7 -0
@@ @@ -12,3 +12,10 @@ position: 6
%body
%p
This is a basic page
+
+ %ul
+ %li Color scheme={{ site.metafields.color_scheme }}
+ %li Facebook ID={{ site.metafields.facebook_id }}
+ %li Google ID={{ site.metafields.google_id }}
+ %li API URL={{ site.metafields.api_url }}
+ %li Expires In={{ site.metafields.expires_in }}
spec/fixtures/default/config/metafields_schema.yml +15 -9
@@ @@ -1,22 +1,28 @@
+ Theme:
+ fields:
+ color_scheme:
+ localized: true
+
Social:
- name:
+ label:
fr: Social (FR)
position: 1
fields:
- - Facebook ID
- - Google ID
+ - facebook_id
+ - google_id
Github:
position: 0
fields:
- "API url":
- name:
+ api_url:
+ label:
+ en: 'API Url'
fr: "Url de l'API"
type: string
- hint: "API endpoint"
- default: https://api.github.com/repos/locomotivecms/engine/issues?state=opened
- "Expire in":
- name:
+ hint: 'API endpoint'
+ expires_in:
+ label:
+ en: 'Expires in'
fr: 'Expire dans'
hint:
en: 'Cache - In milliseconds'
spec/fixtures/default/config/site.yml +10 -0
@@ @@ -19,3 +19,13 @@ meta_keywords:
meta_description: some meta description
robots_txt: "User-agent: *\nDisallow:"
+
+ metafields:
+ color_scheme:
+ en: 'white'
+ fr: 'blue'
+ nb: 'red'
+ facebook_id: 'FB42'
+ google_id: 'G42'
+ api_url: https://api.github.com/repos/vmg/redcarpet/issues?state=closed
+ expires_in: 42
spec/integration/server/metafields_spec.rb +20 -0
@@ @@ -0,0 +1,20 @@
+ require File.dirname(__FILE__) + '/../integration_helper'
+
+ describe 'Site metafields' do
+
+ include Rack::Test::Methods
+
+ def app
+ run_server
+ end
+
+ it 'returns all the values of the site metafields' do
+ get '/basic'
+ expect(last_response.body).to include 'Color scheme=white'
+ expect(last_response.body).to include 'Facebook ID=FB42'
+ expect(last_response.body).to include 'Google ID=G42'
+ expect(last_response.body).to include 'API URL=https://api.github.com/repos/vmg/redcarpet/issues?state=closed'
+ expect(last_response.body).to include 'Expires In=42'
+ end
+
+ end
spec/unit/adapters/filesystem/sanitizers/site_spec.rb +8 -8
@@ @@ -26,19 +26,19 @@ 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=>{:name=>{:fr=>"Social (FR)"}, :position=>1, :fields=>["Facebook ID", "Google ID"]}, :Github=>{:position=>0, :fields=>{:"API url"=>{:name=>{:fr=>"Url de l'API"}, :type=>"string", :hint=>"API endpoint", :default=>"https://api.github.com/repos/locomotivecms/engine/issues?state=opened"}, :"Expire in"=>{:name=>{: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}}}} }
it 'loads the full schema' do
# First namespace
- expect(subject[0][:name]).to eq(default: 'Social', fr: 'Social (FR)')
- expect(subject[0][:position]).to eq 1
- expect(subject[0][:fields]).to eq([{ name: { default: 'Facebook ID' } }, { name: { default: 'Google ID' } }])
+ expect(subject[0]['label']).to eq('default' => 'Social', 'fr' => 'Social (FR)')
+ expect(subject[0]['position']).to eq 1
+ expect(subject[0]['fields']).to eq([{ 'name' => 'facebook_id' }, { 'name' => 'google_id' }])
# Second namespace
- expect(subject[1][:name]).to eq(default: 'Github')
- expect(subject[1][:position]).to eq 0
- expect(subject[1][:fields].count).to eq 2
- expect(subject[1][:fields][0]).to eq(name: { default: 'API url', fr: "Url de l'API" }, type: 'string', hint: { default: 'API endpoint' }, default: 'https://api.github.com/repos/locomotivecms/engine/issues?state=opened')
+ expect(subject[1]['label']).to eq('default' => 'Github')
+ 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', 'label' => { 'default' => 'API Url' }, 'type' => 'string', 'hint' => { 'default' => 'API endpoint' })
end
end
spec/unit/adapters/filesystem/yaml_loaders/site_spec.rb +1 -1
@@ @@ -19,7 +19,7 @@ describe Locomotive::Steam::Adapters::Filesystem::YAMLLoaders::Site do
subject { loader.load(nil).first[:metafields_schema] }
it 'loads the full schema' do
- expect(subject.count).to eq 2
+ expect(subject.count).to eq 3
end
end
spec/unit/liquid/drops/metafields_spec.rb +67 -0
@@ @@ -0,0 +1,67 @@
+ require 'spec_helper'
+
+ describe Locomotive::Steam::Liquid::Drops::Metafields do
+
+ let(:metafields) { { 'analytics_id' => { 'default' => '42' }, 'street' => { 'en' => '7 Albert Camus Alley', 'fr' => '7 allée Albert Camus' } } }
+ let(:schema) { [ { fields: [{ name: 'analytics_id' }] }, { fields: [{ name: 'street', localized: true }, { name: 'country' }] }].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 'calling a metafield' do
+
+ context 'unknown field' do
+
+ subject { drop.before_method(:unknown_field) }
+
+ it { is_expected.to eq nil }
+
+ end
+
+ context 'not localized field' do
+
+ context 'the value exists' do
+
+ subject { drop.before_method(:analytics_id) }
+
+ it { is_expected.to eq '42' }
+
+ end
+
+ context "the value doesn't exist" do
+
+ subject { drop.before_method(:country) }
+
+ it { is_expected.to eq nil }
+
+ end
+
+ end
+
+ context 'localized field' do
+
+ subject { drop.before_method(:street) }
+
+ it { is_expected.to eq '7 Albert Camus Alley' }
+
+ context 'in another locale' do
+
+ let(:context) { ::Liquid::Context.new({}, {}, { locale: 'fr' }) }
+
+ it { is_expected.to eq '7 allée Albert Camus' }
+
+ end
+
+ context 'in a locale with no translation' do
+
+ let(:context) { ::Liquid::Context.new({}, {}, { locale: 'de' }) }
+
+ it { is_expected.to eq nil }
+
+ end
+
+ end
+
+ end
+
+ end