mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-15 07:01:42 +00:00
escribir articulos nuevos y modificar los que existen
This commit is contained in:
parent
2fcc631548
commit
b83528cd96
11 changed files with 249 additions and 114 deletions
|
@ -10,6 +10,22 @@ class PostsController < ApplicationController
|
||||||
@post = find_post(@site)
|
@post = find_post(@site)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@site = find_site
|
||||||
|
@post = Post.new(site: @site, front_matter: { date: Time.now })
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@site = find_site
|
||||||
|
@post = Post.new(site: @site, front_matter: post_params.to_hash)
|
||||||
|
|
||||||
|
if @post.save
|
||||||
|
redirect_to site_posts_path(@site)
|
||||||
|
else
|
||||||
|
render 'posts/new'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
@site = find_site
|
@site = find_site
|
||||||
@post = find_post(@site)
|
@post = find_post(@site)
|
||||||
|
@ -20,12 +36,8 @@ class PostsController < ApplicationController
|
||||||
@site = find_site
|
@site = find_site
|
||||||
@post = find_post(@site)
|
@post = find_post(@site)
|
||||||
|
|
||||||
# crear un array a partir de una cadena separada por comas
|
|
||||||
[:tags,:categories].each do |comma|
|
|
||||||
p[comma] = p.dig(comma).split(',').map(&:strip)
|
|
||||||
end
|
|
||||||
|
|
||||||
@post.update_attributes(p)
|
@post.update_attributes(p)
|
||||||
|
|
||||||
if @post.save
|
if @post.save
|
||||||
redirect_to site_post_path(@site, @post)
|
redirect_to site_post_path(@site, @post)
|
||||||
else
|
else
|
||||||
|
|
|
@ -3,119 +3,180 @@ require 'jekyll/utils'
|
||||||
|
|
||||||
# Esta clase representa un post en un sitio jekyll e incluye métodos
|
# Esta clase representa un post en un sitio jekyll e incluye métodos
|
||||||
# para modificarlos y crear nuevos
|
# para modificarlos y crear nuevos
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
class Post
|
class Post
|
||||||
attr_accessor :content, :front_matter
|
attr_accessor :content, :front_matter
|
||||||
attr_reader :post, :site, :errors
|
attr_reader :post, :site, :errors, :old_post
|
||||||
|
|
||||||
REJECT_FROM_DATA = %w[excerpt slug draft date ext].freeze
|
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
|
||||||
|
|
||||||
# Trabajar con posts. Si estamos creando uno nuevo, el **site** y
|
# Trabajar con posts. Si estamos creando uno nuevo, el **site** y
|
||||||
# el **front_matter** son necesarios, sino, **site** y **post**.
|
# el **front_matter** son necesarios, sino, **site** y **post**.
|
||||||
# XXX chequear que se den las condiciones
|
# XXX chequear que se den las condiciones
|
||||||
def initialize(site:, post: nil, front_matter: {})
|
def initialize(site:, post: nil, front_matter: {})
|
||||||
raise ArgumentError, I18n.t('posts.errors.site') unless site.is_a?(Site)
|
unless site.is_a?(Site)
|
||||||
raise ArgumentError, I18n.t('posts.errors.post') unless post.is_a?(Jekyll::Document)
|
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
|
||||||
|
|
||||||
@site = site
|
@site = site
|
||||||
@post = post
|
@post = post
|
||||||
# los errores tienen que ser un hash para que
|
# los errores tienen que ser un hash para que
|
||||||
# ActiveModel pueda traer los errores normalmente
|
# ActiveModel pueda traer los errores normalmente
|
||||||
@errors = {}
|
@errors = {}
|
||||||
@front_matter = front_matter
|
|
||||||
|
|
||||||
# Crea un post nuevo si no especificamos el post
|
# sincronizar los datos del document
|
||||||
new_post unless @post
|
if new?
|
||||||
load_data! unless new?
|
@front_matter = {}
|
||||||
|
update_attributes front_matter
|
||||||
|
else
|
||||||
|
load_front_matter!
|
||||||
|
merge_with_front_matter! front_matter.stringify_keys
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Si el archivo destino no existe, el post es nuevo
|
# Limpiar los errores
|
||||||
|
def reset_errors!
|
||||||
|
@errors = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
# El post es nuevo si no hay un documento asociado
|
||||||
def new?
|
def new?
|
||||||
!File.exist? @post.path
|
@post.nil? || !File.exist?(@post.try(:path))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Guarda los cambios
|
# 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
|
||||||
def save
|
def save
|
||||||
merge_data_with_front_matter!
|
cleanup!
|
||||||
clean_content!
|
|
||||||
|
return false unless valid?
|
||||||
|
|
||||||
|
new_post if new?
|
||||||
|
|
||||||
return unless write
|
return unless write
|
||||||
return unless detect_file_rename!
|
return unless detect_file_rename!
|
||||||
|
|
||||||
# Vuelve a leer el post para tomar los cambios
|
# Vuelve a leer el post para tomar los cambios
|
||||||
@post.read
|
@post.read
|
||||||
|
add_post_to_site!
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
alias :save! :save
|
alias :save! :save
|
||||||
|
|
||||||
def title
|
def title
|
||||||
get_metadata 'title'
|
get_front_matter 'title'
|
||||||
end
|
end
|
||||||
|
|
||||||
def date
|
def date
|
||||||
get_metadata 'date'
|
get_front_matter 'date'
|
||||||
end
|
end
|
||||||
|
|
||||||
def tags
|
def tags
|
||||||
get_metadata 'tags'
|
get_front_matter 'tags'
|
||||||
end
|
end
|
||||||
|
|
||||||
def categories
|
def categories
|
||||||
get_metadata 'categories'
|
get_front_matter 'categories'
|
||||||
end
|
end
|
||||||
alias :category :categories
|
alias :category :categories
|
||||||
|
|
||||||
|
# Devuelve la ruta del post, si se cambió alguno de los datos,
|
||||||
|
# generamos una ruta nueva para tener siempre la ruta actualizada.
|
||||||
def path
|
def path
|
||||||
basename_changed? ? File.join(@site.path, '_posts', basename_from_front_matter) : @post.try(:path)
|
basename_changed? ? File.join(@site.path, '_posts', basename_from_front_matter) : @post.try(:path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# TODO los slugs se pueden repetir, el identificador real sería
|
||||||
|
# fecha+slug, pero se ve feo en las urls?
|
||||||
def id
|
def id
|
||||||
get_metadata 'slug'
|
get_front_matter 'slug'
|
||||||
end
|
end
|
||||||
alias :slug :id
|
alias :slug :id
|
||||||
alias :to_s :id
|
alias :to_s :id
|
||||||
|
|
||||||
def basename_changed?
|
def basename_changed?
|
||||||
@post.basename != basename_from_front_matter
|
@post.try(:basename) != basename_from_front_matter
|
||||||
end
|
|
||||||
|
|
||||||
def data
|
|
||||||
@post.data
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def content
|
def content
|
||||||
@content ||= @post.content
|
@content ||= @post.try :content
|
||||||
end
|
end
|
||||||
|
|
||||||
# imita Model.update_attributes de ActiveRecord
|
# imita Model.update_attributes de ActiveRecord
|
||||||
def update_attributes(attrs)
|
def update_attributes(attrs)
|
||||||
attrs.each_pair do |k,i|
|
# el cuerpo se maneja por separado
|
||||||
# el contenido no es metadata
|
@content = attrs.delete('content') if attrs.key? 'content'
|
||||||
if k == 'content'
|
merge_with_front_matter! attrs.stringify_keys
|
||||||
@content = i
|
|
||||||
else
|
|
||||||
set_metadata k.to_sym, i
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Requisitos para que el post sea válido
|
||||||
|
def validate
|
||||||
|
add_error validate: I18n.t('posts.errors.date') unless get_front_matter('date').is_a? Time
|
||||||
|
add_error validate: I18n.t('posts.errors.title') if get_front_matter('title').blank?
|
||||||
|
# TODO verificar que el id sea único
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def valid?
|
||||||
|
reset_errors!
|
||||||
|
validate
|
||||||
|
|
||||||
|
@errors.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
# Permite ordenar los posts
|
||||||
|
def <=>(other)
|
||||||
|
@post <=> other.post
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
# Genera un post nuevo y lo agrega a la colección del sitio.
|
||||||
def new_post
|
def new_post
|
||||||
opts = { site: @site, collection: @site.jekyll.posts }
|
opts = { site: @site.jekyll, collection: @site.jekyll.posts }
|
||||||
@post = Jekyll::Document.new(path, opts)
|
@post = Jekyll::Document.new(path, opts)
|
||||||
|
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!
|
||||||
@site.jekyll.posts.docs << @post
|
@site.jekyll.posts.docs << @post
|
||||||
@site.jekyll.posts.docs.sort!
|
@site.jekyll.posts.docs.sort!
|
||||||
|
|
||||||
@post
|
@site.posts << self unless @site.posts.include? self
|
||||||
|
@site.posts.sort!
|
||||||
end
|
end
|
||||||
|
|
||||||
# Obtiene metadatos
|
# Obtiene metadatos asegurándose que siempre trabajamos con strings
|
||||||
def get_metadata(name)
|
def get_front_matter(name)
|
||||||
@front_matter.key?(name) ? @front_matter.dig(name) : @post.data[name]
|
@front_matter.dig(name.to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_metadata(name, value)
|
# Los define, asegurandose que las llaves siempre son strings, para no
|
||||||
@front_matter[name] = value
|
# tener incompatibilidades con jekyll
|
||||||
|
def set_front_matter(name, value)
|
||||||
|
@front_matter[name.to_s] = value
|
||||||
end
|
end
|
||||||
|
|
||||||
# Cambiar el nombre del archivo si cambió el título o la fecha.
|
# Cambiar el nombre del archivo si cambió el título o la fecha.
|
||||||
|
@ -123,18 +184,17 @@ class Post
|
||||||
# engañamos eliminando la instancia de @post y recargando otra.
|
# engañamos eliminando la instancia de @post y recargando otra.
|
||||||
def detect_file_rename!
|
def detect_file_rename!
|
||||||
return true unless basename_changed?
|
return true unless basename_changed?
|
||||||
|
# No eliminamos el archivo a menos que ya exista el reemplazo!
|
||||||
|
return false unless File.exist? path
|
||||||
|
|
||||||
if File.exist? path
|
Rails.logger.info I18n.t('posts.logger.rm', path: path)
|
||||||
add_error path: I18n.t('posts.errors.path')
|
FileUtils.rm @post.path
|
||||||
return
|
replace_post!
|
||||||
end
|
end
|
||||||
|
|
||||||
FileUtils.mv @post.path, path
|
# Reemplaza el post en el sitio por uno nuevo
|
||||||
replace_post! path
|
def replace_post!
|
||||||
end
|
@old_post = @site.jekyll.posts.docs.delete @post
|
||||||
|
|
||||||
def replace_post!(path)
|
|
||||||
@site.jekyll.posts.docs.delete @post
|
|
||||||
|
|
||||||
new_post
|
new_post
|
||||||
end
|
end
|
||||||
|
@ -142,40 +202,47 @@ class Post
|
||||||
# Obtiene el nombre del archivo a partir de los datos que le
|
# Obtiene el nombre del archivo a partir de los datos que le
|
||||||
# pasemos
|
# pasemos
|
||||||
def basename_from_front_matter
|
def basename_from_front_matter
|
||||||
_date = @front_matter[:date]
|
date = get_front_matter('date').strftime('%F')
|
||||||
date = _date.respond_to?(:strftime) ? _date.strftime('%F') : _date
|
slug = get_front_matter('slug')
|
||||||
title = get_metadata 'slug' || Jekyll::Utils.slugify(@front_matter[:title])
|
slug =
|
||||||
ext = get_metadata 'ext' || '.markdown'
|
ext = get_front_matter('ext') || '.markdown'
|
||||||
|
|
||||||
"#{date}-#{title}#{ext}"
|
"#{date}-#{slug}#{ext}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Toma los datos del front matter local y los mueve a los datos
|
# 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,
|
# que van a ir al post. Si hay símbolos se convierten a cadenas,
|
||||||
# porque Jekyll trabaja con cadenas. Se excluyen otros datos que no
|
# porque Jekyll trabaja con cadenas. Se excluyen otros datos que no
|
||||||
# van en el frontmatter
|
# van en el frontmatter
|
||||||
def merge_data_with_front_matter!
|
def merge_with_front_matter!(params)
|
||||||
@data.merge! Hash[@front_matter.map do |k, v|
|
@front_matter.merge! Hash[params.to_hash.map do |k, v|
|
||||||
[k.to_s, v] unless REJECT_FROM_DATA.include? k
|
[k, v] unless REJECT_FROM_DATA.include? k
|
||||||
end.compact]
|
end.compact]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Carga una copia de los datos del post original excluyendo datos
|
# Carga una copia de los datos del post original excluyendo datos
|
||||||
# que no nos interesan
|
# que no nos interesan
|
||||||
def load_data!
|
def load_front_matter!
|
||||||
@data ||= @post.data.reject do |key, _|
|
@front_matter = @post.data.reject do |key, _|
|
||||||
REJECT_FROM_DATA.include? key
|
REJECT_FROM_DATA.include? key
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def cleanup!
|
||||||
|
things_to_arrays!
|
||||||
|
date_to_time!
|
||||||
|
clean_content!
|
||||||
|
slugify_title!
|
||||||
|
end
|
||||||
|
|
||||||
# Aplica limpiezas básicas del contenido
|
# Aplica limpiezas básicas del contenido
|
||||||
def clean_content!
|
def clean_content!
|
||||||
@content = @content.delete("\r")
|
@content.try(:delete!, "\r")
|
||||||
end
|
end
|
||||||
|
|
||||||
# Guarda los cambios en el archivo destino
|
# Guarda los cambios en el archivo destino
|
||||||
def write
|
def write
|
||||||
r = File.open(@post.path, File::RDWR | File::CREAT, 0o640) do |f|
|
r = File.open(path, File::RDWR | File::CREAT, 0o640) do |f|
|
||||||
# Bloquear el archivo para que no sea accedido por otro
|
# Bloquear el archivo para que no sea accedido por otro
|
||||||
# proceso u otra editora
|
# proceso u otra editora
|
||||||
f.flock(File::LOCK_EX)
|
f.flock(File::LOCK_EX)
|
||||||
|
@ -197,8 +264,14 @@ class Post
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Genera el post con front matter, menos los campos que no necesitamos
|
||||||
|
# que estén en el front matter
|
||||||
def full_content
|
def full_content
|
||||||
"#{@data.to_yaml}---\n\n#{@content}"
|
yaml = @front_matter.reject do |k,_|
|
||||||
|
REJECT_FROM_FRONT_MATTER.include? k
|
||||||
|
end
|
||||||
|
|
||||||
|
"#{yaml.to_yaml}---\n\n#{@content}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_error(hash)
|
def add_error(hash)
|
||||||
|
@ -212,4 +285,23 @@ class Post
|
||||||
|
|
||||||
@errors
|
@errors
|
||||||
end
|
end
|
||||||
|
|
||||||
|
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|
|
||||||
|
@front_matter[c.to_s] = @front_matter.dig(c.to_s).split(',').map(&:strip)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def slugify_title!
|
||||||
|
if get_front_matter('slug').blank?
|
||||||
|
title = get_front_matter('title')
|
||||||
|
@front_matter['slug'] = Jekyll::Utils.slugify(title)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -26,6 +26,8 @@ class Site
|
||||||
def posts
|
def posts
|
||||||
return @posts if @posts
|
return @posts if @posts
|
||||||
|
|
||||||
|
Rails.logger.info 'Procesando posts'
|
||||||
|
|
||||||
if @jekyll.posts.docs.empty?
|
if @jekyll.posts.docs.empty?
|
||||||
@jekyll.read
|
@jekyll.read
|
||||||
# Queremos saber cuantas veces releemos los articulos
|
# Queremos saber cuantas veces releemos los articulos
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
- unless @post.errors.empty?
|
- unless @post.errors.empty?
|
||||||
.alert.alert-danger
|
.alert.alert-danger
|
||||||
%ul
|
%ul
|
||||||
- @post.errors.each do |error|
|
- @post.errors.each do |_,error|
|
||||||
%li= error
|
%li= error
|
||||||
|
|
||||||
= form_tag site_post_path(@site, @post), method: :patch, class: 'form' do
|
-# TODO habilitar form_for
|
||||||
|
- if @post.new?
|
||||||
|
- url = site_posts_path(@site)
|
||||||
|
- method = :post
|
||||||
|
- else
|
||||||
|
- url = site_post_path(@site, @post)
|
||||||
|
- method = :patch
|
||||||
|
= form_tag url, method: method, class: 'form' do
|
||||||
.form-group
|
.form-group
|
||||||
= submit_tag t('posts.save'), class: 'btn btn-success'
|
= submit_tag t('posts.save'), class: 'btn btn-success'
|
||||||
.form-group
|
.form-group
|
||||||
|
@ -12,20 +19,21 @@
|
||||||
placeholder: t('posts.title')
|
placeholder: t('posts.title')
|
||||||
.form-group
|
.form-group
|
||||||
= text_area_tag 'post[content]', @post.content, autofocus: true,
|
= text_area_tag 'post[content]', @post.content, autofocus: true,
|
||||||
class: 'form-control post-content', data: { provide: 'markdown' }
|
class: 'form-control post-content', data: { provide: 'markdown' },
|
||||||
|
cols: 72, wrap: 'hard'
|
||||||
.form-group
|
.form-group
|
||||||
= label_tag 'post_date', t('posts.date')
|
= label_tag 'post_date', t('posts.date')
|
||||||
= date_field 'post', 'date', value: @post.date.strftime('%F'),
|
= date_field 'post', 'date', value: @post.date.try(:strftime, '%F'),
|
||||||
class: 'form-control'
|
class: 'form-control'
|
||||||
%small.text-muted.form-text= t('posts.date_help')
|
%small.text-muted.form-text= t('posts.date_help')
|
||||||
.form-group
|
.form-group
|
||||||
= label_tag 'post_categories', t('posts.categories')
|
= label_tag 'post_categories', t('posts.categories')
|
||||||
= text_field 'post', 'categories', value: @post.categories.join(', '),
|
= text_field 'post', 'categories', value: @post.categories.try(:join, ', '),
|
||||||
class: 'form-control'
|
class: 'form-control'
|
||||||
%small.text-muted.form-text= t('posts.tags_help')
|
%small.text-muted.form-text= t('posts.tags_help')
|
||||||
.form-group
|
.form-group
|
||||||
= label_tag 'post_tags', t('posts.tags')
|
= label_tag 'post_tags', t('posts.tags')
|
||||||
= text_field 'post', 'tags', value: @post.tags.join(', '),
|
= text_field 'post', 'tags', value: @post.tags.try(:join, ', '),
|
||||||
class: 'form-control'
|
class: 'form-control'
|
||||||
%small.text-muted.form-text= t('posts.tags_help')
|
%small.text-muted.form-text= t('posts.tags_help')
|
||||||
.form-group
|
.form-group
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
.container-fluid
|
.row
|
||||||
.row
|
|
||||||
%h1
|
|
||||||
= t('posts.editing')
|
|
||||||
= @post.title
|
|
||||||
|
|
||||||
.row
|
|
||||||
.col
|
.col
|
||||||
= render 'posts/form'
|
= render 'posts/form'
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
%h1= @site.name
|
.row
|
||||||
|
.col
|
||||||
|
%h1= @site.name
|
||||||
|
|
||||||
%table.table.table-condensed.table-striped
|
.row
|
||||||
|
.col
|
||||||
|
= link_to t('posts.new'), new_site_post_path(@site),
|
||||||
|
class: 'btn btn-success'
|
||||||
|
|
||||||
|
.row
|
||||||
|
.col
|
||||||
|
%table.table.table-condensed.table-striped
|
||||||
%tbody
|
%tbody
|
||||||
- @site.posts.each do |post|
|
- @site.posts.each do |post|
|
||||||
%tr
|
%tr
|
||||||
|
|
3
app/views/posts/new.haml
Normal file
3
app/views/posts/new.haml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
.row
|
||||||
|
.col
|
||||||
|
= render 'posts/form'
|
|
@ -1,17 +1,21 @@
|
||||||
.row
|
.row
|
||||||
|
.col
|
||||||
%h1= @post.title
|
%h1= @post.title
|
||||||
|
|
||||||
|
.row
|
||||||
|
.col
|
||||||
= link_to t('posts.edit'), edit_site_post_path(@site, @post),
|
= link_to t('posts.edit'), edit_site_post_path(@site, @post),
|
||||||
class: 'btn btn-info'
|
class: 'btn btn-info'
|
||||||
|
|
||||||
|
.row
|
||||||
|
.col
|
||||||
.content
|
.content
|
||||||
:markdown
|
:markdown
|
||||||
#{@post.content}
|
#{@post.content}
|
||||||
|
|
||||||
%table.table.table-condensed.table-striped
|
%table.table.table-condensed.table-striped
|
||||||
%tbody
|
%tbody
|
||||||
- @post.data.each do |key, data|
|
- @post.front_matter.each do |key, data|
|
||||||
%tr
|
%tr
|
||||||
%th= key
|
%th= key
|
||||||
%td
|
%td
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
en:
|
en:
|
||||||
|
errors:
|
||||||
|
argument_error: 'Argument `%{argument}` must be an instance of %{class}'
|
||||||
login:
|
login:
|
||||||
email: 'E-mail'
|
email: 'E-mail'
|
||||||
password: 'Password'
|
password: 'Password'
|
||||||
|
@ -19,8 +21,11 @@ en:
|
||||||
categories_help: 'Comma separated!'
|
categories_help: 'Comma separated!'
|
||||||
slug: 'Slug'
|
slug: 'Slug'
|
||||||
slug_help: 'This is the name of the article on the URL, ie. /title/. You can leave it empty.'
|
slug_help: 'This is the name of the article on the URL, ie. /title/. You can leave it empty.'
|
||||||
|
logger:
|
||||||
|
rm: 'Removed %{path}'
|
||||||
errors:
|
errors:
|
||||||
site: 'Argument `site` must be of class Site'
|
|
||||||
post: 'Argument `post` must be of class Post'
|
|
||||||
path: 'File already exist'
|
path: 'File already exist'
|
||||||
file: "Couldn't write the file"
|
file: "Couldn't write the file"
|
||||||
|
title: 'Post needs a title'
|
||||||
|
date: 'Post needs a valid date'
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
es:
|
es:
|
||||||
|
errors:
|
||||||
|
argument_error: 'El argumento `%{argument}` debe ser una instancia de %{class}'
|
||||||
login:
|
login:
|
||||||
email: 'Dirección de correo'
|
email: 'Dirección de correo'
|
||||||
password: 'Contraseña'
|
password: 'Contraseña'
|
||||||
|
@ -17,6 +19,10 @@ es:
|
||||||
categories_help: '¡Separadas por comas!'
|
categories_help: '¡Separadas por comas!'
|
||||||
slug: 'Nombre la URL'
|
slug: 'Nombre la URL'
|
||||||
slug_help: 'Esto es el nombre del artículo en la URL, por ejemplo /título/. Puedes dejarlo vacío.'
|
slug_help: 'Esto es el nombre del artículo en la URL, por ejemplo /título/. Puedes dejarlo vacío.'
|
||||||
|
logger:
|
||||||
|
rm: 'Eliminado %{path}'
|
||||||
errors:
|
errors:
|
||||||
path: 'El archivo destino ya existe'
|
path: 'El archivo destino ya existe'
|
||||||
file: 'No se pudo escribir el archivo'
|
file: 'No se pudo escribir el archivo'
|
||||||
|
title: 'Necesita un título'
|
||||||
|
date: 'Necesita una fecha'
|
||||||
|
|
|
@ -8,7 +8,7 @@ abbrev@1:
|
||||||
|
|
||||||
"bootstrap-markdown@https://0xacab.org/itacate-kefir/bootstrap-markdown.git":
|
"bootstrap-markdown@https://0xacab.org/itacate-kefir/bootstrap-markdown.git":
|
||||||
version "2.10.0"
|
version "2.10.0"
|
||||||
resolved "https://0xacab.org/itacate-kefir/bootstrap-markdown.git#449141351caa8d96e99fe09f02772ab91e578ab4"
|
resolved "https://0xacab.org/itacate-kefir/bootstrap-markdown.git#580184dc214ea2364fca0fdcb70e3c5e08bd5605"
|
||||||
|
|
||||||
markdown@^0.5.0:
|
markdown@^0.5.0:
|
||||||
version "0.5.0"
|
version "0.5.0"
|
||||||
|
|
Loading…
Reference in a new issue