ver artículos

cada metadato tiene su plantilla de solo lectura para generar una tabla
de metadatos dinámica :D
This commit is contained in:
f 2019-08-14 18:19:01 -03:00
parent 9469cb41e6
commit 1c96e0b0ff
No known key found for this signature in database
GPG key ID: 2AE5A13E321F953D
18 changed files with 116 additions and 126 deletions

View file

@ -141,7 +141,7 @@ GEM
activerecord (>= 4.0.0)
globalid (0.4.2)
activesupport (>= 4.2.0)
haml (5.0.4)
haml (5.1.2)
temple (>= 0.8.0)
tilt
haml-lint (0.999.999)
@ -277,7 +277,7 @@ GEM
rake (>= 0.8.7)
thor (>= 0.19.0, < 2.0)
rainbow (3.0.0)
rake (12.3.2)
rake (12.3.3)
rb-fsevent (0.10.3)
rb-inotify (0.10.0)
ffi (~> 1.0)
@ -306,7 +306,7 @@ GEM
actionpack (>= 5.0)
railties (>= 5.0)
rouge (3.3.0)
rubocop (0.72.0)
rubocop (0.74.0)
jaro_winkler (~> 1.5.1)
parallel (~> 1.10)
parser (>= 2.6)

View file

@ -40,29 +40,8 @@ class ApplicationController < ActionController::Base
site
end
def find_post(site)
id = params[:post_id] || params[:id]
lang = find_lang(site)
posts = site.posts_for(lang)
posts.find do |p|
p.id == id
end
end
def find_lang(site)
params.fetch(:lang, site.default_lang)
end
def find_template(site)
id = params[:template_id] || params[:template] || params.dig(:post, :layout)
site.templates.find do |t|
t.id == id
end
end
def set_locale
I18n.locale = current_usuarie.lang
I18n.locale = current_usuarie.lang if current_usuarie
end
protected

View file

@ -8,8 +8,6 @@ class PostsController < ApplicationController
def index
authorize Post
@site = find_site
# TODO: por qué no lo está leyendo @site.posts?
@site.read
@category = session[:category] = params.dig(:category)
# TODO: Aplicar policy_scope
@posts = @site.posts(lang: I18n.locale)
@ -26,8 +24,7 @@ class PostsController < ApplicationController
def show
@site = find_site
@lang = find_lang(@site)
@post = find_post(@site)
@post = @site.posts.find params[:id]
authorize @post
end
@ -54,8 +51,7 @@ class PostsController < ApplicationController
def edit
@site = find_site
@lang = find_lang(@site)
@post = find_post(@site)
@post = @site.posts.find params[:id]
authorize @post
end

View file

@ -27,8 +27,21 @@ module ApplicationHelper
end
end
# Devuelve todas las etiquetas HTML que queremos mantener
def all_html_tags
%w[h1 h2 h3 h4 h5 h6 p a ul ol li table tr td th tbody thead
tfoot em strong sup blockquote cite pre section article]
end
def sanitize_markdown(text, options = {})
sanitize(CommonMarker.render_html(text), options)
options.merge!(attributes: %w[id href alt class])
document = CommonMarker
.render_doc(text,
%i[FOOTNOTES SMART],
%i[table strikethrough autolink])
sanitize(document.to_html, options)
end
def invalid?(model, field)

View file

@ -25,6 +25,12 @@ class PostRelation < Array
post
end
def find(id)
super() do |p|
p.id == id
end
end
# Intenta guardar todos y devuelve true si pudo
def save_all
map(&:save).all?

View file

@ -108,6 +108,9 @@ class Site < ApplicationRecord
# Lee el sitio y todos los artículos
def read
# No hacer nada si ya se leyó antes
return unless @jekyll.layouts.empty?
@jekyll.read
end
@ -115,7 +118,7 @@ class Site < ApplicationRecord
#
# XXX: Leer directamente sin pasar por Jekyll
def data
read if @jekyll.data.empty?
read
@jekyll.data
end
@ -123,7 +126,7 @@ class Site < ApplicationRecord
# Traer las colecciones. Todos los artículos van a estar dentro de
# colecciones.
def collections
read if @jekyll.collections.empty?
read
@jekyll.collections
end

View file

@ -12,11 +12,18 @@ PostService = Struct.new(:site, :usuarie, :post, :params, keyword_init: true) do
# TODO: No podemos pasar los post_params a build aun porque para
# saber los parámetros tenemos que haber instanciado el post
# primero.
post.update_attributes(post_params) &&
site.repository.commit(file: post.path.absolute,
usuarie: usuarie,
message: I18n.t('post_service.created',
title: post.title.value))
post.update_attributes(post_params) && commit(action: :created)
# Devolver el post aunque no se haya salvado para poder rescatar los
# errores
post
end
def update
# TODO: No podemos pasar los post_params a build aun porque para
# saber los parámetros tenemos que haber instanciado el post
# primero.
post.update_attributes(post_params) && commit(action: :updated)
# Devolver el post aunque no se haya salvado para poder rescatar los
# errores
@ -25,6 +32,13 @@ PostService = Struct.new(:site, :usuarie, :post, :params, keyword_init: true) do
private
def commit(action:)
site.repository.commit(file: post.path.absolute,
usuarie: usuarie,
message: I18n.t("post_service.#{action}",
title: post.title.value))
end
# Solo permitir cambiar estos atributos de cada articulo
def post_params
params.require(:post).permit(post.params)

View file

@ -0,0 +1,8 @@
%tr{ id: attribute }
%th= post_label_t(attribute, post: post)
%td
- if metadata.value.respond_to? :each
- metadata.value.each do |v|
%span.badge.badge-primary= v
- else
%span.badge.badge-primary= metadata.value

View file

@ -0,0 +1,3 @@
%tr{ id: attribute }
%th= post_label_t(attribute, post: post)
%td= sanitize_markdown metadata.value, tags: tags

View file

@ -0,0 +1,3 @@
%tr{ id: attribute }
%th= post_label_t(attribute, post: post)
%td= l metadata.value.to_date

View file

@ -0,0 +1,6 @@
%tr{ id: attribute }
%th= post_label_t(attribute, :path, post: post)
%td
%figure
= image_tag metadata.value['path'], alt: metadata.value['description']
%figcaption= metadata.value['description']

View file

@ -0,0 +1,3 @@
%tr{ id: attribute }
%th= post_label_t(attribute, post: post)
%td= metadata.value

View file

@ -1,91 +1,39 @@
- tags = %w[h1 h2 h3 h4 h5 h6 p a ul ol li table tr td th tbody thead tfoot em strong sup blockquote cite pre]
.row
.col
= render 'layouts/breadcrumb',
crumbs: [link_to(t('sites.index'), sites_path),
@site.name,
link_to(t('posts.index'),
site_posts_path(@site)),
@post.title]
link_to(t('posts.index'), site_posts_path(@site)),
@post.title.value]
.row
.col
%h1{ class: @post.get_front_matter(:dir) }= @post.title
%article.content
= link_to t('posts.edit'),
edit_site_post_path(@site, @post.id),
class: 'btn btn-info btn-block'
%p
- translations = @post.translations.map do |translation|
- link_to translation.title,
site_post_path(@site, translation, lang: translation.lang)
= raw translations.join(' / ')
.row
.col
= link_to t('posts.edit'),
edit_site_post_path(@site, @post, lang: @lang),
class: 'btn btn-info'
.row
.col
.content{ class: @post.get_front_matter(:dir) }
= sanitize_markdown @post.content,
tags: tags
-#
Representar los datos en una tabla:
Texto: tal cual en una celda
Array: píldoras
Array de Hashes: Tabla
Hash: Tabla
TODO DRY
%table.table.table-condensed.table-striped.table-responsive
%tbody
- @post.front_matter.each do |key, data|
%table.table.table-condensed.table-striped.table-responsive
%thead
%tr
%th= t("posts.#{key}")
%td
- if data.is_a? Array
-# Un Array de Hashes
- if data.all? { |a| a.is_a? Hash }
%table
%thead
%tr
- !data.empty? && data.first.keys.each do |k|
%th= k.humanize
%tbody
- data.each do |r|
%tr
- r.each do |_, v|
%td
- if v.is_a? Array
- v.each do |s|
%span.badge.badge-secondary= s
- else
= v
- else
- data.each do |d|
%span.badge.badge-secondary= d
- elsif data.is_a? Hash
%table
%thead
%tr
- data.keys.each do |k|
%th= k.humanize
%tbody
%tr
- data.each do |_, v|
%td= v
- elsif data.respond_to? :content
-# Contenido del artículo
= sanitize_markdown data.content, tags: tags
- elsif data.respond_to? :strftime
-# Fecha
= data.strftime('%F')
- else
-# Texto
- if @post.image? key
%img.img-fluid{ src: @site.get_url_for_sutty(data) }
- elsif @post.url? key
%a{ href: @site.get_url_for_sutty(data) }= data
- else
= data
%th.text-center{ colspan: 2 }= t('.front_matter')
%tbody
-#
TODO: Cambiar por un método que nos deje interactuar
directamente con los metadatos
- @post.attributes.each do |attr|
:ruby
metadata = @post.send(attr)
next unless metadata.front_matter?
= render "posts/attribute_ro/#{metadata.type}", post: @post,
attribute: attr, metadata: metadata, tags: all_html_tags
-# Mostrar todo lo que no va en el front_matter (el contenido)
- @post.attributes.each do |attr|
- next if @post.send(attr).front_matter?
%section{ id: attr }
= sanitize_markdown @post.send(attr).value, tags: all_html_tags

View file

@ -5,6 +5,7 @@ en:
update: 'Updated %{name}'
post_service:
created: 'Created "%{title}"'
updated: 'Updated "%{title}"'
metadata:
array:
cant_be_empty: 'This field cannot be empty'
@ -300,6 +301,8 @@ en:
en: 'English'
ar: 'Arabic'
posts:
show:
front_matter: Post metadata
submit:
save: 'Save'
save_incomplete: 'Save as draft'
@ -326,7 +329,6 @@ en:
edit: 'Edit'
draft: revision
incomplete: draft
invalid: 'This field is required!'
open: 'Tip: You can add new options by typing them and pressing Enter'
private: '&#128274; The values of this field will remain private'
select:

View file

@ -5,6 +5,7 @@ es:
update: 'Actualizado %{name}'
post_service:
created: 'Creado "%{title}"'
updated: 'Modificado "%{title}"'
metadata:
array:
cant_be_empty: 'El campo no puede estar vacío'
@ -313,6 +314,8 @@ es:
en: 'inglés'
ar: 'árabe'
posts:
show:
front_matter: Metadatos del artículo
submit:
save: 'Guardar'
save_incomplete: 'Guardar como borrador'

View file

@ -20,7 +20,7 @@ class PostsControllerTest < ActionDispatch::IntegrationTest
@site.destroy
end
test 'se pueden ver' do
test 'se pueden ver todos' do
get site_posts_url(@site), headers: @authorization
assert_match @site.name, response.body
@ -39,7 +39,6 @@ class PostsControllerTest < ActionDispatch::IntegrationTest
# TODO: implementar reload?
site = Site.find(@site.id)
site.read
new_post = site.posts.first
assert_equal 302, response.status
@ -52,4 +51,11 @@ class PostsControllerTest < ActionDispatch::IntegrationTest
assert_equal I18n.t('post_service.created', title: new_post.title.value),
@site.repository.rugged.head.target.message
end
test 'se pueden ver' do
get site_post_url(@site, @post.id), headers: @authorization
assert_equal 200, response.status
assert_match @post.title.value, response.body
end
end

View file

@ -8,7 +8,6 @@ class PostTest < ActiveSupport::TestCase
#
# TODO: Cambiar a skel cuando publiquemos los códigos y privacidad
@site = create :site, name: 'sutty.nl'
@site.read
@post = @site.posts.sample
end

View file

@ -61,7 +61,6 @@ class SiteTest < ActiveSupport::TestCase
test 'se puede leer un sitio' do
site = create :site, name: 'sutty.nl'
site.read
assert site.valid?
assert !site.posts.empty?
@ -89,7 +88,6 @@ class SiteTest < ActiveSupport::TestCase
test 'el sitio tiene artículos en distintos idiomas' do
site = create :site, name: 'sutty.nl'
site.read
I18n.available_locales.each do |locale|
assert site.posts(lang: locale).size.positive?