class Bridgetown::Resource::Transformer

Attributes

conversions[R]

@return [Array<Hash>]

resource[R]

@return [Bridgetown::Resource::Base]

site[R]

@return [Bridgetown::Site]

Public Class Methods

new(resource) click to toggle source
# File lib/bridgetown-core/resource/transformer.rb, line 15
def initialize(resource)
  @resource = resource
  @site = resource.site
  @conversions = []
end

Public Instance Methods

execute_inline_ruby!() click to toggle source
# File lib/bridgetown-core/resource/transformer.rb, line 41
def execute_inline_ruby!
  return unless site.config.should_execute_inline_ruby?

  Bridgetown::Utils::RubyExec.search_data_for_ruby_code(resource, self)
end
final_ext() click to toggle source

@return [String]

# File lib/bridgetown-core/resource/transformer.rb, line 27
def final_ext
  output_ext # we always need this to get run

  permalink_ext || output_ext
end
inspect() click to toggle source
# File lib/bridgetown-core/resource/transformer.rb, line 47
def inspect
  "#<#{self.class} Conversion Steps: #{conversions.length}>"
end
output_ext() click to toggle source

@return [String]

# File lib/bridgetown-core/resource/transformer.rb, line 22
def output_ext
  @output_ext ||= output_ext_from_converters
end
process!() click to toggle source
# File lib/bridgetown-core/resource/transformer.rb, line 33
def process!
  Bridgetown.logger.debug "Transforming:", resource.relative_path
  resource.around_hook :render do
    run_conversions
    resource.place_in_layout? ? place_into_layouts : resource.output = resource.content.dup
  end
end

Private Instance Methods

converters() click to toggle source

@return [Array<Bridgetown::Converter>]

# File lib/bridgetown-core/resource/transformer.rb, line 66
def converters
  @converters ||= site.matched_converters_for_convertible(resource)
end
output_ext_from_converters() click to toggle source

@return [String]

# File lib/bridgetown-core/resource/transformer.rb, line 71
def output_ext_from_converters
  @conversions = converters.map do |converter|
    {
      converter: converter,
      output_ext: converter.output_ext(resource.extname),
    }
  end

  conversions
    .reverse
    .find do |conversion|
      conversions.length == 1 ||
        !conversion[:converter].is_a?(Bridgetown::Converters::Identity)
    end
    .fetch(:output_ext)
end
place_into_layouts() click to toggle source
# File lib/bridgetown-core/resource/transformer.rb, line 141
def place_into_layouts
  Bridgetown.logger.debug "Placing in Layouts:", resource.relative_path
  output = resource.content.dup
  validated_layouts.each do |layout|
    output = run_layout_conversions layout, output
  end
  resource.output = output
end
run_conversions() click to toggle source

Transformation Actions

# File lib/bridgetown-core/resource/transformer.rb, line 114
def run_conversions # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  input = resource.content.to_s

  # @param content [String]
  # @param converter [Bridgetown::Converter]
  resource.content = converters.each_with_index.inject(input) do |content, (converter, index)|
    output = if converter.method(:convert).arity == 1
               converter.convert content
             else
               converter.convert content, resource
             end
    conversions[index] = {
      type: :content,
      converter: converter,
      output: Bridgetown.env.production? ? nil : output,
      output_ext: conversions[index]&.dig(:output_ext) ||
        converter.output_ext(resource.extname),
    }
    output.html_safe
  rescue StandardError => e
    Bridgetown.logger.error "Conversion error:",
                            "#{converter.class} encountered an error while "\
                            "converting `#{resource.relative_path}'"
    raise e
  end
end
run_layout_conversions(layout, output) click to toggle source
# File lib/bridgetown-core/resource/transformer.rb, line 150
def run_layout_conversions(layout, output)
  layout_converters = site.matched_converters_for_convertible(layout)
  layout_input = layout.content.dup

  layout_converters.inject(layout_input) do |content, converter|
    next(content) unless [2, -2].include?(converter.method(:convert).arity)

    layout.current_document = resource
    layout.current_document_output = output
    layout_output = converter.convert content, layout

    conversions << {
      type: :layout,
      layout: layout,
      converter: converter,
      output: Bridgetown.env.production? ? nil : layout_output,
    }
    layout_output
  rescue StandardError => e
    Bridgetown.logger.error "Conversion error:",
                            "#{converter.class} encountered an error while "\
                            "converting `#{resource.relative_path}'"
    raise e
  end
end
validated_layouts() click to toggle source

@return [Array<Bridgetown::Layout>]

# File lib/bridgetown-core/resource/transformer.rb, line 89
def validated_layouts
  layout = site.layouts[resource.data.layout]
  warn_on_missing_layout layout, resource.data.layout

  layout_list = Set.new([layout])
  while layout
    layout_name = layout.data.layout
    layout = site.layouts[layout_name]
    warn_on_missing_layout layout, layout_name

    layout_list << layout
  end

  layout_list.to_a.compact
end
warn_on_missing_layout(layout, layout_name) click to toggle source
# File lib/bridgetown-core/resource/transformer.rb, line 105
def warn_on_missing_layout(layout, layout_name)
  if layout.nil? && layout_name
    Bridgetown.logger.warn "Build Warning:", "Layout '#{layout_name}' " \
    "requested via #{resource.relative_path} does not exist."
  end
end