-
Notifications
You must be signed in to change notification settings - Fork 9
fix: Internacionalização de nomes de idiomas nos menus de artigos #373
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -19,6 +19,228 @@ | |||||||||||||||||||||||||
| "A&HCI": "Arts & Humanities Citation", | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Dicionário expandido de traduções de idiomas | ||||||||||||||||||||||||||
| # Estrutura: {codigo_iso: {idioma_interface: nome_traduzido}} | ||||||||||||||||||||||||||
| # Usado para traduzir nomes de idiomas nos menus de artigos (resumo, texto, PDF) | ||||||||||||||||||||||||||
| LANGUAGE_TRANSLATIONS = { | ||||||||||||||||||||||||||
| 'pt': { | ||||||||||||||||||||||||||
| 'pt': __('Português'), | ||||||||||||||||||||||||||
| 'en': __('Portuguese'), | ||||||||||||||||||||||||||
| 'es': __('Portugués') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'en': { | ||||||||||||||||||||||||||
| 'pt': __('Inglês'), | ||||||||||||||||||||||||||
| 'en': __('English'), | ||||||||||||||||||||||||||
| 'es': __('Inglés') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'es': { | ||||||||||||||||||||||||||
| 'pt': __('Espanhol'), | ||||||||||||||||||||||||||
| 'en': __('Spanish'), | ||||||||||||||||||||||||||
| 'es': __('Español') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'de': { | ||||||||||||||||||||||||||
| 'pt': __('Alemão'), | ||||||||||||||||||||||||||
| 'en': __('German'), | ||||||||||||||||||||||||||
| 'es': __('Alemán') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'fr': { | ||||||||||||||||||||||||||
| 'pt': __('Francês'), | ||||||||||||||||||||||||||
| 'en': __('French'), | ||||||||||||||||||||||||||
| 'es': __('Francés') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'it': { | ||||||||||||||||||||||||||
| 'pt': __('Italiano'), | ||||||||||||||||||||||||||
| 'en': __('Italian'), | ||||||||||||||||||||||||||
| 'es': __('Italiano') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'ru': { | ||||||||||||||||||||||||||
| 'pt': __('Russo'), | ||||||||||||||||||||||||||
| 'en': __('Russian'), | ||||||||||||||||||||||||||
| 'es': __('Ruso') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'ja': { | ||||||||||||||||||||||||||
| 'pt': __('Japonês'), | ||||||||||||||||||||||||||
| 'en': __('Japanese'), | ||||||||||||||||||||||||||
| 'es': __('Japonés') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'zh': { | ||||||||||||||||||||||||||
| 'pt': __('Chinês'), | ||||||||||||||||||||||||||
| 'en': __('Chinese'), | ||||||||||||||||||||||||||
| 'es': __('Chino') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'cn': { # Alias para zh (compatibilidade com ISO3166_ALPHA2 existente) | ||||||||||||||||||||||||||
| 'pt': __('Chinês'), | ||||||||||||||||||||||||||
| 'en': __('Chinese'), | ||||||||||||||||||||||||||
| 'es': __('Chino') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'ar': { | ||||||||||||||||||||||||||
| 'pt': __('Árabe'), | ||||||||||||||||||||||||||
| 'en': __('Arabic'), | ||||||||||||||||||||||||||
| 'es': __('Árabe') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'ko': { | ||||||||||||||||||||||||||
| 'pt': __('Coreano'), | ||||||||||||||||||||||||||
| 'en': __('Korean'), | ||||||||||||||||||||||||||
| 'es': __('Coreano') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'nl': { | ||||||||||||||||||||||||||
| 'pt': __('Holandês'), | ||||||||||||||||||||||||||
| 'en': __('Dutch'), | ||||||||||||||||||||||||||
| 'es': __('Holandés') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'pl': { | ||||||||||||||||||||||||||
| 'pt': __('Polonês'), | ||||||||||||||||||||||||||
| 'en': __('Polish'), | ||||||||||||||||||||||||||
| 'es': __('Polaco') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'tr': { | ||||||||||||||||||||||||||
| 'pt': __('Turco'), | ||||||||||||||||||||||||||
| 'en': __('Turkish'), | ||||||||||||||||||||||||||
| 'es': __('Turco') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'sv': { | ||||||||||||||||||||||||||
| 'pt': __('Sueco'), | ||||||||||||||||||||||||||
| 'en': __('Swedish'), | ||||||||||||||||||||||||||
| 'es': __('Sueco') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'da': { | ||||||||||||||||||||||||||
| 'pt': __('Dinamarquês'), | ||||||||||||||||||||||||||
| 'en': __('Danish'), | ||||||||||||||||||||||||||
| 'es': __('Danés') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'no': { | ||||||||||||||||||||||||||
| 'pt': __('Norueguês'), | ||||||||||||||||||||||||||
| 'en': __('Norwegian'), | ||||||||||||||||||||||||||
| 'es': __('Noruego') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'fi': { | ||||||||||||||||||||||||||
| 'pt': __('Finlandês'), | ||||||||||||||||||||||||||
| 'en': __('Finnish'), | ||||||||||||||||||||||||||
| 'es': __('Finlandés') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'cs': { | ||||||||||||||||||||||||||
| 'pt': __('Tcheco'), | ||||||||||||||||||||||||||
| 'en': __('Czech'), | ||||||||||||||||||||||||||
| 'es': __('Checo') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'el': { | ||||||||||||||||||||||||||
| 'pt': __('Grego'), | ||||||||||||||||||||||||||
| 'en': __('Greek'), | ||||||||||||||||||||||||||
| 'es': __('Griego') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'he': { | ||||||||||||||||||||||||||
| 'pt': __('Hebraico'), | ||||||||||||||||||||||||||
| 'en': __('Hebrew'), | ||||||||||||||||||||||||||
| 'es': __('Hebreo') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'hi': { | ||||||||||||||||||||||||||
| 'pt': __('Hindi'), | ||||||||||||||||||||||||||
| 'en': __('Hindi'), | ||||||||||||||||||||||||||
| 'es': __('Hindi') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'th': { | ||||||||||||||||||||||||||
| 'pt': __('Tailandês'), | ||||||||||||||||||||||||||
| 'en': __('Thai'), | ||||||||||||||||||||||||||
| 'es': __('Tailandés') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'vi': { | ||||||||||||||||||||||||||
| 'pt': __('Vietnamita'), | ||||||||||||||||||||||||||
| 'en': __('Vietnamese'), | ||||||||||||||||||||||||||
| 'es': __('Vietnamita') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'id': { | ||||||||||||||||||||||||||
| 'pt': __('Indonésio'), | ||||||||||||||||||||||||||
| 'en': __('Indonesian'), | ||||||||||||||||||||||||||
| 'es': __('Indonesio') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'ms': { | ||||||||||||||||||||||||||
| 'pt': __('Malaio'), | ||||||||||||||||||||||||||
| 'en': __('Malay'), | ||||||||||||||||||||||||||
| 'es': __('Malayo') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'ca': { | ||||||||||||||||||||||||||
| 'pt': __('Catalão'), | ||||||||||||||||||||||||||
| 'en': __('Catalan'), | ||||||||||||||||||||||||||
| 'es': __('Catalán') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'gl': { | ||||||||||||||||||||||||||
| 'pt': __('Galego'), | ||||||||||||||||||||||||||
| 'en': __('Galician'), | ||||||||||||||||||||||||||
| 'es': __('Gallego') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'eu': { | ||||||||||||||||||||||||||
| 'pt': __('Basco'), | ||||||||||||||||||||||||||
| 'en': __('Basque'), | ||||||||||||||||||||||||||
| 'es': __('Vasco') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'ro': { | ||||||||||||||||||||||||||
| 'pt': __('Romeno'), | ||||||||||||||||||||||||||
| 'en': __('Romanian'), | ||||||||||||||||||||||||||
| 'es': __('Rumano') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'hu': { | ||||||||||||||||||||||||||
| 'pt': __('Húngaro'), | ||||||||||||||||||||||||||
| 'en': __('Hungarian'), | ||||||||||||||||||||||||||
| 'es': __('Húngaro') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'uk': { | ||||||||||||||||||||||||||
| 'pt': __('Ucraniano'), | ||||||||||||||||||||||||||
| 'en': __('Ukrainian'), | ||||||||||||||||||||||||||
| 'es': __('Ucraniano') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'hr': { | ||||||||||||||||||||||||||
| 'pt': __('Croata'), | ||||||||||||||||||||||||||
| 'en': __('Croatian'), | ||||||||||||||||||||||||||
| 'es': __('Croata') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'sr': { | ||||||||||||||||||||||||||
| 'pt': __('Sérvio'), | ||||||||||||||||||||||||||
| 'en': __('Serbian'), | ||||||||||||||||||||||||||
| 'es': __('Serbio') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'bg': { | ||||||||||||||||||||||||||
| 'pt': __('Búlgaro'), | ||||||||||||||||||||||||||
| 'en': __('Bulgarian'), | ||||||||||||||||||||||||||
| 'es': __('Búlgaro') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'sk': { | ||||||||||||||||||||||||||
| 'pt': __('Eslovaco'), | ||||||||||||||||||||||||||
| 'en': __('Slovak'), | ||||||||||||||||||||||||||
| 'es': __('Eslovaco') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'sl': { | ||||||||||||||||||||||||||
| 'pt': __('Esloveno'), | ||||||||||||||||||||||||||
| 'en': __('Slovenian'), | ||||||||||||||||||||||||||
| 'es': __('Esloveno') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'lt': { | ||||||||||||||||||||||||||
| 'pt': __('Lituano'), | ||||||||||||||||||||||||||
| 'en': __('Lithuanian'), | ||||||||||||||||||||||||||
| 'es': __('Lituano') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'lv': { | ||||||||||||||||||||||||||
| 'pt': __('Letão'), | ||||||||||||||||||||||||||
| 'en': __('Latvian'), | ||||||||||||||||||||||||||
| 'es': __('Letón') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'et': { | ||||||||||||||||||||||||||
| 'pt': __('Estoniano'), | ||||||||||||||||||||||||||
| 'en': __('Estonian'), | ||||||||||||||||||||||||||
| 'es': __('Estonio') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| 'al': { # Alias (compatibilidade com ISO3166_ALPHA2 existente) | ||||||||||||||||||||||||||
| 'pt': __('Albanês'), | ||||||||||||||||||||||||||
| 'en': __('Albanian'), | ||||||||||||||||||||||||||
| 'es': __('Albanés') | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
|
Comment on lines
+231
to
+235
|
||||||||||||||||||||||||||
| 'sq': { # Código ISO correto para albanês | ||||||||||||||||||||||||||
|
Comment on lines
+231
to
+236
|
||||||||||||||||||||||||||
| 'al': { # Alias (compatibilidade com ISO3166_ALPHA2 existente) | |
| 'pt': __('Albanês'), | |
| 'en': __('Albanian'), | |
| 'es': __('Albanés') | |
| }, | |
| 'sq': { # Código ISO correto para albanês | |
| 'al': { # Alias legado para compatibilidade; 'al' é código ISO 3166 (Albânia), não ISO 639-1. Use 'sq' para albanês. | |
| 'pt': __('Albanês'), | |
| 'en': __('Albanian'), | |
| 'es': __('Albanés') | |
| }, | |
| 'sq': { # Código ISO 639-1 correto para albanês |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -5,15 +5,8 @@ | |||||
| {% trans %}Resumo{% endtrans %} | ||||||
| {% for abstract in article.abstracts %} | ||||||
| {% if gs_abstract and article_lang == abstract['language'] %} | ||||||
| {% if abstract['language'] == 'es' %} | ||||||
| (ES) | ||||||
| {% elif abstract['language'] == 'en' %} | ||||||
| (EN) | ||||||
| {% elif abstract['language'] == 'pt' %} | ||||||
| (PT) | ||||||
| {% else %} | ||||||
| {{ abstract['language'] }} | ||||||
| {% endif %} | ||||||
| {# Botão colapsado: mostra código ISO em MAIÚSCULO #} | ||||||
| ({{ abstract['language']|upper }}) | ||||||
| {% endif %} | ||||||
| {% endfor %} | ||||||
| </button> | ||||||
|
|
@@ -23,33 +16,20 @@ | |||||
| {% if gs_abstract and article_lang == abstract['language'] %} | ||||||
| <a href="#" class="current dropdown-item"> | ||||||
| {% trans %}Resumo{% endtrans %} | ||||||
| {% if abstract['language'] == 'es' %} | ||||||
| ({% trans %}Espanhol{% endtrans %}) | ||||||
| {% elif abstract['language'] == 'en' %} | ||||||
| ({% trans %}Inglês{% endtrans %}) | ||||||
| {% elif abstract['language'] == 'pt' %} | ||||||
| ({% trans %}Português{% endtrans %}) | ||||||
| {% else %} | ||||||
| ({{ abstract['language'] }}) | ||||||
| {% endif %} | ||||||
| {# Dropdown expandido: mostra nome traduzido do idioma #} | ||||||
| {# g.interface_language contém o idioma da interface (pt/en/es) #} | ||||||
| {# Compatível com PR #366 - migração de session.get('lang') para g.interface_language #} | ||||||
|
||||||
| {# Compatível com PR #366 - migração de session.get('lang') para g.interface_language #} | |
| {# Compatível com PR #370 - migração de session.get('lang') para g.interface_language #} |
Copilot
AI
Jan 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable g.interface_language is used but does not appear to be set anywhere in the codebase. The current implementation uses session['lang'] (as seen in webapp/main/views.py in the get_locale() function). Until PR #370 is merged and g.interface_language is properly set, this code will fail with an AttributeError. Consider using a fallback approach that works with the current codebase, such as using session.get('lang', 'en') or calling get_locale() directly.
Copilot
AI
Jan 21, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The templates reference g.interface_language, but this variable is not defined anywhere in the current codebase. The templates will fail with an AttributeError when trying to access this undefined attribute.
If this PR depends on PR #370 (or #366 as mentioned in comments) that introduces g.interface_language, that dependency needs to be clearly stated and this PR should not be merged until the dependent PR is merged first. Alternatively, you need to add a fallback that uses the current session.get('lang') approach until the migration is complete.
Copilot
AI
Jan 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable g.interface_language is used but does not appear to be set anywhere in the codebase. The current implementation uses session['lang'] (as seen in webapp/main/views.py in the get_locale() function). Until PR #370 is merged and g.interface_language is properly set, this code will fail with an AttributeError. Consider using a fallback approach that works with the current codebase, such as using session.get('lang', 'en') or calling get_locale() directly.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,22 +1,17 @@ | ||
| {% if article and article.pdfs|length == 1 %} | ||
|
|
||
| <div class="btn-group"> | ||
| <button id="btnGroupDropPDF" type="button" class="btn btn-secondary dropdown-toggle mb-0" data-bs-toggle="dropdown" aria-expanded="false" data-bs-display="static"> | ||
| <button id="btnGroupDropPDFSingle" type="button" class="btn btn-secondary dropdown-toggle mb-0" data-bs-toggle="dropdown" aria-expanded="false" data-bs-display="static"> | ||
| </button> | ||
| <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="btnGroupDropPDF"> | ||
| <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="btnGroupDropPDFSingle"> | ||
| {% for pdf in article.pdfs %} | ||
| <li> | ||
| <a target='_blank' href="{{ url_for('.article_detail_v3', url_seg=article.journal.url_segment, article_pid_v3=article.aid, format='pdf', lang=article.pdfs[0].lang) }}" class="dropdown-item"> | ||
| {% if pdf.lang == 'es' %} | ||
| {% trans %}Download PDF (Espanhol){% endtrans %} | ||
| {% elif pdf.lang == 'en' %} | ||
| {% trans %}Download PDF (Inglês){% endtrans %} | ||
| {% elif pdf.lang == 'pt' %} | ||
| {% trans %}Download PDF (Português){% endtrans %} | ||
| {% else %} | ||
| {{ pdf.lang }} | ||
| {% endif %} | ||
| {# Dropdown: mostra "Download PDF" com nome traduzido do idioma #} | ||
| {# g.interface_language contém o idioma da interface (pt/en/es) #} | ||
| {# Compatível com PR #366 - migração de session.get('lang') para g.interface_language #} | ||
|
||
| {% trans %}Download PDF{% endtrans %} ({{ pdf.lang|language_name(g.interface_language) }}) | ||
|
||
| </a> | ||
| </li> | ||
| {% endfor %} | ||
|
|
@@ -36,22 +31,15 @@ | |
|
|
||
| {# PDF #} | ||
| <div class="btn-group"> | ||
| <button id="btnGroupDropPDF" type="button" class="btn btn-secondary dropdown-toggle mb-0" data-bs-toggle="dropdown" aria-expanded="false" data-bs-display="static"> | ||
| <button id="btnGroupDropPDFMultiple" type="button" class="btn btn-secondary dropdown-toggle mb-0" data-bs-toggle="dropdown" aria-expanded="false" data-bs-display="static"> | ||
| </button> | ||
| <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="btnGroupDropPDF"> | ||
| <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="btnGroupDropPDFMultiple"> | ||
| {% for pdf in article.pdfs %} | ||
| <li> | ||
| <a target='_blank' href="{{ url_for('.article_detail_v3', url_seg=article.journal.url_segment, article_pid_v3=article.aid, format='pdf', lang=pdf.lang) }}" class="dropdown-item"> | ||
| {% if pdf.lang == 'es' %} | ||
| {% trans %}Download PDF (Espanhol){% endtrans %} | ||
| {% elif pdf.lang == 'en' %} | ||
| {% trans %}Download PDF (Inglês){% endtrans %} | ||
| {% elif pdf.lang == 'pt' %} | ||
| {% trans %}Download PDF (Português){% endtrans %} | ||
| {% else %} | ||
| {{ pdf.lang }} | ||
| {% endif %} | ||
| {# Dropdown: mostra "Download PDF" com nome traduzido do idioma #} | ||
| {% trans %}Download PDF{% endtrans %} ({{ pdf.lang|language_name(g.interface_language) }}) | ||
|
||
| </a> | ||
| </li> | ||
| {% endfor %} | ||
|
|
@@ -69,19 +57,12 @@ | |
| {% for pdf in article.pdfs %} | ||
| <li> | ||
| <a href="{{ url_for('.article_epdf', doi=article.doi, pid=article.pid, pdf_path=pdf.url, lang=pdf.lang) }}" class="dropdown-item"> | ||
| {% if pdf.lang == 'es' %} | ||
| {% trans %}Download PDF (Espanhol){% endtrans %} | ||
| {% elif pdf.lang == 'en' %} | ||
| {% trans %}Download PDF (Inglês){% endtrans %} | ||
| {% elif pdf.lang == 'pt' %} | ||
| {% trans %}Download PDF (Português){% endtrans %} | ||
| {% else %} | ||
| {{ pdf.lang }} | ||
| {% endif %} | ||
| {# Dropdown ePDF: mostra "Download PDF" com nome traduzido do idioma #} | ||
| {% trans %}Download PDF{% endtrans %} ({{ pdf.lang|language_name(g.interface_language) }}) | ||
|
||
| </a> | ||
| </li> | ||
| {% endfor %} | ||
| </ul> | ||
| </div> | ||
| {% endif %} | ||
| {% endif %} | ||
| {% endif %} | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment indicates 'cn' is an "Alias para zh (compatibilidade com ISO3166_ALPHA2 existente)", but this is misleading. 'cn' is an ISO 3166 country code (China), not an ISO 639 language code. ISO 639-1 uses 'zh' for Chinese language. While keeping 'cn' for backward compatibility may be necessary, the comment should clarify that 'cn' is not a valid ISO 639 language code and exists only for legacy support.