autocompletar los valores #51

This commit is contained in:
f 2018-06-26 20:04:28 -03:00
parent 0afa42ede9
commit c26cca5fa0
No known key found for this signature in database
GPG key ID: F3FDAB97B5F9F7E7

View file

@ -183,6 +183,10 @@ class Post
contents.fetch('open', value.count < 2)
end
def closed?
!open?
end
# Determina si los valores del campo serán públicos después
#
# XXX Esto es solo una indicación, el theme Jekyll tiene que
@ -221,55 +225,82 @@ class Post
# Obtiene los valores posibles para el campo de la plantilla
def values
return '' if STRING_VALUES.include? value
# XXX por alguna razón `value` no refiere a value() :/
return '' if STRING_VALUES.include? self.value
# Las listas cerradas no necesitan mayor procesamiento
return self.value if array? && closed? && self.value.count > 1
# Y las vacías tampoco
return self.value if array? && self.value.empty?
# Ahorrarnos el trabajo
return @values if @values
# Duplicar el valor para no tener efectos secundarios luego (?)
value = self.value.dup
# 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
# tenemos que rellenarla con los valores que indica.
#
# El primer valor es el que trae la string de autocompletado
values = array? ? value.shift : value
# Si el valor es un array con más de un elemento, queremos usar
# esas opciones. Pero si además es abierto, queremos traer los
# valores cargados anteriormente.
# Procesamos el valor, buscando : como separador de campos que
# queremos encontrar y luego los unimos
_value = (values.try(:split, ':', 2) || []).map do |v|
# Tenemos hasta tres niveles de búsqueda
collection, attr, subattr = v.split('/', 3)
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)
# Si hay un subatributo, tenemos que averiguar todos los
# valores dentro de el
# TODO volver elegante!
elsif subattr
post.site.everything_of(attr, lang: collection)
.compact
.map { |sv| sv[subattr] }
.uniq
else
post.site.everything_of(attr, lang: collection).compact
end
end
# Procesar el valor
if values.is_a?(String)
value = values.split(':', 2).map do |v|
collection, attr, subattr = v.split('/', 3)
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)
# Si hay un subatributo, tenemos que averiguar todos los
# valores dentro de el
# TODO volver elegante!
elsif subattr
post.site.everything_of(attr, lang: collection).compact.map do |v|
tv = v.dig('value')
if tv.is_a? Array
tv.map do |sv|
sv[subattr]
end
else
tv.try :dig, subattr
end
end
else
post.site.everything_of(attr, lang: collection).compact
# Si el valor es abierto, sumar los valores auto-completados a
# lo pre-cargados.
#
# En este punto _value es un array de 1 o 2 arrays, si es de uno,
# value tambien tiene que serlo. Si es de 2, hay que unir cada
# una
if open?
if _value.count == 1
_value = [(_value.first + value).uniq]
elsif _value.count == 2
_value = _value.each_with_index.map do |v,i|
v + value[i]
end
end
values = value.last.zip value.first
end
# En última instancia, traer el valor por defecto
values
binding.pry if _value.last.nil?
# Crea un array de arrays, útil para los select
# [ [ 1, a ], [ 2, b ] ]
# aunque si no hay un : en el autocompletado, el array queda
# [ [ 1, 1 ], [ 2, 2 ] ]
values = _value.last.zip _value.first
# En última instancia, traer el valor por defecto y ahorrarnos
# volver a procesar
@values = values
end
end
end