# frozen_string_literal: true module Archangel module Liquid module Tags ## # Asset custom tag for Liquid # # Example # {% asset 'my-asset.png' %} #=> # # {% asset 'my-asset.png' size:'medium' %} #=> # # {% asset 'my-asset.png' alt:'My image' class:'center' %} #=> # My image # class AssetTag < ApplicationTag include ::ActionView::Helpers::UrlHelper ## # Regex for tag key # KEY_SYNTAX = / #{::Liquid::QuotedString} | ( [\w-]+\.[\w]+ | #{::Liquid::QuotedString} ) /ox ## # Regex for tag syntax # SYNTAX = / (?#{KEY_SYNTAX}) \s* (?.*) \s* /omx ## # Regex for attributes # SYNTAX_ATTRIBUTES = / (?\w+) \s* \: \s* (?#{::Liquid::QuotedFragment}) /ox ## # Asset for Liquid # # @param tag_name [String] the Liquid tag name # @param markup [String] the passed options # @param options [Object] options # def initialize(tag_name, markup, options) super match = SYNTAX.match(markup) if match.blank? raise ::Liquid::SyntaxError, Archangel.t("errors.syntax.asset") end @key = ::Liquid::Variable.new(match[:key], options).name @attributes = {} build_attributes(match[:attributes]) end ## # Render the Asset # # @param context [Object] the Liquid context # @return [String] the rendered Asset # def render(context) return if key.blank? environments = context.environments[0] asset = load_asset_for(environments["site"]) return if asset.blank? asset_decider(asset) end protected attr_reader :attributes, :key, :size def build_attributes(attrs) attrs.scan(SYNTAX_ATTRIBUTES) do |key, value| @attributes[key.to_sym] = ::Liquid::Expression.parse(value) end size = attributes.fetch(:size, nil) @size = %w[small tiny].include?(size) ? size : nil @attributes.delete(:size) end def load_asset_for(site) site.assets.find_by!(file_name: key) rescue StandardError nil end def asset_decider(asset) if %r{image/[gif|jpeg|jpg|png]} =~ asset.content_type image_asset(asset) else linked_asset(asset) end end def image_asset(asset) params = { alt: asset.file_name }.merge(attributes).merge( src: sized_image_asset(asset.file) ).compact.reject { |_, value| value.blank? } tag("img", params) end def linked_asset(asset) options = attributes.compact.reject { |_, value| value.blank? } link_to(asset.file_name, asset.file.url, options) end def sized_image_asset(file) size.blank? ? file.url : file.send(size).url end end end end end ::Liquid::Template.register_tag("asset", Archangel::Liquid::Tags::AssetTag)