From 03473b53e1bdebb5cf73194ccf462604e080a844 Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Wed, 7 Oct 2026 01:23:55 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=AC=20Muestra=20cada=20idioma=20en=20s?= =?UTF-8?q?u=20propia=20lengua?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/base/component/form/select_language.rs | 23 +++++++---- tests/component_form_select_language.rs | 47 ++++++++++++---------- 2 files changed, 42 insertions(+), 28 deletions(-) diff --git a/src/base/component/form/select_language.rs b/src/base/component/form/select_language.rs index f2743c1b..6f8b283a 100644 --- a/src/base/component/form/select_language.rs +++ b/src/base/component/form/select_language.rs @@ -3,8 +3,10 @@ use crate::prelude::*; /// Componente para **elegir un idioma** de la lista de idiomas soportados por PageTop. /// /// Ofrece un elemento por cada idioma de [`Locale::supported_languages()`], con su identificador -/// como valor (p. ej. `"es-ES"`) y su nombre traducido como etiqueta, ordenados por ese nombre en -/// el idioma de la página. Se renderiza como cualquier [`form::select::Field`]. +/// como valor (p. ej. `"es-ES"`) y su nombre escrito en ese mismo idioma como etiqueta (p. ej. +/// *"Español (España)"* o *"English (United States)"*), sea cual sea el idioma de la página; así +/// cualquiera reconoce el suyo aunque no entienda el de la página. Se ordenan por ese nombre, sin +/// distinguir mayúsculas ni acentos. Se renderiza como cualquier [`form::select::Field`]. /// /// La primera opción, con valor vacío, depende de si el campo es obligatorio: /// @@ -46,8 +48,16 @@ impl Component for SelectLanguage { async fn prepare(&self, cx: &mut Context) -> Result { let mut field = self.field().clone(); - let mut languages = Locale::supported_languages(); - languages.sort_by_cached_key(|(_, name)| name.collation_key(&*cx)); + let mut languages: Vec<_> = Locale::supported_languages() + .into_iter() + .map(|(langid, name)| { + let own = name + .lookup(&Locale::Resolved(langid)) + .unwrap_or_else(|| langid.to_string()); + (langid, own) + }) + .collect(); + languages.sort_by_cached_key(|(_, name)| Lc::n(name.clone()).collation_key(&*cx)); let selected = Locale::resolve(self.selected()).as_option(); let known = selected.is_some(); @@ -56,8 +66,7 @@ impl Component for SelectLanguage { let default_name = languages .iter() .find(|(langid, _)| *langid == default_langid) - .and_then(|(_, name)| name.lookup(cx)) - .unwrap_or_else(|| default_langid.to_string()); + .map_or_else(|| default_langid.to_string(), |(_, name)| name.clone()); let label = Lc::l("select_language_site_default").with_arg("language", default_name); field.alter_item(form::select::Item::new("", label).with_selected(!known)); } else if !known { @@ -66,7 +75,7 @@ impl Component for SelectLanguage { } for (langid, name) in languages { - let item = form::select::Item::new(langid.to_string(), name); + let item = form::select::Item::new(langid.to_string(), Lc::n(name)); field.alter_item(item.with_selected(selected == Some(langid))); } Ok(field.render(cx).await) diff --git a/tests/component_form_select_language.rs b/tests/component_form_select_language.rs index db9fd091..e3149011 100644 --- a/tests/component_form_select_language.rs +++ b/tests/component_form_select_language.rs @@ -75,27 +75,32 @@ async fn unknown_selected_value_falls_back_to_the_empty_option() { assert!(html.contains(r#""#)); } +// Languages are sorted by their own name, so the order is the same for every page language. #[pagetop::test] -async fn languages_are_sorted_by_their_translated_name() { +async fn languages_are_sorted_by_their_own_name() { let mut field = form::SelectLanguage::new(); - - let mut cx = Context::default().with_langid(&Locale::resolve("es-ES")); - let html = field.render(&mut cx).await.into_string(); - let spanish = html - .find(">Español (España)") - .expect("Spanish name"); - let english = html - .find(">Inglés (Estados Unidos)") - .expect("English name"); - assert!(spanish < english); - - let mut cx = Context::default().with_langid(&Locale::resolve("en-US")); - let html = field.render(&mut cx).await.into_string(); - let spanish = html - .find(">Spanish (Spain)") - .expect("Spanish name"); - let english = html - .find(">English (United States)") - .expect("English name"); - assert!(english < spanish); + for page in ["en-US", "es-ES"] { + let mut cx = Context::default().with_langid(&Locale::resolve(page)); + let html = field.render(&mut cx).await.into_string(); + let english = html + .find(">English (United States)") + .expect("English name"); + let spanish = html + .find(">Español (España)") + .expect("Spanish name"); + assert!(english < spanish); + } +} + +// Each language is labelled in its own language, whatever the language of the page. +#[pagetop::test] +async fn languages_are_labelled_in_their_own_language() { + for page in ["en-US", "es-ES"] { + let mut field = form::SelectLanguage::new(); + let mut cx = Context::default().with_langid(&Locale::resolve(page)); + let html = field.render(&mut cx).await.into_string(); + + assert!(html.contains(r#""#)); + assert!(html.contains(r#""#)); + } }