commit d0b656f74017be7a2875750fa298cef0702fd26f
parent 99e15c0934457c8b14183f51c383a39f9ad6e72e
Author: Florian Dold <dold@taler.net>
Date: Sun, 23 Aug 2026 20:49:33 +0200
demo-blog: restore twenty featured essays
Diffstat:
13 files changed, 68 insertions(+), 47 deletions(-)
diff --git a/internal/web/articles.go b/internal/web/articles.go
@@ -38,7 +38,17 @@ var (
var articleLocales = map[string]string{
"en": "en", "fr": "fr", "it": "it", "ru": "ru", "tr": "tr",
- "uk": "uk", "de": "de", "es": "es",
+ "uk": "uk", "de": "de", "es": "es", "br": "pt", "pt": "pt",
+}
+
+var selectedArticleSlugs = map[string]bool{
+ "free-sw": true, "thegnuproject": true, "initial-announcement": true,
+ "manifesto": true, "why-free": true, "free-doc": true, "selling": true,
+ "categories": true, "open-source-misses-the-point": true, "not-ipr": true,
+ "words-to-avoid": true, "right-to-read": true, "misinterpreting-copyright": true,
+ "why-copyleft": true, "pragmatic": true, "trivial-patent": true,
+ "can-you-trust": true, "javascript-trap": true,
+ "who-does-that-server-really-serve": true, "compromise": true,
}
func loadArticles() (articleLibrary, error) {
@@ -71,6 +81,9 @@ func loadArticles() (articleLibrary, error) {
return nil, err
}
slug := strings.TrimSuffix(file.Name(), path.Ext(file.Name()))
+ if !selectedArticleSlugs[slug] {
+ continue
+ }
article, ok := parseArticle(locale, slug, string(contents))
if !ok {
continue
diff --git a/internal/web/articles_test.go b/internal/web/articles_test.go
@@ -26,17 +26,24 @@ func TestArticleLocalesAndStableSlugs(t *testing.T) {
if len(articles["zh_Hant"]) != 0 {
t.Fatal("articles were exposed under the unsupported zh_Hant locale")
}
+ expectedCounts := map[string]int{
+ "en": 20, "de": 18, "es": 20, "fr": 20, "it": 20,
+ "pt": 17, "ru": 20, "tr": 19, "uk": 15,
+ }
+ if len(articles) != len(expectedCounts) {
+ t.Errorf("loaded articles for %d locales, want %d", len(articles), len(expectedCounts))
+ }
for locale, localized := range articles {
if !supportedLocales[locale] {
t.Errorf("articles were exposed under unsupported locale %s", locale)
}
- if len(localized) == 0 {
- t.Errorf("no articles loaded for %s", locale)
- }
- if len(localized) > 5 {
- t.Errorf("demo embeds too many articles for %s: %d", locale, len(localized))
+ if len(localized) != expectedCounts[locale] {
+ t.Errorf("loaded %d articles for %s, want %d", len(localized), locale, expectedCounts[locale])
}
for slug, article := range localized {
+ if !selectedArticleSlugs[slug] {
+ t.Errorf("unselected article %q was loaded for %s", slug, locale)
+ }
if slug != article.Slug || slug == "" {
t.Errorf("unstable article identity for %s: key %q, article %q", locale, slug, article.Slug)
}
diff --git a/internal/web/assets.go b/internal/web/assets.go
@@ -5,17 +5,18 @@ import "embed"
// Assets contains everything required at runtime. The resulting executable is
// self-contained and can be deployed without locating a separate data tree.
//
-// Embed a small article selection for each supported language. The full
-// upstream archive remains available in the source tree without making this
-// demo executable unnecessarily large.
+// Embed the selected book chapters in each supported language when a
+// translation is available. The full upstream archive remains in the source
+// tree without making the demo executable unnecessarily large.
//
//go:embed assets/static assets/data assets/translations templates
-//go:embed assets/articles/de/free-sw.html assets/articles/de/gnu-history.html assets/articles/de/manifesto.html assets/articles/de/right-to-read.html
-//go:embed assets/articles/en/categories.html assets/articles/en/free-sw.html assets/articles/en/gnu-history.html assets/articles/en/manifesto.html assets/articles/en/right-to-read.html
-//go:embed assets/articles/es/free-sw.html assets/articles/es/gnu-history.html assets/articles/es/manifesto.html assets/articles/es/right-to-read.html
-//go:embed assets/articles/fr/free-sw.html assets/articles/fr/gnu-history.html assets/articles/fr/manifesto.html assets/articles/fr/right-to-read.html
-//go:embed assets/articles/it/free-sw.html assets/articles/it/gnu-history.html assets/articles/it/manifesto.html assets/articles/it/right-to-read.html
-//go:embed assets/articles/ru/free-sw.html assets/articles/ru/gnu-history.html assets/articles/ru/manifesto.html assets/articles/ru/right-to-read.html
-//go:embed assets/articles/tr/free-sw.html assets/articles/tr/gnu-history.html assets/articles/tr/manifesto.html assets/articles/tr/right-to-read.html
-//go:embed assets/articles/uk/free-sw.html assets/articles/uk/gnu-history.html assets/articles/uk/manifesto.html assets/articles/uk/right-to-read.html
+//go:embed assets/articles/de/free-sw.html assets/articles/de/thegnuproject.html assets/articles/de/initial-announcement.html assets/articles/de/manifesto.html assets/articles/de/why-free.html assets/articles/de/free-doc.html assets/articles/de/selling.html assets/articles/de/categories.html assets/articles/de/open-source-misses-the-point.html assets/articles/de/not-ipr.html assets/articles/de/words-to-avoid.html assets/articles/de/right-to-read.html assets/articles/de/why-copyleft.html assets/articles/de/pragmatic.html assets/articles/de/trivial-patent.html assets/articles/de/can-you-trust.html assets/articles/de/who-does-that-server-really-serve.html assets/articles/de/compromise.html
+//go:embed assets/articles/en/free-sw.html assets/articles/en/thegnuproject.html assets/articles/en/initial-announcement.html assets/articles/en/manifesto.html assets/articles/en/why-free.html assets/articles/en/free-doc.html assets/articles/en/selling.html assets/articles/en/categories.html assets/articles/en/open-source-misses-the-point.html assets/articles/en/not-ipr.html assets/articles/en/words-to-avoid.html assets/articles/en/right-to-read.html assets/articles/en/misinterpreting-copyright.html assets/articles/en/why-copyleft.html assets/articles/en/pragmatic.html assets/articles/en/trivial-patent.html assets/articles/en/can-you-trust.html assets/articles/en/javascript-trap.html assets/articles/en/who-does-that-server-really-serve.html assets/articles/en/compromise.html
+//go:embed assets/articles/es/free-sw.html assets/articles/es/thegnuproject.html assets/articles/es/initial-announcement.html assets/articles/es/manifesto.html assets/articles/es/why-free.html assets/articles/es/free-doc.html assets/articles/es/selling.html assets/articles/es/categories.html assets/articles/es/open-source-misses-the-point.html assets/articles/es/not-ipr.html assets/articles/es/words-to-avoid.html assets/articles/es/right-to-read.html assets/articles/es/misinterpreting-copyright.html assets/articles/es/why-copyleft.html assets/articles/es/pragmatic.html assets/articles/es/trivial-patent.html assets/articles/es/can-you-trust.html assets/articles/es/javascript-trap.html assets/articles/es/who-does-that-server-really-serve.html assets/articles/es/compromise.html
+//go:embed assets/articles/fr/free-sw.html assets/articles/fr/thegnuproject.html assets/articles/fr/initial-announcement.html assets/articles/fr/manifesto.html assets/articles/fr/why-free.html assets/articles/fr/free-doc.html assets/articles/fr/selling.html assets/articles/fr/categories.html assets/articles/fr/open-source-misses-the-point.html assets/articles/fr/not-ipr.html assets/articles/fr/words-to-avoid.html assets/articles/fr/right-to-read.html assets/articles/fr/misinterpreting-copyright.html assets/articles/fr/why-copyleft.html assets/articles/fr/pragmatic.html assets/articles/fr/trivial-patent.html assets/articles/fr/can-you-trust.html assets/articles/fr/javascript-trap.html assets/articles/fr/who-does-that-server-really-serve.html assets/articles/fr/compromise.html
+//go:embed assets/articles/it/free-sw.html assets/articles/it/thegnuproject.html assets/articles/it/initial-announcement.html assets/articles/it/manifesto.html assets/articles/it/why-free.html assets/articles/it/free-doc.html assets/articles/it/selling.html assets/articles/it/categories.html assets/articles/it/open-source-misses-the-point.html assets/articles/it/not-ipr.html assets/articles/it/words-to-avoid.html assets/articles/it/right-to-read.html assets/articles/it/misinterpreting-copyright.html assets/articles/it/why-copyleft.html assets/articles/it/pragmatic.html assets/articles/it/trivial-patent.html assets/articles/it/can-you-trust.html assets/articles/it/javascript-trap.html assets/articles/it/who-does-that-server-really-serve.html assets/articles/it/compromise.html
+//go:embed assets/articles/br/free-sw.html assets/articles/br/thegnuproject.html assets/articles/br/initial-announcement.html assets/articles/br/manifesto.html assets/articles/br/why-free.html assets/articles/br/free-doc.html assets/articles/br/selling.html assets/articles/br/categories.html assets/articles/br/open-source-misses-the-point.html assets/articles/br/not-ipr.html assets/articles/br/words-to-avoid.html assets/articles/br/right-to-read.html assets/articles/br/why-copyleft.html assets/articles/br/pragmatic.html assets/articles/br/javascript-trap.html assets/articles/br/who-does-that-server-really-serve.html assets/articles/br/compromise.html
+//go:embed assets/articles/ru/free-sw.html assets/articles/ru/thegnuproject.html assets/articles/ru/initial-announcement.html assets/articles/ru/manifesto.html assets/articles/ru/why-free.html assets/articles/ru/free-doc.html assets/articles/ru/selling.html assets/articles/ru/categories.html assets/articles/ru/open-source-misses-the-point.html assets/articles/ru/not-ipr.html assets/articles/ru/words-to-avoid.html assets/articles/ru/right-to-read.html assets/articles/ru/misinterpreting-copyright.html assets/articles/ru/why-copyleft.html assets/articles/ru/pragmatic.html assets/articles/ru/trivial-patent.html assets/articles/ru/can-you-trust.html assets/articles/ru/javascript-trap.html assets/articles/ru/who-does-that-server-really-serve.html assets/articles/ru/compromise.html
+//go:embed assets/articles/tr/free-sw.html assets/articles/tr/thegnuproject.html assets/articles/tr/initial-announcement.html assets/articles/tr/manifesto.html assets/articles/tr/why-free.html assets/articles/tr/free-doc.html assets/articles/tr/selling.html assets/articles/tr/categories.html assets/articles/tr/open-source-misses-the-point.html assets/articles/tr/not-ipr.html assets/articles/tr/words-to-avoid.html assets/articles/tr/right-to-read.html assets/articles/tr/misinterpreting-copyright.html assets/articles/tr/why-copyleft.html assets/articles/tr/pragmatic.html assets/articles/tr/can-you-trust.html assets/articles/tr/javascript-trap.html assets/articles/tr/who-does-that-server-really-serve.html assets/articles/tr/compromise.html
+//go:embed assets/articles/uk/free-sw.html assets/articles/uk/thegnuproject.html assets/articles/uk/initial-announcement.html assets/articles/uk/manifesto.html assets/articles/uk/why-free.html assets/articles/uk/free-doc.html assets/articles/uk/selling.html assets/articles/uk/open-source-misses-the-point.html assets/articles/uk/not-ipr.html assets/articles/uk/right-to-read.html assets/articles/uk/why-copyleft.html assets/articles/uk/pragmatic.html assets/articles/uk/javascript-trap.html assets/articles/uk/who-does-that-server-really-serve.html assets/articles/uk/compromise.html
var Assets embed.FS
diff --git a/internal/web/assets/translations/de/LC_MESSAGES/messages.po b/internal/web/assets/translations/de/LC_MESSAGES/messages.po
@@ -299,7 +299,7 @@ msgstr ""
"Installieren Sie die Taler-Wallet in Ihrem Browser und kehren Sie dann "
"hierher zurück."
-#: internal/web/app.go:198 internal/web/articles.go:142
+#: internal/web/app.go:198 internal/web/articles.go:155
msgid "Internal error"
msgstr "Interner Systemfehler"
@@ -325,7 +325,7 @@ msgid "Only GNU Taler works in this demo."
msgstr "In dieser Demo funktioniert nur GNU Taler."
#: internal/web/app.go:222 internal/web/app.go:226 internal/web/app.go:232
-#: internal/web/app.go:258 internal/web/articles.go:131 internal/web/blog.go:46
+#: internal/web/app.go:258 internal/web/articles.go:144 internal/web/blog.go:46
#: internal/web/blog.go:74 internal/web/donations.go:46
#: internal/web/landing.go:25
msgid "Page not found"
@@ -423,7 +423,7 @@ msgstr "Schritt 3: Coins ausgeben"
msgid "Step 4: Send feedback"
msgstr "Schritt 4: Rückmeldung senden"
-#: internal/web/articles.go:137
+#: internal/web/articles.go:150
msgid "Supplemental file not found"
msgstr "Zusatzdatei nicht gefunden"
diff --git a/internal/web/assets/translations/en/LC_MESSAGES/messages.po b/internal/web/assets/translations/en/LC_MESSAGES/messages.po
@@ -287,7 +287,7 @@ msgstr ""
msgid "Install the Taler wallet in your browser, then return here."
msgstr ""
-#: internal/web/app.go:198 internal/web/articles.go:142
+#: internal/web/app.go:198 internal/web/articles.go:155
msgid "Internal error"
msgstr ""
@@ -313,7 +313,7 @@ msgid "Only GNU Taler works in this demo."
msgstr ""
#: internal/web/app.go:222 internal/web/app.go:226 internal/web/app.go:232
-#: internal/web/app.go:258 internal/web/articles.go:131 internal/web/blog.go:46
+#: internal/web/app.go:258 internal/web/articles.go:144 internal/web/blog.go:46
#: internal/web/blog.go:74 internal/web/donations.go:46
#: internal/web/landing.go:25
msgid "Page not found"
@@ -408,7 +408,7 @@ msgstr ""
msgid "Step 4: Send feedback"
msgstr ""
-#: internal/web/articles.go:137
+#: internal/web/articles.go:150
msgid "Supplemental file not found"
msgstr ""
diff --git a/internal/web/assets/translations/es/LC_MESSAGES/messages.po b/internal/web/assets/translations/es/LC_MESSAGES/messages.po
@@ -295,7 +295,7 @@ msgstr "Instalar la cartera Taler"
msgid "Install the Taler wallet in your browser, then return here."
msgstr "Instala la cartera Taler en tu navegador y vuelve aquí."
-#: internal/web/app.go:198 internal/web/articles.go:142
+#: internal/web/app.go:198 internal/web/articles.go:155
msgid "Internal error"
msgstr "Error interno"
@@ -321,7 +321,7 @@ msgid "Only GNU Taler works in this demo."
msgstr "En esta demostración solo funciona GNU Taler."
#: internal/web/app.go:222 internal/web/app.go:226 internal/web/app.go:232
-#: internal/web/app.go:258 internal/web/articles.go:131 internal/web/blog.go:46
+#: internal/web/app.go:258 internal/web/articles.go:144 internal/web/blog.go:46
#: internal/web/blog.go:74 internal/web/donations.go:46
#: internal/web/landing.go:25
msgid "Page not found"
@@ -419,7 +419,7 @@ msgstr "Paso 3: Gasta tus monedas"
msgid "Step 4: Send feedback"
msgstr "Paso 4: Envía tus comentarios"
-#: internal/web/articles.go:137
+#: internal/web/articles.go:150
msgid "Supplemental file not found"
msgstr "No se encontró el archivo adicional"
diff --git a/internal/web/assets/translations/fr/LC_MESSAGES/messages.po b/internal/web/assets/translations/fr/LC_MESSAGES/messages.po
@@ -295,7 +295,7 @@ msgid "Install the Taler wallet in your browser, then return here."
msgstr ""
"Installez le portefeuille Taler dans votre navigateur, puis revenez ici."
-#: internal/web/app.go:198 internal/web/articles.go:142
+#: internal/web/app.go:198 internal/web/articles.go:155
msgid "Internal error"
msgstr "Erreur interne"
@@ -321,7 +321,7 @@ msgid "Only GNU Taler works in this demo."
msgstr "Seul GNU Taler fonctionne dans cette démonstration."
#: internal/web/app.go:222 internal/web/app.go:226 internal/web/app.go:232
-#: internal/web/app.go:258 internal/web/articles.go:131 internal/web/blog.go:46
+#: internal/web/app.go:258 internal/web/articles.go:144 internal/web/blog.go:46
#: internal/web/blog.go:74 internal/web/donations.go:46
#: internal/web/landing.go:25
msgid "Page not found"
@@ -418,7 +418,7 @@ msgstr "Étape 3 : dépensez vos pièces"
msgid "Step 4: Send feedback"
msgstr "Étape 4 : donnez votre avis"
-#: internal/web/articles.go:137
+#: internal/web/articles.go:150
msgid "Supplemental file not found"
msgstr "Fichier complémentaire introuvable"
diff --git a/internal/web/assets/translations/it/LC_MESSAGES/messages.po b/internal/web/assets/translations/it/LC_MESSAGES/messages.po
@@ -296,7 +296,7 @@ msgstr "Installa il portafoglio Taler"
msgid "Install the Taler wallet in your browser, then return here."
msgstr "Installa il portafoglio Taler nel browser, quindi torna qui."
-#: internal/web/app.go:198 internal/web/articles.go:142
+#: internal/web/app.go:198 internal/web/articles.go:155
msgid "Internal error"
msgstr "Errore interno"
@@ -322,7 +322,7 @@ msgid "Only GNU Taler works in this demo."
msgstr "In questa demo funziona solo GNU Taler."
#: internal/web/app.go:222 internal/web/app.go:226 internal/web/app.go:232
-#: internal/web/app.go:258 internal/web/articles.go:131 internal/web/blog.go:46
+#: internal/web/app.go:258 internal/web/articles.go:144 internal/web/blog.go:46
#: internal/web/blog.go:74 internal/web/donations.go:46
#: internal/web/landing.go:25
msgid "Page not found"
@@ -420,7 +420,7 @@ msgstr "Passaggio 3: spendi le tue monete"
msgid "Step 4: Send feedback"
msgstr "Passaggio 4: inviaci un commento"
-#: internal/web/articles.go:137
+#: internal/web/articles.go:150
msgid "Supplemental file not found"
msgstr "File aggiuntivo non trovato"
diff --git a/internal/web/assets/translations/messages.pot b/internal/web/assets/translations/messages.pot
@@ -273,7 +273,7 @@ msgstr ""
msgid "Install the Taler wallet in your browser, then return here."
msgstr ""
-#: internal/web/app.go:198 internal/web/articles.go:142
+#: internal/web/app.go:198 internal/web/articles.go:155
msgid "Internal error"
msgstr ""
@@ -298,7 +298,7 @@ msgstr ""
msgid "Only GNU Taler works in this demo."
msgstr ""
-#: internal/web/app.go:222 internal/web/app.go:226 internal/web/app.go:232 internal/web/app.go:258 internal/web/articles.go:131 internal/web/blog.go:46 internal/web/blog.go:74 internal/web/donations.go:46 internal/web/landing.go:25
+#: internal/web/app.go:222 internal/web/app.go:226 internal/web/app.go:232 internal/web/app.go:258 internal/web/articles.go:144 internal/web/blog.go:46 internal/web/blog.go:74 internal/web/donations.go:46 internal/web/landing.go:25
msgid "Page not found"
msgstr ""
@@ -388,7 +388,7 @@ msgstr ""
msgid "Step 4: Send feedback"
msgstr ""
-#: internal/web/articles.go:137
+#: internal/web/articles.go:150
msgid "Supplemental file not found"
msgstr ""
diff --git a/internal/web/assets/translations/pt/LC_MESSAGES/messages.po b/internal/web/assets/translations/pt/LC_MESSAGES/messages.po
@@ -295,7 +295,7 @@ msgstr "Instalar a carteira Taler"
msgid "Install the Taler wallet in your browser, then return here."
msgstr "Instale a carteira Taler no seu navegador e depois volte aqui."
-#: internal/web/app.go:198 internal/web/articles.go:142
+#: internal/web/app.go:198 internal/web/articles.go:155
msgid "Internal error"
msgstr "Erro interno"
@@ -321,7 +321,7 @@ msgid "Only GNU Taler works in this demo."
msgstr "Apenas o GNU Taler funciona nesta demonstração."
#: internal/web/app.go:222 internal/web/app.go:226 internal/web/app.go:232
-#: internal/web/app.go:258 internal/web/articles.go:131 internal/web/blog.go:46
+#: internal/web/app.go:258 internal/web/articles.go:144 internal/web/blog.go:46
#: internal/web/blog.go:74 internal/web/donations.go:46
#: internal/web/landing.go:25
msgid "Page not found"
@@ -418,7 +418,7 @@ msgstr "Passo 3: gaste as suas moedas"
msgid "Step 4: Send feedback"
msgstr "Passo 4: envie os seus comentários"
-#: internal/web/articles.go:137
+#: internal/web/articles.go:150
msgid "Supplemental file not found"
msgstr "Ficheiro adicional não encontrado"
diff --git a/internal/web/assets/translations/ru/LC_MESSAGES/messages.po b/internal/web/assets/translations/ru/LC_MESSAGES/messages.po
@@ -296,7 +296,7 @@ msgstr "Установить кошелёк Taler"
msgid "Install the Taler wallet in your browser, then return here."
msgstr "Установите кошелёк Taler в браузере, затем вернитесь сюда."
-#: internal/web/app.go:198 internal/web/articles.go:142
+#: internal/web/app.go:198 internal/web/articles.go:155
msgid "Internal error"
msgstr "Внутренняя ошибка"
@@ -322,7 +322,7 @@ msgid "Only GNU Taler works in this demo."
msgstr "В этой демонстрации работает только GNU Taler."
#: internal/web/app.go:222 internal/web/app.go:226 internal/web/app.go:232
-#: internal/web/app.go:258 internal/web/articles.go:131 internal/web/blog.go:46
+#: internal/web/app.go:258 internal/web/articles.go:144 internal/web/blog.go:46
#: internal/web/blog.go:74 internal/web/donations.go:46
#: internal/web/landing.go:25
msgid "Page not found"
@@ -419,7 +419,7 @@ msgstr "Шаг 3. Потратьте монеты"
msgid "Step 4: Send feedback"
msgstr "Шаг 4. Оставьте отзыв"
-#: internal/web/articles.go:137
+#: internal/web/articles.go:150
msgid "Supplemental file not found"
msgstr "Дополнительный файл не найден"
diff --git a/internal/web/assets/translations/tr/LC_MESSAGES/messages.po b/internal/web/assets/translations/tr/LC_MESSAGES/messages.po
@@ -294,7 +294,7 @@ msgstr "Taler cüzdanını yükle"
msgid "Install the Taler wallet in your browser, then return here."
msgstr "Taler cüzdanını tarayıcınıza yükleyin, ardından buraya dönün."
-#: internal/web/app.go:198 internal/web/articles.go:142
+#: internal/web/app.go:198 internal/web/articles.go:155
msgid "Internal error"
msgstr "Iç hata"
@@ -320,7 +320,7 @@ msgid "Only GNU Taler works in this demo."
msgstr "Bu demoda yalnızca GNU Taler çalışır."
#: internal/web/app.go:222 internal/web/app.go:226 internal/web/app.go:232
-#: internal/web/app.go:258 internal/web/articles.go:131 internal/web/blog.go:46
+#: internal/web/app.go:258 internal/web/articles.go:144 internal/web/blog.go:46
#: internal/web/blog.go:74 internal/web/donations.go:46
#: internal/web/landing.go:25
msgid "Page not found"
@@ -417,7 +417,7 @@ msgstr "3. adım: Paralarınızı harcayın"
msgid "Step 4: Send feedback"
msgstr "4. adım: Geri bildirim gönderin"
-#: internal/web/articles.go:137
+#: internal/web/articles.go:150
msgid "Supplemental file not found"
msgstr "Ek dosya bulunamadı"
diff --git a/internal/web/assets/translations/uk/LC_MESSAGES/messages.po b/internal/web/assets/translations/uk/LC_MESSAGES/messages.po
@@ -294,7 +294,7 @@ msgstr "Установити гаманець Taler"
msgid "Install the Taler wallet in your browser, then return here."
msgstr "Установіть гаманець Taler у браузері, а потім поверніться сюди."
-#: internal/web/app.go:198 internal/web/articles.go:142
+#: internal/web/app.go:198 internal/web/articles.go:155
msgid "Internal error"
msgstr "Внутрішня помилка"
@@ -320,7 +320,7 @@ msgid "Only GNU Taler works in this demo."
msgstr "У цій демонстрації працює лише GNU Taler."
#: internal/web/app.go:222 internal/web/app.go:226 internal/web/app.go:232
-#: internal/web/app.go:258 internal/web/articles.go:131 internal/web/blog.go:46
+#: internal/web/app.go:258 internal/web/articles.go:144 internal/web/blog.go:46
#: internal/web/blog.go:74 internal/web/donations.go:46
#: internal/web/landing.go:25
msgid "Page not found"
@@ -417,7 +417,7 @@ msgstr "Крок 3. Витратьте монети"
msgid "Step 4: Send feedback"
msgstr "Крок 4. Надішліть відгук"
-#: internal/web/articles.go:137
+#: internal/web/articles.go:150
msgid "Supplemental file not found"
msgstr "Додатковий файл не знайдено"