mirror of
https://github.com/kevinveenbirkenbach/homepage.veen.world.git
synced 2026-08-24 05:04:33 +00:00
feat(i18n): offer every ISO 639-1 language
The table was thirty languages typed by hand. It is now generated: utils/generate_languages.py takes the 184 alpha-2 codes from pycountry, the display names from CLDR through babel, and the writing direction from CLDR character order. 159 languages carry their endonym; the remaining 25 have no CLDR entry and carry their English ISO name. That corrects the right-to-left set, which had four entries and needs ten — dv, ks, ps, sd, ug and yi were simply missed. Only 29 languages ship an interface catalogue, so the other 155 render in English until one is filled. make i18n-ui fills app/i18n/ui/ for them, and make i18n now covers the interface strings as well; neither asks for a string a shipped catalogue already answers, so hand-written entries stay. 184 entries do not fit on a screen, so the language menu scrolls inside itself. overscroll-behavior keeps the page behind it from moving once the list reaches its end. babel and pycountry are dev dependencies: the generator needs them, the application does not. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -53,7 +53,7 @@ describe('Language switcher', () => {
|
||||
cy.visit('/en/');
|
||||
});
|
||||
|
||||
it('names the active language and offers all thirty', () => {
|
||||
it('names the active language and offers every ISO 639-1 code', () => {
|
||||
cy.get('#navbarDropdownLanguage')
|
||||
.should('have.attr', 'data-bs-toggle', 'dropdown')
|
||||
.and('contain.text', 'English');
|
||||
@@ -61,7 +61,7 @@ describe('Language switcher', () => {
|
||||
cy.get('#navbarDropdownLanguage')
|
||||
.parent('.nav-item')
|
||||
.find('> .dropdown-menu a.dropdown-item')
|
||||
.should('have.length', 30);
|
||||
.should('have.length', 184);
|
||||
});
|
||||
|
||||
it('marks the active language', () => {
|
||||
@@ -200,6 +200,21 @@ describe('Translated interface details', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('scrolls inside the language menu instead of past the page', () => {
|
||||
cy.viewport(1280, 720);
|
||||
cy.visit('/en/');
|
||||
cy.get('#navbarDropdownLanguage').click();
|
||||
|
||||
cy.get('.dropdown-menu.language-menu').should($menu => {
|
||||
const menu = $menu[0];
|
||||
expect(menu.scrollHeight, 'taller than it shows').to.be.greaterThan(
|
||||
menu.clientHeight,
|
||||
);
|
||||
expect(menu.getBoundingClientRect().height).to.be.lessThan(720);
|
||||
expect(getComputedStyle(menu).overflowY).to.eq('auto');
|
||||
});
|
||||
});
|
||||
|
||||
it('offers the switcher in the header only', () => {
|
||||
cy.viewport(1280, 720);
|
||||
cy.visit('/en/');
|
||||
@@ -215,7 +230,7 @@ describe('Search engine metadata', () => {
|
||||
});
|
||||
|
||||
it('declares an alternate for every language plus a default', () => {
|
||||
cy.get('link[rel="alternate"][hreflang]').should('have.length', 31);
|
||||
cy.get('link[rel="alternate"][hreflang]').should('have.length', 185);
|
||||
cy.get('link[rel="alternate"][hreflang="x-default"]').should('exist');
|
||||
cy.get('link[rel="alternate"][hreflang="ja"]')
|
||||
.should('have.attr', 'href')
|
||||
|
||||
Reference in New Issue
Block a user