# frozen_string_literal: true # Representa la plantilla de un campo en los metadatos del artículo # # TODO: Validar el tipo de valor pasado a value= según el :type # # rubocop:disable Metrics/BlockLength MetadataTemplate = Struct.new(:site, :document, :name, :label, :type, :value, :help, :required, :errors, :post, :layout, keyword_init: true) do include ActionText::ContentHelper # El valor por defecto def default_value raise NotImplementedError end # Valores posibles, busca todos los valores actuales en otros # artículos del mismo sitio def values site.everything_of(name, lang: post.try(:lang).try(:value)) end # Valor actual o por defecto # # XXX: No estamos sanitizando la entrada, cada tipo tiene que # auto-sanitizarse. def value self[:value] || document.data.fetch(name.to_s, default_value) end # Detecta si el valor está vacío def empty? value.blank? end # Comprueba si el metadato es válido def valid? validate end def validate self.errors = [] errors << I18n.t("metadata.#{type}.cant_be_empty") unless can_be_empty? errors.empty? end def to_param name end # Decide si el metadato se coloca en el front_matter o no def front_matter? true end def array? type == 'array' end # En caso de que algún campo necesite realizar acciones antes de ser # guardado def save self[:value] = sanitize value true end private # Si es obligatorio no puede estar vacío def can_be_empty? true unless required && empty? end # No usamos sanitize_action_text_content porque espera un ActionText # # Ver ActionText::ContentHelper#sanitize_action_text_content def sanitize(string) return unless string return string unless string.is_a? String sanitizer.sanitize(string, tags: allowed_tags, attributes: allowed_attributes + %w[data-trix-attachment], scrubber: scrubber).strip.html_safe end end # rubocop:enable Metrics/BlockLength