module Cmor module Cms module DatabaseResolver # Include hook for class methods def self.included(base) base.extend(ClassMethods) end # class methods go here module ClassMethods end # instance methods go here def find_templates(name, prefix, partial, details, outside_app_allowed = false) return [] unless resolve(partial) conditions = { pathname: assert_slashs(prefix.to_s), basename: normalize_basename(name), locale: normalize_array(details[:locale]).first, format: normalize_array(details[:formats]).first, handler: normalize_array(details[:handlers]) } format = conditions.delete(:format) locale = conditions.delete(:locale) query = template_class.constantize.where(conditions) # 2) Check for templates with the given format or format is nil query = query.where(["format = ? OR format = '' OR format IS NULL", format]) # 3) Ensure templates with format come first query = query.order('format DESC') # 4) Check for templates with the given locale or locale is nil query = query.where(["locale = ? OR locale = '' OR locale IS NULL", locale]) # 5) Ensure templates with locale come first query = query.order('locale DESC') # 6) Now trigger the query passing on conditions to initialization query.map do |record| initialize_template(record, details) end end # Initialize an ActionView::Template object based on the record found. if Rails.version < '6.0' def initialize_template(record, details) source = build_source(record) identifier = "#{record.class} - #{record.id} - #{record.pathname}#{record.basename}" handler = ::ActionView::Template.registered_template_handler(record.handler) # 5) Check for the record.format, if none is given, try the template # handler format and fallback to the one given on conditions format = record.format && Mime[record.format] format ||= handler.default_format if handler.respond_to?(:default_format) format ||= details[:formats] details = { format: format, updated_at: record.updated_at, virtual_path: "#{record.pathname}#{record.basename}" } details[:layout] = record.layout if record.respond_to?(:layout) && record.layout.present? ::ActionView::Template.new(source, identifier, handler, details) end else def initialize_template(record, details) source = build_source(record) identifier = "#{record.class} - #{record.id} - #{record.pathname}#{record.basename}" handler = ::ActionView::Template.registered_template_handler(record.handler) virtual_path = "#{record.pathname}#{record.basename}" layout = record.layout if record.respond_to?(:layout) && record.layout.present? locals = [] # 5) Check for the record.format, if none is given, try the template # handler format and fallback to the one given on conditions format = record.format && Mime[record.format] format ||= handler.default_format if handler.respond_to?(:default_format) format ||= details[:formats] ::ActionView::Template.new(source, identifier, handler, format: format.symbol, virtual_path: virtual_path, layout: layout, locals: locals) end end def assert_slashs(prefix) output = prefix.dup output << '/' unless output.end_with?('/') output = '/' << output unless output.start_with?('/') output end # Normalize arrays by converting all symbols to strings. def normalize_array(array) array.map(&:to_s) end def build_source fail 'call to abstract method #build_source' end def normalize_basename(_basename) fail 'call to abstract method #normalize_basename' end def resolve(_partial_flag) fail 'call to abstract method #resolve' end def template_class fail 'call to abstract method #template_class' end end end end