mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-16 14:31:42 +00:00
Merge branch 'rails' of 0xacab.org:sutty/sutty into issue-13199
This commit is contained in:
commit
5febaf4cf1
34 changed files with 312 additions and 53 deletions
|
@ -386,6 +386,9 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.word-break-all { word-break: break-all !important; }
|
||||||
|
.hyphens { hyphens: auto; }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Modificadores de Bootstrap que no tienen versión responsive.
|
* Modificadores de Bootstrap que no tienen versión responsive.
|
||||||
*/
|
*/
|
||||||
|
@ -408,6 +411,8 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1);
|
||||||
.text-#{$grid-breakpoint}-right { text-align: right !important; }
|
.text-#{$grid-breakpoint}-right { text-align: right !important; }
|
||||||
.text-#{$grid-breakpoint}-center { text-align: center !important; }
|
.text-#{$grid-breakpoint}-center { text-align: center !important; }
|
||||||
|
|
||||||
|
.word-break-#{$grid-breakpoint}-all { word-break: break-all !important; }
|
||||||
|
|
||||||
// posición
|
// posición
|
||||||
@each $position in $positions {
|
@each $position in $positions {
|
||||||
.position-#{$grid-breakpoint}-#{$position} { position: $position !important; }
|
.position-#{$grid-breakpoint}-#{$position} { position: $position !important; }
|
||||||
|
|
|
@ -91,6 +91,10 @@ class ApplicationController < ActionController::Base
|
||||||
breadcrumb 'stats.index', root_path, match: :exact
|
breadcrumb 'stats.index', root_path, match: :exact
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def site
|
||||||
|
@site ||= find_site
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def configure_permitted_parameters
|
def configure_permitted_parameters
|
||||||
|
|
41
app/controllers/build_stats_controller.rb
Normal file
41
app/controllers/build_stats_controller.rb
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# La lista de estados de compilación, por ahora solo mostramos el último
|
||||||
|
# estado.
|
||||||
|
class BuildStatsController < ApplicationController
|
||||||
|
include ActionView::Helpers::NumberHelper
|
||||||
|
include ActionView::Helpers::DateHelper
|
||||||
|
|
||||||
|
before_action :authenticate_usuarie!
|
||||||
|
|
||||||
|
breadcrumb -> { current_usuarie.email }, :edit_usuarie_registration_path
|
||||||
|
breadcrumb 'sites.index', :sites_path, match: :exact
|
||||||
|
breadcrumb -> { site.title }, -> { site_posts_path(site, locale: locale) }, match: :exact
|
||||||
|
|
||||||
|
def index
|
||||||
|
authorize SiteBuildStat.new(site)
|
||||||
|
breadcrumb I18n.t('build_stats.index.title'), ''
|
||||||
|
|
||||||
|
@headers = %w[type url seconds size].map do |header|
|
||||||
|
t("deploy_mailer.deployed.th.#{header}")
|
||||||
|
end
|
||||||
|
|
||||||
|
@table = site.deployment_list.map do |deploy|
|
||||||
|
type = deploy.class.name.underscore
|
||||||
|
urls = deploy.respond_to?(:urls) ? deploy.urls : [deploy.url].compact
|
||||||
|
urls = [nil] if urls.empty?
|
||||||
|
build_stat = deploy.build_stats.where(status: true).last
|
||||||
|
seconds = build_stat&.seconds || 0
|
||||||
|
|
||||||
|
{
|
||||||
|
title: t("deploy_mailer.deployed.#{type}.title"),
|
||||||
|
urls: urls,
|
||||||
|
seconds: {
|
||||||
|
human: distance_of_time_in_words(seconds),
|
||||||
|
machine: "PT#{seconds}S"
|
||||||
|
},
|
||||||
|
size: number_to_human_size(build_stat&.bytes || 0, precision: 2)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -159,10 +159,6 @@ class PostsController < ApplicationController
|
||||||
end.transform_keys(&:to_sym)
|
end.transform_keys(&:to_sym)
|
||||||
end
|
end
|
||||||
|
|
||||||
def site
|
|
||||||
@site ||= find_site
|
|
||||||
end
|
|
||||||
|
|
||||||
def post
|
def post
|
||||||
@post ||= site.posts(lang: locale).find(params[:post_id] || params[:id])
|
@post ||= site.posts(lang: locale).find(params[:post_id] || params[:id])
|
||||||
end
|
end
|
||||||
|
|
|
@ -96,6 +96,13 @@ class UsuariesController < ApplicationController
|
||||||
|
|
||||||
# XXX: La invitación tiene que ser enviada luego de crear el rol
|
# XXX: La invitación tiene que ser enviada luego de crear el rol
|
||||||
if role.persisted?
|
if role.persisted?
|
||||||
|
# Si es una cuenta manual que no está confirmada aun,
|
||||||
|
# aprovechar para reconfirmarla.
|
||||||
|
if !usuarie.confirmed? && !usuarie.created_by_invite?
|
||||||
|
usuarie.confirmation_token = nil
|
||||||
|
usuarie.send :generate_confirmation_token!
|
||||||
|
end
|
||||||
|
|
||||||
usuarie.deliver_invitation
|
usuarie.deliver_invitation
|
||||||
else
|
else
|
||||||
raise ArgumentError, role.errors.full_messages
|
raise ArgumentError, role.errors.full_messages
|
||||||
|
|
|
@ -7,7 +7,7 @@ class RenewDistributedPressTokensJob < ApplicationJob
|
||||||
# detener la tarea si algo pasa.
|
# detener la tarea si algo pasa.
|
||||||
def perform
|
def perform
|
||||||
DistributedPressPublisher.with_about_to_expire_tokens.find_each do |publisher|
|
DistributedPressPublisher.with_about_to_expire_tokens.find_each do |publisher|
|
||||||
publisher.touch
|
publisher.save
|
||||||
rescue DistributedPress::V1::Error => e
|
rescue DistributedPress::V1::Error => e
|
||||||
data = { instance: publisher.instance, expires_at: publisher.client.token.expires_at }
|
data = { instance: publisher.instance, expires_at: publisher.client.token.expires_at }
|
||||||
|
|
||||||
|
|
|
@ -80,25 +80,18 @@ class DeployDistributedPress < Deploy
|
||||||
|
|
||||||
# Devuelve las URLs de todos los protocolos
|
# Devuelve las URLs de todos los protocolos
|
||||||
def urls
|
def urls
|
||||||
protocol_urls + gateway_urls
|
gateway_urls
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
# @return [Array]
|
||||||
def gateway_urls
|
def gateway_urls
|
||||||
remote_info.dig(:distributed_press, :links).values.map do |protocol|
|
remote_info.dig(:distributed_press, :links)&.values&.map do |protocol|
|
||||||
[ protocol[:link], protocol[:gateway] ]
|
[ protocol[:link], protocol[:gateway] ]
|
||||||
end.flatten.compact.select do |link|
|
end&.flatten&.compact&.select do |link|
|
||||||
link.include? '://'
|
link.include? '://'
|
||||||
end
|
end || []
|
||||||
end
|
|
||||||
|
|
||||||
def protocol_urls
|
|
||||||
remote_info.dig(:distributed_press, :protocols).select do |_, enabled|
|
|
||||||
enabled
|
|
||||||
end.map do |protocol, _|
|
|
||||||
"#{protocol}://#{site.hostname}"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# El cliente de la API
|
# El cliente de la API
|
||||||
|
|
|
@ -27,8 +27,4 @@ class DeployFullRsync < DeployRsync
|
||||||
|
|
||||||
result.present? && result.all?
|
result.present? && result.all?
|
||||||
end
|
end
|
||||||
|
|
||||||
def url
|
|
||||||
"https://#{user_host.last}/"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -38,6 +38,7 @@ class DeployRsync < Deploy
|
||||||
#
|
#
|
||||||
# @return [Boolean]
|
# @return [Boolean]
|
||||||
def ssh?
|
def ssh?
|
||||||
|
return true if destination.start_with? 'rsync://'
|
||||||
user, host = user_host
|
user, host = user_host
|
||||||
ssh_available = false
|
ssh_available = false
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,72 @@ class Site
|
||||||
def not_published_yet?
|
def not_published_yet?
|
||||||
build_stats.jekyll.where(status: true).count.zero?
|
build_stats.jekyll.where(status: true).count.zero?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Cambios posibles luego de la última publicación exitosa:
|
||||||
|
#
|
||||||
|
# * Artículos modificados
|
||||||
|
# * Configuración modificada
|
||||||
|
# * Métodos de publicación añadidos
|
||||||
|
#
|
||||||
|
# @return [Boolean]
|
||||||
|
def awaiting_publication?
|
||||||
|
waiting? && (post_pending? || deploy_pending? || configuration_pending?)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Se modificaron artículos después de publicar el sitio por última
|
||||||
|
# vez
|
||||||
|
#
|
||||||
|
# @return [Boolean]
|
||||||
|
def post_pending?
|
||||||
|
last_indexed_post_time > last_publication_time
|
||||||
|
end
|
||||||
|
|
||||||
|
# Se modificó el sitio después de publicarlo por última vez
|
||||||
|
#
|
||||||
|
# @return [Boolean]
|
||||||
|
def deploy_pending?
|
||||||
|
last_deploy_time > last_publication_time
|
||||||
|
end
|
||||||
|
|
||||||
|
# Se modificó la configuración del sitio
|
||||||
|
#
|
||||||
|
# @return [Boolean]
|
||||||
|
def configuration_pending?
|
||||||
|
last_configuration_time > last_publication_time
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# Encuentra la fecha del último artículo modificado. Si no hay
|
||||||
|
# ninguno, devuelve la fecha de modificación del sitio.
|
||||||
|
#
|
||||||
|
# @return [Time]
|
||||||
|
def last_indexed_post_time
|
||||||
|
indexed_posts.order(updated_at: :desc).select(:updated_at).first&.updated_at || updated_at
|
||||||
|
end
|
||||||
|
|
||||||
|
# Encuentra la fecha de última modificación de los métodos de
|
||||||
|
# publicación.
|
||||||
|
#
|
||||||
|
# @return [Time]
|
||||||
|
def last_deploy_time
|
||||||
|
deploys.order(created_at: :desc).select(:created_at).first&.created_at || updated_at
|
||||||
|
end
|
||||||
|
|
||||||
|
# Encuentra la fecha de última publicación exitosa, si no hay
|
||||||
|
# ninguno, devuelve la fecha de modificación del sitio.
|
||||||
|
#
|
||||||
|
# @return [Time]
|
||||||
|
def last_publication_time
|
||||||
|
build_stats.jekyll.where(status: true).order(created_at: :desc).select(:created_at).first&.created_at || updated_at
|
||||||
|
end
|
||||||
|
|
||||||
|
# Fecha de última modificación de la configuración
|
||||||
|
#
|
||||||
|
# @return [Time]
|
||||||
|
def last_configuration_time
|
||||||
|
File.mtime(config.path)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
3
app/models/site_build_stat.rb
Normal file
3
app/models/site_build_stat.rb
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
SiteBuildStat = Struct.new(:site)
|
|
@ -12,6 +12,8 @@ class Usuarie < ApplicationRecord
|
||||||
validates_with EmailAddress::ActiveRecordValidator, field: :email
|
validates_with EmailAddress::ActiveRecordValidator, field: :email
|
||||||
|
|
||||||
before_create :lang_from_locale!
|
before_create :lang_from_locale!
|
||||||
|
before_update :remove_confirmation_invitation_inconsistencies!
|
||||||
|
before_update :accept_invitation_after_confirmation!
|
||||||
|
|
||||||
has_many :roles
|
has_many :roles
|
||||||
has_many :sites, through: :roles
|
has_many :sites, through: :roles
|
||||||
|
@ -49,9 +51,31 @@ class Usuarie < ApplicationRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Les usuaries necesitan link de invitación si no tenían cuenta
|
||||||
|
# y todavía no aceptaron la invitación anterior.
|
||||||
|
def needs_invitation_link?
|
||||||
|
created_by_invite? && !invitation_accepted?
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def lang_from_locale!
|
def lang_from_locale!
|
||||||
self.lang = I18n.locale.to_s
|
self.lang = I18n.locale.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# El invitation_token solo es necesario cuando fue creade por otre
|
||||||
|
# usuarie. De lo contrario lo que queremos es un proceso de
|
||||||
|
# confirmación.
|
||||||
|
def remove_confirmation_invitation_inconsistencies!
|
||||||
|
self.invitation_token = nil unless created_by_invite?
|
||||||
|
end
|
||||||
|
|
||||||
|
# Si le usuarie (re)confirma su cuenta con una invitación pendiente,
|
||||||
|
# considerarla aceptada también.
|
||||||
|
def accept_invitation_after_confirmation!
|
||||||
|
if confirmed?
|
||||||
|
self.invitation_token = nil
|
||||||
|
self.invitation_accepted_at ||= Time.now.utc
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
16
app/policies/site_build_stat_policy.rb
Normal file
16
app/policies/site_build_stat_policy.rb
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# Quiénes pueden ver estados de compilación de un sitio
|
||||||
|
class SiteBuildStatPolicy
|
||||||
|
attr_reader :site_build_stat, :usuarie
|
||||||
|
|
||||||
|
def initialize(usuarie, site_build_stat)
|
||||||
|
@usuarie = usuarie
|
||||||
|
@site_build_stat = site_build_stat
|
||||||
|
end
|
||||||
|
|
||||||
|
# Todes les usuaries e invitades de este sitio
|
||||||
|
def index?
|
||||||
|
site_build_stat.site.usuarie?(usuarie) || site_build_stat.site.invitade?(usuarie)
|
||||||
|
end
|
||||||
|
end
|
|
@ -15,7 +15,8 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do
|
||||||
|
|
||||||
add_role temporal: false, rol: 'usuarie'
|
add_role temporal: false, rol: 'usuarie'
|
||||||
site.deploys.build type: 'DeployLocal'
|
site.deploys.build type: 'DeployLocal'
|
||||||
sync_nodes
|
# Los sitios de testing no se sincronizan
|
||||||
|
sync_nodes unless site.name.end_with? '.testing'
|
||||||
|
|
||||||
I18n.with_locale(usuarie.lang.to_sym || I18n.default_locale) do
|
I18n.with_locale(usuarie.lang.to_sym || I18n.default_locale) do
|
||||||
# No se puede llamar a site.config antes de save porque el sitio
|
# No se puede llamar a site.config antes de save porque el sitio
|
||||||
|
@ -215,7 +216,7 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do
|
||||||
# Crea los deploys necesarios para sincronizar a otros nodos de Sutty
|
# Crea los deploys necesarios para sincronizar a otros nodos de Sutty
|
||||||
def sync_nodes
|
def sync_nodes
|
||||||
Rails.application.nodes.each do |node|
|
Rails.application.nodes.each do |node|
|
||||||
site.deploys.build(type: 'DeployFullRsync', destination: "sutty@#{node}:")
|
site.deploys.build(type: 'DeployFullRsync', destination: "rsync://rsyncd.#{node}/deploys/", hostname: node)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
20
app/views/build_stats/index.haml
Normal file
20
app/views/build_stats/index.haml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
%main.row
|
||||||
|
%aside.menu.col-md-3
|
||||||
|
= render 'sites/header', site: @site
|
||||||
|
.col
|
||||||
|
%h1= t('.title')
|
||||||
|
|
||||||
|
%table.table
|
||||||
|
%thead
|
||||||
|
%tr
|
||||||
|
- @headers.each do |header|
|
||||||
|
%th{ scope: 'col' }= header
|
||||||
|
%tbody
|
||||||
|
- @table.each do |row|
|
||||||
|
- row[:urls].each do |url|
|
||||||
|
%tr
|
||||||
|
%th{ scope: 'row' }= row[:title]
|
||||||
|
%td= link_to_if url.present?, url, url, class: 'word-break-all'
|
||||||
|
%td
|
||||||
|
%time{ datetime: row[:seconds][:machine] }= row[:seconds][:human]
|
||||||
|
%td= row[:size]
|
|
@ -8,7 +8,7 @@
|
||||||
%h1= site.title
|
%h1= site.title
|
||||||
%p= site.description
|
%p= site.description
|
||||||
|
|
||||||
- if @resource.created_by_invite? && !@resource.invitation_accepted?
|
- if @resource.needs_invitation_link?
|
||||||
%p= link_to t('devise.mailer.invitation_instructions.accept'),
|
%p= link_to t('devise.mailer.invitation_instructions.accept'),
|
||||||
accept_invitation_url(@resource, invitation_token: @token, change_locale_to: @resource.lang)
|
accept_invitation_url(@resource, invitation_token: @token, change_locale_to: @resource.lang)
|
||||||
|
|
||||||
|
@ -18,5 +18,7 @@
|
||||||
format: :'devise.mailer.invitation_instructions.accept_until_format'))
|
format: :'devise.mailer.invitation_instructions.accept_until_format'))
|
||||||
|
|
||||||
%p= t('devise.mailer.invitation_instructions.ignore')
|
%p= t('devise.mailer.invitation_instructions.ignore')
|
||||||
|
- elsif !@resource.confirmed? && @resource.confirmation_token
|
||||||
|
= confirmation_url(@resource, confirmation_token: @resource.confirmation_token, change_locale_to: @resource.lang)
|
||||||
- else
|
- else
|
||||||
%p= link_to t('devise.mailer.invitation_instructions.sign_in'), root_url
|
%p= link_to t('devise.mailer.invitation_instructions.sign_in'), root_url
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
\
|
\
|
||||||
= site.description
|
= site.description
|
||||||
\
|
\
|
||||||
- if @resource.created_by_invite? && !@resource.invitation_accepted?
|
- if @resource.needs_invitation_link?
|
||||||
= accept_invitation_url(@resource, invitation_token: @token, change_locale_to: @resource.lang)
|
= accept_invitation_url(@resource, invitation_token: @token, change_locale_to: @resource.lang)
|
||||||
\
|
\
|
||||||
- if @resource.invitation_due_at
|
- if @resource.invitation_due_at
|
||||||
|
@ -18,6 +18,8 @@
|
||||||
format: :'devise.mailer.invitation_instructions.accept_until_format'))
|
format: :'devise.mailer.invitation_instructions.accept_until_format'))
|
||||||
\
|
\
|
||||||
= t('devise.mailer.invitation_instructions.ignore')
|
= t('devise.mailer.invitation_instructions.ignore')
|
||||||
|
- elsif !@resource.confirmed? && @resource.confirmation_token
|
||||||
|
= confirmation_url(@resource, confirmation_token: @resource.confirmation_token, change_locale_to: @resource.lang)
|
||||||
- else
|
- else
|
||||||
= root_url(change_locale_to: @resource.lang)
|
= root_url(change_locale_to: @resource.lang)
|
||||||
= t('devise.mailer.invitation_instructions.sign_in')
|
= t('devise.mailer.invitation_instructions.sign_in')
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
= link_to t('.tienda'), @site.tienda_url,
|
= link_to t('.tienda'), @site.tienda_url,
|
||||||
role: 'button', class: 'btn'
|
role: 'button', class: 'btn'
|
||||||
|
|
||||||
|
%li.nav-item
|
||||||
|
= link_to t('.contact_us'), t('.contact_us_href'),
|
||||||
|
class: 'btn', rel: 'me', target: '_blank'
|
||||||
|
|
||||||
%li.nav-item
|
%li.nav-item
|
||||||
= link_to t('.logout'), main_app.destroy_usuarie_session_path,
|
= link_to t('.logout'), main_app.destroy_usuarie_session_path,
|
||||||
method: :delete, role: 'button', class: 'btn'
|
method: :delete, role: 'button', class: 'btn'
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
- invalid_help = site.config.fetch('invalid_help', t('.invalid_help'))
|
||||||
|
- sending_help = site.config.fetch('sending_help', t('.sending_help'))
|
||||||
.form-group
|
.form-group
|
||||||
= submit_tag t('.save'), class: 'btn submit-post'
|
= submit_tag t('.save'), class: 'btn submit-post'
|
||||||
= render 'bootstrap/alert', class: 'invalid-help d-none' do
|
= render 'bootstrap/alert', class: 'invalid-help d-none' do
|
||||||
= site.config.fetch('invalid_help', t('.invalid_help'))
|
= invalid_help
|
||||||
= render 'bootstrap/alert', class: 'sending-help d-none' do
|
= render 'bootstrap/alert', class: 'sending-help d-none' do
|
||||||
= site.config.fetch('sending_help', t('.sending_help'))
|
= sending_help
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
%main.row
|
%main.row
|
||||||
%aside.menu.col-md-3
|
%aside.menu.col-md-3
|
||||||
%h1= @site.title
|
= render 'sites/header', site: @site
|
||||||
%p.lead= @site.description
|
|
||||||
- cache_if @usuarie, [@site, I18n.locale] do
|
= render 'sites/status', site: @site
|
||||||
= render 'sites/status', site: @site
|
|
||||||
|
= render 'sites/build', site: @site, class: 'btn-block'
|
||||||
|
|
||||||
%h3= t('posts.new')
|
%h3= t('posts.new')
|
||||||
%table.table.table-sm.mb-3
|
%table.table.table-sm.mb-3
|
||||||
|
@ -29,8 +30,6 @@
|
||||||
type: 'info',
|
type: 'info',
|
||||||
link: site_usuaries_path(@site)
|
link: site_usuaries_path(@site)
|
||||||
|
|
||||||
= render 'sites/build', site: @site
|
|
||||||
|
|
||||||
- if @site.design.credits
|
- if @site.design.credits
|
||||||
= render 'bootstrap/alert' do
|
= render 'bootstrap/alert' do
|
||||||
= sanitize_markdown @site.design.credits
|
= sanitize_markdown @site.design.credits
|
||||||
|
@ -45,7 +44,8 @@
|
||||||
- next if param == 'q'
|
- next if param == 'q'
|
||||||
%input{ type: 'hidden', name: param, value: value }
|
%input{ type: 'hidden', name: param, value: value }
|
||||||
.form-group.flex-grow-0.m-0
|
.form-group.flex-grow-0.m-0
|
||||||
%input.form-control.border.border-magenta{ type: 'search', placeholder: 'Buscar', name: 'q', value: @filter_params[:q] }
|
%label.sr-only{for: 'q'}= t('.search')
|
||||||
|
%input#q.form-control.border.border-magenta{ type: 'search', placeholder: t('.search'), name: 'q', value: @filter_params[:q] }
|
||||||
%input.sr-only{ type: 'submit' }
|
%input.sr-only{ type: 'submit' }
|
||||||
|
|
||||||
- if @site.locales.size > 1
|
- if @site.locales.size > 1
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
method: :post,
|
method: :post,
|
||||||
class: 'form-inline inline' do
|
class: 'form-inline inline' do
|
||||||
= submit_tag site.enqueued? ? t('sites.enqueued') : t('sites.enqueue'),
|
= submit_tag site.enqueued? ? t('sites.enqueued') : t('sites.enqueue'),
|
||||||
class: 'btn no-border-radius',
|
class: "btn no-border-radius #{local_assigns[:class]}",
|
||||||
title: site.enqueued? ? t('help.sites.enqueued') : t('help.sites.enqueue'),
|
title: site.enqueued? ? t('help.sites.enqueued') : t('help.sites.enqueue'),
|
||||||
data: { disable_with: t('sites.enqueued') },
|
data: { disable_with: t('sites.enqueued') },
|
||||||
disabled: site.enqueued?
|
disabled: site.enqueued?
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
layouts: site.incompatible_layouts.to_sentence)
|
layouts: site.incompatible_layouts.to_sentence)
|
||||||
.row.row-cols-1.row-cols-md-2.designs
|
.row.row-cols-1.row-cols-md-2.designs
|
||||||
-# Demasiado complejo para un f.collection_radio_buttons
|
-# Demasiado complejo para un f.collection_radio_buttons
|
||||||
- Design.all.find_each do |design|
|
- Design.all.order(priority: :desc).each do |design|
|
||||||
.design.col.d-flex.flex-column
|
.design.col.d-flex.flex-column
|
||||||
.custom-control.custom-radio
|
.custom-control.custom-radio
|
||||||
= f.radio_button :design_id, design.id,
|
= f.radio_button :design_id, design.id,
|
||||||
|
|
3
app/views/sites/_header.haml
Normal file
3
app/views/sites/_header.haml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
.hyphens{ lang: site.default_locale }
|
||||||
|
%h1= site.title
|
||||||
|
%p.lead= site.description
|
|
@ -1,7 +1,9 @@
|
||||||
- link = nil
|
- link = nil
|
||||||
- if site.not_published_yet?
|
- if site.not_published_yet?
|
||||||
- message = t('.not_published_yet')
|
- message = t('.not_published_yet')
|
||||||
- if site.building?
|
- elsif site.awaiting_publication?
|
||||||
|
- message = t('.awaiting_publication')
|
||||||
|
- elsif site.building?
|
||||||
- if site.average_publication_time_calculable?
|
- if site.average_publication_time_calculable?
|
||||||
- average_building_time = site.average_publication_time
|
- average_building_time = site.average_publication_time
|
||||||
- elsif !site.similar_sites?
|
- elsif !site.similar_sites?
|
||||||
|
@ -16,4 +18,4 @@
|
||||||
- link = true
|
- link = true
|
||||||
|
|
||||||
= render 'bootstrap/alert' do
|
= render 'bootstrap/alert' do
|
||||||
= link_to_if link, message.html_safe, site.url, class: 'alert-link'
|
= link_to_if link, message.html_safe, site_build_stats_path(site), class: 'alert-link'
|
||||||
|
|
|
@ -22,7 +22,7 @@ es:
|
||||||
someone_invited_you: "Alguien te ha invitado a colaborar en %{url}, podés aceptar la invitación con el enlace a continuación."
|
someone_invited_you: "Alguien te ha invitado a colaborar en %{url}, podés aceptar la invitación con el enlace a continuación."
|
||||||
accept: "Aceptar la invitación"
|
accept: "Aceptar la invitación"
|
||||||
accept_until: "La invitación vencerá el %{due_date}."
|
accept_until: "La invitación vencerá el %{due_date}."
|
||||||
ignore: "Si no querés aceptar la invitación, por favor ignora este correo. Tu cuenta no será creada hasta que aceptes la invitación y configures una contraseña."
|
ignore: "Si no querés aceptar la invitación, por favor ignorá este correo. Tu cuenta no será creada hasta que aceptes la invitación y configures una contraseña."
|
||||||
sign_in: "Iniciá sesión con tu cuenta para aceptar o rechazar la invitación."
|
sign_in: "Iniciá sesión con tu cuenta para aceptar o rechazar la invitación."
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
|
|
|
@ -206,6 +206,8 @@ en:
|
||||||
title: 'Your location in Sutty'
|
title: 'Your location in Sutty'
|
||||||
logout: Log out
|
logout: Log out
|
||||||
mutual_aid: Mutual aid
|
mutual_aid: Mutual aid
|
||||||
|
contact_us: "Contact us"
|
||||||
|
contact_us_href: "https://sutty.nl/en/#contact"
|
||||||
collaborations:
|
collaborations:
|
||||||
collaborate:
|
collaborate:
|
||||||
submit: Register
|
submit: Register
|
||||||
|
@ -302,7 +304,7 @@ en:
|
||||||
storage network may continue retaining copies of the data
|
storage network may continue retaining copies of the data
|
||||||
indefinitely.
|
indefinitely.
|
||||||
|
|
||||||
[Learn more](https://ffdweb.org/building-distributed-press-a-publishing-tool-for-the-decentralized-web/)
|
[Learn more](https://sutty.nl/learn-more-about-publish-to-dweb-functionality/)
|
||||||
stats:
|
stats:
|
||||||
index:
|
index:
|
||||||
title: Statistics
|
title: Statistics
|
||||||
|
@ -362,9 +364,10 @@ en:
|
||||||
static_file_migration: 'File migration'
|
static_file_migration: 'File migration'
|
||||||
find_and_replace: 'Search and replace'
|
find_and_replace: 'Search and replace'
|
||||||
status:
|
status:
|
||||||
building: "Your site is building, please wait <time datetime=\"PT%{seconds}S\">%{average_time}</time> to refresh this page..."
|
building: "Your site is building, refresh this page in <time datetime=\"PT%{seconds}S\">%{average_time}</time>."
|
||||||
not_published_yet: "Your site is being published for the first time, please wait up to 1 minute..."
|
not_published_yet: "Your site is being published for the first time, please wait up to 1 minute..."
|
||||||
available: "Your site is available! Click here to visit it."
|
available: "Your site is available! Click here to find all the different ways to visit it."
|
||||||
|
awaiting_publication: "There are unpublished changes. Click the button below and wait a moment to find them on your site."
|
||||||
index:
|
index:
|
||||||
title: 'My Sites'
|
title: 'My Sites'
|
||||||
pull: 'Upgrade'
|
pull: 'Upgrade'
|
||||||
|
@ -430,7 +433,7 @@ en:
|
||||||
title: 'Design'
|
title: 'Design'
|
||||||
actions: 'Information about this design'
|
actions: 'Information about this design'
|
||||||
url: 'Demo'
|
url: 'Demo'
|
||||||
licencia: 'License'
|
license: 'License'
|
||||||
licencia:
|
licencia:
|
||||||
title: 'License for the site and everything published on it'
|
title: 'License for the site and everything published on it'
|
||||||
url: 'Read the license'
|
url: 'Read the license'
|
||||||
|
@ -541,7 +544,8 @@ en:
|
||||||
new: 'Post types'
|
new: 'Post types'
|
||||||
remove_filter_help: 'Remove the filter: %{filter}'
|
remove_filter_help: 'Remove the filter: %{filter}'
|
||||||
categories: 'Everything'
|
categories: 'Everything'
|
||||||
index: 'Posts'
|
index:
|
||||||
|
search: 'Search'
|
||||||
edit: 'Edit'
|
edit: 'Edit'
|
||||||
preview:
|
preview:
|
||||||
btn: 'Preliminary version'
|
btn: 'Preliminary version'
|
||||||
|
@ -699,3 +703,6 @@ en:
|
||||||
filter:
|
filter:
|
||||||
filter: 'Filter'
|
filter: 'Filter'
|
||||||
remove: 'Back'
|
remove: 'Back'
|
||||||
|
build_stats:
|
||||||
|
index:
|
||||||
|
title: "Publications"
|
||||||
|
|
|
@ -206,6 +206,8 @@ es:
|
||||||
title: 'Tu ubicación en Sutty'
|
title: 'Tu ubicación en Sutty'
|
||||||
logout: Cerrar sesión
|
logout: Cerrar sesión
|
||||||
mutual_aid: Ayuda mutua
|
mutual_aid: Ayuda mutua
|
||||||
|
contact_us: "Contacto"
|
||||||
|
contact_us_href: "https://sutty.nl/#contacto"
|
||||||
collaborations:
|
collaborations:
|
||||||
collaborate:
|
collaborate:
|
||||||
submit: Registrarme
|
submit: Registrarme
|
||||||
|
@ -307,7 +309,7 @@ es:
|
||||||
nodos en la red de almacenamiento distribuida puedan retener
|
nodos en la red de almacenamiento distribuida puedan retener
|
||||||
copias de tu contenido indefinidamente.
|
copias de tu contenido indefinidamente.
|
||||||
|
|
||||||
[Saber más (en inglés)](https://ffdweb.org/building-distributed-press-a-publishing-tool-for-the-decentralized-web/)
|
[Saber más](https://sutty.nl/saber-mas-sobre-publicar-a-la-web-distribuida/)
|
||||||
stats:
|
stats:
|
||||||
index:
|
index:
|
||||||
title: Estadísticas
|
title: Estadísticas
|
||||||
|
@ -367,9 +369,10 @@ es:
|
||||||
static_file_migration: 'Migración de archivos'
|
static_file_migration: 'Migración de archivos'
|
||||||
find_and_replace: 'Búsqueda y reemplazo'
|
find_and_replace: 'Búsqueda y reemplazo'
|
||||||
status:
|
status:
|
||||||
building: "Tu sitio se está publicando, por favor espera <time datetime=\"PT%{seconds}S\">%{average_time}</time> para recargar esta página..."
|
building: "Tu sitio se está publicando, recargá esta página en <time datetime=\"PT%{seconds}S\">%{average_time}</time>."
|
||||||
not_published_yet: "Tu sitio se está publicando por primera vez, por favor espera hasta un minuto..."
|
not_published_yet: "Tu sitio se está publicando por primera vez, por favor espera hasta un minuto..."
|
||||||
available: "¡Tu sitio está disponible! Cliquea aquí para visitarlo."
|
available: "¡Tu sitio está disponible! Cliqueá aquí para encontrar todas las formas en que podés visitarlo."
|
||||||
|
awaiting_publication: "Hay cambios sin publicar, cliqueá el botón debajo y espera un momento para encontrarlos en tu sitio."
|
||||||
index:
|
index:
|
||||||
title: 'Mis sitios'
|
title: 'Mis sitios'
|
||||||
pull: 'Actualizar'
|
pull: 'Actualizar'
|
||||||
|
@ -549,7 +552,8 @@ es:
|
||||||
categories: 'Todos'
|
categories: 'Todos'
|
||||||
new: 'Tipos de artículos'
|
new: 'Tipos de artículos'
|
||||||
remove_filter_help: 'Quitar este filtro: %{filter}'
|
remove_filter_help: 'Quitar este filtro: %{filter}'
|
||||||
index: 'Artículos'
|
index:
|
||||||
|
search: 'Buscar'
|
||||||
edit: 'Editar'
|
edit: 'Editar'
|
||||||
preview:
|
preview:
|
||||||
btn: 'Versión preliminar'
|
btn: 'Versión preliminar'
|
||||||
|
@ -708,3 +712,6 @@ es:
|
||||||
filter:
|
filter:
|
||||||
filter: 'Filtrar'
|
filter: 'Filtrar'
|
||||||
remove: 'Volver'
|
remove: 'Volver'
|
||||||
|
build_stats:
|
||||||
|
index:
|
||||||
|
title: "Publicaciones"
|
||||||
|
|
|
@ -75,5 +75,7 @@ Rails.application.routes.draw do
|
||||||
get :'stats/host', to: 'stats#host'
|
get :'stats/host', to: 'stats#host'
|
||||||
get :'stats/uris', to: 'stats#uris'
|
get :'stats/uris', to: 'stats#uris'
|
||||||
get :'stats/resources', to: 'stats#resources'
|
get :'stats/resources', to: 'stats#resources'
|
||||||
|
|
||||||
|
resources :build_stats, only: %i[index]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
5
db/migrate/20230415153231_add_priority_to_designs.rb
Normal file
5
db/migrate/20230415153231_add_priority_to_designs.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class AddPriorityToDesigns < ActiveRecord::Migration[6.1]
|
||||||
|
def change
|
||||||
|
add_column :designs, :priority, :integer
|
||||||
|
end
|
||||||
|
end
|
22
db/migrate/20230421182627_change_full_rsync_destination.rb
Normal file
22
db/migrate/20230421182627_change_full_rsync_destination.rb
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# Envía los cambios a través de rsyncd
|
||||||
|
class ChangeFullRsyncDestination < ActiveRecord::Migration[6.1]
|
||||||
|
def up
|
||||||
|
DeployFullRsync.find_each do |deploy|
|
||||||
|
Rails.application.nodes.each do |node|
|
||||||
|
deploy.destination = "rsync://rsyncd.#{node}/deploys/"
|
||||||
|
deploy.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
DeployFullRsync.find_each do |deploy|
|
||||||
|
Rails.application.nodes.each do |node|
|
||||||
|
deploy.destination = "sutty@#{node}:"
|
||||||
|
deploy.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
8
db/migrate/20230424174544_add_node_to_access_logs.rb
Normal file
8
db/migrate/20230424174544_add_node_to_access_logs.rb
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# Agrega la columna de nodo a los logs
|
||||||
|
class AddNodeToAccessLogs < ActiveRecord::Migration[6.1]
|
||||||
|
def change
|
||||||
|
add_column :access_logs, :node, :string, index: true
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2021_10_22_225449) do
|
ActiveRecord::Schema.define(version: 2023_04_15_153231) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "pg_trgm"
|
enable_extension "pg_trgm"
|
||||||
|
@ -217,6 +217,7 @@ ActiveRecord::Schema.define(version: 2021_10_22_225449) do
|
||||||
t.boolean "disabled", default: false
|
t.boolean "disabled", default: false
|
||||||
t.text "credits"
|
t.text "credits"
|
||||||
t.string "designer_url"
|
t.string "designer_url"
|
||||||
|
t.integer "priority"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "indexed_posts", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
|
create_table "indexed_posts", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
|
||||||
|
@ -380,6 +381,7 @@ ActiveRecord::Schema.define(version: 2021_10_22_225449) do
|
||||||
|
|
||||||
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
|
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
|
||||||
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
|
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
|
||||||
|
|
||||||
create_trigger("indexed_posts_before_insert_update_row_tr", :compatibility => 1).
|
create_trigger("indexed_posts_before_insert_update_row_tr", :compatibility => 1).
|
||||||
on("indexed_posts").
|
on("indexed_posts").
|
||||||
before(:insert, :update) do
|
before(:insert, :update) do
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
disabled: true
|
disabled: true
|
||||||
description_en: "Upload your own theme. [This feature is in development, help us!](https://sutty.nl/en/#contact)"
|
description_en: "Upload your own theme. [This feature is in development, help us!](https://sutty.nl/en/#contact)"
|
||||||
description_es: "Subir tu propio diseño. [Esta posibilidad está en desarrollo, ¡ayudanos!](https://sutty.nl/#contacto)"
|
description_es: "Subir tu propio diseño. [Esta posibilidad está en desarrollo, ¡ayudanos!](https://sutty.nl/#contacto)"
|
||||||
|
priority: '0'
|
||||||
- name_en: 'I want you to develop a site for me'
|
- name_en: 'I want you to develop a site for me'
|
||||||
name_es: 'Quiero que desarrollen mi sitio'
|
name_es: 'Quiero que desarrollen mi sitio'
|
||||||
gem: 'sutty-theme-custom'
|
gem: 'sutty-theme-custom'
|
||||||
|
@ -13,6 +14,7 @@
|
||||||
disabled: true
|
disabled: true
|
||||||
description_en: "If you want us to develop your site, you're welcome to [contact us!](https://sutty.nl/en/#contact) :)"
|
description_en: "If you want us to develop your site, you're welcome to [contact us!](https://sutty.nl/en/#contact) :)"
|
||||||
description_es: "Si querés que desarrollemos tu sitio, [escribinos](https://sutty.nl/#contacto) :)"
|
description_es: "Si querés que desarrollemos tu sitio, [escribinos](https://sutty.nl/#contacto) :)"
|
||||||
|
priority: '2'
|
||||||
- name_en: 'Minima'
|
- name_en: 'Minima'
|
||||||
name_es: 'Mínima'
|
name_es: 'Mínima'
|
||||||
gem: 'sutty-minima'
|
gem: 'sutty-minima'
|
||||||
|
@ -20,6 +22,7 @@
|
||||||
description_en: "Sutty Minima is based on [Minima](https://jekyll.github.io/minima/), a blog-focused theme for Jekyll."
|
description_en: "Sutty Minima is based on [Minima](https://jekyll.github.io/minima/), a blog-focused theme for Jekyll."
|
||||||
description_es: 'Sutty Mínima es una plantilla para blogs basada en [Mínima](https://jekyll.github.io/minima/).'
|
description_es: 'Sutty Mínima es una plantilla para blogs basada en [Mínima](https://jekyll.github.io/minima/).'
|
||||||
license: 'https://0xacab.org/sutty/jekyll/minima/-/blob/master/LICENSE.txt'
|
license: 'https://0xacab.org/sutty/jekyll/minima/-/blob/master/LICENSE.txt'
|
||||||
|
priority: '100'
|
||||||
- name_en: 'Sutty'
|
- name_en: 'Sutty'
|
||||||
name_es: 'Sutty'
|
name_es: 'Sutty'
|
||||||
gem: 'sutty-jekyll-theme'
|
gem: 'sutty-jekyll-theme'
|
||||||
|
@ -29,6 +32,7 @@
|
||||||
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'
|
||||||
credits_es: 'Sutty es parte de la economía solidaria :)'
|
credits_es: 'Sutty es parte de la economía solidaria :)'
|
||||||
credits_en: 'Sutty is a solidarity economy project!'
|
credits_en: 'Sutty is a solidarity economy project!'
|
||||||
|
priority: '90'
|
||||||
- name_en: 'Self-managed Book Publisher'
|
- name_en: 'Self-managed Book Publisher'
|
||||||
name_es: 'Editorial Autogestiva'
|
name_es: 'Editorial Autogestiva'
|
||||||
gem: 'editorial-autogestiva-jekyll-theme'
|
gem: 'editorial-autogestiva-jekyll-theme'
|
||||||
|
@ -38,6 +42,7 @@
|
||||||
license: 'https://0xacab.org/sutty/jekyll/editorial-autogestiva-jekyll-theme/-/blob/master/LICENSE.txt'
|
license: 'https://0xacab.org/sutty/jekyll/editorial-autogestiva-jekyll-theme/-/blob/master/LICENSE.txt'
|
||||||
credits_es: 'Esta plantilla fue inspirada en el trabajo de las [editoriales autogestivas](https://sutty.nl/plantillas-para-crear-cat%C3%A1logos-de-editoriales-autogestivas/)'
|
credits_es: 'Esta plantilla fue inspirada en el trabajo de las [editoriales autogestivas](https://sutty.nl/plantillas-para-crear-cat%C3%A1logos-de-editoriales-autogestivas/)'
|
||||||
credits_en: 'This theme is inspired by [independent publishing projects](https://sutty.nl/en/new-template-for-publishing-projects/)'
|
credits_en: 'This theme is inspired by [independent publishing projects](https://sutty.nl/en/new-template-for-publishing-projects/)'
|
||||||
|
priority: '50'
|
||||||
- name_en: 'Donations'
|
- name_en: 'Donations'
|
||||||
name_es: 'Donaciones'
|
name_es: 'Donaciones'
|
||||||
gem: 'sutty-donaciones-jekyll-theme'
|
gem: 'sutty-donaciones-jekyll-theme'
|
||||||
|
@ -47,6 +52,7 @@
|
||||||
license: 'https://0xacab.org/sutty/jekyll/sutty-donaciones-jekyll-theme/-/blob/master/LICENSE.txt'
|
license: 'https://0xacab.org/sutty/jekyll/sutty-donaciones-jekyll-theme/-/blob/master/LICENSE.txt'
|
||||||
credits_es: 'Diseñamos esta plantilla para [visibilizar campañas de donaciones](https://sutty.nl/plantilla-para-donaciones/) durante la cuarentena.'
|
credits_es: 'Diseñamos esta plantilla para [visibilizar campañas de donaciones](https://sutty.nl/plantilla-para-donaciones/) durante la cuarentena.'
|
||||||
credits_en: 'We designed this theme to increase [visibility for donation requests](https://sutty.nl/template-for-donations/) during the quarantine.'
|
credits_en: 'We designed this theme to increase [visibility for donation requests](https://sutty.nl/template-for-donations/) during the quarantine.'
|
||||||
|
priority: '80'
|
||||||
- name_en: 'Support campaign'
|
- name_en: 'Support campaign'
|
||||||
name_es: 'Adhesiones'
|
name_es: 'Adhesiones'
|
||||||
gem: 'adhesiones-jekyll-theme'
|
gem: 'adhesiones-jekyll-theme'
|
||||||
|
@ -57,6 +63,7 @@
|
||||||
credits_es: 'Desarrollamos esta plantilla junto con [Librenauta](https://sutty.nl/plantilla-para-campa%C3%B1as-de-adhesiones/)'
|
credits_es: 'Desarrollamos esta plantilla junto con [Librenauta](https://sutty.nl/plantilla-para-campa%C3%B1as-de-adhesiones/)'
|
||||||
credits_en: 'This template was made in collaboration with Librenauta'
|
credits_en: 'This template was made in collaboration with Librenauta'
|
||||||
designer_url: 'https://copiona.com/donaunbit/'
|
designer_url: 'https://copiona.com/donaunbit/'
|
||||||
|
priority: '60'
|
||||||
- name_en: 'Community Radio'
|
- name_en: 'Community Radio'
|
||||||
name_es: 'Radio comunitaria'
|
name_es: 'Radio comunitaria'
|
||||||
gem: 'radios-comunitarias-jekyll-theme'
|
gem: 'radios-comunitarias-jekyll-theme'
|
||||||
|
@ -67,6 +74,7 @@
|
||||||
credits_es: 'Desarrollamos esta plantilla junto con Librenauta en 15 horas :)'
|
credits_es: 'Desarrollamos esta plantilla junto con Librenauta en 15 horas :)'
|
||||||
credits_en: 'This template was made in collaboration with Librenauta in 15 hours!'
|
credits_en: 'This template was made in collaboration with Librenauta in 15 hours!'
|
||||||
designer_url: 'https://copiona.com/donaunbit/'
|
designer_url: 'https://copiona.com/donaunbit/'
|
||||||
|
priority: '70'
|
||||||
- name_en: 'Resource toolkit'
|
- name_en: 'Resource toolkit'
|
||||||
name_es: 'Recursero'
|
name_es: 'Recursero'
|
||||||
gem: 'recursero-jekyll-theme'
|
gem: 'recursero-jekyll-theme'
|
||||||
|
@ -74,10 +82,12 @@
|
||||||
disabled: true
|
disabled: true
|
||||||
description_en: "We're working towards adding more themes for you to use. [Contact us!](https://sutty.nl/en/#contact)"
|
description_en: "We're working towards adding more themes for you to use. [Contact us!](https://sutty.nl/en/#contact)"
|
||||||
description_es: "Estamos trabajando para que puedas tener más diseños. [¡Escribinos!](https://sutty.nl/#contacto)"
|
description_es: "Estamos trabajando para que puedas tener más diseños. [¡Escribinos!](https://sutty.nl/#contacto)"
|
||||||
- name_en: 'Other themes'
|
priority: '3'
|
||||||
name_es: 'Mi propio diseño'
|
- name_en: 'More themes'
|
||||||
|
name_es: 'Más plantillas'
|
||||||
gem: 'sutty-theme-own'
|
gem: 'sutty-theme-own'
|
||||||
url: 'https://jekyllthemes.org'
|
url: 'https://jekyllthemes.org'
|
||||||
disabled: true
|
disabled: true
|
||||||
description_en: "We're working towards adding more themes for you to use. [Contact us!](https://sutty.nl/en/#contact)"
|
description_en: "We're working towards adding more themes for you to use. [Contact us!](https://sutty.nl/en/#contact)"
|
||||||
description_es: "Estamos trabajando para que puedas tener más diseños. [¡Escribinos!](https://sutty.nl/#contacto)"
|
description_es: "Estamos trabajando para que puedas tener más diseños. [¡Escribinos!](https://sutty.nl/#contacto)"
|
||||||
|
priority: '1'
|
||||||
|
|
|
@ -19,7 +19,11 @@
|
||||||
|
|
||||||
<p>Gracias por ayudarnos a encontrar errores :)</p>
|
<p>Gracias por ayudarnos a encontrar errores :)</p>
|
||||||
|
|
||||||
<p><a href="/">Volver al panel</a></p>
|
<p>
|
||||||
|
<a href="/">Volver al panel</a>
|
||||||
|
|
|
||||||
|
<a href="https://sutty.nl/#contacto" rel="me" target="_blank">Contáctanos</a>
|
||||||
|
</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="col-10" lang="en">
|
<section class="col-10" lang="en">
|
||||||
|
@ -31,7 +35,11 @@
|
||||||
|
|
||||||
<p>Thanks for helping us in finding errors! :)</p>
|
<p>Thanks for helping us in finding errors! :)</p>
|
||||||
|
|
||||||
<p><a href="/">Go back to panel</a></p>
|
<p>
|
||||||
|
<a href="/">Go back to panel</a>
|
||||||
|
|
|
||||||
|
<a href="https://sutty.nl/en/#contact" rel="me" target="_blank">Contact us</a>
|
||||||
|
</p>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
|
|
Loading…
Reference in a new issue