5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2024-06-02 06:14:16 +00:00

la estructura de un artículo

This commit is contained in:
f 2019-08-06 14:54:17 -03:00
parent b4877baa47
commit 3b46600ed5
No known key found for this signature in database
GPG key ID: 2AE5A13E321F953D
7 changed files with 161 additions and 0 deletions

4
app/models/layout.rb Normal file
View file

@ -0,0 +1,4 @@
# frozen_string_literal: true
# Una plantilla agrupa metadatos que va a tener un artículo
Layout = Struct.new(:site, :name, :metadata, keyword_init: true)

View file

@ -0,0 +1,9 @@
# frozen_string_literal: true
# Una lista de valores
class MetadataArray < MetadataTemplate
# El valor por defecto es una array vacía
def default_value
[]
end
end

View file

@ -0,0 +1,8 @@
# frozen_string_literal: true
# Devuelve metadatos de cierto tipo
class MetadataFactory
def self.build(**args)
"Metadata#{args[:type].camelcase}".constantize.new(args)
end
end

View file

@ -0,0 +1,13 @@
# frozen_string_literal: true
# Define un campo de imagen
class MetadataImage < MetadataTemplate
# Una ruta vacía a la imagen con una descripción vacía
def default_value
{ path: '', description: '' }
end
def empty?
value == default_value
end
end

View file

@ -0,0 +1,9 @@
# frozen_string_literal: true
# Un campo de texto
class MetadataString < MetadataTemplate
# Una string vacía
def default_value
''
end
end

View file

@ -0,0 +1,22 @@
# frozen_string_literal: true
# Representa la plantilla de un campo en los metadatos del artículo
MetadataTemplate = Struct.new(:site, :document, :name, :label, :type,
:value, :help, :required,
keyword_init: true) do
# 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.to_s)
end
# Valor actual o por defecto
def value
super || document.data.dig(name.to_s, default_value)
end
end

96
doc/posts.md Normal file
View file

@ -0,0 +1,96 @@
# Posts
Los posts no corresponden con un modelo en la base de datos, porque se
nos va a complicar sincronizar los datos con el repositorio.
## Jekyll
Como en Jekyll, los artículos son archivos con el siguiente formato:
* Ubicación: _lang/ en lugar de guardar los archivos en _posts, usamos
i18n y guardamos cada uno en el directorio de su propio idioma.
* Nombre: el nombre del archivo contiene la fecha en formato aaaa-mm-dd,
seguidos de un guión, el título en minúsculas y con los espacios
convertidos en guiones. La extensión es .markdown.
Esto también funciona como identificador único.
* Metadatos: Los metadatos del artículo se vuelcan en formato YAML al
principio del archivo, el bloque comienza y termina con tres guiones
("---") en líneas separadas
* Contenido: El contenido del artículo va a continuación de los
metadatos, en formato Markdown
## I18n
Todos los artículos están listos para ser traducidos. Esto ya no es
opcional como antes porque nos genera muchos casos especiales.
La i18n incluye una lista de los nombres de archivo que identifican a
los posts en otros idiomas, para intervincularlos.
## Plantillas de metadatos
Todos los campos de la sección de metadatos son plantillas, incluso para
los artículos, hay una plantilla por defecto con los campos más comunes.
Esto nos permite adaptar distintos tipos de artículos y unificar todo el
desarrollo en una sola lógica.
El sitio contiene una descripción de todas las plantillas. Cuando se
crea un artículo del tipo correspondiente con la plantilla, el artículo
hereda todas las plantillas como atributos y valida la presencia de los
obligatorios y los tipos de datos incorporados.
## Archivos
El nombre de la plantilla de metadatos corresponde con una plantilla
HTML:
```bash
_data/templates/post.yml
_layouts/post.html
```
Al crear el artículo, el metadato `layout:` se completa con el nombre de
la plantilla. Todavía no tenemos un método para cambiar un artículo de
plantilla, ya que requiriría recargar todos los campos.
## Implementación
La clase `MetadataTemplate` representa los valores posibles de un
metadato abstracto. Cada tipo de valor específico tiene su
`MetadataType` donde `Type` es el tipo de metadato. Esto
permite que cada tipo sepa como cargar sus valores por defecto y demás.
La clase `Template` contiene un hash de `{ campo: MetadataTemplate }`.
Su nombre es el nombre de la plantilla.
`Site#templates` contiene un hash de `{ nombre: Template }` para
búsqueda rápida.
`Post#template` es el `Site#templates[:template]` correspondiente.
`Post` es un tipo de `OpenStruct` que valida los valores contra las
plantillas de `Post#template`. Además, puede obtener valores por
defecto. Para esto, se lo construye con el sitio y plantilla. A partir
de esto se generan los `MetadataType` correspondientes, que son
los capaces de generar sus propios valores por defecto.
De dónde obtienen los valores actuales los `MetadataType`?
Cada atributo es una instancia de `PostMetadataType`.
`Post#title` trae el título desde los metadatos leídos o el título por
defecto. `Post#title.values` trae los valores posibles.
Los `Post` se generan desde `Site#posts` que es una relación, al estilo
ActiveRecord.
Al instanciar un `Post`, se pasan el sitio y la plantilla por defecto.
## TODO
* Leer artículos a medida que se los necesita en lugar de todos juntos.