mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-15 04:51:43 +00:00
permitir plantillas en forma de gemas y obtener sus layouts
This commit is contained in:
parent
dcf8ada83f
commit
c1d69c6db4
5 changed files with 127 additions and 27 deletions
8
Gemfile
8
Gemfile
|
@ -52,6 +52,8 @@ gem 'hiredis'
|
||||||
gem 'image_processing'
|
gem 'image_processing'
|
||||||
gem 'inline_svg'
|
gem 'inline_svg'
|
||||||
gem 'jekyll'
|
gem 'jekyll'
|
||||||
|
gem 'jekyll-data', require: 'jekyll-data',
|
||||||
|
git: 'https://0xacab.org/sutty/jekyll/jekyll-data.git'
|
||||||
gem 'mini_magick'
|
gem 'mini_magick'
|
||||||
gem 'mobility'
|
gem 'mobility'
|
||||||
gem 'pg'
|
gem 'pg'
|
||||||
|
@ -69,6 +71,12 @@ gem 'validates_hostname'
|
||||||
gem 'webpacker'
|
gem 'webpacker'
|
||||||
gem 'yaml_db', git: 'https://0xacab.org/sutty/yaml_db.git'
|
gem 'yaml_db', git: 'https://0xacab.org/sutty/yaml_db.git'
|
||||||
|
|
||||||
|
group :themes do
|
||||||
|
gem 'editorial-autogestiva-jekyll-theme', require: false
|
||||||
|
gem 'minima', require: false
|
||||||
|
gem 'sutty-jekyll-theme', require: false
|
||||||
|
end
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
gem 'pry'
|
gem 'pry'
|
||||||
# Adds support for Capybara system testing and selenium driver
|
# Adds support for Capybara system testing and selenium driver
|
||||||
|
|
44
Gemfile.lock
44
Gemfile.lock
|
@ -1,3 +1,10 @@
|
||||||
|
GIT
|
||||||
|
remote: https://0xacab.org/sutty/jekyll/jekyll-data.git
|
||||||
|
revision: 1ad9c175be6bbb31ae6d19cbb8dde18828af90d9
|
||||||
|
specs:
|
||||||
|
jekyll-data (1.1.0)
|
||||||
|
jekyll (>= 3.3, < 5.0.0)
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: https://0xacab.org/sutty/reverse_markdown.git
|
remote: https://0xacab.org/sutty/reverse_markdown.git
|
||||||
revision: 5c243096669aa77e0dc173dec8006b4c5fe07683
|
revision: 5c243096669aa77e0dc173dec8006b4c5fe07683
|
||||||
|
@ -122,6 +129,15 @@ GEM
|
||||||
dotenv (= 2.7.5)
|
dotenv (= 2.7.5)
|
||||||
railties (>= 3.2, < 6.1)
|
railties (>= 3.2, < 6.1)
|
||||||
ed25519 (1.2.4)
|
ed25519 (1.2.4)
|
||||||
|
editorial-autogestiva-jekyll-theme (0.1.0)
|
||||||
|
jekyll (~> 4.0)
|
||||||
|
jekyll-data (~> 1.1)
|
||||||
|
jekyll-feed (~> 0.9)
|
||||||
|
jekyll-images (~> 0.2)
|
||||||
|
jekyll-include-cache (~> 0)
|
||||||
|
jekyll-locales (~> 0.1)
|
||||||
|
jekyll-relative-urls (~> 0.0)
|
||||||
|
jekyll-seo-tag (~> 2.1)
|
||||||
em-websocket (0.5.1)
|
em-websocket (0.5.1)
|
||||||
eventmachine (>= 0.12.9)
|
eventmachine (>= 0.12.9)
|
||||||
http_parser.rb (~> 0.6.0)
|
http_parser.rb (~> 0.6.0)
|
||||||
|
@ -193,8 +209,20 @@ GEM
|
||||||
rouge (~> 3.0)
|
rouge (~> 3.0)
|
||||||
safe_yaml (~> 1.0)
|
safe_yaml (~> 1.0)
|
||||||
terminal-table (~> 1.8)
|
terminal-table (~> 1.8)
|
||||||
|
jekyll-feed (0.13.0)
|
||||||
|
jekyll (>= 3.7, < 5.0)
|
||||||
|
jekyll-images (0.2.3)
|
||||||
|
ruby-filemagic (~> 0.7)
|
||||||
|
ruby-vips (~> 2)
|
||||||
|
jekyll-include-cache (0.2.0)
|
||||||
|
jekyll (>= 3.7, < 5.0)
|
||||||
|
jekyll-locales (0.1.7)
|
||||||
|
jekyll-relative-urls (0.0.5)
|
||||||
|
jekyll (>= 3.8, < 5)
|
||||||
jekyll-sass-converter (2.1.0)
|
jekyll-sass-converter (2.1.0)
|
||||||
sassc (> 2.0.1, < 3.0)
|
sassc (> 2.0.1, < 3.0)
|
||||||
|
jekyll-seo-tag (2.6.1)
|
||||||
|
jekyll (>= 3.3, < 5.0)
|
||||||
jekyll-watch (2.2.1)
|
jekyll-watch (2.2.1)
|
||||||
listen (~> 3.0)
|
listen (~> 3.0)
|
||||||
kramdown (2.1.0)
|
kramdown (2.1.0)
|
||||||
|
@ -222,6 +250,10 @@ GEM
|
||||||
mini_magick (4.10.1)
|
mini_magick (4.10.1)
|
||||||
mini_mime (1.0.2)
|
mini_mime (1.0.2)
|
||||||
mini_portile2 (2.4.0)
|
mini_portile2 (2.4.0)
|
||||||
|
minima (2.5.1)
|
||||||
|
jekyll (>= 3.5, < 5.0)
|
||||||
|
jekyll-feed (~> 0.9)
|
||||||
|
jekyll-seo-tag (~> 2.1)
|
||||||
minitest (5.14.0)
|
minitest (5.14.0)
|
||||||
mobility (0.8.10)
|
mobility (0.8.10)
|
||||||
i18n (>= 0.6.10, < 2)
|
i18n (>= 0.6.10, < 2)
|
||||||
|
@ -326,6 +358,7 @@ GEM
|
||||||
rubocop (>= 0.72.0)
|
rubocop (>= 0.72.0)
|
||||||
ruby-enum (0.7.2)
|
ruby-enum (0.7.2)
|
||||||
i18n
|
i18n
|
||||||
|
ruby-filemagic (0.7.2)
|
||||||
ruby-progressbar (1.10.1)
|
ruby-progressbar (1.10.1)
|
||||||
ruby-vips (2.0.17)
|
ruby-vips (2.0.17)
|
||||||
ffi (~> 1.9)
|
ffi (~> 1.9)
|
||||||
|
@ -362,6 +395,13 @@ GEM
|
||||||
sqlite3 (1.4.2)
|
sqlite3 (1.4.2)
|
||||||
sucker_punch (2.1.2)
|
sucker_punch (2.1.2)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
|
sutty-jekyll-theme (0.1.0)
|
||||||
|
jekyll (~> 4.0)
|
||||||
|
jekyll-feed (~> 0.9)
|
||||||
|
jekyll-images (~> 0.2)
|
||||||
|
jekyll-include-cache (~> 0)
|
||||||
|
jekyll-relative-urls (~> 0.0)
|
||||||
|
jekyll-seo-tag (~> 2.1)
|
||||||
sysexits (1.2.0)
|
sysexits (1.2.0)
|
||||||
temple (0.8.2)
|
temple (0.8.2)
|
||||||
terminal-table (1.8.0)
|
terminal-table (1.8.0)
|
||||||
|
@ -419,6 +459,7 @@ DEPENDENCIES
|
||||||
devise_invitable
|
devise_invitable
|
||||||
dotenv-rails
|
dotenv-rails
|
||||||
ed25519
|
ed25519
|
||||||
|
editorial-autogestiva-jekyll-theme
|
||||||
email_address
|
email_address
|
||||||
exception_notification
|
exception_notification
|
||||||
factory_bot_rails
|
factory_bot_rails
|
||||||
|
@ -430,9 +471,11 @@ DEPENDENCIES
|
||||||
inline_svg
|
inline_svg
|
||||||
jbuilder (~> 2.5)
|
jbuilder (~> 2.5)
|
||||||
jekyll
|
jekyll
|
||||||
|
jekyll-data!
|
||||||
letter_opener
|
letter_opener
|
||||||
listen (>= 3.0.5, < 3.2)
|
listen (>= 3.0.5, < 3.2)
|
||||||
mini_magick
|
mini_magick
|
||||||
|
minima
|
||||||
mobility
|
mobility
|
||||||
pg
|
pg
|
||||||
pry
|
pry
|
||||||
|
@ -454,6 +497,7 @@ DEPENDENCIES
|
||||||
spring-watcher-listen (~> 2.0.0)
|
spring-watcher-listen (~> 2.0.0)
|
||||||
sqlite3
|
sqlite3
|
||||||
sucker_punch
|
sucker_punch
|
||||||
|
sutty-jekyll-theme
|
||||||
terminal-table
|
terminal-table
|
||||||
timecop
|
timecop
|
||||||
turbolinks (~> 5)
|
turbolinks (~> 5)
|
||||||
|
|
|
@ -68,7 +68,7 @@ class Site < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def hostname
|
def hostname
|
||||||
return @hostname if @hostname
|
return @hostname unless name_changed? || @hostname.blank?
|
||||||
|
|
||||||
sub = name || I18n.t('deploys.deploy_local.ejemplo')
|
sub = name || I18n.t('deploys.deploy_local.ejemplo')
|
||||||
@hostname = if sub.ends_with? '.'
|
@hostname = if sub.ends_with? '.'
|
||||||
|
@ -261,6 +261,8 @@ class Site < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def reload_jekyll!
|
def reload_jekyll!
|
||||||
|
reset
|
||||||
|
|
||||||
Dir.chdir(path) do
|
Dir.chdir(path) do
|
||||||
@jekyll = Jekyll::Site.new(jekyll_config)
|
@jekyll = Jekyll::Site.new(jekyll_config)
|
||||||
end
|
end
|
||||||
|
@ -287,10 +289,13 @@ class Site < ApplicationRecord
|
||||||
'quiet' => true, 'excerpt_separator' => '')
|
'quiet' => true, 'excerpt_separator' => '')
|
||||||
|
|
||||||
# No necesitamos cargar plugins en este momento
|
# No necesitamos cargar plugins en este momento
|
||||||
%w[plugins gems theme].each do |unneeded|
|
%w[plugins gems].each do |unneeded|
|
||||||
configuration[unneeded] = [] if configuration.key? unneeded
|
configuration[unneeded] = [] if configuration.key? unneeded
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Eliminar el theme si no es una gema válida
|
||||||
|
configuration.delete 'theme' unless theme_available?
|
||||||
|
|
||||||
# Si estamos usando nuestro propio plugin de i18n, los posts están
|
# Si estamos usando nuestro propio plugin de i18n, los posts están
|
||||||
# en "colecciones"
|
# en "colecciones"
|
||||||
locales.each do |i|
|
locales.each do |i|
|
||||||
|
@ -300,6 +305,20 @@ class Site < ApplicationRecord
|
||||||
configuration
|
configuration
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Lista los nombres de las plantillas disponibles como gemas,
|
||||||
|
# tomándolas dinámicamente de las que agreguemos en el grupo :themes
|
||||||
|
# del Gemfile.
|
||||||
|
def available_themes
|
||||||
|
@available_themes ||= Bundler.load.current_dependencies.select do |gem|
|
||||||
|
gem.groups.include? :themes
|
||||||
|
end.map(&:name)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Detecta si el tema actual es una gema
|
||||||
|
def theme_available?
|
||||||
|
available_themes.include? design.gem
|
||||||
|
end
|
||||||
|
|
||||||
# Devuelve el dominio actual
|
# Devuelve el dominio actual
|
||||||
def self.domain
|
def self.domain
|
||||||
ENV.fetch('SUTTY', 'sutty.nl')
|
ENV.fetch('SUTTY', 'sutty.nl')
|
||||||
|
@ -310,6 +329,12 @@ class Site < ApplicationRecord
|
||||||
File.join(Rails.root, '_sites')
|
File.join(Rails.root, '_sites')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def reset
|
||||||
|
@read = false
|
||||||
|
@layouts = nil
|
||||||
|
@layouts_struct = nil
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Clona el esqueleto de Sutty para crear el sitio nuevo, no pasa nada
|
# Clona el esqueleto de Sutty para crear el sitio nuevo, no pasa nada
|
||||||
|
|
|
@ -27,6 +27,13 @@
|
||||||
description_en: "A design with Sutty's look & feel"
|
description_en: "A design with Sutty's look & feel"
|
||||||
description_es: 'El diseño de Sutty'
|
description_es: 'El diseño de Sutty'
|
||||||
license: 'https://0xacab.org/sutty/jekyll/sutty-jekyll-theme/-/blob/master/LICENSE.txt'
|
license: 'https://0xacab.org/sutty/jekyll/sutty-jekyll-theme/-/blob/master/LICENSE.txt'
|
||||||
|
- name_en: 'Self-managed Book Publisher'
|
||||||
|
name_es: 'Editorial Autogestiva'
|
||||||
|
gem: 'editorial-autogestiva-jekyll-theme'
|
||||||
|
url: 'https://subelamarea.sutty.nl/'
|
||||||
|
description_en: "A theme for self-managed book publishers."
|
||||||
|
description_es: 'Una plantilla para catálogos de editoriales autogestivas.'
|
||||||
|
license: 'https://0xacab.org/sutty/jekyll/editorial-autogestiva-jekyll-theme/-/blob/master/LICENSE.txt'
|
||||||
- name_en: 'Other themes'
|
- name_en: 'Other themes'
|
||||||
name_es: 'Mi propio diseño'
|
name_es: 'Mi propio diseño'
|
||||||
gem: 'sutty-theme-own'
|
gem: 'sutty-theme-own'
|
||||||
|
|
|
@ -3,14 +3,16 @@
|
||||||
require 'test_helper'
|
require 'test_helper'
|
||||||
|
|
||||||
class SiteTest < ActiveSupport::TestCase
|
class SiteTest < ActiveSupport::TestCase
|
||||||
|
def site
|
||||||
|
@site ||= create :site
|
||||||
|
end
|
||||||
|
|
||||||
# Asegurarse que el sitio se destruye al terminar de usarlo
|
# Asegurarse que el sitio se destruye al terminar de usarlo
|
||||||
teardown do
|
teardown do
|
||||||
@site&.destroy
|
site&.destroy
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'se puede crear un sitio' do
|
test 'se puede crear un sitio' do
|
||||||
site = create :site
|
|
||||||
|
|
||||||
assert site.valid?
|
assert site.valid?
|
||||||
# TODO: Mover a la validación del sitio o hacer algo similar
|
# TODO: Mover a la validación del sitio o hacer algo similar
|
||||||
assert File.directory?(site.path)
|
assert File.directory?(site.path)
|
||||||
|
@ -19,78 +21,92 @@ class SiteTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'el nombre tiene que ser único' do
|
test 'el nombre tiene que ser único' do
|
||||||
@site = create :site
|
site2 = build :site, name: site.name
|
||||||
site2 = build :site, name: @site.name
|
|
||||||
|
|
||||||
assert_not site2.valid?
|
assert_not site2.valid?
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'el nombre del sitio puede contener subdominios' do
|
test 'el nombre del sitio puede contener subdominios' do
|
||||||
site = build :site, name: 'hola.chau'
|
@site = build :site, name: 'hola.chau'
|
||||||
site.validate
|
site.validate
|
||||||
|
|
||||||
assert_not site.errors.messages[:name].present?
|
assert_not site.errors.messages[:name].present?
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'el nombre del sitio puede terminar con punto' do
|
test 'el nombre del sitio puede terminar con punto' do
|
||||||
site = build :site, name: 'hola.chau.'
|
@site = build :site, name: 'hola.chau.'
|
||||||
site.validate
|
site.validate
|
||||||
|
|
||||||
assert_not site.errors.messages[:name].present?
|
assert_not site.errors.messages[:name].present?
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'el nombre del sitio no puede contener wildcard' do
|
test 'el nombre del sitio no puede contener wildcard' do
|
||||||
site = build :site, name: '*.chau'
|
@site = build :site, name: '*.chau'
|
||||||
site.validate
|
site.validate
|
||||||
|
|
||||||
assert site.errors.messages[:name].present?
|
assert site.errors.messages[:name].present?
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'el nombre del sitio solo tiene letras, numeros y guiones' do
|
test 'el nombre del sitio solo tiene letras, numeros y guiones' do
|
||||||
site = build :site, name: 'A_Z!'
|
@site = build :site, name: 'A_Z!'
|
||||||
site.validate
|
site.validate
|
||||||
|
|
||||||
assert site.errors.messages[:name].present?
|
assert site.errors.messages[:name].present?
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'al destruir un sitio se eliminan los archivos' do
|
test 'al destruir un sitio se eliminan los archivos' do
|
||||||
site = create :site
|
@site = create :site
|
||||||
assert site.destroy
|
assert site.destroy
|
||||||
assert !File.directory?(site.path)
|
assert !File.directory?(site.path)
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'se puede leer un sitio' do
|
test 'se puede leer un sitio' do
|
||||||
site = create :site
|
|
||||||
|
|
||||||
assert site.valid?
|
assert site.valid?
|
||||||
assert !site.posts.empty?
|
assert !site.posts.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'se pueden renombrar' do
|
test 'se pueden renombrar' do
|
||||||
@site = create :site
|
path = site.path
|
||||||
path = @site.path
|
|
||||||
|
|
||||||
@site.update_attribute :name, SecureRandom.hex
|
site.update_attribute :name, SecureRandom.hex
|
||||||
|
|
||||||
assert_not_equal path, @site.path
|
assert_not_equal path, site.path
|
||||||
assert File.directory?(@site.path)
|
assert File.directory?(site.path)
|
||||||
assert_not File.directory?(path)
|
assert_not File.directory?(path)
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'no se puede guardar html en title y description' do
|
test 'no se puede guardar html en title y description' do
|
||||||
site = build :site
|
_site = build :site
|
||||||
site.description = "<a href='hola'>hola</a><script>alert('pwned')</script>"
|
_site.description = "<a href='hola'>hola</a><script>alert('pwned')</script>"
|
||||||
site.title = "<a href='hola'>hola</a><script>alert('pwned')</script>"
|
_site.title = "<a href='hola'>hola</a><script>alert('pwned')</script>"
|
||||||
|
|
||||||
assert_equal 'hola', site.description
|
assert_equal 'hola', _site.description
|
||||||
assert_equal 'hola', site.title
|
assert_equal 'hola', _site.title
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'el sitio tiene artículos en distintos idiomas' do
|
test 'el sitio tiene artículos en distintos idiomas' do
|
||||||
@site = create :site
|
|
||||||
|
|
||||||
I18n.available_locales.each do |locale|
|
I18n.available_locales.each do |locale|
|
||||||
assert @site.posts(lang: locale).size.positive?
|
assert site.posts(lang: locale).size.positive?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test 'tienen un hostname que puede cambiar' do
|
||||||
|
assert_equal "#{site.name}.#{Site.domain}", site.hostname
|
||||||
|
|
||||||
|
site.name = name = SecureRandom.hex
|
||||||
|
|
||||||
|
assert_equal "#{name}.#{Site.domain}", site.hostname
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'se pueden traer los datos de una plantilla' do
|
||||||
|
@site = create :site, design: Design.find_by(gem: 'editorial-autogestiva-jekyll-theme')
|
||||||
|
|
||||||
|
assert_equal %i[post], site.layouts.to_h.keys
|
||||||
|
|
||||||
|
site.config.write
|
||||||
|
site.reload
|
||||||
|
|
||||||
|
assert_equal %w[book editorial post], site.data['layouts'].keys
|
||||||
|
assert_equal %i[book editorial post], site.layouts.to_h.keys
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue