mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-22 04:46:22 +00:00
cambiar el archivo y metadatos
This commit is contained in:
parent
cbe46babdc
commit
9573776b61
6 changed files with 91 additions and 14 deletions
|
@ -1,39 +1,84 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'yaml'
|
||||
require 'jekyll/utils'
|
||||
|
||||
module Sutty
|
||||
module Models
|
||||
# Un post
|
||||
class Post
|
||||
attr_accessor :content, :front_matter
|
||||
attr_reader :post, :site
|
||||
attr_reader :post, :site, :errors
|
||||
|
||||
REJECT_FROM_DATA = %w[excerpt slug draft date ext].freeze
|
||||
|
||||
def initialize(site, post = nil)
|
||||
def initialize(site, post = nil, front_matter = {})
|
||||
@site = site
|
||||
@post = post
|
||||
@errors = []
|
||||
@front_matter = front_matter
|
||||
|
||||
load_data!
|
||||
end
|
||||
|
||||
def new?
|
||||
!@post.is_a? Jekyll::Document
|
||||
!@post.is_a? ::Jekyll::Document
|
||||
end
|
||||
|
||||
# Guarda los cambios
|
||||
def save
|
||||
front_matter_from_data!
|
||||
merge_data_with_front_matter!
|
||||
clean_content!
|
||||
|
||||
return unless write.zero?
|
||||
return unless write
|
||||
return unless detect_file_rename!
|
||||
|
||||
# Vuelve a leer el post para tomar los cambios
|
||||
@post.read
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def front_matter_from_data!
|
||||
@front_matter ||= @post.data.reject do |key, _|
|
||||
# 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!
|
||||
basename = basename_from_front_matter
|
||||
path = File.join(File.dirname(@post.path), basename)
|
||||
|
||||
return true if basename == @post.basename
|
||||
|
||||
if File.exist? path
|
||||
@errors << 'El archivo destino ya existe'
|
||||
return
|
||||
end
|
||||
|
||||
FileUtils.mv @post.path, path
|
||||
replace_post! path
|
||||
end
|
||||
|
||||
def replace_post!(path)
|
||||
opts = { site: @site, collection: @site.posts }
|
||||
@site.posts.docs.delete @post
|
||||
@post = ::Jekyll::Document.new(path, opts)
|
||||
@site.posts.docs << @post
|
||||
@site.posts.docs.sort!
|
||||
end
|
||||
|
||||
def basename_from_front_matter
|
||||
date = @front_matter[:date].strftime('%F')
|
||||
title = ::Jekyll::Utils.slugify(@front_matter[:title])
|
||||
|
||||
"#{date}-#{title}.markdown"
|
||||
end
|
||||
|
||||
def merge_data_with_front_matter!
|
||||
@data.merge! Hash[@front_matter.map { |k, v| [k.to_s, v] }]
|
||||
end
|
||||
|
||||
def load_data!
|
||||
@data ||= @post.data.reject do |key, _|
|
||||
REJECT_FROM_DATA.include? key
|
||||
end
|
||||
end
|
||||
|
@ -43,8 +88,9 @@ module Sutty
|
|||
@content = @content.delete("\r")
|
||||
end
|
||||
|
||||
# Guarda los cambios en el archivo destino
|
||||
def write
|
||||
File.open(@post.path, File::RDWR | File::CREAT, 0o640) do |f|
|
||||
r = File.open(@post.path, File::RDWR | File::CREAT, 0o640) do |f|
|
||||
# Bloquear el archivo para que no sea accedido por otro
|
||||
# proceso u otra editora
|
||||
f.flock(File::LOCK_EX)
|
||||
|
@ -59,10 +105,15 @@ module Sutty
|
|||
f.flush
|
||||
f.truncate(f.pos)
|
||||
end
|
||||
|
||||
return true if r.zero?
|
||||
|
||||
@errors << 'No se pudo escribir el archivo'
|
||||
false
|
||||
end
|
||||
|
||||
def full_content
|
||||
"#{@front_matter.to_yaml}---\n\n#{@content}"
|
||||
"#{@data.to_yaml}---\n\n#{@content}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -47,12 +47,19 @@ module Sutty
|
|||
end
|
||||
|
||||
post do
|
||||
post = Sutty::Models::Post.new(@site, @post)
|
||||
front_matter = {
|
||||
tags: params[:post][:tags].split(',').map(&:strip),
|
||||
categories: params[:post][:categories].split(',').map(&:strip),
|
||||
title: params[:post][:title],
|
||||
date: Time.new(params[:post][:date])
|
||||
}
|
||||
|
||||
post = Sutty::Models::Post.new(@site, @post, front_matter)
|
||||
post.content = params[:post][:content]
|
||||
|
||||
if post.save
|
||||
flash[:success] = 'Artículo guardado con éxito'
|
||||
redirect to("/sites/#{@site.name}/posts/#{@post.basename}")
|
||||
redirect to("/sites/#{@site.name}/posts/#{post.post.basename}")
|
||||
else
|
||||
flash[:error] = 'Hubo un error al guardar el artículo'
|
||||
redirect back
|
||||
|
|
|
@ -29,3 +29,8 @@ body {
|
|||
line-height: $footer-height;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea.post-content {
|
||||
min-height: 80vh;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
.background-cover{background:url(/assets/img/background.jpg) no-repeat center center fixed;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover}.full-height{height:calc(100vh - 60px)}html{position:relative;min-height:100%}body{margin-bottom:60px}.footer{position:absolute;bottom:0;width:100%;height:60px;line-height:60px;text-align:center}
|
||||
.background-cover{background:url(/assets/img/background.jpg) no-repeat center center fixed;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover}.full-height{height:calc(100vh - 60px)}html{position:relative;min-height:100%}body{margin-bottom:60px}.footer{position:absolute;bottom:0;width:100%;height:60px;line-height:60px;text-align:center}textarea.post-content{min-height:80vh;font-family:monospace}
|
||||
/*# sourceMappingURL=sutty.css.map */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"version": 3,
|
||||
"mappings": "AAEA,iBAAkB,CAChB,UAAU,CAAE,6DAA6D,CACzE,uBAAuB,CAAE,KAAK,CAC9B,oBAAoB,CAAE,KAAK,CAC3B,kBAAkB,CAAE,KAAK,CACzB,eAAe,CAAE,KAAK,CAGxB,YAAa,CACX,MAAM,CAAE,kBAA+B,CAGzC,IAAK,CACH,QAAQ,CAAE,QAAQ,CAClB,UAAU,CAAE,IAAI,CAGlB,IAAK,CACH,aAAa,CApBC,IAAI,CAuBpB,OAAQ,CACN,QAAQ,CAAE,QAAQ,CAClB,MAAM,CAAE,CAAC,CACT,KAAK,CAAE,IAAI,CACX,MAAM,CA3BQ,IAAI,CA4BlB,WAAW,CA5BG,IAAI,CA6BlB,UAAU,CAAE,MAAM",
|
||||
"mappings": "AAEA,iBAAkB,CAChB,UAAU,CAAE,6DAA6D,CACzE,uBAAuB,CAAE,KAAK,CAC9B,oBAAoB,CAAE,KAAK,CAC3B,kBAAkB,CAAE,KAAK,CACzB,eAAe,CAAE,KAAK,CAGxB,YAAa,CACX,MAAM,CAAE,kBAA+B,CAGzC,IAAK,CACH,QAAQ,CAAE,QAAQ,CAClB,UAAU,CAAE,IAAI,CAGlB,IAAK,CACH,aAAa,CApBC,IAAI,CAuBpB,OAAQ,CACN,QAAQ,CAAE,QAAQ,CAClB,MAAM,CAAE,CAAC,CACT,KAAK,CAAE,IAAI,CACX,MAAM,CA3BQ,IAAI,CA4BlB,WAAW,CA5BG,IAAI,CA6BlB,UAAU,CAAE,MAAM,CAGpB,qBAAsB,CACpB,UAAU,CAAE,IAAI,CAChB,WAAW,CAAE,SAAS",
|
||||
"sources": ["sass/sutty.scss"],
|
||||
"names": [],
|
||||
"file": "sutty.css"
|
||||
|
|
|
@ -2,5 +2,19 @@
|
|||
.form-group
|
||||
%button.btn.btn-success{type: 'submit'} Guardar
|
||||
.form-group
|
||||
%textarea.form-control{name: 'post[content]', id: 'contents', autofocus: true}
|
||||
%textarea.form-control.post-content{name: 'post[content]', id: 'contents', autofocus: true}
|
||||
= @post.content
|
||||
.form-group
|
||||
%label{for: 'date'} Fecha de publicación
|
||||
%input.form-control{type: 'text', name: 'post[date]', id: 'date', value: @post.data['date']}
|
||||
.form-group
|
||||
%label{for: 'title'} Título
|
||||
%input.form-control{type: 'text', name: 'post[title]', id: 'title', value: @post.data['title']}
|
||||
.form-group
|
||||
%label{for: 'tags'} Etiquetas
|
||||
%input.form-control{type: 'text', name: 'post[tags]', id: 'tags', value: @post.data['tags'].join(',')}
|
||||
%small.form-text.text-muted Separadas por comas
|
||||
.form-group
|
||||
%label{for: 'categories'} Categorías
|
||||
%input.form-control{type: 'text', name: 'post[categories]', id: 'categories', value: @post.data['categories'].join(',')}
|
||||
%small.form-text.text-muted Separadas por comas
|
||||
|
|
Loading…
Reference in a new issue