On Wed, Jul 17, 2019 at 11:16:21PM +0200, Ludovic Courtès wrote:
> I think we now have an overview of the possibilities (including maybe
> ‘itstool’ that Ricardo mentions.)  I’d say that whoever is interested
> should give it a try with what looks like the most promising approach
> and report back with a prototype.  :-)
> 

I tried to make gettext usable (not yet implementing any discussed
approach), but it is a little rough: I tried using msgctxts.  Sadly
Guile is missing a pgettext function, I think.  Should I use Guile’s
ffi?  I think msgctxts could help with fragmentation, as I would
prefer format strings with msgctxt over HTML-that-is-not-SHTML with
itstool (I may misunderstand itstool though).

sirgazil (Cc), long ago at
<https://lists.gnu.org/archive/html/guile-user/2017-12/msg00071.html>
you said you had written an interleave function for format strings.
Do you have the code somewhere?  I see in the commit log you are still
actively working on the Guix website.

Also, I believe this discussion is actually
<https://issues.guix.info/issue/26302>.  Should I reference this
thread there?

Regards,
Florian
>From f0bb0180dca729aa2c13f881780b279a08f9ea53 Mon Sep 17 00:00:00 2001
From: Florian Pelz <pelzflor...@pelzflorian.de>
Date: Thu, 18 Jul 2019 10:22:44 +0200
Subject: [PATCH 1/2] website: Use needed modules in posts.

* website/posts/back-from-seagl-2018.sxml: Use needed modules.
* website/posts/guix-at-libreplanet-2016.sxml: Use needed modules.
---
 website/posts/back-from-seagl-2018.sxml     | 3 ++-
 website/posts/guix-at-libreplanet-2016.sxml | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/website/posts/back-from-seagl-2018.sxml 
b/website/posts/back-from-seagl-2018.sxml
index c5ad0a9..958369f 100644
--- a/website/posts/back-from-seagl-2018.sxml
+++ b/website/posts/back-from-seagl-2018.sxml
@@ -1,6 +1,7 @@
 (begin
   (use-modules (apps base templates components)
-                  (srfi srfi-19))
+               (apps base utils)
+               (srfi srfi-19))
   `((title . "Back from SeaGL 2018")
     (author . "Chris Marusich")
     (date . ,(make-date 0 0 0 0 10 12 2018 -28800))
diff --git a/website/posts/guix-at-libreplanet-2016.sxml 
b/website/posts/guix-at-libreplanet-2016.sxml
index 8581be4..252def3 100644
--- a/website/posts/guix-at-libreplanet-2016.sxml
+++ b/website/posts/guix-at-libreplanet-2016.sxml
@@ -1,5 +1,6 @@
 (begin
-  (use-modules (srfi srfi-19))
+  (use-modules (srfi srfi-19)
+               (apps base templates components))
   `((title . "Guix at LibrePlanet 2016")
     (author . "David Thompson")
     (date unquote (make-date 0 0 0 0 15 3 2016 3600))
-- 
2.22.0

>From 5b84fb9d20668eb777832f88ad9bc0c8549e92d2 Mon Sep 17 00:00:00 2001
From: Florian Pelz <pelzflor...@pelzflorian.de>
Date: Thu, 18 Jul 2019 16:39:00 +0200
Subject: [PATCH 2/2] [wip] website: Add some gettext support.

* website/apps/base/templates/home.scm (home-t): Mark two messages
with G_ for testing.
* website/po/POTFILES: New file; list the above file here.
* website/po/guix-website.pot: New file; generated from the above.
* website/po/de.po: New file.
* website/po/LINGUAS: New file.  Add linguas for testing.  Currently
their country code has to be specified too.
* website/apps/i18n.scm: New file.  Add utility functions.
* website/haunt.scm: Load linguas and call each builder with each.
* website/wip-howto-test-translation: New file with unfinished
instructions.
---
 website/apps/base/templates/home.scm |  7 ++-
 website/apps/i18n.scm                | 89 ++++++++++++++++++++++++++++
 website/haunt.scm                    | 24 ++++++--
 website/po/LINGUAS                   |  2 +
 website/po/POTFILES                  |  1 +
 website/po/de.po                     | 30 ++++++++++
 website/po/guix-website.pot          | 30 ++++++++++
 website/wip-howto-test-translation   | 27 +++++++++
 8 files changed, 201 insertions(+), 9 deletions(-)
 create mode 100644 website/apps/i18n.scm
 create mode 100644 website/po/LINGUAS
 create mode 100644 website/po/POTFILES
 create mode 100644 website/po/de.po
 create mode 100644 website/po/guix-website.pot
 create mode 100644 website/wip-howto-test-translation

diff --git a/website/apps/base/templates/home.scm 
b/website/apps/base/templates/home.scm
index 5cb3bf5..0eb25a3 100644
--- a/website/apps/base/templates/home.scm
+++ b/website/apps/base/templates/home.scm
@@ -8,6 +8,7 @@
   #:use-module (apps base types)
   #:use-module (apps base utils)
   #:use-module (apps blog templates components)
+  #:use-module (apps i18n)
   #:export (home-t))
 
 
@@ -37,9 +38,9 @@
       (h2 (@ (class "a11y-offset")) "Summary")
       (ul
        (li
-       (b "Liberating.")
-       " Guix is an advanced
-        distribution of the "
+       (b (G_ "Liberating." "featured content"))
+       (G_ " Guix is an advanced
+        distribution of the " "featured content")
        ,(link-yellow
          #:label "GNU operating system"
          #:url (gnu-url "gnu/about-gnu.html"))
diff --git a/website/apps/i18n.scm b/website/apps/i18n.scm
new file mode 100644
index 0000000..54a975f
--- /dev/null
+++ b/website/apps/i18n.scm
@@ -0,0 +1,89 @@
+;;; GNU Guix web site
+;;; Copyright © 2019 Florian Pelz <pelzflor...@pelzflorian.de>
+;;;
+;;; This file is part of the GNU Guix web site.
+;;;
+;;; The GNU Guix web site is free software; you can redistribute it and/or 
modify it
+;;; under the terms of the GNU Affero General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; The GNU Guix web site is distributed in the hope that it will be useful, 
but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU Affero General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU Affero General Public License
+;;; along with the GNU Guix web site.  If not, see 
<http://www.gnu.org/licenses/>.
+
+(define-module (apps i18n)
+  #:use-module (haunt page)
+  #:use-module (haunt utils)
+  #:use-module (ice-9 match)
+  #:use-module (srfi srfi-1)
+  #:export (G_
+            %current-lingua
+            builder->localized-builder
+            builders->localized-builders))
+
+(define %gettext-domain
+  "guix-website")
+
+(bindtextdomain %gettext-domain (getcwd))
+(bind-textdomain-codeset %gettext-domain "UTF-8")
+(textdomain %gettext-domain)
+
+(define* (G_ msg msgctxt)
+  (if msgctxt
+      (gettext (string-append msgctxt "|" msg) %gettext-domain)
+      (gettext msg %gettext-domain)))
+
+(define <page>
+  (@@ (haunt page) <page>))
+
+(define %current-lingua
+  (make-fluid "en_US"))
+
+(define (first-value arg)
+  "For some reason the builder returned by static-directory returns
+multiple values.  This procedure is used to retain only the first
+return value.  TODO THIS SHOULD NOT BE NECESSARY I THINK"
+  arg)
+
+(define (builder->localized-builder builder lingua)
+  (compose
+   (lambda (pages)
+     (map
+      (lambda (page)
+        (match page
+          (($ <page> file-name contents writer)
+           (if (string-suffix? ".html" file-name)
+               (let* ((base (string-drop-right
+                             file-name
+                             (string-length ".html")))
+                      (new-name (string-append base
+                                               "."
+                                               lingua
+                                               ".html")))
+                 (make-page new-name contents writer))
+               page))
+          (else page)))
+      pages))
+   (lambda (site posts)
+     (begin
+       (setlocale LC_ALL (string-append lingua ".utf8"))
+       (with-fluid*
+           %current-lingua lingua
+           (lambda _
+             (begin
+               (first-value (builder site posts)))))))))
+
+(define (builders->localized-builders builders linguas)
+  (flatten
+   (map-in-order
+    (lambda (builder)
+      (map-in-order
+       (lambda (lingua)
+         (builder->localized-builder builder lingua))
+       linguas))
+    builders)))
diff --git a/website/haunt.scm b/website/haunt.scm
index d29c0d4..eb0eafe 100644
--- a/website/haunt.scm
+++ b/website/haunt.scm
@@ -5,13 +5,23 @@
 (use-modules ((apps base builder) #:prefix base:)
             ((apps blog builder) #:prefix blog:)
             ((apps download builder) #:prefix download:)
+             (apps i18n)
             ((apps packages builder) #:prefix packages:)
             (haunt asset)
              (haunt builder assets)
              (haunt reader)
             (haunt reader commonmark)
-             (haunt site))
+             (haunt site)
+             (ice-9 rdelim)
+             (srfi srfi-1))
 
+(define linguas
+  (with-input-from-file "po/LINGUAS"
+    (lambda _
+      (let loop ((line (read-line)))
+        (if (eof-object? line)
+            '()
+            (cons line (loop (read-line))))))))
 
 (site #:title "GNU Guix"
       #:domain (if (getenv "GUIX_WEB_SITE_INFO")
@@ -19,8 +29,10 @@
                    "https://gnu.org/software/guix";)
       #:build-directory "/tmp/gnu.org/software/guix"
       #:readers (list sxml-reader html-reader commonmark-reader)
-      #:builders (list base:builder
-                      blog:builder
-                      download:builder
-                      packages:builder
-                      (static-directory "static")))
+      #:builders (builders->localized-builders
+                  (list base:builder
+                        blog:builder
+                        download:builder
+                        packages:builder
+                        (static-directory "static"))
+                  linguas))
diff --git a/website/po/LINGUAS b/website/po/LINGUAS
new file mode 100644
index 0000000..782116d
--- /dev/null
+++ b/website/po/LINGUAS
@@ -0,0 +1,2 @@
+de_DE
+en_US
diff --git a/website/po/POTFILES b/website/po/POTFILES
new file mode 100644
index 0000000..0007797
--- /dev/null
+++ b/website/po/POTFILES
@@ -0,0 +1 @@
+apps/base/templates/home.scm
diff --git a/website/po/de.po b/website/po/de.po
new file mode 100644
index 0000000..3add92e
--- /dev/null
+++ b/website/po/de.po
@@ -0,0 +1,30 @@
+# German translations for guix-website package.
+# Copyright (C) 2019 Ludovic Courtès
+# This file is distributed under the same license as the guix-website package.
+# Automatically generated, 2019.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: guix-website\n"
+"Report-Msgid-Bugs-To: l...@gnu.org\n"
+"POT-Creation-Date: 2019-07-18 16:31+0200\n"
+"PO-Revision-Date: 2019-07-18 16:33+0200\n"
+"Last-Translator: Automatically generated\n"
+"Language-Team: none\n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: apps/base/templates/home.scm:41
+msgctxt "featured content"
+msgid "Liberating."
+msgstr "Befreiend."
+
+#: apps/base/templates/home.scm:42
+msgctxt "featured content"
+msgid ""
+" Guix is an advanced\n"
+"        distribution of the "
+msgstr "Guix ist eine fortgeschrittene Distribution des "
diff --git a/website/po/guix-website.pot b/website/po/guix-website.pot
new file mode 100644
index 0000000..709077a
--- /dev/null
+++ b/website/po/guix-website.pot
@@ -0,0 +1,30 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Ludovic Courtès
+# This file is distributed under the same license as the guix-website package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: guix-website\n"
+"Report-Msgid-Bugs-To: l...@gnu.org\n"
+"POT-Creation-Date: 2019-07-18 16:31+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <l...@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: apps/base/templates/home.scm:41
+msgctxt "featured content"
+msgid "Liberating."
+msgstr ""
+
+#: apps/base/templates/home.scm:42
+msgctxt "featured content"
+msgid ""
+" Guix is an advanced\n"
+"        distribution of the "
+msgstr ""
diff --git a/website/wip-howto-test-translation 
b/website/wip-howto-test-translation
new file mode 100644
index 0000000..f2f319b
--- /dev/null
+++ b/website/wip-howto-test-translation
@@ -0,0 +1,27 @@
+To create a pot file:
+
+xgettext -f po/POTFILES -o po/guix-website.pot --from-code=UTF-8 
--copyright-holder="Ludovic Courtès" --package-name="guix-website" 
--msgid-bugs-address="l...@gnu.org" --keyword=G_:1,2c
+
+To create a po file from a pot file, do the usual:
+
+cd po
+msginit -l de --no-translator
+
+To merge an existing po file with a new pot file:
+
+cd po
+msgmerge -U de.po guix-website.pot
+
+To update mo files:
+
+mkdir -p de/LC_MESSAGES
+cd po
+msgfmt de.po
+cd ..
+mv po/messages.mo de/LC_MESSAGES/guix-website.mo
+
+To test:
+
+guix environment --ad-hoc haunt
+GUILE_LOAD_PATH=$(guix build 
guile-syntax-highlight)/share/guile/site/2.2:$GUILE_LOAD_PATH 
GUIX_WEB_SITE_LOCAL=yes haunt build
+GUILE_LOAD_PATH=$(guix build 
guile-syntax-highlight)/share/guile/site/2.2:$GUILE_LOAD_PATH haunt serve
-- 
2.22.0

Reply via email to