# Representa los distintos tipos de campos que pueden venir de una # plantilla compleja class Post class TemplateField attr_reader :post, :contents, :key def initialize(post, key, contents) @post = post @key = key @contents = contents end # Obtiene el valor def value complex? ? contents.dig('value') : contents end def type return @type if @type case when text_area? @type = 'text_area' when string? @type = 'text' when string? && contents.split('/', 2).count == 2 @type = 'select' when array? @type = 'select' when boolean? @type = 'check_box' end @type end # El campo es requerido si es complejo y se especifica que lo sea def required? complex? && contents.dig('required') end def boolean? value.is_a?(FalseClass) || value.is_a?(TrueClass) end def string? value.is_a? String end def text_area? value == 'text' end # Si la plantilla es simple no está admitiendo Hashes como valores def simple? !complex? end def complex? contents.is_a? Hash end # XXX Retrocompatibilidad def to_s key end # Convierte el campo en un parámetro def to_param if array? { key.to_sym => [] } else key.to_sym end end def array? value.is_a? Array end # TODO detectar cuando es complejo y tomar el valor de :multiple def multiple? # si la plantilla es simple, es multiple cuando tenemos un array return array? if simple? array? && contents.fetch('multiple', true) end # Detecta si el valor es una tabla de campos def nested? value.is_a? Hash end # Un campo acepta valores abiertos si no es un array con múltiples # elementos def open? # Todos los valores simples son abiertos return true unless complex? return false unless array? # La cosa se complejiza cuando tenemos valores complejos # # Si tenemos una lista cerrada de valores, necesitamos saber si el # campo es abierto o cerrado. Si la lista tiene varios elementos, # es una lista cerrada, opcionalmente abierta. Si la lista tiene # un elemento, quiere decir que estamos autocompletando desde otro # lado. contents.fetch('open', value.count < 2) end def human h = key.humanize h = h + ' *' if required? h end # Obtiene los valores posibles para el campo de la plantilla def values return '' if %w[string text].include? value # Para obtener los valores posibles, hay que procesar la string y # convertirla a parametros # # XXX Prestar atención a no enviar metodos privados # Si es una array de un solo elemento, es un indicador de que # tenemos que rellenarla con los valores que indica if array? && value.count == 1 values = value.first else values = value end # Procesar el valor if values.is_a?(String) value = values.split(':', 2).map do |v| collection, attr = v.split('/', 2) if collection == 'site' # TODO puede ser peligroso permitir acceder a cualquier # atributo de site? No estamos trayendo nada fuera de # lo normal post.site.send(attr.to_sym) else post.site.everything_of(attr, lang: collection) end end values = value.last.zip value.first end # En última instancia, traer el valor por defecto values end end end