diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 59ea10f..1b357c5 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -5,9 +5,8 @@ class ApplicationController < ActionController::Base include ExceptionHandler protect_from_forgery with: :exception - before_action :configure_permitted_parameters, if: :devise_controller? - before_action :set_locale + around_action :set_locale before_action do if current_usuarie.try(:ends_with?, '@' + ENV.fetch('SUTTY', 'sutty.nl')) @@ -36,8 +35,11 @@ class ApplicationController < ActionController::Base site end - def set_locale - I18n.locale = current_usuarie.lang if current_usuarie + # El idioma es el preferido por le usuarie, pero no necesariamente se + # corresponde con el idioma de los artículos, porque puede querer + # traducirlos. + def set_locale(&action) + I18n.with_locale(current_usuarie.try(:lang) || I18n.default_locale, &action) end protected diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 4ebeaf2..8d8018a 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -5,17 +5,24 @@ class PostsController < ApplicationController include Pundit before_action :authenticate_usuarie! + # Las URLs siempre llevan el idioma actual o el de le usuarie + def default_url_options + { locale: params[:locale] || current_usuarie.try(:lang) || I18n.locale } + end + def index authorize Post + @site = find_site - @category = session[:category] = params.dig(:category) - @layout = params.dig(:layout).try :to_sym + @category = params.dig(:category) + @layout = params.dig(:layout).try(:to_sym) # XXX: Cada vez que cambiamos un Post tocamos el sitio con lo que es # más simple saber si hubo cambios. if @category || @layout || stale?(@site) # TODO: Aplicar policy_scope - @posts = @site.posts(lang: lang) + @posts = @site.posts(lang: locale) + # Orden descendiente por número y luego por fecha @posts.sort_by!(:order, :date).reverse! @usuarie = @site.usuarie? current_usuarie end @@ -23,7 +30,7 @@ class PostsController < ApplicationController def show @site = find_site - @post = @site.posts(lang: lang).find params[:id] + @post = @site.posts(lang: locale).find params[:id] authorize @post fresh_when @post @@ -32,7 +39,7 @@ class PostsController < ApplicationController def new authorize Post @site = find_site - @post = @site.posts.build(lang: lang, layout: params[:layout]) + @post = @site.posts.build(lang: locale, layout: params[:layout]) end def create @@ -53,14 +60,14 @@ class PostsController < ApplicationController def edit @site = find_site - @post = @site.posts(lang: lang).find params[:id] + @post = @site.posts(lang: locale).find params[:id] authorize @post end def update @site = find_site - @post = @site.posts(lang: lang).find params[:id] + @post = @site.posts(lang: locale).find params[:id] authorize @post @@ -81,7 +88,7 @@ class PostsController < ApplicationController # Eliminar artículos def destroy @site = find_site - @post = @site.posts(lang: lang).find params[:id] + @post = @site.posts(lang: locale).find params[:id] authorize @post @@ -111,11 +118,15 @@ class PostsController < ApplicationController end # Devuelve el idioma solicitado a través de un parámetro, validando - # que el sitio soporte ese idioma - def lang - return unless params[:lang] - return unless @site.try(:locales).try(:include?, params[:lang]) - - params[:lang] + # que el sitio soporte ese idioma, de lo contrario devuelve el idioma + # actual. + # + # TODO: Debería devolver un error o mostrar una página donde se + # solicite a le usuarie crear el nuevo idioma y que esto lo agregue al + # _config.yml del sitio en lugar de mezclar idiomas. + def locale + @site.try(:locales).try(:find, -> { I18n.locale.to_s }) do |l| + l == params[:locale] + end end end diff --git a/app/models/metadata_lang.rb b/app/models/metadata_lang.rb index b8b774a..96ba23c 100644 --- a/app/models/metadata_lang.rb +++ b/app/models/metadata_lang.rb @@ -11,6 +11,6 @@ class MetadataLang < MetadataTemplate end def values - I18n.available_locales + site.locales end end diff --git a/app/models/metadata_template.rb b/app/models/metadata_template.rb index 375a20f..56b4d27 100644 --- a/app/models/metadata_template.rb +++ b/app/models/metadata_template.rb @@ -17,10 +17,8 @@ MetadataTemplate = Struct.new(:site, :document, :name, :label, :type, # Valores posibles, busca todos los valores actuales en otros # artículos del mismo sitio - # - # TODO: Implementar lang! def values - site.everything_of(name) + site.everything_of(name, lang: post.try(:lang).try(:value)) end # Valor actual o por defecto diff --git a/app/models/site.rb b/app/models/site.rb index c6b50aa..3c3e17a 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -197,6 +197,15 @@ class Site < ApplicationRecord @posts[lang] end + # Todos los Post del sitio para poder buscar en todos. + # + # @return PostRelation + def docs + @docs ||= PostRelation.new(site: self).push(locales.flat_map do |locale| + posts(lang: locale) + end).flatten! + end + # Elimina un artículo de la colección def delete_post(post) lang = post.lang.value @@ -226,11 +235,14 @@ class Site < ApplicationRecord # # TODO: Traer recursivamente, si el campo contiene Hash # + # @param attr [Symbol|String] El atributo a buscar # @return Array def everything_of(attr, lang: nil) - posts(lang: lang).map do |p| + attr = attr.to_sym + + posts(lang: lang).flat_map do |p| p.send(attr).try(:value) if p.attribute? attr - end.flatten.uniq.compact + end.uniq.compact end # Poner en la cola de compilación diff --git a/app/services/post_service.rb b/app/services/post_service.rb index 4dfdba0..220a219 100644 --- a/app/services/post_service.rb +++ b/app/services/post_service.rb @@ -8,8 +8,8 @@ PostService = Struct.new(:site, :usuarie, :post, :params, keyword_init: true) do # # @return Post def create - self.post = site.posts(lang: lang) - .build(layout: params[:post][:layout]) + self.post = site.posts(lang: locale) + .build(layout: layout) post.usuaries << usuarie params[:post][:draft] = true if site.invitade? usuarie @@ -24,8 +24,8 @@ PostService = Struct.new(:site, :usuarie, :post, :params, keyword_init: true) do def create_anonymous # XXX: Confiamos en el parámetro de idioma porque estamos # verificándolos en Site#posts - self.post = site.posts(lang: lang) - .build(layout: params[:post][:layout]) + self.post = site.posts(lang: locale) + .build(layout: layout) # Los artículos anónimos siempre son borradores params[:post][:draft] = true @@ -58,7 +58,7 @@ PostService = Struct.new(:site, :usuarie, :post, :params, keyword_init: true) do # # { uuid => 2, uuid => 1, uuid => 0 } def reorder - posts = site.posts(lang: lang) + posts = site.posts(lang: locale) reorder = params.require(:post).permit(reorder: {}).try(:[], :reorder) modified = PostRelation.new(site: site) @@ -97,20 +97,13 @@ PostService = Struct.new(:site, :usuarie, :post, :params, keyword_init: true) do # Eliminar metadatos internos def anon_post_params - post_params.delete_if do |k, _| + params.permit(post.params).delete_if do |k, _| %w[date slug order uuid].include? k end end - # Devuelve el idioma solicitado a través de un parámetro, validando - # que el sitio soporte ese idioma - # - # TODO: DRY - def lang - return unless params[:lang] - return unless site.try(:locales).try(:include?, params[:lang]) - - params[:lang] + def locale + params.dig(:post, :lang) || I18n.locale end def layout diff --git a/app/services/site_service.rb b/app/services/site_service.rb index c6ae41c..7d64722 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -63,6 +63,8 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do # Crea la licencia del sitio para cada locale disponible en el sitio def add_licencias site.locales.map(&:to_sym).each do |locale| + next unless I18n.available_locales.include? locale + Mobility.with_locale(locale) do add_licencia lang: locale end diff --git a/app/views/posts/attribute_ro/_lang.haml b/app/views/posts/attribute_ro/_lang.haml index cb88aa1..a2df03e 100644 --- a/app/views/posts/attribute_ro/_lang.haml +++ b/app/views/posts/attribute_ro/_lang.haml @@ -1,3 +1,3 @@ %tr{ id: attribute } %th= post_label_t(attribute, post: post) - %td= t(".#{metadata.value}") + %td= t(metadata.value) diff --git a/app/views/posts/attributes/_array.haml b/app/views/posts/attributes/_array.haml index 2c3ebdb..8de3fb9 100644 --- a/app/views/posts/attributes/_array.haml +++ b/app/views/posts/attributes/_array.haml @@ -14,5 +14,5 @@ post: post, attribute: attribute, metadata: metadata %datalist{ id: id_for_datalist(attribute) } - - site.everything_of(attribute).each do |value| + - metadata.values.each do |value| %option{ value: value } diff --git a/app/views/posts/attributes/_lang.haml b/app/views/posts/attributes/_lang.haml index f4517a8..a41fbb3 100644 --- a/app/views/posts/attributes/_lang.haml +++ b/app/views/posts/attributes/_lang.haml @@ -1,2 +1 @@ --# TODO: Implementar i18n -= hidden_field_tag 'post[lang]', I18n.locale.to_s += hidden_field_tag 'post[lang]', post.try(:lang).try(:value) diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index dbd1a7c..b43ec19 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -30,8 +30,16 @@ %h2= t('posts.none') - else = form_tag site_posts_reorder_path, method: :post do - = submit_tag t('posts.reorder'), class: 'btn submit-reorder' - -# TODO: Permitir cambiar el idioma + .d-flex.justify-content-between.align-items-center + = submit_tag t('posts.reorder'), class: 'btn submit-reorder' + + -# + TODO: Pensar una interfaz mejor para cuando haya más de tres + idiomas + .locales + - @site.locales.each do |locale| + = link_to t(locale), site_posts_path(@site, locale: locale), + class: 'mr-2 mt-2 mb-2' %table.table.table-condensed.table-draggable %tbody - @posts.each_with_index do |post, i| diff --git a/config/locales/en.yml b/config/locales/en.yml index 20b6aaf..7c0cf80 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -35,6 +35,7 @@ en: no_method: '%{method} not allowed' es: Castillian Spanish en: English + ar: Arabic seconds: '%{seconds} seconds' contact_mailer: subject: '[%site] Contact form' diff --git a/config/locales/es.yml b/config/locales/es.yml index 7b7cdac..c59fa6f 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -37,6 +37,7 @@ es: no_method: '%{method} no está permitido' es: Castellano en: Inglés + ar: Árabe seconds: '%{seconds} segundos' contact_mailer: subject: '[%{site}] Formulario de contacto' diff --git a/config/routes.rb b/config/routes.rb index e993d0c..aacab67 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -46,9 +46,13 @@ Rails.application.routes.draw do get 'collaborate', to: 'collaborations#collaborate' post 'collaborate', to: 'collaborations#accept_collaboration' - # Gestionar artículos - post :'posts/reorder', to: 'posts#reorder' - resources :posts + # Gestionar artículos según idioma + nested do + scope '(:locale)' do + post :'posts/reorder', to: 'posts#reorder' + resources :posts + end + end # Gestionar traducciones get 'i18n', to: 'i18n#index'