5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2024-06-26 15:06:08 +00:00

cambiar el archivo y metadatos

This commit is contained in:
f 2017-10-09 19:29:31 -03:00
parent cbe46babdc
commit 9573776b61
No known key found for this signature in database
GPG key ID: F3FDAB97B5F9F7E7
6 changed files with 91 additions and 14 deletions

View file

@ -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

View file

@ -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

View file

@ -29,3 +29,8 @@ body {
line-height: $footer-height;
text-align: center;
}
textarea.post-content {
min-height: 80vh;
font-family: monospace;
}

View file

@ -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 */

View file

@ -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"

View file

@ -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