2018-01-29 22:19:10 +00:00
|
|
|
# frozen_string_literal: true
|
|
|
|
require 'jekyll/utils'
|
|
|
|
|
|
|
|
# Esta clase representa un post en un sitio jekyll e incluye métodos
|
|
|
|
# para modificarlos y crear nuevos
|
2018-02-03 22:37:09 +00:00
|
|
|
#
|
|
|
|
# Cuando estamos editando un post, instanciamos este modelo y le
|
|
|
|
# asociamos el Jekyll::Document correspondiente.
|
|
|
|
#
|
|
|
|
# Cuando estamos creando un post, no creamos su Jekyll::Document
|
|
|
|
# hasta que se guardan los datos, porque para poder guardarlo
|
|
|
|
# necesitamos su front_matter completo.
|
|
|
|
#
|
|
|
|
# El front matter está duplicado. El Post mantiene una copia de los
|
|
|
|
# datos y los sincroniza al momento de leer y de escribir el Document.
|
2018-01-29 22:19:10 +00:00
|
|
|
class Post
|
|
|
|
attr_accessor :content, :front_matter
|
2018-05-11 20:00:45 +00:00
|
|
|
attr_reader :post, :site, :errors, :old_post, :lang, :template,
|
|
|
|
:template_fields
|
2018-01-29 22:19:10 +00:00
|
|
|
|
2018-02-03 22:37:09 +00:00
|
|
|
REJECT_FROM_DATA = %w[excerpt].freeze
|
|
|
|
# datos que no tienen que terminar en el front matter
|
|
|
|
REJECT_FROM_FRONT_MATTER = %w[date slug draft ext].freeze
|
2018-05-11 20:00:45 +00:00
|
|
|
# datos que no traemos del template
|
|
|
|
REJECT_FROM_TEMPLATE = %w[date draft categories layout title ext tags date slug].freeze
|
|
|
|
|
2018-01-29 22:19:10 +00:00
|
|
|
|
|
|
|
# Trabajar con posts. Si estamos creando uno nuevo, el **site** y
|
|
|
|
# el **front_matter** son necesarios, sino, **site** y **post**.
|
|
|
|
# XXX chequear que se den las condiciones
|
2018-05-08 21:57:11 +00:00
|
|
|
def initialize(site:, post: nil, front_matter: {}, lang: nil, template: nil)
|
2018-02-03 22:37:09 +00:00
|
|
|
unless site.is_a?(Site)
|
|
|
|
raise ArgumentError,
|
|
|
|
I18n.t('errors.argument_error', argument: :site, class: Site)
|
|
|
|
end
|
|
|
|
|
|
|
|
unless post.nil? || post.is_a?(Jekyll::Document)
|
|
|
|
raise ArgumentError,
|
|
|
|
I18n.t('errors.argument_error', argument: :post,
|
|
|
|
class: Jekyll::Document)
|
|
|
|
end
|
2018-02-02 22:20:31 +00:00
|
|
|
|
2018-01-29 22:19:10 +00:00
|
|
|
@site = site
|
|
|
|
@post = post
|
2018-05-08 21:57:11 +00:00
|
|
|
@template = template
|
2018-01-31 20:29:27 +00:00
|
|
|
# los errores tienen que ser un hash para que
|
|
|
|
# ActiveModel pueda traer los errores normalmente
|
|
|
|
@errors = {}
|
2018-01-29 22:19:10 +00:00
|
|
|
|
2018-02-23 19:20:51 +00:00
|
|
|
# Si el sitio está traducido, trabajamos con la colección del
|
|
|
|
# idioma, sino, con posts
|
|
|
|
if @site.i18n?
|
|
|
|
@collection = @lang = lang || I18n.locale.to_s
|
|
|
|
else
|
|
|
|
@collection = 'posts'
|
|
|
|
end
|
|
|
|
|
2018-02-03 22:37:09 +00:00
|
|
|
# sincronizar los datos del document
|
|
|
|
if new?
|
2018-05-08 21:57:11 +00:00
|
|
|
@front_matter = front_matter_from_template
|
2018-02-03 22:37:09 +00:00
|
|
|
update_attributes front_matter
|
|
|
|
else
|
|
|
|
load_front_matter!
|
|
|
|
merge_with_front_matter! front_matter.stringify_keys
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# Limpiar los errores
|
|
|
|
def reset_errors!
|
|
|
|
@errors = {}
|
2018-01-29 22:19:10 +00:00
|
|
|
end
|
|
|
|
|
2018-02-03 22:37:09 +00:00
|
|
|
# El post es nuevo si no hay un documento asociado
|
2018-01-29 22:19:10 +00:00
|
|
|
def new?
|
2018-02-03 22:37:09 +00:00
|
|
|
@post.nil? || !File.exist?(@post.try(:path))
|
2018-01-29 22:19:10 +00:00
|
|
|
end
|
|
|
|
|
2018-04-27 18:48:26 +00:00
|
|
|
# El número de orden del artículo, si no tiene uno, se le asigna la
|
|
|
|
# posición en la colección de artículos
|
|
|
|
def order
|
|
|
|
get_front_matter 'order'
|
|
|
|
end
|
|
|
|
|
2018-04-27 18:59:51 +00:00
|
|
|
def ordered?
|
2018-04-27 18:48:26 +00:00
|
|
|
!order.nil?
|
|
|
|
end
|
|
|
|
|
2018-02-22 19:01:11 +00:00
|
|
|
# Determina si fue traducido, buscando los slugs de su front_matter
|
|
|
|
# lang en otras colecciones
|
|
|
|
def translated?
|
2018-02-23 19:20:51 +00:00
|
|
|
@site.i18n? && get_front_matter('lang').present?
|
2018-02-22 19:01:11 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def translations
|
2018-02-24 21:24:11 +00:00
|
|
|
@translations ||= find_translations
|
|
|
|
end
|
|
|
|
|
|
|
|
def find_translations
|
2018-02-26 18:58:56 +00:00
|
|
|
slugs = get_front_matter('lang')
|
|
|
|
return [] unless slugs.present?
|
|
|
|
|
|
|
|
slugs.map do |lang, id|
|
2018-02-22 19:01:11 +00:00
|
|
|
next if lang == @lang
|
|
|
|
@site.posts_for(lang).find do |p|
|
|
|
|
p.id == id
|
|
|
|
end
|
|
|
|
end.compact
|
|
|
|
end
|
|
|
|
|
2018-02-03 22:37:09 +00:00
|
|
|
# Guarda los cambios.
|
|
|
|
#
|
|
|
|
# Recién cuando vamos a guardar creamos el Post, porque ya tenemos
|
|
|
|
# todos los datos para escribir el archivo, que es la condición
|
|
|
|
# necesaria para poder crearlo :P
|
2018-01-29 22:19:10 +00:00
|
|
|
def save
|
2018-02-03 22:37:09 +00:00
|
|
|
cleanup!
|
|
|
|
|
|
|
|
return false unless valid?
|
|
|
|
|
|
|
|
new_post if new?
|
2018-01-29 22:19:10 +00:00
|
|
|
|
|
|
|
return unless write
|
|
|
|
return unless detect_file_rename!
|
|
|
|
|
|
|
|
# Vuelve a leer el post para tomar los cambios
|
|
|
|
@post.read
|
2018-02-03 22:37:09 +00:00
|
|
|
add_post_to_site!
|
2018-01-29 22:19:10 +00:00
|
|
|
true
|
|
|
|
end
|
|
|
|
alias :save! :save
|
|
|
|
|
|
|
|
def title
|
2018-02-03 22:37:09 +00:00
|
|
|
get_front_matter 'title'
|
2018-01-29 22:19:10 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def date
|
2018-02-03 22:37:09 +00:00
|
|
|
get_front_matter 'date'
|
2018-01-29 22:19:10 +00:00
|
|
|
end
|
|
|
|
|
2018-02-24 21:24:11 +00:00
|
|
|
def date_as_string
|
|
|
|
date.strftime('%F')
|
|
|
|
end
|
|
|
|
|
2018-01-29 22:19:10 +00:00
|
|
|
def tags
|
2018-05-08 21:33:15 +00:00
|
|
|
get_front_matter('tags') || []
|
2018-01-29 22:19:10 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def categories
|
2018-05-08 21:33:15 +00:00
|
|
|
get_front_matter('categories') || []
|
2018-01-29 22:19:10 +00:00
|
|
|
end
|
|
|
|
alias :category :categories
|
|
|
|
|
2018-02-03 22:37:09 +00:00
|
|
|
# Devuelve la ruta del post, si se cambió alguno de los datos,
|
|
|
|
# generamos una ruta nueva para tener siempre la ruta actualizada.
|
2018-01-29 22:19:10 +00:00
|
|
|
def path
|
2018-02-23 19:20:51 +00:00
|
|
|
if basename_changed?
|
|
|
|
File.join(@site.path, "_#{@collection}", basename_from_front_matter)
|
|
|
|
else
|
|
|
|
@post.try(:path)
|
|
|
|
end
|
2018-01-29 22:19:10 +00:00
|
|
|
end
|
|
|
|
|
2018-02-03 22:37:09 +00:00
|
|
|
# TODO los slugs se pueden repetir, el identificador real sería
|
|
|
|
# fecha+slug, pero se ve feo en las urls?
|
2018-01-29 22:19:10 +00:00
|
|
|
def id
|
2018-02-03 22:37:09 +00:00
|
|
|
get_front_matter 'slug'
|
2018-01-29 22:19:10 +00:00
|
|
|
end
|
|
|
|
alias :slug :id
|
|
|
|
alias :to_s :id
|
|
|
|
|
|
|
|
def basename_changed?
|
2018-02-03 22:37:09 +00:00
|
|
|
@post.try(:basename) != basename_from_front_matter
|
2018-01-30 15:20:19 +00:00
|
|
|
end
|
|
|
|
|
2018-02-24 21:24:11 +00:00
|
|
|
def slug_changed?
|
2018-05-02 18:38:46 +00:00
|
|
|
new? || @post.data.dig('slug') != slug
|
2018-02-24 21:24:11 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Trae el contenido del post, si no lo seteamos ya. O sea que si solo
|
|
|
|
# enviamos actualizaciones al front matter, debería traer el contenido
|
|
|
|
# del post sin cambios
|
2018-01-30 15:20:19 +00:00
|
|
|
def content
|
2018-05-14 19:27:29 +00:00
|
|
|
@content ||= @post.try(:content) || template.try(:content)
|
2018-02-02 22:20:31 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# imita Model.update_attributes de ActiveRecord
|
|
|
|
def update_attributes(attrs)
|
2018-02-03 22:37:09 +00:00
|
|
|
# el cuerpo se maneja por separado
|
|
|
|
@content = attrs.delete('content') if attrs.key? 'content'
|
|
|
|
merge_with_front_matter! attrs.stringify_keys
|
|
|
|
end
|
|
|
|
|
|
|
|
# Requisitos para que el post sea válido
|
|
|
|
def validate
|
2018-02-24 21:24:11 +00:00
|
|
|
add_error validate: I18n.t('posts.errors.date') unless date.is_a? Time
|
|
|
|
add_error validate: I18n.t('posts.errors.title') if title.blank?
|
2018-02-03 22:37:09 +00:00
|
|
|
# TODO verificar que el id sea único
|
|
|
|
end
|
|
|
|
|
|
|
|
def valid?
|
|
|
|
reset_errors!
|
|
|
|
validate
|
|
|
|
|
|
|
|
@errors.empty?
|
|
|
|
end
|
|
|
|
|
|
|
|
# Permite ordenar los posts
|
|
|
|
def <=>(other)
|
|
|
|
@post <=> other.post
|
2018-01-30 15:20:19 +00:00
|
|
|
end
|
|
|
|
|
2018-02-08 14:05:05 +00:00
|
|
|
# Obtiene metadatos asegurándose que siempre trabajamos con strings
|
|
|
|
def get_front_matter(name)
|
|
|
|
@front_matter.dig(name.to_s)
|
|
|
|
end
|
|
|
|
|
2018-05-14 19:27:29 +00:00
|
|
|
# Trae el template a partir del layout
|
|
|
|
def template_from_layout
|
|
|
|
@site.templates.find do |t|
|
|
|
|
t.get_front_matter('slug') == get_front_matter('layout')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-05-11 20:00:45 +00:00
|
|
|
def template_fields
|
2018-05-14 19:27:29 +00:00
|
|
|
@template_fields ||= template.front_matter.reject do |key, _|
|
2018-05-11 20:00:45 +00:00
|
|
|
REJECT_FROM_TEMPLATE.include? key
|
|
|
|
end.keys
|
|
|
|
end
|
|
|
|
|
2018-05-14 21:45:52 +00:00
|
|
|
# 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
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-05-11 20:00:45 +00:00
|
|
|
# Obtiene el tipo de campo para la plantilla
|
|
|
|
def template_form_type_for(field)
|
2018-05-14 19:27:29 +00:00
|
|
|
return if (tt = template.get_front_matter(field)).nil?
|
2018-05-11 20:00:45 +00:00
|
|
|
|
|
|
|
case
|
|
|
|
when tt == 'string'
|
|
|
|
type = 'text'
|
|
|
|
when tt == 'text'
|
|
|
|
type = 'text_area'
|
2018-05-17 18:42:35 +00:00
|
|
|
when tt.is_a?(String) && tt.split('/', 2).count == 2
|
|
|
|
type = 'select'
|
2018-05-11 20:00:45 +00:00
|
|
|
when tt.is_a?(Array)
|
|
|
|
type = 'select'
|
|
|
|
when tt.is_a?(FalseClass) || tt.is_a?(TrueClass)
|
|
|
|
type = 'check_box'
|
|
|
|
end
|
|
|
|
|
|
|
|
type
|
|
|
|
end
|
|
|
|
|
2018-05-14 19:27:29 +00:00
|
|
|
def template_multiple_values?(field)
|
|
|
|
template.get_front_matter(field).is_a? Array
|
|
|
|
end
|
|
|
|
|
2018-05-11 20:00:45 +00:00
|
|
|
# Obtiene los valores posibles para el campo de la plantilla
|
|
|
|
def template_values_for(field)
|
2018-05-14 19:27:29 +00:00
|
|
|
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
|
2018-05-11 20:00:45 +00:00
|
|
|
end
|
|
|
|
|
2018-01-29 22:19:10 +00:00
|
|
|
private
|
|
|
|
|
2018-05-08 21:57:11 +00:00
|
|
|
# Completa el front_matter a partir de las variables de otro
|
|
|
|
def front_matter_from_template
|
2018-05-14 19:27:29 +00:00
|
|
|
return {} unless template
|
2018-05-08 21:57:11 +00:00
|
|
|
|
2018-05-11 15:12:23 +00:00
|
|
|
# Convertimos el slug en layout
|
2018-05-14 19:27:29 +00:00
|
|
|
ft = template.front_matter.dup
|
2018-05-11 15:12:23 +00:00
|
|
|
ft['layout'] = ft.delete('slug')
|
|
|
|
|
|
|
|
ft
|
2018-05-08 21:57:11 +00:00
|
|
|
end
|
|
|
|
|
2018-02-03 22:37:09 +00:00
|
|
|
# Genera un post nuevo y lo agrega a la colección del sitio.
|
2018-01-29 22:19:10 +00:00
|
|
|
def new_post
|
2018-02-23 19:20:51 +00:00
|
|
|
opts = { site: @site.jekyll, collection: @site.jekyll.collections[@collection] }
|
2018-02-02 22:20:31 +00:00
|
|
|
@post = Jekyll::Document.new(path, opts)
|
2018-02-03 22:37:09 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Solo agregar el post al sitio una vez que lo guardamos
|
|
|
|
#
|
|
|
|
# TODO no sería la forma correcta de hacerlo en Rails
|
|
|
|
def add_post_to_site!
|
2018-02-23 19:20:51 +00:00
|
|
|
@site.jekyll.collections[@collection].docs << @post
|
|
|
|
@site.jekyll.collections[@collection].docs.sort!
|
2018-01-29 22:19:10 +00:00
|
|
|
|
2018-02-23 19:20:51 +00:00
|
|
|
unless @site.collections[@collection].include? self
|
|
|
|
@site.collections[@collection] << self
|
|
|
|
@site.collections[@collection].sort!
|
|
|
|
end
|
2018-01-29 22:19:10 +00:00
|
|
|
end
|
|
|
|
|
2018-02-03 22:37:09 +00:00
|
|
|
# Los define, asegurandose que las llaves siempre son strings, para no
|
|
|
|
# tener incompatibilidades con jekyll
|
|
|
|
def set_front_matter(name, value)
|
|
|
|
@front_matter[name.to_s] = value
|
2018-01-29 22:19:10 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Cambiar el nombre del archivo si cambió el título o la fecha.
|
|
|
|
# Como Jekyll no tiene métodos para modificar un Document, lo
|
|
|
|
# engañamos eliminando la instancia de @post y recargando otra.
|
|
|
|
def detect_file_rename!
|
|
|
|
return true unless basename_changed?
|
2018-02-03 22:37:09 +00:00
|
|
|
# No eliminamos el archivo a menos que ya exista el reemplazo!
|
|
|
|
return false unless File.exist? path
|
2018-01-29 22:19:10 +00:00
|
|
|
|
2018-02-03 22:37:09 +00:00
|
|
|
Rails.logger.info I18n.t('posts.logger.rm', path: path)
|
|
|
|
FileUtils.rm @post.path
|
|
|
|
replace_post!
|
2018-01-29 22:19:10 +00:00
|
|
|
end
|
|
|
|
|
2018-02-03 22:37:09 +00:00
|
|
|
# Reemplaza el post en el sitio por uno nuevo
|
|
|
|
def replace_post!
|
2018-02-23 19:20:51 +00:00
|
|
|
@old_post = @site.jekyll.collections[@lang].docs.delete @post
|
2018-01-29 22:19:10 +00:00
|
|
|
|
|
|
|
new_post
|
|
|
|
end
|
|
|
|
|
|
|
|
# Obtiene el nombre del archivo a partir de los datos que le
|
|
|
|
# pasemos
|
|
|
|
def basename_from_front_matter
|
2018-02-24 21:24:11 +00:00
|
|
|
ext = get_front_matter('ext') || '.markdown'
|
2018-01-29 22:19:10 +00:00
|
|
|
|
2018-02-24 21:24:11 +00:00
|
|
|
"#{date_as_string}-#{slug}#{ext}"
|
2018-01-29 22:19:10 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Toma los datos del front matter local y los mueve a los datos
|
|
|
|
# que van a ir al post. Si hay símbolos se convierten a cadenas,
|
2018-02-02 22:20:31 +00:00
|
|
|
# porque Jekyll trabaja con cadenas. Se excluyen otros datos que no
|
|
|
|
# van en el frontmatter
|
2018-02-03 22:37:09 +00:00
|
|
|
def merge_with_front_matter!(params)
|
|
|
|
@front_matter.merge! Hash[params.to_hash.map do |k, v|
|
|
|
|
[k, v] unless REJECT_FROM_DATA.include? k
|
2018-02-02 22:20:31 +00:00
|
|
|
end.compact]
|
2018-01-29 22:19:10 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Carga una copia de los datos del post original excluyendo datos
|
|
|
|
# que no nos interesan
|
2018-02-03 22:37:09 +00:00
|
|
|
def load_front_matter!
|
|
|
|
@front_matter = @post.data.reject do |key, _|
|
2018-01-29 22:19:10 +00:00
|
|
|
REJECT_FROM_DATA.include? key
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-02-03 22:37:09 +00:00
|
|
|
def cleanup!
|
|
|
|
things_to_arrays!
|
|
|
|
date_to_time!
|
|
|
|
clean_content!
|
|
|
|
slugify_title!
|
2018-02-19 20:17:52 +00:00
|
|
|
remove_empty_front_matter!
|
2018-02-24 21:24:11 +00:00
|
|
|
update_lang_front_matter!
|
|
|
|
update_translations!
|
2018-05-02 18:38:46 +00:00
|
|
|
put_in_order!
|
2018-02-24 21:24:11 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Setea el propio idioma en el front_matter de slugs
|
|
|
|
def update_lang_front_matter!
|
|
|
|
return unless translated?
|
|
|
|
|
|
|
|
@front_matter['lang'][@lang] = slug
|
|
|
|
end
|
|
|
|
|
|
|
|
# Busca las traducciones y actualiza el frontmatter si es necesario
|
|
|
|
def update_translations!
|
|
|
|
return unless translated?
|
|
|
|
return unless slug_changed?
|
|
|
|
|
|
|
|
find_translations.each do |post|
|
|
|
|
post.update_attributes(lang: get_front_matter('lang'))
|
|
|
|
post.save
|
|
|
|
end
|
2018-02-19 20:17:52 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def remove_empty_front_matter!
|
|
|
|
@front_matter.delete_if do |k,v|
|
|
|
|
v.blank?
|
|
|
|
end
|
2018-02-03 22:37:09 +00:00
|
|
|
end
|
|
|
|
|
2018-01-29 22:19:10 +00:00
|
|
|
# Aplica limpiezas básicas del contenido
|
|
|
|
def clean_content!
|
2018-02-03 22:37:09 +00:00
|
|
|
@content.try(:delete!, "\r")
|
2018-01-29 22:19:10 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Guarda los cambios en el archivo destino
|
|
|
|
def write
|
2018-02-03 22:37:09 +00:00
|
|
|
r = File.open(path, File::RDWR | File::CREAT, 0o640) do |f|
|
2018-01-29 22:19:10 +00:00
|
|
|
# Bloquear el archivo para que no sea accedido por otro
|
|
|
|
# proceso u otra editora
|
|
|
|
f.flock(File::LOCK_EX)
|
|
|
|
|
|
|
|
# Empezar por el principio
|
|
|
|
f.rewind
|
|
|
|
|
|
|
|
# Escribir
|
|
|
|
f.write(full_content)
|
|
|
|
|
|
|
|
# Eliminar el resto
|
|
|
|
f.flush
|
|
|
|
f.truncate(f.pos)
|
|
|
|
end
|
|
|
|
|
|
|
|
return true if r.zero?
|
|
|
|
|
2018-02-02 22:20:31 +00:00
|
|
|
add_error file: I18n.t('posts.errors.file')
|
2018-01-29 22:19:10 +00:00
|
|
|
false
|
|
|
|
end
|
|
|
|
|
2018-02-03 22:37:09 +00:00
|
|
|
# Genera el post con front matter, menos los campos que no necesitamos
|
2018-02-24 21:24:11 +00:00
|
|
|
# que estén en el front matter.
|
|
|
|
#
|
|
|
|
# El contenido se toma de `content` en lugar de `@content`, para poder
|
|
|
|
# obtener el contenido por defecto si es que no lo enviamos
|
|
|
|
# modificaciones, como en `update_translations!`
|
2018-01-29 22:19:10 +00:00
|
|
|
def full_content
|
2018-02-03 22:37:09 +00:00
|
|
|
yaml = @front_matter.reject do |k,_|
|
|
|
|
REJECT_FROM_FRONT_MATTER.include? k
|
|
|
|
end
|
|
|
|
|
2018-02-24 21:24:11 +00:00
|
|
|
"#{yaml.to_yaml}---\n\n#{content}"
|
2018-01-29 22:19:10 +00:00
|
|
|
end
|
2018-02-02 22:20:31 +00:00
|
|
|
|
|
|
|
def add_error(hash)
|
|
|
|
hash.each_pair do |k,i|
|
|
|
|
if @errors.key?(k)
|
|
|
|
@errors[k] = [@errors[k], i]
|
|
|
|
else
|
|
|
|
@errors[k] = i
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
@errors
|
|
|
|
end
|
2018-02-03 22:37:09 +00:00
|
|
|
|
|
|
|
def date_to_time!
|
|
|
|
unless @front_matter.dig(:date).is_a? Time
|
|
|
|
@front_matter['date'] = @front_matter.dig('date').try(:to_time) || Time.now
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def things_to_arrays!
|
|
|
|
[:tags,:categories].each do |c|
|
2018-02-03 23:41:02 +00:00
|
|
|
thing = @front_matter.dig(c.to_s)
|
2018-02-24 21:24:11 +00:00
|
|
|
next if thing.blank?
|
2018-02-03 23:41:02 +00:00
|
|
|
next if thing.is_a? Array
|
|
|
|
@front_matter[c.to_s] = thing.split(',').map(&:strip)
|
2018-02-03 22:37:09 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def slugify_title!
|
2018-02-24 21:24:11 +00:00
|
|
|
if slug.blank?
|
2018-02-03 22:37:09 +00:00
|
|
|
@front_matter['slug'] = Jekyll::Utils.slugify(title)
|
|
|
|
end
|
|
|
|
end
|
2018-05-02 18:38:46 +00:00
|
|
|
|
|
|
|
# Agregar al final de la cola si no especificamos un orden
|
|
|
|
#
|
|
|
|
# TODO si el artículo tiene una fecha que lo coloca en medio de
|
|
|
|
# la colección en lugar de al final, deberíamos reordenar?
|
|
|
|
def put_in_order!
|
|
|
|
return unless order.nil?
|
|
|
|
|
|
|
|
@front_matter['order'] = @site.posts_for(@collection).count
|
|
|
|
end
|
2018-01-29 22:19:10 +00:00
|
|
|
end
|