class Locomotive::Steam::Adapters::Filesystem::YAMLLoaders::Page

Public Instance Methods

load(scope) click to toggle source

Basically Load all the pages from both the app/views/pages and data/<env>/pages folders

The process of loading locally all the pages is pretty complex. Of course, it handles localized pages. It involves 2 main steps.

1/ load all the pages/layouts under app/views/pages. Because of legacy support, we still grab the data from the YAML header.

2/ load the localized content from the data/<env>/pages folder. The content is fetched from the Wagon sync command. 2 kind of pages are stored in this folder:

- pages with a not null handle property. We call them core pages. They are not aimed
  to be deleted. When found, we merge their content with the original page found by process #1
- pages without a handle and created from a layout. These pages don't own a liquid template.
  We just use the liquid template of the layout they belong to.
# File lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb, line 26
def load(scope)
  super

  @pages_by_fullpath  = {}
  @pages_by_handle    = {}

  # step #1 (cf description of the method)
  load_tree

  # step #2 (cf description of the method)
  load_data

  @pages_by_fullpath.values
end

Private Instance Methods

build(filepath, fullpath, locale) click to toggle source
# File lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb, line 107
def build(filepath, fullpath, locale)
  slug            = fullpath.split('/').last
  attributes      = get_attributes(filepath, fullpath)

  # use first the attributes of the liquid template
  _attributes = {
    title:              { locale => attributes.delete(:title) || (default_locale == locale ? slug.humanize : nil) },
    slug:               { locale => attributes.delete(:slug) || slug.dasherize },
    template_path:      { locale => template_path(filepath, attributes, locale) },
    editable_elements:  build_editable_elements(attributes.delete(:editable_elements), locale),
    _fullpath:          fullpath
  }

  %i(
    redirect_url seo_title meta_description meta_keywords
    sections_content sections_dropzone_content
  ).each do |name|
    _attributes[name] = { locale => attributes.delete(name) }
  end

  _attributes.merge!(attributes)
end
build_editable_element(name, content, locale) click to toggle source
# File lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb, line 237
def build_editable_element(name, content, locale)
  segments    = name.to_s.split('/')
  block, slug = segments[0..-2].join('/'), segments.last
  block       = nil if block.blank?

  { block: block, slug: slug, content: { locale => content } }
end
build_editable_elements(list, locale) click to toggle source
# File lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb, line 211
def build_editable_elements(list, locale)
  return [] if list.blank?

  list.map do |name, content|
    build_editable_element(name, content, locale)
  end
end
complete_attributes_from_data(attributes, data, locale) click to toggle source
# File lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb, line 80
def complete_attributes_from_data(attributes, data, locale)
  return if attributes.nil? # shouldn't happen (undeleted page? local files out of date?)

  # this is super important to handle correctly url type settings in sections
  attributes[:_id] = data['id']

  # required by pages which are not present locally
  attributes[:_fullpath] = data['fullpath']

  # set the attributes
  %i(
    title slug redirect_url seo_title meta_description meta_keywords
    listed published position
    sections_content sections_dropzone_content editable_elements raw_template
  ).each do |name|
    next if (value = data[name.to_s]).nil?

    if name == :editable_elements
      update_editable_elements(attributes, value, locale)
    elsif %i(listed published position).include?(name)
      attributes[name] = value
    elsif name != :raw_template || (name == :raw_template && data['handle'].blank?)
      (attributes[name] ||= {})[locale] = value
    end
  end
end
data_path() click to toggle source
# File lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb, line 251
def data_path
  File.join(self.site_path, 'data', env.to_s, 'pages')
end
each_directory() { |filepath, fullpath, to_sym| ... } click to toggle source
# File lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb, line 185
def each_directory(&block)
  Dir.glob(File.join(path, '**', '*')).each do |filepath|
    next unless File.directory?(filepath)

    fullpath = get_relative_path(filepath)

    yield(filepath, fullpath, default_locale.to_sym)
  end
end
each_file() { |filepath, fullpath, to_sym| ... } click to toggle source
# File lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb, line 171
def each_file(&block)
  Dir.glob(File.join(path, '**', '*')).each do |filepath|
    next unless is_liquid_file?(filepath)

    relative_path = get_relative_path(filepath)

    fullpath, extension_or_locale = relative_path.split('.')[0..1]

    locale = template_extensions.include?(extension_or_locale) ? default_locale : extension_or_locale

    yield(filepath, fullpath, locale.to_sym)
  end
end
find_editable_element(leaf, name) click to toggle source
# File lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb, line 231
def find_editable_element(leaf, name)
  leaf[:editable_elements].find do |el|
    [el[:block], el[:slug]].join('/') == name.to_s
  end
end
get_attributes(filepath, fullpath) click to toggle source
# File lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb, line 150
def get_attributes(filepath, fullpath)
  if File.directory?(filepath)
    {
      title:          File.basename(filepath).humanize,
      listed:         false,
      published:      false
    }
  else
    _load(filepath, true) do |attributes, template|
      # make sure index/404 are the slugs of the index/404 pages
      attributes.delete(:slug) if %w(index 404).include?(fullpath)

      # trick to use the template of the default locale (if available)
      attributes[:template_path] = false if template.blank?

      # page under layouts/ should be treated differently
      set_layout_attributes(attributes) if fullpath.split('/').first == 'layouts'
    end
  end
end
get_relative_path(filepath) click to toggle source
# File lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb, line 207
def get_relative_path(filepath)
  filepath.gsub(path, '').gsub(/^\//, '')
end
is_liquid_file?(filepath) click to toggle source
# File lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb, line 195
def is_liquid_file?(filepath)
  filepath =~ /\.(#{template_extensions.join('|')})$/
end
load_data() click to toggle source
# File lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb, line 61
def load_data
  Dir.glob(File.join(data_path, '**', '*.json')).each do |filepath|
    filepath  =~ /#{data_path}\/([a-z]+)\//
    data      = safe_json_file_load(filepath)
    locale    = $1.to_sym

    next unless locales.include?($1.to_sym)

    if data['handle'].present? # yeah, core page found!
      attributes = @pages_by_handle[data['handle']]
    else
      @pages_by_fullpath[data['fullpath']] ||= {}
      attributes = @pages_by_fullpath[data['fullpath']]
    end

    complete_attributes_from_data(attributes, data, locale)
  end
end
load_tree() click to toggle source
# File lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb, line 43
def load_tree
  # load the core pages and layouts from the app/views/pages folder
  each_file do |filepath, fullpath, locale|
    if leaf = @pages_by_fullpath[fullpath]
      update(leaf, filepath, fullpath, locale)
    else
      leaf = build(filepath, fullpath, locale)
    end

    @pages_by_fullpath[fullpath]    = leaf
    @pages_by_handle[leaf[:handle]] = leaf if leaf[:handle].present?
  end

  each_directory do |filepath, fullpath, locale|
    @pages_by_fullpath[fullpath] ||= build(filepath, fullpath, locale)
  end
end
path() click to toggle source
# File lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb, line 255
def path
  @path ||= File.join(site_path, 'app', 'views', 'pages')
end
set_layout_attributes(attributes) click to toggle source
# File lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb, line 245
def set_layout_attributes(attributes)
  attributes[:is_layout]  = true if attributes[:is_layout].nil?
  attributes[:listed]     = false
  attributes[:published]  = false
end
template_path(filepath, attributes, locale) click to toggle source
# File lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb, line 199
def template_path(filepath, attributes, locale)
  if File.directory?(filepath) || (attributes.delete(:template_path) == false && locale != default_locale)
    false
  else
    filepath
  end
end
update(leaf, filepath, fullpath, locale) click to toggle source
# File lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb, line 130
def update(leaf, filepath, fullpath, locale)
  slug            = fullpath.split('/').last
  attributes      = get_attributes(filepath, fullpath)

  leaf[:title][locale]              ||= attributes.delete(:title) || slug.humanize
  leaf[:slug][locale]               ||= attributes.delete(:slug) || slug.dasherize
  leaf[:template_path][locale]      = template_path(filepath, attributes, locale)

  update_editable_elements(leaf, attributes.delete(:editable_elements), locale)

  %i(
    redirect_url seo_title meta_description meta_keywords
    sections_content sections_dropzone_content
  ).each do |name|
    leaf[name][locale] ||= attributes.delete(name)
  end

  leaf.merge!(attributes)
end
update_editable_elements(leaf, list, locale) click to toggle source
# File lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb, line 219
def update_editable_elements(leaf, list, locale)
  return if list.blank?

  list.each do |name, content|
    if el = find_editable_element(leaf, name)
      el[:content][locale] ||= content
    else
      leaf[:editable_elements] << build_editable_element(name, content, locale)
    end
  end
end