diff --git a/.gitignore b/.gitignore index ba354d25..394e0172 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ .env +.env.local .netlify .hugo_build.lock -node_modules -public -resources +node_modules/ +public/ +resources/ +.DS_Store +.cache/ diff --git a/README.md b/README.md index 61ec4ed4..fc20117d 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ A **FACODI** é uma plataforma de aprendizagem aberta que replica planos curricu - 🎓 Unidades curriculares com ementa, resultados de aprendizagem e tópicos - 🎥 Playlists abertas do YouTube organizadas por prioridade - 📝 Conteúdo em Markdown sincronizado automaticamente com o Supabase -- 🌐 Multilíngue (PT como padrão, EN preparado como fallback) +- 🌐 Multilíngue (PT, EN, ES, FR) --- @@ -33,15 +33,27 @@ facodi.pt/ ├─ config/ │ └─ _default/ ├─ content/ -│ ├─ _index.md -│ └─ courses/ -│ └─ LESTI/ -│ └─ 2024-2025/ -│ ├─ index.md # Curso -│ └─ uc/ -│ └─ LESTI-ALG1/ -│ ├─ index.md # Unidade curricular -│ └─ estruturas-de-dados.md # Tópico +│ ├─ pt/ +│ │ ├─ _index.md +│ │ └─ courses/ +│ │ └─ LESTI/ +│ │ └─ 2024-2025/ +│ │ ├─ index.md # Curso (PT) +│ │ └─ uc/ +│ │ └─ LESTI-ALG1/ +│ │ ├─ index.md # Unidade curricular (PT) +│ │ └─ estruturas-de-dados.md # Tópico (PT) +│ ├─ en/ +│ │ └─ _index.md +│ ├─ es/ +│ │ └─ _index.md +│ └─ fr/ +│ └─ _index.md +├─ i18n/ +│ ├─ pt.yaml +│ ├─ en.yaml +│ ├─ es.yaml +│ └─ fr.yaml ├─ layouts/ │ ├─ _default/baseof.html │ ├─ course/single.html @@ -63,6 +75,14 @@ facodi.pt/ --- +## 🧭 Separação de responsabilidades + +- **Hugo (este repositório)**: guarda todo o conteúdo editorial, configurações multilíngues, layouts e scripts que sincronizam Markdown → Supabase. As chaves do Supabase são lidas via variáveis de ambiente (Netlify/GitHub Actions) e nunca ficam em arquivos versionados. +- **Portal Next.js (futuro)**: consumirá o conteúdo publicado no Supabase para experiências dinâmicas. Quando o portal estiver ativo, chamadas ao Supabase serão feitas no front-end do portal, enquanto o site Hugo permanece estático. +- **Supabase**: continua a ser a origem de dados sincronizada pelos scripts `lint:content`/`sync:content`, preservando o esquema existente (`catalog`, `subjects`, `mapping`). + +--- + ## 🛠️ Scripts disponíveis | Script | Descrição | diff --git a/config/_default/hugo.toml b/config/_default/hugo.toml index 72679145..09ac7205 100644 --- a/config/_default/hugo.toml +++ b/config/_default/hugo.toml @@ -10,7 +10,7 @@ rssLimit = 10 summarylength = 40 defaultContentLanguage = "pt" -defaultContentLanguageInSubdir = false +defaultContentLanguageInSubdir = true copyRight = "FACODI — Conteúdo aberto para aprendizagem comunitária" diff --git a/config/_default/languages.toml b/config/_default/languages.toml index 8846aa2e..0685daf0 100644 --- a/config/_default/languages.toml +++ b/config/_default/languages.toml @@ -1,6 +1,6 @@ [pt] languageName = "Português" - contentDir = "content" + contentDir = "content/pt" weight = 1 [pt.params] languageISO = "PT" @@ -14,4 +14,22 @@ [en.params] languageISO = "EN" languageTag = "en-US" - footer = 'Built by the FACODI community. English content coming soon.' + footer = 'Built by the FACODI community. English content is being translated progressively.' + +[es] + languageName = "Español" + contentDir = "content/es" + weight = 3 + [es.params] + languageISO = "ES" + languageTag = "es-ES" + footer = 'Construido por la comunidad FACODI. Traducciones en curso.' + +[fr] + languageName = "Français" + contentDir = "content/fr" + weight = 4 + [fr.params] + languageISO = "FR" + languageTag = "fr-FR" + footer = 'Construit par la communauté FACODI. Traductions en cours.' diff --git a/config/_default/menus/menus.es.toml b/config/_default/menus/menus.es.toml new file mode 100644 index 00000000..3afba7b9 --- /dev/null +++ b/config/_default/menus/menus.es.toml @@ -0,0 +1,9 @@ +[[main]] + name = "Cursos" + url = "/" + weight = 10 + +[[footer]] + name = "Comunidad" + url = "https://github.com/Monynha-Softwares/facodi.pt" + weight = 10 diff --git a/config/_default/menus/menus.fr.toml b/config/_default/menus/menus.fr.toml new file mode 100644 index 00000000..b43ee009 --- /dev/null +++ b/config/_default/menus/menus.fr.toml @@ -0,0 +1,9 @@ +[[main]] + name = "Cours" + url = "/" + weight = 10 + +[[footer]] + name = "Communauté" + url = "https://github.com/Monynha-Softwares/facodi.pt" + weight = 10 diff --git a/config/_default/params.toml b/config/_default/params.toml index 1ce8f688..6e1bb80d 100644 --- a/config/_default/params.toml +++ b/config/_default/params.toml @@ -63,10 +63,6 @@ mainSections = ["courses"] krokiURL = "https://kroki.io" -[supabase] - url = "" - anon_key = "" - [seo] [seo.title] separator = " | " diff --git a/content/en/_index.md b/content/en/_index.md index 41521c1f..02fcc0a5 100644 --- a/content/en/_index.md +++ b/content/en/_index.md @@ -1,7 +1,7 @@ --- title: "FACODI Catalog" layout: home -draft: true --- FACODI content is primarily authored in Portuguese. English translations will be published as they become available. +In the meantime, you can explore the Portuguese catalog while we expand our multilingual offering. diff --git a/content/es/_index.md b/content/es/_index.md new file mode 100644 index 00000000..c6c3ca65 --- /dev/null +++ b/content/es/_index.md @@ -0,0 +1,7 @@ +--- +title: "Catálogo FACODI" +layout: home +--- + +El catálogo original de FACODI se publica en portugués y las traducciones se añaden de forma progresiva. +Mientras trabajamos en la localización completa, puedes navegar por la versión portuguesa para descubrir los cursos y unidades curriculares disponibles. diff --git a/content/fr/_index.md b/content/fr/_index.md new file mode 100644 index 00000000..5fe4bd9f --- /dev/null +++ b/content/fr/_index.md @@ -0,0 +1,7 @@ +--- +title: "Catalogue FACODI" +layout: home +--- + +Le catalogue principal de FACODI est publié en portugais et les traductions sont ajoutées progressivement. +En attendant la localisation complète, consultez la version portugaise pour explorer les cours et les unités curriculaires disponibles. diff --git a/content/_index.md b/content/pt/_index.md similarity index 100% rename from content/_index.md rename to content/pt/_index.md diff --git a/content/courses/LESTI/2024-2025/index.md b/content/pt/courses/LESTI/2024-2025/index.md similarity index 100% rename from content/courses/LESTI/2024-2025/index.md rename to content/pt/courses/LESTI/2024-2025/index.md diff --git a/content/courses/LESTI/2024-2025/uc/LESTI-ALG1/estruturas-de-dados.md b/content/pt/courses/LESTI/2024-2025/uc/LESTI-ALG1/estruturas-de-dados.md similarity index 100% rename from content/courses/LESTI/2024-2025/uc/LESTI-ALG1/estruturas-de-dados.md rename to content/pt/courses/LESTI/2024-2025/uc/LESTI-ALG1/estruturas-de-dados.md diff --git a/content/courses/LESTI/2024-2025/uc/LESTI-ALG1/index.md b/content/pt/courses/LESTI/2024-2025/uc/LESTI-ALG1/index.md similarity index 100% rename from content/courses/LESTI/2024-2025/uc/LESTI-ALG1/index.md rename to content/pt/courses/LESTI/2024-2025/uc/LESTI-ALG1/index.md diff --git a/hugo_stats.json b/hugo_stats.json index 5176c09e..bbb4761e 100644 --- a/hugo_stats.json +++ b/hugo_stats.json @@ -23,7 +23,6 @@ "line", "link", "meta", - "nav", "noscript", "p", "path", @@ -58,14 +57,12 @@ "container", "container-lg", "content", - "courses", "current", "d-flex", "d-inline-flex", "d-lg-none", "display-5", "display-6", - "doks-sidebar", "dropdown", "dropdown-caret", "dropdown-divider", @@ -73,12 +70,15 @@ "dropdown-menu", "dropdown-menu-lg-end", "dropdown-toggle", + "en", "error404", + "es", "fixed-bottom-right", "flex-column", "flex-grow-1", "flex-lg-row", "footer", + "fr", "fw-semibold", "g-3", "g-4", @@ -92,7 +92,6 @@ "icon-tabler", "icon-tabler-chevron-down", "icon-tabler-chevron-up", - "icon-tabler-dots-vertical", "icon-tabler-language", "icon-tabler-menu", "icon-tabler-moon", @@ -100,7 +99,6 @@ "icon-tabler-x", "justify-content-between", "justify-content-center", - "lead", "list", "list-inline", "list-inline-item", @@ -117,8 +115,6 @@ "ms-auto", "ms-lg-2", "mt-1", - "mt-3", - "mt-n3", "mx-2", "mx-auto", "my-3", @@ -132,7 +128,6 @@ "offcanvas-body", "offcanvas-end", "offcanvas-header", - "offcanvas-start", "offcanvas-title", "order-3", "order-lg-2", @@ -141,6 +136,7 @@ "p-4", "pb-4", "pe-4", + "pt", "py-5", "rounded", "rounded-3", @@ -160,7 +156,6 @@ "text-lg-end", "text-lg-start", "text-muted", - "text-start", "text-uppercase", "visually-hidden", "wrap" @@ -168,13 +163,10 @@ "ids": [ "buttonColorMode", "course-content-md", - "doks-docs-nav", "doks-language-current", "doks-languages", "offcanvasNavMain", "offcanvasNavMainLabel", - "offcanvasNavSection", - "offcanvasNavSectionLabel", "toTop", "visão-geral" ] diff --git a/i18n/en.yaml b/i18n/en.yaml new file mode 100644 index 00000000..5f35c574 --- /dev/null +++ b/i18n/en.yaml @@ -0,0 +1,145 @@ +- id: home_plan_label + translation: "Plan" +- id: home_duration_semester + translation: "semester" +- id: home_duration_semesters + translation: "semesters" +- id: home_summary_placeholder + translation: "Documentation in progress." +- id: home_empty_state + translation: "No courses published yet. Check back soon!" + +- id: course_code_prefix + translation: "Course" +- id: course_plan_label + translation: "Curriculum plan" +- id: course_synced_heading + translation: "Synced content" +- id: course_synced_loading + translation: "Loading detailed description from Supabase…" +- id: course_content_placeholder + translation: "No synced content is available for this course yet." +- id: course_ucs_heading + translation: "Course units" +- id: course_ucs_loading + translation: "Loading course units…" +- id: course_ucs_empty + translation: "No course units have been synchronised." +- id: course_ucs_description_placeholder + translation: "Description coming soon." +- id: course_details_heading + translation: "Course details" +- id: course_details_institution + translation: "Institution" +- id: course_details_school + translation: "School" +- id: course_details_ects + translation: "ECTS" +- id: course_details_duration + translation: "Duration" +- id: course_details_duration_suffix + translation: "semesters" +- id: course_details_duration_suffix_singular + translation: "semester" +- id: course_details_language + translation: "Language" +- id: course_ucs_meta + translation: "Semester {{ .semester }} · {{ .ects }} ECTS" +- id: course_error_details + translation: "Failed to load course details." +- id: course_error_content + translation: "We could not load the synced content." +- id: course_error_ucs + translation: "We could not load the course units." +- id: course_not_found + translation: "Course not found." + +- id: uc_code_prefix + translation: "Course unit" +- id: uc_synced_heading + translation: "Official content" +- id: uc_synced_loading + translation: "Synchronising syllabus and materials…" +- id: uc_content_placeholder + translation: "Content not available yet." +- id: uc_outcomes_heading + translation: "Learning outcomes" +- id: uc_outcomes_loading + translation: "Loading outcomes…" +- id: uc_outcomes_empty + translation: "No outcomes have been registered." +- id: uc_playlists_heading + translation: "Recommended playlists" +- id: uc_playlists_loading + translation: "Loading playlists…" +- id: uc_playlists_empty + translation: "No playlists linked yet." +- id: uc_playlists_priority_label + translation: "Priority" +- id: uc_playlists_button_label + translation: "Open playlist" +- id: uc_topics_heading + translation: "Related topics" +- id: uc_topics_loading + translation: "Loading topics…" +- id: uc_topics_empty + translation: "No topics linked yet." +- id: uc_topics_summary_placeholder + translation: "Summary coming soon." +- id: uc_details_heading + translation: "Information" +- id: uc_details_course + translation: "Course" +- id: uc_details_ects + translation: "ECTS" +- id: uc_details_semester + translation: "Semester" +- id: uc_details_language + translation: "Language" +- id: uc_details_prerequisites + translation: "Prerequisites" +- id: uc_error_details + translation: "Failed to load course-unit information." +- id: uc_error_content + translation: "The synced syllabus could not be loaded." +- id: uc_error_outcomes + translation: "Error loading learning outcomes." +- id: uc_error_playlists + translation: "Error loading playlists." +- id: uc_error_topics + translation: "Error loading topics." +- id: uc_not_found + translation: "Course unit not found." + +- id: topic_code_prefix + translation: "Topic" +- id: topic_synced_heading + translation: "Synced content" +- id: topic_synced_loading + translation: "Loading Markdown content…" +- id: topic_content_placeholder + translation: "Content coming soon." +- id: topic_playlists_heading + translation: "Related playlists" +- id: topic_playlists_loading + translation: "Loading playlists…" +- id: topic_playlists_empty + translation: "No playlists registered yet." +- id: topic_playlists_priority_label + translation: "Priority" +- id: topic_playlists_button_label + translation: "Open playlist" +- id: topic_tags_heading + translation: "Tags" +- id: topic_tags_loading + translation: "Loading tags…" +- id: topic_tags_empty + translation: "No tags available." +- id: topic_error_content + translation: "The topic content could not be loaded." +- id: topic_error_playlists + translation: "Error loading playlists." +- id: topic_error_tags + translation: "Error loading tags." +- id: topic_not_found + translation: "Topic not found." diff --git a/i18n/es.yaml b/i18n/es.yaml new file mode 100644 index 00000000..bf8e8771 --- /dev/null +++ b/i18n/es.yaml @@ -0,0 +1,145 @@ +- id: home_plan_label + translation: "Plan" +- id: home_duration_semester + translation: "semestre" +- id: home_duration_semesters + translation: "semestres" +- id: home_summary_placeholder + translation: "Documentación en preparación." +- id: home_empty_state + translation: "Todavía no hay cursos publicados. ¡Vuelve pronto!" + +- id: course_code_prefix + translation: "Curso" +- id: course_plan_label + translation: "Plan curricular" +- id: course_synced_heading + translation: "Contenido sincronizado" +- id: course_synced_loading + translation: "Cargando la descripción detallada desde Supabase…" +- id: course_content_placeholder + translation: "Aún no hay contenido sincronizado para este curso." +- id: course_ucs_heading + translation: "Unidades curriculares" +- id: course_ucs_loading + translation: "Cargando unidades curriculares…" +- id: course_ucs_empty + translation: "No hay unidades curriculares sincronizadas." +- id: course_ucs_description_placeholder + translation: "Descripción en preparación." +- id: course_details_heading + translation: "Detalles del curso" +- id: course_details_institution + translation: "Institución" +- id: course_details_school + translation: "Escuela" +- id: course_details_ects + translation: "ECTS" +- id: course_details_duration + translation: "Duración" +- id: course_details_duration_suffix + translation: "semestres" +- id: course_details_duration_suffix_singular + translation: "semestre" +- id: course_details_language + translation: "Idioma" +- id: course_ucs_meta + translation: "Semestre {{ .semester }} · {{ .ects }} ECTS" +- id: course_error_details + translation: "Error al cargar los detalles del curso." +- id: course_error_content + translation: "No fue posible cargar el contenido sincronizado." +- id: course_error_ucs + translation: "No fue posible cargar las unidades curriculares." +- id: course_not_found + translation: "Curso no encontrado." + +- id: uc_code_prefix + translation: "Unidad curricular" +- id: uc_synced_heading + translation: "Contenido oficial" +- id: uc_synced_loading + translation: "Sincronizando programa y materiales…" +- id: uc_content_placeholder + translation: "Contenido aún no disponible." +- id: uc_outcomes_heading + translation: "Resultados de aprendizaje" +- id: uc_outcomes_loading + translation: "Cargando resultados…" +- id: uc_outcomes_empty + translation: "No hay resultados registrados." +- id: uc_playlists_heading + translation: "Listas recomendadas" +- id: uc_playlists_loading + translation: "Cargando listas…" +- id: uc_playlists_empty + translation: "No hay listas asociadas." +- id: uc_playlists_priority_label + translation: "Prioridad" +- id: uc_playlists_button_label + translation: "Abrir lista" +- id: uc_topics_heading + translation: "Temas asociados" +- id: uc_topics_loading + translation: "Cargando temas…" +- id: uc_topics_empty + translation: "No hay temas asociados." +- id: uc_topics_summary_placeholder + translation: "Resumen en preparación." +- id: uc_details_heading + translation: "Información" +- id: uc_details_course + translation: "Curso" +- id: uc_details_ects + translation: "ECTS" +- id: uc_details_semester + translation: "Semestre" +- id: uc_details_language + translation: "Idioma" +- id: uc_details_prerequisites + translation: "Prerrequisitos" +- id: uc_error_details + translation: "Error al cargar la información de la unidad curricular." +- id: uc_error_content + translation: "No fue posible cargar el programa sincronizado." +- id: uc_error_outcomes + translation: "Error al cargar los resultados de aprendizaje." +- id: uc_error_playlists + translation: "Error al cargar las listas." +- id: uc_error_topics + translation: "Error al cargar los temas." +- id: uc_not_found + translation: "Unidad curricular no encontrada." + +- id: topic_code_prefix + translation: "Tema" +- id: topic_synced_heading + translation: "Contenido sincronizado" +- id: topic_synced_loading + translation: "Cargando contenido Markdown…" +- id: topic_content_placeholder + translation: "Contenido en preparación." +- id: topic_playlists_heading + translation: "Listas relacionadas" +- id: topic_playlists_loading + translation: "Cargando listas…" +- id: topic_playlists_empty + translation: "No hay listas registradas." +- id: topic_playlists_priority_label + translation: "Prioridad" +- id: topic_playlists_button_label + translation: "Abrir lista" +- id: topic_tags_heading + translation: "Etiquetas" +- id: topic_tags_loading + translation: "Cargando etiquetas…" +- id: topic_tags_empty + translation: "No hay etiquetas." +- id: topic_error_content + translation: "No fue posible cargar el contenido del tema." +- id: topic_error_playlists + translation: "Error al cargar las listas." +- id: topic_error_tags + translation: "Error al cargar las etiquetas." +- id: topic_not_found + translation: "Tema no encontrado." diff --git a/i18n/fr.yaml b/i18n/fr.yaml new file mode 100644 index 00000000..320b8858 --- /dev/null +++ b/i18n/fr.yaml @@ -0,0 +1,145 @@ +- id: home_plan_label + translation: "Plan" +- id: home_duration_semester + translation: "semestre" +- id: home_duration_semesters + translation: "semestres" +- id: home_summary_placeholder + translation: "Documentation en préparation." +- id: home_empty_state + translation: "Aucun cours publié pour le moment. Revenez bientôt !" + +- id: course_code_prefix + translation: "Cours" +- id: course_plan_label + translation: "Plan d'études" +- id: course_synced_heading + translation: "Contenu synchronisé" +- id: course_synced_loading + translation: "Chargement de la description détaillée depuis Supabase…" +- id: course_content_placeholder + translation: "Aucun contenu synchronisé n'est disponible pour ce cours pour l'instant." +- id: course_ucs_heading + translation: "Unités curriculaires" +- id: course_ucs_loading + translation: "Chargement des unités curriculaires…" +- id: course_ucs_empty + translation: "Aucune unité curriculaire synchronisée." +- id: course_ucs_description_placeholder + translation: "Description en préparation." +- id: course_details_heading + translation: "Détails du cours" +- id: course_details_institution + translation: "Institution" +- id: course_details_school + translation: "École" +- id: course_details_ects + translation: "ECTS" +- id: course_details_duration + translation: "Durée" +- id: course_details_duration_suffix + translation: "semestres" +- id: course_details_duration_suffix_singular + translation: "semestre" +- id: course_details_language + translation: "Langue" +- id: course_ucs_meta + translation: "Semestre {{ .semester }} · {{ .ects }} ECTS" +- id: course_error_details + translation: "Échec du chargement des détails du cours." +- id: course_error_content + translation: "Impossible de charger le contenu synchronisé." +- id: course_error_ucs + translation: "Impossible de charger les unités curriculaires." +- id: course_not_found + translation: "Cours introuvable." + +- id: uc_code_prefix + translation: "Unité curriculaire" +- id: uc_synced_heading + translation: "Contenu officiel" +- id: uc_synced_loading + translation: "Synchronisation du programme et des ressources…" +- id: uc_content_placeholder + translation: "Contenu non disponible pour le moment." +- id: uc_outcomes_heading + translation: "Résultats d'apprentissage" +- id: uc_outcomes_loading + translation: "Chargement des résultats…" +- id: uc_outcomes_empty + translation: "Aucun résultat enregistré." +- id: uc_playlists_heading + translation: "Playlists recommandées" +- id: uc_playlists_loading + translation: "Chargement des playlists…" +- id: uc_playlists_empty + translation: "Aucune playlist associée." +- id: uc_playlists_priority_label + translation: "Priorité" +- id: uc_playlists_button_label + translation: "Ouvrir la playlist" +- id: uc_topics_heading + translation: "Sujets associés" +- id: uc_topics_loading + translation: "Chargement des sujets…" +- id: uc_topics_empty + translation: "Aucun sujet associé." +- id: uc_topics_summary_placeholder + translation: "Résumé en préparation." +- id: uc_details_heading + translation: "Informations" +- id: uc_details_course + translation: "Cours" +- id: uc_details_ects + translation: "ECTS" +- id: uc_details_semester + translation: "Semestre" +- id: uc_details_language + translation: "Langue" +- id: uc_details_prerequisites + translation: "Prérequis" +- id: uc_error_details + translation: "Échec du chargement des informations de l'unité curriculaire." +- id: uc_error_content + translation: "Impossible de charger le programme synchronisé." +- id: uc_error_outcomes + translation: "Erreur lors du chargement des résultats d'apprentissage." +- id: uc_error_playlists + translation: "Erreur lors du chargement des playlists." +- id: uc_error_topics + translation: "Erreur lors du chargement des sujets." +- id: uc_not_found + translation: "Unité curriculaire introuvable." + +- id: topic_code_prefix + translation: "Sujet" +- id: topic_synced_heading + translation: "Contenu synchronisé" +- id: topic_synced_loading + translation: "Chargement du contenu Markdown…" +- id: topic_content_placeholder + translation: "Contenu en préparation." +- id: topic_playlists_heading + translation: "Playlists associées" +- id: topic_playlists_loading + translation: "Chargement des playlists…" +- id: topic_playlists_empty + translation: "Aucune playlist enregistrée." +- id: topic_playlists_priority_label + translation: "Priorité" +- id: topic_playlists_button_label + translation: "Ouvrir la playlist" +- id: topic_tags_heading + translation: "Étiquettes" +- id: topic_tags_loading + translation: "Chargement des étiquettes…" +- id: topic_tags_empty + translation: "Aucune étiquette." +- id: topic_error_content + translation: "Impossible de charger le contenu du sujet." +- id: topic_error_playlists + translation: "Erreur lors du chargement des playlists." +- id: topic_error_tags + translation: "Erreur lors du chargement des étiquettes." +- id: topic_not_found + translation: "Sujet introuvable." diff --git a/i18n/pt.yaml b/i18n/pt.yaml new file mode 100644 index 00000000..51b6914f --- /dev/null +++ b/i18n/pt.yaml @@ -0,0 +1,145 @@ +- id: home_plan_label + translation: "Plano" +- id: home_duration_semester + translation: "semestre" +- id: home_duration_semesters + translation: "semestres" +- id: home_summary_placeholder + translation: "Documentação em preparação." +- id: home_empty_state + translation: "Nenhum curso publicado ainda. Volte em breve!" + +- id: course_code_prefix + translation: "Curso" +- id: course_plan_label + translation: "Plano curricular" +- id: course_synced_heading + translation: "Conteúdo sincronizado" +- id: course_synced_loading + translation: "Carregando descrição detalhada a partir do Supabase…" +- id: course_content_placeholder + translation: "Ainda não há conteúdo sincronizado para este curso." +- id: course_ucs_heading + translation: "Unidades curriculares" +- id: course_ucs_loading + translation: "Carregando unidades curriculares…" +- id: course_ucs_empty + translation: "Nenhuma unidade curricular sincronizada." +- id: course_ucs_description_placeholder + translation: "Descrição em preparação." +- id: course_details_heading + translation: "Detalhes do curso" +- id: course_details_institution + translation: "Instituição" +- id: course_details_school + translation: "Escola" +- id: course_details_ects + translation: "ECTS" +- id: course_details_duration + translation: "Duração" +- id: course_details_duration_suffix + translation: "semestres" +- id: course_details_duration_suffix_singular + translation: "semestre" +- id: course_details_language + translation: "Idioma" +- id: course_ucs_meta + translation: "{{ .semester }}º semestre · {{ .ects }} ECTS" +- id: course_error_details + translation: "Falha ao carregar detalhes do curso." +- id: course_error_content + translation: "Não foi possível carregar o conteúdo sincronizado." +- id: course_error_ucs + translation: "Não foi possível carregar as unidades curriculares." +- id: course_not_found + translation: "Curso não encontrado." + +- id: uc_code_prefix + translation: "Unidade curricular" +- id: uc_synced_heading + translation: "Conteúdo oficial" +- id: uc_synced_loading + translation: "Sincronizando ementa e materiais…" +- id: uc_content_placeholder + translation: "Conteúdo ainda não disponível." +- id: uc_outcomes_heading + translation: "Resultados de aprendizagem" +- id: uc_outcomes_loading + translation: "Carregando resultados…" +- id: uc_outcomes_empty + translation: "Nenhum resultado cadastrado." +- id: uc_playlists_heading + translation: "Playlists recomendadas" +- id: uc_playlists_loading + translation: "Carregando playlists…" +- id: uc_playlists_empty + translation: "Sem playlists associadas." +- id: uc_playlists_priority_label + translation: "Prioridade" +- id: uc_playlists_button_label + translation: "Abrir playlist" +- id: uc_topics_heading + translation: "Tópicos associados" +- id: uc_topics_loading + translation: "Carregando tópicos…" +- id: uc_topics_empty + translation: "Sem tópicos associados." +- id: uc_topics_summary_placeholder + translation: "Resumo em preparação." +- id: uc_details_heading + translation: "Informações" +- id: uc_details_course + translation: "Curso" +- id: uc_details_ects + translation: "ECTS" +- id: uc_details_semester + translation: "Semestre" +- id: uc_details_language + translation: "Idioma" +- id: uc_details_prerequisites + translation: "Pré-requisitos" +- id: uc_error_details + translation: "Falha ao carregar informações da UC." +- id: uc_error_content + translation: "Não foi possível carregar a ementa sincronizada." +- id: uc_error_outcomes + translation: "Erro ao carregar resultados de aprendizagem." +- id: uc_error_playlists + translation: "Erro ao carregar playlists." +- id: uc_error_topics + translation: "Erro ao carregar tópicos." +- id: uc_not_found + translation: "UC não encontrada." + +- id: topic_code_prefix + translation: "Tópico" +- id: topic_synced_heading + translation: "Conteúdo sincronizado" +- id: topic_synced_loading + translation: "Carregando conteúdo Markdown…" +- id: topic_content_placeholder + translation: "Conteúdo em preparação." +- id: topic_playlists_heading + translation: "Playlists relacionadas" +- id: topic_playlists_loading + translation: "Carregando playlists…" +- id: topic_playlists_empty + translation: "Sem playlists cadastradas." +- id: topic_playlists_priority_label + translation: "Prioridade" +- id: topic_playlists_button_label + translation: "Abrir playlist" +- id: topic_tags_heading + translation: "Etiquetas" +- id: topic_tags_loading + translation: "Carregando tags…" +- id: topic_tags_empty + translation: "Sem etiquetas." +- id: topic_error_content + translation: "Não foi possível carregar o conteúdo do tópico." +- id: topic_error_playlists + translation: "Erro ao carregar playlists." +- id: topic_error_tags + translation: "Erro ao carregar tags." +- id: topic_not_found + translation: "Tópico não encontrado." diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html index a98637f9..e5594b5a 100644 --- a/layouts/_default/baseof.html +++ b/layouts/_default/baseof.html @@ -2,7 +2,14 @@ {{ partial "head/head" . }} {{ partial "head/body-class" . }} - + {{- $supabaseUrl := getenv "SUPABASE_URL" -}} + {{- $supabaseAnon := getenv "SUPABASE_ANON_KEY" -}} + {{- $messagesJSON := partial "i18n/messages.json" . -}} + {{- $messagesEncoded := "" -}} + {{- if gt (len $messagesJSON) 0 -}} + {{- $messagesEncoded = base64Encode $messagesJSON -}} + {{- end -}} + {{ partial "header/header" . }}
diff --git a/layouts/_partials/footer/script-footer-custom.html b/layouts/_partials/footer/script-footer-custom.html index 9a1de999..be9ac844 100644 --- a/layouts/_partials/footer/script-footer-custom.html +++ b/layouts/_partials/footer/script-footer-custom.html @@ -1,9 +1,3 @@ -{{- $supabaseUrl := site.Params.supabase.url | default (getenv "SUPABASE_URL") -}} -{{- $supabaseAnon := site.Params.supabase.anon_key | default (getenv "SUPABASE_ANON_KEY") -}} - diff --git a/layouts/_partials/i18n/messages.json b/layouts/_partials/i18n/messages.json new file mode 100644 index 00000000..da27c3e3 --- /dev/null +++ b/layouts/_partials/i18n/messages.json @@ -0,0 +1,24 @@ +{{- $courseDetails := dict "heading" (i18n "course_details_heading") "institution" (i18n "course_details_institution") "school" (i18n "course_details_school") "ects" (i18n "course_details_ects") "duration" (i18n "course_details_duration") "durationSuffixSingular" (i18n "course_details_duration_suffix_singular") "durationSuffixPlural" (i18n "course_details_duration_suffix") "language" (i18n "course_details_language") -}} +{{- $courseLoading := dict "content" (i18n "course_synced_loading") "ucs" (i18n "course_ucs_loading") -}} +{{- $courseEmpty := dict "content" (i18n "course_content_placeholder") "ucs" (i18n "course_ucs_empty") "ucDescription" (i18n "course_ucs_description_placeholder") -}} +{{- $courseErrors := dict "details" (i18n "course_error_details") "content" (i18n "course_error_content") "ucs" (i18n "course_error_ucs") "notFound" (i18n "course_not_found") -}} +{{- $courseMeta := dict "uc" (i18n "course_ucs_meta") -}} + +{{- $ucDetails := dict "heading" (i18n "uc_details_heading") "course" (i18n "uc_details_course") "ects" (i18n "uc_details_ects") "semester" (i18n "uc_details_semester") "language" (i18n "uc_details_language") "prerequisites" (i18n "uc_details_prerequisites") -}} +{{- $ucLoading := dict "content" (i18n "uc_synced_loading") "outcomes" (i18n "uc_outcomes_loading") "playlists" (i18n "uc_playlists_loading") "topics" (i18n "uc_topics_loading") -}} +{{- $ucEmpty := dict "outcomes" (i18n "uc_outcomes_empty") "playlists" (i18n "uc_playlists_empty") "topics" (i18n "uc_topics_empty") -}} +{{- $ucPlaceholders := dict "content" (i18n "uc_content_placeholder") "summary" (i18n "uc_topics_summary_placeholder") -}} +{{- $ucLabels := dict "priority" (i18n "uc_playlists_priority_label") -}} +{{- $ucButtons := dict "openPlaylist" (i18n "uc_playlists_button_label") -}} +{{- $ucErrors := dict "details" (i18n "uc_error_details") "content" (i18n "uc_error_content") "outcomes" (i18n "uc_error_outcomes") "playlists" (i18n "uc_error_playlists") "topics" (i18n "uc_error_topics") "notFound" (i18n "uc_not_found") -}} + +{{- $topicLoading := dict "content" (i18n "topic_synced_loading") "playlists" (i18n "topic_playlists_loading") "tags" (i18n "topic_tags_loading") -}} +{{- $topicEmpty := dict "playlists" (i18n "topic_playlists_empty") "tags" (i18n "topic_tags_empty") -}} +{{- $topicPlaceholders := dict "content" (i18n "topic_content_placeholder") -}} +{{- $topicLabels := dict "priority" (i18n "topic_playlists_priority_label") -}} +{{- $topicButtons := dict "openPlaylist" (i18n "topic_playlists_button_label") -}} +{{- $topicErrors := dict "content" (i18n "topic_error_content") "playlists" (i18n "topic_error_playlists") "tags" (i18n "topic_error_tags") "notFound" (i18n "topic_not_found") -}} + +{{- $messages := dict "course" (dict "details" $courseDetails "loading" $courseLoading "empty" $courseEmpty "errors" $courseErrors "meta" $courseMeta) "uc" (dict "details" $ucDetails "loading" $ucLoading "empty" $ucEmpty "placeholders" $ucPlaceholders "labels" $ucLabels "buttons" $ucButtons "errors" $ucErrors) "topic" (dict "loading" $topicLoading "empty" $topicEmpty "placeholders" $topicPlaceholders "labels" $topicLabels "buttons" $topicButtons "errors" $topicErrors) -}} + +{{- $messages | jsonify -}} diff --git a/layouts/course/single.html b/layouts/course/single.html index b2b9844f..ee35aab5 100644 --- a/layouts/course/single.html +++ b/layouts/course/single.html @@ -3,42 +3,42 @@
-

Curso {{ .Params.code }}

+

{{ i18n "course_code_prefix" }} {{ .Params.code }}

{{ .Title }}

{{ with .Params.plan_version }} -

Plano curricular {{ . }}

+

{{ i18n "course_plan_label" }} {{ . }}

{{ end }}
{{ .Content }}
-

Conteúdo sincronizado

+

{{ i18n "course_synced_heading" }}

-

Carregando descrição detalhada a partir do Supabase…

+

{{ i18n "course_synced_loading" }}

-

Unidades curriculares

+

{{ i18n "course_ucs_heading" }}

-
Carregando unidades curriculares…
+
{{ i18n "course_ucs_loading" }}
@@ -41,7 +46,7 @@

{{ end }} {{ else }}
-

Nenhum curso publicado ainda. Volte em breve!

+

{{ i18n "home_empty_state" }}

{{ end }}

diff --git a/layouts/topic/single.html b/layouts/topic/single.html index dabb4d43..2d79a1b9 100644 --- a/layouts/topic/single.html +++ b/layouts/topic/single.html @@ -3,28 +3,28 @@
-

Tópico {{ .Params.slug }}

+

{{ i18n "topic_code_prefix" }} {{ .Params.slug }}

{{ .Title }}

{{ .Content }}
-

Conteúdo sincronizado

+

{{ i18n "topic_synced_heading" }}

-

Carregando conteúdo Markdown…

+

{{ i18n "topic_synced_loading" }}

-

Playlists relacionadas

+

{{ i18n "topic_playlists_heading" }}

-
Carregando playlists…
+
{{ i18n "topic_playlists_loading" }}
-

Etiquetas

+

{{ i18n "topic_tags_heading" }}

- Carregando tags… + {{ i18n "topic_tags_loading" }}
diff --git a/layouts/uc/single.html b/layouts/uc/single.html index 4036e83c..ee75d812 100644 --- a/layouts/uc/single.html +++ b/layouts/uc/single.html @@ -3,51 +3,51 @@
-

Unidade curricular {{ .Params.code }}

+

{{ i18n "uc_code_prefix" }} {{ .Params.code }}

{{ .Title }}

{{ .Content }}
-

Conteúdo oficial

+

{{ i18n "uc_synced_heading" }}

-

Sincronizando ementa e materiais…

+

{{ i18n "uc_synced_loading" }}

-

Resultados de aprendizagem

+

{{ i18n "uc_outcomes_heading" }}

    -
  1. Carregando resultados…
  2. +
  3. {{ i18n "uc_outcomes_loading" }}
-

Playlists recomendadas

+

{{ i18n "uc_playlists_heading" }}

-
Carregando playlists…
+
{{ i18n "uc_playlists_loading" }}
-

Tópicos associados

+

{{ i18n "uc_topics_heading" }}

-
Carregando tópicos…
+
{{ i18n "uc_topics_loading" }}