BathHacked/energy-sparks

View on GitHub
app/services/template_interpolation.rb

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
require 'closed_struct'
require 'mobility/action_text'
require 'mustache'

class TemplateInterpolation
  def initialize(object, with_objects: {}, proxy: [], render_with: Mustache.new)
    @object = object
    @with_objects = with_objects
    @proxy = proxy
    @render_with = render_with
  end

  def interpolate(*fields, with: {})
    base_methods = { template_variables: with }.merge(@with_objects)
    with_proxied_objects = @proxy.inject(base_methods) do |collection, field|
      collection[field] = @object.send(field)
      collection
    end
    templated = fields.inject(with_proxied_objects) do |collection, field|
      template = @object.send(field) || ''
      collection[field] = case template
                          when ActionText::RichText, Mobility::Backends::ActionText::RichTextTranslation
                            process_rich_text_template(template, with)
                          else
                            process_string_template(template, with)
                          end
      collection
    end
    ClosedStruct.new(templated)
  end

  def variables(*fields)
    from_templates = fields.inject([]) do |variables, field|
      variables + get_variables(@object.send(field))
    end
    from_templates.uniq.map {|variable| variable.gsub('gbp', '£') }
  end

private

  def process_string_template(template, variables)
    @render_with.render(template, variables)
  end

  def process_rich_text_template(template, variables)
    # ActionText content wraps up content in a wrapper div, usually <div class="trix-content"></div>
    # fragment returns the content without the wrapper
    template_string = template.body ? template.body.fragment.to_s : ''
    template.body = ActionText::Content.new(process_string_template(template_string, variables))
    template
  end

  def get_variables(template)
    mustache = @render_with
    mustache.template = template_as_string(template)
    mustache.template.tags
  end

  def template_as_string(template)
    template.is_a?(ActionText::RichText) ? template.body.fragment.to_s : template
  end
end