From 09b8e5054562d24267afd32740f5b8093964af1a Mon Sep 17 00:00:00 2001 From: f Date: Mon, 3 Aug 2020 15:58:08 -0300 Subject: [PATCH] verificar que se pueda cambiar de plantilla closes #158 --- app/controllers/sites_controller.rb | 14 ++++---- app/models/site.rb | 56 ++++++++++++++++++++--------- app/views/sites/_form.haml | 27 ++++++++++---- config/locales/en.yml | 4 +++ config/locales/es.yml | 9 +++-- 5 files changed, 78 insertions(+), 32 deletions(-) diff --git a/app/controllers/sites_controller.rb b/app/controllers/sites_controller.rb index ff32742..ca0a246 100644 --- a/app/controllers/sites_controller.rb +++ b/app/controllers/sites_controller.rb @@ -55,7 +55,7 @@ class SitesController < ApplicationController usuarie: current_usuarie) if service.update.valid? - redirect_to sites_path + redirect_to site_path(@site) else render 'edit' end @@ -76,12 +76,12 @@ class SitesController < ApplicationController authorize @site lang = params.require(:posts).require(:lang) - if params[:posts][:force].present? - result = @site.reorder_collection! lang - else - result = @site - .reorder_collection(lang, params.require(:posts).require(:order)) - end + result = if params[:posts][:force].present? + @site.reorder_collection! lang + else + @site + .reorder_collection(lang, params.require(:posts).require(:order)) + end if result flash[:info] = I18n.t('info.posts.reorder') diff --git a/app/models/site.rb b/app/models/site.rb index 771dceb..6e31c13 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -16,10 +16,13 @@ class Site < ApplicationRecord } validates :design_id, presence: true - validate :deploy_local_presence validates_inclusion_of :status, in: %w[waiting enqueued building] validates_presence_of :title validates :description, length: { in: 50..160 } + validate :deploy_local_presence + validate :compatible_layouts, on: :update + + attr_reader :incompatible_layouts friendly_id :name, use: %i[finders] @@ -292,14 +295,6 @@ class Site < ApplicationRecord status == 'enqueued' end - # Obtener una ruta disponible para Sutty - # - # TODO: Refactorizar y testear - def get_url_for_sutty(path) - # Remover los puntos para que no nos envíen a ../../ - File.join('/', 'sites', id, path.gsub('..', '')) - end - # Cargar el sitio Jekyll # # TODO: En lugar de leer todo junto de una vez, extraer la carga de @@ -315,7 +310,7 @@ class Site < ApplicationRecord reset Dir.chdir(path) do - @jekyll = Jekyll::Site.new(jekyll_config) + @jekyll = Jekyll::Site.new(configuration) end end @@ -324,7 +319,9 @@ class Site < ApplicationRecord reload_jekyll! end - def jekyll_config + def configuration + return @configuration if @configuration + # Pasamos destination porque configuration() toma el directorio # actual # @@ -333,7 +330,7 @@ class Site < ApplicationRecord # # excerpt_separator está vacío para no incorporar el Excerpt en los # metadatos de Document - configuration = + @configuration = ::Jekyll.configuration('source' => path, 'destination' => File.join(path, '_site'), 'safe' => true, 'watch' => false, @@ -341,19 +338,19 @@ class Site < ApplicationRecord # No necesitamos cargar plugins en este momento %w[plugins gems].each do |unneeded| - configuration[unneeded] = [] if configuration.key? unneeded + @configuration[unneeded] = [] if @configuration.key? unneeded end # Eliminar el theme si no es una gema válida - configuration.delete 'theme' unless theme_available? + @configuration.delete 'theme' unless theme_available? # Si estamos usando nuestro propio plugin de i18n, los posts están # en "colecciones" locales.each do |i| - configuration['collections'][i] = {} + @configuration['collections'][i] = {} end - configuration + @configuration end # Lista los nombres de las plantillas disponibles como gemas, @@ -438,4 +435,31 @@ class Site < ApplicationRecord errors.add(:deploys, I18n.t('activerecord.errors.models.site.attributes.deploys.deploy_local_presence')) end + + # Valida que al cambiar de plantilla no tengamos artículos en layouts + # inexistentes. + def compatible_layouts + return unless design_id_changed? + + new_configuration = configuration.dup + new_configuration['theme'] = design.gem + new_site = Jekyll::Site.new(new_configuration) + new_site.read + new_site.documents.map(&:read!) + new_layouts = new_site.layouts.keys + old_layouts = new_site.documents.map do |doc| + doc.data['layout'] + end.uniq.compact + + @incompatible_layouts = old_layouts - new_layouts + + return if @incompatible_layouts.empty? + + @incompatible_layouts.map! do |layout| + i18n.dig('layouts', layout) || layout + end + + errors.add(:design_id, + I18n.t('activerecord.errors.models.site.attributes.design_id.layout_incompatible.error')) + end end diff --git a/app/views/sites/_form.haml b/app/views/sites/_form.haml index 1623532..fc88993 100644 --- a/app/views/sites/_form.haml +++ b/app/views/sites/_form.haml @@ -1,6 +1,15 @@ +- unless site.errors.empty? + .alert.alert-info + %h4= t('.errors.title') + %p.lead= t('.errors.help') + %ul + - site.errors.messages.each_pair do |attr, error| + - error.each do |e| + %li= link_to e, '#' + attr.to_s + = form_for site, html: { class: form_class(site) } do |f| - unless site.persisted? - .form-group + .form-group#name %h2= f.label :name %p.lead= sanitize_markdown t('.help.name'), tags: %w[strong] -# @@ -17,7 +26,7 @@ - if invalid? site, :name .invalid-feedback= site.errors.messages[:name].join(', ') - .form-group + .form-group#title %h2= f.label :title %p.lead= t('.help.title') = f.text_field :title, class: form_control(site, :title), @@ -25,7 +34,7 @@ - if invalid? site, :title .invalid-feedback= site.errors.messages[:title].join(', ') - .form-group + .form-group#description %h2= f.label :description %p.lead= t('.help.description') = f.text_area :description, class: form_control(site, :description), @@ -34,9 +43,13 @@ .invalid-feedback= site.errors.messages[:description].join(', ') %hr/ - .form-group + .form-group#design_id %h2= t('.design.title') %p.lead= t('.help.design') + - if invalid? site, :design_id + .alert.alert-info + = t('activerecord.errors.models.site.attributes.design_id.layout_incompatible.help', + layouts: site.incompatible_layouts.to_sentence) .row.designs -# Demasiado complejo para un f.collection_radio_buttons - Design.all.find_each do |design| @@ -61,7 +74,7 @@ target: '_blank', class: 'btn' %hr/ - .form-group.licenses + .form-group.licenses#license_id %h2= t('.licencia.title') %p.lead= t('.help.licencia') - Licencia.all.find_each do |licencia| @@ -91,7 +104,7 @@ %hr/ - if site.persisted? - .form-group + .form-group#contact %h2= t('.contact.title') %p.lead= t('.contact.help') @@ -99,7 +112,7 @@ = f.check_box :contact, class: 'custom-control-input' = f.label :contact, class: 'custom-control-label' - .form-group + .form-group#colaboracion_anonima %h2= t('.colaboracion_anonima.title') %p.lead= t('.colaboracion_anonima.help') diff --git a/config/locales/en.yml b/config/locales/en.yml index ea4b5c1..b042c2c 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -126,6 +126,10 @@ en: confirmation: "The passwords don't match" acepta_politicas_de_privacidad: no_acepta_politicas_de_privacidad: "Please read and accept the privacy policy" + design_id: + layout_incompatible: + error: "Design can't be changed because there're posts with incompatible layouts" + help: "Your site has posts with layout only compatible to the current design. If you change it, the site won't work as you expect. If you're trying out designs, you can delete posts in the following incompatible layouts:: %{layouts}." errors: argument_error: 'Argument `%{argument}` must be an instance of %{class}' unknown_locale: 'Unknown %{locale} locale' diff --git a/config/locales/es.yml b/config/locales/es.yml index 4e910f4..d6877e8 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -99,6 +99,7 @@ es: models: usuarie: Usuarie licencia: Licencia + design: Diseño attributes: usuarie: email: 'Correo electrónico' @@ -119,6 +120,10 @@ es: attributes: deploys: deploy_local_presence: '¡Necesitamos poder generar el sitio!' + design_id: + layout_incompatible: + error: 'No se puede cambiar la plantilla porque hay artículos con formatos incompatibles' + help: 'En tu sitio hay artículos que solo son compatibles con el diseño actual, si cambias la plantilla el sitio no funcionará como esperas. Si estás probando plantillas, puedes eliminar los artículos en los formatos incompatibles: %{layouts}.' errors: argument_error: 'El argumento `%{argument}` debe ser una instancia de %{class}' unknown_locale: 'El idioma %{locale} es desconocido' @@ -344,8 +349,8 @@ es: btn: 'Configuración' form: errors: - title: Hay errores y no pudimos guardar tus cambios :( - help: Por favor, busca los campos marcados como inválidos para resolverlos + title: Hubo errores y no pudimos guardar tus cambios :( + help: Por favor, busca los campos marcados como no válidos para resolverlos help: name: 'El nombre de tu sitio que formará parte de la dirección (**ejemplo**.sutty.nl). Solo puede contener letras minúsculas, números y guiones.' title: 'El título de tu sitio puede ser lo que quieras.'