empezar a mover la logica de plantillas a su propio modelo
This commit is contained in:
parent
c0c0e060ce
commit
1bcb91b6ec
4 changed files with 150 additions and 79 deletions
|
@ -224,88 +224,20 @@ class Post
|
|||
|
||||
def template_fields
|
||||
return [] unless template
|
||||
@template_fields ||= template.front_matter.reject do |key, _|
|
||||
REJECT_FROM_TEMPLATE.include? key
|
||||
end.keys
|
||||
@template_fields ||= template.front_matter.map do |key, contents|
|
||||
next if REJECT_FROM_TEMPLATE.include? key
|
||||
|
||||
Post::TemplateField.new(self, key, contents)
|
||||
end.compact
|
||||
end
|
||||
|
||||
# devuelve las plantillas como strong params
|
||||
def template_params
|
||||
@template_params ||= template_fields.map do |k|
|
||||
v = template.get_front_matter(k)
|
||||
if v.is_a? Array
|
||||
{ k.to_sym => [] }
|
||||
else
|
||||
k.to_sym
|
||||
end
|
||||
k.to_param
|
||||
end
|
||||
end
|
||||
|
||||
# Obtiene el tipo de campo para la plantilla
|
||||
def template_form_type_for(field)
|
||||
return if (tt = template.get_front_matter(field)).nil?
|
||||
|
||||
case
|
||||
when tt == 'string'
|
||||
type = 'text'
|
||||
when tt == 'text'
|
||||
type = 'text_area'
|
||||
when tt.is_a?(String) && tt.split('/', 2).count == 2
|
||||
type = 'select'
|
||||
when tt.is_a?(Array)
|
||||
type = 'select'
|
||||
when tt.is_a?(FalseClass) || tt.is_a?(TrueClass)
|
||||
type = 'check_box'
|
||||
end
|
||||
|
||||
type
|
||||
end
|
||||
|
||||
def template_multiple_values?(field)
|
||||
template.get_front_matter(field).is_a? Array
|
||||
end
|
||||
|
||||
# Obtiene los valores posibles para el campo de la plantilla
|
||||
def template_values_for(field)
|
||||
return '' if %w[string text].include? template.get_front_matter(field)
|
||||
|
||||
# Para obtener los valores posibles, hay que procesar la string y
|
||||
# convertirla a parametros
|
||||
#
|
||||
# XXX Prestar atención a no enviar metodos privados
|
||||
|
||||
value = template.get_front_matter(field)
|
||||
|
||||
# Si es una array de un solo elemento, es un indicador de que
|
||||
# tenemos que rellenarla con los valores que indica
|
||||
if value.is_a?(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
|
||||
@site.send(attr.to_sym)
|
||||
else
|
||||
@site.everything_of(attr, lang: collection)
|
||||
end
|
||||
end
|
||||
|
||||
value = value.last.zip value.first
|
||||
end
|
||||
|
||||
# En última instancia, traer el valor por defecto
|
||||
value
|
||||
end
|
||||
|
||||
def template
|
||||
@template ||= template_from_layout
|
||||
end
|
||||
|
|
109
app/models/post/template_field.rb
Normal file
109
app/models/post/template_field.rb
Normal file
|
@ -0,0 +1,109 @@
|
|||
# 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
|
||||
|
||||
def type
|
||||
return @type if @type
|
||||
return unless simple?
|
||||
|
||||
case
|
||||
when contents == 'string'
|
||||
@type = 'text'
|
||||
when contents == 'text'
|
||||
@type = 'text_area'
|
||||
when contents.is_a?(String) && contents.split('/', 2).count == 2
|
||||
@type = 'select'
|
||||
when contents.is_a?(Array)
|
||||
@type = 'select'
|
||||
when contents.is_a?(FalseClass) || contents.is_a?(TrueClass)
|
||||
@type = 'check_box'
|
||||
end
|
||||
|
||||
@type
|
||||
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
|
||||
|
||||
def to_param
|
||||
if array?
|
||||
{ key.to_sym => [] }
|
||||
else
|
||||
key.to_sym
|
||||
end
|
||||
end
|
||||
|
||||
def array?
|
||||
@contents.is_a? Array
|
||||
end
|
||||
|
||||
# TODO detectar cuando es complejo y tomar el valor de :multiple
|
||||
def multiple?
|
||||
array?
|
||||
end
|
||||
|
||||
def value
|
||||
@contents
|
||||
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 value.is_a?(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
|
||||
|
||||
value = value.last.zip value.first
|
||||
end
|
||||
|
||||
# En última instancia, traer el valor por defecto
|
||||
value
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -76,11 +76,11 @@
|
|||
{ class: 'form-control select2' }
|
||||
%small.text-muted.form-text= t('posts.lang_help')
|
||||
- @post.template_fields.each do |template|
|
||||
- next unless type = @post.template_form_type_for(template)
|
||||
- next unless type = template.type
|
||||
.form-group
|
||||
= label_tag "post_#{template}", template.humanize
|
||||
= label_tag "post_#{template}", template.to_s.humanize
|
||||
- name = "post[#{template}]"
|
||||
- value = @post.new? ? @post.template_values_for(template) : @post.get_front_matter(template)
|
||||
- value = @post.new? ? template.values : @post.get_front_matter(template)
|
||||
- case type
|
||||
- when 'text'
|
||||
= text_field 'post', template,
|
||||
|
@ -92,8 +92,8 @@
|
|||
= hidden_field 'post', template, value: 'false'
|
||||
= check_box_tag name, 'true', value == 'true', class: 'form-control'
|
||||
- when 'select'
|
||||
= select_tag name, options_for_select(@post.template_values_for(template), @post.get_front_matter(template)),
|
||||
= select_tag name, options_for_select(template.values, @post.get_front_matter(template)),
|
||||
{ class: 'form-control select2',
|
||||
multiple: @post.template_multiple_values?(template) }
|
||||
multiple: template.multiple? }
|
||||
.form-group
|
||||
= submit_tag t('posts.save'), class: 'btn btn-success'
|
||||
|
|
|
@ -178,3 +178,33 @@ collections:
|
|||
|
||||
TODO: agregarlo especificamente en `app/models/site.rb` al cargar el
|
||||
sitio.
|
||||
|
||||
## Plantillas complejas
|
||||
|
||||
Algunas plantillas necesitan comportamientos más complejos, por ejemplo
|
||||
cuando un campo es requerido o no es público.
|
||||
|
||||
```
|
||||
campo:
|
||||
help: "Un texto de ayuda"
|
||||
public: false
|
||||
required: true
|
||||
value: {bool,string,text,array,url,email}
|
||||
min: 0
|
||||
max: 100
|
||||
multiple: false
|
||||
```
|
||||
|
||||
Ahora los `value` pueden estar anidados, es decir que dentro de cada
|
||||
value puede haber una serie de `campo` con los mismos valores.
|
||||
|
||||
Las plantillas más simples asumen ciertos valores por defecto:
|
||||
|
||||
```
|
||||
help: nil
|
||||
public: true
|
||||
required: false
|
||||
min: nil
|
||||
max: nil
|
||||
multiple: true
|
||||
```
|
||||
|
|
Loading…
Reference in a new issue