class ComfortableMexicanSofa::Seeds::Page::Importer

Attributes

target_pages[RW]

tracking target page linking. Since we might be linking to something that doesn't exist yet, we'll defer linking to the end of import

Public Class Methods

new(from, to = from) click to toggle source
# File lib/comfortable_mexican_sofa/seeds/page/importer.rb, line 10
def initialize(from, to = from)
  super
  self.path = ::File.join(ComfortableMexicanSofa.config.seeds_path, from, "pages/")
end

Public Instance Methods

import!() click to toggle source
# File lib/comfortable_mexican_sofa/seeds/page/importer.rb, line 15
def import!
  import_page(File.join(path, "index/"), nil)

  link_target_pages

  # Remove pages not found in seeds
  site.pages.where("id NOT IN (?)", seed_ids).destroy_all
end

Private Instance Methods

construct_fragments_attributes(hash, record, path) click to toggle source

Constructing frag attributes hash that can be assigned to page or translation also returning list of frag identifiers so we can destroy old ones

# File lib/comfortable_mexican_sofa/seeds/page/importer.rb, line 154
def construct_fragments_attributes(hash, record, path)
  frag_identifiers = []
  frag_attributes = hash.collect do |frag_header, frag_content|
    tag, identifier = frag_header.split
    frag_hash = {
      identifier: identifier,
      tag:        tag
    }

    # tracking fragments that need removing later
    frag_identifiers << identifier

    # based on tag we need to cram content in proper place and proper format
    case tag
    when "date", "datetime"
      frag_hash[:datetime] = frag_content
    when "checkbox"
      frag_hash[:boolean] = frag_content
    when "file", "files"
      files, file_ids_destroy = files_content(record, identifier, path, frag_content)
      frag_hash[:files]            = files
      frag_hash[:file_ids_destroy] = file_ids_destroy
    else
      frag_hash[:content] = frag_content
    end

    frag_hash
  end

  [frag_identifiers, frag_attributes]
end
files_content(record, identifier, path, frag_content) click to toggle source

Preparing fragment attachments. Returns hashes with file data for ActiveStorage and a list of ids of old attachements to destroy

# File lib/comfortable_mexican_sofa/seeds/page/importer.rb, line 188
def files_content(record, identifier, path, frag_content)
  # preparing attachments
  files = frag_content.split("\n").collect do |filename|
    file_handler = File.open(File.join(path, filename))
    {
      io:           file_handler,
      filename:     filename,
      content_type: MimeMagic.by_magic(file_handler)
    }
  end

  # ensuring that old attachments get removed
  ids_destroy = []
  if (frag = record.fragments.find_by(identifier: identifier))
    ids_destroy = frag.attachments.pluck(:id)
  end

  [files, ids_destroy]
end
import_page(path, parent) click to toggle source

Recursive function that will be called for each child page (subfolder)

# File lib/comfortable_mexican_sofa/seeds/page/importer.rb, line 27
def import_page(path, parent)
  slug = path.split("/").last

  # setting page record
  page =
    if parent.present?
      child = site.pages.where(slug: slug).first_or_initialize
      child.parent = parent
      child
    else
      site.pages.root || site.pages.new(slug: slug)
    end

  content_path = File.join(path, "content.html")

  # If file is newer than page record we'll process it
  if fresh_seed?(page, content_path)

    # reading file content in, resulting in a hash
    fragments_hash  = parse_file_content(content_path)

    # parsing attributes section
    attributes_yaml = fragments_hash.delete("attributes")
    attrs           = YAML.safe_load(attributes_yaml)

    # applying attributes
    layout = site.layouts.find_by(identifier: attrs.delete("layout")) || parent.try(:layout)
    category_ids    = category_names_to_ids(page, attrs.delete("categories"))
    target_page     = attrs.delete("target_page")

    page.attributes = attrs.merge(
      layout: layout,
      category_ids: category_ids
    )

    # applying fragments
    old_frag_identifiers = page.fragments.pluck(:identifier)

    new_frag_identifiers, fragments_attributes =
      construct_fragments_attributes(fragments_hash, page, path)
    page.fragments_attributes = fragments_attributes

    if page.save
      message = "[CMS SEEDS] Imported Page \t #{page.full_path}"
      ComfortableMexicanSofa.logger.info(message)

      # defering target page linking
      if target_page.present?
        self.target_pages ||= {}
        self.target_pages[page.id] = target_page
      end

      # cleaning up old fragments
      page.fragments.where(identifier: old_frag_identifiers - new_frag_identifiers).destroy_all

    else
      message = "[CMS SEEDS] Failed to import Page \n#{page.errors.inspect}"
      ComfortableMexicanSofa.logger.warn(message)
    end
  end

  import_translations(path, page)

  # Tracking what page from seeds we're working with. So we can remove pages
  # that are no longer in seeds
  seed_ids << page.id

  # importing child pages (if there are any)
  Dir["#{path}*/"].each do |page_path|
    import_page(page_path, page)
  end
end
import_translations(path, page) click to toggle source

Importing translations for given page. They look like `content.locale.html`

# File lib/comfortable_mexican_sofa/seeds/page/importer.rb, line 101
def import_translations(path, page)
  old_translations = page.translations.pluck(:locale)
  new_translations = []

  Dir["#{path}content.*.html"].each do |file_path|
    locale = File.basename(file_path).match(%r{content\.(\w+)\.html})[1]
    new_translations << locale

    translation = page.translations.where(locale: locale).first_or_initialize

    next unless fresh_seed?(translation, file_path)

    # reading file content in, resulting in a hash
    fragments_hash  = parse_file_content(file_path)

    # parsing attributes section
    attributes_yaml = fragments_hash.delete("attributes")
    attrs           = YAML.safe_load(attributes_yaml)

    # applying attributes
    layout = site.layouts.find_by(identifier: attrs.delete("layout")) || page.try(:layout)
    translation.attributes = attrs.merge(
      layout: layout
    )

    # applying fragments
    old_frag_identifiers = translation.fragments.pluck(:identifier)

    new_frag_identifiers, fragments_attributes =
      construct_fragments_attributes(fragments_hash, translation, path)
    translation.fragments_attributes = fragments_attributes

    if translation.save
      message = "[CMS SEEDS] Imported Translation \t #{locale}"
      ComfortableMexicanSofa.logger.info(message)

      # cleaning up old fragments
      frags_to_remove = old_frag_identifiers - new_frag_identifiers
      translation.fragments.where(identifier: frags_to_remove).destroy_all

    else
      message = "[CMS SEEDS] Failed to import Translation \n#{locale}"
      ComfortableMexicanSofa.logger.warn(message)
    end
  end

  # Cleaning up removed translations
  translations_to_remove = old_translations - new_translations
  page.translations.where(locale: translations_to_remove).destroy_all
end