class Editmode::ChunkValue

Attributes

branch_id[RW]
cache_identifier[RW]
chunk_type[RW]
collection_id[RW]
content[W]
identifier[RW]
project_id[RW]
response[RW]
transformation[RW]
url[RW]
variable_fallbacks[RW]
variable_values[RW]

Public Class Methods

new(identifier, project_id: Editmode.project_id, **options) click to toggle source
# File lib/editmode/chunk_value.rb, line 16
def initialize(identifier, project_id: Editmode.project_id, **options)
  @identifier = identifier
  @branch_id = options[:branch_id].presence
  @project_id = project_id
  @referrer = options[:referrer].presence || ""
  @variable_values = options[:variables].presence || {}
  @raw = options[:raw].present?
  @skip_sanitize = options[:dangerously_skip_sanitization]
  @skip_cache = options[:skip_cache]
  @transformation = options[:transformation]

  @url = "#{api_root_url}/chunks/#{identifier}"
  @cache_identifier = set_cache_identifier(identifier)

  if options[:response].present?
    @response = options[:response]
    set_response_attributes!
  else
    get_content
  end
end

Public Instance Methods

cached?() click to toggle source
# File lib/editmode/chunk_value.rb, line 71
def cached?
  return false if @skip_cache
  Rails.cache.exist?(cache_identifier)
end
content() click to toggle source
# File lib/editmode/chunk_value.rb, line 64
def content
  raise "undefined method 'content' for chunk_type: collection_item \nDid you mean? field" if chunk_type == 'collection_item'

  result = variable_parse!(@content, variable_fallbacks, variable_values, @raw, @skip_sanitize)
  result.try(:html_safe)
end
field(field = nil) click to toggle source
# File lib/editmode/chunk_value.rb, line 38
def field(field = nil)
  # Field ID can be a slug or field_name
  if chunk_type == 'collection_item'
    if field.present?
      field_chunk = field_chunk(field)
      if field_chunk.present?
        result = field_chunk['chunk_type'] == 'image' ? set_transformation_properties!(field_chunk['content']) : field_chunk['content']
        result = variable_parse!(result, variable_fallbacks, variable_values, @raw, @skip_sanitize)
      else
        raise no_response_received(field)
      end
    else
      raise require_field_id
    end
  else
    raise "undefined method 'field` for chunk_type: #{chunk_type} \n"
  end
  result ||= @content
  result.try(:html_safe)
end
field_chunk(field) click to toggle source
# File lib/editmode/chunk_value.rb, line 59
def field_chunk(field)
  field.downcase!
  @content.detect {|f| f["custom_field_identifier"].downcase == field || f["custom_field_name"].downcase == field }
end

Private Instance Methods

allowed_tag_attributes() click to toggle source
# File lib/editmode/chunk_value.rb, line 91
def allowed_tag_attributes
  %w(style href title src alt width height class target)
end
api_root_url() click to toggle source

Todo: Transfer to helper utils

# File lib/editmode/chunk_value.rb, line 96
def api_root_url
  ENV["EDITMODE_OVERRIDE_API_URL"] || "https://api.editmode.com"
end
get_content() click to toggle source
# File lib/editmode/chunk_value.rb, line 140
def get_content
  if !cached?
    @response = HTTParty.get(url, query: query_params, headers: {referrer: @referrer})
    response_received = true if @response.code == 200
  end

  if !cached? && !response_received
    message = @response.try(:[], 'message') || no_response_received(identifier)

    raise message
  else
    Rails.cache.write(cache_identifier, @response.to_json) if @response.present?
    cached_response = Rails.cache.fetch(cache_identifier)

    if cached_response.present?
      @response = json?(cached_response) ? JSON.parse(cached_response) : cached_response
    end

    set_response_attributes!
  end
end
json?(json) click to toggle source
# File lib/editmode/chunk_value.rb, line 104
def json?(json)
  JSON.parse(json)
  return true
rescue JSON::ParserError => e
  return false
end
no_response_received(id = "") click to toggle source
# File lib/editmode/chunk_value.rb, line 171
def no_response_received(id = "")
  "Sorry, we can't find a chunk using this identifier: \"#{id}\". This can happen if you've deleted a chunk on editmode.com or if your local cache is out of date. If it persists, try running Rails.cache clear."
end
query_params() click to toggle source
# File lib/editmode/chunk_value.rb, line 133
def query_params
  the_params = { 'project_id' => project_id }
  the_params['branch_id'] = branch_id if branch_id.present?

  the_params
end
set_cache_identifier(id) click to toggle source
# File lib/editmode/chunk_value.rb, line 100
def set_cache_identifier(id)
  "chunk_#{project_id}#{branch_id}#{id}"
end
set_response_attributes!() click to toggle source
# File lib/editmode/chunk_value.rb, line 162
def set_response_attributes!
  @chunk_type = response['chunk_type']
  
  @content = @chunk_type == 'image' ? set_transformation_properties!(response['content']) : response['content'] 
  @variable_fallbacks = response['variable_fallbacks'].presence || {}
  @collection_id = response["collection"]["identifier"] if chunk_type == 'collection_item'
  @branch_id = response['branch_id']
end
set_transformation_properties!(url) click to toggle source
# File lib/editmode/chunk_value.rb, line 77
def set_transformation_properties!(url)
  if transformation.present? && url.present?
    transformation.gsub!(" ", ",")
    transformation.gsub!(/\s/, '')
  
    uri = URI(url)
    uri.query = [uri.query, "tr=#{transformation}"].compact.join("&")
    
    url = uri.to_s
  end

  url
end
variable_parse!(content, variables = {}, values = {}, raw = true, skip_sanitize=false) click to toggle source
# File lib/editmode/chunk_value.rb, line 111
def variable_parse!(content, variables = {}, values = {}, raw = true, skip_sanitize=false)
  tokens = content.scan(/\{{(.*?)\}}/)
  if tokens.any?
    tokens.flatten!
    tokens.each do |token|
      token_value = values[token.to_sym] || variables[token] || ""
      sanitized_value = ActionController::Base.helpers.sanitize(token_value)

      unless raw
        sanitized_value = content_tag("em-var", :data => {chunk_variable: token, chunk_variable_value: sanitized_value}) do
          sanitized_value
        end
      end

      content.gsub!("{{#{token}}}", sanitized_value)
    end
  end

  content = ActionController::Base.helpers.sanitize(content, attributes: allowed_tag_attributes) unless skip_sanitize
  return content
end