From bf79f99062348a8920c3f73a056470bb57673d71 Mon Sep 17 00:00:00 2001 From: Emi Date: Thu, 27 Feb 2025 19:33:16 +0100 Subject: [PATCH] Add localization plugin and initial `es` translation (#1011) * Add plugin and initial `es` translation * Add missing features to plugin * Translate home page and sponsors * Add language selector and widen nav * Fix mobile style and language selector * Add js helper file * Update header.css * translate footer --- Gemfile.lock | 16 +- _config.yml | 5 +- _i18n/en.yml | 91 ++++++++++- _i18n/es.yml | 91 ++++++++++- _includes/footer.html | 51 +++--- _includes/header.html | 40 +++-- _includes/sponsors.html | 6 +- _layouts/default.html | 23 +-- _plugins/localize.rb | 164 +++++++++++++++++++ assets/css/header.css | 271 ++++++++++++++++++++++++++++++++ assets/css/main.scss | 240 +--------------------------- assets/css/transparent-nav.scss | 6 + assets/icons/language-light.svg | 1 + assets/icons/language.svg | 1 + assets/js/localize.js | 16 ++ pages/home.html | 113 +++++-------- 16 files changed, 758 insertions(+), 377 deletions(-) create mode 100644 _plugins/localize.rb create mode 100644 assets/css/header.css create mode 100644 assets/icons/language-light.svg create mode 100644 assets/icons/language.svg create mode 100644 assets/js/localize.js diff --git a/Gemfile.lock b/Gemfile.lock index d97be49576..c86a31c46d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,10 +1,10 @@ GEM remote: https://rubygems.org/ specs: - addressable (2.8.1) - public_suffix (>= 2.0.2, < 6.0) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) colorator (1.1.0) - concurrent-ruby (1.1.10) + concurrent-ruby (1.3.5) em-websocket (0.5.3) eventmachine (>= 0.12.9) http_parser.rb (~> 0) @@ -13,7 +13,7 @@ GEM ffi (1.15.5-x64-unknown) forwardable-extended (2.6.0) http_parser.rb (0.8.0) - i18n (1.12.0) + i18n (1.14.7) concurrent-ruby (~> 1.0) jekyll (4.2.2) addressable (~> 2.4) @@ -38,8 +38,8 @@ GEM sassc (> 2.0.1, < 3.0) jekyll-watch (2.2.1) listen (~> 3.0) - kramdown (2.4.0) - rexml + kramdown (2.5.1) + rexml (>= 3.3.9) kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) liquid (4.0.4) @@ -49,11 +49,11 @@ GEM mercenary (0.4.0) pathutil (0.16.2) forwardable-extended (~> 2.6) - public_suffix (5.0.1) + public_suffix (6.0.1) rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) - rexml (3.3.9) + rexml (3.4.0) rouge (3.30.0) safe_yaml (1.0.5) sassc (2.4.0) diff --git a/_config.yml b/_config.yml index 2530c3ebac..6b571b6d91 100644 --- a/_config.yml +++ b/_config.yml @@ -67,12 +67,9 @@ defaults: plugins: - jekyll-paginate-v2 - jekyll-redirect-from - # - jekyll-multiple-languages-plugin # Internationalization -languages: ["en", "es"] -exclude_from_localizations: ["assets", "storage"] -default_lang: "en" +lang: "en" # Pagination (used by the blog) pagination: diff --git a/_i18n/en.yml b/_i18n/en.yml index 0c871733ae..b3cd7cc8a8 100644 --- a/_i18n/en.yml +++ b/_i18n/en.yml @@ -1,3 +1,90 @@ +meta: + description: Develop your 2D & 3D games, cross-platform projects, or even XR ideas! +header: + features: Features + showcase: Showcase + blog: Blog + community: Community + assets: Assets + download: Download + docs: Docs + contribute: Contribute + donate: Donate + language: Language +footer: + download: Download + documentation: Documentation + features: Features + web_editor: Web editor + release_archive: Release archive + source_code: Source code + project: Project + blog: Blog + code_of_conduct: Code of conduct + governance: Governance + teams: Teams + priorities: Priorities + communities: Communities + resources: Resources + asset_library: Asset library + press_kit: Press kit + showcase: Showcase + education: Education + foundation: Foundation + about: About + donate: Donate + license: License + privacy_policy: Privacy policy + contact_us: Contact us + text: "Juan Linietsky, Ariel Manzur and contributors. Hosted by the Godot Foundation. Website source code on GitHub." +sponsors: + title: "Godot is sponsored by:" + text: If you are interested in a corporate sponsorship, please write to contact@godot.foundation.
To donate as an individual, you can do so through the Godot Engine development fund. + cta: Donate home: - h1: "The game engine you've been waiting for." - subtitle: "A simple, responsive Jekyll theme for your blog or site." + h1: Your free, open‑source
game engine. + subtitle: Develop your 2D & 3D games, cross-platform projects, or even XR ideas! + whats_new: What's new + download_latest: Download Latest + looking_for: 'Looking for Godot 3, our experimental releases, or a previous version?' + latest_news: Latest news + more_news: More news + cards: + h2: A different way to make games + design: + title: Innovative design + text: Godot's Node and Scene system gives you both power and flexibility to create anything. + script: + title: Use the right language for the job + text: Keep your code modular with an object-oriented API using Godot's own GDScript, C#, C++, or bring your own using GDExtension. + extra: C# support is currently only available for desktop and mobile platforms as of Godot 4.2.
Use Godot 3 to run C# on the Web platform. + 2d: + title: Dedicated 2D engine + text: Make crisp and performant 2D games with Godot's dedicated 2D rendering engine with real 2D pixel coordinates and 2D nodes. + 3d: + title: Simple and powerful 3D + text: Godot's 3D nodes give you everything you need to build, animate, and render your 3D worlds and characters. + deploy: + title: Release on all platforms + text: Deploy your game on desktop, mobile, and the web in seconds. Godot even supports consoles through third party publishers. + open: + title: Open Source + text: "Truly open development: anyone who contributes to Godot benefits equally from others’ contributions." + cta: Learn more about using Godot + get_involved: + title: Get involved + text: Join the community and help create a game engine that belongs to everybody. + cards: + cta: Learn more + code: + title: Code + text: If you know how to code, you can help by fixing bugs and working with engine contributors towards the implementation of new features. + document: + title: Document + text: Documentation quality is essential in a game engine; help make it better by updating the API reference, writing new guides or submitting corrections. + report: + title: Report + text: Found a problem with the engine? Don't forget to report it so that developers can track it down. + foundation: + text: "You don't need to be an engine developer to help Godot. Join the development fund and help us make the Godot Engine even more awesome!" + donate: Donate \ No newline at end of file diff --git a/_i18n/es.yml b/_i18n/es.yml index d93bcc7b0e..6bd7ebee31 100644 --- a/_i18n/es.yml +++ b/_i18n/es.yml @@ -1,3 +1,90 @@ +meta: + description: Desarrolla tus juegos 2D y 3D, proyectos multiplataforma o incluso XR +header: + features: Funciones + showcase: Creaciones + blog: Blog + community: Comunidad + assets: Assets + download: Descargar + docs: Docs + contribute: Contribuir + donate: Donar + language: Idioma +footer: + download: Descargar + documentation: Documentación + features: Funciones + web_editor: Editor web + release_archive: Archivo de versiones + source_code: Código fuente + project: Proyecto + blog: Blog + code_of_conduct: Código de conducta + governance: Gobernanza + teams: Equipos + priorities: Prioridades + communities: Comunidades + resources: Recursos + asset_library: Biblioteca de Assets + press_kit: Kit de prensa + showcase: Creaciones + education: Educación + foundation: Fundación + about: Acerca de + donate: Donar + license: Licencia + privacy_policy: Política de privacidad + contact_us: Contáctanos + text: "Juan Linietsky, Ariel Manzur y colaboradores. Alojado por la Godot Foundation. Código fuente de la web en GitHub." +sponsors: + title: "Godot está patrocinado por:" + text: Si estás interesado en un patrocinio corporativo, por favor escribe a contact@godot.foundation.
Si quieres donar como individuo, puedes hacerlo a través del fondo de desarrollo de Godot Engine. + cta: Donar home: - h1: "Español" - subtitle: "Un tema Jekyll simple y adaptable para tu blog o sitio." + h1: Tu motor de juegos gratuito
y de código abierto. + subtitle: Desarrolla tus juegos 2D y 3D, proyectos multiplataforma o incluso XR + whats_new: Novedades + download_latest: Descargar Última Versión + looking_for: '¿Buscas Godot 3, nuestras versiones experimentales, o una versión anterior?' + latest_news: Últimas noticias (en inglés) + more_news: Más noticias + cards: + h2: Una forma diferente de hacer juegos + design: + title: "Diseño innovador" + text: "El sistema de Nodos y Escenas de Godot te da poder y flexibilidad para crear cualquier cosa." + script: + title: "Usa el lenguaje adecuado para cada trabajo" + text: "Mantén tu código modular con una API orientada a objetos usando GDScript, C#, C++, o trae el tuyo propio usando GDExtension." + extra: "El soporte para C# solo está disponible actualmente para plataformas de escritorio y móviles en Godot 4.2. Usa Godot 3 para ejecutar C# en Web." + 2d: + title: "Motor 2D dedicado" + text: "Crea juegos 2D con el motor de renderizado 2D dedicado de Godot con coordenadas de píxeles 2D reales y nodos 2D." + 3d: + title: "3D simple y potente" + text: "Los nodos 3D de Godot te dan todo lo que necesitas para construir, animar y renderizar tus mundos y personajes 3D." + deploy: + title: "Publica en todas las plataformas" + text: "Publica tu juego en escritorio, móvil y web en segundos. Godot incluso soporta consolas a través de terceros." + open: + title: "Código abierto" + text: "Desarrollo verdaderamente abierto: cualquiera que contribuya a Godot se beneficia igualmente de las contribuciones de otros." + cta: ¿Quieres saber más sobre Godot? + get_involved: + title: Contribuye + text: "Únete a la comunidad y ayuda a crear un motor de juegos que pertenezca a todos." + cards: + cta: Ver más + code: + title: Código + text: Si sabes programar, puedes ayudar a corregir errores y trabajar con los contribuyentes del motor con la implementación de nuevas funciones. + document: + title: Documenta + text: La calidad de la documentación es esencial en un motor de juegos; ayúdanos a mejorarla actualizando la referencia de la API, escribiendo nuevas guías o enviando correcciones. + report: + title: Reporta + text: ¿Encontraste un problema con el motor? No olvides reportarlo para que los desarrolladores puedan solucionarlo. + foundation: + text: "No necesitas ser un desarrollador para ayudar a Godot. ¡Únete al fondo de desarrollo y ayúdanos a hacer el motor Godot aún más impresionante!" + donate: Dona \ No newline at end of file diff --git a/_includes/footer.html b/_includes/footer.html index 57af1a21e4..bf2fa02ae1 100644 --- a/_includes/footer.html +++ b/_includes/footer.html @@ -6,49 +6,49 @@

Godot Engine

-

Project

+

{% t footer.project %}

-

Resources

+

{% t footer.resources %}

-

Foundation

+

{% t footer.foundation %}


- © 2007-{{ site.time | date: '%Y' }} Juan Linietsky, Ariel Manzur and contributors. Hosted by the Godot Foundation. Website source code on GitHub. + © 2007-{{ site.time | date: '%Y' }} {% t footer.text %}

+ diff --git a/_includes/header.html b/_includes/header.html index 9588cea9ab..085555a7f1 100644 --- a/_includes/header.html +++ b/_includes/header.html @@ -16,22 +16,44 @@
+ +
diff --git a/_includes/sponsors.html b/_includes/sponsors.html index 0fb51a3de0..9f2bf00441 100644 --- a/_includes/sponsors.html +++ b/_includes/sponsors.html @@ -1,6 +1,6 @@
-

Godot is sponsored by:

+

{% t sponsors.title %}

Patron

{% for sponsor in site.data.sponsors.patron %} @@ -33,7 +33,7 @@ {% endfor %}
-

If you want to sponsor the project, please write to contact@godot.foundation.

- Donate now! +

{% t sponsors.text %}

+ {% t sponsors.cta %}
\ No newline at end of file diff --git a/_layouts/default.html b/_layouts/default.html index a86962de53..e458556353 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -1,11 +1,11 @@ - + - + @@ -14,21 +14,23 @@ - - + - - - - - {% if page.title %} - {{ page.title | remove: " - Godot Engine" }}{% if page.notitlesuffix != true %} – Godot Engine{% endif %} + {% if page.title[current_lang] or page.title %} + {% if page.title[current_lang] %} + + {{ page.title[current_lang] | remove: " - Godot Engine" }}{% if page.notitlesuffix != true %} – Godot Engine{% endif %} + {% else %} + + {{ page.title | remove: " - Godot Engine" }}{% if page.notitlesuffix != true %} – Godot Engine{% endif %} + {% endif %} {% else %} + Godot Engine {% endif %} @@ -38,6 +40,7 @@ + diff --git a/_plugins/localize.rb b/_plugins/localize.rb new file mode 100644 index 0000000000..303f57c280 --- /dev/null +++ b/_plugins/localize.rb @@ -0,0 +1,164 @@ +# Simple localization plugin for Jekyll by Emilio Coppola v1.0 +# +# Usage: +# - Add 'localize' front matter to pages that should be localized +# - Add 'lang' front matter to pages that should have a specific language +# - Add translations to _i18n/{lang}.yml files +# - Use the '{% t useyourkeyhere %}' tag to translate text +# - Use the '{% current_lang %}' tag to get the current page language +# - Use the '{% tlink /your/path %}' tag to get the localized URL +# ---------------------------------------- +# Example `index.html`: +# --- +# localize: [en, fr] +# --- +#

{% t home.title %}

+#

Current language: {% current_lang %}

+# About +# +# _i18n/en.yml: +# home: +# title: "Welcome" +# +# _i18n/fr.yml: +# home: +# title: "Bienvenue" +# +# This will generate the following pages: +# - /index.html +# - /fr/index.html +# +# ----- +# Localize front-matter by adding an array of the languages you want to support. +# For example, to support titles in English and French: +# --- +# title: +# en: "Welcome" +# fr: "Bienvenue" +# --- +# And then use in a template or layout like this: +# {{ page.title[current_lang] | default: page.title }} +# ----- + +require 'yaml' +module Jekyll + class TranslateTag < Liquid::Tag + def initialize(tag_name, text, tokens) + super + @text = text.strip + end + + def render(context) + site = context.registers[:site] + page = context.registers[:page] + lang = page['lang'] || site.config['lang'] || 'en' + + translations = YAML.load_file(File.join(site.source, "_i18n/#{lang}.yml")) + result = @text.split('.').reduce(translations) { |result, key| result&.[](key) } + + if result.nil? + default_translations = YAML.load_file(File.join(site.source, "_i18n/en.yml")) + result = @text.split('.').reduce(default_translations) { |result, key| result&.[](key) } + return result || "Translation key doesn't exist: #{@text}" + end + + result + end + end + + class CurrentLangTag < Liquid::Tag + def render(context) + site = context.registers[:site] + page = context.registers[:page] + lang = page['lang'] || site.config['lang'] || 'en' + + # Store the language in Liquid's context + context['current_lang'] = lang + + lang # Still return the language for inline use + end + end + + class TranslateUrlTag < Liquid::Tag + def initialize(tag_name, url, tokens) + super + @url = url.strip + end + + def render(context) + site = context.registers[:site] + page = context.registers[:page] + lang = page['lang'] || site.config['lang'] || 'en' + default_lang = site.config['lang'] || 'en' + + # If we're in the default language, return the URL as is + return @url if lang == default_lang + + # Otherwise, prepend the language code + # Ensure the URL starts with a forward slash + url = @url.start_with?('/') ? @url : "/#{@url}" + "/#{lang}#{url}" + end + end + + class LocalizationGenerator < Generator + safe true + priority :high + + def clean_url(url) + # Remove any file with extension from the end of the URL + # This will match 'index.html', 'index.php', etc. + cleaned_url = url.sub(/index\.[^\/]+$/, '') + + # Ensure trailing slash + cleaned_url.end_with?('/') ? cleaned_url : "#{cleaned_url}/" + end + + def create_page(site, original_page, lang, is_default = false) + new_page = Jekyll::Page.new( + site, + site.source, + File.dirname(original_page.path), + File.basename(original_page.path) + ) + + new_page.data.merge!(original_page.data) + new_page.content = original_page.content.dup + new_page.data['lang'] = lang + + unless is_default + base_url = clean_url(original_page.url) + new_page.data['permalink'] = "/#{lang}#{base_url}" + end + + new_page + end + + def generate(site) + default_lang = site.config['lang'] || 'en' + + # Process pages with localization front matter + localizable_pages = site.pages.select { |page| page.data['localize'].is_a?(Array) } + + new_pages = localizable_pages.flat_map do |page| + # Create default language page + default_page = create_page(site, page, default_lang, true) + + # Create pages for other languages + other_pages = page.data['localize'] + .reject { |lang| lang == default_lang } + .map { |lang| create_page(site, page, lang) } + + [default_page, *other_pages] + end + + # Replace original pages with localized versions + site.pages.delete_if { |page| page.data['localize'].is_a?(Array) } + site.pages.concat(new_pages) + end + end +end + +Liquid::Template.register_tag('t', Jekyll::TranslateTag) +Liquid::Template.register_tag('current_lang', Jekyll::CurrentLangTag) +Liquid::Template.register_tag('tlink', Jekyll::TranslateUrlTag) \ No newline at end of file diff --git a/assets/css/header.css b/assets/css/header.css new file mode 100644 index 0000000000..d0d4c17858 --- /dev/null +++ b/assets/css/header.css @@ -0,0 +1,271 @@ +header { + /* Show on top of GodotCon banner (if any). */ + position: relative; + z-index: 2; + + height: 64px; + background-color: var(--navbar-background-color); + display: flex; + align-items: center; + box-shadow: var(--base-shadow); + + .container { + overflow: initial; + width: 100%; + } + #logo-link { + /* Make the logo's clickable area as tall as for other navigation links. */ + padding: 0.2rem 0.5rem; + padding-top: 6px; + margin-left: -9px; + padding-right: 15px; + margin-right: -23px; + } +} + +#nav, #nav_head { + .fund { + margin-right: 0px; + margin-left: 0px; + padding-left: 7px; + &.desktop { + @media (max-width: 1200px) { + display: none; + } + } + &.mobile { + top: -2px; + position: relative; + @media (min-width: 1200px) { + display: none; + } + } + a { + text-decoration: none; + color: #F35774; + color: white; + background-color: #F35774 !important; + border-radius: var(--button-border-radius); + box-shadow: inset 0 0 0 2px #F35774; + padding: 13px; + } + } +} + + +#nav_toggle_cb { + display: none; +} + +#nav_toggle_btn { + line-height: 0px; + cursor: pointer; + user-select: none; + border-radius: 100%; + @media (min-width: 1200px) { + display: none; + } +} + +.mobile-language-selector { + display: none; +} + +.mobile-links { + display: grid; + grid-template-columns: 1fr 49px; + align-items: center; + @media (min-width: 1200px) { + display: none; + } +} + +#nav { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + padding-left: 26px; + a { + text-decoration: none; + font-size: 16px; + font-weight: 400; + color: var(--navbar-link-color); + padding: 1.3175rem 1rem; + margin-left: 14px; + } + ul { + list-style: none; + margin: 0; + padding-left: 0; + + } + a:hover, #logo-link:hover { + background-color: hsla(0, 0%, 50%, 0.1); + } +} + +#nav > ul { + display: flex; + align-items: center; + height: 100%; +} + +#nav > ul > :first-child { + padding-left: 0; +} + +#nav > ul > :last-child { + padding-right: 0; +} + +#nav > ul li { + padding-left: 1rem; + margin-bottom: 0; + margin-left: -1rem; + margin-right: -1rem; +} + +#nav li.active > a { + color: var(--navbar-link-current-color); +} + +#nav > ul ul { + display: none; +} + +#nav_head { + display: flex; + align-items: center; + justify-content: space-between; +} + +/* Mobile style */ +@media (max-width: 1200px) { + .hide-on-mobile { + display: none; + } + + header { + height: auto; + } + header > div { + flex-direction: column; + } + + #logo-link { + margin: 0; + } + #nav_head { + width: 100%; + margin-top: 0.25rem; + } + #nav_toggle_btn { + display: block; + /* Make the navbar toggle button easier to click. */ + padding: 1.25rem; + margin-top: -0.2rem; + margin-right: -1rem; + } + #nav_toggle_btn:hover { + background-color: hsla(0, 0%, 50%, 0.15); + } + #nav_toggle_btn:active { + background-color: hsla(0, 0%, 50%, 0.25); + } + #nav_toggle_cb:checked ~ header nav { + display: block; + } + #nav { + display: none; + padding-left: 0; + } + #nav ul { + align-items: flex-start; + flex-direction: column; + height: auto; + } + #nav > ul { + margin-bottom: 16px; + } + #nav ul li { + padding: 0; + padding-top: 16px; + width: 100%; + } + #nav ul a { + width: 100%; + display: block; + /* Make links easier to click but still close to each other. */ + padding-top: 0.75rem; + padding-bottom: 0.75rem; + padding-left: 1.5rem; + padding-right: 1.5rem; + margin-top: -0.4375rem; + margin-bottom: -0.4375rem; + } + +} + +/* Language selector */ +.language-selector { + background-image: none; +} +.language-option { + @media (max-width: 1200px) { + margin-left: 30px; + } +} + +@media (prefers-color-scheme: dark) { + #nav_toggle_btn { + filter: invert(100%)saturate(0%)brightness(120%); + } +} + +/* Language selector */ +@media (min-width: 1200px) { + #nav { + .language-selector { + width: 66px; + height: 43px; + display: block; + text-align: center; + background-image: url(/assets/icons/language.svg); + background-repeat: no-repeat; + background-position: 28px 6px; + background-size: 42px; + opacity: 0.8; + margin-left: -10px; + cursor: pointer; + user-select: none; + @media (prefers-color-scheme: light) { + background-image: url(/assets/icons/language-light.svg); + } + } + .language-dropdown { + box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); + z-index: 1; + border-radius: 5px; + background: #303030; + border: 1px solid #ffffff3b; + position: relative; + top: 50px; + width: 120px; + left: -65px; + display: none; + a { + padding: 5px 10px; + margin: 0; + display: block; + } + } + .language-selector.open .language-dropdown { + display: block; + } + .language-option { + user-select: none; + } + } +} + diff --git a/assets/css/main.scss b/assets/css/main.scss index 5adff1cc50..b3190dcca7 100644 --- a/assets/css/main.scss +++ b/assets/css/main.scss @@ -37,8 +37,6 @@ --big-button-color: #478cbf; - --fund-color: #F35774; - --base-shadow: 0 0 4px rgba(0, 0, 0, 0.2); --more-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); --background-color: #d5daea; @@ -125,8 +123,6 @@ --big-button-color: #478cbf; - --fund-color: #F35774; - --base-shadow: 0 0 4px rgba(0, 0, 0, 0.4); --more-shadow: 0 2px 10px rgba(0, 0, 0, 0.4); --background-color: #202326; @@ -180,10 +176,7 @@ opacity: 0.85; } - /* Invert hamburger menu button on mobile to be visible on dark navbar. */ - #nav_toggle_btn { - filter: invert(100%) saturate(0%) brightness(120%); - } + .dark-invert { filter: invert(100%); @@ -428,168 +421,6 @@ main { padding-right: 0px; } -header { - /* Show on top of GodotCon banner (if any). */ - position: relative; - z-index: 2; - - width: 100vw; - height: 64px; - background-color: var(--navbar-background-color); - display: flex; - align-items: center; - box-shadow: var(--base-shadow); - - .container { - overflow: initial; - } - - #nav, #nav_head { - .fund { - margin-right: 0px; - &.desktop { - @media (max-width: 1200px) { - display: none; - } - } - &.mobile { - top: -2px; - position: relative; - @media (min-width: 1200px) { - display: none; - } - } - a { - text-decoration: none; - color: var(--fund-color); - color: white; - background-color: var(--fund-color) !important; // avoid hover overwrite - border-radius: var(--button-border-radius); - box-shadow: inset 0 0 0 2px var(--fund-color); - padding: 13px; - } - } - } - #logo-link { - /* Make the logo's clickable area as tall as for other navigation links. */ - padding: 0.2rem 0.5rem; - padding-top: 6px; - margin-left: -9px; - padding-right: 15px; - margin-right: -23px; - } -} - -header > div.container { - width: 100%; -} - -#nav_head { - display: flex; - align-items: center; - justify-content: space-between; -} -#nav_toggle_cb, -#nav_toggle_btn { - display: none; - line-height: 0px; - cursor: pointer; - /* Prevent double-clicking the button from highlighting the icon as selected text on desktop. */ - user-select: none; -} - -.mobile-links { - display: grid; - grid-template-columns: 1fr 49px; - align-items: center; -} - -#nav { - width: 100%; - display: flex; - justify-content: space-between; - align-items: center; - padding-right: 1rem; -} - -#nav a { - text-decoration: none; - font-size: 16px; - font-weight: 400; - color: var(--navbar-link-color); - /* Make links easier to click. */ - padding: 1.3175rem 1rem; -} - -#nav a:hover, -#logo-link:hover { - background-color: hsla(0, 0%, 50%, 0.1); -} - -#nav ul { - list-style: none; - margin: 0; - padding-left: 0; -} - -#nav > ul { - display: flex; - align-items: center; - height: 100%; -} - -#nav > ul > :first-child { - padding-left: 0; -} - -#nav > ul > :last-child { - padding-right: 0; -} - -#nav > ul li { - padding-left: 1rem; - padding-right: 1rem; - margin-bottom: 0; - margin-left: -1rem; - margin-right: -1rem; -} - -#nav li.active > a { - color: var(--navbar-link-current-color); -} - -#nav > ul ul { - display: none; -} - -a.patronImgLink { - display: inline-block; -} - -a.patronImgLink > img { - display: block; -} - -a.patreonLink { - text-decoration: none; - height: 64px !important; - margin-left: 16px !important; -} - -a.patreonLink > .patreon { - height: inherit; - padding-left: 8px; - padding-right: 8px; -} - -a.patreonLink .patreon-brand { - background-size: 160px; -} - -a.patreonLink .patreon-uppercase { - font-size: 12px; -} - ul { padding-left: 2rem; } @@ -1000,75 +831,6 @@ pre > code { article .content { width: 100%; } - - header { - height: auto; - } - header > div { - flex-direction: column; - } - - #logo-link { - margin: 0; - } - #nav_head { - width: 100%; - margin-top: 0.25rem; - } - #nav_toggle_btn { - display: block; - /* Make the navbar toggle button easier to click. */ - padding: 1.25rem; - margin-top: -0.2rem; - margin-right: -1rem; - } - #nav_toggle_btn:hover { - background-color: hsla(0, 0%, 50%, 0.15); - } - #nav_toggle_btn:active { - background-color: hsla(0, 0%, 50%, 0.25); - } - #nav_toggle_cb:checked ~ header nav { - display: block; - } - #nav { - display: none; - } - #nav ul { - align-items: flex-start; - flex-direction: column; - height: auto; - } - #nav > ul { - margin-bottom: 16px; - } - #nav ul li { - padding: 0; - padding-top: 16px; - width: 100%; - } - #nav ul a { - width: 100%; - display: block; - /* Make links easier to click but still close to each other. */ - padding-top: 0.75rem; - padding-bottom: 0.75rem; - padding-left: 1.5rem; - padding-right: 1.5rem; - margin-top: -0.4375rem; - margin-bottom: -0.4375rem; - } - a.patreonLink { - text-decoration: none; - height: 64px !important; - margin-left: 0px !important; - margin-top: 16px; - } - a.patreonLink > .patreon { - height: inherit; - padding-left: 8px; - padding-right: 8px; - } } @media (max-width: 1020px) { diff --git a/assets/css/transparent-nav.scss b/assets/css/transparent-nav.scss index 1de62bf3fc..6d3aa88de4 100644 --- a/assets/css/transparent-nav.scss +++ b/assets/css/transparent-nav.scss @@ -49,3 +49,9 @@ nav#nav { } } } + +#nav .language-selector { + @media (min-width: 1200px) { + background-image: url(/assets/icons/language.svg) !important; + } +} \ No newline at end of file diff --git a/assets/icons/language-light.svg b/assets/icons/language-light.svg new file mode 100644 index 0000000000..166a52e1ee --- /dev/null +++ b/assets/icons/language-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/language.svg b/assets/icons/language.svg new file mode 100644 index 0000000000..e30582a70e --- /dev/null +++ b/assets/icons/language.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/js/localize.js b/assets/js/localize.js new file mode 100644 index 0000000000..03e0e9ccc4 --- /dev/null +++ b/assets/js/localize.js @@ -0,0 +1,16 @@ +// Get the language label +const languageMap = { + 'en': 'English', + 'es': 'Español', + 'de': 'Deutsch', + 'ja': '日本語', + 'zh': '中文', + 'pt': 'Português' +}; + +document.querySelectorAll('.localize-language-label').forEach(function(el) { + const lang = el.textContent; + if (languageMap[lang]) { + el.textContent = languageMap[lang]; + } +}); \ No newline at end of file diff --git a/pages/home.html b/pages/home.html index 47af869fa8..e036b24ae5 100644 --- a/pages/home.html +++ b/pages/home.html @@ -1,10 +1,13 @@ --- permalink: / -title: "Godot Engine - Free and open source 2D and 3D game engine" +title: + en: "Godot Engine - Free and open source 2D and 3D game engine" + es: "Godot Engine - Motor de videojuegos 2D y 3D gratuito y de código abierto" notitlesuffix: true description: "Godot provides a huge set of common tools, so you can just focus on making your game without reinventing the wheel." layout: default +localize: ["en", "es"] --- {% include header.html %} @@ -199,11 +202,8 @@ layout: default
-

- Your free, open‑source
- game engine. -

-

Develop your 2D & 3D games, cross-platform projects, or even XR ideas!

+

{% t home.h1 %}

+

{% t home.subtitle %}

{% assign stable_version_3 = site.data.versions | find: "featured", "3" %} @@ -213,16 +213,16 @@ layout: default - Looking for Godot 3, our experimental releases, or a previous version? + {% t home.looking_for %}
@@ -233,7 +233,7 @@ layout: default
-

Latest news

+

{% t home.latest_news %}

{% assign latest_posts = site.article | sort:"date" | reverse %} @@ -267,7 +267,7 @@ layout: default {% endif %} {% endfor %}
@@ -276,7 +276,7 @@ layout: default
-

A different way to make games

+

{% t home.cards.h2 %}

@@ -298,15 +296,8 @@ layout: default
-

Use the right language for the job

-

- Keep your code modular with an object-oriented API using Godot's own - GDScript, C#, C++, or bring your own using GDExtension. -

- C# support is currently only available for desktop and mobile platforms - as of Godot 4.2.
Use Godot 3 to run C# on the Web platform. -
-

+

{%t home.cards.script.title %}

+

{%t home.cards.script.text %}

{%t home.cards.script.extra %}

@@ -315,11 +306,8 @@ layout: default
-

Dedicated 2D engine

-

- Make crisp and performant 2D games with Godot's dedicated 2D - rendering engine with real 2D pixel coordinates and 2D nodes. -

+

{%t home.cards.2d.title %}

+

{%t home.cards.2d.text %}

@@ -329,11 +317,8 @@ layout: default
-

Simple and powerful 3D

-

- Godot's 3D nodes give you everything you need to build, animate, - and render your 3D worlds and characters. -

+

{%t home.cards.3d.title %}

+

{%t home.cards.3d.text %}

@@ -343,11 +328,8 @@ layout: default
-

Release on all platforms

-

- Deploy your game on desktop, mobile, and the web in seconds. Godot - even supports consoles through third party publishers. -

+

{%t home.cards.deploy.title %}

+

{%t home.cards.deploy.text %}

@@ -357,59 +339,47 @@ layout: default
-

Open Source

-

- Truly open development: anyone who contributes to Godot benefits - equally from others’ contributions. -

+

{%t home.cards.open.title %}

+

{%t home.cards.open.text %}

-

Get involved

-

- Join the community and help create a game engine that belongs to everybody. +

{%t home.get_involved.title %}

+

{%t home.get_involved.text %}

-

Code

-

- If you know how to code, you can help by fixing bugs and working with engine contributors towards the - implementation of new features. -

+

{%t home.get_involved.cards.code.title %}

+

{%t home.get_involved.cards.code.text %}

Learn more + class="btn btn-flat btn-flat-frosted" target="_blank" rel="noopener">{%t home.get_involved.cards.cta %}
-

Document

-

- Documentation quality is essential in a game engine; help make it better by updating the API reference, writing - new guides or submitting corrections. -

+

{%t home.get_involved.cards.document.title %}

+

{%t home.get_involved.cards.document.text %}

Learn more + class="btn btn-flat btn-flat-frosted" target="_blank" rel="noopener">{%t home.get_involved.cards.cta %}
-

Report

-

- Found a problem with the engine? Don't forget to report it so that developers can track it down. -

+

{%t home.get_involved.cards.report.title %}

+

{%t home.get_involved.cards.report.text %}

Learn more + class="btn btn-flat btn-flat-frosted" target="_blank" rel="noopener">{%t home.get_involved.cards.cta %}
@@ -421,11 +391,9 @@ layout: default Godot Foundation logo -

- You don't need to be an engine developer to help Godot. Join the development fund and help us make the Godot Engine even more awesome! -

+

{%t home.foundation.text %}

- Donate + {%t home.foundation.donate %}
@@ -434,10 +402,6 @@ layout: default