GNU logs - #26302, boring messages


Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: ng0 <contact.ng0@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Wed, 29 Mar 2017 15:41:01 +0000
Resent-Message-ID: <handler.26302.B.149080206023575 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: report 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: 26302 <at> debbugs.gnu.org
X-Debbugs-Original-To: bug-guix@HIDDEN
Received: via spool by submit <at> debbugs.gnu.org id=B.149080206023575
          (code B ref -1); Wed, 29 Mar 2017 15:41:01 +0000
Received: (at submit) by debbugs.gnu.org; 29 Mar 2017 15:41:00 +0000
Received: from localhost ([127.0.0.1]:51490 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1ctFiW-00068B-GP
	for submit <at> debbugs.gnu.org; Wed, 29 Mar 2017 11:41:00 -0400
Received: from eggs.gnu.org ([208.118.235.92]:40021)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <contact.ng0@HIDDEN>) id 1ctFiU-00067w-NV
 for submit <at> debbugs.gnu.org; Wed, 29 Mar 2017 11:40:59 -0400
Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)
 (envelope-from <contact.ng0@HIDDEN>) id 1ctFiO-0005GB-EO
 for submit <at> debbugs.gnu.org; Wed, 29 Mar 2017 11:40:53 -0400
X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org
X-Spam-Level: 
X-Spam-Status: No, score=0.0 required=5.0 tests=BAYES_20,T_DKIM_INVALID
 autolearn=disabled version=3.3.2
Received: from lists.gnu.org ([2001:4830:134:3::11]:38580)
 by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
 (Exim 4.71) (envelope-from <contact.ng0@HIDDEN>)
 id 1ctFiO-0005G7-CD
 for submit <at> debbugs.gnu.org; Wed, 29 Mar 2017 11:40:52 -0400
Received: from eggs.gnu.org ([2001:4830:134:3::10]:59203)
 by lists.gnu.org with esmtp (Exim 4.71)
 (envelope-from <contact.ng0@HIDDEN>) id 1ctFiM-0005h4-Lk
 for bug-guix@HIDDEN; Wed, 29 Mar 2017 11:40:52 -0400
Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)
 (envelope-from <contact.ng0@HIDDEN>) id 1ctFiJ-0005F6-VZ
 for bug-guix@HIDDEN; Wed, 29 Mar 2017 11:40:50 -0400
Received: from fragranza.investici.org ([178.175.144.26]:39156)
 by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32)
 (Exim 4.71) (envelope-from <contact.ng0@HIDDEN>)
 id 1ctFiJ-0005Ea-KJ
 for bug-guix@HIDDEN; Wed, 29 Mar 2017 11:40:47 -0400
Received: from [178.175.144.26] (fragranza [178.175.144.26]) (Authenticated
 sender: niasterisk@HIDDEN) by localhost (Postfix) with ESMTPSA id
 3E3E22C016F
 for <bug-guix@HIDDEN>; Wed, 29 Mar 2017 15:40:44 +0000 (UTC)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cryptolab.net;
 s=stigmate; t=1490802044;
 bh=mxavcjL7QiW1g1yYp+0Ta7HBI4+if7PW0Xlszb4iZNQ=;
 h=Date:From:To:Subject;
 b=G8belrE1QHjNjWHfoxYPDX2nmNhBbLeuhHZTUL9oM5SJ6z98e0OePmBvpE1Vjc6/4
 0cKz4q3QSThOajBPeTOE0T5AP1Sa4F1AX7jv9DbWlXRLrI1GhSMtAsdeb2R2y4nNOb
 xPafRoJbWcCZnxtmdwv1mUJrC3ZTkA4eLQ7JRkTs=
Date: Wed, 29 Mar 2017 15:40:40 +0000
From: ng0 <contact.ng0@HIDDEN>
Message-ID: <20170329154040.ddscahwp2agknihb@abyayala>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]
 [fuzzy]
X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x
X-Received-From: 2001:4830:134:3::11
X-Spam-Score: -4.1 (----)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -4.1 (----)

One thing I like about the template of https://taler.net is the usage of
javascript free translations of text (jinja2 is used), easy to select
and write.
I think translations of web sites are useful, necessary and important.                                                                                                                                                             
We must provide this in the long run on the Guix web site aswell.




Message sent:


Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-Mailer: MIME-tools 5.505 (Entity 5.505)
Content-Type: text/plain; charset=utf-8
X-Loop: help-debbugs@HIDDEN
From: help-debbugs@HIDDEN (GNU bug Tracking System)
To: ng0 <contact.ng0@HIDDEN>
Subject: bug#26302: Acknowledgement ([website] translations)
Message-ID: <handler.26302.B.149080206023575.ack <at> debbugs.gnu.org>
References: <20170329154040.ddscahwp2agknihb@abyayala>
X-Gnu-PR-Message: ack 26302
X-Gnu-PR-Package: guix
Reply-To: 26302 <at> debbugs.gnu.org
Date: Wed, 29 Mar 2017 15:41:01 +0000

Thank you for filing a new bug report with debbugs.gnu.org.

This is an automatically generated reply to let you know your message
has been received.

Your message is being forwarded to the package maintainers and other
interested parties for their attention; they will reply in due course.

Your message has been sent to the package maintainer(s):
 bug-guix@HIDDEN

If you wish to submit further information on this problem, please
send it to 26302 <at> debbugs.gnu.org.

Please do not send mail to help-debbugs@HIDDEN unless you wish
to report a problem with the Bug-tracking system.

--=20
26302: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D26302
GNU Bug Tracking System
Contact help-debbugs@HIDDEN with problems


Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: ng0 <contact.ng0@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Wed, 29 Mar 2017 16:14:02 +0000
Resent-Message-ID: <handler.26302.B26302.149080402726492 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: 26302 <at> debbugs.gnu.org
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.149080402726492
          (code B ref 26302); Wed, 29 Mar 2017 16:14:02 +0000
Received: (at 26302) by debbugs.gnu.org; 29 Mar 2017 16:13:47 +0000
Received: from localhost ([127.0.0.1]:51506 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1ctGEF-0006tE-Ll
	for submit <at> debbugs.gnu.org; Wed, 29 Mar 2017 12:13:47 -0400
Received: from latitanza.investici.org ([82.94.249.234]:26847)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <contact.ng0@HIDDEN>) id 1ctGED-0006t2-Il
 for 26302 <at> debbugs.gnu.org; Wed, 29 Mar 2017 12:13:46 -0400
Received: from [82.94.249.234] (latitanza [82.94.249.234]) (Authenticated
 sender: niasterisk@HIDDEN) by localhost (Postfix) with ESMTPSA id
 E4A2212132B
 for <26302 <at> debbugs.gnu.org>; Wed, 29 Mar 2017 16:13:43 +0000 (UTC)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cryptolab.net;
 s=stigmate; t=1490804024;
 bh=Ozb14k59GxIkg12O7b6AM/V/H8cLtcOPQbtGMFG777k=;
 h=Date:From:To:Subject:References:In-Reply-To;
 b=k0/HD124/hrktKqf+/1U1Iuz+4hvaopEvMx/kqkiYcMULub8QS1aIvpjSbxww6oya
 VVXmks8bKbg8LP0GAumiJsMU91/PMMEvAX4l9laEpE00zYUd/GFaT5wpe0hEQYXwSt
 YQ/Gjd29iPBuR2Y+oLafD2f5WJmim7h8XVIc0cq8=
Date: Wed, 29 Mar 2017 16:13:40 +0000
From: ng0 <contact.ng0@HIDDEN>
Message-ID: <20170329161340.kxiixggwjsssh5hh@abyayala>
Mail-Followup-To: 26302 <at> debbugs.gnu.org
References: <20170329154040.ddscahwp2agknihb@abyayala>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
In-Reply-To: <20170329154040.ddscahwp2agknihb@abyayala>
X-Spam-Score: 0.0 (/)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: 0.0 (/)

ng0 transcribed 0.4K bytes:
> One thing I like about the template of https://taler.net is the usage of
> javascript free translations of text (jinja2 is used), easy to select
> and write.
> I think translations of web sites are useful, necessary and important.                                                                                                                                                             
> We must provide this in the long run on the Guix web site aswell.
> 

"Must" sounds very strong, but I think we should do this for the all
parts possible of the website, starting with the basic website.

Whoever has an idea how to approach this using Guile should pick this
task up.




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: ng0 <contact.ng0@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Sat, 15 Apr 2017 12:01:02 +0000
Resent-Message-ID: <handler.26302.B26302.149225763217868 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: 26302 <at> debbugs.gnu.org
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.149225763217868
          (code B ref 26302); Sat, 15 Apr 2017 12:01:02 +0000
Received: (at 26302) by debbugs.gnu.org; 15 Apr 2017 12:00:32 +0000
Received: from localhost ([127.0.0.1]:47959 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1czMNU-0004e7-2a
	for submit <at> debbugs.gnu.org; Sat, 15 Apr 2017 08:00:32 -0400
Received: from latitanza.investici.org ([82.94.249.234]:40266)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <contact.ng0@HIDDEN>) id 1czMNQ-0004dv-Bz
 for 26302 <at> debbugs.gnu.org; Sat, 15 Apr 2017 08:00:29 -0400
Received: from [82.94.249.234] (latitanza [82.94.249.234]) (Authenticated
 sender: niasterisk@HIDDEN) by localhost (Postfix) with ESMTPSA id
 F2270120B93
 for <26302 <at> debbugs.gnu.org>; Sat, 15 Apr 2017 12:00:26 +0000 (UTC)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cryptolab.net;
 s=stigmate; t=1492257627;
 bh=kaka3lWaijXVIxy7+LHd8jLEqRus7LTYE+jB75/ENEY=;
 h=Date:From:To:Subject:References:In-Reply-To;
 b=XHmUjC+xcqFOmtI+1IILP9gFEqxAVCHJbMP8mi6J3iUEfav9r2VTxP8obzePxUcAC
 KkLN4uE1WyLAI0OdWAq7Xxqo1xZiA8FUGm58x9k+cjasZcopY1gd6BO6HmJwLSCCJr
 AdV/5SKja6mz67j9g6T36f7zWFhbLnukJ4ux8hSE=
Date: Sat, 15 Apr 2017 12:00:24 +0000
From: ng0 <contact.ng0@HIDDEN>
Message-ID: <20170415120024.f5hb7kw5vzqdogia@abyayala>
Mail-Followup-To: 26302 <at> debbugs.gnu.org
References: <20170329154040.ddscahwp2agknihb@abyayala>
 <20170329161340.kxiixggwjsssh5hh@abyayala>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: 8bit
In-Reply-To: <20170329161340.kxiixggwjsssh5hh@abyayala>
X-Spam-Score: 0.0 (/)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: 0.0 (/)

ng0 transcribed 0.7K bytes:
> ng0 transcribed 0.4K bytes:
> > One thing I like about the template of https://taler.net is the usage of
> > javascript free translations of text (jinja2 is used), easy to select
> > and write.
> > I think translations of web sites are useful, necessary and important.                                                                                                                                                             
> > We must provide this in the long run on the Guix web site aswell.
> > 
> 
> "Must" sounds very strong, but I think we should do this for the all
> parts possible of the website, starting with the basic website.
> 
> Whoever has an idea how to approach this using Guile should pick this
> task up.
> 

Update on this bug, as I just had some insights in an OStatus Federation
thread with Rafał Piątkowski.

We make use of SXML.
XML has native support for translations, but it's not "user friendly".
The goal here would be to simply the way translations are done.
Here is one way how you can achieve native xml translations:
https://www.xml.com/pub/a/2004/01/07/xmltm.html

Our newsposts are in Markdown.
Does Commonmark (what we use as far as I understand Haunt) support
extensions?
Otherwise we can write one new "post" per translation and have a
dialogue / menu to switch the language.


-- 
PGP and more: https://people.pragmatique.xyz/ng0/




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: ng0 <contact.ng0@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Sat, 15 Apr 2017 12:27:02 +0000
Resent-Message-ID: <handler.26302.B26302.149225917920204 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: 26302 <at> debbugs.gnu.org
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.149225917920204
          (code B ref 26302); Sat, 15 Apr 2017 12:27:02 +0000
Received: (at 26302) by debbugs.gnu.org; 15 Apr 2017 12:26:19 +0000
Received: from localhost ([127.0.0.1]:47978 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1czMmR-0005Fo-50
	for submit <at> debbugs.gnu.org; Sat, 15 Apr 2017 08:26:19 -0400
Received: from latitanza.investici.org ([82.94.249.234]:64383)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <contact.ng0@HIDDEN>) id 1czMmP-0005Fe-G0
 for 26302 <at> debbugs.gnu.org; Sat, 15 Apr 2017 08:26:18 -0400
Received: from [82.94.249.234] (latitanza [82.94.249.234]) (Authenticated
 sender: niasterisk@HIDDEN) by localhost (Postfix) with ESMTPSA id
 7E4AA120E72
 for <26302 <at> debbugs.gnu.org>; Sat, 15 Apr 2017 12:26:16 +0000 (UTC)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cryptolab.net;
 s=stigmate; t=1492259176;
 bh=3R+EPngCLutjonfhlTdu4eEC2THbchWXhXQa+e/p7HQ=;
 h=Date:From:To:Subject:References:In-Reply-To;
 b=BeRjZyDJARA+q6X1wdmt8S2KKIHW8yPYBHWIB4xFcZyXzqE/PS6xR9SAvLSbzYVHQ
 6kTqJcKP7l0seY0mymXp4GwWSdec+SSundTQhNChfp7I6lWrhoUFfKT6LLLZh3vMUD
 vL3VkiuiE6QooWNZnhFgClZOHiXKrVh6wpcl1xl8=
Date: Sat, 15 Apr 2017 12:26:14 +0000
From: ng0 <contact.ng0@HIDDEN>
Message-ID: <20170415122614.ag3bbkpixtpc7457@abyayala>
Mail-Followup-To: 26302 <at> debbugs.gnu.org
References: <20170329154040.ddscahwp2agknihb@abyayala>
 <20170329161340.kxiixggwjsssh5hh@abyayala>
 <20170415120024.f5hb7kw5vzqdogia@abyayala>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: 8bit
In-Reply-To: <20170415120024.f5hb7kw5vzqdogia@abyayala>
X-Spam-Score: 0.0 (/)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: 0.0 (/)

ng0 transcribed 1.4K bytes:
> ng0 transcribed 0.7K bytes:
> > ng0 transcribed 0.4K bytes:
> > > One thing I like about the template of https://taler.net is the usage of
> > > javascript free translations of text (jinja2 is used), easy to select
> > > and write.
> > > I think translations of web sites are useful, necessary and important.                                                                                                                                                             
> > > We must provide this in the long run on the Guix web site aswell.
> > > 
> > 
> > "Must" sounds very strong, but I think we should do this for the all
> > parts possible of the website, starting with the basic website.
> > 
> > Whoever has an idea how to approach this using Guile should pick this
> > task up.
> > 
> 
> Update on this bug, as I just had some insights in an OStatus Federation
> thread with Rafał Piątkowski.
> 
> We make use of SXML.
> XML has native support for translations, but it's not "user friendly".
> The goal here would be to simply the way translations are done.
> Here is one way how you can achieve native xml translations:
> https://www.xml.com/pub/a/2004/01/07/xmltm.html
> 
> Our newsposts are in Markdown.
> Does Commonmark (what we use as far as I understand Haunt) support
> extensions?
> Otherwise we can write one new "post" per translation and have a
> dialogue / menu to switch the language.
> 
> 
> -- 
> PGP and more: https://people.pragmatique.xyz/ng0/
> 
> 
> 

This
https://stackoverflow.com/questions/22824132/multiple-translations-in-a-single-restructuredtext-file
suggstest that at least with ReStructuredText (and Sphinx) we could
achieve something, so in case Commonmark doesn't work out,
ReStructuredText is an option.

-- 
PGP and more: https://people.pragmatique.xyz/ng0/




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: ludo@HIDDEN (Ludovic =?UTF-8?Q?Court=C3=A8s?=)
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Mon, 31 Jul 2017 21:12:01 +0000
Resent-Message-ID: <handler.26302.B26302.150153549124428 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: ng0 <contact.ng0@HIDDEN>
Cc: 26302 <at> debbugs.gnu.org
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.150153549124428
          (code B ref 26302); Mon, 31 Jul 2017 21:12:01 +0000
Received: (at 26302) by debbugs.gnu.org; 31 Jul 2017 21:11:31 +0000
Received: from localhost ([127.0.0.1]:35814 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1dcHyN-0006Lv-G1
	for submit <at> debbugs.gnu.org; Mon, 31 Jul 2017 17:11:31 -0400
Received: from eggs.gnu.org ([208.118.235.92]:54985)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <ludo@HIDDEN>) id 1dcHyL-0006Li-8f
 for 26302 <at> debbugs.gnu.org; Mon, 31 Jul 2017 17:11:29 -0400
Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)
 (envelope-from <ludo@HIDDEN>) id 1dcHyD-00011R-3B
 for 26302 <at> debbugs.gnu.org; Mon, 31 Jul 2017 17:11:24 -0400
X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org
X-Spam-Level: 
X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD
 autolearn=disabled version=3.3.2
Received: from fencepost.gnu.org ([2001:4830:134:3::e]:34631)
 by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from <ludo@HIDDEN>)
 id 1dcHyC-00011C-Vk; Mon, 31 Jul 2017 17:11:21 -0400
Received: from reverse-83.fdn.fr ([80.67.176.83]:38892 helo=ribbon)
 by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256)
 (Exim 4.82) (envelope-from <ludo@HIDDEN>)
 id 1dcHyC-0005vp-E3; Mon, 31 Jul 2017 17:11:20 -0400
From: ludo@HIDDEN (Ludovic =?UTF-8?Q?Court=C3=A8s?=)
References: <20170329154040.ddscahwp2agknihb@abyayala>
Date: Mon, 31 Jul 2017 23:11:18 +0200
In-Reply-To: <20170329154040.ddscahwp2agknihb@abyayala> (ng0's message of
 "Wed, 29 Mar 2017 15:40:40 +0000")
Message-ID: <8760e8l3bd.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]
X-Received-From: 2001:4830:134:3::e
X-Spam-Score: -5.0 (-----)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -5.0 (-----)

Hi,

ng0 <contact.ng0@HIDDEN> skribis:

> One thing I like about the template of https://taler.net is the usage of
> javascript free translations of text (jinja2 is used), easy to select
> and write.
> I think translations of web sites are useful, necessary and important.=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20
> We must provide this in the long run on the Guix web site aswell.

FWIW I agree.

I wouldn=E2=80=99t want to use JS for that, though.

It may be that the simplest solution would be to use Gettext since,
after all, the web site is a regular Scheme program.

I would welcome work in this direction!

Ludo=E2=80=99.




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: ng0 <ng0@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Mon, 31 Jul 2017 21:56:01 +0000
Resent-Message-ID: <handler.26302.B26302.150153811928418 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Cc: 26302 <at> debbugs.gnu.org, ng0 <ng0@HIDDEN>
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.150153811928418
          (code B ref 26302); Mon, 31 Jul 2017 21:56:01 +0000
Received: (at 26302) by debbugs.gnu.org; 31 Jul 2017 21:55:19 +0000
Received: from localhost ([127.0.0.1]:35831 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1dcIeg-0007OD-Ie
	for submit <at> debbugs.gnu.org; Mon, 31 Jul 2017 17:55:19 -0400
Received: from aibo.runbox.com ([91.220.196.211]:48678)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <ng0@HIDDEN>) id 1dcIee-0007O4-CC
 for 26302 <at> debbugs.gnu.org; Mon, 31 Jul 2017 17:55:13 -0400
Received: from [10.9.9.211] (helo=mailfront11.runbox.com)
 by mailtransmit03.runbox with esmtp (Exim 4.86_2)
 (envelope-from <ng0@HIDDEN>)
 id 1dcIeb-0000Nr-57; Mon, 31 Jul 2017 23:55:09 +0200
Received: from tollana.enn.lu ([85.248.227.164] helo=localhost)
 by mailfront11.runbox.com with esmtpsa (uid:892961 )
 (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82)
 id 1dcIeJ-0005Cw-CE; Mon, 31 Jul 2017 23:54:51 +0200
Date: Mon, 31 Jul 2017 21:54:48 +0000
From: ng0 <ng0@HIDDEN>
Message-ID: <20170731215448.6zsu2qcfykuzbcd2@abyayala>
Mail-Followup-To: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>,
 26302 <at> debbugs.gnu.org
References: <20170329154040.ddscahwp2agknihb@abyayala> <8760e8l3bd.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: multipart/signed; micalg=pgp-sha512;
 protocol="application/pgp-signature"; boundary="5wc62jpx3vi3h4nh"
Content-Disposition: inline
In-Reply-To: <8760e8l3bd.fsf@HIDDEN>
X-Spam-Score: -0.7 (/)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.7 (/)


--5wc62jpx3vi3h4nh
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Ludovic Court=C3=A8s transcribed 1.1K bytes:
> Hi,
>=20
> ng0 <contact.ng0@HIDDEN> skribis:
>=20
> > One thing I like about the template of https://taler.net is the usage of
> > javascript free translations of text (jinja2 is used), easy to select
> > and write.
> > I think translations of web sites are useful, necessary and important. =
                                                                           =
                                                                           =
     =20
> > We must provide this in the long run on the Guix web site aswell.
>=20
> FWIW I agree.
>=20
> I wouldn=E2=80=99t want to use JS for that, though.
>=20
> It may be that the simplest solution would be to use Gettext since,
> after all, the web site is a regular Scheme program.
>=20
> I would welcome work in this direction!
>=20
> Ludo=E2=80=99.

I made some progress here, but only in theory and discussion.
It might take some time until I can write it down, and my approach
to websites and their translations might not be what we as Guix would want.

I'll update this with more info, I'll basically intend to use my own
project website as a testing ground for this with the version after
the current work in progress version.
--=20
ng0
GnuPG: A88C8ADD129828D7EAC02E52E22F9BBFEE348588
GnuPG: https://n0is.noblogs.org/my-keys
https://www.infotropique.org https://krosos.org

--5wc62jpx3vi3h4nh
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEEqIyK3RKYKNfqwC5S4i+bv+40hYgFAll/pygACgkQ4i+bv+40
hYg+thAAmV+tXe+t62RzsM2DWBQCnJLgErwLiWpxFtkbdNL7FGhiPXO4QL3IfdGl
jVkOhxs4xtk0zXzCKQeMTO3FOdjX4lRi/wewgbG6iff4B8Tqzy9cWYBJErIVO0OM
pWrDkcsKC2a6D27GWhVDjaXPDKxgd/tnpb4PBlQtttB/VwEs6IOu0ZzhRpL5vN/f
zKRRdRiIr9iBIPNwf1JQI8dNfwVP/MLpt2s8f6dW5NSAl1k190C+OXKFE9crSC5R
EUGGYplE6ZPymmd/A5BC5MoA9/Ll2aeIeXR37pVWG1McxnOd2UO3qf0qs6IftHR5
tDnIXk50LDOiTWRgrsnZwtDa07SsgbBhbmJasawKvxxyAj9ULXOhkVln4upcDsiQ
JCsuwhcO4sCapuShT9Tw2IbDUaK3vPiTUHAVQ3TUlAoRxXab98JK7D+BeG5l5Rkb
ngVjL7tKTRYq2tYB3vAMcOU2F0xYpTjKGQ8K6/hTjJYmyKOP69EXul3GHGDKXJkT
nOLwIZqe0phKlp3bpGn0AOPqhel7sUofhtYMk2108HP0E3vq6/kjwC8VJBLG+BHo
CXrSi7IZPvYbXQxRMCLokI38C1jpv6h8ETOL7SGM6LbzZshbMsnA3DAH0J7B9QYX
14tjcqf22fEgM2ZE91JuqFTW6VBT8XktFUH0wO0sP9BoUMfwcwc=
=thlg
-----END PGP SIGNATURE-----

--5wc62jpx3vi3h4nh--




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Fri, 06 Sep 2019 14:26:01 +0000
Resent-Message-ID: <handler.26302.B26302.15677799537586 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>, 26302 <at> debbugs.gnu.org
Cc: Mark H Weaver <mhw@HIDDEN>
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.15677799537586
          (code B ref 26302); Fri, 06 Sep 2019 14:26:01 +0000
Received: (at 26302) by debbugs.gnu.org; 6 Sep 2019 14:25:53 +0000
Received: from localhost ([127.0.0.1]:37248 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1i6FBR-0001yI-DM
	for submit <at> debbugs.gnu.org; Fri, 06 Sep 2019 10:25:53 -0400
Received: from pelzflorian.de ([5.45.111.108]:33314 helo=mail.pelzflorian.de)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pelzflorian@HIDDEN>) id 1i6FBP-0001y8-7h
 for 26302 <at> debbugs.gnu.org; Fri, 06 Sep 2019 10:25:52 -0400
Received: from pelzflorian.localdomain (unknown [5.45.111.108])
 by mail.pelzflorian.de (Postfix) with ESMTPSA id A2F4A3600FA;
 Fri,  6 Sep 2019 16:25:48 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=pelzflorian.de;
 s=mail; t=1567779949;
 bh=eUN/zwkZfFjxfkmKRLtOb2/fvfTtCtrBUU+CjRQ31Hc=;
 h=Date:From:To:Cc:Subject:References:In-Reply-To;
 b=LcSDc+FP+I0ou78L1uF7oJCYpHpw6H7Z/4Nnn9SbxrAm7PfszUn8AfIdx4ax2sBme
 /W2V0gBoenA1HIXZGJ8AhaRsWWOGJWDNY+o7AHCQ4byr1x57XRAYOsvQ3dvPxd72k+
 0WSC36ogzZD8HgYr+m2yuKEWklfvjqcGWV9at8kE=
Date: Fri, 6 Sep 2019 16:25:48 +0200
From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Message-ID: <20190906142548.4crfjgvxilgalgrs@HIDDEN>
References: <20170329154040.ddscahwp2agknihb@abyayala> <8760e8l3bd.fsf@HIDDEN>
 <20170731215448.6zsu2qcfykuzbcd2@abyayala>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="jc5p4xzpw3odooxa"
Content-Disposition: inline
Content-Transfer-Encoding: 8bit
In-Reply-To: <20170731215448.6zsu2qcfykuzbcd2@abyayala>
User-Agent: NeoMutt/20180716
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>


--jc5p4xzpw3odooxa
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: 8bit

Hello!

I think it is better to continue here with the discussion from
<https://lists.gnu.org/archive/html/guix-devel/2019-08/msg00178.html>.


Find attached preliminary patches that add a working website
translation system to guix-artwork.  Of course, the patches should
*not* be pushed before there is a working nginx configuration with
appropriate redirects.  (Except the first three patches; I do not
understand how you could even build the website without my first
patch?)


I am not entirely certain in my use of macros, but believe it is
right.  See my discussion with Mark H Weaver at
<https://lists.gnu.org/archive/html/guile-user/2019-09/msg00008.html>.


In my patches, I have used spaces for indentation.  Most previous
website code used a mix of tabs and spaces, like in emacs’ strange
default setting.  If you want, I can tabify my patches.  I cannot see
any reason for using mixed tabs+spaces with emacs-style Lisp
indentation though.


For redirecting previous URLs based on the HTTP Accept-Language
header, there is
<https://www.nginx.com/resources/wiki/modules/accept_language/#accept-language-installation>.
It could be added to nginx.

I do not know what the new URLs should be.  After reading
<https://webmasters.stackexchange.com/questions/403/how-should-i-structure-my-urls-for-both-seo-and-localization>
I now understand that there indeed should be separate URLs for each
language and Accept-Language headers are not sufficient.  However,
Ludo’s idea of translating URLs including the basename
<https://lists.gnu.org/archive/html/guix-devel/2019-08/msg00164.html>,
i.e. /help.html as /es/ayuda.html, leads to questions about the
implementation such as what Jelle Licht mentioned
<https://lists.gnu.org/archive/html/guix-devel/2019-08/msg00169.html>.
We can do whatever we want, so let’s do what is best.  What do you
think, /es/ayuda/ or /es/help/ or something else?

For ayuda, we would then need to make `guix build -f .guix.scm` build
with the static website also some kind of association list for
redirects that is readable by nginx lua code or whatever (could there
be guile plugins for nginx??).

We can do /es/help/ now and make /es/ayuda/ later.

Also, using the language code alone will no longer suffice once we
have two /zh/help/ for mainland and traditional-character Chinese.


One of the attached patches adds a PO file with a German translation
that was needed for testing purposes; of course translations should
normally be submitted via the Translation Project.  The patch need not
be applied; do as you see fit.


With respect to the help mailing list blurbs on the website, my code
gives priority to the PO file translation of the blurb and uses the
previous hard-coded translations as a fall-back.  I would keep the
blurbs this way until all are part of a PO file at the Translation
Project.

The Chinese language blurb is written in traditional Chinese
characters.  I believe there never was a decision on
<https://lists.gnu.org/archive/html/guix-devel/2018-03/msg00131.html>,
so I leave the language code as “zh” for now, even though someone may
add a “zh-cn” too.

I transferred the German blurb by Andreas Enge in
<https://lists.gnu.org/archive/html/guix-devel/2018-03/msg00026.html>
to the new German PO file, but changed the spelling “auf deutsch” to
the official orthography as per the official word list 2017 because
the German Translation Project team has decided on following official
orthography instead of allowing for personal style (but thank you to
Andreas Enge for showing me belleslettres who may well be right).


Next, I will look at adding a locale selection dropdown similar to the
About dropdown that is on the website now.  I would like to make both
About and locale selection be of visible size dependent on whether a
hidden <input type=radio> or an <input type=checkbox> is checked (the
latter would allow multiple dropdowns to be shown simultaneously).  A
probably insufficient, too new alternative is <details> (?).  I would
like to make the dropdowns keyboard-navigable (reachable using only
the tab key and no mouse/pointing device) in a way similar to what
happens when pressing tab on <https://en.wiktionary.org/wiki/geeks>.
This would be incompatible with <details>, I believe.


Regards,
Florian

--jc5p4xzpw3odooxa
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="0001-website-Use-needed-modules-in-posts.patch"

From fa96d7ec0a71dfea4b5c2cae8bdfb2a8f27f678d Mon Sep 17 00:00:00 2001
From: Florian Pelz <pelzflorian@HIDDEN>
Date: Thu, 18 Jul 2019 10:22:44 +0200
Subject: [PATCH 1/6] 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.23.0


--jc5p4xzpw3odooxa
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="0002-website-Fix-typing-mistake.patch"

From afd68ec639494320b5248b75315174d2dc1f7adb Mon Sep 17 00:00:00 2001
From: Florian Pelz <pelzflorian@HIDDEN>
Date: Sat, 31 Aug 2019 11:52:31 +0200
Subject: [PATCH 2/6] website: Fix typing mistake.

* website/apps/base/templates/contribute.scm (contribute-t):
Add missing word.
---
 website/apps/base/templates/contribute.scm | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/website/apps/base/templates/contribute.scm b/website/apps/base/templates/contribute.scm
index 6c4787f..4d68e87 100644
--- a/website/apps/base/templates/contribute.scm
+++ b/website/apps/base/templates/contribute.scm
@@ -201,7 +201,7 @@
 	(h3 (@ (id "testing")) "Test and Bug Reports")
 	(p
 	 "Install the software and send feedback to the community
-         about your experience. Help the project reporting bugs.")
+         about your experience. Help the project by reporting bugs.")
 	(p
 	 "Before reporting a bug, please check whether the bug is
          already "
-- 
2.23.0


--jc5p4xzpw3odooxa
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: attachment; filename="0003-website-Fix-typo.patch"
Content-Transfer-Encoding: 8bit

From 3bd446c4242f278123a113bd65ef2bf302a29afd Mon Sep 17 00:00:00 2001
From: Florian Pelz <pelzflorian@HIDDEN>
Date: Sat, 31 Aug 2019 21:00:29 +0200
Subject: [PATCH 3/6] website: Fix typo.

* website/apps/base/templates/security.scm (security-t): Fix typo.
---
 website/apps/base/templates/security.scm | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/website/apps/base/templates/security.scm b/website/apps/base/templates/security.scm
index ea997b2..b772912 100644
--- a/website/apps/base/templates/security.scm
+++ b/website/apps/base/templates/security.scm
@@ -16,7 +16,7 @@
   (theme
    #:title '("Security")
    #:description
-   "Important information about geting security updates for your
+   "Important information about getting security updates for your
    GNUGuix installation, and instructions on how to report
    security issues."
    #:keywords
-- 
2.23.0


--jc5p4xzpw3odooxa
Content-Type: text/plain; charset=utf-8
Content-Disposition: attachment; filename="0004-website-Add-custom-xgettext-to-extract-from-nested-s.patch"
Content-Transfer-Encoding: 8bit

From eead17da1649a180ee3e5ae1b7ec40640531252d Mon Sep 17 00:00:00 2001
From: Florian Pelz <pelzflorian@HIDDEN>
Date: Fri, 6 Sep 2019 08:36:11 +0200
Subject: [PATCH 4/6] website: Add custom xgettext to extract from nested sexps
 for i18n.

* website/scripts/sexp-xgettext.scm: New file for generating a POT file.
* website/sexp-xgettext.scm: New file with module for looking up
translations.
* website/apps/i18n.scm: New file.  Add utility functions.
* website/i18n-howto: New file with usage instructions.
* website/po/POTFILES: New file; list apps/base/templates files here.
* website/po/LINGUAS: New file.  List en_US lingua.
* website/haunt.scm: Wrap each builder to build the locale set in LC_ALL.
* website/README: Adapt build instructions for i18n.
* website/.guix.scm: Make Haunt build directory writable so Haunt can
overwrite duplicate assets.  Convert PO files to MO files and build for
each lingua.
---
 website/.guix.scm                 |  63 ++-
 website/README                    |   8 +-
 website/apps/i18n.scm             | 103 ++++
 website/haunt.scm                 |  17 +-
 website/i18n-howto.txt            |  86 ++++
 website/po/LINGUAS                |   3 +
 website/po/POTFILES               |  33 ++
 website/scripts/sexp-xgettext.scm | 823 ++++++++++++++++++++++++++++++
 website/sexp-xgettext.scm         | 530 +++++++++++++++++++
 9 files changed, 1647 insertions(+), 19 deletions(-)
 create mode 100644 website/apps/i18n.scm
 create mode 100644 website/i18n-howto.txt
 create mode 100644 website/po/LINGUAS
 create mode 100644 website/po/POTFILES
 create mode 100644 website/scripts/sexp-xgettext.scm
 create mode 100644 website/sexp-xgettext.scm

diff --git a/website/.guix.scm b/website/.guix.scm
index f6e50fb..dfbb527 100644
--- a/website/.guix.scm
+++ b/website/.guix.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix web site
 ;;; Copyright © 2017, 2019 Ludovic Courtès <ludo@HIDDEN>
+;;; Copyright © 2019 Florian Pelz <pelzflorian@HIDDEN>
 ;;;
 ;;; This file is part of the GNU Guix web site.
 ;;;
@@ -18,13 +19,22 @@
 
 ;; Run 'guix build -f .guix.scm' to build the web site.
 
+;; We need %linguas from the (sexp-xgettext) module.  Therefore, we
+;; add its path to the load path.  FIXME: Adding "." to the load path
+;; only works if sexp-xgettext.scm is in the current working
+;; directory.
+(set! %load-path (cons "." %load-path))
+
 (use-modules (guix) (gnu)
              (guix modules)
              (guix git-download)
              (guix gexp)
              (guix channels)
              (srfi srfi-9)
-             (ice-9 match))
+             (ice-9 match)
+             (ice-9 rdelim)
+             (ice-9 regex)
+             (sexp-xgettext))
 
 (define this-directory
   (dirname (current-filename)))
@@ -92,23 +102,56 @@
                                     ":"))))
             (close-pipe pipe))
 
+          ;; Make the copy writable so Haunt can overwrite duplicate assets.
+          (invoke #+(file-append (specification->package "coreutils")
+                                 "/bin/chmod")
+                  "--recursive" "u+w" ".")
+
+          ;; For translations, create MO files from PO files.
+          (for-each
+           (lambda (lingua)
+             (let* ((msgfmt #+(file-append (specification->package "gettext")
+                                           "/bin/msgfmt"))
+                    (lingua-file (string-append "po/" lingua ".po"))
+                    (lang (car (string-split lingua #\_)))
+                    (lang-file (string-append "po/" lang ".po")))
+               (define (create-mo filename)
+                 (begin
+                   (invoke msgfmt filename)
+                   (mkdir-p (string-append lingua "/LC_MESSAGES"))
+                   (rename-file "messages.mo"
+                                (string-append lingua "/LC_MESSAGES/"
+                                               "guix-website.mo"))))
+               (cond
+                ((file-exists? lingua-file)
+                 (create-mo lingua-file))
+                ((file-exists? lang-file)
+                 (create-mo lang-file))
+                (else #t))))
+           (list #$@%linguas))
+
           ;; So we can read/write UTF-8 files.
           (setenv "GUIX_LOCPATH"
                   #+(file-append (specification->package "glibc-utf8-locales")
                                  "/lib/locale"))
-          (setenv "LC_ALL" "en_US.utf8")
 
           ;; Use a sane default.
           (setenv "XDG_CACHE_HOME" "/tmp/.cache")
 
-          (invoke #+(file-append (specification->package "haunt")
-                                 "/bin/haunt")
-                  "build")
-
-          (mkdir-p #$output)
-          (copy-recursively "/tmp/gnu.org/software/guix" #$output
-                            #:log (%make-void-port "w"))
-          (symlink "guix.html" (string-append #$output "/index.html"))))))
+          ;; Build the website for each translation.
+          (for-each
+           (lambda (lingua)
+             (begin
+               (setenv "LC_ALL" (string-append lingua ".utf8"))
+               (invoke #+(file-append (specification->package "haunt")
+                                      "/bin/haunt")
+                       "build")
+               (mkdir-p #$output)
+               (copy-recursively "/tmp/gnu.org/software/guix" #$output
+                                 #:log (%make-void-port "w"))
+               (symlink (string-append "guix." lingua ".html")
+                        (string-append #$output "/index." lingua ".html"))))
+           (list #$@%linguas))))))
 
 (computed-file "guix-web-site" build)
 
diff --git a/website/README b/website/README
index d3a3a78..ff54053 100644
--- a/website/README
+++ b/website/README
@@ -24,14 +24,18 @@ commands:
 
 #+BEGIN_EXAMPLE
 $ cd path/to/guix-artwork/website
-$ GUIX_WEB_SITE_LOCAL=yes haunt build
+$ export GUILE_LOAD_PATH=$(guix build guile-syntax-highlight)/share/guile/site/2.2:$GUILE_LOAD_PATH
+$ LC_ALL=en_US.utf8 GUIX_WEB_SITE_LOCAL=yes haunt build
 $ haunt serve
 #+END_EXAMPLE
 
-Then, visit http://localhost:8080/guix.html in a web browser.
+Then, visit http://localhost:8080/en/guix.html in a web browser.
 
 You can stop the server pressing ~Ctrl + C~ twice.
 
+See also the file i18n-howto.txt for information on working with
+translations.
+
 * Deploying
 
 Like the pages of many GNU websites, this website is managed through
diff --git a/website/apps/i18n.scm b/website/apps/i18n.scm
new file mode 100644
index 0000000..d02dac9
--- /dev/null
+++ b/website/apps/i18n.scm
@@ -0,0 +1,103 @@
+;;; GNU Guix web site
+;;; Copyright © 2019 Florian Pelz <pelzflorian@HIDDEN>
+;;;
+;;; 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 (sexp-xgettext)
+  #:use-module (srfi srfi-1)
+  #:export (G_
+            N_
+            C_
+            NC_
+            %current-lingua
+            %current-lang
+            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)
+
+;; NOTE: The sgettext macros have no hygiene because they use
+;; datum->syntax and do not preserve the semantics of anything looking
+;; like an sgettext macro.  This is an exceptional use case; do not
+;; try this at home.
+
+(define-syntax G_
+  sgettext)
+
+(set-simple-keywords! '(G_))
+
+(define-syntax N_ ;like ngettext
+  sngettext)
+
+(define-syntax C_ ;like pgettext
+  spgettext)
+
+(define-syntax NC_ ;like npgettext
+  snpgettext)
+
+(set-complex-keywords! '(N_ C_ NC_))
+
+(define <page>
+  (@@ (haunt page) <page>))
+
+(define %current-lingua
+  (car (string-split (setlocale LC_ALL) #\.)))
+
+(define %current-lang
+  (car (string-split %current-lingua #\_)))
+
+(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."
+  arg)
+
+(define (builder->localized-builder builder)
+  "Returns a Haunt builder procedure generated from an existing
+BUILDER with translations for the current system locale coming from
+sexp-xgettext."
+  (compose
+   (lambda (pages)
+     (map
+      (lambda (page)
+        (match page
+          (($ <page> file-name contents writer)
+           (let ((new-name (string-append %current-lang
+                                          "/"
+                                          file-name)))
+             (make-page new-name contents writer)))
+          (else page)))
+      pages))
+   (lambda (site posts)
+     (first-value (builder site posts)))))
+
+(define (builders->localized-builders builders)
+  "Returns a list of new Haunt builder procedures generated from
+BUILDERS and localized via sexp-xgettext for the current system
+locale."
+  (flatten
+   (map-in-order
+    builder->localized-builder
+    builders)))
diff --git a/website/haunt.scm b/website/haunt.scm
index 9f66920..3d7963e 100644
--- a/website/haunt.scm
+++ b/website/haunt.scm
@@ -5,20 +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))
 
 (site #:title "GNU Guix"
       #:domain "https://guix.gnu.org"
       #: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"))))
diff --git a/website/i18n-howto.txt b/website/i18n-howto.txt
new file mode 100644
index 0000000..0d0c7c1
--- /dev/null
+++ b/website/i18n-howto.txt
@@ -0,0 +1,86 @@
+With sexp-xgettext, arbitrary s-expressions can be marked for
+translation (not only strings like with normal xgettext).
+
+S-expressions can be marked with G_ (simple marking for translation),
+N_ (“complex” marking with different forms depending on number like
+ngettext), C_ (“complex” marking distinguished from other markings by
+a msgctxt like pgettext) or NC_ (mix of both).
+
+Marking a string for translation behaves like normal gettext.  Marking
+a parenthesized expression (i.e. a list or procedure call) extracts
+each string from the parenthesized expression.  If a symbol, keyword
+or other parenthesized expression occurs between the strings, it is
+extracted as an XML element.  Expressions before or after all strings
+are not extracted.  If strings from a parenthesized sub-expression
+shall be extracted too, the sub-expression must again be marked with
+G_ unless it is the only sub-expression or it follows a quote,
+unquote, quasiquote or unquote-splicing.  The order of XML elements
+can be changed in the translation to produce a different ordering
+inside a parenthesized expression.  If a string shall not be extracted
+from a marked expression, it must be wrapped, for example by a call to
+the identity procedure.  Be careful when marking non-SHTML content
+such as procedure calls for translation: Additional strings will be
+inserted between non-string elements.
+
+Known issues:
+
+* Line numbers are sometimes off.
+
+* Some less important other TODOs in the comments.
+
+=====
+
+The following commands are an example of the translation for locale
+de_DE.  Adapt as necessary.  We assume the software requirements
+mentioned in the README are installed.
+
+To create a pot file:
+
+guile scripts/sexp-xgettext.scm -f po/POTFILES \
+                                -o po/guix-website.pot \
+                                --from-code=UTF-8 \
+                                --copyright-holder="Ludovic Courtès" \
+                                --package-name="guix-website" \
+                                --msgid-bugs-address="ludo@HIDDEN" \
+                                --keyword=G_ \
+                                --keyword=N_:1,2 \
+                                --keyword=C_:1c,2 \
+                                --keyword=NC_:1c,2,3
+
+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 build all languages:
+
+guix build -f .guix.scm
+
+To test the de_DE translation:
+
+guix environment --ad-hoc haunt
+LC_ALL=de_DE.utf8 \
+ 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
+
+For checking for errors / debugging newly marked files you can try:
+
+GUILE_LOAD_PATH=.:$(guix build haunt)/share/guile/site/2.2:\
+$(guix build guile-syntax-highlight)/share/guile/site/2.2:$GUILE_LOAD_PATH \
+ guile apps/base/templates/about.scm   # an example for debugging about.scm
diff --git a/website/po/LINGUAS b/website/po/LINGUAS
new file mode 100644
index 0000000..d4dd759
--- /dev/null
+++ b/website/po/LINGUAS
@@ -0,0 +1,3 @@
+# Translation with sexp-xgettext requires the full LL_CC locale name
+# to be specified.
+en_US
diff --git a/website/po/POTFILES b/website/po/POTFILES
new file mode 100644
index 0000000..2a5d37a
--- /dev/null
+++ b/website/po/POTFILES
@@ -0,0 +1,33 @@
+# high-priority files that should come first in the PO file
+apps/base/templates/home.scm
+apps/base/templates/theme.scm
+apps/base/templates/components.scm
+apps/base/templates/about.scm
+apps/base/data.scm
+apps/base/templates/help.scm
+# other files
+apps/base/templates/contact.scm
+apps/base/templates/contribute.scm
+apps/base/templates/donate.scm
+apps/base/templates/graphics.scm
+apps/base/templates/irc.scm
+apps/base/templates/menu.scm
+apps/base/templates/screenshot.scm
+apps/base/templates/security.scm
+apps/download/data.scm
+apps/download/templates/components.scm
+apps/download/templates/download.scm
+apps/blog/templates/components.scm
+apps/blog/templates/feed.scm
+apps/blog/templates/post-list.scm
+apps/blog/templates/post.scm
+apps/blog/templates/tag.scm
+apps/download/data.scm
+apps/download/templates/components.scm
+apps/download/templates/download.scm
+apps/packages/templates/components.scm
+apps/packages/templates/detailed-index.scm
+apps/packages/templates/detailed-package-list.scm
+apps/packages/templates/index.scm
+apps/packages/templates/package-list.scm
+apps/packages/templates/package.scm
diff --git a/website/scripts/sexp-xgettext.scm b/website/scripts/sexp-xgettext.scm
new file mode 100644
index 0000000..a21d289
--- /dev/null
+++ b/website/scripts/sexp-xgettext.scm
@@ -0,0 +1,823 @@
+;;; GNU Guix web site
+;;; Copyright © 2019 Florian Pelz <pelzflorian@HIDDEN>
+;;;
+;;; 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/>.
+
+(use-modules (ice-9 getopt-long)
+             (ice-9 match)
+             (ice-9 peg)
+             (ice-9 receive)
+             (ice-9 regex)
+             (ice-9 textual-ports)
+             (srfi srfi-1) ;lists
+             (srfi srfi-9) ;records
+             (srfi srfi-19) ;date
+             (srfi srfi-26)) ;cut
+
+;;; This script imitates xgettext, but combines nested s-expressions
+;;; in the input Scheme files to a single msgstr in the PO file.  It
+;;; works by first reading the keywords specified on the command-line,
+;;; then dealing with the remaining options using (ice-9 getopt-long).
+;;; Then, it parses each Scheme file in the POTFILES file specified
+;;; with --files-from and constructs po entries from it.  For parsing,
+;;; a PEG is used instead of Scheme’s read, because we can extract
+;;; comments with it.  The po entries are written to the PO file
+;;; specified with the --output option.  Scheme code can then use the
+;;; (sexp-xgettext) module to deconstruct the msgids looked up in the
+;;; PO file via gettext.
+
+(define-record-type <keyword-spec>
+  (make-keyword-spec id sg pl c total xcomment)
+  keyword-spec?
+  (id keyword-spec-id) ;identifier
+  (sg keyword-spec-sg) ;arg with singular
+  (pl keyword-spec-pl) ;arg with plural
+  (c keyword-spec-c) ;arg with msgctxt or 'mixed if sg is mixed msgctxt|singular
+  (total keyword-spec-total) ;total number of args
+  (xcomment keyword-spec-xcomment))
+
+(define (complex-keyword-spec? keyword-spec)
+  (match keyword-spec
+    (($ <keyword-spec> _ _ #f #f _ #f) #f)
+    (else #t)))
+
+(define %keyword-specs
+  ;; List of valid xgettext keyword options.
+  ;; Read keywords from command-line options.
+  (let loop ((opts (cdr (command-line)));command-line options from
+                                        ;which to extract --keyword
+                                        ;options
+             (remaining-opts '()) ;unhandled opts
+             (specs '()))
+    (define (string->integer str)
+      (if (string-match "[0-9]+" str)
+          (string->number str)
+          (error "Not a decimal integer.")))
+    (define* (argnums->spec id #:optional (argnums '()))
+      (let loop ((sg #f)
+                 (pl #f)
+                 (c #f)
+                 (total #f)
+                 (xcomment #f)
+                 (argnums argnums))
+        (match argnums
+          (() (make-keyword-spec id
+                                 (if sg sg 1)
+                                 pl
+                                 c
+                                 total
+                                 xcomment))
+          ((arg . argnums)
+           (cond
+            ((string-suffix? "c" arg)
+             (cond (c (error "c suffix clashes"))
+                   (else
+                    (let* ((number-str (string-drop-right arg 1))
+                           (number (string->integer number-str)))
+                      (loop sg pl number total xcomment argnums)))))
+            ((string-suffix? "g" arg)
+             (cond
+              (sg (error "Only first argnum can have g suffix."))
+              (c (error "g suffix clashes."))
+              (else
+               (let* ((number-str (string-drop-right arg 1))
+                      (number (string->integer number-str)))
+                 (loop number #f 'mixed total xcomment argnums)))))
+            ((string-suffix? "t" arg)
+             (cond (total (error "t suffix clashes"))
+                   (else
+                    (let* ((number-str (string-drop-right arg 1))
+                           (number (string->integer number-str)))
+                      (loop sg pl c number xcomment argnums)))))
+            ((string-suffix? "\"" arg)
+             (cond (xcomment (error "xcomment clashes"))
+                   (else
+                    (let* ((comment (substring arg
+                                               1
+                                               (- (string-length arg) 1))))
+                      (loop sg pl c total comment argnums)))))
+            (else
+             (let* ((number (string->integer arg)))
+               (if sg
+                   (if pl
+                       (error "Too many argnums.")
+                       (loop sg number c total xcomment argnums))
+                   (loop number #f c total xcomment argnums)))))))))
+
+    (define (string->spec str) ;see `info xgettext`
+      (match (string-split str #\:)
+        ((id) (argnums->spec id))
+        ((id argnums)
+         (argnums->spec id (string-split argnums #\,)))))
+    (match opts
+      (() (begin
+            ;; remove recognized --keyword command-line options:
+            (set-program-arguments (cons (car (command-line))
+                                         (reverse remaining-opts)))
+            specs))
+      ((current-opt . rest)
+       (cond
+        ((string=? "--" current-opt) specs)
+        ((string-prefix? "--keyword=" current-opt)
+         (let ((keyword (string-drop current-opt (string-length "--keyword="))))
+           (loop rest remaining-opts (cons (string->spec keyword) specs))))
+        ((or (string=? "--keyword" current-opt)
+             (string=? "-k" current-opt))
+         (let ((next-opt (car rest)))
+           (loop (cdr rest)
+                 remaining-opts
+                 (cons (string->spec next-opt) specs))))
+        (else (loop rest (cons current-opt remaining-opts) specs)))))))
+
+;;; Other options are not repeated, so we can use getopt-long:
+
+(define %options ;; Corresponds to what is documented at `info xgettext`.
+  (let ((option-spec
+         `((files (single-char #\f) (value #t))
+           (directory (single-char #\D) (value #t))
+           (default-domain (single-char #\d) (value #t))
+           (output (single-char #\o) (value #t))
+           (output-dir (single-char #\p) (value #t))
+           (from-code (value #t))
+           (join-existing (single-char #\j) (value #f))
+           (exclude-file (single-char #\x) (value #t))
+           (add-comments (single-char #\c) (value #t))
+
+           ;; Because getopt-long does not support repeated options,
+           ;; we took care of --keyword options further up.
+           ;; (keyword (single-char #\k) (value #t))
+
+           (flag (value #t))
+           (force-po (value #f))
+           (indent (single-char #\i) (value #f))
+           (no-location (value #f))
+           (add-location (single-char #\n) (value #t))
+           (width (single-char #\w) (value #t))
+           (no-wrap (value #f))
+           (sort-output (single-char #\s) (value #f))
+           (sort-by-file (single-char #\F) (value #f))
+           (omit-header (value #f))
+           (copyright-holder (value #t))
+           (foreign-user (value #f))
+           (package-name (value #t))
+           (package-version (value #t))
+           (msgid-bugs-address (value #t))
+           (msgstr-prefix (single-char #\m) (value #t))
+           (msgstr-suffix (single-char #\m) (value #t))
+           (help (value #f))
+           (pack (value #f)))))
+    (getopt-long (command-line) option-spec)))
+
+
+(define parse-scheme-file
+  ;; This procedure parses FILE and returns a parse tree.
+  (let ()
+    ;;TODO: Optionally ignore case.
+    (define-peg-pattern NL all "\n")
+    (define-peg-pattern comment all (and ";"
+                                         (* (and peg-any
+                                                 (not-followed-by NL)))
+                                         (and peg-any (followed-by NL))))
+    (define-peg-pattern empty none (or " " "\t"))
+    (define-peg-pattern whitespace body (or empty NL))
+    (define-peg-pattern quotation body (or "'" "`" "," ",@"))
+                                        ;TODO: Allow user to specify
+                                        ;other quote reader macros to
+                                        ;be ignored and also ignore
+                                        ;quote spelled out without
+                                        ;reader macro.
+    (define-peg-pattern open body (and (? quotation)
+                                       (or "(" "[" "{")))
+    (define-peg-pattern close body (or ")" "]" "}"))
+    (define-peg-pattern string body (and (followed-by "\"")
+                                         (* (or "\\\""
+                                                (and (or NL peg-any)
+                                                     (not-followed-by "\""))))
+                                         (and (or NL peg-any)
+                                              (followed-by "\""))
+                                         "\""))
+    (define-peg-pattern token all (or string
+                                      (and
+                                       (not-followed-by open)
+                                       (not-followed-by close)
+                                       (not-followed-by comment)
+                                       (* (and peg-any
+                                               (not-followed-by open)
+                                               (not-followed-by close)
+                                               (not-followed-by comment)
+                                               (not-followed-by string)
+                                               (not-followed-by whitespace)))
+                                       (or
+                                        (and peg-any (followed-by open))
+                                        (and peg-any (followed-by close))
+                                        (and peg-any (followed-by comment))
+                                        (and peg-any (followed-by string))
+                                        (and peg-any (followed-by whitespace))
+                                        (not-followed-by peg-any)))))
+    (define-peg-pattern list all (or (and (? quotation) "(" program ")")
+                                     (and (? quotation) "[" program "]")
+                                     (and (? quotation) "{" program "}")))
+    (define-peg-pattern t-or-s body (or token list))
+    (define-peg-pattern program all (* (or whitespace
+                                           comment
+                                           t-or-s)))
+    (lambda (file)
+      (call-with-input-file file
+        (lambda (port)
+          ;; It would be nice to match port directly without
+          ;; converting to a string first, but apparently guile cannot
+          ;; do that yet.
+          (let ((string (get-string-all port)))
+            (peg:tree (match-pattern program string))))))))
+
+
+(define-record-type <po-entry>
+  (make-po-entry ecomments ref flags ctxt id idpl)
+  po-entry?
+;;; irrelevant: (tcomments po-entry-tcomments) ;translator-comments
+  (ecomments po-entry-ecomments) ;extracted-comments
+  (ref po-entry-ref) ;reference
+  (flags po-entry-flags)
+;;; irrelevant: (prevctxt po-entry-prevctxt) ;previous-ctxt
+;;; irrelevant: (prev po-entry-prev) ;previous-translation
+  (ctxt po-entry-ctxt) ;msgctxt
+  (id po-entry-id) ;msgid
+  (idpl po-entry-idpl) ;msgid-plural
+;;; irrelevant: (str po-entry-str) ;msgstr string or association list
+;;;                                ;integer to string
+  )
+
+(define (po-equal? po1 po2)
+  "Returns whether PO1 and PO2 have equal ctxt, id and idpl."
+  (and (equal? (po-entry-ctxt po1) (po-entry-ctxt po2))
+       (equal? (po-entry-id po1) (po-entry-id po2))
+       (equal? (po-entry-idpl po1) (po-entry-idpl po2))))
+
+(define (combine-duplicate-po-entries list)
+  "Returns LIST with duplicate po entries replaced by a single PO
+entry with both refs."
+  (let loop ((remaining list))
+    (match remaining
+      (() '())
+      ((head . tail)
+       (receive (before from)
+           (break (cut po-equal? head <>) tail)
+         (cond
+          ((null? from) (cons head (loop tail)))
+          (else
+           (loop
+            (cons
+             (match head
+               (($ <po-entry> ecomments1 ref1 flags ctxt id idpl)
+                (match (car from)
+                  (($ <po-entry> ecomments2 ref2 _ _ _ _)
+                   (let ((ecomments (if (or ecomments1 ecomments2)
+                                        (append (or ecomments1 '())
+                                                (or ecomments2 '()))
+                                        #f))
+                         (ref (if (or ref1 ref2)
+                                  (string-join
+                                   (cons
+                                    (or ref1 "")
+                                    (cons
+                                     (or ref2 "")
+                                     '())))
+                                  #f)))
+                     (make-po-entry ecomments ref flags ctxt id idpl))))))
+             (append before (cdr from)))))))))))
+
+(define (write-po-entry po-entry)
+  (define (prepare-text text)
+    "If TEXT is false, returns #f.  Otherwise corrects the formatting
+of TEXT by escaping backslashes and newlines and enclosing TEXT in
+quotes. Note that Scheme’s write is insufficient because it would
+escape far more.  TODO: Strings should be wrappable to a maximum line
+width."
+    (and text
+         (string-append "\""
+                        (with-output-to-string
+                          (lambda ()
+                            (call-with-input-string text
+                              (lambda (port)
+                                (let loop ((c (get-char port)))
+                                  (unless (eof-object? c)
+                                    (case c
+                                      ((#\\) (display "\\"))
+                                      ((#\newline) (display "\\n"))
+                                      (else (write-char c)))
+                                    (loop (get-char port))))))))
+                        "\"")))
+  (define (write-component c prefix)
+    (when c
+      (begin (display prefix)
+             (display " ")
+             (display c)
+             (newline))))
+  (match po-entry
+    (($ <po-entry> ecomments ref flags ctxt id idpl)
+     (let ((prepared-ctxt (prepare-text ctxt))
+           (prepared-id (prepare-text id))
+           (prepared-idpl (prepare-text idpl)))
+       (when ecomments
+         (for-each
+          (lambda (line)
+            (write-component line "#."))
+          (reverse ecomments)))
+       (write-component ref "#:")
+       (write-component (and flags (string-join flags ", ")) "#,")
+       (write-component prepared-ctxt "msgctxt")
+       (write-component prepared-id "msgid")
+       (write-component prepared-idpl "msgid_plural")
+       (if idpl
+           (begin
+             (display "msgstr[0] \"\"")
+             (newline)
+             (display "msgstr[1] \"\""))
+           (display "msgstr \"\""))
+       (newline)))))
+
+(define %comments-line
+  (make-parameter #f))
+
+(define %ecomments-string
+  (make-parameter #f))
+
+(define (update-ecomments-string! str)
+  "Sets the value of the parameter object %ecomments-string if str is
+an ecomments string.  An ecomments string is extracted from a comment
+because it starts with TRANSLATORS or a key specified with
+--add-comments." ;TODO: Support for other keys is missing.
+  (cond
+   ((not str) (%ecomments-string #f))
+   ((= (1+ (or (%comments-line) -42)) (or (%line-number) 0))
+    (let ((m (string-match ";+[ \t]*(.*)" str)))
+      (when m
+        (%comments-line (%line-number))
+        (%ecomments-string
+         (if (%ecomments-string)
+             (cons (match:substring m 1) (%ecomments-string))
+             (list (match:substring m 1)))))))
+   (else
+    (let ((m (string-match ";+[ \t]*(TRANSLATORS:.*)" str)))
+      (if m
+          (begin
+            (%comments-line (%line-number))
+            (%ecomments-string
+             (if (%ecomments-string)
+                 (cons (match:substring m 1) (%ecomments-string))
+                 (list (match:substring m 1)))))
+          (%ecomments-string '#f))))))
+
+(define %file-name
+  (make-parameter #f))
+
+(define (update-file-name! name)
+  "Sets the value of the parameter object %file-name to NAME."
+  (%file-name name))
+
+(define %old-line-number
+  (make-parameter #f))
+
+(define (update-old-line-number! number)
+  "Sets the value of the parameter object %old-line-number to NUMBER."
+  (%old-line-number number))
+
+(define %line-number
+  (make-parameter #f))
+
+(define (update-line-number! number)
+  "Sets the value of the parameter object %line-number to NUMBER."
+  (%line-number number))
+
+(define (incr-line-number!)
+  "Increments the value of the parameter object %line-number by 1."
+  (%line-number (1+ (%line-number))))
+
+(define (incr-line-number-for-each-nl! list)
+  "Increments %line-number once for each NL recursively in LIST.  Does
+nothing if LIST is no list but e.g. an empty 'program."
+  (when (list? list)
+    (for-each
+     (lambda (part)
+       (match part
+         ('NL (incr-line-number!))
+         ((? list?) (incr-line-number-for-each-nl! part))
+         (else #f)))
+     list)))
+
+(define (current-ref)
+  "Returns the location field for a PO entry."
+  (let ((add (option-ref %options 'add-location 'full)))
+    (cond
+     ((option-ref %options 'no-location #f) #f)
+     ((eq? add 'full)
+      (string-append (%file-name) ":" (number->string (%line-number))))
+     ((eq? add 'file)
+      (%file-name))
+     ((eq? add 'never)
+      #f))))
+
+(define (make-simple-po-entry msgid)
+  (let ((po (make-po-entry
+             (%ecomments-string)
+             (current-ref)
+             #f ;TODO: Use scheme-format for format strings?
+             #f ;no ctxt
+             msgid
+             #f)))
+    (update-ecomments-string! #f)
+    po))
+
+
+(define (matching-keyword id)
+  "Returns the keyword-spec whose identifier is the same as ID, or #f
+if ID is no string or no such keyword-spec exists."
+  (and (symbol? id)
+       (let ((found (member (symbol->string id)
+                            %keyword-specs
+                            (lambda (id spec)
+                              (string=? id (keyword-spec-id spec))))))
+         (and found (car found)))))
+
+(define (nth-exp program n)
+  "Returns the Nth 'token or 'list inside the PROGRAM parse tree or #f
+if no tokens or lists exist."
+  (let loop ((i 0)
+             (rest program))
+    (define (on-hit exp)
+      (if (= i n) exp
+          ;; else:
+          (loop (1+ i) (cdr rest))))
+    (match rest
+      (() #f)
+      ((('token . _) . _) (on-hit (car rest)))
+      ((('list open-paren exp close-paren) . _) (on-hit (car rest)))
+      ((_ . _) (loop i (cdr rest)))
+      (else #f))))
+
+(define (more-than-one-exp? program)
+  "Returns true if PROGRAM consiste of more than one expression."
+  (if (matching-keyword (token->string-symbol-or-keyw (nth-exp program 0)))
+      (nth-exp program 2) ;if there is third element, keyword does not count
+      (nth-exp program 1)))
+
+(define (token->string-symbol-or-keyw tok)
+  "For a parse tree TOK, if it is a 'token parse tree, returns its
+value as a string, symbol or #:-keyword, otherwise returns #f."
+  (match tok
+    (('token (parts ...) . remaining)
+     ;; This is a string with line breaks in it.
+     (with-input-from-string
+         (string-append
+          (apply string-append
+                 (map-in-order
+                  (lambda (part)
+                    (match part
+                      (('NL _)
+                       (begin (incr-line-number!)
+                              "\n"))
+                      (else part)))
+                  parts))
+          (car remaining))
+       (lambda ()
+         (read))))
+    (('token exp)
+     (with-input-from-string exp
+       (lambda ()
+         (read))))
+    (else #f)))
+
+(define (complex-marked-list->po-entries parse-tree)
+  "Checks if PARSE-TREE is marked by a keyword.  If yes, for a complex
+keyword spec, returns a list of po-entries for it.  For a simple
+keyword spec, returns the argument number of its singular form.
+Otherwise returns #f."
+  (let* ((first (nth-exp parse-tree 0))
+         (spec (matching-keyword (token->string-symbol-or-keyw first))))
+    (if spec
+        (if ;if the identifier of a complex keyword occurs first
+         (complex-keyword-spec? spec)
+         ;; then make po entries for it
+         (match spec
+           (($ <keyword-spec> id sg pl c total xcomment)
+            (if (eq? c 'mixed) ; if msgctxt and singular msgid are in one string
+                (let* ((exp (nth-exp parse-tree sg))
+                       (val (token->string-symbol-or-keyw exp))
+                       (idx (if (string? val) (string-rindex val #\|))))
+                  (list
+                   (let ((po (make-po-entry
+                              (%ecomments-string)
+                              (current-ref)
+                              #f ;TODO: Use scheme-format for format strings?
+                              (string-take val idx)
+                              (string-drop val (1+ idx))
+                              #f))) ;plural forms are unsupported here
+                     (update-ecomments-string! #f)
+                     po)))
+                ;; else construct msgids
+                (receive (pl-id pl-entries)
+                    (match pl
+                      (#f (values #f '()))
+                      (else (construct-msgid-and-po-entries
+                             (nth-exp parse-tree pl))))
+                  (receive (sg-id sg-entries)
+                      (construct-msgid-and-po-entries
+                       (nth-exp parse-tree sg))
+                    (cons
+                     (let ((po (make-po-entry
+                                (%ecomments-string)
+                                (current-ref)
+                                #f ;TODO: Use scheme-format for format strings?
+                                (and c (token->string-symbol-or-keyw
+                                        (nth-exp parse-tree c)))
+                                sg-id
+                                pl-id)))
+                       (update-ecomments-string! #f)
+                       po)
+                     (append sg-entries pl-entries)))))))
+         ;; else if it is a simple keyword, return the argnum:
+         (keyword-spec-sg spec))
+        ;; if no keyword occurs, then false
+        #f)))
+
+(define (construct-po-entries parse-tree)
+  "Converts a PARSE-TREE resulting from a call to parse-scheme-file to
+a list of po-entry records.  Unlike construct-msgid-and-po-entries,
+strings are not collected to a msgid.  The list of po-entry records is
+the return value."
+  (let ((entries (complex-marked-list->po-entries parse-tree)))
+    (cond
+     ((list? entries) entries)
+     ((number? entries) ;parse-tree yields a single, simple po entry
+      (update-old-line-number! (%line-number))
+      (receive (id entries)
+          (construct-msgid-and-po-entries
+           (nth-exp parse-tree entries))
+        (update-line-number! (%old-line-number))
+        (let ((po (make-simple-po-entry id)))
+          (incr-line-number-for-each-nl! parse-tree)
+          (cons po entries))))
+     (else ;search for marked translations in parse-tree
+      (match parse-tree
+        (() '())
+        (('comment str) (begin
+                          (update-ecomments-string! str)
+                          '()))
+        (('NL _) (begin (incr-line-number!) '()))
+        (('token . _) (begin (incr-line-number-for-each-nl! parse-tree) '()))
+        (('list open-paren program close-paren)
+         (construct-po-entries program))
+        (('program . components)
+         (append-map construct-po-entries components))
+        ;; Note: PEG compresses empty programs to non-lists:
+        ('program
+         '()))))))
+
+(define* (tag counter prefix #:key (flavor 'start))
+  "Formats the number COUNTER as a tag according to FLAVOR, which is
+either 'start, 'end or 'empty for a start, end or empty tag,
+respectively."
+  (string-append "<"
+                 (if (eq? flavor 'end) "/" "")
+                 prefix
+                 (number->string counter)
+                 (if (eq? flavor 'empty) "/" "")
+                 ">"))
+
+(define-record-type <construct-fold-state>
+  (make-construct-fold-state msgid-string maybe-part counter po-entries)
+  construct-fold-state?
+  ;; msgid constructed so far; #f if none, "" if only empty string:
+  (msgid-string construct-fold-state-msgid-string)
+  ;; only append this if string follows:
+  (maybe-part construct-fold-state-maybe-part)
+  ;; counter for next tag:
+  (counter construct-fold-state-counter)
+  ;; complete po entries from marked sub-expressions:
+  (po-entries construct-fold-state-po-entries))
+
+(define* (construct-msgid-and-po-entries parse-tree
+                                         #:optional
+                                         (prefix ""))
+  "Like construct-po-entries, but with two return values.  The first
+is an accumulated msgid constructed from all components in PARSE-TREE
+for use in make-po-entry.  Non-strings are replaced by tags containing
+PREFIX.  The second return value is a list of po entries for
+sub-expressions marked with a complex keyword spec."
+  (match parse-tree
+    (() (values "" '()))
+    ;; Note: PEG compresses empty programs to non-lists:
+    ('program (values "" '()))
+    (('comment str) (begin
+                      (update-ecomments-string! str)
+                      (values "" '())))
+    (('NL _) (begin (incr-line-number!)
+                    (error "Program consists only of line break."
+                           `(,(%file-name) ,(%line-number)))))
+    (('token . _)
+     (let ((maybe-string (token->string-symbol-or-keyw parse-tree)))
+       (if (string? maybe-string)
+           (values maybe-string '())
+           (error "Single symbol marked for translation."
+                  `(,maybe-string ,(%file-name) ,(%line-number))))))
+    (('list open-paren program close-paren)
+     ;; parse program instead
+     (construct-msgid-and-po-entries program prefix))
+    (('program (? matching-keyword))
+     (error "Double-marked for translation."
+            `(,parse-tree ,(%file-name) ,(%line-number))))
+    (('program . components)
+     ;; Concatenate strings in parse-tree to a new msgid and add an
+     ;; <x> tag for each list in between.
+     (match
+         (fold
+          (lambda (component prev-state)
+            (match prev-state
+              (($ <construct-fold-state> msgid-string maybe-part
+                  counter po-entries)
+               (match component
+                 (('comment str) (begin (update-ecomments-string! str)
+                                        prev-state))
+                 (('NL _) (begin (incr-line-number!)
+                                 prev-state))
+                 (('token . _)
+                  (let ((maybe-string (token->string-symbol-or-keyw component)))
+                    (cond
+                     ((string? maybe-string)
+                      ;; if string, append maybe-string to previous msgid
+                      (make-construct-fold-state
+                       (string-append (or msgid-string "")
+                                      maybe-part maybe-string)
+                       ""
+                       counter
+                       po-entries))
+                     ((and (more-than-one-exp? components) ;not the only symbol
+                           (or (not msgid-string) ;no string so far
+                               (string-suffix? ">" msgid-string))) ;tag before
+                      prev-state) ;then ignore
+                     (else ;append tag representing the token
+                      (make-construct-fold-state
+                       msgid-string
+                       (string-append
+                        maybe-part
+                        (tag counter prefix #:flavor 'empty))
+                       (1+ counter)
+                       po-entries)))))
+                 (('list open-paren program close-paren)
+                  (let ((first (nth-exp program 0)))
+                    (incr-line-number-for-each-nl! list)
+                    (match (complex-marked-list->po-entries program)
+                      ((? list? result)
+                       (make-construct-fold-state
+                        msgid-string
+                        (string-append
+                         maybe-part
+                         (tag counter prefix #:flavor 'empty))
+                        (1+ counter)
+                        (append result po-entries)))
+                      (result
+                       (cond
+                        ((number? result)
+                         (receive (id entries)
+                             (construct-msgid-and-po-entries
+                              (nth-exp program result)
+                              (string-append prefix
+                                             (number->string counter)
+                                             "."))
+                           (make-construct-fold-state
+                            (string-append (or msgid-string "")
+                                           maybe-part
+                                           (tag counter prefix
+                                                #:flavor 'start)
+                                           id
+                                           (tag counter prefix
+                                                #:flavor 'end))
+                            ""
+                            (1+ counter)
+                            (append entries po-entries))))
+                        ((not (more-than-one-exp? components))
+                         ;; Singletons do not need to be marked.
+                         (receive (id entries)
+                             (construct-msgid-and-po-entries
+                              program
+                              prefix)
+                           (make-construct-fold-state
+                            id
+                            ""
+                            counter
+                            (append entries po-entries))))
+                        (else ;unmarked list
+                         (if (not msgid-string)
+                             ;; then ignore
+                             prev-state
+                             ;; else:
+                             (make-construct-fold-state
+                              msgid-string
+                              (string-append
+                               maybe-part
+                               (tag counter prefix #:flavor 'empty))
+                              (1+ counter)
+                              po-entries))))))))))))
+          (make-construct-fold-state #f "" 1 '())
+          components)
+       (($ <construct-fold-state> msgid-string maybe-part counter po-entries)
+        (values (or msgid-string
+                    (error "Marking for translation yields empty msgid."
+                           %file-name %line-number))
+                po-entries))))))
+
+(define scheme-file->po-entries
+  (compose construct-po-entries
+           parse-scheme-file))
+
+(define %files-from-port
+  (let ((files-from (option-ref %options 'files #f)))
+    (if files-from
+        (open-input-file files-from)
+        (current-input-port))))
+
+(define %source-files
+  (let loop ((line (get-line %files-from-port))
+             (source-files '()))
+    (if (eof-object? line)
+        (begin
+          (close-port %files-from-port)
+          source-files)
+        ;; else read file names before comment
+        (let ((before-comment (car (string-split line #\#))))
+          (loop (get-line %files-from-port)
+                (append
+                 (map match:substring (list-matches "[^ \t]+" before-comment))
+                 source-files))))))
+
+(define %output-po-entries
+  (fold (lambda (scheme-file po-entries)
+          (begin
+            (update-file-name! scheme-file)
+            (update-line-number! 1)
+            (update-old-line-number! #f)
+            (%comments-line #f)
+            (append (scheme-file->po-entries scheme-file)
+                    po-entries)))
+        '()
+        %source-files))
+
+(define %output-port
+  (let ((output (option-ref %options 'output #f))
+        (domain (option-ref %options 'default-domain #f)))
+    (cond
+     (output (open-output-file output))
+     (domain (open-output-file (string-append domain ".po")))
+     (else (open-output-file "messages.po")))))
+
+(with-output-to-port %output-port
+  (lambda ()
+    (let ((copyright (option-ref %options 'copyright-holder
+                                 "THE PACKAGE'S COPYRIGHT HOLDER"))
+          (package (option-ref %options 'package-name "PACKAGE"))
+          (version (option-ref %options 'package-version #f))
+          (bugs-email (option-ref %options 'msgid-bugs-address "")))
+      (display "# SOME DESCRIPTIVE TITLE.\n")
+      (display (string-append "# Copyright (C) YEAR " copyright "\n"))
+      (display (string-append "# This file is distributed under the same \
+license as the " package " package.\n"))
+      (display "# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n")
+      (display "#\n")
+      (write-po-entry (make-po-entry #f #f '("fuzzy") #f "" #f))
+      (display (string-append "\"Project-Id-Version: "
+                              package
+                              (if version
+                                  (string-append " " version)
+                                  "")
+                              "\\n\"\n"))
+      (display (string-append "\"Report-Msgid-Bugs-To: "
+                              bugs-email
+                              "\\n\"\n"))
+      (display (string-append "\"POT-Creation-Date: "
+                              (date->string (current-date) "~1 ~H:~M~z")
+                              "\\n\"\n"))
+      (display "\"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n")
+      (display "\"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n\"\n")
+      (display "\"Language-Team: LANGUAGE <LL@HIDDEN>\\n\"\n")
+      (display "\"Language: \\n\"\n")
+      (display "\"MIME-Version: 1.0\\n\"\n")
+      (display "\"Content-Type: text/plain; charset=UTF-8\\n\"\n")
+      (display "\"Content-Transfer-Encoding: 8bit\\n\"\n")
+      (for-each (lambda (po-entry)
+                  (begin
+                    (newline)
+                    (write-po-entry po-entry)))
+                (combine-duplicate-po-entries %output-po-entries)))))
diff --git a/website/sexp-xgettext.scm b/website/sexp-xgettext.scm
new file mode 100644
index 0000000..2b7abfc
--- /dev/null
+++ b/website/sexp-xgettext.scm
@@ -0,0 +1,530 @@
+;;; GNU Guix web site
+;;; Copyright © 2019 Florian Pelz <pelzflorian@HIDDEN>
+;;;
+;;; 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 (sexp-xgettext)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 peg)
+  #:use-module (ice-9 rdelim)
+  #:use-module (ice-9 receive)
+  #:use-module (ice-9 regex)
+  #:use-module (srfi srfi-1) ;lists
+  #:use-module (srfi srfi-9) ;records
+  #:export (set-complex-keywords!
+            set-simple-keywords!
+            sgettext
+            sngettext
+            spgettext
+            snpgettext
+            %linguas))
+
+(define %complex-keywords
+  ;; Use set-complex-keywords! to change this to a list of keywords
+  ;; for sexp-xgettext functions other than sgettext.
+  (make-parameter '()))
+
+(define (set-complex-keywords! kw)
+  (%complex-keywords kw))
+
+(define %simple-keywords
+  ;; Use set-simple-keywords! to change this to a list of keywords
+  ;; for sgettext.
+  (make-parameter '()))
+
+(define (set-simple-keywords! kw)
+  (%simple-keywords kw))
+
+(define (gettext-keyword? id)
+  (or (member id (%complex-keywords))
+      (member id (%simple-keywords))))
+
+;;COPIED FROM scripts/sexp-xgettext.scm:
+(define* (tag counter prefix #:key (flavor 'start))
+  "Formats the number COUNTER as a tag according to FLAVOR, which is
+either 'start, 'end or 'empty for a start, end or empty tag,
+respectively."
+  (string-append "<"
+                 (if (eq? flavor 'end) "/" "")
+                 prefix
+                 (number->string counter)
+                 (if (eq? flavor 'empty) "/" "")
+                 ">"))
+;;END COPIED FROM scripts/sexp-xgettext.scm
+
+;;ADAPTED FROM scripts/sexp-xgettext.scm
+(define-record-type <construct-fold-state>
+  (make-construct-fold-state msgid-string maybe-part counter)
+  construct-fold-state?
+  ;; msgid constructed so far; #f if none, "" if only empty string
+  (msgid-string construct-fold-state-msgid-string)
+  ;; only append this if string follows:
+  (maybe-part construct-fold-state-maybe-part)
+  ;; counter for next tag:
+  (counter construct-fold-state-counter))
+;;END ADAPTED FROM scripts/sexp-xgettext.scm
+
+(define (sexp->msgid exp)
+  "Return the msgid as constructed by construct-msgid-and-po-entries
+in scripts/sexp-xgettext.scm from the expression EXP."
+  (let loop ((exp exp)
+             (prefix ""))
+    (match exp
+      (() "")
+      ((or ('quote inner-exp)
+           ('quasiquote inner-exp)
+           ('unquote inner-exp)
+           ('unquote-splicing inner-exp))
+       (loop inner-exp prefix))
+      ((first-component . components)
+       (cond
+        ((gettext-keyword? first-component)
+         (error "Double-marked for translation." exp))
+        (else
+         (or
+          (construct-fold-state-msgid-string
+           (fold
+            (lambda (component prev-state)
+              (match prev-state
+                (($ <construct-fold-state> msgid-string maybe-part counter)
+                 (let inner-loop ((exp component))
+                   (match exp
+                     ((or (? symbol?) (? keyword?))
+                      (if (not msgid-string)
+                          ;; ignore symbols at the beginning
+                          prev-state
+                          ;; else make a tag for the symbol
+                          (make-construct-fold-state
+                           msgid-string
+                           (string-append maybe-part
+                                          (tag counter prefix #:flavor 'empty))
+                           (1+ counter))))
+                     ((? string?)
+                      (make-construct-fold-state
+                       (string-append (or msgid-string "")
+                                      maybe-part exp)
+                       "" counter))
+                     ((? list?)
+                      (match exp
+                        (() ;ignore empty list
+                         prev-state)
+                        ((or (singleton)
+                             ('quote singleton)
+                             ('quasiquote singleton)
+                             ('unquote singleton)
+                             ('unquote-splicing singleton))
+                         (inner-loop singleton))
+                        ((components ...)
+                         (cond
+                          ((and (not (null? components))
+                                (member (car components) (%simple-keywords)))
+                           ;; if marked for translation, insert inside tag
+                           (make-construct-fold-state
+                            (string-append (or msgid-string "")
+                                           maybe-part
+                                           (tag counter prefix #:flavor 'start)
+                                           (loop (cadr components)
+                                                 (string-append
+                                                  prefix
+                                                  (number->string counter)
+                                                  "."))
+                                           (tag counter prefix #:flavor 'end))
+                            ""
+                            (1+ counter)))
+                          ;; else ignore if first
+                          ((not msgid-string)
+                           prev-state)
+                          ;; else make empty tag
+                          (else (make-construct-fold-state
+                                 msgid-string
+                                 (string-append
+                                  maybe-part
+                                  (tag counter prefix #:flavor 'empty))
+                                 (1+ counter))))))))))))
+            (make-construct-fold-state #f "" 1)
+            exp))
+          (error "Marking for translation yields empty msgid." exp)))))
+      ((? string?) exp)
+      (else (error "Single symbol marked for translation." exp)))))
+
+(define-record-type <deconstruct-fold-state>
+  (make-deconstruct-fold-state tagged maybe-tagged counter)
+  deconstruct-fold-state?
+  ;; XML-tagged expressions as an association list name->expression:
+  (tagged deconstruct-fold-state-tagged)
+  ;; associate this not-yet-tagged expression with pre if string
+  ;; follows, with post if not:
+  (maybe-tagged deconstruct-fold-state-maybe-tagged)
+  ;; counter for next tag:
+  (counter deconstruct-fold-state-counter))
+
+(define (deconstruct exp msgstr)
+  "Return an s-expression like EXP, but filled with the content from
+MSGSTR."
+  (define (find-empty-element msgstr name)
+    "Returns the regex match structure for the empty tag for XML
+element of type NAME inside MSGSTR.  If the element does not exist or
+is more than the empty tag, #f is returned."
+    (string-match (string-append "<" (regexp-quote name) "/>") msgstr))
+  (define (find-element-with-content msgstr name)
+    "Returns the regex match structure for the non-empty XML element
+of type NAME inside MSGSTR.  Submatch 1 is its content.  If the
+element does not exist or is just the empty tag, #f is returned."
+    (string-match (string-append "<" (regexp-quote name) ">"
+                                 "(.*)"
+                                 "</" (regexp-quote name) ">")
+                  msgstr))
+  (define (get-first-element-name prefix msgstr)
+    "Returns the name of the first XML element in MSGSTR whose name
+begins with PREFIX, or #f if there is none."
+    (let ((m (string-match
+              (string-append "<(" (regexp-quote prefix) "[^>/.]+)/?>") msgstr)))
+      (and m (match:substring m 1))))
+  (define (prefix+counter prefix counter)
+    "Returns PREFIX with the number COUNTER appended."
+    (string-append prefix (number->string counter)))
+  (let loop ((exp exp)
+             (msgstr msgstr)
+             (prefix ""))
+    (define (unwrap-marked-expression exp)
+      "Returns two values for an expression EXP containing a (possibly
+quoted/unquoted) marking for translation with a simple keyword at its
+root.  The first return value is a list with the inner expression, the
+second is a procedure to wrap the processed inner expression in the
+same quotes or unquotes again."
+      (match exp
+        (('quote inner-exp)
+         (receive (unwrapped quotation)
+             (unwrap-marked-expression inner-exp)
+           (values unwrapped
+                   (lambda (res)
+                     (list 'quote (quotation res))))))
+        (('quasiquote inner-exp)
+         (receive (unwrapped quotation)
+             (unwrap-marked-expression inner-exp)
+           (values unwrapped
+                   (lambda (res)
+                     (list 'quasiquote (quotation res))))))
+        (('unquote inner-exp)
+         (receive (unwrapped quotation)
+             (unwrap-marked-expression inner-exp)
+           (values unwrapped
+                   (lambda (res)
+                     (list 'unquote (quotation res))))))
+        (('unquote-splicing inner-exp)
+         (receive (unwrapped quotation)
+             (unwrap-marked-expression inner-exp)
+           (values unwrapped
+                   (lambda (res)
+                     (list 'unquote-splicing (quotation res))))))
+        ((marking . rest) ;list with marking as car
+         ;; assume arg to translate is first argument to marking:
+         (values (list-ref rest 0) identity))))
+    (define (assemble-parenthesized-expression prefix tagged)
+      "Returns a parenthesized expression deconstructed from MSGSTR
+with the meaning of XML elements taken from the name->expression
+association list TAGGED.  The special tags [prefix]pre and
+[prefix]post are associated with a list of expressions before or after
+all others in the parenthesized expression with the prefix,
+respectively, in reverse order."
+      (append ;prepend pre elements to what is in msgstr
+       (reverse (or (assoc-ref tagged (string-append prefix "pre")) '()))
+       (let assemble ((rest msgstr))
+         (let ((name (get-first-element-name prefix rest)))
+           (cond
+            ((and name (find-empty-element rest name)) =>
+             ;; first XML element in rest is empty element
+             (lambda (m)
+               (cons*
+                (match:prefix m) ;prepend string before name
+                (assoc-ref tagged name) ;and expression for name
+                (assemble (match:suffix m)))))
+            ((and name (find-element-with-content rest name)) =>
+             ;; first XML element in rest has content
+             (lambda (m)
+               (receive (unwrapped quotation)
+                   (unwrap-marked-expression (assoc-ref tagged name))
+                 (cons*
+                  (match:prefix m) ;prepend string before name
+                  ;; and the deconstructed element with the content as msgstr:
+                  (quotation
+                   (loop
+                    unwrapped
+                    (match:substring m 1)
+                    (string-append name ".")))
+                  (assemble (match:suffix m))))))
+            (else
+             ;; there is no first element
+             (cons
+              rest ;return remaining string
+              (reverse ;and post expressions
+               (or (assoc-ref tagged (string-append prefix "post")) '())))))))))
+    (match exp
+      (() '())
+      (('quote singleton)
+       (cons 'quote (list (loop singleton msgstr prefix))))
+      (('quasiquote singleton)
+       (cons 'quasiquote (list (loop singleton msgstr prefix))))
+      (('unquote singleton)
+       (cons 'unquote (list (loop singleton msgstr prefix))))
+      (('unquote-splicing singleton)
+       (cons 'unquote-splicing (list (loop singleton msgstr prefix))))
+      ((singleton)
+       (list (loop singleton msgstr prefix)))
+      ((first-component . components)
+       (cond
+        ((gettext-keyword? first-component)
+         ;; another marking for translation
+         ;; -> should be an error anyway; just retain exp
+         exp)
+        (else
+         ;; This handles a single level of a parenthesized expression.
+         ;; assemble-parenthesized-expression will call loop to
+         ;; recurse to deeper levels.
+         (let ((tagged-state
+                (fold
+                 (lambda (component prev-state)
+                   (match prev-state
+                     (($ <deconstruct-fold-state> tagged maybe-tagged counter)
+                      (let inner-loop ((exp component) ;sexp to handle
+                                       (quoting identity)) ;for wrapping state
+                        (define (tagged-with-maybes)
+                          "Returns the value of tagged after adding
+all maybe-tagged expressions.  This should be used as the base value
+for tagged when a string or marked expression is seen."
+                          (match counter
+                            (#f
+                             (alist-cons (string-append prefix "pre")
+                                         maybe-tagged
+                                         tagged))
+                            ((? number?)
+                             (let accumulate ((prev-counter counter)
+                                              (maybes (reverse maybe-tagged)))
+                               (match maybes
+                                 (() tagged)
+                                 ((head . tail)
+                                  (alist-cons
+                                   (prefix+counter prefix prev-counter)
+                                   head
+                                   (accumulate (1+ prev-counter) tail))))))))
+                        (define (add-maybe exp)
+                          "Returns a deconstruct-fold-state with EXP
+added to maybe-tagged.  This should be used for expressions that are
+neither strings nor marked for translation with a simple keyword."
+                          (make-deconstruct-fold-state
+                           tagged
+                           (cons (quoting exp) maybe-tagged)
+                           counter))
+                        (define (counter-with-maybes)
+                          "Returns the old counter value incremented
+by one for each expression in maybe-tagged.  This should be used
+together with tagged-with-maybes."
+                          (match counter
+                            ((? number?)
+                             (+ counter (length maybe-tagged)))
+                            (#f
+                             1)))
+                        (define (add-tagged exp)
+                          "Returns a deconstruct-fold-state with an
+added association in tagged from the current counter to EXP.  If
+MAYBE-TAGGED is not empty, associations for its expressions are added
+to pre or their respective counter.  This should be used for
+expressions marked for translation with a simple keyword."
+                          (let ((c (counter-with-maybes)))
+                            (make-deconstruct-fold-state
+                             (alist-cons
+                              (prefix+counter prefix c)
+                              (quoting exp)
+                              (tagged-with-maybes))
+                             '()
+                             (1+ c))))
+                        (match exp
+                          (('quote inner-exp)
+                           (inner-loop inner-exp
+                                       (lambda (res)
+                                         (list 'quote res))))
+                          (('quasiquote inner-exp)
+                           (inner-loop inner-exp
+                                       (lambda (res)
+                                         (list 'quasiquote res))))
+                          (('unquote inner-exp)
+                           (inner-loop inner-exp
+                                       (lambda (res)
+                                         (list 'unquote res))))
+                          (('unquote-splicing inner-exp)
+                           (inner-loop inner-exp
+                                       (lambda (res)
+                                         (list 'unquote-splicing res))))
+                          (((? gettext-keyword?) . rest)
+                           (add-tagged exp))
+                          ((or (? symbol?) (? keyword?) (? list?))
+                           (add-maybe exp))
+                          ((? string?)
+                           ;; elements in maybe-tagged appear between strings
+                           (let ((c (counter-with-maybes)))
+                             (make-deconstruct-fold-state
+                              (tagged-with-maybes)
+                              '()
+                              c))))))))
+                 (make-deconstruct-fold-state '() '() #f)
+                 exp)))
+           (match tagged-state
+             (($ <deconstruct-fold-state> tagged maybe-tagged counter)
+              (assemble-parenthesized-expression
+               prefix
+               (match maybe-tagged
+                 (() tagged)
+                 (else ;associate maybe-tagged with pre or post
+                  (alist-cons
+                   (cond ;if there already is a pre, use post
+                    ((assoc-ref tagged (string-append prefix "pre"))
+                     (string-append prefix "post"))
+                    (else (string-append prefix "pre")))
+                   maybe-tagged
+                   tagged))))))))))
+      ((? string?) msgstr)
+      (else (error "Single symbol marked for translation." exp)))))
+
+;; NOTE: The sgettext macros have no hygiene because they use
+;; datum->syntax and do not preserve the semantics of anything looking
+;; like an sgettext macro.  This is an exceptional use case; do not
+;; try this at home.
+
+(define (sgettext x)
+  "After choosing an identifier for marking s-expressions for
+translation, make it usable by defining a macro with it calling
+sgettext.  If for example the chosen identifier is G_,
+use (define-syntax G_ sgettext)."
+  (syntax-case x ()
+    ((id exp)
+     (let* ((msgid (sexp->msgid (syntax->datum #'exp)))
+            (new-exp (deconstruct (syntax->datum #'exp)
+                                  (gettext msgid))))
+       (datum->syntax #'id new-exp)))))
+
+;; gettext’s share/gettext/gettext.h tells us we can prepend a msgctxt
+;; and #\eot before a msgid in a gettext call.
+
+(define (spgettext x)
+  "After choosing an identifier for behavior similar to pgettext:1c,2,
+make it usable like (define-syntax C_ spgettext)."
+  (syntax-case x ()
+    ((id msgctxt exp)
+     (let* ((gettext-context-glue #\eot) ;as defined in gettext.h
+            (lookup (string-append (syntax->datum #'msgctxt)
+                                   (string gettext-context-glue)
+                                   (sexp->msgid (syntax->datum #'exp))))
+            (msgstr (car (reverse (string-split (gettext lookup)
+                                                gettext-context-glue))))
+            (new-exp (deconstruct (syntax->datum #'exp)
+                                  msgstr)))
+       (datum->syntax #'id new-exp)))))
+
+(define %plural-numbers
+  ;; Hard-coded list of input numbers such that for each language’s
+  ;; plural formula, for each possible output grammatical number,
+  ;; there is an n among %plural-numbers that yields this output
+  ;; (cf. section Plural forms in the gettext manual), except 1 is
+  ;; omitted from this list because it is a special case for
+  ;; sngettext.  That is, calling ngettext with each number from
+  ;; %plural-numbers and with 1 in any locale is guaranteed to return
+  ;; each plural form at least once.  It would be more resilient
+  ;; towards new languages if instead of hard-coding we computed this
+  ;; from the Plural-Forms in the MO file header entry, but that is
+  ;; not worth the incurred code complexity.
+  '(0 2 3 11 100))
+
+(define (sngettext x)
+  "After choosing an identifier for behavior similar to ngettext:1,2,
+make it usable like (define-syntax N_ sngettext).  sngettext takes
+into account that not all languages have only singular and plural
+forms."
+  (syntax-case x ()
+    ((id exp1 exp2 n)
+     (let* ((msgid1 (sexp->msgid (syntax->datum #'exp1)))
+            (msgid2 (sexp->msgid (syntax->datum #'exp2)))
+            (msgstr1 (ngettext msgid1 msgid2 1))
+            (result (acons ;return an association list msgstr->deconstructed
+                     ;; msgstr for n=1:
+                     msgstr1
+                     `(,'unquote ,(deconstruct (syntax->datum #'exp1)
+                                               msgstr1))
+                     ;; other msgstr for n of each plural form:
+                     (map
+                      (lambda (n)
+                        (let ((msgstr (ngettext msgid1 msgid2 n)))
+                          (cons msgstr `(,'unquote
+                                         ,(deconstruct (syntax->datum #'exp2)
+                                                       msgstr)))))
+                      %plural-numbers))))
+       (datum->syntax
+        #'id
+        `(,assoc-ref (,'quasiquote ,result)
+                     (,ngettext ,msgid1 ,msgid2 ,(syntax->datum #'n))))))))
+
+(define (snpgettext x)
+  "After choosing an identifier for behavior similar to npgettext:1c,2,3,
+make it usable like (define-syntax NC_ snpgettext)."
+  (syntax-case x ()
+    ((id msgctxt exp1 exp2 n)
+     (let* ((gettext-context-glue #\eot) ;as defined in gettext.h
+            (msgid1 (string-append (syntax->datum #'msgctxt)
+                                   (string gettext-context-glue)
+                                   (sexp->msgid (syntax->datum #'exp1))))
+            ;; gettext.h implementation shows: msgctxt is only part of msgid1.
+            (msgid2 (sexp->msgid (syntax->datum #'exp2)))
+            (msgstr1 (car
+                      (reverse
+                       (string-split
+                        (ngettext msgid1 msgid2 1)
+                        gettext-context-glue))))
+            (result (acons ;return an association list msgstr->deconstructed
+                     ;; msgstr for n=1:
+                     msgstr1
+                     `(,'unquote ,(deconstruct (syntax->datum #'exp1)
+                                               msgstr1))
+                     ;; other msgstr for n of each plural form:
+                     (map
+                      (lambda (n)
+                        (let ((msgstr (car
+                                       (reverse
+                                        (string-split
+                                         (ngettext msgid1 msgid2 n)
+                                         gettext-context-glue)))))
+                          (cons msgstr `(,'unquote
+                                         ,(deconstruct (syntax->datum #'exp2)
+                                                       msgstr)))))
+                      %plural-numbers))))
+       (datum->syntax
+        #'id
+        `(,assoc-ref (,'quasiquote ,result)
+                     (,car
+                      (,reverse
+                       (,string-split
+                        (,ngettext ,msgid1 ,msgid2 ,(syntax->datum #'n))
+                        ,gettext-context-glue)))))))))
+
+(define %linguas
+  (with-input-from-file "po/LINGUAS"
+    (lambda _
+      (let loop ((line (read-line)))
+        (if (eof-object? line)
+            '()
+            ;; else read linguas before comment
+            (let ((before-comment (car (string-split line #\#))))
+              (append
+               (map match:substring (list-matches "[^ \t]+" before-comment))
+               (loop (read-line)))))))))
-- 
2.23.0


--jc5p4xzpw3odooxa
Content-Type: text/plain; charset=utf-8
Content-Disposition: attachment; filename="0005-website-Mark-all-files-in-apps-for-translation.patch"
Content-Transfer-Encoding: 8bit

From a5cc8ce287f8d2817ba27c1220461b282efe8cbf Mon Sep 17 00:00:00 2001
From: Florian Pelz <pelzflorian@HIDDEN>
Date: Fri, 6 Sep 2019 08:42:15 +0200
Subject: [PATCH 5/6] website: Mark all files in apps for translation.

* website/po/guix-website.pot: New file.
* website/apps/base/utils.scm (manual-url-with-language): New
procedure.
* website/apps/base/templates/components.scm (manual-href,
manual-link-yellow): New procedures.
(breadcrumbs, contact->shtml, navbar): Mark for translation.
* website/apps/base/data.scm (contact-media, screenshots): Mark for
translation.
* website/apps/base/templates/about.scm (about-t): Mark for
translation.
* website/apps/base/templates/contact.scm (contact-t): Mark for
translation.
* website/apps/base/templates/contribute.scm (contribute-t): Mark for
translation.
* website/apps/base/templates/donate.scm (donate-t): Mark for
translation.
* website/apps/base/templates/graphics.scm (graphics-t): Mark for
translation.
* website/apps/base/templates/help.scm (help-t): Mark for translation.
* website/apps/base/templates/home.scm (home-t): Mark for translation.
* website/apps/base/templates/irc.scm (irc-t): Mark for translation.
* website/apps/base/templates/menu.scm (menu-t): Mark for translation.
* website/apps/base/templates/screenshot.scm (screenshot-t):
Mark for translation.
* website/apps/base/templates/security.scm (security-t): Mark for
translation.
* website/apps/base/templates/theme.scm (theme): Mark for translation.
* website/apps/blog/templates/components.scm (post-preview, sidebar):
Mark for translation.
* website/apps/blog/templates/feed.scm (atom-feed-t): Mark for
translation.
* website/apps/blog/templates/post-list.scm (post-list-t): Mark for
translation.
* website/apps/blog/templates/post.scm (post-t): Mark for translation.
* website/apps/blog/templates/tag.scm (tag-t): Mark for translation.
* website/apps/download/data.scm (home-t): Mark for translation.
* website/apps/download/templates/components.scm (system-downloads):
Mark for translation.
* website/apps/download/templates/download.scm (download-t): Mark for
translation.
* website/apps/packages/templates/components.scm (detailed-package-preview,
letter-selector, sidebar, supported-systems->shtml): Mark for translation.
* website/apps/packages/templates/detailed-index.scm (detailed-index-t):
Mark for translation.
* website/apps/packages/templates/detailed-package-list.scm
(detailed-package-list-t): Mark for translation.
* website/apps/packages/templates/index.scm (index-t): Mark for translation.
* website/apps/packages/templates/package-list.scm (package-list-t):
Mark for translation.
* website/apps/packages/templates/package.scm (package-t): Mark for
translation.
---
 website/apps/base/data.scm                    |  242 ++--
 website/apps/base/templates/about.scm         |  169 ++-
 website/apps/base/templates/components.scm    |  102 +-
 website/apps/base/templates/contact.scm       |   20 +-
 website/apps/base/templates/contribute.scm    |  385 +++---
 website/apps/base/templates/donate.scm        |  397 +++---
 website/apps/base/templates/graphics.scm      |   87 +-
 website/apps/base/templates/help.scm          |   86 +-
 website/apps/base/templates/home.scm          |  245 ++--
 website/apps/base/templates/irc.scm           |   48 +-
 website/apps/base/templates/menu.scm          |   17 +-
 website/apps/base/templates/screenshot.scm    |   14 +-
 website/apps/base/templates/security.scm      |   91 +-
 website/apps/base/templates/theme.scm         |   48 +-
 website/apps/base/utils.scm                   |   23 +
 website/apps/blog/templates/components.scm    |   16 +-
 website/apps/blog/templates/feed.scm          |    3 +-
 website/apps/blog/templates/post-list.scm     |   23 +-
 website/apps/blog/templates/post.scm          |   14 +-
 website/apps/blog/templates/tag.scm           |   27 +-
 website/apps/download/data.scm                |   46 +-
 .../apps/download/templates/components.scm    |   12 +-
 website/apps/download/templates/download.scm  |   68 +-
 .../apps/packages/templates/components.scm    |   80 +-
 .../packages/templates/detailed-index.scm     |   47 +-
 .../templates/detailed-package-list.scm       |   23 +-
 website/apps/packages/templates/index.scm     |   45 +-
 .../apps/packages/templates/package-list.scm  |   21 +-
 website/apps/packages/templates/package.scm   |   56 +-
 website/po/guix-website.pot                   | 1209 +++++++++++++++++
 30 files changed, 2618 insertions(+), 1046 deletions(-)
 create mode 100644 website/po/guix-website.pot

diff --git a/website/apps/base/data.scm b/website/apps/base/data.scm
index dfe65fe..1a4217c 100644
--- a/website/apps/base/data.scm
+++ b/website/apps/base/data.scm
@@ -1,10 +1,15 @@
 ;;; GNU Guix web site
+;;; Copyright © 2019 Florian Pelz <pelzflorian@HIDDEN>
 ;;; Initially written by sirgazil who waves all
 ;;; copyright interest on this file.
 
 (define-module (apps base data)
+  #:use-module (apps base templates components)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
+  #:use-module (srfi srfi-1)
+  #:use-module (sexp-xgettext)
   #:export (contact-media
 	    screenshots))
 
@@ -17,150 +22,187 @@
   (list
    ;; The first three will be featured in the home page.
    (contact
-    #:name "IRC Channel"
+    #:name (G_ "IRC Channel")
     #:description
-    '(p
-      "Join the " (code "#guix") " channel on the Freenode IRC network to chat
-      with the community about GNU Guix or to get help in
-      real-time.")
+    (G_
+     `(p
+       "Join the " (code "#guix") " channel on the Freenode IRC network to chat
+       with the community about GNU Guix or to get help in
+       real-time."))
     #:url (guix-url "contact/irc/")
     #:log guix-irc-log-url)
 
    (contact
-    #:name "Info Mailing List"
+    #:name (G_ "Info Mailing List")
     #:description
-    '(p "Subscribe to the " (code "info-guix") " low-traffic mailing
+    (G_
+     `(p
+       "Subscribe to the " (code "info-guix") " low-traffic mailing
 list to receive important announcements sent by the project maintainers (in
-English).")
+English)."))
     #:url "https://lists.gnu.org/mailman/listinfo/info-guix"
     #:log "https://lists.gnu.org/archive/html/info-guix")
 
    (contact
-    #:name "Help Mailing List"
+    #:name (G_ "Help Mailing List")
     #:description
-    `(("de"
-       "Melden Sie sich bei der „Help“-Mailingliste an, um per E-Mail
+    ;; Compute an association list from language code to blurb.
+    ;; If possible, look up translated blurbs from the PO file.
+    ;; Fall back to old hard-coded translations.
+    (let ((original '(G_
+                      "Subscribe to the Help mailing list to get support
+from the GNU Guix community via email.  You can post messages in English
+though we also accept other languages."))
+          (lang-code '(C_ "unique lingua code like en or zh-cn" "en")))
+      (sort
+       (delete-duplicates
+        (append
+         (delete ;delete untranslated blurbs other than "en"
+          (cons original lang-code)
+          (map-in-order
+           (lambda (lingua)
+             (begin
+               (setlocale LC_ALL (string-append lingua ".utf8"))
+               (let ((out (list (gettext (string-append
+                                          (cadr lang-code) ;msgctxt
+                                          (string #\eot) ;separates msgctxt
+                                          (caddr lang-code))) ;msgid
+                                (gettext (cadr original)))))
+                 (setlocale LC_ALL "")
+                 (if (string-index (car out) #\eot) ;if untranslated
+                     (list (caddr lang-code) (cadr original)) ;use original
+                     out)))) ;else use what has been looked up via gettext
+           %linguas)
+          (lambda (to-delete b) (and ;delete where text is equal to original
+                                 (string=? (cadar to-delete) (cadr b))
+                                 ;; but language code is different
+                                 (not (string=? (cadddr to-delete) (car b))))))
+         `(("de"
+            "Melden Sie sich bei der „Help“-Mailingliste an, um per E-Mail
 gemeinschaftlichen Rat zu GuixSD und Guix zu bekommen.  Sie können
 Nachrichten auch auf deutsch verfassen.")
-      ("en"
-       "Subscribe to the Help mailing list to get support from the
-GNU Guix community via email.  You can post messages in English though we
-also accept other languages.")
-      ("eo"
-       "Subskribu al la retmesaĝolisto \"Help\" por demandi helpon pri
+           ("eo"
+            "Subskribu al la retmesaĝolisto \"Help\" por demandi helpon pri
 GNU Guix al la grupo.  Vi povas skribi esperantlingve.")
-      ("es"
-       "Suscríbete a la lista de correo electrónico \"Help\" por pedir
+           ("es"
+            "Suscríbete a la lista de correo electrónico \"Help\" por pedir
 ayuda con Guix.  Puedes escribir mensajes en Español.")
-      ("fr"
-       "Abonnez-vous à la liste de diffusion « Help » pour obtenir l'aide
+           ("fr"
+             "Abonnez-vous à la liste de diffusion « Help » pour obtenir l'aide
 de la communauté sur GNU Guix par courrier électronique.  Vous
 pouvez envoyer des messages en français.")
-      ("hu"
-       "Iratkozzon fel a „Help“ levelezőlistára, hogy segítséget kaphasson
+           ("hu"
+            "Iratkozzon fel a „Help“ levelezőlistára, hogy segítséget kaphasson
 e-mailben a GuixSD és a GNU Guix közösségtől. Magyarul is küldhet
 üzeneteket.")
-      ("it"
-       "Iscrivetevi alla mailing list 'Help' per essere aiutati da altri
+           ("it"
+            "Iscrivetevi alla mailing list 'Help' per essere aiutati da altri
 utenti di Guix e GuixSD.  Potete scrivere sulla mailing list anche in
 italiano.")
-      ("ja"
-       "メールでGNU GuixとGuixSDのコミュニティからサポートを受けるには、
+           ("ja"
+            "メールでGNU GuixとGuixSDのコミュニティからサポートを受けるには、
 「Help」のメーリングリストに登録してください。
 メッセージ内容は日本語でも問題ございませんが、多言語でも受け付けております。")
-      ("nb"
-       "Meld deg på diskusjonslisten «Help» for å få råd og tips fra
+           ("nb"
+            "Meld deg på diskusjonslisten «Help» for å få råd og tips fra
 andre GuixSD- og GNU Guix-brukere via e-post.  Du kan legge inn
 meldinger på norsk.")
-      ("nl"
-       "Abonneer je op de discussielijst \"Help\" om hulp te vragen
+           ("nl"
+            "Abonneer je op de discussielijst \"Help\" om hulp te vragen
 van de GuixSD- en GNU Guix-gemeenschap.  Je kunt berichten sturen in
 het Nederlands.")
-      ("ru"
-       "Подпишитесь на список рассылки «Help», чтобы получить помощь от
+           ("ru"
+            "Подпишитесь на список рассылки «Help», чтобы получить помощь от
 сообщества GuixSD и GNU Guix по электронной почте.  Вы можете писать на русском
 языке.")
-      ("zh"
-       "訂閱「Help」郵件群組以電郵從GuixSD及GNU Guix社群取得支援。你可以使用
-正體、繁體中文發送訊息"))
-
+           ("zh"
+            "訂閱「Help」郵件群組以電郵從GuixSD及GNU Guix社群取得支援。你可以使用
+正體、繁體中文發送訊息")))
+        (lambda (a b) (string=? (car a) (car b))))
+       (lambda (a b) (string<? (car a) (car b)))))
     #:url "https://lists.gnu.org/mailman/listinfo/help-guix"
     #:log "https://lists.gnu.org/archive/html/help-guix")
 
    (contact
-    #:name "Bug Reporting"
+    #:name (G_ "Bug Reporting")
     #:description
-    '(p
-      "If you found a bug in Guix, check whether the bug is
-      already in the "
-      (a (@ (href "https://issues.guix.gnu.org"))
-	 "bug database")
-      ". If it is not, please "
-      (a (@ (href "mailto:bug-guix@HIDDEN")) "report it."))
+    (G_
+     `(p
+       "If you found a bug in Guix, check whether the bug is
+       already in the "
+       ,(G_ `(a (@ (href "https://issues.guix.gnu.org"))
+                "bug database"))
+       ". If it is not, please "
+       ,(G_ `(a (@ (href "mailto:bug-guix@HIDDEN")) "report it."))))
     #:url "https://lists.gnu.org/mailman/listinfo/bug-guix"
     #:log "https://issues.guix.gnu.org/")
 
    (contact
-    #:name "Development Mailing List"
+    #:name (G_ "Development Mailing List")
     #:description
-    '(p
-      "Discussion about the development of GNU Guix. "
-      (a (@ (href "https://lists.gnu.org/archive/html/bug-guix/2013-07/msg00039.html"))
-	 " Until July 2013")
-      ", the bug-Guix mailing list filled that role. ")
+    (G_
+     `(p
+       "Discussion about the development of GNU Guix. "
+       ,(G_ `(a (@ (href "https://lists.gnu.org/archive/html/bug-guix/2013-07/msg00039.html"))
+                " Until July 2013"))
+       ", the bug-Guix mailing list filled that role. "))
     #:url "https://lists.gnu.org/mailman/listinfo/guix-devel"
     #:log "https://lists.gnu.org/archive/html/guix-devel")
 
    (contact
-    #:name "Patches Mailing List"
+    #:name (G_ "Patches Mailing List")
     #:description
-    `(p
-      "Submission of patches.  Every message sent to this mailing list
-      leads to a new entry in our "
-      (a (@ (href "https://issues.guix.gnu.org"))
-	 "patch tracking tool")
-      ".  See "
-      (a (@ (href "https://debbugs.gnu.org/Advanced.html")) "this page")
-      " for more information on how to use it; see "
-      (a (@ (href ,(manual-url "Submitting-Patches.html")))
-         "the manual")
-      " for more information on how to submit a patch.  "
-      (a (@ (href "https://lists.gnu.org/archive/html/guix-devel/2017-02/msg00627.html"))
-	 "Until February 2017")
-      ", the guix-devel mailing list filled that role.")
+    (G_
+     `(p
+       "Submission of patches.  Every message sent to this mailing list
+       leads to a new entry in our "
+       ,(G_ `(a (@ (href "https://issues.guix.gnu.org"))
+                "patch tracking tool"))
+       ".  See "
+       ,(G_ `(a (@ (href "https://debbugs.gnu.org/Advanced.html")) "this page"))
+       " for more information on how to use it; see "
+       ,(G_ (manual-href "the manual" (G_ "en") (G_ "Submitting-Patches.html")))
+       " for more information on how to submit a patch.  "
+       ,(G_
+         `(a (@ (href "https://lists.gnu.org/archive/html/guix-devel/2017-02/msg00627.html"))
+             "Until February 2017"))
+       ", the guix-devel mailing list filled that role."))
     #:url "https://lists.gnu.org/mailman/listinfo/guix-patches"
     #:log "https://issues.guix.gnu.org")
 
    (contact
-    #:name "Commits Mailing List"
+    #:name (G_ "Commits Mailing List")
     #:description
-    `(p
-      "Notifications of commits made to the "
-      (a (@ (href ,(guix-url "contribute/"))) "Git repositories")
-      ".")
+    (G_
+     `(p
+       "Notifications of commits made to the "
+       ,(G_ `(a (@ (href ,(guix-url "contribute/"))) "Git repositories"))
+       "."))
     #:url "https://lists.gnu.org/mailman/listinfo/guix-commits"
     #:log "https://lists.gnu.org/archive/html/guix-commits")
 
    (contact
-    #:name "Security Mailing List"
+    #:name (G_ "Security Mailing List")
     #:description
-    `(p
-      "This is a private mailing list that anyone can post to to "
-      (a (@ (href ,(guix-url "security/"))) "report security issues")
-      " in Guix itself or in "
-      "the " (a (@ (href ,(guix-url "packages/"))) "packages")
-      " it provides.  Posting here allows Guix developers to address
-      the problem before it is widely publicized.")
+    (G_
+     `(p
+       "This is a private mailing list that anyone can post to to "
+       ,(G_ `(a (@ (href ,(guix-url "security/"))) "report security issues"))
+       " in Guix itself or in "
+       "the " ,(G_ `(a (@ (href ,(guix-url "packages/"))) "packages"))
+       " it provides.  Posting here allows Guix developers to address
+       the problem before it is widely publicized."))
     #:url "https://lists.gnu.org/mailman/listinfo/guix-security"
     #:log "")
 
    (contact
-    #:name "Sysadmin Mailing List"
+    #:name (G_ "Sysadmin Mailing List")
     #:description
-    '(p
-      "Private mailing list for the "
-      (a (@ (href "https://hydra.gnu.org/")) "build farm")
-      " system administration.")
+    (G_
+     `(p
+       "Private mailing list for the "
+       ,(G_ `(a (@ (href "https://hydra.gnu.org/")) "build farm"))
+       " system administration."))
     #:url "https://lists.gnu.org/mailman/listinfo/guix-sysadmin"
     #:log "")
 
@@ -168,23 +210,23 @@ het Nederlands.")
    ;; Non-Guix lists.
 
    (contact
-    #:name "GNU System Discuss Mailing List"
+    #:name (G_ "GNU System Discuss Mailing List")
     #:description
-    '(p "Discussion about the development of the broader GNU system.")
+    (G_ '(p "Discussion about the development of the broader GNU system."))
     #:url "https://lists.gnu.org/mailman/listinfo/gnu-system-discuss"
     #:log "https://lists.gnu.org/archive/html/gnu-system-discuss/")
 
    (contact
-    #:name "GNU/Linux-libre Mailing List"
+    #:name (G_ "GNU/Linux-libre Mailing List")
     #:description
-    '(p "Workgroup for fully free GNU/Linux distributions.")
+    (G_ '(p "Workgroup for fully free GNU/Linux distributions."))
     #:url "https://lists.nongnu.org/mailman/listinfo/gnu-linux-libre"
     #:log "https://lists.nongnu.org/archive/html/gnu-linux-libre/")
 
    (contact
-    #:name "GNU Info Mailing List"
+    #:name (G_ "GNU Info Mailing List")
     #:description
-    '(p "GNU software announcements.")
+    (G_ '(p "GNU software announcements."))
     #:url "https://lists.gnu.org/mailman/listinfo/info-gnu"
     #:log "https://lists.gnu.org/archive/html/info-gnu/")))
 
@@ -193,36 +235,36 @@ het Nederlands.")
 (define screenshots
   (list
    (screenshot
-    #:title "Graphical log-in"
+    #:title (C_ "screenshot title" "Graphical log-in")
     #:slug "slim"
     #:image (guix-url "static/media/img/gdm-sessions.png")
     #:preview (guix-url "static/media/img/gdm-sessions.mini.png")
-    #:caption "Graphical log-in screen")
+    #:caption (G_ "Graphical log-in screen"))
 
    (screenshot
-    #:title "GNOME"
+    #:title (C_ "screenshot title" "GNOME")
     #:slug "gnome"
     #:image (guix-url "static/media/img/gnome-totem-epiphany.png")
     #:preview (guix-url "static/media/img/gnome-totem-epiphany.mini.png")
-    #:caption "Control your computer with the GNOME desktop environment")
+    #:caption (G_ "Control your computer with the GNOME desktop environment"))
 
    (screenshot
-    #:title "Xfce"
+    #:title (C_ "screenshot title" "Xfce")
     #:slug "xfce"
     #:image (guix-url "static/media/img/guixsd-xfce-icecat-emacs.png")
     #:preview (guix-url "static/media/img/guixsd-xfce-icecat-emacs.mini.png")
-    #:caption "The Xfce desktop environment with GNU Emacs and IceCat")
+    #:caption (G_ "The Xfce desktop environment with GNU Emacs and IceCat"))
 
    (screenshot
-    #:title "Virtual machine"
+    #:title (C_ "screenshot title" "Virtual machine")
     #:slug "virtual-machine"
     #:image (guix-url "static/media/img/guix-system-vm.png")
     #:preview (guix-url "static/media/img/guix-system-vm.mini.png")
-    #:caption "Virtual machine started with 'guix system vm'")
+    #:caption (G_ "Virtual machine started with 'guix system vm'"))
 
    (screenshot
-    #:title "Enlightenment"
+    #:title (C_ "screenshot title" "Enlightenment")
     #:slug "enlightenment"
     #:image (guix-url "static/media/img/enlightenment-inkscape.png")
     #:preview (guix-url "static/media/img/enlightenment-inkscape.mini.png")
-    #:caption "Enlightenment, Inkscape, and Serbian text")))
+    #:caption (G_ "Enlightenment, Inkscape, and Serbian text"))))
diff --git a/website/apps/base/templates/about.scm b/website/apps/base/templates/about.scm
index a654e2f..ab81cb2 100644
--- a/website/apps/base/templates/about.scm
+++ b/website/apps/base/templates/about.scm
@@ -3,105 +3,124 @@
 ;;; copyright interest on this file.
 
 (define-module (apps base templates about)
+  #:use-module (apps base templates components)
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (about-t))
 
 
 (define (about-t)
   "Return the About page in SHTML."
   (theme
-   #:title '("About")
+   #:title (C_ "webpage title" '("About"))
    #:description
-   "Guix is an advanced distribution of the GNU operating system.
-    Guix is technology that respects the freedom of computer users.
-    You are free to run the system for any purpose, study how it
-    works, improve it, and share it with the whole world."
+   (G_ "Guix is an advanced distribution of the GNU operating system.
+   Guix is technology that respects the freedom of computer users.
+   You are free to run the system for any purpose, study how it
+   works, improve it, and share it with the whole world.")
    #:keywords
-   (list "GNU" "Linux" "Unix" "Free software" "Libre software"
-	 "Operating system" "GNU Hurd" "GNU Guix package manager")
-   #:active-menu-item "About"
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+    (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager") #\|)
+   #:active-menu-item (C_ "website menu" "About")
    #:css (list
 	  (guix-url "static/base/css/page.css"))
-   #:crumbs (list (crumb "About" "./"))
+   #:crumbs (list (crumb (C_ "website menu" "About") "./"))
    #:content
    `(main
      (section
       (@ (class "page centered-block limit-width"))
-      (h2 "About the Project")
+      ,(G_ `(h2 "About the Project"))
 
-      (p
-       "The " (em "GNU Guix") " package and system manager is a "
-       (a (@ (href ,(gnu-url "philosophy/free-sw.html")))
-	  "free software")
-       " project developed by volunteers around the world under the
-       umbrella of the " (a (@ (href ,(gnu-url))) "GNU Project") ". ")
+      ,(G_
+        `(p
+          "The " ,(G_ `(em "GNU Guix")) " package and system manager is a "
+          ,(G_ `(a (@ (href ,(gnu-url "philosophy/free-sw.html")))
+                   "free software"))
+          " project developed by volunteers around the world under the
+            umbrella of the "
+          ,(G_ `(a (@ (href ,(gnu-url))) "GNU Project")) ". "))
 
-      (p
-       "Guix System is an advanced distribution of the "
-       (a (@ (href ,(gnu-url))) "GNU operating system")
-       ".  It uses the "
-       (a (@ (href ,(gnu-url "software/linux-libre"))) "Linux-libre")
-       " kernel, and support for "
-       (a (@ (href ,(gnu-url "software/hurd"))) "the Hurd")
-       " is being worked on.  As a GNU distribution, it is committed
-       to respecting and enhancing "
-       (a (@ (href ,(gnu-url "philosophy/free-sw.html")))
-	  "the freedom of its users")
-       ".  As such, it adheres to the "
-       (a (@ (href ,(gnu-url "distros/free-system-distribution-guidelines.html")))
-	  "GNU Free System Distribution Guidelines") ".")
+      ,(G_
+        `(p
+          "Guix System is an advanced distribution of the "
+          ,(G_ `(a (@ (href ,(gnu-url))) "GNU operating system"))
+          ".  It uses the "
+          ,(G_ `(a (@ (href ,(gnu-url "software/linux-libre"))) "Linux-libre"))
+          " kernel, and support for "
+          ,(G_ `(a (@ (href ,(gnu-url "software/hurd"))) "the Hurd"))
+          " is being worked on.  As a GNU distribution, it is committed
+            to respecting and enhancing "
+          ,(G_ `(a (@ (href ,(gnu-url "philosophy/free-sw.html")))
+                   "the freedom of its users"))
+          ".  As such, it adheres to the "
+          ,(G_ `(a (@ (href ,(gnu-url "distros/free-system-distribution-guidelines.html")))
+                   "GNU Free System Distribution Guidelines")) "."))
 
-      (p
-       "GNU Guix provides "
-       (a (@ (href ,(manual-url "Features.html")))
-	  "state-of-the-art package management features")
-       " such as transactional upgrades and roll-backs, reproducible
-       build environments, unprivileged package management, and
-       per-user profiles.  It uses low-level mechanisms from the "
-       (a (@ (href "https://nixos.org/nix/")) "Nix")
-       " package manager, but packages are "
-       (a (@ (href ,(manual-url "Defining-Packages.html"))) "defined")
-       " as native "
-       (a (@ (href ,(gnu-url "software/guile"))) "Guile")
-       " modules, using extensions to the "
-       (a (@ (href "http://schemers.org")) "Scheme")
-       " language—which makes it nicely hackable.")
+      ;; TRANSLATORS: Features and Defining Packages are section names
+      ;; in the English (en) manual.
+      ,(G_
+        `(p
+          "GNU Guix provides "
+          ,(G_ (manual-href "state-of-the-art package management features"
+                            (G_ "en")
+                            (G_ "Features.html")))
+          " such as transactional upgrades and roll-backs, reproducible
+            build environments, unprivileged package management, and
+            per-user profiles.  It uses low-level mechanisms from the "
+          ,(G_ `(a (@ (href "https://nixos.org/nix/")) "Nix"))
+          " package manager, but packages are "
+          ,(G_ (manual-href "defined" (G_ "en") (G_ "Defining-Packages.html")))
+          " as native "
+          ,(G_ `(a (@ (href ,(gnu-url "software/guile"))) "Guile"))
+          " modules, using extensions to the "
+          ,(G_ `(a (@ (href "http://schemers.org")) "Scheme"))
+          " language—which makes it nicely hackable."))
 
-      (p
-       "Guix takes that a step further by additionally supporting stateless,
-       reproducible "
-       (a (@ (href ,(manual-url "Using-the-Configuration-System.html")))
-	  "operating system configurations")
-       ". This time the whole system is hackable in Scheme, from the "
-       (a (@ (href ,(manual-url "Initial-RAM-Disk.html")))
-	  "initial RAM disk")
-       " to the "
-       (a (@ (href ,(gnu-url "software/shepherd")))
-	  "initialization system")
-       ", and to the "
-       (a (@ (href ,(manual-url "Defining-Services.html")))
-	  "system services")
-       ".")
+      ;; TRANSLATORS: Using the Configuration System, Initial RAM Disk
+      ;; and Defining Services are section names in the English (en)
+      ;; manual.
+      ,(G_
+        `(p
+          "Guix takes that a step further by additionally supporting stateless,
+           reproducible "
+          ,(G_ (manual-href "operating system configurations"
+                            (G_ "en")
+                            (G_ "Using-the-Configuration-System.html")))
+          ". This time the whole system is hackable in Scheme, from the "
+          ,(G_ (manual-href "initial RAM disk"
+                            (G_ "en")
+                            (G_ "Initial-RAM-Disk.html")))
+          " to the "
+          ,(G_ `(a (@ (href ,(gnu-url "software/shepherd")))
+                   "initialization system"))
+          ", and to the "
+          ,(G_ (manual-href "system services"
+                            (G_ "en")
+                            (G_ "Defining-Services.html")))
+          "."))
 
 
-      (h3 (@ (id "mantainer")) "Maintainer")
+      ,(G_ `(h3 (@ (id "mantainer")) "Maintainer"))
 
-      (p
-       "Guix is currently maintained by Ludovic Courtès and Ricardo
-       Wurmus.  Please use the "
-       (a (@ (href ,(guix-url "contact/"))) "mailing lists")
-       " for contact. ")
+      ,(G_
+        `(p
+          "Guix is currently maintained by Ludovic Courtès and Ricardo
+          Wurmus.  Please use the "
+          ,(G_ `(a (@ (href ,(guix-url "contact/"))) "mailing lists"))
+          " for contact. "))
 
 
-      (h3 (@ (id "license")) "Licensing")
+      ,(G_ `(h3 (@ (id "license")) "Licensing"))
 
-      (p
-       "Guix is free software; you can redistribute it and/or modify
-       it under the terms of the "
-       (a (@ (rel "license") (href ,(gnu-url "licenses/gpl.html")))
-	  "GNU General Public License")
-       " as published by the Free Software Foundation; either
-       version\xa03 of the License, or (at your option) any later
-       version. ")))))
+      ,(G_
+        `(p
+          "Guix is free software; you can redistribute it and/or modify
+          it under the terms of the "
+          ,(G_ `(a (@ (rel "license") (href ,(gnu-url "licenses/gpl.html")))
+                   "GNU General Public License"))
+          " as published by the Free Software Foundation; either
+          version\xa03 of the License, or (at your option) any later
+          version. "))))))
diff --git a/website/apps/base/templates/components.scm b/website/apps/base/templates/components.scm
index d3f6af1..6b5ec21 100644
--- a/website/apps/base/templates/components.scm
+++ b/website/apps/base/templates/components.scm
@@ -1,4 +1,5 @@
 ;;; GNU Guix web site
+;;; Copyright © 2019 Florian Pelz <pelzflorian@HIDDEN>
 ;;; Initially written by sirgazil who waves all
 ;;; copyright interest on this file.
 
@@ -12,6 +13,7 @@
   #:use-module (apps aux web)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:use-module (srfi srfi-1)
   #:use-module (ice-9 match)
   #:export (breadcrumbs
@@ -23,6 +25,8 @@
 	    link-more
 	    link-subtle
 	    link-yellow
+            manual-href
+            manual-link-yellow
 	    navbar
 	    page-indicator
 	    page-selector
@@ -41,9 +45,9 @@
      (apps base types)."
   `(nav
     (@ (class "breadcrumbs"))
-    (h2 (@ (class "a11y-offset")) "Your location:")
+    ,(G_ `(h2 (@ (class "a11y-offset")) "Your location:"))
 
-    (a (@ (class "crumb") (href ,(guix-url))) "Home") (span " → ")
+    ,(G_ `(a (@ (class "crumb") (href ,(guix-url))) "Home")) (span " → ")
     ,@(separate (crumbs->shtml crumbs) '(span " → "))))
 
 
@@ -121,8 +125,9 @@
        (sxml->string*
         (match (contact-description contact)
           ((and multilingual (((? string?) (? string?)) ...))
-           (match (assoc "en" multilingual)
-             (("en" blurb) blurb)))
+           (let ((code %current-lang))
+             (match (assoc code multilingual)
+               ((code blurb) blurb))))
           (blurb
            blurb)))
        30)
@@ -145,7 +150,7 @@
     ,(if (string=? (contact-log contact) "")
 	 ""
 	 `(small
-	   " (" (a (@ (href ,(contact-log contact))) "archive") ") "))
+	   " (" ,(G_ `(a (@ (href ,(contact-log contact))) "archive")) ") "))
 
     ;; The description can be a list of language/blurb pairs.
     ,(match (contact-description contact)
@@ -216,6 +221,51 @@
   `(a (@ (class "link-yellow") (href ,url)) ,label))
 
 
+
+
+(define (manual-href label manual-lang _1 subpath _2)
+  "Return an HTML a element with its href attribute pointing to the
+manual.  It can be marked for translation as:
+
+  (G_ (manual-href \"some-text\" (G_ \"en\") (G_ \"Some-section.html\")))
+
+   LABEL (string)
+     The content of the a element.
+
+   MANUAL-LANG (string)
+     The normalized language for the Guix manual as produced by
+'doc/build.scm' in the Guix source tree, i.e. \"en\" for the English
+manual.
+
+   SUBPATH (string)
+     The same as in the manual-url procedure."
+  ;; The _ arguments are placeholders for args added by G_, cf. i18n-howto.txt.
+  `(a (@ (href ,(manual-url subpath #:language manual-lang))) label))
+
+(define* (manual-link-yellow label manual-lang _1 #:optional (subpath "") _2)
+  "Return a link-yellow component pointing to the manual.  It can be
+used like this:
+
+  (manual-link-yellow \"some-text\" (G_ \"en\") \"Package-Management.html\")
+
+   LABEL (string)
+     The label of the link-yellow.
+
+   MANUAL-LANG (string)
+     The normalized language for the Guix manual as produced by
+'doc/build.scm' in the Guix source tree, i.e. \"en\" for the English
+manual.
+
+   SUBPATH (string)
+     The same as in the manual-url procedure."
+  ;; The _ arguments are placeholders for args added by G_, cf. i18n-howto.txt.
+  (link-yellow
+   #:label label
+   #:url (manual-url subpath #:language manual-lang)))
+
+
+
+
 (define* (menu-dropdown #:key (label "Item") (active-item "") (url "#") (items '()))
   "Return an SHTML li element representing a dropdown for the navbar.
 
@@ -284,26 +334,26 @@
     (h1
      (a
       (@ (class "branding") (href ,(guix-url)))
-      (span (@ (class "a11y-offset")) "Guix")))
+      ,(C_ "website menu" `(span (@ (class "a11y-offset")) "Guix"))))
 
     ;; Menu.
     (nav (@ (class "menu"))
-     (h2 (@ (class "a11y-offset")) "Website menu:")
+         ,(G_ `(h2 (@ (class "a11y-offset")) "website menu:"))
      (ul
-      ,(menu-item #:label "Overview" #:active-item active-item #:url (guix-url))
-      ,(menu-item #:label "Download" #:active-item active-item #:url (guix-url "download/"))
-      ,(menu-item #:label "Packages" #:active-item active-item #:url (guix-url "packages/"))
-      ,(menu-item #:label "Blog" #:active-item active-item #:url (guix-url "blog/"))
-      ,(menu-item #:label "Help" #:active-item active-item #:url (guix-url "help/"))
-      ,(menu-item #:label "Donate" #:active-item active-item #:url (guix-url "donate/"))
-
-      ,(menu-dropdown #:label "About" #:active-item active-item #:url (guix-url "about/")
+      ,(C_ "website menu" (menu-item #:label "Overview" #:active-item active-item #:url (guix-url)))
+      ,(C_ "website menu" (menu-item #:label "Download" #:active-item active-item #:url (guix-url "download/")))
+      ,(C_ "website menu" (menu-item #:label "Packages" #:active-item active-item #:url (guix-url "packages/")))
+      ,(C_ "website menu" (menu-item #:label "Blog" #:active-item active-item #:url (guix-url "blog/")))
+      ,(C_ "website menu" (menu-item #:label "Help" #:active-item active-item #:url (guix-url "help/")))
+      ,(C_ "website menu" (menu-item #:label "Donate" #:active-item active-item #:url (guix-url "donate/")))
+
+      ,(menu-dropdown #:label (C_ "website menu" "About") #:active-item active-item #:url (guix-url "about/")
 	#:items
-	(list
-	 (menu-item #:label "Contact" #:active-item active-item #:url (guix-url "contact/"))
-	 (menu-item #:label "Contribute" #:active-item active-item #:url (guix-url "contribute/"))
-	 (menu-item #:label "Security" #:active-item active-item #:url (guix-url "security/"))
-	 (menu-item #:label "Graphics" #:active-item active-item #:url (guix-url "graphics/"))))))
+        (list
+         (C_ "website menu" (menu-item #:label "Contact" #:active-item active-item #:url (guix-url "contact/")))
+         (C_ "website menu" (menu-item #:label "Contribute" #:active-item active-item #:url (guix-url "contribute/")))
+         (C_ "website menu" (menu-item #:label "Security" #:active-item active-item #:url (guix-url "security/")))
+         (C_ "website menu" (menu-item #:label "Graphics" #:active-item active-item #:url (guix-url "graphics/")))))))
 
     ;; Menu button.
     (a
@@ -321,10 +371,10 @@
    TOTAL-PAGES (number)
      The total number of pages that should be displayed."
   (if (> total-pages 1)
-      `(span
-	(@ (class "page-number-indicator"))
-	" (Page " ,(number->string page-number)
-	" of " ,(number->string total-pages) ")")
+      (G_ `(span
+            (@ (class "page-number-indicator"))
+            " (Page " ,(number->string page-number)
+            " of " ,(number->string total-pages) ")"))
       ""))
 
 
@@ -345,8 +395,8 @@
     (@ (class "page-selector"))
     (h3
      (@ (class "a11y-offset"))
-     ,(string-append "Page " (number->string active-page) " of "
-		     (number->string pages) ". Go to another page: "))
+     ,(G_ (string-append "Page " (number->string active-page) " of "
+                         (number->string pages) ". Go to another page: ")))
     ,(if (> pages 1)
 	 (map
 	  (lambda (page-number)
diff --git a/website/apps/base/templates/contact.scm b/website/apps/base/templates/contact.scm
index d4ee2f2..44dbabb 100644
--- a/website/apps/base/templates/contact.scm
+++ b/website/apps/base/templates/contact.scm
@@ -7,31 +7,33 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (contact-t))
 
 
 (define (contact-t context)
   "Return the Contact page in SHTML with the data in CONTEXT."
   (theme
-   #:title '("Contact")
+   #:title (C_ "webpage title" '("Contact"))
    #:description
-   "A list of channels to communicate with GNU Guix users
-   and developers about anything you want."
+   (G_ "A list of channels to communicate with GNU Guix users
+   and developers about anything you want.")
    #:keywords
-   '("GNU" "Linux" "Unix" "Free software" "Libre software"
-     "Operating system" "GNU Hurd" "GNU Guix package manager"
-     "Community" "Mailing lists" "IRC channels" "Bug reports" "Help")
-   #:active-menu-item "About"
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+    (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|Community|Mailing lists|IRC \
+channels|Bug reports|Help") #\|)
+   #:active-menu-item (C_ "website menu" "About")
    #:css (list
 	  (guix-url "static/base/css/page.css")
           (guix-url "static/base/css/buttons.css")
 	  (guix-url "static/base/css/contact.css"))
-   #:crumbs (list (crumb "Contact" "./"))
+   #:crumbs (list (crumb (C_ "website menu" "Contact") "./"))
    #:content
    `(main
      (section
       (@ (class "page centered-block limit-width"))
-      (h2 "Contact")
+      ,(G_ `(h2 "Contact"))
 
       ,@(map
 	 contact->shtml
diff --git a/website/apps/base/templates/contribute.scm b/website/apps/base/templates/contribute.scm
index 4d68e87..ff12815 100644
--- a/website/apps/base/templates/contribute.scm
+++ b/website/apps/base/templates/contribute.scm
@@ -7,248 +7,289 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (contribute-t))
 
 
 (define (contribute-t)
   "Return the Contribute page in SHTML."
   (theme
-   #:title '("Contribute")
+   #:title (C_ "webpage title" '("Contribute"))
    #:description
-   "Check all the ways you can contribute to make GNU Guix
-   better, and join the world-wide community of volunteers."
+   (G_ "Check all the ways you can contribute to make GNU Guix
+   better, and join the world-wide community of volunteers.")
    #:keywords
-   '("GNU" "Linux" "Unix" "Free software" "Libre software"
-     "Operating system" "GNU Hurd" "GNU Guix package manager"
-     "Volunteer" "Development" "Translation" "I18N" "L10N"
-     "Artwork")
-   #:active-menu-item "About"
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+    (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|Volunteer|Development|\
+Translation|I18N|L10N|Artwork") #\|)
+   #:active-menu-item (C_ "website menu" "About")
    #:css (list
 	  (guix-url "static/base/css/page.css")
 	  (guix-url "static/base/css/item-preview.css"))
-   #:crumbs (list (crumb "Contribute" "./"))
+   #:crumbs (list (crumb (C_ "website menu" "Contribute") "./"))
    #:content
    `(main
      (section
       (@ (class "page centered-block limit-width"))
-      (h2 "Contribute")
-
-      (p
-       "GNU Guix is a large project developed
-       mostly by volunteers from all around the world. You are welcome
-       to join us in the "
-       (a (@ (href "https://lists.gnu.org/mailman/listinfo/guix-devel"))
-	  "development mailing list")
-       " or in the "
-       (a (@ (href ,(guix-url "contact/irc/"))) "#guix channel")
-       " in IRC Freenode. Tell us how would you like to help, and we
-       will do our best to guide you. ")
-
-      (p
-       "We want to provide a warm, friendly, and harassment-free environment,
-	so that anyone can contribute to the best of their abilities.  To this
-	end our project uses a “Contributor Covenant”, which was adapted from "
-       (a (@ (href "https://contributor-covenant.org/"))
-          "https://contributor-covenant.org/")
-       ".  You can find the full pledge in the "
-       (a (@ (href "//git.savannah.gnu.org/cgit/guix.git/tree/CODE-OF-CONDUCT")
-	     (class "mono"))
-          "CODE-OF-CONDUCT") " file.")
+      ,(G_ `(h2 "Contribute"))
+
+      ,(G_
+        `(p
+          "GNU Guix is a large project developed
+           mostly by volunteers from all around the world. You are welcome
+           to join us in the "
+          ,(G_
+            `(a (@ (href "https://lists.gnu.org/mailman/listinfo/guix-devel"))
+                "development mailing list"))
+          " or in the "
+          ,(G_
+            `(a (@ (href ,(guix-url "contact/irc/"))) "#guix channel"))
+          " in IRC Freenode. Tell us how would you like to help, and we
+          will do our best to guide you. "))
+
+      ,(G_
+        `(p
+          "We want to provide a warm, friendly, and harassment-free environment,
+           so that anyone can contribute to the best of their abilities.  To
+           this end our project uses a “Contributor Covenant”, which was adapted
+           from "
+          ,(G_ ((lambda (url)
+                  `(a (@ (href ,url)) url))
+                "https://contributor-covenant.org/"))
+          ".  You can find the full pledge in the "
+          ,(G_
+            `(a (@ (href "//git.savannah.gnu.org/cgit/guix.git/tree/CODE-OF-CONDUCT")
+                   (class "mono"))
+                "CODE-OF-CONDUCT"))
+          " file."))
 
       (div
        (@ (class "centered-text"))
 
        (div
 	(@ (class "summary-box"))
-	(h3 (@ (id "pms")) "Project Management")
-	(p
-	 "We use "
-	 (a (@ (href "https://savannah.gnu.org/")) "Savannah")
-	 " as the central point for development, maintenance and
-         distribution of the Guix System Distribution and GNU Guix.")
-	(p
-	 "The source files for all the components of the project,
-         including software, web site, documentation, and artwork, are
-         available in "
-	 (a (@ (href "https://savannah.gnu.org/git/?group=guix"))
-	    "Git repositories")
-	 " at Savannah. ")
+        ,(G_ `(h3 (@ (id "pms")) "Project Management"))
+        ,(G_
+          `(p
+            "We use "
+            ,(G_ `(a (@ (href "https://savannah.gnu.org/")) "Savannah"))
+            " as the central point for development, maintenance and
+            distribution of the Guix System Distribution and GNU Guix."))
+        ,(G_
+          `(p
+            "The source files for all the components of the project,
+            including software, web site, documentation, and artwork, are
+            available in "
+            ,(G_ `(a (@ (href "https://savannah.gnu.org/git/?group=guix"))
+                     "Git repositories"))
+            " at Savannah. "))
 	(p
 	 ,(link-more
-	   #:label "Access Savannah"
+           #:label (G_ "Access Savannah")
 	   #:url "https://savannah.gnu.org/projects/guix")))
 
        (div
 	(@ (class "summary-box"))
-	(h3 (@ (id "art")) "Art")
-	(p
-	 "We are always looking for artists to help us design and
-         improve user interfaces, and create multimedia material for
-         documentation, presentations, and promotional items. ")
-	(p
-	 "The artwork used in the different components of the project
-         is available in the "
-	 (a (@ (href "//git.savannah.gnu.org/cgit/guix/guix-artwork.git"))
-	    "guix-artwork")
-	 " repository. ")
+        ,(G_ `(h3 (@ (id "art")) "Art"))
+        ,(G_
+          `(p
+            "We are always looking for artists to help us design and
+            improve user interfaces, and create multimedia material for
+            documentation, presentations, and promotional items. "))
+        ,(G_
+          `(p
+            "The artwork used in the different components of the project
+            is available in the "
+            ,(G_
+              `(a (@ (href "//git.savannah.gnu.org/cgit/guix/guix-artwork.git"))
+                  "guix-artwork"))
+            " repository. "))
 	(p
 	 ,(link-more
-	   #:label "Contribute"
+           #:label (G_ "Contribute")
 	   #:url "https://lists.gnu.org/mailman/listinfo/guix-devel")))
 
 
        (div
 	(@ (class "summary-box"))
-	(h3 (@ (id "documentation")) "Documentation")
-	(p
-	 "You can read the "
-	 (a (@ (href ,(guix-url "help/"))) "project documentation")
-	 " already available in the system and in the website, and
-         help us identify any errors or omissions. Creating new
-         manuals, tutorials, and blog entries will also help users and
-         developers discover what we do. ")
-	(p
-	 "Helping improve the documentation of the "
-	 (a (@ (href ,(guix-url "packages/"))) "packaged software")
-	 " is another way to contribute. ")
+        ,(G_ `(h3 (@ (id "documentation")) "Documentation"))
+        ,(G_
+          `(p
+            "You can read the "
+            ,(G_ `(a (@ (href ,(guix-url "help/"))) "project documentation"))
+            " already available in the system and in the website, and
+            help us identify any errors or omissions. Creating new
+            manuals, tutorials, and blog entries will also help users and
+            developers discover what we do. "))
+        ,(G_
+          `(p
+            "Helping improve the documentation of the "
+            ,(G_ `(a (@ (href ,(guix-url "packages/"))) "packaged software"))
+            " is another way to contribute. "))
 	(p
 	 ,(link-more
-	   #:label "Start writing"
+           #:label (G_ "Start writing")
 	   #:url "https://lists.gnu.org/mailman/listinfo/guix-devel")))
 
 
        (div
 	(@ (class "summary-box"))
-	(h3 (@ (id "packages")) "Packages")
-	(p
-	 "Hundreds of software, documentation, and assets need to be
-         packaged to make it easier for users to install their
-         favorite tools with the Guix package manager, and be
-         productive using the system. ")
-	(p
-	 "Information on how to add packages to the distribution can
-         be found "
-	 (a (@ (href ,(manual-url "Packaging-Guidelines.html")))
-	    "in the manual")
-	 ". ")
-	(p
-	 "Check out the "
-	 (a (@ (href ,(guix-url "packages/")))
-	    "package database")
-	 " for a list of available packages, and the "
-	 (a (@ (href "//bugs.gnu.org/guix-patches"))
-	    "patch-tracking database")
-	 " for a list of pending submissions.")
+        ,(G_ `(h3 (@ (id "packages")) "Packages"))
+        ,(G_
+          `(p
+            "Hundreds of software, documentation, and assets need to be
+            packaged to make it easier for users to install their
+            favorite tools with the Guix package manager, and be
+            productive using the system. "))
+        ;; TRANSLATORS: Packaging Guidelines is a section name in the
+        ;; English (en) manual.
+        ,(G_
+          `(p
+            "Information on how to add packages to the distribution can
+            be found "
+            ,(G_
+              (manual-href
+               "in the manual"
+               (G_ "en")
+               (G_ "Packaging-Guidelines.html")))
+            ". "))
+        ,(G_
+          `(p
+            "Check out the "
+            ,(G_ `(a (@ (href ,(guix-url "packages/")))
+                     "package database"))
+            " for a list of available packages, and the "
+            ,(G_ `(a (@ (href "//bugs.gnu.org/guix-patches"))
+                     "patch-tracking database"))
+            " for a list of pending submissions."))
 	(p
 	 ,(link-more
-	   #:label "Send a new package"
+           #:label (G_ "Send a new package")
 	   #:url "https://lists.gnu.org/mailman/listinfo/guix-patches")))
 
 
        (div
 	(@ (class "summary-box"))
-	(h3 (@ (id "programming")) "Programming")
-	(p
-	 "Source code is in the "
-	 (a (@ (href "//git.savannah.gnu.org/cgit/guix.git/"))
-	    "main Git repository")
-	 ".  "
-	 "We use "
-	 (a (@ (href ,(gnu-url "software/guile"))) "GNU Guile")
-	 " as the main programming and extension language for the
-         components of the system. ")
-	(p
-	 "You will find it useful to browse the "
-	 (a (@ (href ,(gnu-url "software/guile/manual")))
-	    "Guile manual")
-	 " or other "
-	 (a (@ (href "http://www.schemers.org/Documents/#intro-texts"))
-	    "introductory material about Scheme")
-	 ". Also, make sure to read the "
-	 (a (@ (href ,(manual-url "Contributing.html")))
-	    "Contributing")
-	 " section of the manual for more details on the development
-         setup, as well as the coding and cooperation conventions used
-         in the project. ")
+        ,(G_ `(h3 (@ (id "programming")) "Programming"))
+        ,(G_
+          `(p
+            "Source code is in the "
+            ,(G_ `(a (@ (href "//git.savannah.gnu.org/cgit/guix.git/"))
+                     "main Git repository"))
+            ".  "
+            "We use "
+            ,(G_ `(a (@ (href ,(gnu-url "software/guile"))) "GNU Guile"))
+            " as the main programming and extension language for the
+            components of the system. "))
+        ;; TRANSLATORS: Contributing is a section name in the English
+        ;; (en) manual.
+        ,(G_
+          `(p
+            "You will find it useful to browse the "
+            ,(G_
+              `(a (@ (href ,(gnu-url "software/guile/manual")))
+                  "Guile manual"))
+            " or other "
+            ,(G_ `(a (@ (href "http://www.schemers.org/Documents/#intro-texts"))
+                     "introductory material about Scheme"))
+            ". Also, make sure to read the "
+            ,(G_ (manual-href "Contributing"
+                              (G_ "en")
+                              (G_ "Contributing.html")))
+            " section of the manual for more details on the development
+            setup, as well as the coding and cooperation conventions used
+            in the project. "))
 	(p
 	 ,(link-more
-	   #:label "Send a patch"
+           #:label (G_ "Send a patch")
 	   #:url "https://lists.gnu.org/mailman/listinfo/guix-patches")))
 
 
        (div
 	(@ (class "summary-box"))
-	(h3 (@ (id "sysadmin")) "System Administration")
-	(p
-	 "Our system infrastructure makes it possible for all the
-         contributors to communicate and collaborate in the project,
-         and users to be able to download and install packages. Help
-         us keep the system up and running smoothly. ")
-	(p
-	 "You can also "
-	 (a (@ (href ,(guix-url "donate/")))
-	    "donate hardware or hosting")
-	 " for our "
-	 (a (@ (href "https://hydra.gnu.org")) "build farm") ".  ")
+        ,(G_ `(h3 (@ (id "sysadmin")) "System Administration"))
+        ,(G_
+          `(p
+            "Our system infrastructure makes it possible for all the
+            contributors to communicate and collaborate in the project,
+            and users to be able to download and install packages. Help
+            us keep the system up and running smoothly. "))
+        ,(G_
+          `(p
+            "You can also "
+            ,(G_ `(a (@ (href ,(guix-url "donate/")))
+                     "donate hardware or hosting"))
+            " for our "
+            ,(G_ `(a (@ (href "https://hydra.gnu.org")) "build farm")) ".  "))
 	(p
 	 ,(link-more
-	   #:label "Contribute"
+           #:label (G_ "Contribute")
 	   #:url "https://lists.gnu.org/mailman/listinfo/guix-devel")))
 
 
        (div
 	(@ (class "summary-box"))
-	(h3 (@ (id "testing")) "Test and Bug Reports")
-	(p
-	 "Install the software and send feedback to the community
-         about your experience. Help the project by reporting bugs.")
-	(p
-	 "Before reporting a bug, please check whether the bug is
-         already "
-	 (a (@ (href "https://issues.guix.gnu.org"))
-	    "in the bug database")
-	 ". See "
-	 (a (@ (href "https://debbugs.gnu.org/Developer.html"))
-	    "the developer information page")
-	 " for more information on how to manipulate bug reports. ")
+        ,(G_ `(h3 (@ (id "testing")) "Test and Bug Reports"))
+        ,(G_
+          `(p
+            "Install the software and send feedback to the community
+            about your experience. Help the project by reporting bugs."))
+        ,(G_
+          `(p
+            "Before reporting a bug, please check whether the bug is
+            already "
+            ,(G_ `(a (@ (href "https://issues.guix.gnu.org"))
+                     "in the bug database"))
+            ". See "
+            ,(G_ `(a (@ (href "https://debbugs.gnu.org/Developer.html"))
+                     "the developer information page"))
+            " for more information on how to manipulate bug reports. "))
 	(p
 	 ,(link-more
-	   #:label "Report a bug"
+           #:label (G_ "Report a bug")
 	   #:url "https://lists.gnu.org/mailman/listinfo/bug-guix")))
 
 
        (div
 	(@ (class "summary-box"))
-	(h3 (@ (id "translation")) "Translation")
-	(p
-	 "You can help translate the "
-	 (a (@ (href "https://translationproject.org/domain/guix.html"))
-	    "software")
-	 ", the "
-	 (a (@ (href "https://translationproject.org/domain/guix-packages.html"))
-	    "package descriptions")
-         ", and the "
-            (a (@ (href "https://translationproject.org/domain/guix-manual.html"))
-	       "manual")
-	 " into your language.  See the "
-	 (a (@ (href "https://translationproject.org/html/translators.html"))
-	    "Translation Project")
-	 " for information on how you can help.")
-	(p
-	 (a (@ (href ,(guix-url "packages"))) "Software packages")
-	 " provided by the system may have their own translation
-         tools.  Visit their websites and help translate. ")
-	(p
+        ,(G_ `(h3 (@ (id "translation")) "Translation"))
+        ,(G_
+          `(p
+            "You can help translate the "
+            ,(G_
+              `(a (@ (href "https://translationproject.org/domain/guix.html"))
+                  "software"))
+            ", the "
+            ,(G_
+              `(a (@ (href "https://translationproject.org/domain/guix-packages.html"))
+                  "package descriptions"))
+            ", and the "
+            ,(G_
+              `(a (@ (href "https://translationproject.org/domain/guix-manual.html"))
+                  "manual"))
+            " into your language.  See the "
+            ,(G_
+              `(a (@ (href "https://translationproject.org/html/translators.html"))
+                  "Translation Project"))
+            " for information on how you can help."))
+        ,(G_
+          `(p
+            ,(G_ `(a (@ (href ,(guix-url "packages"))) "Software packages"))
+            " provided by the system may have their own translation
+            tools.  Visit their websites and help translate. "))
+        (p
 	 ,(link-more
-	   #:label "Start translating"
+           #:label (G_ "Start translating")
 	   #:url "https://translationproject.org/"))))
 
 
-      (h3 (@ (id "resources")) "Other resources for contributors")
-      (p
-       "Documents, supporting material of previous talks, and
-       auxiliary information useful to hackers and maintainers is
-       available at "
-       (a (@ (href "//git.savannah.gnu.org/cgit/guix/maintenance.git"))
-	  "git://git.sv.gnu.org/guix/maintenance.git")
-       ".")))))
+      ,(G_ `(h3 (@ (id "resources")) "Other resources for contributors"))
+      ,(G_
+        `(p
+          "Documents, supporting material of previous talks, and
+          auxiliary information useful to hackers and maintainers is
+          available at "
+          (a (@ (href "//git.savannah.gnu.org/cgit/guix/maintenance.git"))
+             "git://git.sv.gnu.org/guix/maintenance.git")
+          "."))))))
diff --git a/website/apps/base/templates/donate.scm b/website/apps/base/templates/donate.scm
index 8babaec..301e801 100644
--- a/website/apps/base/templates/donate.scm
+++ b/website/apps/base/templates/donate.scm
@@ -7,206 +7,267 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (donate-t))
 
 
 (define (donate-t)
   "Return the Donate page in SHTML."
   (theme
-   #:title '("Donate")
+   #:title (C_ "webpage title" '("Donate"))
    #:description
-   "We are looking for donations of hardware and optionally hosting
-   for machines (they should be usable with exclusively free
-   software)."
+   (G_ "We are looking for donations of hardware and optionally
+   hosting for machines (they should be usable with exclusively
+   free software).")
    #:keywords
-   '("GNU" "Linux" "Unix" "Free software" "Libre software"
-     "Operating system" "GNU Hurd" "GNU Guix package manager"
-     "Donations")
-   #:active-menu-item "Donate"
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+    (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|Donations") #\|)
+   #:active-menu-item (C_ "website menu" "Donate")
    #:css (list
 	  (guix-url "static/base/css/page.css"))
-   #:crumbs (list (crumb "Donate" "./"))
+   #:crumbs (list (crumb (C_ "website menu" "Donate") "./"))
    #:content
    `(main
      (section
       (@ (class "page centered-block limit-width"))
-      (h2 "Donate")
+      ,(G_ `(h2 "Donate"))
 
-      (p
-       "The "
-       (a (@ (href "https://hydra.gnu.org/jobset/gnu/master"))
-	  "build farm")
-       " of the Guix System Distribution runs on donated hardware and"
-       " hosting. As the distribution grows (see the "
-       (a (@ (href ,(guix-url "packages/"))) "package list")
-       "), so do the computing and storage needs.")
+      ,(G_
+        `(p
+          "The "
+          ,(G_
+            `(a (@ (href "https://hydra.gnu.org/jobset/gnu/master"))
+                "build farm"))
+          " of the Guix System Distribution runs on donated hardware and"
+          " hosting. As the distribution grows (see the "
+          ,(G_ `(a (@ (href ,(guix-url "packages/"))) "package list"))
+          "), so do the computing and storage needs."))
 
-      (p
-       "We have "
-       (a (@ (href "https://savannah.gnu.org/forum/forum.php?forum_id=8423"))
-	  "started a fundraising campaign")
-       " to strengthen our build farm, with "
-       (a (@ (href "https://www.fsf.org/blogs/community/fsf-announces-support-for-gnu-guix"))
-	  "support from the Free Software Foundation (FSF)")
-       ".  Please consider helping out by making a donation on this
-       FSF-hosted page:")
+      ,(G_
+        `(p
+          "We have "
+          ,(G_
+            `(a (@ (href "https://savannah.gnu.org/forum/forum.php?forum_id=8423"))
+                "started a fundraising campaign"))
+          " to strengthen our build farm, with "
+          ,(G_
+            `(a (@ (href "https://www.fsf.org/blogs/community/fsf-announces-support-for-gnu-guix"))
+                "support from the Free Software Foundation (FSF)"))
+          ".  Please consider helping out by making a donation on this
+          FSF-hosted page:"))
 
       (p
        (@ (class "centered-text"))
        ,(button-big
-	 #:label "♥ DONATE!"
+         #:label (C_ "button" "♥ DONATE!")
 	 #:url "https://my.fsf.org/civicrm/contribute/transact?reset=1&id=50"))
 
-      (h3
-       (@ (id "hardware-and-hosting"))
-       "Hardware and Hosting")
+      ,(G_
+        `(h3
+          (@ (id "hardware-and-hosting"))
+          "Hardware and Hosting"))
 
-      (p
-       "We are also looking for donations of hardware and optionally
-        hosting for the following kinds of machines (they should be
-        usable with exclusively free software): ")
+      ,(G_
+        `(p
+          "We are also looking for donations of hardware and optionally
+           hosting for the following kinds of machines (they should be
+           usable with exclusively free software): "))
 
       (ul
-       (li "x86_64 machines, with on the order of 1\xa0TiB of storage
-            and 4\xa0GiB of RAM;")
-       (li "armv7 machines (such as the Novena) to more quickly test
-            and provide binaries for the armhf-linux port;")
-       (li "mips64el machines to strengthen this port."))
+       ,(G_
+         `(li "x86_64 machines, with on the order of 1\xa0TiB of storage
+               and 4\xa0GiB of RAM;"))
+       ,(G_
+         `(li "armv7 machines (such as the Novena) to more quickly test
+               and provide binaries for the armhf-linux port;"))
+       ,(G_
+         `(li "mips64el machines to strengthen this port.")))
 
-      (p
-       "Please get in touch with us through the "
-       (a (@ (href ,(guix-url "contact/"))) "usual channels")
-       " or using the " (b "guix-hardware@HIDDEN") " private alias to
-        discuss any opportunities. ")
+      ,(G_
+        `(p
+          "Please get in touch with us through the "
+          ,(G_ `(a (@ (href ,(guix-url "contact/"))) "usual channels"))
+          " or using the " (b "guix-hardware@HIDDEN") " private alias to
+           discuss any opportunities. "))
 
 
-      (h3
-       (@ (id "hardware-donors"))
-       "Thanks to the donors!")
+      ,(G_
+        `(h3
+          (@ (id "hardware-donors"))
+          "Thanks to the donors!"))
 
-      (p
-       "The table below summarizes hardware and hosting donations that
-        make the " (a (@ (href "https://hydra.gnu.org")) "build farm")
-	" for the Guix System Distribution a reality.")
+      ,(G_
+        `(p
+          "The table below summarizes hardware and hosting donations that
+           make the " ,(G_ `(a (@ (href "https://hydra.gnu.org")) "build farm"))
+           " for the Guix System Distribution a reality."))
 
       (div
        (@ (class "table-box"))
        (table
 	(thead
-	 (tr (th "machine")
-	     (th "system")
-	     (th "donors")))
+         ,(G_ `(tr ,(G_ `(th "machine"))
+                   ,(G_ `(th "system"))
+                   ,(G_ `(th "donors")))))
 	(tbody
-	 (tr
-	  (td "hydra.gnu.org")
-	  (td "build farm front-end")
-	  (td
-	   (ul
-	    (li
-	     (a (@ (href "https://www.fsf.org/"))
-            "Free Software Foundation")))))
-     (tr
-      (td "berlin.guixsd.org")
-      (td "build farm with 25 build nodes for x86_64-linux and
-i686-linux, and dedicated storage")
-      (td
-       (ul
-        (li
-         (a (@ (href "https://www.mdc-berlin.de/"))
-            "Max Delbrück Center for Molecular Medicine")
-         " (hardware and hosting)"))))
-	 (tr
-	  (td "overdrive1.guixsd.org")
-	  (td "aarch64-linux")
-	  (td
-	   (ul
-	    (li (a (@ (href "https://www.arm.com/"))
-		   "ARM Holdings") " (hardware)"))))
-	 (tr
-	  (td "bayfront.guixsd.org")
-	  (td "new build farm front-end (WIP)")
-	  (td
-	   (ul
-	    (li
-	     (a (@ (href ,(guix-url "news/growing-our-build-farm.html")))
-		"Igalia")))))
-	 (tr
-	  (td "hydra.gnunet.org")
-	  (td "x86_64-linux, i686-linux")
-	  (td (ul (li (a (@ (href "https://gnunet.org/fsnsg"))
-			 "Free Secure Network Systems Group")
-		      " at the "
-		      (a (@ (href "https://www.tum.de/"))
-			 "Technische Universität München")))))
-	 (tr
-	  (td "chapters.gnu.org")
-	  (td "x86_64-linux, i686-linux")
-	  (td
-	   (ul
-	    (li (a (@ (href "https://es.gnu.org"))
-		   "GNU\xa0España") " (hardware)")
-	    (li (a (@ (href "https://fsffrance.org/index.en.html"))
-		   "FSF\xa0France")
-		" (hosting)"))))
-	 (tr
-	  (td "librenote")
-	  (td "mips64el-linux")
-	  (td (ul (li "Daniel Clark (hardware)")
-		  (li "Mark H Weaver (hosting)"))))
-	 (tr
-	  (td "hydra-slave0")
-	  (td "mips64el-linux")
-	  (td
-	   (ul
-	    (li (a (@ (href "https://www.fsf.org/"))
-		   "Free Software Foundation")))))
-	 (tr
-	  (td "guix.sjd.se")
-	  (td "x86_64-linux, i686-linux")
-	  (td
-	   (ul
-	    (li (a (@ (href "http://josefsson.org"))
-		   "Simon Josefsson")))))
-	 (tr
-	  (td "x15.sjd.se")
-	  (td "armhf-linux")
-	  (td
-	   (ul
-	    (li (a (@ (href "http://josefsson.org"))
-		   "Simon Josefsson")))))
-	 (tr
-	  (td "hydra-slave1")
-	  (td "armhf-linux")
-	  (td
-	   (ul
-	    (li "Steve Sprang (hardware)")
-	    ;; XXX: Eventually move to the FSF?
-	    (li "Mark H Weaver (hosting)"))))
-	 (tr
-	  (td "hydra-slave2")
-	  (td "armhf-linux")
-	  (td
-	   (ul
-	    (li (a (@ (href "http://harmoninstruments.com/"))
-		   "Harmon Instruments")
-		" (hardware)")
-	    ;; XXX: Eventually move to the FSF?
-	    (li "Mark H Weaver (hosting)"))))
-	 (tr
-	  (td "hydra-slave3")
-	  (td "armhf-linux")
-	  (td
-	   (ul
-	    (li (a (@ (href "http://www.kosagi.com/w/index.php?title=Novena_Main_Page"))
-		   "Kosagi (Sutajio Ko-Usagi Pte Ltd)")
-		" (hardware)")
-	    (li "Mark H Weaver (hosting)"))))
-	 (tr
-	  (td "redhill")
-	  (td "armhf-linux")
-	  (td
-	   (ul
-	    (li (a (@ (href "http://www.kosagi.com/w/index.php?title=Novena_Main_Page"))
-		   "Kosagi (Sutajio Ko-Usagi Pte Ltd)")
-		" (hardware)")
-	    (li "Andreas Enge (hosting)")))))))))))
+         ,(G_ `(tr
+                ,(G_ `(td "hydra.gnu.org"))
+                ,(G_ `(td "build farm front-end"))
+                ,(G_ ((lambda (content)
+                        `(td
+                          (ul
+                           (li
+                            (a (@ (href "https://www.fsf.org/"))
+                               ,content)))))
+                      "Free Software Foundation"))))
+         ,(G_ `(tr
+                ,(G_ `(td "berlin.guixsd.org"))
+                ,(G_ `(td "build farm with 25 build nodes for x86_64-linux and
+i686-linux, and dedicated storage"))
+                ,(G_ ((lambda content
+                        `(td
+                          (ul
+                           (li
+                            ,@content))))
+                      (G_ `(a (@ (href "https://www.mdc-berlin.de/"))
+                              "Max Delbrück Center for Molecular Medicine"))
+                      " (hardware and hosting)"))))
+         ,(G_ `(tr
+                ,(G_ `(td "overdrive1.guixsd.org"))
+                ,(G_ `(td "aarch64-linux"))
+                ,(G_ ((lambda content
+                        `(td
+                          (ul
+                           (li
+                            ,@content))))
+                      (G_ `(a (@ (href "https://www.arm.com/"))
+                              "ARM Holdings") " (hardware)")))))
+         ,(G_
+           `(tr
+             ,(G_ `(td "bayfront.guixsd.org"))
+             ,(G_ `(td "new build farm front-end (WIP)"))
+             ,(G_ ((lambda (content)
+                        `(td
+                          (ul
+                           (li
+                            (a
+                             (@ (href ,(guix-url "news/growing-our-build-farm.html")))
+                             ,content)))))
+                   "Igalia"))))
+         ,(G_ `(tr
+                ,(G_ `(td "hydra.gnunet.org"))
+                ,(G_ `(td "x86_64-linux, i686-linux"))
+                ,(G_ ((lambda content
+                        `(td
+                          (ul
+                           (li
+                            ,@content))))
+                      (G_ `(a (@ (href "https://gnunet.org/fsnsg"))
+                              "Free Secure Network Systems Group"))
+                      " at the "
+                      (G_ `(a (@ (href "https://www.tum.de/"))
+                              "Technische Universität München"))))))
+         ,(G_ `(tr
+                ,(G_ `(td "chapters.gnu.org"))
+                ,(G_ `(td "x86_64-linux, i686-linux"))
+                ,(G_ ((lambda content
+                        `(td
+                          (ul
+                           ,@content)))
+                      (G_ `(li
+                            ,(G_ `(a (@ (href "https://es.gnu.org"))
+                                     "GNU\xa0España"))
+                            " (hardware)"))
+                      (G_ `(li
+                            ,(G_ `(a (@ (href "https://fsffrance.org/index.en.html"))
+                                     "FSF\xa0France"))
+                            " (hosting)"))))))
+         ,(G_ `(tr
+                ,(G_ `(td "librenote"))
+                ,(G_ `(td "mips64el-linux"))
+                ,(G_ ((lambda content
+                        `(td
+                          (ul
+                           ,@content)))
+                      (G_ `(li "Daniel Clark (hardware)"))
+                      (G_ `(li "Mark H Weaver (hosting)"))))))
+         ,(G_ `(tr
+                ,(G_ `(td "hydra-slave0"))
+                ,(G_ `(td "mips64el-linux"))
+                ,(G_ ((lambda (content)
+                        `(td
+                          (ul
+                           (li
+                            (a (@ (href "https://www.fsf.org/"))
+                               ,content)))))
+                      "Free Software Foundation"))))
+         ,(G_ `(tr
+                ,(G_ `(td "guix.sjd.se"))
+                ,(G_ `(td "x86_64-linux, i686-linux"))
+                ,(G_ ((lambda (content)
+                        `(td
+                          (ul
+                           (li
+                            (a (@ (href "http://josefsson.org"))
+                               ,content)))))
+                      "Simon Josefsson"))))
+         ,(G_ `(tr
+                ,(G_ `(td "x15.sjd.se"))
+                ,(G_ `(td "armhf-linux"))
+                ,(G_ ((lambda (content)
+                        `(td
+                          (ul
+                           (li
+                            (a (@ (href "http://josefsson.org"))
+                               ,content)))))
+                      "Simon Josefsson"))))
+         ,(G_ `(tr
+                ,(G_ `(td "hydra-slave1"))
+                ,(G_ `(td "armhf-linux"))
+                ,(G_ ((lambda content
+                        `(td
+                          (ul
+                           ,@content)))
+                      (G_ `(li "Steve Sprang (hardware)"))
+                      ;; XXX: Eventually move to the FSF?
+                      (G_ `(li "Mark H Weaver (hosting)"))))))
+         ,(G_ `(tr
+                ,(G_ `(td "hydra-slave2"))
+                ,(G_ `(td "armhf-linux"))
+                ,(G_ ((lambda content
+                        `(td
+                          (ul
+                           ,@content)))
+                      (G_ `(li
+                            ,(G_ `(a (@ (href "http://harmoninstruments.com/"))
+                                     "Harmon Instruments"))
+                            " (hardware)"))
+                      ;; XXX: Eventually move to the FSF?
+                      (G_ `(li "Mark H Weaver (hosting)"))))))
+         ,(G_
+           `(tr
+             ,(G_ `(td "hydra-slave3"))
+             ,(G_ `(td "armhf-linux"))
+             ,(G_ ((lambda content
+                     `(td
+                       (ul
+                        ,@content)))
+                   (G_ `(li
+                    ,(G_ `(a (@ (href "http://www.kosagi.com/w/index.php?title=Novena_Main_Page"))
+                             "Kosagi (Sutajio Ko-Usagi Pte Ltd)"))
+                    " (hardware)"))
+                   (G_ `(li "Mark H Weaver (hosting)"))))))
+         ,(G_
+           `(tr
+             ,(G_ `(td "redhill"))
+             ,(G_ `(td "armhf-linux"))
+             ,(G_ ((lambda content
+                     `(td
+                       (ul
+                        ,@content)))
+                   (G_ `(li
+                    ,(G_ `(a (@ (href "http://www.kosagi.com/w/index.php?title=Novena_Main_Page"))
+                             "Kosagi (Sutajio Ko-Usagi Pte Ltd)"))
+                    " (hardware)"))
+                   (G_ `(li "Andreas Enge (hosting)")))))))))))))
diff --git a/website/apps/base/templates/graphics.scm b/website/apps/base/templates/graphics.scm
index 80b6532..6c1d70f 100644
--- a/website/apps/base/templates/graphics.scm
+++ b/website/apps/base/templates/graphics.scm
@@ -6,66 +6,73 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (graphics-t))
 
 
 (define (graphics-t)
   "Return the Graphics page in SHTML."
   (theme
-   #:title '("Graphics")
+   #:title (C_ "webpage title" '("Graphics"))
    #:description
-   "Information about images used for the graphical identity of
-   GNU Guix and Guix System (formerly “GuixSD”)."
+   (G_ "Information about images used for the graphical identity
+   of GNU Guix and Guix System (formerly “GuixSD”).")
    #:keywords
-   '("GNU" "Linux" "Unix" "Free software" "Libre software"
-     "Operating system" "GNU Hurd" "GNU Guix package manager"
-     "Branding" "Logo")
-   #:active-menu-item "About"
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+    (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|Donations|Branding|Logo") #\|)
+   #:active-menu-item (C_ "website menu" "About")
    #:css (list
 	  (guix-url "static/base/css/page.css"))
-   #:crumbs (list (crumb "Graphics" "./"))
+   #:crumbs (list (crumb (C_ "website menu" "Graphics") "./"))
    #:content
    `(main
      (section
       (@ (class "page centered-block limit-width"))
-      (h2 "Graphics")
+      ,(G_ `(h2 "Graphics"))
 
-      (p
-       "For questions regarding the graphics listed in this page,
-       please contact "
-       (a (@ (href "https://lists.gnu.org/mailman/listinfo/help-guix"))
-	  ("help-guix@HIDDEN"))
-       ".")
+      ,(G_
+        `(p
+          "For questions regarding the graphics listed in this page,
+          please contact "
+          ,(G_ `(a (@ (href "https://lists.gnu.org/mailman/listinfo/help-guix"))
+                   "help-guix@HIDDEN"))
+          "."))
       (p
        (@ (class "centered-text"))
        (img (@ (src ,(guix-url "static/base/img/Guix.png"))
-	       (alt "GNU Guix logotype"))))
-      (p
-       "The standalone Guix, formerly known as the “Guix System
-       Distribution” or GuixSD, had its own logo, which is now
-       deprecated.")
+               ,(G_ `(alt "GNU Guix logotype")))))
+      ,(G_
+        `(p
+          "The standalone Guix, formerly known as the “Guix System
+          Distribution” or GuixSD, had its own logo, which is now
+          deprecated."))
 
-      (p
-       "The GNU Guix and GuixSD
-       logotypes were designed by Luis Felipe López Acevedo
-       (a.k.a. sirgazil).  They are available under the following
-       terms:")
+      ,(G_
+        `(p
+          "The GNU Guix and GuixSD
+          logotypes were designed by Luis Felipe López Acevedo
+          (a.k.a. sirgazil).  They are available under the following
+          terms:"))
       (blockquote
        (p "Copyright © 2015 Luis Felipe López Acevedo")
        (p
-	"Permission is granted to copy, distribute and/or modify this
+        "Permission is granted to copy, distribute and/or modify this
         work under the terms of the "
-	(a (@ (href "https://creativecommons.org/licenses/by-sa/4.0/"))
-	   "Creative Commons Attribution-ShareAlike 4.0 International License")
-	"."))
-      (p
-       "The source files (SVG) for these logotypes, their variants, and
-       other artwork used in the different components of the GNU Guix
-       project are available in the "
-       (a (@ (href "//git.savannah.gnu.org/cgit/guix/guix-artwork.git/tree/logo"))
-	  "guix-artwork")
-       " repository, including the previous GNU Guix logotype designed
-       by Nikita Karetnikov in 2013 and "
-       (a (@ (href "https://debbugs.gnu.org/cgi/bugreport.cgi?bug=25205"))
-	  "superseded")
-       " by the golden GNU in 2016.")))))
+        `(a (@ (href "https://creativecommons.org/licenses/by-sa/4.0/"))
+            "Creative Commons Attribution-ShareAlike 4.0 International License")
+        "."))
+      ,(G_
+        `(p
+          "The source files (SVG) for these logotypes, their variants, and
+          other artwork used in the different components of the GNU Guix
+          project are available in the "
+          ,(G_
+            `(a (@ (href "//git.savannah.gnu.org/cgit/guix/guix-artwork.git/tree/logo"))
+                "guix-artwork"))
+          " repository, including the previous GNU Guix logotype designed
+          by Nikita Karetnikov in 2013 and "
+          ,(G_
+            `(a (@ (href "https://debbugs.gnu.org/cgi/bugreport.cgi?bug=25205"))
+                "superseded"))
+          " by the golden GNU in 2016."))))))
diff --git a/website/apps/base/templates/help.scm b/website/apps/base/templates/help.scm
index 8117957..08cecb2 100644
--- a/website/apps/base/templates/help.scm
+++ b/website/apps/base/templates/help.scm
@@ -7,31 +7,32 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (help-t))
 
 
 (define (help-t)
   "Return the Help page in SHTML."
   (theme
-   #:title '("Help")
+   #:title (C_ "webpage title" '("Help"))
    #:description
-   "A list of resources about how to use GNU Guix, plus
+   (G_ "A list of resources about how to use GNU Guix, plus
    information about getting help from the community of users and
-   developers."
+   developers.")
    #:keywords
-   '("GNU" "Linux" "Unix" "Free software" "Libre software"
-     "Operating system" "GNU Hurd" "GNU Guix package manager"
-     "Help resources")
-   #:active-menu-item "Help"
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+    (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|Help resources") #\|)
+   #:active-menu-item (C_ "website menu" "Help")
    #:css (list
 	  (guix-url "static/base/css/page.css")
 	  (guix-url "static/base/css/item-preview.css"))
-   #:crumbs (list (crumb "Help" "./"))
+   #:crumbs (list (crumb (C_ "website menu" "Help") "./"))
    #:content
    `(main
      (section
       (@ (class "page"))
-      (h2 "Help")
+      ,(G_ `(h2 "Help"))
 
       (div
        (@ (class "centered-text"))
@@ -42,13 +43,14 @@
 	(img
 	 (@ (src ,(guix-url "static/base/img/manual-icon.png"))
 	    (alt "")))
-	(h3 "GNU Guix Manual")
-	(p
-	 "Documentation for GNU Guix is available
-         online.  You may also find more information about Guix by running "
-	 (code "info guix") ".")
-	(p
-         ,(link-more #:label "Read Guix manual"
+        ,(G_ `(h3 "GNU Guix Manual"))
+        ,(G_
+          `(p
+            "Documentation for GNU Guix is available
+            online.  You may also find more information about Guix by running "
+            ,(G_ `(code "info guix")) "."))
+        (p
+         ,(link-more #:label (G_ "Read Guix manual")
                      #:url (guix-url "manual/en")))
         (p
          (a (@ (href ,(guix-url "manual/de"))) "Deutsch") " | "
@@ -59,7 +61,7 @@
          (a (@ (href ,(guix-url "manual/zh-cn"))) "简体中文"))
 
         ,(link-more
-	  #:label "Get Guix reference card"
+          #:label (G_ "Get Guix reference card")
 	  #:url (guix-url "guix-refcard.pdf")))
 
 
@@ -67,15 +69,16 @@
 	(@ (class "summary-box"))
 	(img (@ (src ,(guix-url "static/base/img/library-icon.png"))
 		(alt "")))
-	(h3 "GNU Manuals")
-	(p
-	 "Guix is a distribution of the "
-	 (a (@ (href ,(gnu-url))) "GNU operating system")
-	 ".  Documentation for GNU packages is
-         available online in various formats. ")
+        ,(G_ `(h3 "GNU Manuals"))
+        ,(G_
+          `(p
+            "Guix is a distribution of the "
+            ,(G_ `(a (@ (href ,(gnu-url))) "GNU operating system"))
+            ".  Documentation for GNU packages is
+            available online in various formats. "))
 	(p
 	 ,(link-more
-	   #:label "Browse GNU manuals"
+           #:label (G_ "Browse GNU manuals")
 	   #:url (gnu-url "manual"))))
 
 
@@ -83,18 +86,20 @@
 	(@ (class "summary-box"))
 	(img (@ (src ,(guix-url "static/base/img/chat-icon.png"))
 		(alt "")))
-	(h3 "IRC Chat")
-	(p
-	 "For real-time support from the community, you can connect
-         to the " (code "#guix") " channel on irc.freenode.net. There
-         you can get help about anything related to GNU Guix.")
-	(p
-	 "The " (code "#guix") " channel is logged. Previous
-         conversations can be browsed online. See the "
-	 (a (@ (href ,guix-irc-log-url)) "channel logs") ". ")
+        ,(G_ `(h3 "IRC Chat"))
+        ,(G_
+          `(p
+            "For real-time support from the community, you can connect
+            to the " (code "#guix") " channel on irc.freenode.net. There
+            you can get help about anything related to GNU Guix."))
+        ,(G_
+          `(p
+            "The " (code "#guix") " channel is logged. Previous
+            conversations can be browsed online. See the "
+            ,(G_ `(a (@ (href ,guix-irc-log-url)) "channel logs")) ". "))
 	(p
 	 ,(link-more
-	   #:label "Connect"
+           #:label (G_ "Connect")
 	   #:url (guix-url "contact/irc/"))))
 
 
@@ -102,13 +107,14 @@
 	(@ (class "summary-box"))
 	(img (@ (src ,(guix-url "static/base/img/email-icon.png"))
 		(alt "")))
-	(h3 "Mailing lists")
-	(p
-	 "Email support from the community is also available through
-         several mailing list. The messages sent to the lists are
-         public and archived online.")
+        ,(G_ `(h3 "Mailing lists"))
+        ,(G_
+          `(p
+            "Email support from the community is also available through
+            several mailing list. The messages sent to the lists are
+            public and archived online."))
 
 	(p
 	 ,(link-more
-	   #:label "See all lists"
+           #:label (G_ "See all lists")
 	   #:url (guix-url "contact/")))))))))
diff --git a/website/apps/base/templates/home.scm b/website/apps/base/templates/home.scm
index 5cb3bf5..f0f889e 100644
--- a/website/apps/base/templates/home.scm
+++ b/website/apps/base/templates/home.scm
@@ -8,24 +8,27 @@
   #:use-module (apps base types)
   #:use-module (apps base utils)
   #:use-module (apps blog templates components)
+  #:use-module (apps i18n)
   #:export (home-t))
 
 
 (define (home-t context)
   "Return the Home page in SHTML using the data in CONTEXT."
   (theme
-   #:title '("GNU's advanced distro and transactional package manager")
+   #:title (C_ "webpage title"
+               '("GNU's advanced distro and transactional package manager"))
    #:description
-   "Guix is an advanced distribution of the GNU operating system.
+   (G_ "Guix is an advanced distribution of the GNU operating system.
    Guix is technology that respects the freedom of computer users.
-   You are free to run the system for any purpose, study how it works,
-   improve it, and share it with the whole world."
+   You are free to run the system for any purpose, study how it
+   works, improve it, and share it with the whole world.")
    #:keywords
-   '("GNU" "Linux" "Unix" "Free software" "Libre software"
-     "Operating system" "GNU Hurd" "GNU Guix package manager"
-     "GNU Guile" "Guile Scheme" "Transactional upgrades"
-     "Functional package management" "Reproducibility")
-   #:active-menu-item "Overview"
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+    (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile \
+Scheme|Transactional upgrades|Functional package \
+management|Reproducibility") #\|)
+   #:active-menu-item (C_ "website menu" "Overview")
    #:css (list
 	  (guix-url "static/base/css/item-preview.css")
 	  (guix-url "static/base/css/index.css"))
@@ -34,83 +37,94 @@
      ;; Featured content.
      (section
       (@ (class "featured-content"))
-      (h2 (@ (class "a11y-offset")) "Summary")
+      ,(G_ `(h2 (@ (class "a11y-offset")) "Summary"))
       (ul
-       (li
-	(b "Liberating.")
-	" Guix is an advanced
-        distribution of the "
-	,(link-yellow
-	  #:label "GNU operating system"
-	  #:url (gnu-url "gnu/about-gnu.html"))
-	" developed by the "
-	,(link-yellow
-	  #:label "GNU Project"
-	  #:url (gnu-url))
-	"—which respects the "
-	,(link-yellow
-	  #:label "freedom of computer users"
-	  #:url (gnu-url "distros/free-system-distribution-guidelines.html"))
-	". ")
-
-       (li
-	(b "Dependable.")
-        " Guix "
-	,(link-yellow
-	  #:label "supports"
-	  #:url (manual-url "Package-Management.html"))
-        " transactional upgrades and roll-backs, unprivileged
-        package management, "
-	,(link-yellow
-	  #:label "and more"
-	  #:url (manual-url "Features.html"))
-	".  When used as a standalone distribution, Guix supports "
-        ,(link-yellow
-          #:label "declarative system configuration"
-          #:url (manual-url "Using-the-Configuration-System.html"))
-        " for transparent and reproducible operating systems.")
-
-       (li
-	(b "Hackable.")
-	" It provides "
-	,(link-yellow
-	  #:label "Guile Scheme"
-	  #:url (gnu-url "software/guile/"))
-	" APIs, including high-level embedded domain-specific
-        languages (EDSLs) to "
-	,(link-yellow
-	  #:label "define packages"
-	  #:url (manual-url "Defining-Packages.html"))
-	" and "
-	,(link-yellow
-	  #:label "whole-system configurations"
-	  #:url (manual-url "System-Configuration.html"))
-	"."))
+       ,(G_
+         `(li
+           ,(G_ `(b "Liberating."))
+           " Guix is an advanced distribution of the "
+           ,(G_ (link-yellow
+                 #:label "GNU operating system"
+                 #:url (gnu-url "gnu/about-gnu.html")))
+           " developed by the "
+           ,(G_ (link-yellow
+                 #:label "GNU Project"
+                 #:url (gnu-url)))
+           "—which respects the "
+           ,(G_ (link-yellow
+                 #:label "freedom of computer users"
+                 #:url (gnu-url "distros/free-system-distribution-\
+guidelines.html")))
+           ". "))
+
+       ;; TRANSLATORS: Package Management, Features and Using the
+       ;; Configuration System are section names in the English (en)
+       ;; manual.
+       ,(G_
+         `(li
+           ,(G_ `(b "Dependable."))
+           " Guix "
+           ,(G_ (manual-link-yellow "supports"
+                                    (G_ "en")
+                                    (G_ "Package-Management.html")))
+           " transactional upgrades and roll-backs, unprivileged \
+package management, "
+           ,(G_ (manual-link-yellow "and more"
+                                    (G_ "en")
+                                    (G_ "Features.html")))
+           ".  When used as a standalone distribution, Guix supports "
+           ,(G_ (manual-link-yellow "declarative system configuration"
+                                    (G_ "en")
+                                    (G_ "Using-the-Configuration-System.html")))
+           " for transparent and reproducible operating systems."))
+
+       ;; TRANSLATORS: Defining Packages and System Configuration are
+       ;; section names in the English (en) manual.
+       ,(G_
+         `(li
+           ,(G_ `(b "Hackable."))
+           " It provides "
+           ,(G_ (link-yellow
+                 #:label "Guile Scheme"
+                 #:url (gnu-url "software/guile/")))
+           " APIs, including high-level embedded domain-specific \
+languages (EDSLs) to "
+           ,(G_ (manual-link-yellow "define packages"
+                                    (G_ "en")
+                                    (G_ "Defining-Packages.html")))
+           " and "
+           ,(G_ (manual-link-yellow "whole-system configurations"
+                                    (G_ "en")
+                                    (G_ "System-Configuration.html")))
+           ".")))
 
       (div
        (@ (class "action-box centered-text"))
        ,(button-big
-	 #:label (string-append "DOWNLOAD v" (latest-guix-version))
+         #:label (apply string-append
+                        (C_ "button" `("DOWNLOAD v" ,(latest-guix-version) "")))
 	 #:url (guix-url "download/")
 	 #:light #true)
        " " ; A space for readability in non-CSS browsers.
        ,(button-big
-	 #:label "CONTRIBUTE"
+         #:label (C_ "button" "CONTRIBUTE")
 	 #:url (guix-url "contribute/")
 	 #:light #true)))
 
      ;; Discover Guix.
      (section
       (@ (class "discovery-box"))
-      (h2 "Discover Guix")
-
-      (p
-       (@ (class "limit-width centered-block"))
-       "Guix comes with thousands of packages which include
-       applications, system tools, documentation, fonts, and other
-       digital goods readily available for installing with the "
-       ,(link-yellow #:label "GNU Guix" #:url "#guix-in-other-distros")
-       " package manager.")
+      ,(G_ `(h2 "Discover Guix"))
+
+      ,(G_
+        `(p
+          (@ (class "limit-width centered-block"))
+          "Guix comes with thousands of packages which include \
+applications, system tools, documentation, fonts, and other digital \
+goods readily available for installing with the "
+          ,(G_ (link-yellow #:label "GNU Guix"
+                            #:url (identity "#guix-in-other-distros")))
+          " package manager."))
 
       (div
        (@ (class "screenshots-box"))
@@ -119,55 +133,57 @@
       (div
        (@ (class "action-box centered-text"))
        ,(button-big
-	 #:label "ALL PACKAGES"
+         #:label (C_ "button" "ALL PACKAGES")
 	 #:url (guix-url "packages/")
 	 #:light #true))
 
       ,(horizontal-separator #:light #true)
 
       ;; Guix in different fields.
-      (h3 "GNU Guix in your field")
+      ,(G_ `(h3 "GNU Guix in your field"))
 
-      (p
-       (@ (class "limit-width centered-block"))
-       "Read some stories about how people are using GNU Guix in their daily
-       lives.")
+      ,(G_
+        `(p
+          (@ (class "limit-width centered-block"))
+          "Read some stories about how people are using GNU Guix in
+their daily lives."))
 
       (div
        (@ (class "fields-box"))
 
        " " ; A space for readability in non-CSS browsers (same below).
        ,(button-big
-	 #:label "SOFTWARE DEVELOPMENT"
-	 #:url (guix-url "blog/tags/software-development/")
-	 #:light #true)
+         #:label (C_ "button" "SOFTWARE DEVELOPMENT")
+         #:url (guix-url "blog/tags/software-development/")
+         #:light #true)
        " "
        ,(button-big
-	 #:label "BIOINFORMATICS"
-	 #:url (guix-url "blog/tags/bioinformatics/")
-	 #:light #true)
+         #:label (C_ "button" "BIOINFORMATICS")
+         #:url (guix-url "blog/tags/bioinformatics/")
+         #:light #true)
        " "
        ,(button-big
-	 #:label "HIGH PERFORMANCE COMPUTING"
-	 #:url (guix-url "blog/tags/high-performance-computing/")
-	 #:light #true)
+         #:label (C_ "button" "HIGH PERFORMANCE COMPUTING")
+         #:url (guix-url "blog/tags/high-performance-computing/")
+         #:light #true)
        " "
        ,(button-big
-	 #:label "RESEARCH"
-	 #:url (guix-url "blog/tags/research/")
-	 #:light #true)
+         #:label (C_ "button" "RESEARCH")
+         #:url (guix-url "blog/tags/research/")
+         #:light #true)
        " "
        ,(button-big
-	 #:label "ALL FIELDS..."
-	 #:url (guix-url "blog/")
-	 #:light #true))
+         #:label (C_ "button" "ALL FIELDS...")
+         #:url (guix-url "blog/")
+         #:light #true))
 
       ,(horizontal-separator #:light #true)
 
       ;; Using Guix in other distros.
-      (h3
-       (@ (id "guix-in-other-distros"))
-       "GNU Guix in other GNU/Linux distros")
+      ,(G_
+        `(h3
+          (@ (id "guix-in-other-distros"))
+          "GNU Guix in other GNU/Linux distros"))
 
       (div
        (@ (class "info-box"))
@@ -176,54 +192,55 @@
 	   (src "https://audio-video.gnu.org/video/misc/2016-07__GNU_Guix_Demo_2.webm")
 	   (poster ,(guix-url "static/media/img/guix-demo.png"))
 	   (controls "controls"))
-	(p
-	 "Video: "
-	 ,(link-yellow
-	   #:label "Demo of Guix in another GNU/Linux distribution"
-	   #:url "https://audio-video.gnu.org/video/misc/2016-07__GNU_Guix_Demo_2.webm")
-	 " (1 minute, 30 seconds).")))
+        ,(G_
+          `(p
+            "Video: "
+            ,(G_ (link-yellow
+                  #:label "Demo of Guix in another GNU/Linux distribution"
+                  #:url "https://audio-video.gnu.org/video/misc/\
+2016-07__GNU_Guix_Demo_2.webm"))
+            " (1 minute, 30 seconds)."))))
 
       (div
        (@ (class "info-box justify-left"))
-       (p
-	"If you don't use GNU Guix as a standalone GNU/Linux distribution,
-        you still can use it as a
-	package manager on top of any GNU/Linux distribution. This
-        way, you can benefit from all its conveniences.")
+       ,(G_ `(p
+              "If you don't use GNU Guix as a standalone GNU/Linux \
+distribution, you still can use it as a package manager on top of any \
+GNU/Linux distribution. This way, you can benefit from all its conveniences."))
 
-       (p
-	"Guix won't interfere with the package manager that comes
-        with your distribution. They can live together."))
+       ,(G_ `(p
+              "Guix won't interfere with the package manager that comes \
+with your distribution. They can live together.")))
 
       (div
        (@ (class "action-box centered-text"))
        ,(button-big
-	 #:label "TRY IT OUT!"
+         #:label (C_ "button" "TRY IT OUT!")
 	 #:url (guix-url "download/")
 	 #:light #true)))
 
      ;; Latest Blog posts.
      (section
       (@ (class "centered-text"))
-      (h2 "Blog")
+      ,(G_ `(h2 "Blog"))
 
       ,@(map post-preview (context-datum context "posts"))
 
       (div
        (@ (class "action-box centered-text"))
        ,(button-big
-	 #:label "ALL POSTS"
+         #:label (C_ "button" "ALL POSTS")
 	 #:url (guix-url "blog/"))))
 
      ;; Contact info.
      (section
       (@ (class "contact-box centered-text"))
-      (h2 "Contact")
+      ,(G_ `(h2 "Contact"))
 
       ,@(map contact-preview (context-datum context "contact-media"))
 
       (div
        (@ (class "action-box centered-text"))
        ,(button-big
-	 #:label "ALL CONTACT MEDIA"
+         #:label (C_ "button" "ALL CONTACT MEDIA")
 	 #:url (guix-url "contact/")))))))
diff --git a/website/apps/base/templates/irc.scm b/website/apps/base/templates/irc.scm
index c21f77e..5674d1f 100644
--- a/website/apps/base/templates/irc.scm
+++ b/website/apps/base/templates/irc.scm
@@ -6,45 +6,49 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (irc-t))
 
 
 (define (irc-t)
   "Return the Kiwi IRC widget page in SHTML."
   (theme
-   #:title '("IRC" "Contact")
+   #:title
+   (list (C_ "webpage title" "IRC")
+         (C_ "webpage title" "Contact"))
    #:description
-   "Internet relay chat."
+   (G_ "Internet relay chat.")
    #:keywords
-   '("GNU" "Linux" "Unix" "Free software" "Libre software"
-     "Operating system" "GNU Hurd" "GNU Guix package manager"
-     "IRC" "chat")
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+    (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|IRC|chat") #\|)
    #:active-menu-item "About"
    #:css (list
 	  (guix-url "static/base/css/page.css")
 	  (guix-url "static/base/css/irc.css"))
-   #:crumbs (list (crumb "Contact" (guix-url "contact/"))
-		  (crumb "IRC" "./"))
+   #:crumbs (list (crumb (C_ "webpage title" "Contact") (guix-url "contact/"))
+		  (crumb (C_ "webpage title" "IRC") "./"))
    #:content
    `(main
      (section
       (@ (class "page"))
-      (h2 "IRC")
+      ,(G_ `(h2 "IRC"))
 
-      (p
-       (@ (class "centered-block limit-width"))
-       "Join the " (code "#guix") " channel on the "
-       (a (@ (href "https://en.wikipedia.org/wiki/Freenode"))
-	"Freenode IRC network")
-       " to chat with the GNU Guix community or to get help
-       in real-time. You can use the chat widget below, or just use
-       the "
-       (a (@ (href "https://en.wikipedia.org/wiki/Comparison_of_Internet_Relay_Chat_clients"))
-	  "IRC client")
-       " of your preference. Note that the conversations that happen
-       on the " (code "#guix") " channel are logged ("
-       (a (@ (href ,guix-irc-log-url)) "browse the log")
-       ").")
+      ,(G_
+        `(p
+          (@ (class "centered-block limit-width"))
+          "Join the " (code "#guix") " channel on the "
+          ,(G_ `(a (@ (href "https://en.wikipedia.org/wiki/Freenode"))
+                   "Freenode IRC network"))
+          " to chat with the GNU Guix community or to get help
+          in real-time. You can use the chat widget below, or just use
+          the "
+          ,(G_ `(a (@ (href "https://en.wikipedia.org/wiki/Comparison_of_Internet_Relay_Chat_clients"))
+                   "IRC client"))
+          " of your preference. Note that the conversations that happen
+          on the " (code "#guix") " channel are logged ("
+          ,(G_ `(a (@ (href ,guix-irc-log-url)) "browse the log"))
+          ")."))
 
       (iframe
        (@ (class "chat-widget centered-block")
diff --git a/website/apps/base/templates/menu.scm b/website/apps/base/templates/menu.scm
index b87387f..ce6b54e 100644
--- a/website/apps/base/templates/menu.scm
+++ b/website/apps/base/templates/menu.scm
@@ -6,17 +6,20 @@
   #:use-module (apps base templates components)
   #:use-module (apps base templates theme)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (menu-t))
 
 
 (define (menu-t)
   "Return the Menu page in SHTML."
   (theme
-   #:title '("Menu")
-   #:description "Website menu."
-   #:keywords '("GNU" "Linux" "Unix" "Free software" "Libre software"
-		"Operating system" "GNU Hurd" "GNU Guix package manager"
-		"GNU Guile" "Guile Scheme" "Transactional upgrades"
-		"Functional package management" "Reproducibility")
-   #:active-menu-item "Menu"
+   #:title (C_ "webpage title" '("Menu"))
+   #:description (G_ "Website menu.")
+   #:keywords
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+    (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile \
+Scheme|Transactional upgrades|Functional package \
+management|Reproducibility") #\|)
+   #:active-menu-item (C_ "website menu" "Menu")
    #:css (list (guix-url "static/base/css/menu.css"))))
diff --git a/website/apps/base/templates/screenshot.scm b/website/apps/base/templates/screenshot.scm
index 41a3a07..60662fa 100644
--- a/website/apps/base/templates/screenshot.scm
+++ b/website/apps/base/templates/screenshot.scm
@@ -7,6 +7,7 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (screenshot-t))
 
 
@@ -15,14 +16,15 @@
   (let ((shot (context-datum context "screenshot"))
 	(shots (context-datum context "screenshots")))
     (theme
-     #:title (list (screenshot-title shot) "Screenshots")
+     #:title (list (screenshot-title shot) (C_ "webpage title" "Screenshots"))
      #:description (screenshot-caption shot)
      #:keywords
-     '("GNU" "Linux" "Unix" "Free software" "Libre software"
-       "Operating system" "GNU Hurd" "GNU Guix package manager"
-       "GNU Guile" "Guile Scheme" "Transactional upgrades"
-       "Functional package management" "Reproducibility")
-     #:active-menu-item "Overview"
+     (string-split ;TRANSLATORS: |-separated list of webpage keywords
+      (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile \
+Scheme|Transactional upgrades|Functional package \
+management|Reproducibility") #\|)
+     #:active-menu-item (C_ "website menu" "Overview")
      #:css (list (guix-url "static/base/css/index.css")
 		 (guix-url "static/base/css/screenshots.css"))
      #:content
diff --git a/website/apps/base/templates/security.scm b/website/apps/base/templates/security.scm
index b772912..d28b548 100644
--- a/website/apps/base/templates/security.scm
+++ b/website/apps/base/templates/security.scm
@@ -3,9 +3,11 @@
 ;;; copyright interest on this file.
 
 (define-module (apps base templates security)
+  #:use-module (apps base templates components)
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (security-t))
 
 (define ludovics-key
@@ -14,36 +16,38 @@
 (define (security-t)
   "Return the Security page in SHTML."
   (theme
-   #:title '("Security")
+   #:title (C_ "webpage title" '("Security"))
    #:description
-   "Important information about getting security updates for your
-   GNU Guix installation, and instructions on how to report
-   security issues."
+   (G_ "Important information about getting security updates
+   for your GNU Guix installation, and instructions on how
+   to report security issues.")
    #:keywords
-   '("GNU" "Linux" "Unix" "Free software" "Libre software"
-     "Operating system" "GNU Hurd" "GNU Guix package manager"
-     "Security updates")
-   #:active-menu-item "About"
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+      (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|Security updates") #\|)
+   #:active-menu-item (C_ "website menu" "About")
    #:css (list
 	  (guix-url "static/base/css/page.css"))
-   #:crumbs (list (crumb "Security" "./"))
+   #:crumbs (list (crumb (C_ "website menu" "Security") "./"))
    #:content
    `(main
      (section
       (@ (class "page centered-block limit-width"))
-      (h2 "Security")
+      ,(G_ `(h2 "Security"))
 
-      (h3 "How to report security issues")
-      (p
-       "To report sensitive security issues in Guix itself or the
-        packages it provides, you can write to the private mailing list "
-       (a (@ (href "https://lists.gnu.org/mailman/listinfo/guix-security"))
-	  ("guix-security@HIDDEN")) ".  This list is monitored by a
-        small team of Guix developers.")
-      (p
-       "If you prefer to send your report using OpenPGP encrypted email,
-        please send it to one of the following Guix developers using their
-        respective OpenPGP key:")
+      ,(G_ `(h3 "How to report security issues"))
+      ,(G_
+        `(p
+          "To report sensitive security issues in Guix itself or the
+           packages it provides, you can write to the private mailing list "
+          (a (@ (href "https://lists.gnu.org/mailman/listinfo/guix-security"))
+             ("guix-security@HIDDEN")) ".  This list is monitored by a
+           small team of Guix developers."))
+      ,(G_
+        `(p
+          "If you prefer to send your report using OpenPGP encrypted email,
+           please send it to one of the following Guix developers using their
+           respective OpenPGP key:"))
       (ul
         (li "Leo Famulari"
           (ul (@ (class "mono"))
@@ -58,23 +62,30 @@
           (ul (@ (class "mono"))
             (li "BCA6 89B6 3655 3801 C3C6 2150 197A 5888 235F ACAC"))))
 
-      (h3 "Release signatures")
-      (p
-       "Releases of Guix are signed using the OpenPGP "
-       "key with the fingerprint "
-       (span (@ (class "mono")) ,ludovics-key)
-       ".  "
-       "Users should "
-       (a (@ (href ,(manual-url "Binary-Installation.html"))) "verify")
-       " their downloads before extracting or running them.")
+      ,(G_ `(h3 "Release signatures"))
+      ,(G_
+        `(p
+          "Releases of Guix are signed using the OpenPGP "
+          "key with the fingerprint "
+          (span (@ (class "mono")) ,ludovics-key)
+          ".  "
+          "Users should "
+          ,(G_ (manual-href "verify"
+                            (G_ "en")
+                            (G_ "Binary-Installation.html")))
+          " their downloads before extracting or running them."))
 
-      (h3 "Security updates")
-      (p
-       "When security vulnerabilities are found in Guix or the "
-       "packages provided by Guix, we will provide "
-       (a (@ (href ,(manual-url "Security-Updates.html"))) "security updates")
-       " quickly and with minimal disruption for users.")
-      (p
-       "Guix uses a “rolling release” model.  All security "
-       "bug-fixes are pushed directly to the master branch.  There"
-       " is no “stable” branch that only receives security fixes.")))))
+      ,(G_ `(h3 "Security updates"))
+      ,(G_
+        `(p
+          "When security vulnerabilities are found in Guix or the "
+          "packages provided by Guix, we will provide "
+          ,(G_ (manual-href "security updates"
+                            (G_ "en")
+                            (G_ "Security-Updates.html")))
+          " quickly and with minimal disruption for users."))
+      ,(G_
+        `(p
+          "Guix uses a “rolling release” model.  All security "
+          "bug-fixes are pushed directly to the master branch.  There"
+          " is no “stable” branch that only receives security fixes."))))))
diff --git a/website/apps/base/templates/theme.scm b/website/apps/base/templates/theme.scm
index ecb27ef..ffff948 100644
--- a/website/apps/base/templates/theme.scm
+++ b/website/apps/base/templates/theme.scm
@@ -5,15 +5,16 @@
 (define-module (apps base templates theme)
   #:use-module (apps base templates components)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (theme))
 
 
 (define* (theme #:key
-		(lang-tag "en")
+                (lang-tag %current-lang)
 		(title '())
 		(description "")
 		(keywords '())
-		(active-menu-item "About")
+                (active-menu-item (C_ "website menu" "About"))
 		(css '())
 		(scripts '())
 		(crumbs '())
@@ -65,12 +66,14 @@
   `((doctype "html")
 
     (html
-     (@ (lang "en"))
+     (@ (lang %current-lang))
 
      (head
       ,(if (null? title)
-	   `(title "GNU Guix")
-	   `(title ,(string-join (append title '("GNU Guix")) " — ")))
+           `(title ,(C_ "webpage title" "GNU Guix"))
+           `(title ,(string-join (append title
+                                         (C_ "webpage title" '("GNU Guix")))
+                                 " — ")))
       (meta (@ (charset "UTF-8")))
       (meta (@ (name "keywords") (content ,(string-join keywords ", "))))
       (meta (@ (name "description") (content ,description)))
@@ -91,7 +94,7 @@
 	     css)
       ;; Feeds.
       (link (@ (type "application/atom+xml") (rel "alternate")
-	       (title "GNU Guix — Activity Feed")
+	       (title (C_ "webpage title" "GNU Guix — Activity Feed"))
 	       (href ,(guix-url "feeds/blog.atom"))))
       (link (@ (rel "icon") (type "image/png")
 	       (href ,(guix-url "static/base/img/icon.png"))))
@@ -108,17 +111,22 @@
       ,(if (null? crumbs) "" (breadcrumbs crumbs))
 
       ,content
-      (footer
-       "Made with " (span (@ (class "metta")) "♥")
-       " by humans and powered by "
-       (a (@ (class "link-yellow") (href ,(gnu-url "software/guile/")))
-	  "GNU Guile") ".  "
-	  (a
-	   (@ (class "link-yellow")
-	      (href "//git.savannah.gnu.org/cgit/guix/guix-artwork.git/tree/website"))
-	   "Source code")
-	  " under the "
-	  (a
-	   (@ (class "link-yellow")
-	      (href ,(gnu-url "licenses/agpl-3.0.html")))
-	   "GNU AGPL") ".")))))
+      ,(G_
+        `(footer
+          "Made with " ,(G_ `(span (@ (class "metta")) "♥"))
+          " by humans and powered by "
+          ,(G_ `(a
+                 (@ (class "link-yellow")
+                    (href ,(gnu-url "software/guile/")))
+                 "GNU Guile"))
+          ".  "
+          ,(G_ `(a
+                 (@ (class "link-yellow")
+                    (href "//git.savannah.gnu.org/cgit/guix/guix-artwork.git/tree/website"))
+                 "Source code"))
+          " under the "
+          ,(G_ `(a
+                 (@ (class "link-yellow")
+                    (href ,(gnu-url "licenses/agpl-3.0.html")))
+                 "GNU AGPL"))
+          "."))))))
diff --git a/website/apps/base/utils.scm b/website/apps/base/utils.scm
index d57ec7c..eb11b42 100644
--- a/website/apps/base/utils.scm
+++ b/website/apps/base/utils.scm
@@ -3,6 +3,7 @@
 ;;; Copyright © 2015 Mathieu Lirzin <mthl@HIDDEN>
 ;;; Copyright © 2013 Alex Sassmannshausen <alex.sassmannshausen@HIDDEN>
 ;;; Copyright © 2017 Eric Bavier <bavier@HIDDEN>
+;;; Copyright © 2019 Florian Pelz <pelzflorian@HIDDEN>
 ;;; Initially written by sirgazil who waives all copyright interest on this
 ;;; file.
 ;;;
@@ -35,6 +36,7 @@
 	    guix-url
 	    latest-guix-version
 	    manual-url
+            manual-url-with-language
 	    number*
 	    paginate))
 
@@ -115,6 +117,27 @@
                                            "/html_node/")
                             subpath))))
 
+(define* (manual-url-with-language _ language #:optional (subpath ""))
+  "Shorthand for manual-url without keywords for prettier output
+PO files when marked for translation.  It can be marked for translation
+as:
+
+  (G_ (manual-url-with-language (G_ \"en\") (G_ \"Some-section.html\")))
+
+   LANGUAGE (string)
+     Normalized language for the Guix manual as produced by
+'doc/build.scm' in the Guix source tree, i.e. \"en\" for the English
+manual.
+
+   SUBPATH (string)
+     Like manual-url.
+
+   RETURN VALUE (string)
+     A URL path. For example:
+     /software/guix/manual/en/html_node/System-installation.html."
+  ;; The _ argument is a placeholder for an arg added by G_, cf. i18n-howto.txt.
+  (manual-url subpath #:language language))
+
 
 
 ;;;
diff --git a/website/apps/blog/templates/components.scm b/website/apps/blog/templates/components.scm
index fe67f29..38d02ac 100644
--- a/website/apps/blog/templates/components.scm
+++ b/website/apps/blog/templates/components.scm
@@ -8,6 +8,7 @@
   #:use-module (apps aux web)
   #:use-module (apps base utils)
   #:use-module (apps blog utils)
+  #:use-module (apps i18n)
   #:use-module (haunt post)
   #:use-module (srfi srfi-19)
   #:export (post-preview
@@ -29,11 +30,12 @@
     (h3 ,(post-ref post 'title))
     (p
      (@ (class "item-date"))
-     ,(date->string (post-date post) "~B ~e, ~Y"))
+     ,(date->string (post-date post) (C_ "SRFI-19 date->string format"
+                                         "~B ~e, ~Y")))
     (p
      (@ (class "item-summary"))
      ,(string-summarize (sxml->string* (post-sxml post)) 30)
-     "…")))
+     (C_ "blog post summary ellipsis" "…"))))
 
 
 (define* (sidebar tags #:optional (current-tag #false))
@@ -44,13 +46,13 @@
      Haunt's 'posts/group-by-tag' procedure in (haunt post) module."
   `(section
     (@ (class "side-bar"))
-    (h3 (@ (class "a11y-offset")) "Blog menu: ")
+    (h3 (@ (class "a11y-offset")) (G_ "Blog menu: "))
 
     (h4
      (@ (class "bar-title bar-title-top"))
      ,(if current-tag
-	  "Get topic updates"
-	  "Get blog updates"))
+          (G_ "Get topic updates")
+          (G_ "Get blog updates")))
     (ul
      (@ (class "bar-list"))
      (li (@ (class "bar-item"))
@@ -62,9 +64,9 @@
 					     (slugify current-tag)
 					     ".atom"))))
 		    `(href ,(guix-url (url-path-join "feeds" "blog.atom")))))
-	    " Atom feed")))
+            (C_ "button" "Atom feed"))))
 
-    (h4 (@ (class "bar-title")) "Posts by topic")
+    (h4 (@ (class "bar-title")) (G_ "Posts by topic"))
     (ul
      (@ (class "bar-list"))
      ,@(map
diff --git a/website/apps/blog/templates/feed.scm b/website/apps/blog/templates/feed.scm
index 5e015d0..0392345 100644
--- a/website/apps/blog/templates/feed.scm
+++ b/website/apps/blog/templates/feed.scm
@@ -10,6 +10,7 @@
   #:use-module (apps base types)
   #:use-module (apps base utils)
   #:use-module (apps blog utils)
+  #:use-module (apps i18n)
   #:use-module (haunt html)
   #:use-module (haunt post)
   #:use-module (srfi srfi-19)
@@ -28,7 +29,7 @@
       (@ (xmlns "http://www.w3.org/2005/Atom"))
       (id ,id)
       (title ,title)
-      (author (name "GNU Guix") (uri ,domain))
+      (author (name (C_ "feed author name" "GNU Guix")) (uri ,domain))
       (icon ,(guix-url "static/base/img/icon.png"))
       (updated ,(date->string (current-date) "~4"))
       (link (@ (rel "alternate") (href ,alternate)))
diff --git a/website/apps/blog/templates/post-list.scm b/website/apps/blog/templates/post-list.scm
index a64e33a..5b3f73f 100644
--- a/website/apps/blog/templates/post-list.scm
+++ b/website/apps/blog/templates/post-list.scm
@@ -9,6 +9,7 @@
   #:use-module (apps base types)
   #:use-module (apps base utils)
   #:use-module ((apps blog templates components) #:prefix blog:)
+  #:use-module (apps i18n)
   #:export (post-list-t))
 
 
@@ -19,22 +20,24 @@
 	(total-pages
 	 (number->string (context-datum context "total-pages"))))
     (theme
-     #:title (list (string-append "Page " page-number) "Blog")
+     #:title (list (G_ (string-append "Page " page-number ""))
+                   (C_ "webpage title" "Blog"))
      #:description
-     "Blog posts about GNU Guix."
+     (G_ "Blog posts about GNU Guix.")
      #:keywords
-     '("GNU" "Linux" "Unix" "Free software" "Libre software"
-       "Operating system" "GNU Hurd" "GNU Guix package manager"
-       "GNU Guile" "Guile Scheme" "Transactional upgrades"
-       "Functional package management" "Reproducibility")
-     #:active-menu-item "Blog"
+     (string-split ;TRANSLATORS: |-separated list of webpage keywords
+      (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile \
+Scheme|Transactional upgrades|Functional package \
+management|Reproducibility") #\|)
+     #:active-menu-item (C_ "website menu" "Blog")
      #:css
      (list (guix-url "static/base/css/page.css")
 	   (guix-url "static/base/css/item-preview.css")
 	   (guix-url "static/base/css/sidebar.css"))
      #:crumbs
-     (list (crumb "Blog" (guix-url "blog/"))
-	   (crumb (string-append "Page " page-number)
+     (list (crumb (C_ "website menu" "Blog") (guix-url "blog/"))
+           (crumb (G_ (string-append "Page " page-number ""))
 		  (guix-url (url-path-join "blog"
 					   "page"
 					   page-number
@@ -43,7 +46,7 @@
      `(main
        (section
 	(@ (class "page centered-text"))
-	(h2 "Blog"
+        (h2 (G_ "Blog")
 	    ,(page-indicator (string->number page-number)
 			     (string->number total-pages)))
 
diff --git a/website/apps/blog/templates/post.scm b/website/apps/blog/templates/post.scm
index fe90ba0..2871431 100644
--- a/website/apps/blog/templates/post.scm
+++ b/website/apps/blog/templates/post.scm
@@ -9,6 +9,7 @@
   #:use-module (apps base utils)
   #:use-module (apps blog utils)
   #:use-module ((apps blog templates components) #:prefix blog:)
+  #:use-module (apps i18n)
   #:use-module (haunt post)
   #:use-module (srfi srfi-19)
   #:export (post-t))
@@ -21,17 +22,17 @@
     (theme
      #:title (list (post-ref post 'title)
 		   (date->string (post-date post) "~Y")
-		   "Blog")
+                   (C_ "webpage title" "Blog"))
      #:description
-     "Blog posts about GNU Guix."
+     (G_ "Blog posts about GNU Guix.")
      #:keywords tags
-     #:active-menu-item "Blog"
+     #:active-menu-item (C_ "website menu" "Blog")
      #:css
      (list (guix-url "static/base/css/page.css")
 	   (guix-url "static/base/css/code.css")
 	   (guix-url "static/blog/css/post.css"))
      #:crumbs
-     (list (crumb "Blog" (guix-url "blog/"))
+     (list (crumb (C_ "website menu" "Blog") (guix-url "blog/"))
 	   (crumb (post-ref post 'title)
 		  (guix-url (post-url-path post))))
      #:content
@@ -42,13 +43,14 @@
 	(p
 	 (@ (class "post-metadata centered-text"))
 	 ,(post-ref post 'author) " — "
-	 ,(date->string (post-date post) "~B ~e, ~Y"))
+         ,(date->string (post-date post) (C_ "SRFI-19 date->string format"
+                                             "~B ~e, ~Y")))
 
 	,(syntax-highlight (post-sxml post))
 
 	(div
 	 (@ (class "tag-list"))
-	 (p "Related topics:")
+         ,(G_ `(p "Related topics:"))
 
 	 ,@(map
 	    (lambda (tag)
diff --git a/website/apps/blog/templates/tag.scm b/website/apps/blog/templates/tag.scm
index 7d9c88b..7bd7570 100644
--- a/website/apps/blog/templates/tag.scm
+++ b/website/apps/blog/templates/tag.scm
@@ -10,6 +10,7 @@
   #:use-module (apps base utils)
   #:use-module ((apps blog templates components) #:prefix blog:)
   #:use-module (apps blog utils)
+  #:use-module (apps i18n)
   #:export (tag-t))
 
 
@@ -21,25 +22,27 @@
 	(total-pages
 	 (number->string (context-datum context "total-pages"))))
     (theme
-     #:title (list (string-append "Page " page-number) tag "Blog")
+     #:title (list (G_ (string-append "Page " page-number ""))
+                   tag (C_ "webpage title" "Blog"))
      #:description
-     (string-append "Blog posts about "
-		    tag
-		    " on GNU Guix.")
+     (G_ (string-append "Blog posts about "
+                        tag
+                        " on GNU Guix."))
      #:keywords
-     '("GNU" "Linux" "Unix" "Free software" "Libre software"
-       "Operating system" "GNU Hurd" "GNU Guix package manager"
-       "GNU Guile" "Guile Scheme" "Transactional upgrades"
-       "Functional package management" "Reproducibility")
-     #:active-menu-item "Blog"
+     (string-split ;TRANSLATORS: |-separated list of webpage keywords
+      (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile \
+Scheme|Transactional upgrades|Functional package \
+management|Reproducibility") #\|)
+     #:active-menu-item (C_ "website menu" "Blog")
      #:css
      (list (guix-url "static/base/css/page.css")
 	   (guix-url "static/base/css/item-preview.css")
 	   (guix-url "static/base/css/sidebar.css"))
      #:crumbs
-     (list (crumb "Blog" (guix-url "blog/"))
+     (list (crumb (C_ "website menu" "Blog") (guix-url "blog/"))
 	   (crumb tag (guix-url (tag-url-path tag)))
-	   (crumb (string-append "Page " page-number)
+           (crumb (G_ (string-append "Page " page-number ""))
 		  (guix-url (url-path-join (tag-url-path tag)
 					   "page"
 					   page-number
@@ -48,7 +51,7 @@
      `(main
        (section
 	(@ (class "page centered-text"))
-	(h2 "Blog — " ,tag
+        (h2 ,(G_ "Blog — ") ,tag
 	    ,(page-indicator (string->number page-number)
 			     (string->number total-pages)))
 
diff --git a/website/apps/download/data.scm b/website/apps/download/data.scm
index 8e432db..34c50df 100644
--- a/website/apps/download/data.scm
+++ b/website/apps/download/data.scm
@@ -5,6 +5,7 @@
 (define-module (apps download data)
   #:use-module (apps base utils)
   #:use-module (apps download types)
+  #:use-module (apps i18n)
   #:export (system-downloads))
 
 
@@ -16,34 +17,44 @@
 (define system-downloads
   (list
    (download
-    #:title (string-append "GNU Guix System " (latest-guix-version))
+    #:title (C_ "download page title"
+                (string-append "GNU Guix System " (latest-guix-version) ""))
     #:description
     `(div
-      (p "USB/DVD ISO installer of the standalone Guix System."))
+      ,(G_ `(p "USB/DVD ISO installer of the standalone Guix System.")))
     #:image (guix-url "static/base/img/GuixSD-package.png")
     #:base-url (string-append "https://ftp.gnu.org/gnu/guix/guix-system-install-"
 			      (latest-guix-version) ".")
     #:variants (list (variant "x86_64" "x86_64-linux.iso.xz")
 		     (variant "i686" "i686-linux.iso.xz"))
-    #:manual (manual-url "System-Installation.html"))
+    ;; TRANSLATORS: System installation is a section name in the
+    ;; English (en) manual.
+    #:manual (G_ (manual-url-with-language (G_ "en")
+                                           "System-Installation.html")))
 
    (download
-    #:title (string-append "GNU Guix " (latest-guix-version) " QEMU Image")
+    #:title (C_ "download page title"
+                (string-append "GNU Guix " (latest-guix-version) " QEMU Image"))
     #:description
     `(div
-      (p "QCOW2 virtual machine (VM) image."))
+      ,(G_ `(p "QCOW2 virtual machine (VM) image.")))
     #:image (guix-url "static/base/img/QEMU-package.png")
     #:base-url (string-append "https://ftp.gnu.org/gnu/guix/guix-system-vm-image-"
 			      (latest-guix-version) ".")
     #:variants (list (variant "x86_64" "x86_64-linux.xz"))
-    #:manual (manual-url "Running-Guix-in-a-VM.html"))
+    ;; TRANSLATORS: Running Guix in a VM is a section name in the
+    ;; English (en) manual.
+    #:manual (G_ (manual-url-with-language (G_ "en")
+                                           "Running-Guix-in-a-VM.html")))
 
    (download
-    #:title (string-append "GNU Guix " (latest-guix-version) " Binary")
+    #:title (C_ "download page title"
+                (string-append "GNU Guix " (latest-guix-version) " Binary"))
     #:description
-    '(p
-      "Self-contained tarball providing binaries for Guix and its
-      dependencies, to be installed on top of your Linux-based system.")
+    (G_
+     '(p
+       "Self-contained tarball providing binaries for Guix and its
+       dependencies, to be installed on top of your Linux-based system."))
     #:image (guix-url "static/base/img/Guix-package.png")
     #:base-url (string-append "https://ftp.gnu.org/gnu/guix/guix-binary-"
 			      (latest-guix-version) ".")
@@ -51,13 +62,20 @@
 		     (variant "i686" "i686-linux.tar.xz")
 		     (variant "armhf" "armhf-linux.tar.xz")
                      (variant "aarch64" "aarch64-linux.tar.xz"))
-    #:manual (manual-url "Binary-Installation.html"))
+    ;; TRANSLATORS: Binary Installation is a section name in the
+    ;; English (en) manual.
+    #:manual (G_ (manual-url-with-language (G_ "en")
+                                           "Binary-Installation.html")))
 
    (download
-    #:title (string-append "GNU Guix " (latest-guix-version) " Source")
-    #:description '(p "Source code distribution.")
+    #:title (C_ "download page title"
+                (string-append "GNU Guix " (latest-guix-version) " Source"))
+    #:description (G_ '(p "Source code distribution."))
     #:image (guix-url "static/base/img/src-package.png")
     #:base-url (string-append "https://ftp.gnu.org/gnu/guix/guix-"
 			      (latest-guix-version) ".")
     #:variants (list (variant "tarball" "tar.gz"))
-    #:manual (manual-url "Requirements.html"))))
+    ;; TRANSLATORS: Requirements is a section name in the English (en)
+    ;; manual.
+    #:manual (G_ (manual-url-with-language (G_ "en")
+                                           "Requirements.html")))))
diff --git a/website/apps/download/templates/components.scm b/website/apps/download/templates/components.scm
index bbd46b0..60e7330 100644
--- a/website/apps/download/templates/components.scm
+++ b/website/apps/download/templates/components.scm
@@ -4,6 +4,7 @@
 
 (define-module (apps download templates components)
   #:use-module (apps download types)
+  #:use-module (apps i18n)
   #:export (download))
 
 
@@ -21,7 +22,7 @@
     (img (@ (src ,(download-image dnd)) (alt "")))
     (h3 ,(download-title dnd))
     ,(download-description dnd)
-    (p "Download options:")
+    ,(G_ `(p "Download options:"))
     ,@(map (lambda (variant)
 	     `(a
 	       (@ (class "download-btn")
@@ -34,7 +35,7 @@
 	  (download-variants dnd))
 
     (p
-     "Signatures: "
+     ,(G_ "Signatures: ")
      ,@(map (lambda (variant)
 	     `(a
 	       (@ (class "signature-btn")
@@ -46,4 +47,9 @@
 	       " ")) ; Force a space for readability in non-CSS browsers.
 	    (download-variants dnd)))
 
-    (p (a (@ (href ,(download-manual dnd))) "Installation instructions") ".")))
+    ,(G_
+      `(p
+        ,(G_
+          `(a (@ (href ,(download-manual dnd)))
+              "Installation instructions"))
+        "."))))
diff --git a/website/apps/download/templates/download.scm b/website/apps/download/templates/download.scm
index f888a0b..ffa6ce0 100644
--- a/website/apps/download/templates/download.scm
+++ b/website/apps/download/templates/download.scm
@@ -23,56 +23,60 @@
   #:use-module (apps base types)
   #:use-module (apps base utils)
   #:use-module (apps download templates components)
+  #:use-module (apps i18n)
   #:export (download-t))
 
 
 (define (download-t context)
   "Return the Download page in SHTML."
   (theme
-   #:title '("Download")
+   #:title (C_ "webpage title" '("Download"))
    #:description
-   "Installers and source files for GNU Guix.  GNU Guix can be
-   installed on different GNU/Linux distributions."
+   (G_ "Installers and source files for GNU Guix.  GNU Guix can be
+   installed on different GNU/Linux distributions.")
    #:keywords
-   '("GNU" "Linux" "Unix" "Free software" "Libre software"
-     "Operating system" "GNU Hurd" "GNU Guix package manager"
-     "Installer" "Source code" "Package manager")
-   #:active-menu-item "Download"
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+    (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|Installer|Source code|\
+Package manager") #\|)
+   #:active-menu-item (C_ "website menu" "Download")
    #:css (list
 	  (guix-url "static/base/css/page.css")
 	  (guix-url "static/base/css/download.css"))
-   #:crumbs (list (crumb "Download" "./"))
+   #:crumbs (list (crumb (C_ "website menu" "Download") "./"))
    #:content
    `(main
      (section
       (@ (class "page"))
-      (h2 "Download")
+      ,(G_ `(h2 "Download"))
 
-      (p
-       (@ (class "centered-block limit-width"))
-       "As of version " ,(latest-guix-version)
-       ", the standalone Guix System "
-       (a
-	(@ (href ,(manual-url "System-Installation.html")))
-	"can be installed")
-       " on an i686, x86_64, ARMv7, or AArch64 machine.  It uses the "
-       (a (@ (href ,(gnu-url "software/linux-libre"))) "Linux-Libre")
-       " kernel and the "
-       (a (@ (href ,(gnu-url "software/shepherd"))) "GNU Shepherd")
-       " init system. Alternately, GNU Guix
-       can be installed as an additional package manager on top of an
-       installed Linux-based system.")
+      ,(G_
+        `(p
+          (@ (class "centered-block limit-width"))
+          "As of version " ,(latest-guix-version)
+          ", the standalone Guix System "
+          ,(G_ `(a
+                 (@ (href ,(manual-url "System-Installation.html")))
+                 "can be installed"))
+          " on an i686, x86_64, ARMv7, or AArch64 machine.  It uses the "
+          ,(G_ `(a (@ (href ,(gnu-url "software/linux-libre"))) "Linux-Libre"))
+          " kernel and the "
+          ,(G_ `(a (@ (href ,(gnu-url "software/shepherd"))) "GNU Shepherd"))
+          " init system. Alternately, GNU Guix
+          can be installed as an additional package manager on top of an
+          installed Linux-based system."))
 
       (div
        (@ (class "centered-text"))
        ,@(map download (context-datum context "downloads")))
 
-      (p
-       (@ (class "centered-block limit-width"))
-       "Source code and binaries for the Guix System distribution ISO
-       image as well as GNU Guix can be found on the GNU servers at "
-       (a (@ (href "https://ftp.gnu.org/gnu/guix/"))
-	  "https://ftp.gnu.org/gnu/guix/")
-       ".  Older releases can still be found on "
-       (a (@ (href "https://alpha.gnu.org/gnu/guix/"))
-          "alpha.gnu.org") ".")))))
+      ,(G_
+        `(p
+          (@ (class "centered-block limit-width"))
+          "Source code and binaries for the Guix System distribution ISO
+          image as well as GNU Guix can be found on the GNU servers at "
+          (a (@ (href "https://ftp.gnu.org/gnu/guix/"))
+             "https://ftp.gnu.org/gnu/guix/")
+          ".  Older releases can still be found on "
+          (a (@ (href "https://alpha.gnu.org/gnu/guix/"))
+             "alpha.gnu.org") "."))))))
diff --git a/website/apps/packages/templates/components.scm b/website/apps/packages/templates/components.scm
index 96e4296..926ec0b 100644
--- a/website/apps/packages/templates/components.scm
+++ b/website/apps/packages/templates/components.scm
@@ -8,6 +8,7 @@
   #:use-module (apps aux web)
   #:use-module (apps base templates components)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:use-module (apps packages data)
   #:use-module (apps packages types)
   #:use-module (apps packages utils)
@@ -55,37 +56,38 @@
      ;; 'gnu-package?' might fetch stuff from the network.  Assume #f if that
      ;; doesn't work.
      ,(if (false-if-exception (gnu-package? package))
-          '(p (i "This is a GNU package.  "))
+          `(p (i ,(G_ "This is a GNU package.  ")))
           "")
 
      ,(package-description-shtml package))
 
     (ul
      (@ (class "package-info"))
-     (li (b "License:") " "
-	 ,(license->shtml (package-license package))
-	 ".")
-
-     (li (b "Website:") " "
-	 ,(link-subtle #:label (package-home-page package)
-		       #:url (package-home-page package)) ".")
-
-     (li (b "Package source:") " "
-	 ,(location->shtml (package-location package))
-	 ".")
-
-     (li (b "Patches:") " "
-	 ,(patches->shtml (package-patches package))
-	 ".")
-
-     (li (b "Lint issues:") " "
-     	 ,(if (null? (package-lint-issues package))
-     	      "No"
-     	      (link-subtle #:label "Yes"
-     	 		   #:url (guix-url "packages/issues/")))
-     	 ".")
-
-     (li (b "Builds:") " " ,(supported-systems->shtml package) ".")
+     ,(G_ `(li ,(G_ `(b "License:")) " "
+               ,(license->shtml (package-license package))
+               "."))
+
+     ,(G_ `(li ,(G_ `(b "Website:")) " "
+               ,(link-subtle #:label (package-home-page package)
+                             #:url (package-home-page package)) "."))
+
+     ,(G_ `(li ,(G_ `(b "Package source:")) " "
+               ,(location->shtml (package-location package))
+               "."))
+
+     ,(G_ `(li ,(G_ `(b "Patches:")) " "
+               ,(patches->shtml (package-patches package))
+               "."))
+
+     ,(G_ `(li ,(G_ `(b "Lint issues:")) " "
+               ,(if (null? (package-lint-issues package))
+                    (G_ "No")
+                    (link-subtle #:label (G_ "Yes")
+                                 #:url (guix-url "packages/issues/")))
+               "."))
+
+     ,(G_ `(li ,(G_ `(b "Builds:")) " "
+               ,(supported-systems->shtml package) "."))
      "\n")))
 
 
@@ -99,7 +101,7 @@
      A span element if the count is 0. A mark element otherwise."
   `(,(if (> count 0) 'mark 'span)
     ,(number->string count)
-    ,(if (= count 1) " issue" " issues")))
+    ,(N_ " issue" " issues" count)))
 
 
 (define* (letter-selector #:optional (active-letter ""))
@@ -110,10 +112,10 @@
      The letter that should be displayed as active."
   `(section
     (@ (class "letter-selector"))
-    (h3 (@ (class "a11y-offset")) "Packages menu: ")
+    ,(G_ `(h3 (@ (class "a11y-offset")) "Packages menu: "))
 
-    (h4 (@ (class "selector-title selector-title-top"))
-	"Browse alphabetically")
+    ,(G_ `(h4 (@ (class "selector-title selector-title-top"))
+              "Browse alphabetically"))
     (div
      (@ (class "selector-box-padded"))
      ,@(map
@@ -199,7 +201,7 @@
      If the list of patches is empty, return the string 'None'.
      Otherwise, return a list of links to patches."
   (if (null? patches)
-      "None"
+      (G_ "None")
       (separate
        (map (lambda (patch)
 	      (link-subtle #:label (ilink-name patch)
@@ -216,9 +218,9 @@
      The letter in which the current packages are listed."
   `(section
     (@ (class "side-bar"))
-    (h3 (@ (class "a11y-offset")) "Packages menu: ")
+    ,(G_ `(h3 (@ (class "a11y-offset")) "Packages menu: "))
 
-    (h4 (@ (class "bar-title bar-title-top")) "Browse alphabetically")
+    ,(G_ `(h4 (@ (class "bar-title bar-title-top")) "Browse alphabetically"))
     (div
      (@ (class "bar-box-padded"))
      ,@(map
@@ -233,16 +235,16 @@
 
     ;; FIXME: This is currently too costly to produce so we just disable it.
 
-    ;; (h4 (@ (class "bar-title")) "Packages Issues")
+    ;; ,(G_ `(h4 (@ (class "bar-title")) "Packages Issues"))
     ;; (ul
     ;;  (@ (class "bar-list"))
     ;;  (li (@ (class "bar-item"))
-    ;;      (a (@ (class "bar-link")
-    ;;            (href ,(guix-url "packages/issues/lint/"))) "Lint"))
+    ;;      ,(G_ `(a (@ (class "bar-link")
+    ;;                  (href ,(guix-url "packages/issues/lint/"))) "Lint")))
     ;;  (li (@ (class "bar-item"))
-    ;;      (a (@ (class "bar-link")
-    ;;            (href ,(guix-url "packages/issues/reproducibility/")))
-    ;;         "Reproducibility")))
+    ;;      ,(G_ `(a (@ (class "bar-link")
+    ;;                  (href ,(guix-url "packages/issues/reproducibility/")))
+    ;;               "Reproducibility"))))
     ))
 
 
@@ -265,7 +267,7 @@
                   %hydra-supported-systems
                   (package-transitive-supported-systems package))))
     (if (null? systems)
-	"None"
+        (G_ "None")
 	(separate
 	 (map (lambda (system)
 		(link-subtle #:label system
diff --git a/website/apps/packages/templates/detailed-index.scm b/website/apps/packages/templates/detailed-index.scm
index 81dfdd6..68dc9de 100644
--- a/website/apps/packages/templates/detailed-index.scm
+++ b/website/apps/packages/templates/detailed-index.scm
@@ -8,6 +8,7 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:use-module (apps packages templates components)
   #:use-module (srfi srfi-19)
   #:export (detailed-index-t))
@@ -18,39 +19,45 @@
 packages to advertise."
   (let ((packages (context-datum context "packages")))
     (theme
-     #:title (list "Packages")
+     #:title (C_ "webpage title" (list "Packages"))
      #:description
-     "List of packages available through GNU Guix."
+     (G_ "List of packages available through GNU Guix.")
      #:keywords
-     (list "GNU" "Linux" "Unix" "Free software" "Libre software"
-	   "Operating system" "GNU Hurd" "GNU Guix package manager"
-	   "GNU Guile" "Guile Scheme" "Transactional upgrades"
-	   "Functional package management" "Reproducibility")
-     #:active-menu-item "Packages"
+     (string-split ;TRANSLATORS: |-separated list of webpage keywords
+      (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile \
+Scheme|Transactional upgrades|Functional package \
+management|Reproducibility") #\|)
+     #:active-menu-item (C_ "website menu" "Packages")
      #:css
      (list (guix-url "static/base/css/page.css")
 	   (guix-url "static/base/css/item-preview.css")
 	   (guix-url "static/packages/css/letter-selector.css")
 	   (guix-url "static/packages/css/package-list.css"))
      #:crumbs
-     (list (crumb "Packages" (guix-url "packages/")))
+     (list (crumb (C_ "website menu" "Packages") (guix-url "packages/")))
      #:content
      `(main
        (section
 	(@ (class "page centered-text"))
-	(h2 "Packages")
+        ,(G_ `(h2 "Packages"))
 
-	(p
-	 (@ (class "limit-width centered-block"))
-	 "GNU Guix provides " ,(number* (or total (length packages)))
-	 " packages transparently "
-	 (a (@ (href "https://hydra.gnu.org/jobset/gnu/master#tabs-status"))
-	    "available as pre-built binaries")
-	 ". These pages provide a complete list of the packages.  Our "
-	 (a (@ (href "https://hydra.gnu.org/jobset/gnu/master"))
-	    "continuous integration system")
-	 " shows their current build status "
-	 "(updated " ,(date->string (current-date) "~B ~e, ~Y") ").")
+        ,(G_
+          `(p
+            (@ (class "limit-width centered-block"))
+            "GNU Guix provides " ,(number* (or total (length packages)))
+            " packages transparently "
+            ,(G_
+              `(a (@ (href "https://hydra.gnu.org/jobset/gnu/master#tabs-status"))
+                  "available as pre-built binaries"))
+            ". These pages provide a complete list of the packages.  Our "
+            ,(G_
+              `(a (@ (href "https://hydra.gnu.org/jobset/gnu/master"))
+                  "continuous integration system"))
+            " shows their current build status "
+            "(updated " ,(date->string (current-date)
+                                       (C_ "SRFI-19 date->string format"
+                                           "~B ~e, ~Y")) ")."))
 
 	(div
 	 (@ (class "sheet sheet-padded justify-left"))
diff --git a/website/apps/packages/templates/detailed-package-list.scm b/website/apps/packages/templates/detailed-package-list.scm
index c0a60de..9b23ed1 100644
--- a/website/apps/packages/templates/detailed-package-list.scm
+++ b/website/apps/packages/templates/detailed-package-list.scm
@@ -8,6 +8,7 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:use-module (apps packages templates components)
   #:export (detailed-package-list-t))
 
@@ -20,15 +21,17 @@
 	(total-pages
 	 (number->string (context-datum context "total-pages"))))
     (theme
-     #:title (list (string-append "Page " page-number) letter "Packages")
+     #:title (list (G_ (string-append "Page " page-number ""))
+                   letter (C_ "webpage title" "Packages"))
      #:description
-     "List of packages available through GNU Guix."
+     (G_ "List of packages available through GNU Guix.")
      #:keywords
-     '("GNU" "Linux" "Unix" "Free software" "Libre software"
-       "Operating system" "GNU Hurd" "GNU Guix package manager"
-       "GNU Guile" "Guile Scheme" "Transactional upgrades"
-       "Functional package management" "Reproducibility")
-     #:active-menu-item "Packages"
+     (string-split ;TRANSLATORS: |-separated list of webpage keywords
+      (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile \
+Scheme|Transactional upgrades|Functional package \
+management|Reproducibility") #\|)
+     #:active-menu-item (C_ "website menu" "Packages")
      #:css
      (list (guix-url "static/base/css/page.css")
 	   (guix-url "static/base/css/item-preview.css")
@@ -37,11 +40,11 @@
      #:scripts
      (list (guix-url "static/packages/js/build-status.js"))
      #:crumbs
-     (list (crumb "Packages" (guix-url "packages/"))
+     (list (crumb (C_ "website menu" "Packages") (guix-url "packages/"))
 	   (crumb letter (guix-url (url-path-join "packages"
 						  letter
 						  "")))
-	   (crumb (string-append "Page " page-number)
+           (crumb (G_ (string-append "Page " page-number ""))
 		  (guix-url (url-path-join "packages"
 					   "page"
 					   page-number
@@ -50,7 +53,7 @@
      `(main
        (section
 	(@ (class "page centered-text"))
-	(h2 "Packages — " ,letter
+        (h2 (G_ "Packages — ") ,letter
 	    ,(page-indicator (string->number page-number)
 			     (string->number total-pages)))
 
diff --git a/website/apps/packages/templates/index.scm b/website/apps/packages/templates/index.scm
index afd10d9..aa0a91d 100644
--- a/website/apps/packages/templates/index.scm
+++ b/website/apps/packages/templates/index.scm
@@ -8,6 +8,7 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:use-module (apps packages templates components)
   #:use-module (srfi srfi-19)
   #:export (index-t))
@@ -18,37 +19,43 @@
   (let ((packages (context-datum context "packages"))
 	(total    (context-datum context "total")))
     (theme
-     #:title (list "Packages")
+     #:title (C_ "webpage title" (list "Packages"))
      #:description
-     "List of packages available through GNU Guix."
+     (G_ "List of packages available through GNU Guix.")
      #:keywords
-     (list "GNU" "Linux" "Unix" "Free software" "Libre software"
-	   "Operating system" "GNU Hurd" "GNU Guix package manager"
-	   "GNU Guile" "Guile Scheme" "Transactional upgrades"
-	   "Functional package management" "Reproducibility")
-     #:active-menu-item "Packages"
+     (string-split ;TRANSLATORS: |-separated list of webpage keywords
+      (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile \
+Scheme|Transactional upgrades|Functional package \
+management|Reproducibility") #\|)
+     #:active-menu-item (C_ "website menu" "Packages")
      #:css
      (list (guix-url "static/base/css/page.css")
 	   (guix-url "static/base/css/item-preview.css")
 	   (guix-url "static/packages/css/letter-selector.css"))
      #:crumbs
-     (list (crumb "Packages" (guix-url "packages/")))
+     (list (crumb (C_ "website menu" "Packages") (guix-url "packages/")))
      #:content
      `(main
        (section
 	(@ (class "page centered-text"))
-	(h2 "Packages")
+        ,(G_ `(h2 "Packages"))
 
-	(p
-	 (@ (class "limit-width centered-block"))
-	 "GNU Guix provides " ,(number* total) " packages transparently "
-	 (a (@ (href "https://hydra.gnu.org/jobset/gnu/master#tabs-status"))
-	    "available as pre-built binaries")
-	 ". These pages provide a complete list of the packages.  Our "
-	 (a (@ (href "https://hydra.gnu.org/jobset/gnu/master"))
-	    "continuous integration system")
-	 " shows their current build status "
-	 "(updated " ,(date->string (current-date) "~B ~e, ~Y") ").")
+        ,(G_
+          `(p
+            (@ (class "limit-width centered-block"))
+            "GNU Guix provides " ,(number* total) " packages transparently "
+            ,(G_
+              `(a (@ (href "https://hydra.gnu.org/jobset/gnu/master#tabs-status"))
+                  "available as pre-built binaries"))
+            ". These pages provide a complete list of the packages.  Our "
+            ,(G_
+              `(a (@ (href "https://hydra.gnu.org/jobset/gnu/master"))
+                  "continuous integration system"))
+            " shows their current build status "
+            "(updated " ,(date->string (current-date)
+                                       (C_ "SRFI-19 date->string format"
+                                           "~B ~e, ~Y")) ")."))
 
 	(div
 	 (@ (class "sheet"))
diff --git a/website/apps/packages/templates/package-list.scm b/website/apps/packages/templates/package-list.scm
index e047812..d77ed17 100644
--- a/website/apps/packages/templates/package-list.scm
+++ b/website/apps/packages/templates/package-list.scm
@@ -8,6 +8,7 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:use-module (apps packages templates components)
   #:export (package-list-t))
 
@@ -20,25 +21,27 @@
 	(total-pages
 	 (number->string (context-datum context "total-pages"))))
     (theme
-     #:title (list (string-append "Page " page-number) letter "Packages")
+     #:title (list (G_ (string-append "Page " page-number ""))
+                   letter (C_ "webpage title" "Packages"))
      #:description
      "List of packages available through GNU Guix."
      #:keywords
-     '("GNU" "Linux" "Unix" "Free software" "Libre software"
-       "Operating system" "GNU Hurd" "GNU Guix package manager"
-       "GNU Guile" "Guile Scheme" "Transactional upgrades"
-       "Functional package management" "Reproducibility")
-     #:active-menu-item "Packages"
+     (string-split ;TRANSLATORS: |-separated list of webpage keywords
+      (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile \
+Scheme|Transactional upgrades|Functional package \
+management|Reproducibility") #\|)
+     #:active-menu-item (C_ "website menu" "Packages")
      #:css
      (list (guix-url "static/base/css/page.css")
 	   (guix-url "static/base/css/item-preview.css")
 	   (guix-url "static/packages/css/letter-selector.css"))
      #:crumbs
-     (list (crumb "Packages" (guix-url "packages/"))
+     (list (crumb (C_ "website menu" "Packages") (guix-url "packages/"))
 	   (crumb letter (guix-url (url-path-join "packages"
 						  letter
 						  "")))
-	   (crumb (string-append "Page " page-number)
+           (crumb (G_ (string-append "Page " page-number ""))
 		  (guix-url (url-path-join "packages"
 					   "page"
 					   page-number
@@ -47,7 +50,7 @@
      `(main
        (section
 	(@ (class "page centered-text"))
-	(h2 "Packages — " ,letter
+	(h2 (G_ "Packages — ") ,letter
 	    ,(page-indicator (string->number page-number)
 			     (string->number total-pages)))
 
diff --git a/website/apps/packages/templates/package.scm b/website/apps/packages/templates/package.scm
index 9dfb2fa..814700f 100644
--- a/website/apps/packages/templates/package.scm
+++ b/website/apps/packages/templates/package.scm
@@ -8,6 +8,7 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:use-module (apps packages templates components)
   #:use-module (apps packages types)
   #:use-module (apps packages utils)
@@ -24,19 +25,20 @@
 				    (package-version package)))
 	 (lint-issues (package-lint-issues package)))
     (theme
-     #:title (list package-id "Packages")
+     #:title (C_ "webpage title" (list package-id "Packages"))
      #:description (package-synopsis-shtml package)
      #:keywords
-     '("GNU" "Linux" "Unix" "Free software" "Libre software"
-       "Operating system" "GNU Hurd" "GNU Guix package manager"
-       "GNU Guile" "Guile Scheme" "Transactional upgrades"
-       "Functional package management" "Reproducibility")
-     #:active-menu-item "Packages"
+     (string-split ;TRANSLATORS: |-separated list of webpage keywords
+      (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile \
+Scheme|Transactional upgrades|Functional package \
+management|Reproducibility") #\|)
+     #:active-menu-item (C_ "website menu" "Packages")
      #:css
      (list (guix-url "static/base/css/page.css")
 	   (guix-url "static/packages/css/package.css"))
      #:crumbs
-     (list (crumb "Packages" (guix-url "packages/"))
+     (list (crumb (C_ "website menu" "Packages") (guix-url "packages/"))
 	   (crumb package-id
 		  (guix-url (package-url-path package))))
      #:content
@@ -51,31 +53,35 @@
         ;; 'gnu-package?' might fetch stuff from the network.  Assume #f if
         ;; that doesn't work.
 	(p ,(if (false-if-exception (gnu-package? package))
-                '(it "This is a GNU package.  ")
+                (G_ '(it "This is a GNU package.  "))
                 "")
            ,(package-description-shtml package))
 
 	(ul
 	 (@ (class "package-info"))
-	 (li (b "Website: ")
-	     (a (@ (href ,(package-home-page package)))
-		,(package-home-page package)))
-	 (li (b "License: ")
-	     ,(license->shtml (package-license package)))
-	 (li (b "Package source: ")
-	     ,(location->shtml (package-location package)))
-	 (li (b "Patches: ")
-	     ,(patches->shtml (package-patches package)))
-	 (li (b "Builds: ")
-	     ,(supported-systems->shtml package)))
+         ,(G_ `(li ,(G_ `(b "Website: "))
+                   (a (@ (href ,(package-home-page package)))
+                      ,(package-home-page package))))
+         ,(G_ `(li ,(G_ `(b "License: "))
+                   ,(license->shtml (package-license package))))
+         ,(G_ `(li ,(G_ `(b "Package source: "))
+                   ,(location->shtml (package-location package))))
+         ,(G_ `(li ,(G_ `(b "Patches: "))
+                   ,(patches->shtml (package-patches package))))
+         ,(G_ `(li ,(G_ `(b "Builds: "))
+                   ,(supported-systems->shtml package))))
 
 	;; Lint issues.
 	,(if (null? lint-issues)
 	     ""
-	     `((h3 "Lint issues")
-	       (p
-		,(issue-count->shtml (length lint-issues)) ". "
-		"See " (a (@ (href "#")) "package definition")
-		" in Guix source code.")
+             (G_ `(,(G_ `(h3 "Lint issues"))
+                   ,(G_
+                     `(p
+                       ""
+                       ,(issue-count->shtml
+                         (length lint-issues))
+                       ". "
+                       "See " ,(G_ `(a (@ (href "#")) "package definition"))
+                       " in Guix source code."))
 
-	       ,@(map lint-issue->shtml lint-issues))))))))
+                   ,@(map lint-issue->shtml lint-issues)))))))))
diff --git a/website/po/guix-website.pot b/website/po/guix-website.pot
new file mode 100644
index 0000000..3ed5d51
--- /dev/null
+++ b/website/po/guix-website.pot
@@ -0,0 +1,1209 @@
+# 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: ludo@HIDDEN\n"
+"POT-Creation-Date: 2019-09-06 10:23+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@HIDDEN>\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:18
+msgctxt "webpage title"
+msgid "GNU's advanced distro and transactional package manager"
+msgstr ""
+
+#: apps/base/templates/home.scm:20 apps/base/templates/about.scm:19
+msgid "Guix is an advanced distribution of the GNU operating system.\n   Guix is technology that respects the freedom of computer users.\n   You are free to run the system for any purpose, study how it\n   works, improve it, and share it with the whole world."
+msgstr ""
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/home.scm:26 apps/base/templates/menu.scm:20 apps/base/templates/screenshot.scm:23 apps/blog/templates/post-list.scm:29 apps/blog/templates/tag.scm:33 apps/packages/templates/detailed-index.scm:27 apps/packages/templates/detailed-package-list.scm:30 apps/packages/templates/index.scm:27 apps/packages/templates/package-list.scm:30 apps/packages/templates/package.scm:32
+msgid "GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile Scheme|Transactional upgrades|Functional package management|Reproducibility"
+msgstr ""
+
+#: apps/base/templates/home.scm:30 apps/base/templates/components.scm:343 apps/base/templates/screenshot.scm:27
+msgctxt "website menu"
+msgid "Overview"
+msgstr ""
+
+#: apps/base/templates/home.scm:39
+msgid "Summary"
+msgstr ""
+
+#: apps/base/templates/home.scm:41
+msgid "<1>Liberating.</1> Guix is an advanced distribution of the <2>GNU operating system</2> developed by the <3>GNU Project</3>—which respects the <4>freedom of computer users</4>. "
+msgstr ""
+
+#. TRANSLATORS: Package Management, Features and Using the
+#. Configuration System are section names in the English (en)
+#. manual.
+#: apps/base/templates/home.scm:62
+msgid "<1>Dependable.</1> Guix <2>supports<2.1>en</2.1><2.2>Package-Management.html</2.2></2> transactional upgrades and roll-backs, unprivileged package management, <3>and more<3.1>en</3.1><3.2>Features.html</3.2></3>.  When used as a standalone distribution, Guix supports <4>declarative system configuration<4.1>en</4.1><4.2>Using-the-Configuration-System.html</4.2></4> for transparent and reproducible operating systems."
+msgstr ""
+
+#. TRANSLATORS: Defining Packages and System Configuration are
+#. section names in the English (en) manual.
+#: apps/base/templates/home.scm:82
+msgid "<1>Hackable.</1> It provides <2>Guile Scheme</2> APIs, including high-level embedded domain-specific languages (EDSLs) to <3>define packages<3.1>en</3.1><3.2>Defining-Packages.html</3.2></3> and <4>whole-system configurations<4.1>en</4.1><4.2>System-Configuration.html</4.2></4>."
+msgstr ""
+
+#: apps/base/templates/home.scm:104
+msgctxt "button"
+msgid "DOWNLOAD v<1/>"
+msgstr ""
+
+#: apps/base/templates/home.scm:109
+msgctxt "button"
+msgid "CONTRIBUTE"
+msgstr ""
+
+#: apps/base/templates/home.scm:116
+msgid "Discover Guix"
+msgstr ""
+
+#: apps/base/templates/home.scm:118
+msgid "Guix comes with thousands of packages which include applications, system tools, documentation, fonts, and other digital goods readily available for installing with the <1>GNU Guix</1> package manager."
+msgstr ""
+
+#: apps/base/templates/home.scm:135
+msgctxt "button"
+msgid "ALL PACKAGES"
+msgstr ""
+
+#: apps/base/templates/home.scm:142
+msgid "GNU Guix in your field"
+msgstr ""
+
+#: apps/base/templates/home.scm:144
+msgid "Read some stories about how people are using GNU Guix in\ntheir daily lives."
+msgstr ""
+
+#: apps/base/templates/home.scm:155
+msgctxt "button"
+msgid "SOFTWARE DEVELOPMENT"
+msgstr ""
+
+#: apps/base/templates/home.scm:160
+msgctxt "button"
+msgid "BIOINFORMATICS"
+msgstr ""
+
+#: apps/base/templates/home.scm:165
+msgctxt "button"
+msgid "HIGH PERFORMANCE COMPUTING"
+msgstr ""
+
+#: apps/base/templates/home.scm:170
+msgctxt "button"
+msgid "RESEARCH"
+msgstr ""
+
+#: apps/base/templates/home.scm:175
+msgctxt "button"
+msgid "ALL FIELDS..."
+msgstr ""
+
+#: apps/base/templates/home.scm:182
+msgid "GNU Guix in other GNU/Linux distros"
+msgstr ""
+
+#: apps/base/templates/home.scm:194
+msgid "Video: <1>Demo of Guix in another GNU/Linux distribution<1.1/>https://audio-video.gnu.org/video/misc/2016-07__GNU_Guix_Demo_2.webm</1> (1 minute, 30 seconds)."
+msgstr ""
+
+#: apps/base/templates/home.scm:205
+msgid "If you don't use GNU Guix as a standalone GNU/Linux distribution, you still can use it as a package manager on top of any GNU/Linux distribution. This way, you can benefit from all its conveniences."
+msgstr ""
+
+#: apps/base/templates/home.scm:210
+msgid "Guix won't interfere with the package manager that comes with your distribution. They can live together."
+msgstr ""
+
+#: apps/base/templates/home.scm:217
+msgctxt "button"
+msgid "TRY IT OUT!"
+msgstr ""
+
+#: apps/base/templates/home.scm:224 apps/blog/templates/post-list.scm:49
+msgid "Blog"
+msgstr ""
+
+#: apps/base/templates/home.scm:231
+msgctxt "button"
+msgid "ALL POSTS"
+msgstr ""
+
+#: apps/base/templates/home.scm:237 apps/base/templates/contact.scm:36
+msgid "Contact"
+msgstr ""
+
+#: apps/base/templates/home.scm:244
+msgctxt "button"
+msgid "ALL CONTACT MEDIA"
+msgstr ""
+
+#: apps/base/templates/theme.scm:17 apps/base/templates/components.scm:350 apps/base/templates/about.scm:27 apps/base/templates/about.scm:30 apps/base/templates/contact.scm:26 apps/base/templates/contribute.scm:26 apps/base/templates/graphics.scm:24 apps/base/templates/security.scm:28
+msgctxt "website menu"
+msgid "About"
+msgstr ""
+
+#: apps/base/templates/theme.scm:73 apps/base/templates/theme.scm:75
+msgctxt "webpage title"
+msgid "GNU Guix"
+msgstr ""
+
+#: apps/base/templates/theme.scm:97
+msgctxt "webpage title"
+msgid "GNU Guix — Activity Feed"
+msgstr ""
+
+#: apps/base/templates/theme.scm:114
+msgid "Made with <1>♥</1> by humans and powered by <2>GNU Guile</2>.  <3>Source code</3> under the <4>GNU AGPL</4>."
+msgstr ""
+
+#: apps/base/templates/components.scm:48
+msgid "Your location:"
+msgstr ""
+
+#: apps/base/templates/components.scm:50
+msgid "Home"
+msgstr ""
+
+#: apps/base/templates/components.scm:153
+msgid "archive"
+msgstr ""
+
+#: apps/base/templates/components.scm:337
+msgctxt "website menu"
+msgid "Guix"
+msgstr ""
+
+#: apps/base/templates/components.scm:341
+msgid "website menu:"
+msgstr ""
+
+#: apps/base/templates/components.scm:344 apps/download/templates/download.scm:42 apps/download/templates/download.scm:46 apps/download/templates/download.scm:42 apps/download/templates/download.scm:46
+msgctxt "website menu"
+msgid "Download"
+msgstr ""
+
+#: apps/base/templates/components.scm:345 apps/packages/templates/detailed-index.scm:31 apps/packages/templates/detailed-index.scm:38 apps/packages/templates/detailed-package-list.scm:34 apps/packages/templates/detailed-package-list.scm:43 apps/packages/templates/index.scm:31 apps/packages/templates/index.scm:37 apps/packages/templates/package-list.scm:34 apps/packages/templates/package-list.scm:40 apps/packages/templates/package.scm:36 apps/packages/templates/package.scm:41
+msgctxt "website menu"
+msgid "Packages"
+msgstr ""
+
+#: apps/base/templates/components.scm:346 apps/blog/templates/post-list.scm:33 apps/blog/templates/post-list.scm:39 apps/blog/templates/post.scm:29 apps/blog/templates/post.scm:35 apps/blog/templates/tag.scm:37 apps/blog/templates/tag.scm:43
+msgctxt "website menu"
+msgid "Blog"
+msgstr ""
+
+#: apps/base/templates/components.scm:347 apps/base/templates/help.scm:26 apps/base/templates/help.scm:30
+msgctxt "website menu"
+msgid "Help"
+msgstr ""
+
+#: apps/base/templates/components.scm:348 apps/base/templates/donate.scm:26 apps/base/templates/donate.scm:29
+msgctxt "website menu"
+msgid "Donate"
+msgstr ""
+
+#: apps/base/templates/components.scm:353 apps/base/templates/contact.scm:31
+msgctxt "website menu"
+msgid "Contact"
+msgstr ""
+
+#: apps/base/templates/components.scm:354 apps/base/templates/contribute.scm:30
+msgctxt "website menu"
+msgid "Contribute"
+msgstr ""
+
+#: apps/base/templates/components.scm:355 apps/base/templates/security.scm:31
+msgctxt "website menu"
+msgid "Security"
+msgstr ""
+
+#: apps/base/templates/components.scm:356 apps/base/templates/graphics.scm:27
+msgctxt "website menu"
+msgid "Graphics"
+msgstr ""
+
+#: apps/base/templates/components.scm:374
+msgid " (Page <1/> of <2/>)"
+msgstr ""
+
+#: apps/base/templates/components.scm:398
+msgid "Page <1/> of <2/>. Go to another page: "
+msgstr ""
+
+#: apps/base/templates/about.scm:17
+msgctxt "webpage title"
+msgid "About"
+msgstr ""
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/about.scm:25
+msgid "GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU Guix package manager"
+msgstr ""
+
+#: apps/base/templates/about.scm:35
+msgid "About the Project"
+msgstr ""
+
+#: apps/base/templates/about.scm:37
+msgid "The <1>GNU Guix</1> package and system manager is a <2>free software</2> project developed by volunteers around the world under the\n            umbrella of the <3>GNU Project</3>. "
+msgstr ""
+
+#: apps/base/templates/about.scm:46
+msgid "Guix System is an advanced distribution of the <1>GNU operating system</1>.  It uses the <2>Linux-libre</2> kernel, and support for <3>the Hurd</3> is being worked on.  As a GNU distribution, it is committed\n            to respecting and enhancing <4>the freedom of its users</4>.  As such, it adheres to the <5>GNU Free System Distribution Guidelines</5>."
+msgstr ""
+
+#. TRANSLATORS: Features and Defining Packages are section names
+#. in the English (en) manual.
+#: apps/base/templates/about.scm:64
+msgid "GNU Guix provides <1>state-of-the-art package management features<1.1>en</1.1><1.2>Features.html</1.2></1> such as transactional upgrades and roll-backs, reproducible\n            build environments, unprivileged package management, and\n            per-user profiles.  It uses low-level mechanisms from the <2>Nix</2> package manager, but packages are <3>defined<3.1>en</3.1><3.2>Defining-Packages.html</3.2></3> as native <4>Guile</4> modules, using extensions to the <5>Scheme</5> language—which makes it nicely hackable."
+msgstr ""
+
+#. TRANSLATORS: Using the Configuration System, Initial RAM Disk
+#. and Defining Services are section names in the English (en)
+#. manual.
+#: apps/base/templates/about.scm:85
+msgid "Guix takes that a step further by additionally supporting stateless,\n           reproducible <1>operating system configurations<1.1>en</1.1><1.2>Using-the-Configuration-System.html</1.2></1>. This time the whole system is hackable in Scheme, from the <2>initial RAM disk<2.1>en</2.1><2.2>Initial-RAM-Disk.html</2.2></2> to the <3>initialization system</3>, and to the <4>system services<4.1>en</4.1><4.2>Defining-Services.html</4.2></4>."
+msgstr ""
+
+#: apps/base/templates/about.scm:106
+msgid "Maintainer"
+msgstr ""
+
+#: apps/base/templates/about.scm:108
+msgid "Guix is currently maintained by Ludovic Courtès and Ricardo\n          Wurmus.  Please use the <1>mailing lists</1> for contact. "
+msgstr ""
+
+#: apps/base/templates/about.scm:116
+msgid "Licensing"
+msgstr ""
+
+#: apps/base/templates/about.scm:118
+msgid "Guix is free software; you can redistribute it and/or modify\n          it under the terms of the <1>GNU General Public License</1> as published by the Free Software Foundation; either\n          version 3 of the License, or (at your option) any later\n          version. "
+msgstr ""
+
+#: apps/base/data.scm:25
+msgid "IRC Channel"
+msgstr ""
+
+#: apps/base/data.scm:27
+msgid "Join the <1/> channel on the Freenode IRC network to chat\n       with the community about GNU Guix or to get help in\n       real-time."
+msgstr ""
+
+#: apps/base/data.scm:36
+msgid "Info Mailing List"
+msgstr ""
+
+#: apps/base/data.scm:38
+msgid "Subscribe to the <1/> low-traffic mailing\nlist to receive important announcements sent by the project maintainers (in\nEnglish)."
+msgstr ""
+
+#: apps/base/data.scm:47
+msgid "Help Mailing List"
+msgstr ""
+
+#: apps/base/data.scm:52
+msgid "Subscribe to the Help mailing list to get support\nfrom the GNU Guix community via email.  You can post messages in English\nthough we also accept other languages."
+msgstr ""
+
+#: apps/base/data.scm:56
+msgctxt "unique lingua code like en or zh-cn"
+msgid "en"
+msgstr ""
+
+#: apps/base/data.scm:127
+msgid "Bug Reporting"
+msgstr ""
+
+#: apps/base/data.scm:129
+msgid "If you found a bug in Guix, check whether the bug is\n       already in the <1>bug database</1>. If it is not, please <2>report it.</2>"
+msgstr ""
+
+#: apps/base/data.scm:141
+msgid "Development Mailing List"
+msgstr ""
+
+#: apps/base/data.scm:143
+msgid "Discussion about the development of GNU Guix. <1> Until July 2013</1>, the bug-Guix mailing list filled that role. "
+msgstr ""
+
+#: apps/base/data.scm:153
+msgid "Patches Mailing List"
+msgstr ""
+
+#: apps/base/data.scm:155
+msgid "Submission of patches.  Every message sent to this mailing list\n       leads to a new entry in our <1>patch tracking tool</1>.  See <2>this page</2> for more information on how to use it; see <3>the manual<3.1>en</3.1><3.2>Submitting-Patches.html</3.2></3> for more information on how to submit a patch.  <4>Until February 2017</4>, the guix-devel mailing list filled that role."
+msgstr ""
+
+#: apps/base/data.scm:174
+msgid "Commits Mailing List"
+msgstr ""
+
+#: apps/base/data.scm:176
+msgid "Notifications of commits made to the <1>Git repositories</1>."
+msgstr ""
+
+#: apps/base/data.scm:185
+msgid "Security Mailing List"
+msgstr ""
+
+#: apps/base/data.scm:187
+msgid "This is a private mailing list that anyone can post to to <1>report security issues</1> in Guix itself or in the <2>packages</2> it provides.  Posting here allows Guix developers to address\n       the problem before it is widely publicized."
+msgstr ""
+
+#: apps/base/data.scm:199
+msgid "Sysadmin Mailing List"
+msgstr ""
+
+#: apps/base/data.scm:201
+msgid "Private mailing list for the <1>build farm</1> system administration."
+msgstr ""
+
+#: apps/base/data.scm:213
+msgid "GNU System Discuss Mailing List"
+msgstr ""
+
+#: apps/base/data.scm:215
+msgid "Discussion about the development of the broader GNU system."
+msgstr ""
+
+#: apps/base/data.scm:220
+msgid "GNU/Linux-libre Mailing List"
+msgstr ""
+
+#: apps/base/data.scm:222
+msgid "Workgroup for fully free GNU/Linux distributions."
+msgstr ""
+
+#: apps/base/data.scm:227
+msgid "GNU Info Mailing List"
+msgstr ""
+
+#: apps/base/data.scm:229
+msgid "GNU software announcements."
+msgstr ""
+
+#: apps/base/data.scm:238
+msgctxt "screenshot title"
+msgid "Graphical log-in"
+msgstr ""
+
+#: apps/base/data.scm:242
+msgid "Graphical log-in screen"
+msgstr ""
+
+#: apps/base/data.scm:245
+msgctxt "screenshot title"
+msgid "GNOME"
+msgstr ""
+
+#: apps/base/data.scm:249
+msgid "Control your computer with the GNOME desktop environment"
+msgstr ""
+
+#: apps/base/data.scm:252
+msgctxt "screenshot title"
+msgid "Xfce"
+msgstr ""
+
+#: apps/base/data.scm:256
+msgid "The Xfce desktop environment with GNU Emacs and IceCat"
+msgstr ""
+
+#: apps/base/data.scm:259
+msgctxt "screenshot title"
+msgid "Virtual machine"
+msgstr ""
+
+#: apps/base/data.scm:263
+msgid "Virtual machine started with 'guix system vm'"
+msgstr ""
+
+#: apps/base/data.scm:266
+msgctxt "screenshot title"
+msgid "Enlightenment"
+msgstr ""
+
+#: apps/base/data.scm:270
+msgid "Enlightenment, Inkscape, and Serbian text"
+msgstr ""
+
+#: apps/base/templates/help.scm:17
+msgctxt "webpage title"
+msgid "Help"
+msgstr ""
+
+#: apps/base/templates/help.scm:19
+msgid "A list of resources about how to use GNU Guix, plus\n   information about getting help from the community of users and\n   developers."
+msgstr ""
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/help.scm:24
+msgid "GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU Guix package manager|Help resources"
+msgstr ""
+
+#: apps/base/templates/help.scm:35
+msgid "Help"
+msgstr ""
+
+#: apps/base/templates/help.scm:46
+msgid "GNU Guix Manual"
+msgstr ""
+
+#: apps/base/templates/help.scm:47
+msgid "Documentation for GNU Guix is available\n            online.  You may also find more information about Guix by running <1>info guix</1>."
+msgstr ""
+
+#: apps/base/templates/help.scm:53
+msgid "Read Guix manual"
+msgstr ""
+
+#: apps/base/templates/help.scm:64
+msgid "Get Guix reference card"
+msgstr ""
+
+#: apps/base/templates/help.scm:74
+msgid "GNU Manuals"
+msgstr ""
+
+#: apps/base/templates/help.scm:75
+msgid "Guix is a distribution of the <1>GNU operating system</1>.  Documentation for GNU packages is\n            available online in various formats. "
+msgstr ""
+
+#: apps/base/templates/help.scm:83
+msgid "Browse GNU manuals"
+msgstr ""
+
+#: apps/base/templates/help.scm:91
+msgid "IRC Chat"
+msgstr ""
+
+#: apps/base/templates/help.scm:92
+msgid "For real-time support from the community, you can connect\n            to the <1/> channel on irc.freenode.net. There\n            you can get help about anything related to GNU Guix."
+msgstr ""
+
+#: apps/base/templates/help.scm:97
+msgid "The <1/> channel is logged. Previous\n            conversations can be browsed online. See the <2>channel logs</2>. "
+msgstr ""
+
+#: apps/base/templates/help.scm:104
+msgid "Connect"
+msgstr ""
+
+#: apps/base/templates/help.scm:112
+msgid "Mailing lists"
+msgstr ""
+
+#: apps/base/templates/help.scm:113
+msgid "Email support from the community is also available through\n            several mailing list. The messages sent to the lists are\n            public and archived online."
+msgstr ""
+
+#: apps/base/templates/help.scm:121
+msgid "See all lists"
+msgstr ""
+
+#: apps/base/templates/contact.scm:17 apps/base/templates/irc.scm:18 apps/base/templates/irc.scm:29
+msgctxt "webpage title"
+msgid "Contact"
+msgstr ""
+
+#: apps/base/templates/contact.scm:19
+msgid "A list of channels to communicate with GNU Guix users\n   and developers about anything you want."
+msgstr ""
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/contact.scm:23
+msgid "GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU Guix package manager|Community|Mailing lists|IRC channels|Bug reports|Help"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:17
+msgctxt "webpage title"
+msgid "Contribute"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:19
+msgid "Check all the ways you can contribute to make GNU Guix\n   better, and join the world-wide community of volunteers."
+msgstr ""
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/contribute.scm:23
+msgid "GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU Guix package manager|Volunteer|Development|Translation|I18N|L10N|Artwork"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:35 apps/base/templates/contribute.scm:110 apps/base/templates/contribute.scm:227
+msgid "Contribute"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:37
+msgid "GNU Guix is a large project developed\n           mostly by volunteers from all around the world. You are welcome\n           to join us in the <1>development mailing list</1> or in the <2>#guix channel</2> in IRC Freenode. Tell us how would you like to help, and we\n          will do our best to guide you. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:51
+msgid "We want to provide a warm, friendly, and harassment-free environment,\n           so that anyone can contribute to the best of their abilities.  To\n           this end our project uses a “Contributor Covenant”, which was adapted\n           from <1>https://contributor-covenant.org/</1>.  You can find the full pledge in the <2>CODE-OF-CONDUCT</2> file."
+msgstr ""
+
+#: apps/base/templates/contribute.scm:72
+msgid "Project Management"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:73
+msgid "We use <1>Savannah</1> as the central point for development, maintenance and\n            distribution of the Guix System Distribution and GNU Guix."
+msgstr ""
+
+#: apps/base/templates/contribute.scm:79
+msgid "The source files for all the components of the project,\n            including software, web site, documentation, and artwork, are\n            available in <1>Git repositories</1> at Savannah. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:89
+msgid "Access Savannah"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:94
+msgid "Art"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:95
+msgid "We are always looking for artists to help us design and\n            improve user interfaces, and create multimedia material for\n            documentation, presentations, and promotional items. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:100
+msgid "The artwork used in the different components of the project\n            is available in the <1>guix-artwork</1> repository. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:116
+msgid "Documentation"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:117
+msgid "You can read the <1>project documentation</1> already available in the system and in the website, and\n            help us identify any errors or omissions. Creating new\n            manuals, tutorials, and blog entries will also help users and\n            developers discover what we do. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:125
+msgid "Helping improve the documentation of the <1>packaged software</1> is another way to contribute. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:132
+msgid "Start writing"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:138 apps/packages/templates/detailed-index.scm:43 apps/packages/templates/index.scm:42
+msgid "Packages"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:139
+msgid "Hundreds of software, documentation, and assets need to be\n            packaged to make it easier for users to install their\n            favorite tools with the Guix package manager, and be\n            productive using the system. "
+msgstr ""
+
+#. TRANSLATORS: Packaging Guidelines is a section name in the
+#. English (en) manual.
+#: apps/base/templates/contribute.scm:147
+msgid "Information on how to add packages to the distribution can\n            be found <1>in the manual<1.1>en</1.1><1.2>Packaging-Guidelines.html</1.2></1>. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:157
+msgid "Check out the <1>package database</1> for a list of available packages, and the <2>patch-tracking database</2> for a list of pending submissions."
+msgstr ""
+
+#: apps/base/templates/contribute.scm:168
+msgid "Send a new package"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:174
+msgid "Programming"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:175
+msgid "Source code is in the <1>main Git repository</1>.  We use <2>GNU Guile</2> as the main programming and extension language for the\n            components of the system. "
+msgstr ""
+
+#. TRANSLATORS: Contributing is a section name in the English
+#. (en) manual.
+#: apps/base/templates/contribute.scm:187
+msgid "You will find it useful to browse the <1>Guile manual</1> or other <2>introductory material about Scheme</2>. Also, make sure to read the <3>Contributing<3.1>en</3.1><3.2>Contributing.html</3.2></3> section of the manual for more details on the development\n            setup, as well as the coding and cooperation conventions used\n            in the project. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:205
+msgid "Send a patch"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:211
+msgid "System Administration"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:212
+msgid "Our system infrastructure makes it possible for all the\n            contributors to communicate and collaborate in the project,\n            and users to be able to download and install packages. Help\n            us keep the system up and running smoothly. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:218
+msgid "You can also <1>donate hardware or hosting</1> for our <2>build farm</2>.  "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:233
+msgid "Test and Bug Reports"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:234
+msgid "Install the software and send feedback to the community\n            about your experience. Help the project by reporting bugs."
+msgstr ""
+
+#: apps/base/templates/contribute.scm:238
+msgid "Before reporting a bug, please check whether the bug is\n            already <1>in the bug database</1>. See <2>the developer information page</2> for more information on how to manipulate bug reports. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:250
+msgid "Report a bug"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:256
+msgid "Translation"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:257
+msgid "You can help translate the <1>software</1>, the <2>package descriptions</2>, and the <3>manual</3> into your language.  See the <4>Translation Project</4> for information on how you can help."
+msgstr ""
+
+#: apps/base/templates/contribute.scm:276
+msgid "<1>Software packages</1> provided by the system may have their own translation\n            tools.  Visit their websites and help translate. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:283
+msgid "Start translating"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:287
+msgid "Other resources for contributors"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:288
+msgid "Documents, supporting material of previous talks, and\n          auxiliary information useful to hackers and maintainers is\n          available at <1/>."
+msgstr ""
+
+#: apps/base/templates/donate.scm:17
+msgctxt "webpage title"
+msgid "Donate"
+msgstr ""
+
+#: apps/base/templates/donate.scm:19
+msgid "We are looking for donations of hardware and optionally\n   hosting for machines (they should be usable with exclusively\n   free software)."
+msgstr ""
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/donate.scm:24
+msgid "GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU Guix package manager|Donations"
+msgstr ""
+
+#: apps/base/templates/donate.scm:34
+msgid "Donate"
+msgstr ""
+
+#: apps/base/templates/donate.scm:36
+msgid "The <1>build farm</1> of the Guix System Distribution runs on donated hardware and hosting. As the distribution grows (see the <2>package list</2>), so do the computing and storage needs."
+msgstr ""
+
+#: apps/base/templates/donate.scm:47
+msgid "We have <1>started a fundraising campaign</1> to strengthen our build farm, with <2>support from the Free Software Foundation (FSF)</2>.  Please consider helping out by making a donation on this\n          FSF-hosted page:"
+msgstr ""
+
+#: apps/base/templates/donate.scm:63
+msgctxt "button"
+msgid "♥ DONATE!"
+msgstr ""
+
+#: apps/base/templates/donate.scm:66
+msgid "Hardware and Hosting"
+msgstr ""
+
+#: apps/base/templates/donate.scm:71
+msgid "We are also looking for donations of hardware and optionally\n           hosting for the following kinds of machines (they should be\n           usable with exclusively free software): "
+msgstr ""
+
+#: apps/base/templates/donate.scm:78
+msgid "x86_64 machines, with on the order of 1 TiB of storage\n               and 4 GiB of RAM;"
+msgstr ""
+
+#: apps/base/templates/donate.scm:81
+msgid "armv7 machines (such as the Novena) to more quickly test\n               and provide binaries for the armhf-linux port;"
+msgstr ""
+
+#: apps/base/templates/donate.scm:84
+msgid "mips64el machines to strengthen this port."
+msgstr ""
+
+#: apps/base/templates/donate.scm:87
+msgid "Please get in touch with us through the <1>usual channels</1> or using the <2/> private alias to\n           discuss any opportunities. "
+msgstr ""
+
+#: apps/base/templates/donate.scm:95
+msgid "Thanks to the donors!"
+msgstr ""
+
+#: apps/base/templates/donate.scm:100
+msgid "The table below summarizes hardware and hosting donations that\n           make the <1>build farm</1> for the Guix System Distribution a reality."
+msgstr ""
+
+#: apps/base/templates/donate.scm:110
+msgid "<1>machine</1><2>system</2><3>donors</3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:114
+msgid "<1>hydra.gnu.org</1><2>build farm front-end</2><3>Free Software Foundation</3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:124
+msgid "<1>berlin.guixsd.org</1><2>build farm with 25 build nodes for x86_64-linux and\ni686-linux, and dedicated storage</2><3><3.1>Max Delbrück Center for Molecular Medicine</3.1> (hardware and hosting)</3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:136
+msgid "<1>overdrive1.guixsd.org</1><2>aarch64-linux</2><3><3.1>ARM Holdings</3.1></3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:146
+msgid "<1>bayfront.guixsd.org</1><2>new build farm front-end (WIP)</2><3>Igalia</3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:158
+msgid "<1>hydra.gnunet.org</1><2>x86_64-linux, i686-linux</2><3><3.1>Free Secure Network Systems Group</3.1> at the <3.2>Technische Universität München</3.2></3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:171
+msgid "<1>chapters.gnu.org</1><2>x86_64-linux, i686-linux</2><3><3.1><3.1.1>GNU España</3.1.1> (hardware)</3.1><3.2><3.2.1>FSF France</3.2.1> (hosting)</3.2></3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:186
+msgid "<1>librenote</1><2>mips64el-linux</2><3><3.1>Daniel Clark (hardware)</3.1><3.2>Mark H Weaver (hosting)</3.2></3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:195
+msgid "<1>hydra-slave0</1><2>mips64el-linux</2><3>Free Software Foundation</3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:205
+msgid "<1>guix.sjd.se</1><2>x86_64-linux, i686-linux</2><3>Simon Josefsson</3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:215
+msgid "<1>x15.sjd.se</1><2>armhf-linux</2><3>Simon Josefsson</3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:225
+msgid "<1>hydra-slave1</1><2>armhf-linux</2><3><3.1>Steve Sprang (hardware)</3.1><3.2>Mark H Weaver (hosting)</3.2></3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:235
+msgid "<1>hydra-slave2</1><2>armhf-linux</2><3><3.1><3.1.1>Harmon Instruments</3.1.1> (hardware)</3.1><3.2>Mark H Weaver (hosting)</3.2></3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:248
+msgid "<1>hydra-slave3</1><2>armhf-linux</2><3><3.1><3.1.1>Kosagi (Sutajio Ko-Usagi Pte Ltd)</3.1.1> (hardware)</3.1><3.2>Mark H Weaver (hosting)</3.2></3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:261
+msgid "<1>redhill</1><2>armhf-linux</2><3><3.1><3.1.1>Kosagi (Sutajio Ko-Usagi Pte Ltd)</3.1.1> (hardware)</3.1><3.2>Andreas Enge (hosting)</3.2></3>"
+msgstr ""
+
+#: apps/base/templates/graphics.scm:16
+msgctxt "webpage title"
+msgid "Graphics"
+msgstr ""
+
+#: apps/base/templates/graphics.scm:18
+msgid "Information about images used for the graphical identity\n   of GNU Guix and Guix System (formerly “GuixSD”)."
+msgstr ""
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/graphics.scm:22
+msgid "GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU Guix package manager|Donations|Branding|Logo"
+msgstr ""
+
+#: apps/base/templates/graphics.scm:32
+msgid "Graphics"
+msgstr ""
+
+#: apps/base/templates/graphics.scm:34
+msgid "For questions regarding the graphics listed in this page,\n          please contact <1>help-guix@HIDDEN</1>."
+msgstr ""
+
+#: apps/base/templates/graphics.scm:44
+msgid "GNU Guix logotype"
+msgstr ""
+
+#: apps/base/templates/graphics.scm:45
+msgid "The standalone Guix, formerly known as the “Guix System\n          Distribution” or GuixSD, had its own logo, which is now\n          deprecated."
+msgstr ""
+
+#: apps/base/templates/graphics.scm:51
+msgid "The GNU Guix and GuixSD\n          logotypes were designed by Luis Felipe López Acevedo\n          (a.k.a. sirgazil).  They are available under the following\n          terms:"
+msgstr ""
+
+#: apps/base/templates/graphics.scm:65
+msgid "The source files (SVG) for these logotypes, their variants, and\n          other artwork used in the different components of the GNU Guix\n          project are available in the <1>guix-artwork</1> repository, including the previous GNU Guix logotype designed\n          by Nikita Karetnikov in 2013 and <2>superseded</2> by the golden GNU in 2016."
+msgstr ""
+
+#: apps/base/templates/irc.scm:17 apps/base/templates/irc.scm:30
+msgctxt "webpage title"
+msgid "IRC"
+msgstr ""
+
+#: apps/base/templates/irc.scm:20
+msgid "Internet relay chat."
+msgstr ""
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/irc.scm:23
+msgid "GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU Guix package manager|IRC|chat"
+msgstr ""
+
+#: apps/base/templates/irc.scm:35
+msgid "IRC"
+msgstr ""
+
+#: apps/base/templates/irc.scm:37
+msgid "Join the <1/> channel on the <2>Freenode IRC network</2> to chat with the GNU Guix community or to get help\n          in real-time. You can use the chat widget below, or just use\n          the <3>IRC client</3> of your preference. Note that the conversations that happen\n          on the <4/> channel are logged (<5>browse the log</5>)."
+msgstr ""
+
+#: apps/base/templates/menu.scm:16
+msgctxt "webpage title"
+msgid "Menu"
+msgstr ""
+
+#: apps/base/templates/menu.scm:17
+msgid "Website menu."
+msgstr ""
+
+#: apps/base/templates/menu.scm:24
+msgctxt "website menu"
+msgid "Menu"
+msgstr ""
+
+#: apps/base/templates/screenshot.scm:19
+msgctxt "webpage title"
+msgid "Screenshots"
+msgstr ""
+
+#: apps/base/templates/security.scm:19
+msgctxt "webpage title"
+msgid "Security"
+msgstr ""
+
+#: apps/base/templates/security.scm:21
+msgid "Important information about getting security updates\n   for your GNU Guix installation, and instructions on how\n   to report security issues."
+msgstr ""
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/security.scm:26
+msgid "GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU Guix package manager|Security updates"
+msgstr ""
+
+#: apps/base/templates/security.scm:36
+msgid "Security"
+msgstr ""
+
+#: apps/base/templates/security.scm:38
+msgid "How to report security issues"
+msgstr ""
+
+#: apps/base/templates/security.scm:39
+msgid "To report sensitive security issues in Guix itself or the\n           packages it provides, you can write to the private mailing list <1/>.  This list is monitored by a\n           small team of Guix developers."
+msgstr ""
+
+#: apps/base/templates/security.scm:46
+msgid "If you prefer to send your report using OpenPGP encrypted email,\n           please send it to one of the following Guix developers using their\n           respective OpenPGP key:"
+msgstr ""
+
+#: apps/base/templates/security.scm:65
+msgid "Release signatures"
+msgstr ""
+
+#: apps/base/templates/security.scm:66
+msgid "Releases of Guix are signed using the OpenPGP key with the fingerprint <1/>.  Users should <2>verify<2.1>en</2.1><2.2>Binary-Installation.html</2.2></2> their downloads before extracting or running them."
+msgstr ""
+
+#: apps/base/templates/security.scm:78
+msgid "Security updates"
+msgstr ""
+
+#: apps/base/templates/security.scm:79
+msgid "When security vulnerabilities are found in Guix or the packages provided by Guix, we will provide <1>security updates<1.1>en</1.1><1.2>Security-Updates.html</1.2></1> quickly and with minimal disruption for users."
+msgstr ""
+
+#: apps/base/templates/security.scm:87
+msgid "Guix uses a “rolling release” model.  All security bug-fixes are pushed directly to the master branch.  There is no “stable” branch that only receives security fixes."
+msgstr ""
+
+#: apps/download/data.scm:20 apps/download/data.scm:20
+msgctxt "download page title"
+msgid "GNU Guix System <1/>"
+msgstr ""
+
+#: apps/download/data.scm:23 apps/download/data.scm:23
+msgid "USB/DVD ISO installer of the standalone Guix System."
+msgstr ""
+
+#. TRANSLATORS: System installation is a section name in the
+#. English (en) manual.
+#. TRANSLATORS: System installation is a section name in the
+#. English (en) manual.
+#: apps/download/data.scm:31 apps/download/data.scm:31
+msgid "<1>en</1>System-Installation.html"
+msgstr ""
+
+#: apps/download/data.scm:35 apps/download/data.scm:35
+msgctxt "download page title"
+msgid "GNU Guix <1/> QEMU Image"
+msgstr ""
+
+#: apps/download/data.scm:38 apps/download/data.scm:38
+msgid "QCOW2 virtual machine (VM) image."
+msgstr ""
+
+#. TRANSLATORS: Running Guix in a VM is a section name in the
+#. English (en) manual.
+#. TRANSLATORS: Running Guix in a VM is a section name in the
+#. English (en) manual.
+#: apps/download/data.scm:45 apps/download/data.scm:45
+msgid "<1>en</1>Running-Guix-in-a-VM.html"
+msgstr ""
+
+#: apps/download/data.scm:49 apps/download/data.scm:49
+msgctxt "download page title"
+msgid "GNU Guix <1/> Binary"
+msgstr ""
+
+#: apps/download/data.scm:51 apps/download/data.scm:51
+msgid "Self-contained tarball providing binaries for Guix and its\n       dependencies, to be installed on top of your Linux-based system."
+msgstr ""
+
+#. TRANSLATORS: Binary Installation is a section name in the
+#. English (en) manual.
+#. TRANSLATORS: Binary Installation is a section name in the
+#. English (en) manual.
+#: apps/download/data.scm:64 apps/download/data.scm:64
+msgid "<1>en</1>Binary-Installation.html"
+msgstr ""
+
+#: apps/download/data.scm:68 apps/download/data.scm:68
+msgctxt "download page title"
+msgid "GNU Guix <1/> Source"
+msgstr ""
+
+#: apps/download/data.scm:69 apps/download/data.scm:69
+msgid "Source code distribution."
+msgstr ""
+
+#. TRANSLATORS: Requirements is a section name in the English (en)
+#. manual.
+#. TRANSLATORS: Requirements is a section name in the English (en)
+#. manual.
+#: apps/download/data.scm:76 apps/download/data.scm:76
+msgid "<1>en</1>Requirements.html"
+msgstr ""
+
+#: apps/download/templates/components.scm:25 apps/download/templates/components.scm:25
+msgid "Download options:"
+msgstr ""
+
+#: apps/download/templates/components.scm:38 apps/download/templates/components.scm:38
+msgid "Signatures: "
+msgstr ""
+
+#: apps/download/templates/components.scm:50 apps/download/templates/components.scm:50
+msgid "<1>Installation instructions</1>."
+msgstr ""
+
+#: apps/download/templates/download.scm:33 apps/download/templates/download.scm:33
+msgctxt "webpage title"
+msgid "Download"
+msgstr ""
+
+#: apps/download/templates/download.scm:35 apps/download/templates/download.scm:35
+msgid "Installers and source files for GNU Guix.  GNU Guix can be\n   installed on different GNU/Linux distributions."
+msgstr ""
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/download/templates/download.scm:39 apps/download/templates/download.scm:39
+msgid "GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU Guix package manager|Installer|Source code|Package manager"
+msgstr ""
+
+#: apps/download/templates/download.scm:51 apps/download/templates/download.scm:51
+msgid "Download"
+msgstr ""
+
+#: apps/download/templates/download.scm:53 apps/download/templates/download.scm:53
+msgid "As of version <1/>, the standalone Guix System <2>can be installed</2> on an i686, x86_64, ARMv7, or AArch64 machine.  It uses the <3>Linux-Libre</3> kernel and the <4>GNU Shepherd</4> init system. Alternately, GNU Guix\n          can be installed as an additional package manager on top of an\n          installed Linux-based system."
+msgstr ""
+
+#: apps/download/templates/download.scm:73 apps/download/templates/download.scm:73
+msgid "Source code and binaries for the Guix System distribution ISO\n          image as well as GNU Guix can be found on the GNU servers at <1/>.  Older releases can still be found on <2/>."
+msgstr ""
+
+#: apps/blog/templates/components.scm:33 apps/blog/templates/post.scm:46
+msgctxt "SRFI-19 date->string format"
+msgid "~B ~e, ~Y"
+msgstr ""
+
+#: apps/blog/templates/components.scm:37
+msgctxt "blog post summary ellipsis"
+msgid "…"
+msgstr ""
+
+#: apps/blog/templates/components.scm:48
+msgid "Blog menu: "
+msgstr ""
+
+#: apps/blog/templates/components.scm:53
+msgid "Get topic updates"
+msgstr ""
+
+#: apps/blog/templates/components.scm:54
+msgid "Get blog updates"
+msgstr ""
+
+#: apps/blog/templates/components.scm:66
+msgctxt "button"
+msgid "Atom feed"
+msgstr ""
+
+#: apps/blog/templates/components.scm:68
+msgid "Posts by topic"
+msgstr ""
+
+#: apps/blog/templates/feed.scm:32
+msgctxt "feed author name"
+msgid "GNU Guix"
+msgstr ""
+
+#: apps/blog/templates/post-list.scm:23 apps/blog/templates/post-list.scm:40 apps/blog/templates/tag.scm:25 apps/blog/templates/tag.scm:45 apps/packages/templates/detailed-package-list.scm:24 apps/packages/templates/detailed-package-list.scm:47 apps/packages/templates/package-list.scm:24 apps/packages/templates/package-list.scm:44
+msgid "Page <1/>"
+msgstr ""
+
+#: apps/blog/templates/post-list.scm:24 apps/blog/templates/post.scm:25 apps/blog/templates/tag.scm:26
+msgctxt "webpage title"
+msgid "Blog"
+msgstr ""
+
+#: apps/blog/templates/post-list.scm:26 apps/blog/templates/post.scm:27
+msgid "Blog posts about GNU Guix."
+msgstr ""
+
+#: apps/blog/templates/post.scm:52
+msgid "Related topics:"
+msgstr ""
+
+#: apps/blog/templates/tag.scm:28
+msgid "Blog posts about <1/> on GNU Guix."
+msgstr ""
+
+#: apps/blog/templates/tag.scm:54
+msgid "Blog — "
+msgstr ""
+
+#: apps/packages/templates/components.scm:59 apps/packages/templates/package.scm:56
+msgid "This is a GNU package.  "
+msgstr ""
+
+#: apps/packages/templates/components.scm:66
+msgid "<1>License:</1> <2/>."
+msgstr ""
+
+#: apps/packages/templates/components.scm:70
+msgid "<1>Website:</1> <2/>."
+msgstr ""
+
+#: apps/packages/templates/components.scm:74
+msgid "<1>Package source:</1> <2/>."
+msgstr ""
+
+#: apps/packages/templates/components.scm:78
+msgid "<1>Patches:</1> <2/>."
+msgstr ""
+
+#: apps/packages/templates/components.scm:82
+msgid "<1>Lint issues:</1> <2/>."
+msgstr ""
+
+#: apps/packages/templates/components.scm:89
+msgid "<1>Builds:</1> <2/>."
+msgstr ""
+
+#: apps/packages/templates/components.scm:104
+msgid " issue"
+msgid_plural " issues"
+msgstr[0] ""
+msgstr[1] ""
+
+#: apps/packages/templates/components.scm:115 apps/packages/templates/components.scm:221
+msgid "Packages menu: "
+msgstr ""
+
+#: apps/packages/templates/components.scm:117 apps/packages/templates/components.scm:223
+msgid "Browse alphabetically"
+msgstr ""
+
+#: apps/packages/templates/components.scm:204 apps/packages/templates/components.scm:270
+msgid "None"
+msgstr ""
+
+#: apps/packages/templates/detailed-index.scm:22 apps/packages/templates/detailed-package-list.scm:25 apps/packages/templates/index.scm:22 apps/packages/templates/package-list.scm:25 apps/packages/templates/package.scm:28
+msgctxt "webpage title"
+msgid "Packages"
+msgstr ""
+
+#: apps/packages/templates/detailed-index.scm:24 apps/packages/templates/detailed-package-list.scm:27 apps/packages/templates/index.scm:24
+msgid "List of packages available through GNU Guix."
+msgstr ""
+
+#: apps/packages/templates/detailed-index.scm:45 apps/packages/templates/index.scm:44
+msgid "GNU Guix provides <1/> packages transparently <2>available as pre-built binaries</2>. These pages provide a complete list of the packages.  Our <3>continuous integration system</3> shows their current build status (updated <4/>)."
+msgstr ""
+
+#: apps/packages/templates/detailed-package-list.scm:56 apps/packages/templates/package-list.scm:53
+msgid "Packages — "
+msgstr ""
+
+#: apps/packages/templates/package.scm:62
+msgid "<1>Website: </1>"
+msgstr ""
+
+#: apps/packages/templates/package.scm:65
+msgid "<1>License: </1>"
+msgstr ""
+
+#: apps/packages/templates/package.scm:67
+msgid "<1>Package source: </1>"
+msgstr ""
+
+#: apps/packages/templates/package.scm:69
+msgid "<1>Patches: </1>"
+msgstr ""
+
+#: apps/packages/templates/package.scm:71
+msgid "<1>Builds: </1>"
+msgstr ""
+
+#: apps/packages/templates/package.scm:77
+msgid "<1>Lint issues</1><2><2.1/>. See <2.2>package definition</2.2> in Guix source code.</2>"
+msgstr ""
-- 
2.23.0


--jc5p4xzpw3odooxa
Content-Type: text/plain; charset=utf-8
Content-Disposition: attachment; filename="0006-website-Add-German-translation.patch"
Content-Transfer-Encoding: 8bit

From 6520d896d87849224458057a1f88f2005c3dc00a Mon Sep 17 00:00:00 2001
From: Florian Pelz <pelzflorian@HIDDEN>
Date: Fri, 6 Sep 2019 10:27:13 +0200
Subject: [PATCH 6/6] website: Add German translation.

* website/po/de.po: New file.
* website/po/LINGUAS: Add de_DE lingua.
* website/apps/base/data.scm (contact-media): Remove German blurb.
---
 website/apps/base/data.scm  |    6 +-
 website/po/LINGUAS          |    1 +
 website/po/de.po            | 1888 +++++++++++++++++++++++++++++++++++
 website/po/guix-website.pot |   78 +-
 4 files changed, 1929 insertions(+), 44 deletions(-)
 create mode 100644 website/po/de.po

diff --git a/website/apps/base/data.scm b/website/apps/base/data.scm
index 1a4217c..ff5939e 100644
--- a/website/apps/base/data.scm
+++ b/website/apps/base/data.scm
@@ -77,11 +77,7 @@ though we also accept other languages."))
                                  (string=? (cadar to-delete) (cadr b))
                                  ;; but language code is different
                                  (not (string=? (cadddr to-delete) (car b))))))
-         `(("de"
-            "Melden Sie sich bei der „Help“-Mailingliste an, um per E-Mail
-gemeinschaftlichen Rat zu GuixSD und Guix zu bekommen.  Sie können
-Nachrichten auch auf deutsch verfassen.")
-           ("eo"
+         `(("eo"
             "Subskribu al la retmesaĝolisto \"Help\" por demandi helpon pri
 GNU Guix al la grupo.  Vi povas skribi esperantlingve.")
            ("es"
diff --git a/website/po/LINGUAS b/website/po/LINGUAS
index d4dd759..dc8e711 100644
--- a/website/po/LINGUAS
+++ b/website/po/LINGUAS
@@ -1,3 +1,4 @@
 # Translation with sexp-xgettext requires the full LL_CC locale name
 # to be specified.
+de_DE
 en_US
diff --git a/website/po/de.po b/website/po/de.po
new file mode 100644
index 0000000..569e5e7
--- /dev/null
+++ b/website/po/de.po
@@ -0,0 +1,1888 @@
+# 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.
+# Florian Pelz <pelzflorian@HIDDEN>, 2019.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: guix-website\n"
+"Report-Msgid-Bugs-To: ludo@HIDDEN\n"
+"POT-Creation-Date: 2019-09-06 15:59+0200\n"
+"PO-Revision-Date: 2019-09-06 10:32+0200\n"
+"Last-Translator: Florian Pelz <pelzflorian@HIDDEN>\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:18
+msgctxt "webpage title"
+msgid "GNU's advanced distro and transactional package manager"
+msgstr "GNUs fortgeschrittene Distribution und transaktionelle Paketverwaltung"
+
+#: apps/base/templates/home.scm:20 apps/base/templates/about.scm:19
+msgid ""
+"Guix is an advanced distribution of the GNU operating system.\n"
+"   Guix is technology that respects the freedom of computer users.\n"
+"   You are free to run the system for any purpose, study how it\n"
+"   works, improve it, and share it with the whole world."
+msgstr ""
+"Guix ist eine fortgeschrittene Distribution des GNU-Betriebssystems.\n"
+"   Guix ist eine Technologie, die die Freiheit der Benutzer von "
+"Rechengeräten respektiert.\n"
+"   Es steht Ihnen frei, das System zu jedem Zweck auszuführen, seine "
+"Funktionsweise zu studieren,\n"
+"   es zu verbessern und es mit der ganzen Welt zu teilen."
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/home.scm:26 apps/base/templates/menu.scm:20
+#: apps/base/templates/screenshot.scm:23 apps/blog/templates/post-list.scm:29
+#: apps/blog/templates/tag.scm:33 apps/packages/templates/detailed-index.scm:27
+#: apps/packages/templates/detailed-package-list.scm:30
+#: apps/packages/templates/index.scm:27
+#: apps/packages/templates/package-list.scm:30
+#: apps/packages/templates/package.scm:32
+msgid ""
+"GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU "
+"Guix package manager|GNU Guile|Guile Scheme|Transactional upgrades|"
+"Functional package management|Reproducibility"
+msgstr ""
+"GNU|Linux|Unix|Freie Software|Libre-Software|Betriebssystem|GNU Hurd|GNU-"
+"Guix-Paketverwaltung|GNU Guile|Guile Scheme|Transaktionelle Aktualisierungen|"
+"Funktionale Paketverwaltung|Reproduzierbarkeit"
+
+#: apps/base/templates/home.scm:30 apps/base/templates/components.scm:343
+#: apps/base/templates/screenshot.scm:27
+msgctxt "website menu"
+msgid "Overview"
+msgstr "Übersicht"
+
+#: apps/base/templates/home.scm:39
+msgid "Summary"
+msgstr "Zusammenfassung"
+
+#: apps/base/templates/home.scm:41
+msgid ""
+"<1>Liberating.</1> Guix is an advanced distribution of the <2>GNU operating "
+"system</2> developed by the <3>GNU Project</3>—which respects the <4>freedom "
+"of computer users</4>. "
+msgstr ""
+"<1>Befreiend.</1> Guix ist eine fortgeschrittende Distribution des <2>GNU-"
+"Betriebssystems</2>, das vom <3>GNU-Projekt</3> entwickelt wurde und die "
+"<4>Freiheit der Benutzer von Rechengeräten</4> respektiert. "
+
+#. TRANSLATORS: Package Management, Features and Using the
+#. Configuration System are section names in the English (en)
+#. manual.
+#: apps/base/templates/home.scm:62
+msgid ""
+"<1>Dependable.</1> Guix <2>supports<2.1>en</2.1><2.2>Package-Management."
+"html</2.2></2> transactional upgrades and roll-backs, unprivileged package "
+"management, <3>and more<3.1>en</3.1><3.2>Features.html</3.2></3>.  When used "
+"as a standalone distribution, Guix supports <4>declarative system "
+"configuration<4.1>en</4.1><4.2>Using-the-Configuration-System.html</4.2></4> "
+"for transparent and reproducible operating systems."
+msgstr ""
+"<1>Verlässlich.</1> Guix <2>unterstützt<2.1>de</2.1><2.2>Paketverwaltung."
+"html</2.2></2> transaktionelle Aktualisierungen und Rücksetzungen, "
+"„unprivilegierte“ Paketverwaltung für Nutzer ohne besondere Berechtigungen "
+"<3>und noch mehr<3.1>de</3.1><3.2>Funktionalitaten.html</3.2></3>. Wenn es "
+"als eigenständige Distribution verwendet wird, unterstützt Guix eine "
+"<4>deklarative Konfiguration des Systems<4.1>de</4.1><4.2>Das-"
+"Konfigurationssystem-nutzen.html</4.2></4> für transparente und "
+"reproduzierbare Betriebssysteme."
+
+#. TRANSLATORS: Defining Packages and System Configuration are
+#. section names in the English (en) manual.
+#: apps/base/templates/home.scm:82
+msgid ""
+"<1>Hackable.</1> It provides <2>Guile Scheme</2> APIs, including high-level "
+"embedded domain-specific languages (EDSLs) to <3>define "
+"packages<3.1>en</3.1><3.2>Defining-Packages.html</3.2></3> and <4>whole-"
+"system configurations<4.1>en</4.1><4.2>System-Configuration.html</4.2></4>."
+msgstr ""
+"<1>Hackbar.</1> Programmierschnittstellen (APIs) in <2>Guile Scheme</2> "
+"werden zur Verfügung gestellt, einschließlich hochsprachlicher eingebetteter "
+"domänenspezifischer Sprachen (Embedded Domain-Specific Languages, EDSLs), "
+"mit denen Sie <3>Pakete definieren<3.1>de</3.1><3.2>Pakete-definieren."
+"html</3.2></3> und <4>Konfigurationen des gesamten "
+"Systems<4.1>de</4.1><4.2>Systemkonfiguration.html</4.2></4> festlegen können."
+
+#: apps/base/templates/home.scm:104
+msgctxt "button"
+msgid "DOWNLOAD v<1/>"
+msgstr "v<1/> HERUNTERLADEN"
+
+#: apps/base/templates/home.scm:109
+msgctxt "button"
+msgid "CONTRIBUTE"
+msgstr "MITMACHEN"
+
+#: apps/base/templates/home.scm:116
+msgid "Discover Guix"
+msgstr "Entdecken Sie Guix"
+
+#: apps/base/templates/home.scm:118
+msgid ""
+"Guix comes with thousands of packages which include applications, system "
+"tools, documentation, fonts, and other digital goods readily available for "
+"installing with the <1>GNU Guix</1> package manager."
+msgstr ""
+"Mit Guix kommen Tausende von Paketen. Dazu gehören Anwendungen, "
+"Systemwerkzeuge, Dokumentation, Schriftarten sowie andere digitale Güter, "
+"die jederzeit zur Installation mit dem Paketverwaltungswerkzeug <1>GNU "
+"Guix</1> bereitstehen."
+
+#: apps/base/templates/home.scm:135
+msgctxt "button"
+msgid "ALL PACKAGES"
+msgstr "ALLE PAKETE"
+
+#: apps/base/templates/home.scm:142
+msgid "GNU Guix in your field"
+msgstr "GNU Guix in Ihrem Bereich"
+
+#: apps/base/templates/home.scm:144
+msgid ""
+"Read some stories about how people are using GNU Guix in\n"
+"their daily lives."
+msgstr ""
+"Lesen Sie ein paar Erfahrungen, wie die Leute GNU Guix in\n"
+"ihrem täglichen Leben benutzen."
+
+#: apps/base/templates/home.scm:155
+msgctxt "button"
+msgid "SOFTWARE DEVELOPMENT"
+msgstr "SOFTWARE-ENTWICKLUNG"
+
+#: apps/base/templates/home.scm:160
+msgctxt "button"
+msgid "BIOINFORMATICS"
+msgstr "BIOINFORMATIK"
+
+#: apps/base/templates/home.scm:165
+msgctxt "button"
+msgid "HIGH PERFORMANCE COMPUTING"
+msgstr "HOCHLEISTUNGSRECHNEN"
+
+#: apps/base/templates/home.scm:170
+msgctxt "button"
+msgid "RESEARCH"
+msgstr "FORSCHUNG"
+
+#: apps/base/templates/home.scm:175
+msgctxt "button"
+msgid "ALL FIELDS..."
+msgstr "ALLE BEREICHE …"
+
+#: apps/base/templates/home.scm:182
+msgid "GNU Guix in other GNU/Linux distros"
+msgstr "GNU Guix auf anderen GNU/Linux-Distributionen"
+
+#: apps/base/templates/home.scm:194
+msgid ""
+"Video: <1>Demo of Guix in another GNU/Linux distribution<1.1/>https://audio-"
+"video.gnu.org/video/misc/2016-07__GNU_Guix_Demo_2.webm</1> (1 minute, 30 "
+"seconds)."
+msgstr ""
+"Video: <1>Vorführung von Guix auf einer anderen GNU/Linux-Distribution<1.1/"
+">https://audio-video.gnu.org/video/misc/2016-07__GNU_Guix_Demo_2.webm</1> (1 "
+"Minute, 30 Sekunden)."
+
+#: apps/base/templates/home.scm:205
+msgid ""
+"If you don't use GNU Guix as a standalone GNU/Linux distribution, you still "
+"can use it as a package manager on top of any GNU/Linux distribution. This "
+"way, you can benefit from all its conveniences."
+msgstr ""
+"Wenn Sie GNU Guix nicht als eine eigenständige GNU/Linux-Distribution "
+"verwenden, können Sie es trotzdem zur Paketverwaltung benutzen, aufgesetzt "
+"auf eine beliebige bestehende GNU/Linux-Distribution. Auf diese Weise können "
+"Sie all seine Vorteile genießen."
+
+#: apps/base/templates/home.scm:210
+msgid ""
+"Guix won't interfere with the package manager that comes with your "
+"distribution. They can live together."
+msgstr ""
+"Guix und das Paketverwaltungswerkzeug, das mit Ihrer Distribution "
+"ausgeliefert wird, werden sich gegenseitig nicht stören. Sie können "
+"friedlich koexistieren."
+
+#: apps/base/templates/home.scm:217
+msgctxt "button"
+msgid "TRY IT OUT!"
+msgstr "PROBIEREN SIE ES AUS!"
+
+#: apps/base/templates/home.scm:224 apps/blog/templates/post-list.scm:49
+msgid "Blog"
+msgstr "Blog"
+
+#: apps/base/templates/home.scm:231
+msgctxt "button"
+msgid "ALL POSTS"
+msgstr "ALLE EINTRÄGE"
+
+#: apps/base/templates/home.scm:237 apps/base/templates/contact.scm:36
+msgid "Contact"
+msgstr "Kontakt"
+
+#: apps/base/templates/home.scm:244
+msgctxt "button"
+msgid "ALL CONTACT MEDIA"
+msgstr "ALLE KONTAKTMÖGLICHKEITEN"
+
+#: apps/base/templates/theme.scm:17 apps/base/templates/components.scm:350
+#: apps/base/templates/about.scm:27 apps/base/templates/about.scm:30
+#: apps/base/templates/contact.scm:26 apps/base/templates/contribute.scm:26
+#: apps/base/templates/graphics.scm:24 apps/base/templates/security.scm:28
+msgctxt "website menu"
+msgid "About"
+msgstr "Über Guix"
+
+#: apps/base/templates/theme.scm:73 apps/base/templates/theme.scm:75
+msgctxt "webpage title"
+msgid "GNU Guix"
+msgstr "GNU Guix"
+
+#: apps/base/templates/theme.scm:97
+msgctxt "webpage title"
+msgid "GNU Guix — Activity Feed"
+msgstr "GNU Guix — Aktivitäten-Feed"
+
+#: apps/base/templates/theme.scm:114
+msgid ""
+"Made with <1>♥</1> by humans and powered by <2>GNU Guile</2>.  <3>Source "
+"code</3> under the <4>GNU AGPL</4>."
+msgstr ""
+"Mit <1>♥</1> von Menschen gemacht und durch <2>GNU Guile</2> ermöglicht. "
+"<3>Quellcode</3> unter der <4>GNU AGPL</4>."
+
+#: apps/base/templates/components.scm:48
+msgid "Your location:"
+msgstr "Sie befinden sich hier:"
+
+#: apps/base/templates/components.scm:50
+msgid "Home"
+msgstr "Hauptseite"
+
+#: apps/base/templates/components.scm:153
+msgid "archive"
+msgstr "Archiv"
+
+#: apps/base/templates/components.scm:337
+msgctxt "website menu"
+msgid "Guix"
+msgstr "Guix"
+
+#: apps/base/templates/components.scm:341
+msgid "website menu:"
+msgstr "Menü des Webauftritts:"
+
+#: apps/base/templates/components.scm:344
+#: apps/download/templates/download.scm:42
+#: apps/download/templates/download.scm:46
+msgctxt "website menu"
+msgid "Download"
+msgstr "Herunterladen"
+
+#: apps/base/templates/components.scm:345
+#: apps/packages/templates/detailed-index.scm:31
+#: apps/packages/templates/detailed-index.scm:38
+#: apps/packages/templates/detailed-package-list.scm:34
+#: apps/packages/templates/detailed-package-list.scm:43
+#: apps/packages/templates/index.scm:31 apps/packages/templates/index.scm:37
+#: apps/packages/templates/package-list.scm:34
+#: apps/packages/templates/package-list.scm:40
+#: apps/packages/templates/package.scm:36
+#: apps/packages/templates/package.scm:41
+msgctxt "website menu"
+msgid "Packages"
+msgstr "Pakete"
+
+#: apps/base/templates/components.scm:346 apps/blog/templates/post-list.scm:33
+#: apps/blog/templates/post-list.scm:39 apps/blog/templates/post.scm:29
+#: apps/blog/templates/post.scm:35 apps/blog/templates/tag.scm:37
+#: apps/blog/templates/tag.scm:43
+msgctxt "website menu"
+msgid "Blog"
+msgstr "Blog"
+
+#: apps/base/templates/components.scm:347 apps/base/templates/help.scm:26
+#: apps/base/templates/help.scm:30
+msgctxt "website menu"
+msgid "Help"
+msgstr "Hilfe"
+
+#: apps/base/templates/components.scm:348 apps/base/templates/donate.scm:26
+#: apps/base/templates/donate.scm:29
+msgctxt "website menu"
+msgid "Donate"
+msgstr "Spenden"
+
+#: apps/base/templates/components.scm:353 apps/base/templates/contact.scm:31
+msgctxt "website menu"
+msgid "Contact"
+msgstr "Kontakt"
+
+#: apps/base/templates/components.scm:354 apps/base/templates/contribute.scm:30
+msgctxt "website menu"
+msgid "Contribute"
+msgstr "Mitmachen"
+
+#: apps/base/templates/components.scm:355 apps/base/templates/security.scm:31
+msgctxt "website menu"
+msgid "Security"
+msgstr "Sicherheit"
+
+#: apps/base/templates/components.scm:356 apps/base/templates/graphics.scm:27
+msgctxt "website menu"
+msgid "Graphics"
+msgstr "Grafiken"
+
+#: apps/base/templates/components.scm:374
+msgid " (Page <1/> of <2/>)"
+msgstr " (Seite <1/> von <2/>)"
+
+#: apps/base/templates/components.scm:398
+msgid "Page <1/> of <2/>. Go to another page: "
+msgstr "Seite <1/> von <2/>. Besuchen Sie eine andere Seite: "
+
+#: apps/base/templates/about.scm:17
+msgctxt "webpage title"
+msgid "About"
+msgstr "Über Guix"
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/about.scm:25
+msgid ""
+"GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU "
+"Guix package manager"
+msgstr ""
+"GNU|Linux|Unix|Freie Software|Libre-Software|Betriebssystem|GNU Hurd|GNU-"
+"Guix-Paketverwaltung"
+
+#: apps/base/templates/about.scm:35
+msgid "About the Project"
+msgstr "Über das Projekt"
+
+#: apps/base/templates/about.scm:37
+msgid ""
+"The <1>GNU Guix</1> package and system manager is a <2>free software</2> "
+"project developed by volunteers around the world under the\n"
+"            umbrella of the <3>GNU Project</3>. "
+msgstr ""
+"<1>GNU Guix</1>, ein Programm zur Verwaltung von Paketen und Systemen, ist "
+"ein <2>Freie-Software-Projekt</2>, das von Freiwilligen aus der ganzen Welt "
+"im Rahmen des <3>GNU-Projekts</3> entwickelt wird. "
+
+#: apps/base/templates/about.scm:46
+msgid ""
+"Guix System is an advanced distribution of the <1>GNU operating system</1>.  "
+"It uses the <2>Linux-libre</2> kernel, and support for <3>the Hurd</3> is "
+"being worked on.  As a GNU distribution, it is committed\n"
+"            to respecting and enhancing <4>the freedom of its users</4>.  As "
+"such, it adheres to the <5>GNU Free System Distribution Guidelines</5>."
+msgstr ""
+"„Guix System“ ist eine fortgeschrittene Distribution des <1>GNU-"
+"Betriebssystems</1>. Es verwendet <2>Linux-libre</2> als seinen Kernel; an "
+"Unterstützung für <3>GNU Hurd</3> wird gearbeitet. Als GNU-Distribution "
+"gehört es zu seiner Zielsetzung, <4>die Freiheit seiner Nutzer</4> zu "
+"respektieren und zu vermehren. Daher folgt es den <5>Richtlinien für Freie "
+"Systemdistributionen</5>."
+
+#. TRANSLATORS: Features and Defining Packages are section names
+#. in the English (en) manual.
+#: apps/base/templates/about.scm:64
+msgid ""
+"GNU Guix provides <1>state-of-the-art package management "
+"features<1.1>en</1.1><1.2>Features.html</1.2></1> such as transactional "
+"upgrades and roll-backs, reproducible\n"
+"            build environments, unprivileged package management, and\n"
+"            per-user profiles.  It uses low-level mechanisms from the "
+"<2>Nix</2> package manager, but packages are "
+"<3>defined<3.1>en</3.1><3.2>Defining-Packages.html</3.2></3> as native "
+"<4>Guile</4> modules, using extensions to the <5>Scheme</5> language—which "
+"makes it nicely hackable."
+msgstr ""
+"GNU Guix bietet <1>Paketverwaltungsfunktionalitäten auf dem Stand der "
+"Technik<1.1>de</1.1><1.2>Funktionalitaten.html</1.2></1>, wie etwa "
+"transaktionelle Aktualisierungen und Rücksetzungen, reproduzierbare "
+"Erstellungsumgebungen, eine „unprivilegierte“ Paketverwaltung für Nutzer "
+"ohne besondere Berechtigungen sowie ein eigenes Paketprofil für jeden "
+"Nutzer. Dazu verwendet es dieselben Mechanismen, die dem "
+"Paketverwaltungsprogramm <2>Nix</2> zu Grunde liegen, jedoch werden Pakete "
+"als reine <4>Guile</4>-Module <3>definiert<3.1>de</3.1><3.2>Pakete-"
+"definieren.html</3.2></3>. Dazu erweitert Guix die <5>Scheme</5>-"
+"Programmiersprache, wodurch es leicht ist, selbst an diesen zu hacken."
+
+#. TRANSLATORS: Using the Configuration System, Initial RAM Disk
+#. and Defining Services are section names in the English (en)
+#. manual.
+#: apps/base/templates/about.scm:85
+msgid ""
+"Guix takes that a step further by additionally supporting stateless,\n"
+"           reproducible <1>operating system "
+"configurations<1.1>en</1.1><1.2>Using-the-Configuration-System."
+"html</1.2></1>. This time the whole system is hackable in Scheme, from the "
+"<2>initial RAM disk<2.1>en</2.1><2.2>Initial-RAM-Disk.html</2.2></2> to the "
+"<3>initialization system</3>, and to the <4>system "
+"services<4.1>en</4.1><4.2>Defining-Services.html</4.2></4>."
+msgstr ""
+"Guix geht dabei noch einen Schritt weiter, indem es zusätzlich noch "
+"zustandslose, reproduzierbare "
+"<1>Betriebssystemkonfigurationen<1.1>de</1.1><1.2>Das-Konfigurationssystem-"
+"nutzen.html</1.2></1> unterstützt. In diesem Fall kann am ganzen System in "
+"Scheme gehackt werden, von der <2>initialen RAM-"
+"Disk<2.1>de</2.1><2.2>Initiale-RAM_002dDisk.html</2.2></2> bis hin zum "
+"<3>Initialisierungssystem</3> und den "
+"<4>Systemdiensten<4.1>de</4.1><4.2>Dienste-definieren.html</4.2></4>."
+
+#: apps/base/templates/about.scm:106
+msgid "Maintainer"
+msgstr "Betreuer"
+
+#: apps/base/templates/about.scm:108
+msgid ""
+"Guix is currently maintained by Ludovic Courtès and Ricardo\n"
+"          Wurmus.  Please use the <1>mailing lists</1> for contact. "
+msgstr ""
+"Die Betreuer („Maintainer“) von Guix sind zur Zeit Ludovic Courtès und "
+"Ricardo Wurmus. Benutzen Sie bitte die <1>Mailing-Listen</1>, um Kontakt "
+"aufzunehmen."
+
+#: apps/base/templates/about.scm:116
+msgid "Licensing"
+msgstr "Lizenzierung"
+
+#: apps/base/templates/about.scm:118
+msgid ""
+"Guix is free software; you can redistribute it and/or modify\n"
+"          it under the terms of the <1>GNU General Public License</1> as "
+"published by the Free Software Foundation; either\n"
+"          version 3 of the License, or (at your option) any later\n"
+"          version. "
+msgstr ""
+"Guix ist freie Software. Sie können es weitergeben und/oder verändern, "
+"solange Sie sich an die Regeln der <1>GNU General Public License</1> halten, "
+"so wie sie von der Free Software Foundation festgelegt wurden; entweder in "
+"Version 3 der Lizenz oder (nach Ihrem Ermessen) in jeder neueren Version."
+
+#: apps/base/data.scm:25
+msgid "IRC Channel"
+msgstr "IRC-Kanal"
+
+#: apps/base/data.scm:27
+msgid ""
+"Join the <1/> channel on the Freenode IRC network to chat\n"
+"       with the community about GNU Guix or to get help in\n"
+"       real-time."
+msgstr ""
+"Treten Sie dem <1/>-Kanal auf dem Freenode-IRC-Netzwerk bei, um mit der "
+"Gemeinde über GNU Guix zu reden oder im Gespräch Hilfe zu bekommen."
+
+#: apps/base/data.scm:36
+msgid "Info Mailing List"
+msgstr "Info-Mailing-Liste"
+
+#: apps/base/data.scm:38
+msgid ""
+"Subscribe to the <1/> low-traffic mailing\n"
+"list to receive important announcements sent by the project maintainers (in\n"
+"English)."
+msgstr ""
+"Tragen Sie sich auf der Mailing-Liste <1/> ein, um wichtige Ankündigungen "
+"durch die Projektbetreuer zu empfangen (auf Englisch). Diese Liste hat ein "
+"geringes E-Mail-Aufkommen."
+
+#: apps/base/data.scm:47
+msgid "Help Mailing List"
+msgstr "„Help“-Mailing-Liste"
+
+# Übernommen von Andreas Enge:
+# https://lists.gnu.org/archive/html/guix-devel/2018-03/msg00042.html
+#: apps/base/data.scm:52
+msgid ""
+"Subscribe to the Help mailing list to get support\n"
+"from the GNU Guix community via email.  You can post messages in English\n"
+"though we also accept other languages."
+msgstr ""
+"Melden Sie sich bei der „Help“-Mailingliste an, um per E-Mail "
+"gemeinschaftlichen Rat zu GNU Guix zu bekommen. Sie können Nachrichten auch "
+"auf Deutsch verfassen."
+
+#: apps/base/data.scm:56
+msgctxt "unique lingua code like en or zh-cn"
+msgid "en"
+msgstr "de"
+
+#: apps/base/data.scm:123
+msgid "Bug Reporting"
+msgstr "Fehler melden"
+
+#: apps/base/data.scm:125
+msgid ""
+"If you found a bug in Guix, check whether the bug is\n"
+"       already in the <1>bug database</1>. If it is not, please <2>report it."
+"</2>"
+msgstr ""
+"Wenn Sie einen Fehler in Guix gefunden haben, schauen Sie bitte, ob er "
+"bereits in der <1>Fehlerdatenbank</1> steht. Wenn nicht, sind wir dankbar, "
+"wenn Sie <2>ihn melden</2>."
+
+#: apps/base/data.scm:137
+msgid "Development Mailing List"
+msgstr "Entwicklungs-Mailing-Liste"
+
+#: apps/base/data.scm:139
+msgid ""
+"Discussion about the development of GNU Guix. <1> Until July 2013</1>, the "
+"bug-Guix mailing list filled that role. "
+msgstr ""
+"Hier finden Diskussionen über die Entwicklung von GNU Guix statt. <1>Bis zum "
+"Juli 2013</1> hat die Mailing-Liste bug-Guix diese Rolle übernommen. "
+
+#: apps/base/data.scm:149
+msgid "Patches Mailing List"
+msgstr "Patches-Mailing-Liste"
+
+#: apps/base/data.scm:151
+msgid ""
+"Submission of patches.  Every message sent to this mailing list\n"
+"       leads to a new entry in our <1>patch tracking tool</1>.  See <2>this "
+"page</2> for more information on how to use it; see <3>the "
+"manual<3.1>en</3.1><3.2>Submitting-Patches.html</3.2></3> for more "
+"information on how to submit a patch.  <4>Until February 2017</4>, the guix-"
+"devel mailing list filled that role."
+msgstr ""
+"Hier werden Patches eingereicht. Jede E-Mail, die an diese Liste geschickt "
+"wird, hat die Erzeugung eines neuen Eintrags in unserem <1>Werkzeug zur "
+"Erfassung von Patches</1> zur Folge. Auf <2>dieser Seite</2> finden Sie "
+"weitere Informationen darüber, wie Sie mit der Liste umgehen; <3>im "
+"Handbuch<3.1>de</3.1><3.2>Einreichen-von-Patches.html</3.2></3> sind "
+"Informationen zu finden, wie Sie einen Patch einreichen. <4>Bis zum 4. "
+"Februar 2017</4> hatte die Mailing-Liste guix-devel diese Rolle inne."
+
+#: apps/base/data.scm:170
+msgid "Commits Mailing List"
+msgstr "Commits-Mailing-Liste"
+
+#: apps/base/data.scm:172
+msgid "Notifications of commits made to the <1>Git repositories</1>."
+msgstr "Benachrichtigt über Commits auf den <1>Git-Repositorys</1>."
+
+#: apps/base/data.scm:181
+msgid "Security Mailing List"
+msgstr "Sicherheits-Mailing-Liste"
+
+#: apps/base/data.scm:183
+msgid ""
+"This is a private mailing list that anyone can post to to <1>report security "
+"issues</1> in Guix itself or in the <2>packages</2> it provides.  Posting "
+"here allows Guix developers to address\n"
+"       the problem before it is widely publicized."
+msgstr ""
+"Dies ist eine private Mailing-Liste, an die jeder schreiben kann, um "
+"<1>Sicherheitslücken zu melden</1>, die sich in Guix selbst oder in den zur "
+"Verfügung gestellten <2>Paketen</2> befinden. Eine E-Mail an diese Liste "
+"gibt den Guix-Entwicklern die Gelegenheit, Lücken zu beseitigen, bevor sie "
+"weithin bekannt werden."
+
+#: apps/base/data.scm:195
+msgid "Sysadmin Mailing List"
+msgstr "Sysadmin-Mailing-Liste"
+
+#: apps/base/data.scm:197
+msgid "Private mailing list for the <1>build farm</1> system administration."
+msgstr ""
+"Private Mailing-Liste für Systemadministratoren der <1>Erstellungsfarm</1>."
+
+#: apps/base/data.scm:209
+msgid "GNU System Discuss Mailing List"
+msgstr "Mailing-Liste für GNU-System-Diskussionen"
+
+#: apps/base/data.scm:211
+msgid "Discussion about the development of the broader GNU system."
+msgstr "Für Diskussionen über die Entwicklung des GNU-Systems allgemein."
+
+#: apps/base/data.scm:216
+msgid "GNU/Linux-libre Mailing List"
+msgstr "GNU/Linux-libre-Mailing-Liste"
+
+#: apps/base/data.scm:218
+msgid "Workgroup for fully free GNU/Linux distributions."
+msgstr "Arbeitsgruppe für völlig freie GNU/Linux-Distributionen."
+
+#: apps/base/data.scm:223
+msgid "GNU Info Mailing List"
+msgstr "GNU-Info-Mailing-Liste"
+
+#: apps/base/data.scm:225
+msgid "GNU software announcements."
+msgstr "Ankündigungen für GNU-Software."
+
+#: apps/base/data.scm:234
+msgctxt "screenshot title"
+msgid "Graphical log-in"
+msgstr "Grafische Anmeldung"
+
+#: apps/base/data.scm:238
+msgid "Graphical log-in screen"
+msgstr "Grafischer Anmeldebildschirm"
+
+#: apps/base/data.scm:241
+msgctxt "screenshot title"
+msgid "GNOME"
+msgstr "GNOME"
+
+#: apps/base/data.scm:245
+msgid "Control your computer with the GNOME desktop environment"
+msgstr "Steuern Sie Ihren Rechner mit der GNOME-Arbeitsumgebung"
+
+#: apps/base/data.scm:248
+msgctxt "screenshot title"
+msgid "Xfce"
+msgstr "Xfce"
+
+#: apps/base/data.scm:252
+msgid "The Xfce desktop environment with GNU Emacs and IceCat"
+msgstr "Die Xfce-Arbeitsumgebung mit GNU Emacs und IceCat"
+
+#: apps/base/data.scm:255
+msgctxt "screenshot title"
+msgid "Virtual machine"
+msgstr "Virtuelle Maschine"
+
+#: apps/base/data.scm:259
+msgid "Virtual machine started with 'guix system vm'"
+msgstr "Über ‚guix system vm‘ gestartete Virtuelle Maschine"
+
+#: apps/base/data.scm:262
+msgctxt "screenshot title"
+msgid "Enlightenment"
+msgstr "Enlightenment"
+
+#: apps/base/data.scm:266
+msgid "Enlightenment, Inkscape, and Serbian text"
+msgstr "Enlightenment, Inkscape und serbische Schrift"
+
+#: apps/base/templates/help.scm:17
+msgctxt "webpage title"
+msgid "Help"
+msgstr "Hilfe"
+
+#: apps/base/templates/help.scm:19
+msgid ""
+"A list of resources about how to use GNU Guix, plus\n"
+"   information about getting help from the community of users and\n"
+"   developers."
+msgstr ""
+"Eine Liste von Ressourcen, wie man GNU Guix benutzt, sowie Informationen "
+"darüber, wie Sie Hilfe von der Nutzer- und Entwicklergemeinde bekommen "
+"können."
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/help.scm:24
+msgid ""
+"GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU "
+"Guix package manager|Help resources"
+msgstr ""
+"GNU|Linux|Unix|Freie Software|Libre-Software|Betriebssystem|GNU Hurd|GNU-"
+"Guix-Paketverwaltung|Hilfe-Ressourcen"
+
+#: apps/base/templates/help.scm:35
+msgid "Help"
+msgstr "Hilfe"
+
+#: apps/base/templates/help.scm:46
+msgid "GNU Guix Manual"
+msgstr "Handbuch von GNU Guix"
+
+#: apps/base/templates/help.scm:47
+msgid ""
+"Documentation for GNU Guix is available\n"
+"            online.  You may also find more information about Guix by "
+"running <1>info guix</1>."
+msgstr ""
+"Sie können Dokumentation für GNU Guix online lesen. Sie können weitere "
+"Informationen über Guix auch bekommen, indem Sie <1>info guix</1> ausführen."
+
+#: apps/base/templates/help.scm:53
+msgid "Read Guix manual"
+msgstr "Lesen Sie das Guix-Handbuch"
+
+#: apps/base/templates/help.scm:64
+msgid "Get Guix reference card"
+msgstr "Guix-Referenzkarte herunterladen"
+
+#: apps/base/templates/help.scm:72
+msgid "GNU Manuals"
+msgstr "GNU-Handbücher"
+
+#: apps/base/templates/help.scm:73
+msgid ""
+"Guix is a distribution of the <1>GNU operating system</1>.  Documentation "
+"for GNU packages is\n"
+"            available online in various formats. "
+msgstr ""
+"Guix ist eine Distribution des <1>GNU-Betriebssystems</1>. Dokumentation für "
+"GNU-Pakete gibt es online in verschiedenen Formaten."
+
+#: apps/base/templates/help.scm:81
+msgid "Browse GNU manuals"
+msgstr "GNU-Handbücher lesen"
+
+#: apps/base/templates/help.scm:89
+msgid "IRC Chat"
+msgstr "IRC-Chat"
+
+#: apps/base/templates/help.scm:90
+msgid ""
+"For real-time support from the community, you can connect\n"
+"            to the <1/> channel on irc.freenode.net. There\n"
+"            you can get help about anything related to GNU Guix."
+msgstr ""
+"Sie können Hilfe von der Guix-Gemeinde per Chat bekommen, indem Sie sich mit "
+"dem <1/>-Kanal auf irc.freenode.net verbinden. Dort bekommen Sie Hilfe zu "
+"allem, was mit GNU Guix zu tun hat."
+
+#: apps/base/templates/help.scm:95
+msgid ""
+"The <1/> channel is logged. Previous\n"
+"            conversations can be browsed online. See the <2>channel "
+"logs</2>. "
+msgstr ""
+"Der <1/>-Kanal wird protokolliert. Vergangene Kommunikation kann online "
+"eingesehen werden; siehe die <2>Kanalprotokolle</2>. "
+
+#: apps/base/templates/help.scm:102
+msgid "Connect"
+msgstr "Verbinden"
+
+#: apps/base/templates/help.scm:110
+msgid "Mailing lists"
+msgstr "Mailing-Listen"
+
+#: apps/base/templates/help.scm:111
+msgid ""
+"Email support from the community is also available through\n"
+"            several mailing list. The messages sent to the lists are\n"
+"            public and archived online."
+msgstr ""
+"E-Mail-Hilfe aus der Gemeinde bekommen Sie auch auf mehreren Mailing-Listen. "
+"Die Nachrichten, die an die Listen geschickt werden, sind öffentlich "
+"einsehbar und werden online archiviert."
+
+#: apps/base/templates/help.scm:119
+msgid "See all lists"
+msgstr "Alle Listen sehen"
+
+#: apps/base/templates/contact.scm:17 apps/base/templates/irc.scm:18
+#: apps/base/templates/irc.scm:29
+msgctxt "webpage title"
+msgid "Contact"
+msgstr "Kontakt"
+
+#: apps/base/templates/contact.scm:19
+msgid ""
+"A list of channels to communicate with GNU Guix users\n"
+"   and developers about anything you want."
+msgstr ""
+"Eine Liste der Kanäle, auf denen Sie mit Nutzern und Entwicklern von "
+"GNU Guix reden können, worüber Sie möchten."
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/contact.scm:23
+msgid ""
+"GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU "
+"Guix package manager|Community|Mailing lists|IRC channels|Bug reports|Help"
+msgstr ""
+"GNU|Linux|Unix|Freie Software|Libre-Software|Betriebssystem|GNU Hurd|GNU-"
+"Guix-Paketverwaltung|Gemeinde|Community|Mailing-Listen|IRC-Kanäle|Probleme "
+"melden|Hilfe"
+
+#: apps/base/templates/contribute.scm:17
+msgctxt "webpage title"
+msgid "Contribute"
+msgstr "Mitmachen"
+
+#: apps/base/templates/contribute.scm:19
+msgid ""
+"Check all the ways you can contribute to make GNU Guix\n"
+"   better, and join the world-wide community of volunteers."
+msgstr ""
+"Sehen Sie, wo Sie mitmachen können, um GNU Guix zu verbessern, und treten "
+"Sie der weltweiten Gemeinschaft der Freiwilligen bei."
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/contribute.scm:23
+msgid ""
+"GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU "
+"Guix package manager|Volunteer|Development|Translation|I18N|L10N|Artwork"
+msgstr ""
+"GNU|Linux|Unix|Freie Software|Libre-Software|Betriebssystem|GNU Hurd|GNU-"
+"Guix-Paketverwaltung|Mitmachen|Entwicklung|Übersetzung|I18N|L10N|Grafiken|"
+"Medien|Design"
+
+#: apps/base/templates/contribute.scm:35 apps/base/templates/contribute.scm:110
+#: apps/base/templates/contribute.scm:227
+msgid "Contribute"
+msgstr "Mitmachen"
+
+#: apps/base/templates/contribute.scm:37
+msgid ""
+"GNU Guix is a large project developed\n"
+"           mostly by volunteers from all around the world. You are welcome\n"
+"           to join us in the <1>development mailing list</1> or in the "
+"<2>#guix channel</2> in IRC Freenode. Tell us how would you like to help, "
+"and we\n"
+"          will do our best to guide you. "
+msgstr ""
+"GNU Guix ist ein großes Projekt, das hauptsächlich von Freiwilligen aus "
+"aller Welt entwickelt wird. Sie sind bei uns auf der <1>Mailing-Liste zur "
+"Guix-Entwicklung</1> oder auf dem <2>„#guix“-Kanal</2> im IRC von Freenode "
+"herzlich willkommen. Sagen Sie uns, wie Sie uns helfen möchten, und wir tun "
+"unser Bestes, um Sie dabei zu begleiten."
+
+#: apps/base/templates/contribute.scm:51
+msgid ""
+"We want to provide a warm, friendly, and harassment-free environment,\n"
+"           so that anyone can contribute to the best of their abilities.  "
+"To\n"
+"           this end our project uses a “Contributor Covenant”, which was "
+"adapted\n"
+"           from <1>https://contributor-covenant.org/</1>.  You can find the "
+"full pledge in the <2>CODE-OF-CONDUCT</2> file."
+msgstr ""
+"Wir möchten eine warme, freundliche Umgebung frei von Belästigungen bieten, "
+"damit jeder so gut er kann mithelfen kann. Deshalb folgt dieses Projekt "
+"einer Vereinbarung („Contributor Covenant“), die auf <1>https://www."
+"contributor-covenant.org/translations</1> basiert. Sie können unser "
+"vollständiges Versprechen in der Datei <2>CODE-OF-CONDUCT</2> nachlesen."
+
+#: apps/base/templates/contribute.scm:72
+msgid "Project Management"
+msgstr "Projektverwaltung"
+
+#: apps/base/templates/contribute.scm:73
+msgid ""
+"We use <1>Savannah</1> as the central point for development, maintenance "
+"and\n"
+"            distribution of the Guix System Distribution and GNU Guix."
+msgstr ""
+"Wir verwenden <1>Savannah</1> als zentralen Sammlungspunkt für die "
+"Entwicklung, Wartung und Verteilung der Guix-System-Distribution und von "
+"GNU Guix."
+
+#: apps/base/templates/contribute.scm:79
+msgid ""
+"The source files for all the components of the project,\n"
+"            including software, web site, documentation, and artwork, are\n"
+"            available in <1>Git repositories</1> at Savannah. "
+msgstr ""
+"Die Quelldateien für alle Komponenten des Projekts, einschließlich seiner "
+"Software, seines Webauftritts, seiner Dokumentation, seiner Grafiken und "
+"Mediendateien, befinden sich in <1>Git-Repositorys</1> bei Savannah. "
+
+#: apps/base/templates/contribute.scm:89
+msgid "Access Savannah"
+msgstr "Zu Savannah"
+
+#: apps/base/templates/contribute.scm:94
+msgid "Art"
+msgstr "Grafiken und Medien"
+
+#: apps/base/templates/contribute.scm:95
+msgid ""
+"We are always looking for artists to help us design and\n"
+"            improve user interfaces, and create multimedia material for\n"
+"            documentation, presentations, and promotional items. "
+msgstr ""
+"Wir sind immer auf der Suche nach Künstlern, die uns beim Design und der "
+"Verbesserung von Benutzeroberflächen unterstützen und Multimedia-Material "
+"für die Dokumentation, für Präsentationen und Werbeartikel erschaffen."
+
+#: apps/base/templates/contribute.scm:100
+msgid ""
+"The artwork used in the different components of the project\n"
+"            is available in the <1>guix-artwork</1> repository. "
+msgstr ""
+"Die Grafiken und Mediendateien, die in den verschiedenen Komponenten des "
+"Projekts zum Einsatz kommen, stehen im <1>guix-artwork</1>-Repository zur "
+"Verfügung."
+
+#: apps/base/templates/contribute.scm:116
+msgid "Documentation"
+msgstr "Dokumentation"
+
+#: apps/base/templates/contribute.scm:117
+msgid ""
+"You can read the <1>project documentation</1> already available in the "
+"system and in the website, and\n"
+"            help us identify any errors or omissions. Creating new\n"
+"            manuals, tutorials, and blog entries will also help users and\n"
+"            developers discover what we do. "
+msgstr ""
+"Sie können die <1>Projektdokumentation</1>, die es schon im System und auf "
+"dem Webauftritt gibt, lesen und uns dabei helfen, Fehler zu finden und "
+"Unvollständiges zu ergänzen. Wenn Sie neue Handbücher, Anleitungen und Blog-"
+"Einträge schreiben, können Nutzer und Entwickler leichter erkennen, was wir "
+"tun."
+
+#: apps/base/templates/contribute.scm:125
+msgid ""
+"Helping improve the documentation of the <1>packaged software</1> is another "
+"way to contribute. "
+msgstr ""
+"Hilfe bei der Verbesserung der Dokumentation der von uns <1>in Paketen "
+"angebotenen Software</1> ist eine weitere Möglichkeit, GNU Guix zu "
+"unterstützen."
+
+#: apps/base/templates/contribute.scm:132
+msgid "Start writing"
+msgstr "Schreiben Sie Texte"
+
+#: apps/base/templates/contribute.scm:138
+#: apps/packages/templates/detailed-index.scm:43
+#: apps/packages/templates/index.scm:42
+msgid "Packages"
+msgstr "Pakete"
+
+#: apps/base/templates/contribute.scm:139
+msgid ""
+"Hundreds of software, documentation, and assets need to be\n"
+"            packaged to make it easier for users to install their\n"
+"            favorite tools with the Guix package manager, and be\n"
+"            productive using the system. "
+msgstr ""
+"Für Hunderte von Programmen, Dokumentation und Medien müssen noch Pakete "
+"geschrieben werden, damit es Benutzer leichter haben, ihre "
+"Lieblingswerkzeuge mit dem Guix-Paketverwaltungsprogramm zu installieren und "
+"das System produktiv zu nutzen."
+
+#. TRANSLATORS: Packaging Guidelines is a section name in the
+#. English (en) manual.
+#: apps/base/templates/contribute.scm:147
+msgid ""
+"Information on how to add packages to the distribution can\n"
+"            be found <1>in the manual<1.1>en</1.1><1.2>Packaging-Guidelines."
+"html</1.2></1>. "
+msgstr ""
+"Informationen, wie Sie Pakete zur Distribution hinzufügen können, finden Sie "
+"<1>im Handbuch<1.1>de</1.1><1.2>Paketrichtlinien.html</1.2></1>. "
+
+#: apps/base/templates/contribute.scm:157
+msgid ""
+"Check out the <1>package database</1> for a list of available packages, and "
+"the <2>patch-tracking database</2> for a list of pending submissions."
+msgstr ""
+"Schauen Sie in die <1>Paketdatenbank</1>, wenn Sie eine Liste der "
+"verfügbaren Pakete sehen wollen, und in die <2>Datenbank zur Patch-"
+"Erfassung</2> für eine Liste unbearbeiteter Einreichungen."
+
+#: apps/base/templates/contribute.scm:168
+msgid "Send a new package"
+msgstr "Senden Sie ein neues Paket"
+
+#: apps/base/templates/contribute.scm:174
+msgid "Programming"
+msgstr "Programmierung"
+
+#: apps/base/templates/contribute.scm:175
+msgid ""
+"Source code is in the <1>main Git repository</1>.  We use <2>GNU Guile</2> "
+"as the main programming and extension language for the\n"
+"            components of the system. "
+msgstr ""
+"Der Quellcode ist im <1>Haupt-Git-Repository</1> zu finden. Wir benutzen die "
+"Programmier- und Erweiterungssprache <2>GNU Guile</2> für den Großteil der "
+"Programmierung und der Komponenten des Systems."
+
+#. TRANSLATORS: Contributing is a section name in the English
+#. (en) manual.
+#: apps/base/templates/contribute.scm:187
+msgid ""
+"You will find it useful to browse the <1>Guile manual</1> or other "
+"<2>introductory material about Scheme</2>. Also, make sure to read the "
+"<3>Contributing<3.1>en</3.1><3.2>Contributing.html</3.2></3> section of the "
+"manual for more details on the development\n"
+"            setup, as well as the coding and cooperation conventions used\n"
+"            in the project. "
+msgstr ""
+"Sie werden es hilfreich finden, das <1>Guile-Handbuch</1> oder andere "
+"<2>einführende Texte über Scheme</2> zu lesen. Sie sollten außerdem den "
+"Abschnitt <3>Mitwirken<3.1>de</3.1><3.2>Mitwirken.html</3.2></3> im Handbuch "
+"lesen, um mehr Details über die Einrichtung Ihrer Entwicklungsumgebung sowie "
+"die Konventionen für Programmierung und Zusammenarbeit zu erfahren, die im "
+"Projekt gelten."
+
+#: apps/base/templates/contribute.scm:205
+msgid "Send a patch"
+msgstr "Einen Patch senden"
+
+#: apps/base/templates/contribute.scm:211
+msgid "System Administration"
+msgstr "Systemadministration"
+
+#: apps/base/templates/contribute.scm:212
+msgid ""
+"Our system infrastructure makes it possible for all the\n"
+"            contributors to communicate and collaborate in the project,\n"
+"            and users to be able to download and install packages. Help\n"
+"            us keep the system up and running smoothly. "
+msgstr ""
+"Dank unserer Systeminfrastruktur ist es allen Beteiligten möglich, im "
+"Projekt zu kommunizieren und zusammenzuarbeiten, und Nutzer können Pakete "
+"herunterladen und installieren. Helfen Sie uns dabei, dass das System weiter "
+"gut läuft."
+
+#: apps/base/templates/contribute.scm:218
+msgid ""
+"You can also <1>donate hardware or hosting</1> for our <2>build farm</2>.  "
+msgstr ""
+"Sie können für unsere <2>Erstellungsfarm</2> auch <1>Hardware spenden oder "
+"sie bei Ihnen aufstellen („Hosting“)</1>."
+
+#: apps/base/templates/contribute.scm:233
+msgid "Test and Bug Reports"
+msgstr "Testen und Fehlerberichte"
+
+#: apps/base/templates/contribute.scm:234
+msgid ""
+"Install the software and send feedback to the community\n"
+"            about your experience. Help the project by reporting bugs."
+msgstr ""
+"Installieren Sie die Software und geben Sie der Gemeinde Rückmeldung über "
+"Ihre Erfahrungen. Helfen Sie dem Projekt, indem Sie Fehler melden."
+
+#: apps/base/templates/contribute.scm:238
+msgid ""
+"Before reporting a bug, please check whether the bug is\n"
+"            already <1>in the bug database</1>. See <2>the developer "
+"information page</2> for more information on how to manipulate bug reports. "
+msgstr ""
+"Bevor Sie einen Fehler melden, schauen Sie bitte, ob es den Fehler schon in "
+"der <1>Fehlerdatenbank</1> gibt. Siehe <2>die Informationsseite für "
+"Entwickler</2>, um weitere Informationen zu bekommen, wie Sie Fehlerberichte "
+"ergänzen."
+
+#: apps/base/templates/contribute.scm:250
+msgid "Report a bug"
+msgstr "Einen Fehler melden"
+
+#: apps/base/templates/contribute.scm:256
+msgid "Translation"
+msgstr "Übersetzung"
+
+#: apps/base/templates/contribute.scm:257
+msgid ""
+"You can help translate the <1>software</1>, the <2>package descriptions</2>, "
+"and the <3>manual</3> into your language.  See the <4>Translation "
+"Project</4> for information on how you can help."
+msgstr ""
+"Sie können dabei helfen, die <1>Software</1>, die <2>Paketbeschreibungen</2> "
+"oder das <3>Handbuch</3> auf Ihre Sprache zu übersetzen. Siehe das "
+"<4>Translation Project</4> für Informationen, wie Sie helfen können."
+
+#: apps/base/templates/contribute.scm:276
+msgid ""
+"<1>Software packages</1> provided by the system may have their own "
+"translation\n"
+"            tools.  Visit their websites and help translate. "
+msgstr ""
+"Die vom System bereitgestellten <1>Software-Pakete</1> können ihre eigenen "
+"Werkzeuge haben, mit denen sie übersetzt werden können. Besuchen Sie deren "
+"Webauftritte und helfen Sie dort bei deren Übersetzung."
+
+#: apps/base/templates/contribute.scm:283
+msgid "Start translating"
+msgstr "Übersetzen Sie mit"
+
+#: apps/base/templates/contribute.scm:287
+msgid "Other resources for contributors"
+msgstr "Andere Ressourcen für Mitwirkende"
+
+#: apps/base/templates/contribute.scm:288
+msgid ""
+"Documents, supporting material of previous talks, and\n"
+"          auxiliary information useful to hackers and maintainers is\n"
+"          available at <1/>."
+msgstr ""
+"Dokumente, unterstützendes Material vergangener Vorträge sowie zusätzliche "
+"Informationen, die für Hacker und Betreuer nützlich sein können, sind auf <1/"
+"> zu finden."
+
+#: apps/base/templates/donate.scm:17
+msgctxt "webpage title"
+msgid "Donate"
+msgstr "Spenden"
+
+#: apps/base/templates/donate.scm:19
+msgid ""
+"We are looking for donations of hardware and optionally\n"
+"   hosting for machines (they should be usable with exclusively\n"
+"   free software)."
+msgstr ""
+"Wir suchen gespendete Hardware und optional auch Hosting für Maschinen (sie "
+"sollten mit ausschließlich freier Software nutzbar sein)."
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/donate.scm:24
+msgid ""
+"GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU "
+"Guix package manager|Donations"
+msgstr ""
+"GNU|Linux|Unix|Freie Software|Libre-Software|Betriebssystem|GNU Hurd|GNU-"
+"Guix-Paketverwaltung|Spenden"
+
+#: apps/base/templates/donate.scm:34
+msgid "Donate"
+msgstr "Spenden"
+
+#: apps/base/templates/donate.scm:36
+msgid ""
+"The <1>build farm</1> of the Guix System Distribution runs on donated "
+"hardware and hosting. As the distribution grows (see the <2>package "
+"list</2>), so do the computing and storage needs."
+msgstr ""
+"Die <1>Erstellungsfarm</1> der Guix-System-Distribution läuft mit "
+"gespendeter Hardware und Hosting. So wie die Distribution wächst (siehe die "
+"<2>Liste der Pakete</2>), so wachsen auch die nötigen Rechen- und "
+"Speicherkapazitäten."
+
+#: apps/base/templates/donate.scm:47
+msgid ""
+"We have <1>started a fundraising campaign</1> to strengthen our build farm, "
+"with <2>support from the Free Software Foundation (FSF)</2>.  Please "
+"consider helping out by making a donation on this\n"
+"          FSF-hosted page:"
+msgstr ""
+"Wir haben eine <1>Spendensammlung gestartet</1>, um unsere Erstellungsfarm "
+"zu verstärken, mit <2>Unterstützung durch die Free Software Foundation "
+"(FSF)</2>. Bitte denken Sie darüber nach, ob Sie uns mit einer Spende auf "
+"dieser von der FSF betriebenen Seite unterstützen möchten:"
+
+#: apps/base/templates/donate.scm:63
+msgctxt "button"
+msgid "♥ DONATE!"
+msgstr "♥ SPENDEN!"
+
+#: apps/base/templates/donate.scm:66
+msgid "Hardware and Hosting"
+msgstr "Hardware und Hosting"
+
+#: apps/base/templates/donate.scm:71
+msgid ""
+"We are also looking for donations of hardware and optionally\n"
+"           hosting for the following kinds of machines (they should be\n"
+"           usable with exclusively free software): "
+msgstr ""
+"Wir suchen auch Hardware-Spenden und optional auch Hosting für die folgenden "
+"Arten von Maschinen (sie sollten mit ausschließlich freier Software nutzbar "
+"sein):"
+
+#: apps/base/templates/donate.scm:78
+msgid ""
+"x86_64 machines, with on the order of 1 TiB of storage\n"
+"               and 4 GiB of RAM;"
+msgstr ""
+"x86_64-Maschinen mit in der Größenordnung von 1 TiB an Plattenspeicher und "
+"4 GiB Arbeitsspeicher,"
+
+#: apps/base/templates/donate.scm:81
+msgid ""
+"armv7 machines (such as the Novena) to more quickly test\n"
+"               and provide binaries for the armhf-linux port;"
+msgstr ""
+"ARMv7-Maschinen (wie Novena), um schnell Binärdateien für die Portierung auf "
+"armhf-linux testen und bereitstellen zu können,"
+
+#: apps/base/templates/donate.scm:84
+msgid "mips64el machines to strengthen this port."
+msgstr "MIPS64el-Maschinen, um diese Portierung zu verstärken."
+
+#: apps/base/templates/donate.scm:87
+msgid ""
+"Please get in touch with us through the <1>usual channels</1> or using the "
+"<2/> private alias to\n"
+"           discuss any opportunities. "
+msgstr ""
+"Bitte treten Sie mit uns über die <1>üblichen Kanäle</1> oder über die "
+"private Alias-Adresse <2/> in Kontakt, um Möglichkeiten zu diskutieren."
+
+#: apps/base/templates/donate.scm:95
+msgid "Thanks to the donors!"
+msgstr "Danke an die Spender!"
+
+#: apps/base/templates/donate.scm:100
+msgid ""
+"The table below summarizes hardware and hosting donations that\n"
+"           make the <1>build farm</1> for the Guix System Distribution a "
+"reality."
+msgstr ""
+"Die folgende Tabelle fasst Hardware- und Hosting-Spenden zusammen, die die "
+"<1>Erstellungsfarm</1> für die Guix-System-Distribution Wirklichkeit werden "
+"lassen."
+
+#: apps/base/templates/donate.scm:110
+msgid "<1>machine</1><2>system</2><3>donors</3>"
+msgstr "<1>Maschine</1><2>System</2><3>Spender</3>"
+
+#: apps/base/templates/donate.scm:114
+msgid ""
+"<1>hydra.gnu.org</1><2>build farm front-end</2><3>Free Software "
+"Foundation</3>"
+msgstr ""
+"<1>hydra.gnu.org</1><2>Vordergrundsystem („Front-end“) für die "
+"Erstellungsfarm</2><3>Free Software Foundation</3>"
+
+#: apps/base/templates/donate.scm:124
+msgid ""
+"<1>berlin.guixsd.org</1><2>build farm with 25 build nodes for x86_64-linux "
+"and\n"
+"i686-linux, and dedicated storage</2><3><3.1>Max Delbrück Center for "
+"Molecular Medicine</3.1> (hardware and hosting)</3>"
+msgstr ""
+"<1>berlin.guixsd.org</1><2>Erstellungsfarm mit 25 Erstellungsknoten für "
+"x86_64-linux und i686-linux, mit dediziertem Speicher</2><3><3.1>Max-"
+"Delbrück-Centrum für Molekulare Medizin</3.1> (Hardware und Hosting)</3>"
+
+#: apps/base/templates/donate.scm:136
+msgid ""
+"<1>overdrive1.guixsd.org</1><2>aarch64-linux</2><3><3.1>ARM "
+"Holdings</3.1></3>"
+msgstr ""
+"<1>overdrive1.guixsd.org</1><2>aarch64-linux</2><3><3.1>ARM "
+"Holdings</3.1></3>"
+
+#: apps/base/templates/donate.scm:146
+msgid ""
+"<1>bayfront.guixsd.org</1><2>new build farm front-end (WIP)</2><3>Igalia</3>"
+msgstr ""
+"<1>bayfront.guixsd.org</1><2>Neues Vordergrundsystem („Front-end“), in "
+"Arbeit</2><3>Igalia</3>"
+
+#: apps/base/templates/donate.scm:158
+msgid ""
+"<1>hydra.gnunet.org</1><2>x86_64-linux, i686-linux</2><3><3.1>Free Secure "
+"Network Systems Group</3.1> at the <3.2>Technische Universität "
+"München</3.2></3>"
+msgstr ""
+"<1>hydra.gnunet.org</1><2>x86_64-linux, i686-linux</2><3><3.1>Free Secure "
+"Network Systems Group</3.1> an der <3.2>Technischen Universität "
+"München</3.2></3>"
+
+#: apps/base/templates/donate.scm:171
+msgid ""
+"<1>chapters.gnu.org</1><2>x86_64-linux, i686-"
+"linux</2><3><3.1><3.1.1>GNU España</3.1.1> "
+"(hardware)</3.1><3.2><3.2.1>FSF France</3.2.1> (hosting)</3.2></3>"
+msgstr ""
+"<1>chapters.gnu.org</1><2>x86_64-linux, i686-"
+"linux</2><3><3.1><3.1.1>GNU España</3.1.1> "
+"(Hardware)</3.1><3.2><3.2.1>FSF France</3.2.1> (Hosting)</3.2></3>"
+
+#: apps/base/templates/donate.scm:186
+msgid ""
+"<1>librenote</1><2>mips64el-linux</2><3><3.1>Daniel Clark "
+"(hardware)</3.1><3.2>Mark H Weaver (hosting)</3.2></3>"
+msgstr ""
+"<1>librenote</1><2>mips64el-linux</2><3><3.1>Daniel Clark "
+"(Hardware)</3.1><3.2>Mark H Weaver (Hosting)</3.2></3>"
+
+#: apps/base/templates/donate.scm:195
+msgid "<1>hydra-slave0</1><2>mips64el-linux</2><3>Free Software Foundation</3>"
+msgstr ""
+"<1>hydra-slave0</1><2>mips64el-linux</2><3>Free Software Foundation</3>"
+
+#: apps/base/templates/donate.scm:205
+msgid "<1>guix.sjd.se</1><2>x86_64-linux, i686-linux</2><3>Simon Josefsson</3>"
+msgstr ""
+"<1>guix.sjd.se</1><2>x86_64-linux, i686-linux</2><3>Simon Josefsson</3>"
+
+#: apps/base/templates/donate.scm:215
+msgid "<1>x15.sjd.se</1><2>armhf-linux</2><3>Simon Josefsson</3>"
+msgstr "<1>x15.sjd.se</1><2>armhf-linux</2><3>Simon Josefsson</3>"
+
+#: apps/base/templates/donate.scm:225
+msgid ""
+"<1>hydra-slave1</1><2>armhf-linux</2><3><3.1>Steve Sprang "
+"(hardware)</3.1><3.2>Mark H Weaver (hosting)</3.2></3>"
+msgstr ""
+"<1>hydra-slave1</1><2>armhf-linux</2><3><3.1>Steve Sprang "
+"(Hardware)</3.1><3.2>Mark H Weaver (Hosting)</3.2></3>"
+
+#: apps/base/templates/donate.scm:235
+msgid ""
+"<1>hydra-slave2</1><2>armhf-linux</2><3><3.1><3.1.1>Harmon "
+"Instruments</3.1.1> (hardware)</3.1><3.2>Mark H Weaver (hosting)</3.2></3>"
+msgstr ""
+"<1>hydra-slave2</1><2>armhf-linux</2><3><3.1><3.1.1>Harmon "
+"Instruments</3.1.1> (Hardware)</3.1><3.2>Mark H Weaver (Hosting)</3.2></3>"
+
+#: apps/base/templates/donate.scm:248
+msgid ""
+"<1>hydra-slave3</1><2>armhf-linux</2><3><3.1><3.1.1>Kosagi (Sutajio Ko-Usagi "
+"Pte Ltd)</3.1.1> (hardware)</3.1><3.2>Mark H Weaver (hosting)</3.2></3>"
+msgstr ""
+"<1>hydra-slave3</1><2>armhf-linux</2><3><3.1><3.1.1>Kosagi (Sutajio Ko-Usagi "
+"Pte Ltd)</3.1.1> (Hardware)</3.1><3.2>Mark H Weaver (Hosting)</3.2></3>"
+
+#: apps/base/templates/donate.scm:261
+msgid ""
+"<1>redhill</1><2>armhf-linux</2><3><3.1><3.1.1>Kosagi (Sutajio Ko-Usagi Pte "
+"Ltd)</3.1.1> (hardware)</3.1><3.2>Andreas Enge (hosting)</3.2></3>"
+msgstr ""
+"<1>redhill</1><2>armhf-linux</2><3><3.1><3.1.1>Kosagi (Sutajio Ko-Usagi Pte "
+"Ltd)</3.1.1> (Hardware)</3.1><3.2>Andreas Enge (Hosting)</3.2></3>"
+
+#: apps/base/templates/graphics.scm:16
+msgctxt "webpage title"
+msgid "Graphics"
+msgstr "Grafiken"
+
+#: apps/base/templates/graphics.scm:18
+msgid ""
+"Information about images used for the graphical identity\n"
+"   of GNU Guix and Guix System (formerly “GuixSD”)."
+msgstr ""
+"Informationen über benutzte Bilder und die grafische Identität von GNU Guix "
+"und Guix System (ehemals “GuixSD”)."
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/graphics.scm:22
+msgid ""
+"GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU "
+"Guix package manager|Donations|Branding|Logo"
+msgstr ""
+"GNU|Linux|Unix|Freie Software|Libre-Software|Betriebssystem|GNU Hurd|GNU-"
+"Guix-Paketverwaltung|Spenden|Gestaltung|Logo"
+
+#: apps/base/templates/graphics.scm:32
+msgid "Graphics"
+msgstr "Grafiken"
+
+#: apps/base/templates/graphics.scm:34
+msgid ""
+"For questions regarding the graphics listed in this page,\n"
+"          please contact <1>help-guix@HIDDEN</1>."
+msgstr ""
+"Bei Fragen zu den auf dieser Seite aufgeführten Grafiken kontaktieren Sie "
+"bitte <1>help-guix@HIDDEN</1>."
+
+#: apps/base/templates/graphics.scm:44
+msgid "GNU Guix logotype"
+msgstr "Logotype von GNU Guix"
+
+#: apps/base/templates/graphics.scm:45
+msgid ""
+"The standalone Guix, formerly known as the “Guix System\n"
+"          Distribution” or GuixSD, had its own logo, which is now\n"
+"          deprecated."
+msgstr ""
+"Eine eigenständige Guix-Installation, ehemals bekannt als die „Guix-System-"
+"Distribution“ oder GuixSD, hatte ihr eigenes Logo, das nicht länger gültig "
+"ist."
+
+#: apps/base/templates/graphics.scm:51
+msgid ""
+"The GNU Guix and GuixSD\n"
+"          logotypes were designed by Luis Felipe López Acevedo\n"
+"          (a.k.a. sirgazil).  They are available under the following\n"
+"          terms:"
+msgstr ""
+"Die Logotypen von GNU Guix und GuixSD wurden von Luis Felipe López Acevedo "
+"gestaltet (auch bekannt als sirgazil). Sie sind unter den folgenden "
+"Bedingungen verfügbar:"
+
+#: apps/base/templates/graphics.scm:65
+msgid ""
+"The source files (SVG) for these logotypes, their variants, and\n"
+"          other artwork used in the different components of the GNU Guix\n"
+"          project are available in the <1>guix-artwork</1> repository, "
+"including the previous GNU Guix logotype designed\n"
+"          by Nikita Karetnikov in 2013 and <2>superseded</2> by the golden "
+"GNU in 2016."
+msgstr ""
+"Die Quelldateien (SVG) für diese Logotypen, ihre Varianten und andere "
+"Grafiken und Mediendateien, die in den verschiedenen Komponenten des GNU-"
+"Guix-Projekts benutzt werden, sind im <1>guix-artwork</1>-Repository "
+"verfügbar, einschließlich der vorherigen Logotype von GNU Guix, die von "
+"Nikita Karetnikov 2013 gestaltet wurde und 2016 durch das goldene GNU "
+"<2>ersetzt wurde</2>."
+
+#: apps/base/templates/irc.scm:17 apps/base/templates/irc.scm:30
+msgctxt "webpage title"
+msgid "IRC"
+msgstr "IRC"
+
+#: apps/base/templates/irc.scm:20
+msgid "Internet relay chat."
+msgstr "Internet Relay Chat."
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/irc.scm:23
+msgid ""
+"GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU "
+"Guix package manager|IRC|chat"
+msgstr ""
+"GNU|Linux|Unix|Freie Software|Libre-Software|Betriebssystem|GNU Hurd|GNU-"
+"Guix-Paketverwaltung|IRC|Chat"
+
+#: apps/base/templates/irc.scm:35
+msgid "IRC"
+msgstr "IRC"
+
+#: apps/base/templates/irc.scm:37
+msgid ""
+"Join the <1/> channel on the <2>Freenode IRC network</2> to chat with the "
+"GNU Guix community or to get help\n"
+"          in real-time. You can use the chat widget below, or just use\n"
+"          the <3>IRC client</3> of your preference. Note that the "
+"conversations that happen\n"
+"          on the <4/> channel are logged (<5>browse the log</5>)."
+msgstr ""
+"Kommen Sie auf den <1/>-Kanal auf dem <2>Freenode-IRC-Netzwerk</2>, um mit "
+"der GNU-Guix-Gemeinde live zu chatten. Sie können das Chatfeld unten "
+"benutzen oder einfach Ihren bevorzugten <3>IRC-Client</3> dorthin verbinden. "
+"Beachten Sie, dass Kommunikation auf dem <4/>-Kanal protokolliert wird "
+"(<5>lesen Sie das Protokoll</5>)."
+
+#: apps/base/templates/menu.scm:16
+msgctxt "webpage title"
+msgid "Menu"
+msgstr "Menü"
+
+#: apps/base/templates/menu.scm:17
+msgid "Website menu."
+msgstr "Menü des Webauftritts."
+
+#: apps/base/templates/menu.scm:24
+msgctxt "website menu"
+msgid "Menu"
+msgstr "Menü"
+
+#: apps/base/templates/screenshot.scm:19
+msgctxt "webpage title"
+msgid "Screenshots"
+msgstr "Screenshots"
+
+#: apps/base/templates/security.scm:19
+msgctxt "webpage title"
+msgid "Security"
+msgstr "Sicherheit"
+
+#: apps/base/templates/security.scm:21
+msgid ""
+"Important information about getting security updates\n"
+"   for your GNU Guix installation, and instructions on how\n"
+"   to report security issues."
+msgstr ""
+"Wichtige Informationen, wie Sie Sicherheitsaktualisierungen für Ihre "
+"Installation von GNU Guix bekommen, und eine Anleitung, wie Sie "
+"Sicherheitslücken melden."
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/security.scm:26
+msgid ""
+"GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU "
+"Guix package manager|Security updates"
+msgstr ""
+"GNU|Linux|Unix|Freie Software|Libre-Software|Betriebssystem|GNU Hurd|GNU-"
+"Guix-Paketverwaltung|Sicherheitsaktualisierungen"
+
+#: apps/base/templates/security.scm:36
+msgid "Security"
+msgstr "Sicherheit"
+
+#: apps/base/templates/security.scm:38
+msgid "How to report security issues"
+msgstr "Wie Sie Sicherheitsprobleme melden"
+
+#: apps/base/templates/security.scm:39
+msgid ""
+"To report sensitive security issues in Guix itself or the\n"
+"           packages it provides, you can write to the private mailing list "
+"<1/>.  This list is monitored by a\n"
+"           small team of Guix developers."
+msgstr ""
+"Um sensible Sicherheitslücken in Guix selbst oder den bereitgestellten "
+"Paketen zu melden, können Sie eine Nachricht an die private Mailing-Liste <1/"
+"> schicken. Diese Liste wird von einer kleinen Gruppe von Guix-Entwicklern "
+"beobachtet."
+
+#: apps/base/templates/security.scm:46
+msgid ""
+"If you prefer to send your report using OpenPGP encrypted email,\n"
+"           please send it to one of the following Guix developers using "
+"their\n"
+"           respective OpenPGP key:"
+msgstr ""
+"Wenn Sie es bevorzugen, Ihre Meldung in einer mit OpenPGP verschlüsselten E-"
+"Mail zu übermitteln, senden Sie diese bitte einem der folgenden Guix-"
+"Entwickler unter Nutzung des entsprechenden OpenPGP-Schlüssels:"
+
+#: apps/base/templates/security.scm:65
+msgid "Release signatures"
+msgstr "Signaturen der Veröffentlichungen"
+
+#: apps/base/templates/security.scm:66
+msgid ""
+"Releases of Guix are signed using the OpenPGP key with the fingerprint <1/"
+">.  Users should <2>verify<2.1>en</2.1><2.2>Binary-Installation."
+"html</2.2></2> their downloads before extracting or running them."
+msgstr ""
+"Veröffentlichungen von Guix werden mit dem OpenPGP-Schlüssel mit dem "
+"Fingerabdruck <1/> signiert. Benutzer sollten heruntergeladene Dateien "
+"<2>verifizieren<2.1>de</2.1><2.2>Aus-Binardatei-installieren.html</2.2></2>, "
+"bevor sie diese entpacken oder ausführen."
+
+#: apps/base/templates/security.scm:78
+msgid "Security updates"
+msgstr "Sicherheitsaktualisierungen"
+
+#: apps/base/templates/security.scm:79
+msgid ""
+"When security vulnerabilities are found in Guix or the packages provided by "
+"Guix, we will provide <1>security updates<1.1>en</1.1><1.2>Security-Updates."
+"html</1.2></1> quickly and with minimal disruption for users."
+msgstr ""
+"Wenn Sicherheitslücken in Guix oder den von Guix bereitgestellten Paketen "
+"gefunden werden, werden wir schnell "
+"<1>Sicherheitsaktualisierungen<1.1>de</1.1><1.2>Sicherheitsaktualisierungen."
+"html</1.2></1> ausliefern, mit minimaler Beeinträchtigung für die Nutzer."
+
+#: apps/base/templates/security.scm:87
+msgid ""
+"Guix uses a “rolling release” model.  All security bug-fixes are pushed "
+"directly to the master branch.  There is no “stable” branch that only "
+"receives security fixes."
+msgstr ""
+"Guix verfolgt ein Rolling-Release-Modell. Jeder Patch, der eine "
+"Sicherheitslücke beseitigt, wird direkt auf den „master“-Branch gepusht. Es "
+"gibt keinen „stable“-Branch, der nur Sicherheitsaktualisierungen erhält."
+
+#: apps/download/data.scm:20
+msgctxt "download page title"
+msgid "GNU Guix System <1/>"
+msgstr "GNU Guix System <1/>"
+
+#: apps/download/data.scm:23
+msgid "USB/DVD ISO installer of the standalone Guix System."
+msgstr "USB/DVD-ISO-Installationsabbild des eigenständigen „Guix System“."
+
+#. TRANSLATORS: System installation is a section name in the
+#. English (en) manual.
+#. TRANSLATORS: System installation is a section name in the
+#. English (en) manual.
+#: apps/download/data.scm:31
+msgid "<1>en</1>System-Installation.html"
+msgstr "<1>de</1>Systeminstallation.html"
+
+#: apps/download/data.scm:35
+msgctxt "download page title"
+msgid "GNU Guix <1/> QEMU Image"
+msgstr "QEMU-Abbild mit GNU Guix <1/>"
+
+#: apps/download/data.scm:38
+msgid "QCOW2 virtual machine (VM) image."
+msgstr "Image für eine virtuelle Maschine (VM) im QCOW2-Format."
+
+#. TRANSLATORS: Running Guix in a VM is a section name in the
+#. English (en) manual.
+#. TRANSLATORS: Running Guix in a VM is a section name in the
+#. English (en) manual.
+#: apps/download/data.scm:45
+msgid "<1>en</1>Running-Guix-in-a-VM.html"
+msgstr "<1>de</1>Guix-in-einer-VM-starten.html"
+
+#: apps/download/data.scm:49
+msgctxt "download page title"
+msgid "GNU Guix <1/> Binary"
+msgstr "GNU Guix <1/> als Binärdatei"
+
+#: apps/download/data.scm:51
+msgid ""
+"Self-contained tarball providing binaries for Guix and its\n"
+"       dependencies, to be installed on top of your Linux-based system."
+msgstr ""
+"Tarball mit Binärdateien für Guix und dessen Abhängigkeiten, die Ihr "
+"bestehendes Linux-basiertes System ergänzen können."
+
+#. TRANSLATORS: Binary Installation is a section name in the
+#. English (en) manual.
+#. TRANSLATORS: Binary Installation is a section name in the
+#. English (en) manual.
+#: apps/download/data.scm:64
+msgid "<1>en</1>Binary-Installation.html"
+msgstr "<1>de</1>Aus-Binardatei-installieren.html"
+
+#: apps/download/data.scm:68
+msgctxt "download page title"
+msgid "GNU Guix <1/> Source"
+msgstr "Quellcode von GNU Guix <1/>"
+
+#: apps/download/data.scm:69
+msgid "Source code distribution."
+msgstr "Quellcode-Distribution."
+
+#. TRANSLATORS: Requirements is a section name in the English (en)
+#. manual.
+#. TRANSLATORS: Requirements is a section name in the English (en)
+#. manual.
+#: apps/download/data.scm:76
+msgid "<1>en</1>Requirements.html"
+msgstr "<1>de</1>Voraussetzungen.html"
+
+#: apps/download/templates/components.scm:25
+msgid "Download options:"
+msgstr "Herunterladen für:"
+
+#: apps/download/templates/components.scm:38
+msgid "Signatures: "
+msgstr "Signaturen:"
+
+#: apps/download/templates/components.scm:50
+msgid "<1>Installation instructions</1>."
+msgstr "<1>Installationsanleitung</1>."
+
+#: apps/download/templates/download.scm:33
+msgctxt "webpage title"
+msgid "Download"
+msgstr "Herunterladen"
+
+#: apps/download/templates/download.scm:35
+msgid ""
+"Installers and source files for GNU Guix.  GNU Guix can be\n"
+"   installed on different GNU/Linux distributions."
+msgstr ""
+"Installationsprogramme und Quelldateien für GNU Guix. GNU Guix kann auf "
+"verschiedenen GNU/Linux-Distributionen installiert werden."
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/download/templates/download.scm:39
+msgid ""
+"GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU "
+"Guix package manager|Installer|Source code|Package manager"
+msgstr ""
+"GNU|Linux|Unix|Freie Software|Libre-Software|Betriebssystem|GNU Hurd|GNU-"
+"Guix-Paketverwaltung|Installationsprogramm|Installationsabbild|Installation|"
+"Quellcode|Paketverwaltung"
+
+#: apps/download/templates/download.scm:51
+msgid "Download"
+msgstr "Herunterladen"
+
+#: apps/download/templates/download.scm:53
+msgid ""
+"As of version <1/>, the standalone Guix System <2>can be installed</2> on an "
+"i686, x86_64, ARMv7, or AArch64 machine.  It uses the <3>Linux-Libre</3> "
+"kernel and the <4>GNU Shepherd</4> init system. Alternately, GNU Guix\n"
+"          can be installed as an additional package manager on top of an\n"
+"          installed Linux-based system."
+msgstr ""
+"Stand Version <1/> kann das eigenständige Guix System auf einer Maschine mit "
+"i686-, x86_64-, ARMv7- oder AArch64-Architektur <2>installiert werden</2>. "
+"Als Kernel wird <3>Linux-Libre</3> benutzt und <4>GNU Shepherd</4> als Init-"
+"System. Alternativ kann GNU Guix als zusätzliches Paketverwaltungsprogramm "
+"auf einem bereits installierten Linux-basierten System installiert werden."
+
+#: apps/download/templates/download.scm:73
+msgid ""
+"Source code and binaries for the Guix System distribution ISO\n"
+"          image as well as GNU Guix can be found on the GNU servers at <1/"
+">.  Older releases can still be found on <2/>."
+msgstr ""
+"Den Quellcode und Binärdateien für die „Guix System“-Distribution als ISO-"
+"Abbild sowie für GNU Guix finden Sie auf den GNU-Servern unter <1/>. Ältere "
+"Veröffentlichungen können weiterhin auf <2/> gefunden werden."
+
+#: apps/blog/templates/components.scm:33 apps/blog/templates/post.scm:46
+msgctxt "SRFI-19 date->string format"
+msgid "~B ~e, ~Y"
+msgstr "~e. ~B ~Y"
+
+#: apps/blog/templates/components.scm:37
+msgctxt "blog post summary ellipsis"
+msgid "…"
+msgstr "…"
+
+#: apps/blog/templates/components.scm:48
+msgid "Blog menu: "
+msgstr "Blog-Menü: "
+
+#: apps/blog/templates/components.scm:53
+msgid "Get topic updates"
+msgstr "Neues zum Thema abonnieren"
+
+#: apps/blog/templates/components.scm:54
+msgid "Get blog updates"
+msgstr "Neue Blog-Einträge abonnieren"
+
+#: apps/blog/templates/components.scm:66
+msgctxt "button"
+msgid "Atom feed"
+msgstr "Atom-Feed"
+
+#: apps/blog/templates/components.scm:68
+msgid "Posts by topic"
+msgstr "Einträge nach Thema"
+
+#: apps/blog/templates/feed.scm:32
+msgctxt "feed author name"
+msgid "GNU Guix"
+msgstr "GNU Guix"
+
+#: apps/blog/templates/post-list.scm:23 apps/blog/templates/post-list.scm:40
+#: apps/blog/templates/tag.scm:25 apps/blog/templates/tag.scm:45
+#: apps/packages/templates/detailed-package-list.scm:24
+#: apps/packages/templates/detailed-package-list.scm:47
+#: apps/packages/templates/package-list.scm:24
+#: apps/packages/templates/package-list.scm:44
+msgid "Page <1/>"
+msgstr "Seite <1/>"
+
+#: apps/blog/templates/post-list.scm:24 apps/blog/templates/post.scm:25
+#: apps/blog/templates/tag.scm:26
+msgctxt "webpage title"
+msgid "Blog"
+msgstr "Blog"
+
+#: apps/blog/templates/post-list.scm:26 apps/blog/templates/post.scm:27
+msgid "Blog posts about GNU Guix."
+msgstr "Blog-Einträge über GNU Guix."
+
+#: apps/blog/templates/post.scm:52
+msgid "Related topics:"
+msgstr "Ähnliche Themen:"
+
+#: apps/blog/templates/tag.scm:28
+msgid "Blog posts about <1/> on GNU Guix."
+msgstr "Blog-Einträge über <1/> bei GNU Guix."
+
+#: apps/blog/templates/tag.scm:54
+msgid "Blog — "
+msgstr "Blog — "
+
+#: apps/packages/templates/components.scm:59
+#: apps/packages/templates/package.scm:56
+msgid "This is a GNU package.  "
+msgstr "Dies ist ein GNU-Paket.  "
+
+#: apps/packages/templates/components.scm:66
+msgid "<1>License:</1> <2/>."
+msgstr "<1>Lizenz:</1> <2/>."
+
+#: apps/packages/templates/components.scm:70
+msgid "<1>Website:</1> <2/>."
+msgstr "<1>Webauftritt:</1> <2/>."
+
+#: apps/packages/templates/components.scm:74
+msgid "<1>Package source:</1> <2/>."
+msgstr "<1>Paketquellcode:</1> <2/>."
+
+#: apps/packages/templates/components.scm:78
+msgid "<1>Patches:</1> <2/>."
+msgstr "<1>Patches:</1> <2/>."
+
+#: apps/packages/templates/components.scm:82
+msgid "<1>Lint issues:</1> <2/>."
+msgstr "<1>Automatisch erkannte Paketfehler:</1> <2/>."
+
+#: apps/packages/templates/components.scm:89
+msgid "<1>Builds:</1> <2/>."
+msgstr "<1>Erstellungen:</1> <2/>."
+
+#: apps/packages/templates/components.scm:104
+msgid " issue"
+msgid_plural " issues"
+msgstr[0] " Fehler"
+msgstr[1] " Fehler"
+
+#: apps/packages/templates/components.scm:115
+#: apps/packages/templates/components.scm:221
+msgid "Packages menu: "
+msgstr "Paketmenü: "
+
+#: apps/packages/templates/components.scm:117
+#: apps/packages/templates/components.scm:223
+msgid "Browse alphabetically"
+msgstr "Alphabetisch anzeigen"
+
+#: apps/packages/templates/components.scm:204
+#: apps/packages/templates/components.scm:270
+msgid "None"
+msgstr "Keine"
+
+#: apps/packages/templates/detailed-index.scm:22
+#: apps/packages/templates/detailed-package-list.scm:25
+#: apps/packages/templates/index.scm:22
+#: apps/packages/templates/package-list.scm:25
+#: apps/packages/templates/package.scm:28
+msgctxt "webpage title"
+msgid "Packages"
+msgstr "Pakete"
+
+#: apps/packages/templates/detailed-index.scm:24
+#: apps/packages/templates/detailed-package-list.scm:27
+#: apps/packages/templates/index.scm:24
+msgid "List of packages available through GNU Guix."
+msgstr "Liste der mit GNU Guix verfügbaren Pakete."
+
+#: apps/packages/templates/detailed-index.scm:45
+#: apps/packages/templates/index.scm:44
+msgid ""
+"GNU Guix provides <1/> packages transparently <2>available as pre-built "
+"binaries</2>. These pages provide a complete list of the packages.  Our "
+"<3>continuous integration system</3> shows their current build status "
+"(updated <4/>)."
+msgstr ""
+"Mit GNU Guix sind <1/> Pakete <2>als vorerstellte Binärdateien</2> "
+"transparent verfügbar. Auf diesen Seiten finden Sie eine vollständige Liste "
+"aller Pakete. Unser <3>System zur kontinuierlichen Integration</3> zeigt "
+"Ihnen deren aktuellen Status (Stand <4/>)."
+
+#: apps/packages/templates/detailed-package-list.scm:56
+#: apps/packages/templates/package-list.scm:53
+msgid "Packages — "
+msgstr "Pakete — "
+
+#: apps/packages/templates/package.scm:62
+msgid "<1>Website: </1>"
+msgstr "<1>Webauftritt: </1>"
+
+#: apps/packages/templates/package.scm:65
+msgid "<1>License: </1>"
+msgstr "<1>Lizenz: </1>"
+
+#: apps/packages/templates/package.scm:67
+msgid "<1>Package source: </1>"
+msgstr "<1>Paketquellcode: </1>"
+
+#: apps/packages/templates/package.scm:69
+msgid "<1>Patches: </1>"
+msgstr "<1>Patches: </1>"
+
+#: apps/packages/templates/package.scm:71
+msgid "<1>Builds: </1>"
+msgstr "<1>Erstellungen: </1>"
+
+#: apps/packages/templates/package.scm:77
+msgid ""
+"<1>Lint issues</1><2><2.1/>. See <2.2>package definition</2.2> in Guix "
+"source code.</2>"
+msgstr ""
+"<1>Automatisch erkannte Paketfehler</1><2><2.1/>. Siehe die "
+"<2.2>Paketdefinition</2.2> im Quellcode von Guix.</2>"
diff --git a/website/po/guix-website.pot b/website/po/guix-website.pot
index 3ed5d51..7bb48d2 100644
--- a/website/po/guix-website.pot
+++ b/website/po/guix-website.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: guix-website\n"
 "Report-Msgid-Bugs-To: ludo@HIDDEN\n"
-"POT-Creation-Date: 2019-09-06 10:23+0200\n"
+"POT-Creation-Date: 2019-09-06 15:59+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@HIDDEN>\n"
@@ -334,120 +334,120 @@ msgctxt "unique lingua code like en or zh-cn"
 msgid "en"
 msgstr ""
 
-#: apps/base/data.scm:127
+#: apps/base/data.scm:123
 msgid "Bug Reporting"
 msgstr ""
 
-#: apps/base/data.scm:129
+#: apps/base/data.scm:125
 msgid "If you found a bug in Guix, check whether the bug is\n       already in the <1>bug database</1>. If it is not, please <2>report it.</2>"
 msgstr ""
 
-#: apps/base/data.scm:141
+#: apps/base/data.scm:137
 msgid "Development Mailing List"
 msgstr ""
 
-#: apps/base/data.scm:143
+#: apps/base/data.scm:139
 msgid "Discussion about the development of GNU Guix. <1> Until July 2013</1>, the bug-Guix mailing list filled that role. "
 msgstr ""
 
-#: apps/base/data.scm:153
+#: apps/base/data.scm:149
 msgid "Patches Mailing List"
 msgstr ""
 
-#: apps/base/data.scm:155
+#: apps/base/data.scm:151
 msgid "Submission of patches.  Every message sent to this mailing list\n       leads to a new entry in our <1>patch tracking tool</1>.  See <2>this page</2> for more information on how to use it; see <3>the manual<3.1>en</3.1><3.2>Submitting-Patches.html</3.2></3> for more information on how to submit a patch.  <4>Until February 2017</4>, the guix-devel mailing list filled that role."
 msgstr ""
 
-#: apps/base/data.scm:174
+#: apps/base/data.scm:170
 msgid "Commits Mailing List"
 msgstr ""
 
-#: apps/base/data.scm:176
+#: apps/base/data.scm:172
 msgid "Notifications of commits made to the <1>Git repositories</1>."
 msgstr ""
 
-#: apps/base/data.scm:185
+#: apps/base/data.scm:181
 msgid "Security Mailing List"
 msgstr ""
 
-#: apps/base/data.scm:187
+#: apps/base/data.scm:183
 msgid "This is a private mailing list that anyone can post to to <1>report security issues</1> in Guix itself or in the <2>packages</2> it provides.  Posting here allows Guix developers to address\n       the problem before it is widely publicized."
 msgstr ""
 
-#: apps/base/data.scm:199
+#: apps/base/data.scm:195
 msgid "Sysadmin Mailing List"
 msgstr ""
 
-#: apps/base/data.scm:201
+#: apps/base/data.scm:197
 msgid "Private mailing list for the <1>build farm</1> system administration."
 msgstr ""
 
-#: apps/base/data.scm:213
+#: apps/base/data.scm:209
 msgid "GNU System Discuss Mailing List"
 msgstr ""
 
-#: apps/base/data.scm:215
+#: apps/base/data.scm:211
 msgid "Discussion about the development of the broader GNU system."
 msgstr ""
 
-#: apps/base/data.scm:220
+#: apps/base/data.scm:216
 msgid "GNU/Linux-libre Mailing List"
 msgstr ""
 
-#: apps/base/data.scm:222
+#: apps/base/data.scm:218
 msgid "Workgroup for fully free GNU/Linux distributions."
 msgstr ""
 
-#: apps/base/data.scm:227
+#: apps/base/data.scm:223
 msgid "GNU Info Mailing List"
 msgstr ""
 
-#: apps/base/data.scm:229
+#: apps/base/data.scm:225
 msgid "GNU software announcements."
 msgstr ""
 
-#: apps/base/data.scm:238
+#: apps/base/data.scm:234
 msgctxt "screenshot title"
 msgid "Graphical log-in"
 msgstr ""
 
-#: apps/base/data.scm:242
+#: apps/base/data.scm:238
 msgid "Graphical log-in screen"
 msgstr ""
 
-#: apps/base/data.scm:245
+#: apps/base/data.scm:241
 msgctxt "screenshot title"
 msgid "GNOME"
 msgstr ""
 
-#: apps/base/data.scm:249
+#: apps/base/data.scm:245
 msgid "Control your computer with the GNOME desktop environment"
 msgstr ""
 
-#: apps/base/data.scm:252
+#: apps/base/data.scm:248
 msgctxt "screenshot title"
 msgid "Xfce"
 msgstr ""
 
-#: apps/base/data.scm:256
+#: apps/base/data.scm:252
 msgid "The Xfce desktop environment with GNU Emacs and IceCat"
 msgstr ""
 
-#: apps/base/data.scm:259
+#: apps/base/data.scm:255
 msgctxt "screenshot title"
 msgid "Virtual machine"
 msgstr ""
 
-#: apps/base/data.scm:263
+#: apps/base/data.scm:259
 msgid "Virtual machine started with 'guix system vm'"
 msgstr ""
 
-#: apps/base/data.scm:266
+#: apps/base/data.scm:262
 msgctxt "screenshot title"
 msgid "Enlightenment"
 msgstr ""
 
-#: apps/base/data.scm:270
+#: apps/base/data.scm:266
 msgid "Enlightenment, Inkscape, and Serbian text"
 msgstr ""
 
@@ -485,43 +485,43 @@ msgstr ""
 msgid "Get Guix reference card"
 msgstr ""
 
-#: apps/base/templates/help.scm:74
+#: apps/base/templates/help.scm:72
 msgid "GNU Manuals"
 msgstr ""
 
-#: apps/base/templates/help.scm:75
+#: apps/base/templates/help.scm:73
 msgid "Guix is a distribution of the <1>GNU operating system</1>.  Documentation for GNU packages is\n            available online in various formats. "
 msgstr ""
 
-#: apps/base/templates/help.scm:83
+#: apps/base/templates/help.scm:81
 msgid "Browse GNU manuals"
 msgstr ""
 
-#: apps/base/templates/help.scm:91
+#: apps/base/templates/help.scm:89
 msgid "IRC Chat"
 msgstr ""
 
-#: apps/base/templates/help.scm:92
+#: apps/base/templates/help.scm:90
 msgid "For real-time support from the community, you can connect\n            to the <1/> channel on irc.freenode.net. There\n            you can get help about anything related to GNU Guix."
 msgstr ""
 
-#: apps/base/templates/help.scm:97
+#: apps/base/templates/help.scm:95
 msgid "The <1/> channel is logged. Previous\n            conversations can be browsed online. See the <2>channel logs</2>. "
 msgstr ""
 
-#: apps/base/templates/help.scm:104
+#: apps/base/templates/help.scm:102
 msgid "Connect"
 msgstr ""
 
-#: apps/base/templates/help.scm:112
+#: apps/base/templates/help.scm:110
 msgid "Mailing lists"
 msgstr ""
 
-#: apps/base/templates/help.scm:113
+#: apps/base/templates/help.scm:111
 msgid "Email support from the community is also available through\n            several mailing list. The messages sent to the lists are\n            public and archived online."
 msgstr ""
 
-#: apps/base/templates/help.scm:121
+#: apps/base/templates/help.scm:119
 msgid "See all lists"
 msgstr ""
 
-- 
2.23.0


--jc5p4xzpw3odooxa--




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Fri, 06 Sep 2019 14:43:01 +0000
Resent-Message-ID: <handler.26302.B26302.15677809279278 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>, 26302 <at> debbugs.gnu.org
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.15677809279278
          (code B ref 26302); Fri, 06 Sep 2019 14:43:01 +0000
Received: (at 26302) by debbugs.gnu.org; 6 Sep 2019 14:42:07 +0000
Received: from localhost ([127.0.0.1]:37252 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1i6FR8-0002Pa-PO
	for submit <at> debbugs.gnu.org; Fri, 06 Sep 2019 10:42:07 -0400
Received: from pelzflorian.de ([5.45.111.108]:33346 helo=mail.pelzflorian.de)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pelzflorian@HIDDEN>) id 1i6FR5-0002PR-Pc
 for 26302 <at> debbugs.gnu.org; Fri, 06 Sep 2019 10:42:04 -0400
Received: from pelzflorian.localdomain (unknown [5.45.111.108])
 by mail.pelzflorian.de (Postfix) with ESMTPSA id 73E623600FA;
 Fri,  6 Sep 2019 16:42:02 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=pelzflorian.de;
 s=mail; t=1567780922;
 bh=O5Hno3h2c7AaFnrWvUWoaLLMzOCTwrW+0ewHM1Ygv1g=;
 h=Date:From:To:Subject:References:In-Reply-To;
 b=JWlyik9WkbqPmVExXG0PuoObJ7QkmhMaUxKJ+L6CkeXe+UogLzybcSGxLPTDVfbh2
 64qJXbQ6Tyv2mswmqkViGSZiWwkwxOHw/cxcycFCh3ed+YOgvXF6OCMnVtV45quixF
 0sFgABuEBXG7penu6hE5o1TPozUevsHOPW3U3uWY=
Date: Fri, 6 Sep 2019 16:42:02 +0200
From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Message-ID: <20190906144202.5qi62iimhz2npdqp@HIDDEN>
References: <20170329154040.ddscahwp2agknihb@abyayala> <8760e8l3bd.fsf@HIDDEN>
 <20170731215448.6zsu2qcfykuzbcd2@abyayala>
 <20190906142548.4crfjgvxilgalgrs@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <20190906142548.4crfjgvxilgalgrs@HIDDEN>
User-Agent: NeoMutt/20180716
X-Spam-Score: 0.0 (/)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

The 6th patch wrongly updated guix-website.pot.  I will not resend.




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
References: <20170329154040.ddscahwp2agknihb@abyayala>
Resent-From: sirgazil <sirgazil@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Fri, 06 Sep 2019 18:18:02 +0000
Resent-Message-ID: <handler.26302.B26302.156779384331972 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: "26302" <26302 <at> debbugs.gnu.org>
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.156779384331972
          (code B ref 26302); Fri, 06 Sep 2019 18:18:02 +0000
Received: (at 26302) by debbugs.gnu.org; 6 Sep 2019 18:17:23 +0000
Received: from localhost ([127.0.0.1]:37344 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1i6InS-0008Jc-Nf
	for submit <at> debbugs.gnu.org; Fri, 06 Sep 2019 14:17:23 -0400
Received: from sender4-pp-o95.zoho.com ([136.143.188.95]:25585)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <sirgazil@HIDDEN>) id 1i6InQ-0008JR-0f
 for 26302 <at> debbugs.gnu.org; Fri, 06 Sep 2019 14:17:21 -0400
ARC-Seal: i=1; a=rsa-sha256; t=1567793836; cv=none; d=zoho.com; s=zohoarc; 
 b=QBJ3HgLQNwEN3cxcyJO6u/tCbFeaFe1lL84RwiSzdDD8lVbUsLJRe8Bu9aZo4KsIkLI+sDaQKVkm3TBquaFRJgUAkm/SZmiKJY8tnDbCoQrbCxlNg9MDM1chx5G78Q8Hgd0BGs39IwgZ9Ee5KZFBYLpnoKXzfVwAdR44TA4fG7E=
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com;
 s=zohoarc; t=1567793836;
 h=Content-Type:Content-Transfer-Encoding:Date:From:MIME-Version:Message-ID:Subject:To:ARC-Authentication-Results;
 bh=OcY6g5S5YGRUKzcYOjXPK2gWmCtKH6hjy6Kl6Q2Y600=; 
 b=PomiHEGaPXKZm9mtaCI/Ltg/fDO2toX21JELQ8h5G9G/rHC5dz8rE5tV50ko35iBfKxm5aS6NblbdWTafUApHqXzTS+2aAAL1UZkIl3UgMnRNVRD8r/QcHu4V6QI1cycoc6iuulddY3lEcey1xMvWegFIJiXbBbTYo6UOh4FcTE=
ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass  header.i=zoho.com;
 spf=pass  smtp.mailfrom=sirgazil@HIDDEN;
 dmarc=pass header.from=<sirgazil@HIDDEN> header.from=<sirgazil@HIDDEN>
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=zapps768; d=zoho.com; 
 h=date:from:to:message-id:in-reply-to:subject:mime-version:content-type:user-agent;
 b=dhUf6MzrrIQ714mu65m0PZWIzH22K4/9jg6ZOAlbEXTLAjrFhMoxJeRBl2QLG+a553Ls4yjqTZlF
 5NrLhS2CuwhGpdMmc5BTft40CZK+zt0XGeKT6LHraPhWJC97431o  
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1567793836; 
 s=zm2019; d=zoho.com; i=sirgazil@HIDDEN;
 h=Date:From:To:Message-ID:In-Reply-To:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding;
 l=1593; bh=OcY6g5S5YGRUKzcYOjXPK2gWmCtKH6hjy6Kl6Q2Y600=;
 b=SyyXD+tCZTC/aCAlBg7ppLyOfy7nJGWHGEvq7lkomH1OP36TO0ZkLo0vG3KiAIZw
 xBQaUuVyfxHf/ZE/najt8svNpZm//jfaPf7om6xWfSEFcbFC9fogsqpg6UmxjKVa/HQ
 CNmCwbJoxOOEYqd9pKEL5eQdt/jmH/DOCZmEPtpc=
Received: from mail.zoho.com by mx.zohomail.com
 with SMTP id 1567793830430807.5663756543497;
 Fri, 6 Sep 2019 11:17:10 -0700 (PDT)
Received: from  [179.15.13.185] by mail.zoho.com
 with HTTP;Fri, 6 Sep 2019 11:17:10 -0700 (PDT)
Date: Fri, 06 Sep 2019 13:17:10 -0500
From: sirgazil <sirgazil@HIDDEN>
Message-ID: <16d07cb5a1d.ca69255821627.8144164908931126811@HIDDEN>
In-Reply-To: 
MIME-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Priority: Medium
User-Agent: Zoho Mail
X-Mailer: Zoho Mail
X-Spam-Score: 0.0 (/)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

Hi, Florian :)

I haven't had the time to work on the website again, so I haven't tried you=
r code yet. But I'm glad you're working on this.

Regarding URLs, I would prefer using IRIs, like follows:

    /IETF-LANGUAGE-TAG/path/to/resource/

So:

    /es-ES/v=C3=ADdeos/
    /es-CO/videos/

Currently, I do this for document-like resources, but I haven't thought if =
the same should be done for other resources like images, videos, etc., that=
 may need localization as well.

I have to say that I'm always afraid that something will break if you don't=
 feed English to current systems, though. See for example the URLs that res=
ult when you export texinfo documentation written in other languages to HTM=
L:

  https://guix.gnu.org/manual/es/html_node/Instalacion-del-sistema.html#Ins=
talaci_00f3n-del-sistema

In this example, the accented "=C3=B3" of "Instalaci=C3=B3n" is changed in =
two different ways that make the URL less readable for a Spanish speaker.

Still, I think it's good to internationalize whatever is supposed to be "lo=
calizable" (in theory) to push systems to handle other languages better.

Speaking of the manual, I would also think about changing its URL path to t=
he /IETF-LANGUAGE-TAG/manual/ form to make everything uniform if possible.

As for the website dropdowns, that could be reported as a separate issue (y=
es, they are not really accessible at the moment). I didn't know how to imp=
lement the tab navigation for them at that time, but I think it is possible=
 using only CSS.



---
https://sirgazil.bitbucket.io/








Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Sun, 08 Sep 2019 17:17:02 +0000
Resent-Message-ID: <handler.26302.B26302.156796300616316 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: sirgazil <sirgazil@HIDDEN>
Cc: 26302 <26302 <at> debbugs.gnu.org>
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.156796300616316
          (code B ref 26302); Sun, 08 Sep 2019 17:17:02 +0000
Received: (at 26302) by debbugs.gnu.org; 8 Sep 2019 17:16:46 +0000
Received: from localhost ([127.0.0.1]:39094 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1i70nt-0004F5-2s
	for submit <at> debbugs.gnu.org; Sun, 08 Sep 2019 13:16:46 -0400
Received: from pelzflorian.de ([5.45.111.108]:53780 helo=mail.pelzflorian.de)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pelzflorian@HIDDEN>) id 1i70no-0004Es-Az
 for 26302 <at> debbugs.gnu.org; Sun, 08 Sep 2019 13:16:41 -0400
Received: from pelzflorian.localdomain (unknown [5.45.111.108])
 by mail.pelzflorian.de (Postfix) with ESMTPSA id BD4E63602A4;
 Sun,  8 Sep 2019 19:16:38 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=pelzflorian.de;
 s=mail; t=1567962998;
 bh=NEnogc6FNDh6byO0drUDK6P8iSVfyiXQYtfVhfJPnfc=;
 h=Date:From:To:Cc:Subject:References:In-Reply-To;
 b=vjVho/cST7Vgg/rL7uWnfEZMk/hDwsjN3EpyhgFR/Y5HQWQVsh7Re5G6GCx8MGzAj
 A+W2pKi/oD8WRFUPnmknVX6lL31vf1o1mlqwNIQjXUUYjVD2EyAB+b2o8zV1EeEbHn
 JmYQaq6MaKfbPNVCeExGSShQqqhhBfgThIv20VS0=
Date: Sun, 8 Sep 2019 19:16:38 +0200
From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Message-ID: <20190908171638.cna67eearj4rbn2k@HIDDEN>
References: <20170329154040.ddscahwp2agknihb@abyayala>
 <16d07cb5a1d.ca69255821627.8144164908931126811@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: 8bit
In-Reply-To: <16d07cb5a1d.ca69255821627.8144164908931126811@HIDDEN>
User-Agent: NeoMutt/20180716
X-Spam-Score: 0.0 (/)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

On Fri, Sep 06, 2019 at 01:17:10PM -0500, sirgazil via Bug reports for GNU Guix wrote:
> Hi, Florian :)
> 
> I haven't had the time to work on the website again, so I haven't
> tried your code yet. But I'm glad you're working on this.
> 

:)


> Regarding URLs, I would prefer using IRIs, like follows:
> 
>     /IETF-LANGUAGE-TAG/path/to/resource/
> 
> So:
> 
>     /es-ES/vídeos/
>     /es-CO/videos/
> 

As I understand it, es and es-ES and es-Latn-ES would all be language
tags (or just subtags??) for Spanish from Spain.  Do we use the full
tag es-Latn-ES?  Probably es-ES makes more sense than es-Latn-ES for
many languages (but not all).  The Translation Project will generally
only provide one script, it seems.  Maybe often es is enough.  I
suppose we could write an associative list mapping locales for which
translations exist to language tags.



> Currently, I do this for document-like resources, but I haven't
> thought if the same should be done for other resources like images,
> videos, etc., that may need localization as well.
>

I would prefer if nginx responded with /es/help/index.html only if
/help/index.html does not exist, the same for other file extensions.



> I have to say that I'm always afraid that something will break if
> you don't feed English to current systems, though. See for example
> the URLs that result when you export texinfo documentation written
> in other languages to HTML:
>
>   https://guix.gnu.org/manual/es/html_node/Instalacion-del-sistema.html#Instalaci_00f3n-del-sistema
> 
> In this example, the accented "ó" of "Instalación" is changed in two
> different ways that make the URL less readable for a Spanish
> speaker.
> 
> Still, I think it's good to internationalize whatever is supposed to
> be "localizable" (in theory) to push systems to handle other
> languages better.
>

I believe Texinfo performs this rather complex mapping (especially for
Chinese manuals!) because domain registrars forbid Unicode characters
that do not match the Top Level Domain for security reasons.  I am
unsure if we can translate anything to non-Latin filenames.



> Speaking of the manual, I would also think about changing its URL
> path to the /IETF-LANGUAGE-TAG/manual/ form to make everything
> uniform if possible.
>

I agree.



> As for the website dropdowns, that could be reported as a separate
> issue (yes, they are not really accessible at the moment). I didn't
> know how to implement the tab navigation for them at that time, but
> I think it is possible using only CSS.
> 
> 

I think a language selection dropdown is required for a multilingual
website.

I realize my code in patch 4 is insufficient when not run manually
because the Guix’ maintenance repository’s hydra/berlin.scm does not
run .guix.scm from the website directory.  I will resend patch 4 when
I have a working dropdown and berlin virtual machine.

Regards,
Florian




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Sun, 08 Sep 2019 19:45:02 +0000
Resent-Message-ID: <handler.26302.B26302.1567971895900 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: "pelzflorian \(Florian Pelz\)" <pelzflorian@HIDDEN>
Cc: Mark H Weaver <mhw@HIDDEN>, 26302 <at> debbugs.gnu.org
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.1567971895900
          (code B ref 26302); Sun, 08 Sep 2019 19:45:02 +0000
Received: (at 26302) by debbugs.gnu.org; 8 Sep 2019 19:44:55 +0000
Received: from localhost ([127.0.0.1]:39153 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1i737G-0000EQ-FU
	for submit <at> debbugs.gnu.org; Sun, 08 Sep 2019 15:44:55 -0400
Received: from eggs.gnu.org ([209.51.188.92]:49323)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <ludo@HIDDEN>) id 1i737F-0000E8-8k
 for 26302 <at> debbugs.gnu.org; Sun, 08 Sep 2019 15:44:53 -0400
Received: from fencepost.gnu.org ([2001:470:142:3::e]:50923)
 by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from <ludo@HIDDEN>)
 id 1i7379-00006C-PP; Sun, 08 Sep 2019 15:44:47 -0400
Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=45276 helo=ribbon)
 by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256)
 (Exim 4.82) (envelope-from <ludo@HIDDEN>)
 id 1i7379-0006AQ-CI; Sun, 08 Sep 2019 15:44:47 -0400
From: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
References: <20170329154040.ddscahwp2agknihb@abyayala>
 <8760e8l3bd.fsf@HIDDEN> <20170731215448.6zsu2qcfykuzbcd2@abyayala>
 <20190906142548.4crfjgvxilgalgrs@HIDDEN>
X-URL: http://www.fdn.fr/~lcourtes/
X-Revolutionary-Date: 22 Fructidor an 227 de la =?UTF-8?Q?R=C3=A9volution?=
X-PGP-Key-ID: 0x090B11993D9AEBB5
X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc
X-PGP-Fingerprint: 3CE4 6455 8A84 FDC6 9DB4  0CFB 090B 1199 3D9A EBB5
X-OS: x86_64-pc-linux-gnu
Date: Sun, 08 Sep 2019 21:44:44 +0200
In-Reply-To: <20190906142548.4crfjgvxilgalgrs@HIDDEN>
 (pelzflorian@HIDDEN's message of "Fri, 6 Sep 2019 16:25:48
 +0200")
Message-ID: <878sqy7etv.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]
X-Spam-Score: -2.3 (--)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -3.3 (---)

Hi Florian,

"pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN> skribis:

> Find attached preliminary patches that add a working website
> translation system to guix-artwork.  Of course, the patches should
> *not* be pushed before there is a working nginx configuration with
> appropriate redirects.  (Except the first three patches; I do not
> understand how you could even build the website without my first
> patch?)

Cool, thanks for opening this issue!

> In my patches, I have used spaces for indentation.  Most previous
> website code used a mix of tabs and spaces, like in emacs=E2=80=99 strange
> default setting.  If you want, I can tabify my patches.  I cannot see
> any reason for using mixed tabs+spaces with emacs-style Lisp
> indentation though.

Spaces are good (easily pastable in the REPL), the whole Guix code base
is meant to use spaces only.

> For redirecting previous URLs based on the HTTP Accept-Language
> header, there is
> <https://www.nginx.com/resources/wiki/modules/accept_language/#accept-lan=
guage-installation>.
> It could be added to nginx.

Good.

> I do not know what the new URLs should be.  After reading
> <https://webmasters.stackexchange.com/questions/403/how-should-i-structur=
e-my-urls-for-both-seo-and-localization>
> I now understand that there indeed should be separate URLs for each
> language and Accept-Language headers are not sufficient.  However,
> Ludo=E2=80=99s idea of translating URLs including the basename
> <https://lists.gnu.org/archive/html/guix-devel/2019-08/msg00164.html>,
> i.e. /help.html as /es/ayuda.html, leads to questions about the
> implementation such as what Jelle Licht mentioned
> <https://lists.gnu.org/archive/html/guix-devel/2019-08/msg00169.html>.
> We can do whatever we want, so let=E2=80=99s do what is best.  What do you
> think, /es/ayuda/ or /es/help/ or something else?
>
> For ayuda, we would then need to make `guix build -f .guix.scm` build
> with the static website also some kind of association list for
> redirects that is readable by nginx lua code or whatever (could there
> be guile plugins for nginx??).
>
> We can do /es/help/ now and make /es/ayuda/ later.

Yeah, let=E2=80=99s keep that for later.

> One of the attached patches adds a PO file with a German translation
> that was needed for testing purposes; of course translations should
> normally be submitted via the Translation Project.  The patch need not
> be applied; do as you see fit.

I wonder if we should use the TP for this.  Thoughts?

> With respect to the help mailing list blurbs on the website, my code
> gives priority to the PO file translation of the blurb and uses the
> previous hard-coded translations as a fall-back.  I would keep the
> blurbs this way until all are part of a PO file at the Translation
> Project.

Sounds good.

> The Chinese language blurb is written in traditional Chinese
> characters.  I believe there never was a decision on
> <https://lists.gnu.org/archive/html/guix-devel/2018-03/msg00131.html>,
> so I leave the language code as =E2=80=9Czh=E2=80=9D for now, even though=
 someone may
> add a =E2=80=9Czh-cn=E2=80=9D too.

Yeah, we can always adjust later.

Thanks!

Ludo=E2=80=99.




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Sun, 08 Sep 2019 20:47:02 +0000
Resent-Message-ID: <handler.26302.B26302.156797559013198 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Cc: Mark H Weaver <mhw@HIDDEN>, 26302 <at> debbugs.gnu.org
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.156797559013198
          (code B ref 26302); Sun, 08 Sep 2019 20:47:02 +0000
Received: (at 26302) by debbugs.gnu.org; 8 Sep 2019 20:46:30 +0000
Received: from localhost ([127.0.0.1]:39199 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1i744s-0003Qd-E5
	for submit <at> debbugs.gnu.org; Sun, 08 Sep 2019 16:46:30 -0400
Received: from pelzflorian.de ([5.45.111.108]:54002 helo=mail.pelzflorian.de)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pelzflorian@HIDDEN>) id 1i744p-0003N5-FO
 for 26302 <at> debbugs.gnu.org; Sun, 08 Sep 2019 16:46:28 -0400
Received: from pelzflorian.localdomain (unknown [5.45.111.108])
 by mail.pelzflorian.de (Postfix) with ESMTPSA id 1EEC73602A4;
 Sun,  8 Sep 2019 22:46:25 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=pelzflorian.de;
 s=mail; t=1567975586;
 bh=GAZ+9H9yKDC3Sz+HXKKmAlSlY1axjWVQlHB/s21NepE=;
 h=Date:From:To:Cc:Subject:References:In-Reply-To;
 b=U5Q+fNENbPqPpb8UdTl7BaBcfRJ1QDoKC2pyH9fpZWlj4FYP4+D6kyd5D78vxBSLQ
 F+1Km0HvpUsbZjf6C3RF5vWo1FlKzSuKhqK5jtQf/ODhdJXryG3dPZ/80ezKajcmep
 LpHHbD5TCMXidDmqJI2y+RU0E1lMTn4JrrZ8hucE=
Date: Sun, 8 Sep 2019 22:46:25 +0200
From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Message-ID: <20190908204625.yjzkhzlwwbz6ivck@HIDDEN>
References: <20170329154040.ddscahwp2agknihb@abyayala> <8760e8l3bd.fsf@HIDDEN>
 <20170731215448.6zsu2qcfykuzbcd2@abyayala>
 <20190906142548.4crfjgvxilgalgrs@HIDDEN>
 <878sqy7etv.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: 8bit
In-Reply-To: <878sqy7etv.fsf@HIDDEN>
User-Agent: NeoMutt/20180716
X-Spam-Score: 0.0 (/)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

On Sun, Sep 08, 2019 at 09:44:44PM +0200, Ludovic Courtès wrote:
> Cool, thanks for opening this issue!
> 

Thank you!  (Well, it was ng0’s old issue and people on the list
started talking about its topic again.)


> > One of the attached patches adds a PO file with a German translation
> > that was needed for testing purposes; of course translations should
> > normally be submitted via the Translation Project.  The patch need not
> > be applied; do as you see fit.
> 
> I wonder if we should use the TP for this.  Thoughts?
> 

We can, because it’s an ordinary POT file like guix-manual (but easier
because no Texinfo knowledge is required).  With the TP, there would
be many more translations, although often incomplete and in a few
cases wrong, but the readers will notice.  All the translators can do
is reorder existing SHTML, at worst misrepresenting GNU, redirecting
translatable links wrongly or preventing the website from building.

Regards,
Florian




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: sirgazil <sirgazil@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Tue, 10 Sep 2019 01:05:02 +0000
Resent-Message-ID: <handler.26302.B26302.156807749810155 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Cc: 26302 <26302 <at> debbugs.gnu.org>
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.156807749810155
          (code B ref 26302); Tue, 10 Sep 2019 01:05:02 +0000
Received: (at 26302) by debbugs.gnu.org; 10 Sep 2019 01:04:58 +0000
Received: from localhost ([127.0.0.1]:40752 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1i7UaY-0002di-Ce
	for submit <at> debbugs.gnu.org; Mon, 09 Sep 2019 21:04:58 -0400
Received: from sender4-pp-o94.zoho.com ([136.143.188.94]:25487)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <sirgazil@HIDDEN>) id 1i7UaV-0002dW-HY
 for 26302 <at> debbugs.gnu.org; Mon, 09 Sep 2019 21:04:57 -0400
ARC-Seal: i=1; a=rsa-sha256; t=1568076579; cv=none; d=zoho.com; s=zohoarc; 
 b=CFKN1WRF2TZbmtgphnja6P+HLJRkAEsjQD/bvCenWWtWv2/BeQG1WovvUxndj1wFOAqJhsjDnz+dxI+QmQqFum4g2dBnVzVa02QUgG8D6iTGOkMqjdKnMFfzKMCzB/qHgWlvM1lDCeO6fWKhrqfEilZaYYAYyOe8HFxKFBev9pA=
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com;
 s=zohoarc; t=1568076579;
 h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:To:ARC-Authentication-Results;
 bh=f0fCgtUIrmtMrT4jtDTCWbce3QS34bPiuQrC+TcXoFE=; 
 b=OVrKzKm0eofjnJgOUm9sy/BlFu8tadZREEdd1wDG6WhFQSmlEL6txUmDHUlM2gEdkNqHg4RNt8GlvvPhAEEz272E9Kw4L1Y0Vb1EDukaTRpiAQr5oxUO3eb8V6qbgVx/RSYBh08fDrhfpP/Y6muJFnfb7jcyIm9DF7ERDlz6RMs=
ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass  header.i=zoho.com;
 spf=pass  smtp.mailfrom=sirgazil@HIDDEN;
 dmarc=pass header.from=<sirgazil@HIDDEN> header.from=<sirgazil@HIDDEN>
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=zapps768; d=zoho.com; 
 h=date:from:to:cc:message-id:in-reply-to:references:subject:mime-version:content-type:user-agent;
 b=H7c8P4Gc8hYPSvPnPQtC1ihOtBemFbiL/MKYeRgXZ3+WC2yPNXZhbUJdMAEhPkXJ3fNrf2ACFBMo
 yVzdX5Jdr/XW1vGHrh+WUULCav8gfVyYA1RW1KM4ULrt2GiWgBaF  
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1568076579; 
 s=zm2019; d=zoho.com; i=sirgazil@HIDDEN;
 h=Date:From:To:Cc:Message-ID:In-Reply-To:References:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding;
 l=1448; bh=f0fCgtUIrmtMrT4jtDTCWbce3QS34bPiuQrC+TcXoFE=;
 b=nNQ3Xr/ID+aYiwRlZQI9hgch3id19waBsSjjfdB5nllMCfIhIZPwLWfjp4aCqudF
 mZmG8zB7Zts4rBwXQb4dUhXmxIo4Z425yTZnb8TiSX5zcC3u0vIg6SUIgIrOsPN30zJ
 vZpc/nllDholAQsrL2LIFxQD9TgEhqgDR8hefYj4=
Received: from mail.zoho.com by mx.zohomail.com
 with SMTP id 1568076573162516.919970858339;
 Mon, 9 Sep 2019 17:49:33 -0700 (PDT)
Received: from  [179.15.13.185] by mail.zoho.com
 with HTTP;Mon, 9 Sep 2019 17:49:33 -0700 (PDT)
Date: Mon, 09 Sep 2019 19:49:33 -0500
From: sirgazil <sirgazil@HIDDEN>
Message-ID: <16d18a5a9e8.12ab66c8254154.2756956535677606704@HIDDEN>
In-Reply-To: <20190908171638.cna67eearj4rbn2k@HIDDEN>
References: <20170329154040.ddscahwp2agknihb@abyayala>
 <16d07cb5a1d.ca69255821627.8144164908931126811@HIDDEN>
 <20190908171638.cna67eearj4rbn2k@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Priority: Medium
User-Agent: Zoho Mail
X-Mailer: Zoho Mail
X-Spam-Score: 0.0 (/)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

---- On Sun, 08 Sep 2019 12:16:38 -0500 pelzflorian (Florian Pelz) <pelzflo=
rian@HIDDEN> wrote ----

 > > Regarding URLs, I would prefer using IRIs, like follows:=20
 > >=20
 > >     /IETF-LANGUAGE-TAG/path/to/resource/=20
 > >=20
 > > So:=20
 > >=20
 > >     /es-ES/v=C3=ADdeos/=20
 > >     /es-CO/videos/=20
 > >=20
 > =20
 > As I understand it, es and es-ES and es-Latn-ES would all be language=20
 > tags (or just subtags??) for Spanish from Spain.  Do we use the full=20
 > tag es-Latn-ES?  Probably es-ES makes more sense than es-Latn-ES for=20
 > many languages (but not all).  The Translation Project will generally=20
 > only provide one script, it seems.  Maybe often es is enough.  I=20
 > suppose we could write an associative list mapping locales for which=20
 > translations exist to language tags.=20

I'm not suggesting any particular IETF language tags for Spanish variants, =
though. I think one could start supporting only the language tags equivalen=
t to the teams defined in the Translation Project (TP).=20

In the case of Spanish, many libre projects start focusing only on "es" (wh=
ich is the case for the TP), and that's ok, but it's good to support varian=
ts. As far as I understand, the TP allows creating teams for language varia=
nts (there is a pt_BR team). For example, I'd like to have an "es-CO" catal=
og to override some translations of the "es" catalog that are only common i=
n Spain.






Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Sun, 15 Sep 2019 20:19:01 +0000
Resent-Message-ID: <handler.26302.B26302.156857870514728 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: sirgazil <sirgazil@HIDDEN>
Cc: 26302 <26302 <at> debbugs.gnu.org>
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.156857870514728
          (code B ref 26302); Sun, 15 Sep 2019 20:19:01 +0000
Received: (at 26302) by debbugs.gnu.org; 15 Sep 2019 20:18:25 +0000
Received: from localhost ([127.0.0.1]:48756 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1i9ayW-0003pS-VM
	for submit <at> debbugs.gnu.org; Sun, 15 Sep 2019 16:18:25 -0400
Received: from pelzflorian.de ([5.45.111.108]:36584 helo=mail.pelzflorian.de)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pelzflorian@HIDDEN>) id 1i9ayU-0003pJ-Gv
 for 26302 <at> debbugs.gnu.org; Sun, 15 Sep 2019 16:18:23 -0400
Received: from pelzflorian.localdomain (unknown [5.45.111.108])
 by mail.pelzflorian.de (Postfix) with ESMTPSA id 4E4493602A4;
 Sun, 15 Sep 2019 22:18:20 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=pelzflorian.de;
 s=mail; t=1568578701;
 bh=4OH5b4NtiQImfBwk2OuFFCZG61FY6zgMHRR0hfRUqiE=;
 h=Date:From:To:Cc:Subject:References:In-Reply-To;
 b=Vsp0PiiJdgox7uWq2kRdAEKAzkVFnLeXM58wcAUQikNYhMEH9V13I7tnNSFJBV16+
 l9r+IB3lD1CqLomIrJWseO2l/vRxKsBLigypXLi92yB04jrLZZv6d3HgUPjJDiIdPP
 WgDnJ9o/VLEHiHWqEhblqyvJcUxPwRZh7P+/PmQ4=
Date: Sun, 15 Sep 2019 22:18:20 +0200
From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Message-ID: <20190915201819.3yxm25fayvbxwdpl@HIDDEN>
References: <20170329154040.ddscahwp2agknihb@abyayala>
 <16d07cb5a1d.ca69255821627.8144164908931126811@HIDDEN>
 <20190908171638.cna67eearj4rbn2k@HIDDEN>
 <16d18a5a9e8.12ab66c8254154.2756956535677606704@HIDDEN>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="uvu3qehc3367oshy"
Content-Disposition: inline
Content-Transfer-Encoding: 8bit
In-Reply-To: <16d18a5a9e8.12ab66c8254154.2756956535677606704@HIDDEN>
User-Agent: NeoMutt/20180716
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>


--uvu3qehc3367oshy
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: 8bit

On Mon, Sep 09, 2019 at 07:49:33PM -0500, sirgazil wrote:
> I think one could start supporting only the
> language tags equivalent to the teams defined in the Translation
> Project (TP).
> 

This is a good suggestion, I think.  Find attached new versions of all
patches that work on a berlin.scm virtual machine (slightly modified
to use substitutes and not run some services).  These include patches
for dropdown accessibility and an ugly language dropdown.

The language dropdown redirects to the homepage, because Haunt offers
no nice way to get the name of the same page.

I have used the code “en” for U.S. English because the TP team for
British English is already called en_GB, so its code would be en-GB.

What’s missing is code for adding the nginx plugin

https://www.nginx.com/resources/wiki/modules/accept_language/

to Guix so it can be used on berlin.scm.  It seems to offer all that
is required for redirecting existing URLs.

Regards,
Florian

--uvu3qehc3367oshy
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="0001-website-Use-needed-modules-in-posts.patch"

From fa96d7ec0a71dfea4b5c2cae8bdfb2a8f27f678d Mon Sep 17 00:00:00 2001
From: Florian Pelz <pelzflorian@HIDDEN>
Date: Thu, 18 Jul 2019 10:22:44 +0200
Subject: [PATCH 1/8] 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.23.0


--uvu3qehc3367oshy
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="0002-website-Fix-typing-mistake.patch"

From afd68ec639494320b5248b75315174d2dc1f7adb Mon Sep 17 00:00:00 2001
From: Florian Pelz <pelzflorian@HIDDEN>
Date: Sat, 31 Aug 2019 11:52:31 +0200
Subject: [PATCH 2/8] website: Fix typing mistake.

* website/apps/base/templates/contribute.scm (contribute-t):
Add missing word.
---
 website/apps/base/templates/contribute.scm | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/website/apps/base/templates/contribute.scm b/website/apps/base/templates/contribute.scm
index 6c4787f..4d68e87 100644
--- a/website/apps/base/templates/contribute.scm
+++ b/website/apps/base/templates/contribute.scm
@@ -201,7 +201,7 @@
 	(h3 (@ (id "testing")) "Test and Bug Reports")
 	(p
 	 "Install the software and send feedback to the community
-         about your experience. Help the project reporting bugs.")
+         about your experience. Help the project by reporting bugs.")
 	(p
 	 "Before reporting a bug, please check whether the bug is
          already "
-- 
2.23.0


--uvu3qehc3367oshy
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: attachment; filename="0003-website-Fix-typo.patch"
Content-Transfer-Encoding: 8bit

From 3bd446c4242f278123a113bd65ef2bf302a29afd Mon Sep 17 00:00:00 2001
From: Florian Pelz <pelzflorian@HIDDEN>
Date: Sat, 31 Aug 2019 21:00:29 +0200
Subject: [PATCH 3/8] website: Fix typo.

* website/apps/base/templates/security.scm (security-t): Fix typo.
---
 website/apps/base/templates/security.scm | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/website/apps/base/templates/security.scm b/website/apps/base/templates/security.scm
index ea997b2..b772912 100644
--- a/website/apps/base/templates/security.scm
+++ b/website/apps/base/templates/security.scm
@@ -16,7 +16,7 @@
   (theme
    #:title '("Security")
    #:description
-   "Important information about geting security updates for your
+   "Important information about getting security updates for your
    GNUGuix installation, and instructions on how to report
    security issues."
    #:keywords
-- 
2.23.0


--uvu3qehc3367oshy
Content-Type: text/plain; charset=utf-8
Content-Disposition: attachment; filename="0004-website-Add-custom-xgettext-to-extract-from-nested-s.patch"
Content-Transfer-Encoding: 8bit

From f7174a89cdaa0fbbbe5aa08c9934c80f34381242 Mon Sep 17 00:00:00 2001
From: Florian Pelz <pelzflorian@HIDDEN>
Date: Sun, 15 Sep 2019 21:28:28 +0200
Subject: [PATCH 4/8] website: Add custom xgettext to extract from nested sexps
 for i18n.

* website/scripts/sexp-xgettext.scm: New file for generating a POT file.
* website/sexp-xgettext.scm: New file with module for looking up
translations.
* website/apps/i18n.scm: New file.  Add utility functions.
* website/i18n-howto: New file with usage instructions.
* website/po/POTFILES: New file; list apps/base/templates files here.
* website/po/LINGUAS: New file.  List en_US lingua.
* website/po/ietf-tags.scm: New file.  Add association for en_US lingua.
* website/haunt.scm: Wrap each builder to build the locale set in LC_ALL.
* website/README: Adapt build instructions for i18n.
* website/.guix.scm: Make Haunt build directory writable so Haunt can
overwrite duplicate assets.  Convert PO files to MO files and build for
each lingua.
---
 website/.guix.scm                 |  76 ++-
 website/README                    |   8 +-
 website/apps/i18n.scm             | 127 +++++
 website/haunt.scm                 |  17 +-
 website/i18n-howto.txt            |  86 ++++
 website/po/LINGUAS                |   3 +
 website/po/POTFILES               |  34 ++
 website/po/ietf-tags.scm          |   9 +
 website/scripts/sexp-xgettext.scm | 823 ++++++++++++++++++++++++++++++
 website/sexp-xgettext.scm         | 530 +++++++++++++++++++
 10 files changed, 1690 insertions(+), 23 deletions(-)
 create mode 100644 website/apps/i18n.scm
 create mode 100644 website/i18n-howto.txt
 create mode 100644 website/po/LINGUAS
 create mode 100644 website/po/POTFILES
 create mode 100644 website/po/ietf-tags.scm
 create mode 100644 website/scripts/sexp-xgettext.scm
 create mode 100644 website/sexp-xgettext.scm

diff --git a/website/.guix.scm b/website/.guix.scm
index f6e50fb..a5fe505 100644
--- a/website/.guix.scm
+++ b/website/.guix.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix web site
 ;;; Copyright © 2017, 2019 Ludovic Courtès <ludo@HIDDEN>
+;;; Copyright © 2019 Florian Pelz <pelzflorian@HIDDEN>
 ;;;
 ;;; This file is part of the GNU Guix web site.
 ;;;
@@ -18,16 +19,27 @@
 
 ;; Run 'guix build -f .guix.scm' to build the web site.
 
+(define this-directory
+  (dirname (current-filename)))
+
+;; Make sure po/LINGUAS will be found in the current working
+;; directory.
+(chdir this-directory)
+
+;; We need %linguas from the (sexp-xgettext) module.
+;; Therefore, we add its path to the load path.
+(set! %load-path (cons this-directory %load-path))
+
 (use-modules (guix) (gnu)
              (guix modules)
              (guix git-download)
              (guix gexp)
              (guix channels)
              (srfi srfi-9)
-             (ice-9 match))
-
-(define this-directory
-  (dirname (current-filename)))
+             (ice-9 match)
+             (ice-9 rdelim)
+             (ice-9 regex)
+             (sexp-xgettext))
 
 (define source
   (local-file this-directory "guix-web-site"
@@ -72,7 +84,6 @@
                        (ice-9 match))
 
           (copy-recursively #$source ".")
-
           ;; Set 'GUILE_LOAD_PATH' so that Haunt find the Guix modules and
           ;; its dependencies.  To find out the load path of Guix and its
           ;; dependencies, fetch its value over 'guix repl'.
@@ -92,23 +103,60 @@
                                     ":"))))
             (close-pipe pipe))
 
+          ;; Make the copy writable so Haunt can overwrite duplicate assets.
+          (invoke #+(file-append (specification->package "coreutils")
+                                 "/bin/chmod")
+                  "--recursive" "u+w" ".")
+
+          ;; For translations, create MO files from PO files.
+          (for-each
+           (lambda (lingua)
+             (let* ((msgfmt #+(file-append (specification->package "gettext")
+                                           "/bin/msgfmt"))
+                    (lingua-file (string-append "po/" lingua ".po"))
+                    (lang (car (string-split lingua #\_)))
+                    (lang-file (string-append "po/" lang ".po")))
+               (define (create-mo filename)
+                 (begin
+                   (invoke msgfmt filename)
+                   (mkdir-p (string-append lingua "/LC_MESSAGES"))
+                   (rename-file "messages.mo"
+                                (string-append lingua "/LC_MESSAGES/"
+                                               "guix-website.mo"))))
+               (cond
+                ((file-exists? lingua-file)
+                 (create-mo lingua-file))
+                ((file-exists? lang-file)
+                 (create-mo lang-file))
+                (else #t))))
+           (list #$@%linguas))
+
           ;; So we can read/write UTF-8 files.
           (setenv "GUIX_LOCPATH"
                   #+(file-append (specification->package "glibc-utf8-locales")
                                  "/lib/locale"))
-          (setenv "LC_ALL" "en_US.utf8")
 
           ;; Use a sane default.
           (setenv "XDG_CACHE_HOME" "/tmp/.cache")
 
-          (invoke #+(file-append (specification->package "haunt")
-                                 "/bin/haunt")
-                  "build")
-
-          (mkdir-p #$output)
-          (copy-recursively "/tmp/gnu.org/software/guix" #$output
-                            #:log (%make-void-port "w"))
-          (symlink "guix.html" (string-append #$output "/index.html"))))))
+          ;; Build the website for each translation.
+          (for-each
+           (lambda (lingua)
+             (begin
+               (setenv "LC_ALL" (string-append lingua ".utf8"))
+               (invoke #+(file-append (specification->package "haunt")
+                                      "/bin/haunt")
+                       "build")
+               (mkdir-p #$output)
+               (copy-recursively "/tmp/gnu.org/software/guix" #$output
+                                 #:log (%make-void-port "w"))
+               (let ((tag (assoc-ref
+                           (call-with-input-file "po/ietf-tags.scm"
+                             (lambda (port) (read port)))
+                           lingua)))
+                 (symlink "guix.html"
+                          (string-append #$output "/" tag "/index.html")))))
+           (list #$@%linguas))))))
 
 (computed-file "guix-web-site" build)
 
diff --git a/website/README b/website/README
index d3a3a78..ff54053 100644
--- a/website/README
+++ b/website/README
@@ -24,14 +24,18 @@ commands:
 
 #+BEGIN_EXAMPLE
 $ cd path/to/guix-artwork/website
-$ GUIX_WEB_SITE_LOCAL=yes haunt build
+$ export GUILE_LOAD_PATH=$(guix build guile-syntax-highlight)/share/guile/site/2.2:$GUILE_LOAD_PATH
+$ LC_ALL=en_US.utf8 GUIX_WEB_SITE_LOCAL=yes haunt build
 $ haunt serve
 #+END_EXAMPLE
 
-Then, visit http://localhost:8080/guix.html in a web browser.
+Then, visit http://localhost:8080/en/guix.html in a web browser.
 
 You can stop the server pressing ~Ctrl + C~ twice.
 
+See also the file i18n-howto.txt for information on working with
+translations.
+
 * Deploying
 
 Like the pages of many GNU websites, this website is managed through
diff --git a/website/apps/i18n.scm b/website/apps/i18n.scm
new file mode 100644
index 0000000..bb60b32
--- /dev/null
+++ b/website/apps/i18n.scm
@@ -0,0 +1,127 @@
+;;; GNU Guix web site
+;;; Copyright © 2019 Florian Pelz <pelzflorian@HIDDEN>
+;;;
+;;; 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 (sexp-xgettext)
+  #:use-module (srfi srfi-1)
+  #:export (G_
+            N_
+            C_
+            NC_
+            %current-ietf-tag
+            %current-lang
+            %current-lingua
+            builder->localized-builder
+            builders->localized-builders
+            ietf-tags-file-contents
+            localize-url))
+
+(define %gettext-domain
+  "guix-website")
+
+(bindtextdomain %gettext-domain (getcwd))
+(bind-textdomain-codeset %gettext-domain "UTF-8")
+(textdomain %gettext-domain)
+
+;; NOTE: The sgettext macros have no hygiene because they use
+;; datum->syntax and do not preserve the semantics of anything looking
+;; like an sgettext macro.  This is an exceptional use case; do not
+;; try this at home.
+
+(define-syntax G_
+  sgettext)
+
+(set-simple-keywords! '(G_))
+
+(define-syntax N_ ;like ngettext
+  sngettext)
+
+(define-syntax C_ ;like pgettext
+  spgettext)
+
+(define-syntax NC_ ;like npgettext
+  snpgettext)
+
+(set-complex-keywords! '(N_ C_ NC_))
+
+(define <page>
+  (@@ (haunt page) <page>))
+
+(define %current-lingua
+  ;; strip the character encoding:
+  (car (string-split (setlocale LC_ALL) #\.)))
+
+(define-syntax ietf-tags-file-contents
+  (identifier-syntax
+   (force (delay (call-with-input-file
+                     "po/ietf-tags.scm"
+                   (lambda (port) (read port)))))))
+
+
+(define %current-ietf-tag
+  (or (assoc-ref ietf-tags-file-contents %current-lingua)
+      "en"))
+
+(define %current-lang
+  (car (string-split %current-ietf-tag #\-)))
+
+(define* (localize-url url #:key (lingua %current-ietf-tag))
+  "Given a URL as used in a href attribute, transforms it to point to
+the version for LINGUA as produced by builder->localized-builder."
+  (if (and (string-prefix? "/" url)
+           (or (string-suffix? ".html" url)
+               (string-suffix? "/" url)))
+      (string-append "/" lingua url)
+      url))
+
+(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."
+  arg)
+
+(define (builder->localized-builder builder)
+  "Returns a Haunt builder procedure generated from an existing
+BUILDER with translations for the current system locale coming from
+sexp-xgettext."
+  (compose
+   (lambda (pages)
+     (map
+      (lambda (page)
+        (match page
+          (($ <page> file-name contents writer)
+           (let ((new-name (string-append %current-ietf-tag
+                                          "/"
+                                          file-name)))
+             (make-page new-name contents writer)))
+          (else page)))
+      pages))
+   (lambda (site posts)
+     (first-value (builder site posts)))))
+
+(define (builders->localized-builders builders)
+  "Returns a list of new Haunt builder procedures generated from
+BUILDERS and localized via sexp-xgettext for the current system
+locale."
+  (flatten
+   (map-in-order
+    builder->localized-builder
+    builders)))
diff --git a/website/haunt.scm b/website/haunt.scm
index 9f66920..3d7963e 100644
--- a/website/haunt.scm
+++ b/website/haunt.scm
@@ -5,20 +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))
 
 (site #:title "GNU Guix"
       #:domain "https://guix.gnu.org"
       #: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"))))
diff --git a/website/i18n-howto.txt b/website/i18n-howto.txt
new file mode 100644
index 0000000..0d0c7c1
--- /dev/null
+++ b/website/i18n-howto.txt
@@ -0,0 +1,86 @@
+With sexp-xgettext, arbitrary s-expressions can be marked for
+translation (not only strings like with normal xgettext).
+
+S-expressions can be marked with G_ (simple marking for translation),
+N_ (“complex” marking with different forms depending on number like
+ngettext), C_ (“complex” marking distinguished from other markings by
+a msgctxt like pgettext) or NC_ (mix of both).
+
+Marking a string for translation behaves like normal gettext.  Marking
+a parenthesized expression (i.e. a list or procedure call) extracts
+each string from the parenthesized expression.  If a symbol, keyword
+or other parenthesized expression occurs between the strings, it is
+extracted as an XML element.  Expressions before or after all strings
+are not extracted.  If strings from a parenthesized sub-expression
+shall be extracted too, the sub-expression must again be marked with
+G_ unless it is the only sub-expression or it follows a quote,
+unquote, quasiquote or unquote-splicing.  The order of XML elements
+can be changed in the translation to produce a different ordering
+inside a parenthesized expression.  If a string shall not be extracted
+from a marked expression, it must be wrapped, for example by a call to
+the identity procedure.  Be careful when marking non-SHTML content
+such as procedure calls for translation: Additional strings will be
+inserted between non-string elements.
+
+Known issues:
+
+* Line numbers are sometimes off.
+
+* Some less important other TODOs in the comments.
+
+=====
+
+The following commands are an example of the translation for locale
+de_DE.  Adapt as necessary.  We assume the software requirements
+mentioned in the README are installed.
+
+To create a pot file:
+
+guile scripts/sexp-xgettext.scm -f po/POTFILES \
+                                -o po/guix-website.pot \
+                                --from-code=UTF-8 \
+                                --copyright-holder="Ludovic Courtès" \
+                                --package-name="guix-website" \
+                                --msgid-bugs-address="ludo@HIDDEN" \
+                                --keyword=G_ \
+                                --keyword=N_:1,2 \
+                                --keyword=C_:1c,2 \
+                                --keyword=NC_:1c,2,3
+
+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 build all languages:
+
+guix build -f .guix.scm
+
+To test the de_DE translation:
+
+guix environment --ad-hoc haunt
+LC_ALL=de_DE.utf8 \
+ 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
+
+For checking for errors / debugging newly marked files you can try:
+
+GUILE_LOAD_PATH=.:$(guix build haunt)/share/guile/site/2.2:\
+$(guix build guile-syntax-highlight)/share/guile/site/2.2:$GUILE_LOAD_PATH \
+ guile apps/base/templates/about.scm   # an example for debugging about.scm
diff --git a/website/po/LINGUAS b/website/po/LINGUAS
new file mode 100644
index 0000000..d4dd759
--- /dev/null
+++ b/website/po/LINGUAS
@@ -0,0 +1,3 @@
+# Translation with sexp-xgettext requires the full LL_CC locale name
+# to be specified.
+en_US
diff --git a/website/po/POTFILES b/website/po/POTFILES
new file mode 100644
index 0000000..c4f4b9c
--- /dev/null
+++ b/website/po/POTFILES
@@ -0,0 +1,34 @@
+# high-priority files that should come first in the PO file
+apps/base/utils.scm
+apps/base/templates/home.scm
+apps/base/templates/theme.scm
+apps/base/templates/components.scm
+apps/base/templates/about.scm
+apps/base/data.scm
+apps/base/templates/help.scm
+# other files
+apps/base/templates/contact.scm
+apps/base/templates/contribute.scm
+apps/base/templates/donate.scm
+apps/base/templates/graphics.scm
+apps/base/templates/irc.scm
+apps/base/templates/menu.scm
+apps/base/templates/screenshot.scm
+apps/base/templates/security.scm
+apps/download/data.scm
+apps/download/templates/components.scm
+apps/download/templates/download.scm
+apps/blog/templates/components.scm
+apps/blog/templates/feed.scm
+apps/blog/templates/post-list.scm
+apps/blog/templates/post.scm
+apps/blog/templates/tag.scm
+apps/download/data.scm
+apps/download/templates/components.scm
+apps/download/templates/download.scm
+apps/packages/templates/components.scm
+apps/packages/templates/detailed-index.scm
+apps/packages/templates/detailed-package-list.scm
+apps/packages/templates/index.scm
+apps/packages/templates/package-list.scm
+apps/packages/templates/package.scm
diff --git a/website/po/ietf-tags.scm b/website/po/ietf-tags.scm
new file mode 100644
index 0000000..8102a49
--- /dev/null
+++ b/website/po/ietf-tags.scm
@@ -0,0 +1,9 @@
+;;; This file contains an association list for each translation from
+;;; the locale to an IETF language tag to be used in the URL path of
+;;; translated pages.  The language tag results from the translation
+;;; team’s language code from
+;;; <https://translationproject.org/team/index.html>.  The underscore
+;;; in the team’s code is replaced by a hyphen.  For example, az would
+;;; be used for the Azerbaijani language (not az-Latn) and zh-CN would
+;;; be used for mainland Chinese (not zh-Hans-CN).
+(("en_US" . "en"))
diff --git a/website/scripts/sexp-xgettext.scm b/website/scripts/sexp-xgettext.scm
new file mode 100644
index 0000000..a21d289
--- /dev/null
+++ b/website/scripts/sexp-xgettext.scm
@@ -0,0 +1,823 @@
+;;; GNU Guix web site
+;;; Copyright © 2019 Florian Pelz <pelzflorian@HIDDEN>
+;;;
+;;; 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/>.
+
+(use-modules (ice-9 getopt-long)
+             (ice-9 match)
+             (ice-9 peg)
+             (ice-9 receive)
+             (ice-9 regex)
+             (ice-9 textual-ports)
+             (srfi srfi-1) ;lists
+             (srfi srfi-9) ;records
+             (srfi srfi-19) ;date
+             (srfi srfi-26)) ;cut
+
+;;; This script imitates xgettext, but combines nested s-expressions
+;;; in the input Scheme files to a single msgstr in the PO file.  It
+;;; works by first reading the keywords specified on the command-line,
+;;; then dealing with the remaining options using (ice-9 getopt-long).
+;;; Then, it parses each Scheme file in the POTFILES file specified
+;;; with --files-from and constructs po entries from it.  For parsing,
+;;; a PEG is used instead of Scheme’s read, because we can extract
+;;; comments with it.  The po entries are written to the PO file
+;;; specified with the --output option.  Scheme code can then use the
+;;; (sexp-xgettext) module to deconstruct the msgids looked up in the
+;;; PO file via gettext.
+
+(define-record-type <keyword-spec>
+  (make-keyword-spec id sg pl c total xcomment)
+  keyword-spec?
+  (id keyword-spec-id) ;identifier
+  (sg keyword-spec-sg) ;arg with singular
+  (pl keyword-spec-pl) ;arg with plural
+  (c keyword-spec-c) ;arg with msgctxt or 'mixed if sg is mixed msgctxt|singular
+  (total keyword-spec-total) ;total number of args
+  (xcomment keyword-spec-xcomment))
+
+(define (complex-keyword-spec? keyword-spec)
+  (match keyword-spec
+    (($ <keyword-spec> _ _ #f #f _ #f) #f)
+    (else #t)))
+
+(define %keyword-specs
+  ;; List of valid xgettext keyword options.
+  ;; Read keywords from command-line options.
+  (let loop ((opts (cdr (command-line)));command-line options from
+                                        ;which to extract --keyword
+                                        ;options
+             (remaining-opts '()) ;unhandled opts
+             (specs '()))
+    (define (string->integer str)
+      (if (string-match "[0-9]+" str)
+          (string->number str)
+          (error "Not a decimal integer.")))
+    (define* (argnums->spec id #:optional (argnums '()))
+      (let loop ((sg #f)
+                 (pl #f)
+                 (c #f)
+                 (total #f)
+                 (xcomment #f)
+                 (argnums argnums))
+        (match argnums
+          (() (make-keyword-spec id
+                                 (if sg sg 1)
+                                 pl
+                                 c
+                                 total
+                                 xcomment))
+          ((arg . argnums)
+           (cond
+            ((string-suffix? "c" arg)
+             (cond (c (error "c suffix clashes"))
+                   (else
+                    (let* ((number-str (string-drop-right arg 1))
+                           (number (string->integer number-str)))
+                      (loop sg pl number total xcomment argnums)))))
+            ((string-suffix? "g" arg)
+             (cond
+              (sg (error "Only first argnum can have g suffix."))
+              (c (error "g suffix clashes."))
+              (else
+               (let* ((number-str (string-drop-right arg 1))
+                      (number (string->integer number-str)))
+                 (loop number #f 'mixed total xcomment argnums)))))
+            ((string-suffix? "t" arg)
+             (cond (total (error "t suffix clashes"))
+                   (else
+                    (let* ((number-str (string-drop-right arg 1))
+                           (number (string->integer number-str)))
+                      (loop sg pl c number xcomment argnums)))))
+            ((string-suffix? "\"" arg)
+             (cond (xcomment (error "xcomment clashes"))
+                   (else
+                    (let* ((comment (substring arg
+                                               1
+                                               (- (string-length arg) 1))))
+                      (loop sg pl c total comment argnums)))))
+            (else
+             (let* ((number (string->integer arg)))
+               (if sg
+                   (if pl
+                       (error "Too many argnums.")
+                       (loop sg number c total xcomment argnums))
+                   (loop number #f c total xcomment argnums)))))))))
+
+    (define (string->spec str) ;see `info xgettext`
+      (match (string-split str #\:)
+        ((id) (argnums->spec id))
+        ((id argnums)
+         (argnums->spec id (string-split argnums #\,)))))
+    (match opts
+      (() (begin
+            ;; remove recognized --keyword command-line options:
+            (set-program-arguments (cons (car (command-line))
+                                         (reverse remaining-opts)))
+            specs))
+      ((current-opt . rest)
+       (cond
+        ((string=? "--" current-opt) specs)
+        ((string-prefix? "--keyword=" current-opt)
+         (let ((keyword (string-drop current-opt (string-length "--keyword="))))
+           (loop rest remaining-opts (cons (string->spec keyword) specs))))
+        ((or (string=? "--keyword" current-opt)
+             (string=? "-k" current-opt))
+         (let ((next-opt (car rest)))
+           (loop (cdr rest)
+                 remaining-opts
+                 (cons (string->spec next-opt) specs))))
+        (else (loop rest (cons current-opt remaining-opts) specs)))))))
+
+;;; Other options are not repeated, so we can use getopt-long:
+
+(define %options ;; Corresponds to what is documented at `info xgettext`.
+  (let ((option-spec
+         `((files (single-char #\f) (value #t))
+           (directory (single-char #\D) (value #t))
+           (default-domain (single-char #\d) (value #t))
+           (output (single-char #\o) (value #t))
+           (output-dir (single-char #\p) (value #t))
+           (from-code (value #t))
+           (join-existing (single-char #\j) (value #f))
+           (exclude-file (single-char #\x) (value #t))
+           (add-comments (single-char #\c) (value #t))
+
+           ;; Because getopt-long does not support repeated options,
+           ;; we took care of --keyword options further up.
+           ;; (keyword (single-char #\k) (value #t))
+
+           (flag (value #t))
+           (force-po (value #f))
+           (indent (single-char #\i) (value #f))
+           (no-location (value #f))
+           (add-location (single-char #\n) (value #t))
+           (width (single-char #\w) (value #t))
+           (no-wrap (value #f))
+           (sort-output (single-char #\s) (value #f))
+           (sort-by-file (single-char #\F) (value #f))
+           (omit-header (value #f))
+           (copyright-holder (value #t))
+           (foreign-user (value #f))
+           (package-name (value #t))
+           (package-version (value #t))
+           (msgid-bugs-address (value #t))
+           (msgstr-prefix (single-char #\m) (value #t))
+           (msgstr-suffix (single-char #\m) (value #t))
+           (help (value #f))
+           (pack (value #f)))))
+    (getopt-long (command-line) option-spec)))
+
+
+(define parse-scheme-file
+  ;; This procedure parses FILE and returns a parse tree.
+  (let ()
+    ;;TODO: Optionally ignore case.
+    (define-peg-pattern NL all "\n")
+    (define-peg-pattern comment all (and ";"
+                                         (* (and peg-any
+                                                 (not-followed-by NL)))
+                                         (and peg-any (followed-by NL))))
+    (define-peg-pattern empty none (or " " "\t"))
+    (define-peg-pattern whitespace body (or empty NL))
+    (define-peg-pattern quotation body (or "'" "`" "," ",@"))
+                                        ;TODO: Allow user to specify
+                                        ;other quote reader macros to
+                                        ;be ignored and also ignore
+                                        ;quote spelled out without
+                                        ;reader macro.
+    (define-peg-pattern open body (and (? quotation)
+                                       (or "(" "[" "{")))
+    (define-peg-pattern close body (or ")" "]" "}"))
+    (define-peg-pattern string body (and (followed-by "\"")
+                                         (* (or "\\\""
+                                                (and (or NL peg-any)
+                                                     (not-followed-by "\""))))
+                                         (and (or NL peg-any)
+                                              (followed-by "\""))
+                                         "\""))
+    (define-peg-pattern token all (or string
+                                      (and
+                                       (not-followed-by open)
+                                       (not-followed-by close)
+                                       (not-followed-by comment)
+                                       (* (and peg-any
+                                               (not-followed-by open)
+                                               (not-followed-by close)
+                                               (not-followed-by comment)
+                                               (not-followed-by string)
+                                               (not-followed-by whitespace)))
+                                       (or
+                                        (and peg-any (followed-by open))
+                                        (and peg-any (followed-by close))
+                                        (and peg-any (followed-by comment))
+                                        (and peg-any (followed-by string))
+                                        (and peg-any (followed-by whitespace))
+                                        (not-followed-by peg-any)))))
+    (define-peg-pattern list all (or (and (? quotation) "(" program ")")
+                                     (and (? quotation) "[" program "]")
+                                     (and (? quotation) "{" program "}")))
+    (define-peg-pattern t-or-s body (or token list))
+    (define-peg-pattern program all (* (or whitespace
+                                           comment
+                                           t-or-s)))
+    (lambda (file)
+      (call-with-input-file file
+        (lambda (port)
+          ;; It would be nice to match port directly without
+          ;; converting to a string first, but apparently guile cannot
+          ;; do that yet.
+          (let ((string (get-string-all port)))
+            (peg:tree (match-pattern program string))))))))
+
+
+(define-record-type <po-entry>
+  (make-po-entry ecomments ref flags ctxt id idpl)
+  po-entry?
+;;; irrelevant: (tcomments po-entry-tcomments) ;translator-comments
+  (ecomments po-entry-ecomments) ;extracted-comments
+  (ref po-entry-ref) ;reference
+  (flags po-entry-flags)
+;;; irrelevant: (prevctxt po-entry-prevctxt) ;previous-ctxt
+;;; irrelevant: (prev po-entry-prev) ;previous-translation
+  (ctxt po-entry-ctxt) ;msgctxt
+  (id po-entry-id) ;msgid
+  (idpl po-entry-idpl) ;msgid-plural
+;;; irrelevant: (str po-entry-str) ;msgstr string or association list
+;;;                                ;integer to string
+  )
+
+(define (po-equal? po1 po2)
+  "Returns whether PO1 and PO2 have equal ctxt, id and idpl."
+  (and (equal? (po-entry-ctxt po1) (po-entry-ctxt po2))
+       (equal? (po-entry-id po1) (po-entry-id po2))
+       (equal? (po-entry-idpl po1) (po-entry-idpl po2))))
+
+(define (combine-duplicate-po-entries list)
+  "Returns LIST with duplicate po entries replaced by a single PO
+entry with both refs."
+  (let loop ((remaining list))
+    (match remaining
+      (() '())
+      ((head . tail)
+       (receive (before from)
+           (break (cut po-equal? head <>) tail)
+         (cond
+          ((null? from) (cons head (loop tail)))
+          (else
+           (loop
+            (cons
+             (match head
+               (($ <po-entry> ecomments1 ref1 flags ctxt id idpl)
+                (match (car from)
+                  (($ <po-entry> ecomments2 ref2 _ _ _ _)
+                   (let ((ecomments (if (or ecomments1 ecomments2)
+                                        (append (or ecomments1 '())
+                                                (or ecomments2 '()))
+                                        #f))
+                         (ref (if (or ref1 ref2)
+                                  (string-join
+                                   (cons
+                                    (or ref1 "")
+                                    (cons
+                                     (or ref2 "")
+                                     '())))
+                                  #f)))
+                     (make-po-entry ecomments ref flags ctxt id idpl))))))
+             (append before (cdr from)))))))))))
+
+(define (write-po-entry po-entry)
+  (define (prepare-text text)
+    "If TEXT is false, returns #f.  Otherwise corrects the formatting
+of TEXT by escaping backslashes and newlines and enclosing TEXT in
+quotes. Note that Scheme’s write is insufficient because it would
+escape far more.  TODO: Strings should be wrappable to a maximum line
+width."
+    (and text
+         (string-append "\""
+                        (with-output-to-string
+                          (lambda ()
+                            (call-with-input-string text
+                              (lambda (port)
+                                (let loop ((c (get-char port)))
+                                  (unless (eof-object? c)
+                                    (case c
+                                      ((#\\) (display "\\"))
+                                      ((#\newline) (display "\\n"))
+                                      (else (write-char c)))
+                                    (loop (get-char port))))))))
+                        "\"")))
+  (define (write-component c prefix)
+    (when c
+      (begin (display prefix)
+             (display " ")
+             (display c)
+             (newline))))
+  (match po-entry
+    (($ <po-entry> ecomments ref flags ctxt id idpl)
+     (let ((prepared-ctxt (prepare-text ctxt))
+           (prepared-id (prepare-text id))
+           (prepared-idpl (prepare-text idpl)))
+       (when ecomments
+         (for-each
+          (lambda (line)
+            (write-component line "#."))
+          (reverse ecomments)))
+       (write-component ref "#:")
+       (write-component (and flags (string-join flags ", ")) "#,")
+       (write-component prepared-ctxt "msgctxt")
+       (write-component prepared-id "msgid")
+       (write-component prepared-idpl "msgid_plural")
+       (if idpl
+           (begin
+             (display "msgstr[0] \"\"")
+             (newline)
+             (display "msgstr[1] \"\""))
+           (display "msgstr \"\""))
+       (newline)))))
+
+(define %comments-line
+  (make-parameter #f))
+
+(define %ecomments-string
+  (make-parameter #f))
+
+(define (update-ecomments-string! str)
+  "Sets the value of the parameter object %ecomments-string if str is
+an ecomments string.  An ecomments string is extracted from a comment
+because it starts with TRANSLATORS or a key specified with
+--add-comments." ;TODO: Support for other keys is missing.
+  (cond
+   ((not str) (%ecomments-string #f))
+   ((= (1+ (or (%comments-line) -42)) (or (%line-number) 0))
+    (let ((m (string-match ";+[ \t]*(.*)" str)))
+      (when m
+        (%comments-line (%line-number))
+        (%ecomments-string
+         (if (%ecomments-string)
+             (cons (match:substring m 1) (%ecomments-string))
+             (list (match:substring m 1)))))))
+   (else
+    (let ((m (string-match ";+[ \t]*(TRANSLATORS:.*)" str)))
+      (if m
+          (begin
+            (%comments-line (%line-number))
+            (%ecomments-string
+             (if (%ecomments-string)
+                 (cons (match:substring m 1) (%ecomments-string))
+                 (list (match:substring m 1)))))
+          (%ecomments-string '#f))))))
+
+(define %file-name
+  (make-parameter #f))
+
+(define (update-file-name! name)
+  "Sets the value of the parameter object %file-name to NAME."
+  (%file-name name))
+
+(define %old-line-number
+  (make-parameter #f))
+
+(define (update-old-line-number! number)
+  "Sets the value of the parameter object %old-line-number to NUMBER."
+  (%old-line-number number))
+
+(define %line-number
+  (make-parameter #f))
+
+(define (update-line-number! number)
+  "Sets the value of the parameter object %line-number to NUMBER."
+  (%line-number number))
+
+(define (incr-line-number!)
+  "Increments the value of the parameter object %line-number by 1."
+  (%line-number (1+ (%line-number))))
+
+(define (incr-line-number-for-each-nl! list)
+  "Increments %line-number once for each NL recursively in LIST.  Does
+nothing if LIST is no list but e.g. an empty 'program."
+  (when (list? list)
+    (for-each
+     (lambda (part)
+       (match part
+         ('NL (incr-line-number!))
+         ((? list?) (incr-line-number-for-each-nl! part))
+         (else #f)))
+     list)))
+
+(define (current-ref)
+  "Returns the location field for a PO entry."
+  (let ((add (option-ref %options 'add-location 'full)))
+    (cond
+     ((option-ref %options 'no-location #f) #f)
+     ((eq? add 'full)
+      (string-append (%file-name) ":" (number->string (%line-number))))
+     ((eq? add 'file)
+      (%file-name))
+     ((eq? add 'never)
+      #f))))
+
+(define (make-simple-po-entry msgid)
+  (let ((po (make-po-entry
+             (%ecomments-string)
+             (current-ref)
+             #f ;TODO: Use scheme-format for format strings?
+             #f ;no ctxt
+             msgid
+             #f)))
+    (update-ecomments-string! #f)
+    po))
+
+
+(define (matching-keyword id)
+  "Returns the keyword-spec whose identifier is the same as ID, or #f
+if ID is no string or no such keyword-spec exists."
+  (and (symbol? id)
+       (let ((found (member (symbol->string id)
+                            %keyword-specs
+                            (lambda (id spec)
+                              (string=? id (keyword-spec-id spec))))))
+         (and found (car found)))))
+
+(define (nth-exp program n)
+  "Returns the Nth 'token or 'list inside the PROGRAM parse tree or #f
+if no tokens or lists exist."
+  (let loop ((i 0)
+             (rest program))
+    (define (on-hit exp)
+      (if (= i n) exp
+          ;; else:
+          (loop (1+ i) (cdr rest))))
+    (match rest
+      (() #f)
+      ((('token . _) . _) (on-hit (car rest)))
+      ((('list open-paren exp close-paren) . _) (on-hit (car rest)))
+      ((_ . _) (loop i (cdr rest)))
+      (else #f))))
+
+(define (more-than-one-exp? program)
+  "Returns true if PROGRAM consiste of more than one expression."
+  (if (matching-keyword (token->string-symbol-or-keyw (nth-exp program 0)))
+      (nth-exp program 2) ;if there is third element, keyword does not count
+      (nth-exp program 1)))
+
+(define (token->string-symbol-or-keyw tok)
+  "For a parse tree TOK, if it is a 'token parse tree, returns its
+value as a string, symbol or #:-keyword, otherwise returns #f."
+  (match tok
+    (('token (parts ...) . remaining)
+     ;; This is a string with line breaks in it.
+     (with-input-from-string
+         (string-append
+          (apply string-append
+                 (map-in-order
+                  (lambda (part)
+                    (match part
+                      (('NL _)
+                       (begin (incr-line-number!)
+                              "\n"))
+                      (else part)))
+                  parts))
+          (car remaining))
+       (lambda ()
+         (read))))
+    (('token exp)
+     (with-input-from-string exp
+       (lambda ()
+         (read))))
+    (else #f)))
+
+(define (complex-marked-list->po-entries parse-tree)
+  "Checks if PARSE-TREE is marked by a keyword.  If yes, for a complex
+keyword spec, returns a list of po-entries for it.  For a simple
+keyword spec, returns the argument number of its singular form.
+Otherwise returns #f."
+  (let* ((first (nth-exp parse-tree 0))
+         (spec (matching-keyword (token->string-symbol-or-keyw first))))
+    (if spec
+        (if ;if the identifier of a complex keyword occurs first
+         (complex-keyword-spec? spec)
+         ;; then make po entries for it
+         (match spec
+           (($ <keyword-spec> id sg pl c total xcomment)
+            (if (eq? c 'mixed) ; if msgctxt and singular msgid are in one string
+                (let* ((exp (nth-exp parse-tree sg))
+                       (val (token->string-symbol-or-keyw exp))
+                       (idx (if (string? val) (string-rindex val #\|))))
+                  (list
+                   (let ((po (make-po-entry
+                              (%ecomments-string)
+                              (current-ref)
+                              #f ;TODO: Use scheme-format for format strings?
+                              (string-take val idx)
+                              (string-drop val (1+ idx))
+                              #f))) ;plural forms are unsupported here
+                     (update-ecomments-string! #f)
+                     po)))
+                ;; else construct msgids
+                (receive (pl-id pl-entries)
+                    (match pl
+                      (#f (values #f '()))
+                      (else (construct-msgid-and-po-entries
+                             (nth-exp parse-tree pl))))
+                  (receive (sg-id sg-entries)
+                      (construct-msgid-and-po-entries
+                       (nth-exp parse-tree sg))
+                    (cons
+                     (let ((po (make-po-entry
+                                (%ecomments-string)
+                                (current-ref)
+                                #f ;TODO: Use scheme-format for format strings?
+                                (and c (token->string-symbol-or-keyw
+                                        (nth-exp parse-tree c)))
+                                sg-id
+                                pl-id)))
+                       (update-ecomments-string! #f)
+                       po)
+                     (append sg-entries pl-entries)))))))
+         ;; else if it is a simple keyword, return the argnum:
+         (keyword-spec-sg spec))
+        ;; if no keyword occurs, then false
+        #f)))
+
+(define (construct-po-entries parse-tree)
+  "Converts a PARSE-TREE resulting from a call to parse-scheme-file to
+a list of po-entry records.  Unlike construct-msgid-and-po-entries,
+strings are not collected to a msgid.  The list of po-entry records is
+the return value."
+  (let ((entries (complex-marked-list->po-entries parse-tree)))
+    (cond
+     ((list? entries) entries)
+     ((number? entries) ;parse-tree yields a single, simple po entry
+      (update-old-line-number! (%line-number))
+      (receive (id entries)
+          (construct-msgid-and-po-entries
+           (nth-exp parse-tree entries))
+        (update-line-number! (%old-line-number))
+        (let ((po (make-simple-po-entry id)))
+          (incr-line-number-for-each-nl! parse-tree)
+          (cons po entries))))
+     (else ;search for marked translations in parse-tree
+      (match parse-tree
+        (() '())
+        (('comment str) (begin
+                          (update-ecomments-string! str)
+                          '()))
+        (('NL _) (begin (incr-line-number!) '()))
+        (('token . _) (begin (incr-line-number-for-each-nl! parse-tree) '()))
+        (('list open-paren program close-paren)
+         (construct-po-entries program))
+        (('program . components)
+         (append-map construct-po-entries components))
+        ;; Note: PEG compresses empty programs to non-lists:
+        ('program
+         '()))))))
+
+(define* (tag counter prefix #:key (flavor 'start))
+  "Formats the number COUNTER as a tag according to FLAVOR, which is
+either 'start, 'end or 'empty for a start, end or empty tag,
+respectively."
+  (string-append "<"
+                 (if (eq? flavor 'end) "/" "")
+                 prefix
+                 (number->string counter)
+                 (if (eq? flavor 'empty) "/" "")
+                 ">"))
+
+(define-record-type <construct-fold-state>
+  (make-construct-fold-state msgid-string maybe-part counter po-entries)
+  construct-fold-state?
+  ;; msgid constructed so far; #f if none, "" if only empty string:
+  (msgid-string construct-fold-state-msgid-string)
+  ;; only append this if string follows:
+  (maybe-part construct-fold-state-maybe-part)
+  ;; counter for next tag:
+  (counter construct-fold-state-counter)
+  ;; complete po entries from marked sub-expressions:
+  (po-entries construct-fold-state-po-entries))
+
+(define* (construct-msgid-and-po-entries parse-tree
+                                         #:optional
+                                         (prefix ""))
+  "Like construct-po-entries, but with two return values.  The first
+is an accumulated msgid constructed from all components in PARSE-TREE
+for use in make-po-entry.  Non-strings are replaced by tags containing
+PREFIX.  The second return value is a list of po entries for
+sub-expressions marked with a complex keyword spec."
+  (match parse-tree
+    (() (values "" '()))
+    ;; Note: PEG compresses empty programs to non-lists:
+    ('program (values "" '()))
+    (('comment str) (begin
+                      (update-ecomments-string! str)
+                      (values "" '())))
+    (('NL _) (begin (incr-line-number!)
+                    (error "Program consists only of line break."
+                           `(,(%file-name) ,(%line-number)))))
+    (('token . _)
+     (let ((maybe-string (token->string-symbol-or-keyw parse-tree)))
+       (if (string? maybe-string)
+           (values maybe-string '())
+           (error "Single symbol marked for translation."
+                  `(,maybe-string ,(%file-name) ,(%line-number))))))
+    (('list open-paren program close-paren)
+     ;; parse program instead
+     (construct-msgid-and-po-entries program prefix))
+    (('program (? matching-keyword))
+     (error "Double-marked for translation."
+            `(,parse-tree ,(%file-name) ,(%line-number))))
+    (('program . components)
+     ;; Concatenate strings in parse-tree to a new msgid and add an
+     ;; <x> tag for each list in between.
+     (match
+         (fold
+          (lambda (component prev-state)
+            (match prev-state
+              (($ <construct-fold-state> msgid-string maybe-part
+                  counter po-entries)
+               (match component
+                 (('comment str) (begin (update-ecomments-string! str)
+                                        prev-state))
+                 (('NL _) (begin (incr-line-number!)
+                                 prev-state))
+                 (('token . _)
+                  (let ((maybe-string (token->string-symbol-or-keyw component)))
+                    (cond
+                     ((string? maybe-string)
+                      ;; if string, append maybe-string to previous msgid
+                      (make-construct-fold-state
+                       (string-append (or msgid-string "")
+                                      maybe-part maybe-string)
+                       ""
+                       counter
+                       po-entries))
+                     ((and (more-than-one-exp? components) ;not the only symbol
+                           (or (not msgid-string) ;no string so far
+                               (string-suffix? ">" msgid-string))) ;tag before
+                      prev-state) ;then ignore
+                     (else ;append tag representing the token
+                      (make-construct-fold-state
+                       msgid-string
+                       (string-append
+                        maybe-part
+                        (tag counter prefix #:flavor 'empty))
+                       (1+ counter)
+                       po-entries)))))
+                 (('list open-paren program close-paren)
+                  (let ((first (nth-exp program 0)))
+                    (incr-line-number-for-each-nl! list)
+                    (match (complex-marked-list->po-entries program)
+                      ((? list? result)
+                       (make-construct-fold-state
+                        msgid-string
+                        (string-append
+                         maybe-part
+                         (tag counter prefix #:flavor 'empty))
+                        (1+ counter)
+                        (append result po-entries)))
+                      (result
+                       (cond
+                        ((number? result)
+                         (receive (id entries)
+                             (construct-msgid-and-po-entries
+                              (nth-exp program result)
+                              (string-append prefix
+                                             (number->string counter)
+                                             "."))
+                           (make-construct-fold-state
+                            (string-append (or msgid-string "")
+                                           maybe-part
+                                           (tag counter prefix
+                                                #:flavor 'start)
+                                           id
+                                           (tag counter prefix
+                                                #:flavor 'end))
+                            ""
+                            (1+ counter)
+                            (append entries po-entries))))
+                        ((not (more-than-one-exp? components))
+                         ;; Singletons do not need to be marked.
+                         (receive (id entries)
+                             (construct-msgid-and-po-entries
+                              program
+                              prefix)
+                           (make-construct-fold-state
+                            id
+                            ""
+                            counter
+                            (append entries po-entries))))
+                        (else ;unmarked list
+                         (if (not msgid-string)
+                             ;; then ignore
+                             prev-state
+                             ;; else:
+                             (make-construct-fold-state
+                              msgid-string
+                              (string-append
+                               maybe-part
+                               (tag counter prefix #:flavor 'empty))
+                              (1+ counter)
+                              po-entries))))))))))))
+          (make-construct-fold-state #f "" 1 '())
+          components)
+       (($ <construct-fold-state> msgid-string maybe-part counter po-entries)
+        (values (or msgid-string
+                    (error "Marking for translation yields empty msgid."
+                           %file-name %line-number))
+                po-entries))))))
+
+(define scheme-file->po-entries
+  (compose construct-po-entries
+           parse-scheme-file))
+
+(define %files-from-port
+  (let ((files-from (option-ref %options 'files #f)))
+    (if files-from
+        (open-input-file files-from)
+        (current-input-port))))
+
+(define %source-files
+  (let loop ((line (get-line %files-from-port))
+             (source-files '()))
+    (if (eof-object? line)
+        (begin
+          (close-port %files-from-port)
+          source-files)
+        ;; else read file names before comment
+        (let ((before-comment (car (string-split line #\#))))
+          (loop (get-line %files-from-port)
+                (append
+                 (map match:substring (list-matches "[^ \t]+" before-comment))
+                 source-files))))))
+
+(define %output-po-entries
+  (fold (lambda (scheme-file po-entries)
+          (begin
+            (update-file-name! scheme-file)
+            (update-line-number! 1)
+            (update-old-line-number! #f)
+            (%comments-line #f)
+            (append (scheme-file->po-entries scheme-file)
+                    po-entries)))
+        '()
+        %source-files))
+
+(define %output-port
+  (let ((output (option-ref %options 'output #f))
+        (domain (option-ref %options 'default-domain #f)))
+    (cond
+     (output (open-output-file output))
+     (domain (open-output-file (string-append domain ".po")))
+     (else (open-output-file "messages.po")))))
+
+(with-output-to-port %output-port
+  (lambda ()
+    (let ((copyright (option-ref %options 'copyright-holder
+                                 "THE PACKAGE'S COPYRIGHT HOLDER"))
+          (package (option-ref %options 'package-name "PACKAGE"))
+          (version (option-ref %options 'package-version #f))
+          (bugs-email (option-ref %options 'msgid-bugs-address "")))
+      (display "# SOME DESCRIPTIVE TITLE.\n")
+      (display (string-append "# Copyright (C) YEAR " copyright "\n"))
+      (display (string-append "# This file is distributed under the same \
+license as the " package " package.\n"))
+      (display "# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n")
+      (display "#\n")
+      (write-po-entry (make-po-entry #f #f '("fuzzy") #f "" #f))
+      (display (string-append "\"Project-Id-Version: "
+                              package
+                              (if version
+                                  (string-append " " version)
+                                  "")
+                              "\\n\"\n"))
+      (display (string-append "\"Report-Msgid-Bugs-To: "
+                              bugs-email
+                              "\\n\"\n"))
+      (display (string-append "\"POT-Creation-Date: "
+                              (date->string (current-date) "~1 ~H:~M~z")
+                              "\\n\"\n"))
+      (display "\"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n")
+      (display "\"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n\"\n")
+      (display "\"Language-Team: LANGUAGE <LL@HIDDEN>\\n\"\n")
+      (display "\"Language: \\n\"\n")
+      (display "\"MIME-Version: 1.0\\n\"\n")
+      (display "\"Content-Type: text/plain; charset=UTF-8\\n\"\n")
+      (display "\"Content-Transfer-Encoding: 8bit\\n\"\n")
+      (for-each (lambda (po-entry)
+                  (begin
+                    (newline)
+                    (write-po-entry po-entry)))
+                (combine-duplicate-po-entries %output-po-entries)))))
diff --git a/website/sexp-xgettext.scm b/website/sexp-xgettext.scm
new file mode 100644
index 0000000..2b7abfc
--- /dev/null
+++ b/website/sexp-xgettext.scm
@@ -0,0 +1,530 @@
+;;; GNU Guix web site
+;;; Copyright © 2019 Florian Pelz <pelzflorian@HIDDEN>
+;;;
+;;; 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 (sexp-xgettext)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 peg)
+  #:use-module (ice-9 rdelim)
+  #:use-module (ice-9 receive)
+  #:use-module (ice-9 regex)
+  #:use-module (srfi srfi-1) ;lists
+  #:use-module (srfi srfi-9) ;records
+  #:export (set-complex-keywords!
+            set-simple-keywords!
+            sgettext
+            sngettext
+            spgettext
+            snpgettext
+            %linguas))
+
+(define %complex-keywords
+  ;; Use set-complex-keywords! to change this to a list of keywords
+  ;; for sexp-xgettext functions other than sgettext.
+  (make-parameter '()))
+
+(define (set-complex-keywords! kw)
+  (%complex-keywords kw))
+
+(define %simple-keywords
+  ;; Use set-simple-keywords! to change this to a list of keywords
+  ;; for sgettext.
+  (make-parameter '()))
+
+(define (set-simple-keywords! kw)
+  (%simple-keywords kw))
+
+(define (gettext-keyword? id)
+  (or (member id (%complex-keywords))
+      (member id (%simple-keywords))))
+
+;;COPIED FROM scripts/sexp-xgettext.scm:
+(define* (tag counter prefix #:key (flavor 'start))
+  "Formats the number COUNTER as a tag according to FLAVOR, which is
+either 'start, 'end or 'empty for a start, end or empty tag,
+respectively."
+  (string-append "<"
+                 (if (eq? flavor 'end) "/" "")
+                 prefix
+                 (number->string counter)
+                 (if (eq? flavor 'empty) "/" "")
+                 ">"))
+;;END COPIED FROM scripts/sexp-xgettext.scm
+
+;;ADAPTED FROM scripts/sexp-xgettext.scm
+(define-record-type <construct-fold-state>
+  (make-construct-fold-state msgid-string maybe-part counter)
+  construct-fold-state?
+  ;; msgid constructed so far; #f if none, "" if only empty string
+  (msgid-string construct-fold-state-msgid-string)
+  ;; only append this if string follows:
+  (maybe-part construct-fold-state-maybe-part)
+  ;; counter for next tag:
+  (counter construct-fold-state-counter))
+;;END ADAPTED FROM scripts/sexp-xgettext.scm
+
+(define (sexp->msgid exp)
+  "Return the msgid as constructed by construct-msgid-and-po-entries
+in scripts/sexp-xgettext.scm from the expression EXP."
+  (let loop ((exp exp)
+             (prefix ""))
+    (match exp
+      (() "")
+      ((or ('quote inner-exp)
+           ('quasiquote inner-exp)
+           ('unquote inner-exp)
+           ('unquote-splicing inner-exp))
+       (loop inner-exp prefix))
+      ((first-component . components)
+       (cond
+        ((gettext-keyword? first-component)
+         (error "Double-marked for translation." exp))
+        (else
+         (or
+          (construct-fold-state-msgid-string
+           (fold
+            (lambda (component prev-state)
+              (match prev-state
+                (($ <construct-fold-state> msgid-string maybe-part counter)
+                 (let inner-loop ((exp component))
+                   (match exp
+                     ((or (? symbol?) (? keyword?))
+                      (if (not msgid-string)
+                          ;; ignore symbols at the beginning
+                          prev-state
+                          ;; else make a tag for the symbol
+                          (make-construct-fold-state
+                           msgid-string
+                           (string-append maybe-part
+                                          (tag counter prefix #:flavor 'empty))
+                           (1+ counter))))
+                     ((? string?)
+                      (make-construct-fold-state
+                       (string-append (or msgid-string "")
+                                      maybe-part exp)
+                       "" counter))
+                     ((? list?)
+                      (match exp
+                        (() ;ignore empty list
+                         prev-state)
+                        ((or (singleton)
+                             ('quote singleton)
+                             ('quasiquote singleton)
+                             ('unquote singleton)
+                             ('unquote-splicing singleton))
+                         (inner-loop singleton))
+                        ((components ...)
+                         (cond
+                          ((and (not (null? components))
+                                (member (car components) (%simple-keywords)))
+                           ;; if marked for translation, insert inside tag
+                           (make-construct-fold-state
+                            (string-append (or msgid-string "")
+                                           maybe-part
+                                           (tag counter prefix #:flavor 'start)
+                                           (loop (cadr components)
+                                                 (string-append
+                                                  prefix
+                                                  (number->string counter)
+                                                  "."))
+                                           (tag counter prefix #:flavor 'end))
+                            ""
+                            (1+ counter)))
+                          ;; else ignore if first
+                          ((not msgid-string)
+                           prev-state)
+                          ;; else make empty tag
+                          (else (make-construct-fold-state
+                                 msgid-string
+                                 (string-append
+                                  maybe-part
+                                  (tag counter prefix #:flavor 'empty))
+                                 (1+ counter))))))))))))
+            (make-construct-fold-state #f "" 1)
+            exp))
+          (error "Marking for translation yields empty msgid." exp)))))
+      ((? string?) exp)
+      (else (error "Single symbol marked for translation." exp)))))
+
+(define-record-type <deconstruct-fold-state>
+  (make-deconstruct-fold-state tagged maybe-tagged counter)
+  deconstruct-fold-state?
+  ;; XML-tagged expressions as an association list name->expression:
+  (tagged deconstruct-fold-state-tagged)
+  ;; associate this not-yet-tagged expression with pre if string
+  ;; follows, with post if not:
+  (maybe-tagged deconstruct-fold-state-maybe-tagged)
+  ;; counter for next tag:
+  (counter deconstruct-fold-state-counter))
+
+(define (deconstruct exp msgstr)
+  "Return an s-expression like EXP, but filled with the content from
+MSGSTR."
+  (define (find-empty-element msgstr name)
+    "Returns the regex match structure for the empty tag for XML
+element of type NAME inside MSGSTR.  If the element does not exist or
+is more than the empty tag, #f is returned."
+    (string-match (string-append "<" (regexp-quote name) "/>") msgstr))
+  (define (find-element-with-content msgstr name)
+    "Returns the regex match structure for the non-empty XML element
+of type NAME inside MSGSTR.  Submatch 1 is its content.  If the
+element does not exist or is just the empty tag, #f is returned."
+    (string-match (string-append "<" (regexp-quote name) ">"
+                                 "(.*)"
+                                 "</" (regexp-quote name) ">")
+                  msgstr))
+  (define (get-first-element-name prefix msgstr)
+    "Returns the name of the first XML element in MSGSTR whose name
+begins with PREFIX, or #f if there is none."
+    (let ((m (string-match
+              (string-append "<(" (regexp-quote prefix) "[^>/.]+)/?>") msgstr)))
+      (and m (match:substring m 1))))
+  (define (prefix+counter prefix counter)
+    "Returns PREFIX with the number COUNTER appended."
+    (string-append prefix (number->string counter)))
+  (let loop ((exp exp)
+             (msgstr msgstr)
+             (prefix ""))
+    (define (unwrap-marked-expression exp)
+      "Returns two values for an expression EXP containing a (possibly
+quoted/unquoted) marking for translation with a simple keyword at its
+root.  The first return value is a list with the inner expression, the
+second is a procedure to wrap the processed inner expression in the
+same quotes or unquotes again."
+      (match exp
+        (('quote inner-exp)
+         (receive (unwrapped quotation)
+             (unwrap-marked-expression inner-exp)
+           (values unwrapped
+                   (lambda (res)
+                     (list 'quote (quotation res))))))
+        (('quasiquote inner-exp)
+         (receive (unwrapped quotation)
+             (unwrap-marked-expression inner-exp)
+           (values unwrapped
+                   (lambda (res)
+                     (list 'quasiquote (quotation res))))))
+        (('unquote inner-exp)
+         (receive (unwrapped quotation)
+             (unwrap-marked-expression inner-exp)
+           (values unwrapped
+                   (lambda (res)
+                     (list 'unquote (quotation res))))))
+        (('unquote-splicing inner-exp)
+         (receive (unwrapped quotation)
+             (unwrap-marked-expression inner-exp)
+           (values unwrapped
+                   (lambda (res)
+                     (list 'unquote-splicing (quotation res))))))
+        ((marking . rest) ;list with marking as car
+         ;; assume arg to translate is first argument to marking:
+         (values (list-ref rest 0) identity))))
+    (define (assemble-parenthesized-expression prefix tagged)
+      "Returns a parenthesized expression deconstructed from MSGSTR
+with the meaning of XML elements taken from the name->expression
+association list TAGGED.  The special tags [prefix]pre and
+[prefix]post are associated with a list of expressions before or after
+all others in the parenthesized expression with the prefix,
+respectively, in reverse order."
+      (append ;prepend pre elements to what is in msgstr
+       (reverse (or (assoc-ref tagged (string-append prefix "pre")) '()))
+       (let assemble ((rest msgstr))
+         (let ((name (get-first-element-name prefix rest)))
+           (cond
+            ((and name (find-empty-element rest name)) =>
+             ;; first XML element in rest is empty element
+             (lambda (m)
+               (cons*
+                (match:prefix m) ;prepend string before name
+                (assoc-ref tagged name) ;and expression for name
+                (assemble (match:suffix m)))))
+            ((and name (find-element-with-content rest name)) =>
+             ;; first XML element in rest has content
+             (lambda (m)
+               (receive (unwrapped quotation)
+                   (unwrap-marked-expression (assoc-ref tagged name))
+                 (cons*
+                  (match:prefix m) ;prepend string before name
+                  ;; and the deconstructed element with the content as msgstr:
+                  (quotation
+                   (loop
+                    unwrapped
+                    (match:substring m 1)
+                    (string-append name ".")))
+                  (assemble (match:suffix m))))))
+            (else
+             ;; there is no first element
+             (cons
+              rest ;return remaining string
+              (reverse ;and post expressions
+               (or (assoc-ref tagged (string-append prefix "post")) '())))))))))
+    (match exp
+      (() '())
+      (('quote singleton)
+       (cons 'quote (list (loop singleton msgstr prefix))))
+      (('quasiquote singleton)
+       (cons 'quasiquote (list (loop singleton msgstr prefix))))
+      (('unquote singleton)
+       (cons 'unquote (list (loop singleton msgstr prefix))))
+      (('unquote-splicing singleton)
+       (cons 'unquote-splicing (list (loop singleton msgstr prefix))))
+      ((singleton)
+       (list (loop singleton msgstr prefix)))
+      ((first-component . components)
+       (cond
+        ((gettext-keyword? first-component)
+         ;; another marking for translation
+         ;; -> should be an error anyway; just retain exp
+         exp)
+        (else
+         ;; This handles a single level of a parenthesized expression.
+         ;; assemble-parenthesized-expression will call loop to
+         ;; recurse to deeper levels.
+         (let ((tagged-state
+                (fold
+                 (lambda (component prev-state)
+                   (match prev-state
+                     (($ <deconstruct-fold-state> tagged maybe-tagged counter)
+                      (let inner-loop ((exp component) ;sexp to handle
+                                       (quoting identity)) ;for wrapping state
+                        (define (tagged-with-maybes)
+                          "Returns the value of tagged after adding
+all maybe-tagged expressions.  This should be used as the base value
+for tagged when a string or marked expression is seen."
+                          (match counter
+                            (#f
+                             (alist-cons (string-append prefix "pre")
+                                         maybe-tagged
+                                         tagged))
+                            ((? number?)
+                             (let accumulate ((prev-counter counter)
+                                              (maybes (reverse maybe-tagged)))
+                               (match maybes
+                                 (() tagged)
+                                 ((head . tail)
+                                  (alist-cons
+                                   (prefix+counter prefix prev-counter)
+                                   head
+                                   (accumulate (1+ prev-counter) tail))))))))
+                        (define (add-maybe exp)
+                          "Returns a deconstruct-fold-state with EXP
+added to maybe-tagged.  This should be used for expressions that are
+neither strings nor marked for translation with a simple keyword."
+                          (make-deconstruct-fold-state
+                           tagged
+                           (cons (quoting exp) maybe-tagged)
+                           counter))
+                        (define (counter-with-maybes)
+                          "Returns the old counter value incremented
+by one for each expression in maybe-tagged.  This should be used
+together with tagged-with-maybes."
+                          (match counter
+                            ((? number?)
+                             (+ counter (length maybe-tagged)))
+                            (#f
+                             1)))
+                        (define (add-tagged exp)
+                          "Returns a deconstruct-fold-state with an
+added association in tagged from the current counter to EXP.  If
+MAYBE-TAGGED is not empty, associations for its expressions are added
+to pre or their respective counter.  This should be used for
+expressions marked for translation with a simple keyword."
+                          (let ((c (counter-with-maybes)))
+                            (make-deconstruct-fold-state
+                             (alist-cons
+                              (prefix+counter prefix c)
+                              (quoting exp)
+                              (tagged-with-maybes))
+                             '()
+                             (1+ c))))
+                        (match exp
+                          (('quote inner-exp)
+                           (inner-loop inner-exp
+                                       (lambda (res)
+                                         (list 'quote res))))
+                          (('quasiquote inner-exp)
+                           (inner-loop inner-exp
+                                       (lambda (res)
+                                         (list 'quasiquote res))))
+                          (('unquote inner-exp)
+                           (inner-loop inner-exp
+                                       (lambda (res)
+                                         (list 'unquote res))))
+                          (('unquote-splicing inner-exp)
+                           (inner-loop inner-exp
+                                       (lambda (res)
+                                         (list 'unquote-splicing res))))
+                          (((? gettext-keyword?) . rest)
+                           (add-tagged exp))
+                          ((or (? symbol?) (? keyword?) (? list?))
+                           (add-maybe exp))
+                          ((? string?)
+                           ;; elements in maybe-tagged appear between strings
+                           (let ((c (counter-with-maybes)))
+                             (make-deconstruct-fold-state
+                              (tagged-with-maybes)
+                              '()
+                              c))))))))
+                 (make-deconstruct-fold-state '() '() #f)
+                 exp)))
+           (match tagged-state
+             (($ <deconstruct-fold-state> tagged maybe-tagged counter)
+              (assemble-parenthesized-expression
+               prefix
+               (match maybe-tagged
+                 (() tagged)
+                 (else ;associate maybe-tagged with pre or post
+                  (alist-cons
+                   (cond ;if there already is a pre, use post
+                    ((assoc-ref tagged (string-append prefix "pre"))
+                     (string-append prefix "post"))
+                    (else (string-append prefix "pre")))
+                   maybe-tagged
+                   tagged))))))))))
+      ((? string?) msgstr)
+      (else (error "Single symbol marked for translation." exp)))))
+
+;; NOTE: The sgettext macros have no hygiene because they use
+;; datum->syntax and do not preserve the semantics of anything looking
+;; like an sgettext macro.  This is an exceptional use case; do not
+;; try this at home.
+
+(define (sgettext x)
+  "After choosing an identifier for marking s-expressions for
+translation, make it usable by defining a macro with it calling
+sgettext.  If for example the chosen identifier is G_,
+use (define-syntax G_ sgettext)."
+  (syntax-case x ()
+    ((id exp)
+     (let* ((msgid (sexp->msgid (syntax->datum #'exp)))
+            (new-exp (deconstruct (syntax->datum #'exp)
+                                  (gettext msgid))))
+       (datum->syntax #'id new-exp)))))
+
+;; gettext’s share/gettext/gettext.h tells us we can prepend a msgctxt
+;; and #\eot before a msgid in a gettext call.
+
+(define (spgettext x)
+  "After choosing an identifier for behavior similar to pgettext:1c,2,
+make it usable like (define-syntax C_ spgettext)."
+  (syntax-case x ()
+    ((id msgctxt exp)
+     (let* ((gettext-context-glue #\eot) ;as defined in gettext.h
+            (lookup (string-append (syntax->datum #'msgctxt)
+                                   (string gettext-context-glue)
+                                   (sexp->msgid (syntax->datum #'exp))))
+            (msgstr (car (reverse (string-split (gettext lookup)
+                                                gettext-context-glue))))
+            (new-exp (deconstruct (syntax->datum #'exp)
+                                  msgstr)))
+       (datum->syntax #'id new-exp)))))
+
+(define %plural-numbers
+  ;; Hard-coded list of input numbers such that for each language’s
+  ;; plural formula, for each possible output grammatical number,
+  ;; there is an n among %plural-numbers that yields this output
+  ;; (cf. section Plural forms in the gettext manual), except 1 is
+  ;; omitted from this list because it is a special case for
+  ;; sngettext.  That is, calling ngettext with each number from
+  ;; %plural-numbers and with 1 in any locale is guaranteed to return
+  ;; each plural form at least once.  It would be more resilient
+  ;; towards new languages if instead of hard-coding we computed this
+  ;; from the Plural-Forms in the MO file header entry, but that is
+  ;; not worth the incurred code complexity.
+  '(0 2 3 11 100))
+
+(define (sngettext x)
+  "After choosing an identifier for behavior similar to ngettext:1,2,
+make it usable like (define-syntax N_ sngettext).  sngettext takes
+into account that not all languages have only singular and plural
+forms."
+  (syntax-case x ()
+    ((id exp1 exp2 n)
+     (let* ((msgid1 (sexp->msgid (syntax->datum #'exp1)))
+            (msgid2 (sexp->msgid (syntax->datum #'exp2)))
+            (msgstr1 (ngettext msgid1 msgid2 1))
+            (result (acons ;return an association list msgstr->deconstructed
+                     ;; msgstr for n=1:
+                     msgstr1
+                     `(,'unquote ,(deconstruct (syntax->datum #'exp1)
+                                               msgstr1))
+                     ;; other msgstr for n of each plural form:
+                     (map
+                      (lambda (n)
+                        (let ((msgstr (ngettext msgid1 msgid2 n)))
+                          (cons msgstr `(,'unquote
+                                         ,(deconstruct (syntax->datum #'exp2)
+                                                       msgstr)))))
+                      %plural-numbers))))
+       (datum->syntax
+        #'id
+        `(,assoc-ref (,'quasiquote ,result)
+                     (,ngettext ,msgid1 ,msgid2 ,(syntax->datum #'n))))))))
+
+(define (snpgettext x)
+  "After choosing an identifier for behavior similar to npgettext:1c,2,3,
+make it usable like (define-syntax NC_ snpgettext)."
+  (syntax-case x ()
+    ((id msgctxt exp1 exp2 n)
+     (let* ((gettext-context-glue #\eot) ;as defined in gettext.h
+            (msgid1 (string-append (syntax->datum #'msgctxt)
+                                   (string gettext-context-glue)
+                                   (sexp->msgid (syntax->datum #'exp1))))
+            ;; gettext.h implementation shows: msgctxt is only part of msgid1.
+            (msgid2 (sexp->msgid (syntax->datum #'exp2)))
+            (msgstr1 (car
+                      (reverse
+                       (string-split
+                        (ngettext msgid1 msgid2 1)
+                        gettext-context-glue))))
+            (result (acons ;return an association list msgstr->deconstructed
+                     ;; msgstr for n=1:
+                     msgstr1
+                     `(,'unquote ,(deconstruct (syntax->datum #'exp1)
+                                               msgstr1))
+                     ;; other msgstr for n of each plural form:
+                     (map
+                      (lambda (n)
+                        (let ((msgstr (car
+                                       (reverse
+                                        (string-split
+                                         (ngettext msgid1 msgid2 n)
+                                         gettext-context-glue)))))
+                          (cons msgstr `(,'unquote
+                                         ,(deconstruct (syntax->datum #'exp2)
+                                                       msgstr)))))
+                      %plural-numbers))))
+       (datum->syntax
+        #'id
+        `(,assoc-ref (,'quasiquote ,result)
+                     (,car
+                      (,reverse
+                       (,string-split
+                        (,ngettext ,msgid1 ,msgid2 ,(syntax->datum #'n))
+                        ,gettext-context-glue)))))))))
+
+(define %linguas
+  (with-input-from-file "po/LINGUAS"
+    (lambda _
+      (let loop ((line (read-line)))
+        (if (eof-object? line)
+            '()
+            ;; else read linguas before comment
+            (let ((before-comment (car (string-split line #\#))))
+              (append
+               (map match:substring (list-matches "[^ \t]+" before-comment))
+               (loop (read-line)))))))))
-- 
2.23.0


--uvu3qehc3367oshy
Content-Type: text/plain; charset=utf-8
Content-Disposition: attachment; filename="0005-website-Mark-all-files-in-apps-for-translation.patch"
Content-Transfer-Encoding: 8bit

From e3ddfc769631e8899ba8114f454502c73d8e7691 Mon Sep 17 00:00:00 2001
From: Florian Pelz <pelzflorian@HIDDEN>
Date: Sun, 15 Sep 2019 17:15:48 +0200
Subject: [PATCH 5/8] website: Mark all files in apps for translation.

* website/po/guix-website.pot: New file.
* website/apps/base/utils.scm (manual-url-with-language): New
procedure.
(locale-display-name): New procedure.
(guix-url): Use localized URLs by default.
* website/apps/base/templates/components.scm (manual-href,
manual-link-yellow): New procedures.
(breadcrumbs, contact->shtml, navbar): Mark for translation.
* website/apps/base/data.scm (contact-media, screenshots): Mark for
translation.
* website/apps/base/templates/about.scm (about-t): Mark for
translation.
* website/apps/base/templates/contact.scm (contact-t): Mark for
translation.
* website/apps/base/templates/contribute.scm (contribute-t): Mark for
translation.
* website/apps/base/templates/donate.scm (donate-t): Mark for
translation.
* website/apps/base/templates/graphics.scm (graphics-t): Mark for
translation.
* website/apps/base/templates/help.scm (help-t): Mark for translation.
* website/apps/base/templates/home.scm (home-t): Mark for translation.
* website/apps/base/templates/irc.scm (irc-t): Mark for translation.
* website/apps/base/templates/menu.scm (menu-t): Mark for translation.
* website/apps/base/templates/screenshot.scm (screenshot-t):
Mark for translation.
* website/apps/base/templates/security.scm (security-t): Mark for
translation.
* website/apps/base/templates/theme.scm (theme): Mark for translation.
* website/apps/blog/templates/components.scm (post-preview, sidebar):
Mark for translation.
* website/apps/blog/templates/feed.scm (atom-feed-t): Mark for
translation.
* website/apps/blog/templates/post-list.scm (post-list-t): Mark for
translation.
* website/apps/blog/templates/post.scm (post-t): Mark for translation.
* website/apps/blog/templates/tag.scm (tag-t): Mark for translation.
* website/apps/download/data.scm (home-t): Mark for translation.
* website/apps/download/templates/components.scm (system-downloads):
Mark for translation.
* website/apps/download/templates/download.scm (download-t): Mark for
translation.
* website/apps/packages/templates/components.scm (detailed-package-preview,
letter-selector, sidebar, supported-systems->shtml): Mark for translation.
* website/apps/packages/templates/detailed-index.scm (detailed-index-t):
Mark for translation.
* website/apps/packages/templates/detailed-package-list.scm
(detailed-package-list-t): Mark for translation.
* website/apps/packages/templates/index.scm (index-t): Mark for translation.
* website/apps/packages/templates/package-list.scm (package-list-t):
Mark for translation.
* website/apps/packages/templates/package.scm (package-t): Mark for
translation.
---
 website/apps/base/data.scm                    |  242 ++--
 website/apps/base/templates/about.scm         |  169 ++-
 website/apps/base/templates/components.scm    |  102 +-
 website/apps/base/templates/contact.scm       |   20 +-
 website/apps/base/templates/contribute.scm    |  385 +++---
 website/apps/base/templates/donate.scm        |  397 +++---
 website/apps/base/templates/graphics.scm      |   87 +-
 website/apps/base/templates/help.scm          |  100 +-
 website/apps/base/templates/home.scm          |  245 ++--
 website/apps/base/templates/irc.scm           |   48 +-
 website/apps/base/templates/menu.scm          |   17 +-
 website/apps/base/templates/screenshot.scm    |   14 +-
 website/apps/base/templates/security.scm      |   91 +-
 website/apps/base/templates/theme.scm         |   51 +-
 website/apps/base/utils.scm                   |   49 +-
 website/apps/blog/templates/components.scm    |   16 +-
 website/apps/blog/templates/feed.scm          |    3 +-
 website/apps/blog/templates/post-list.scm     |   23 +-
 website/apps/blog/templates/post.scm          |   14 +-
 website/apps/blog/templates/tag.scm           |   27 +-
 website/apps/download/data.scm                |   46 +-
 .../apps/download/templates/components.scm    |   12 +-
 website/apps/download/templates/download.scm  |   68 +-
 .../apps/packages/templates/components.scm    |   80 +-
 .../packages/templates/detailed-index.scm     |   47 +-
 .../templates/detailed-package-list.scm       |   23 +-
 website/apps/packages/templates/index.scm     |   45 +-
 .../apps/packages/templates/package-list.scm  |   21 +-
 website/apps/packages/templates/package.scm   |   56 +-
 website/po/guix-website.pot                   | 1216 +++++++++++++++++
 30 files changed, 2654 insertions(+), 1060 deletions(-)
 create mode 100644 website/po/guix-website.pot

diff --git a/website/apps/base/data.scm b/website/apps/base/data.scm
index dfe65fe..1a4217c 100644
--- a/website/apps/base/data.scm
+++ b/website/apps/base/data.scm
@@ -1,10 +1,15 @@
 ;;; GNU Guix web site
+;;; Copyright © 2019 Florian Pelz <pelzflorian@HIDDEN>
 ;;; Initially written by sirgazil who waves all
 ;;; copyright interest on this file.
 
 (define-module (apps base data)
+  #:use-module (apps base templates components)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
+  #:use-module (srfi srfi-1)
+  #:use-module (sexp-xgettext)
   #:export (contact-media
 	    screenshots))
 
@@ -17,150 +22,187 @@
   (list
    ;; The first three will be featured in the home page.
    (contact
-    #:name "IRC Channel"
+    #:name (G_ "IRC Channel")
     #:description
-    '(p
-      "Join the " (code "#guix") " channel on the Freenode IRC network to chat
-      with the community about GNU Guix or to get help in
-      real-time.")
+    (G_
+     `(p
+       "Join the " (code "#guix") " channel on the Freenode IRC network to chat
+       with the community about GNU Guix or to get help in
+       real-time."))
     #:url (guix-url "contact/irc/")
     #:log guix-irc-log-url)
 
    (contact
-    #:name "Info Mailing List"
+    #:name (G_ "Info Mailing List")
     #:description
-    '(p "Subscribe to the " (code "info-guix") " low-traffic mailing
+    (G_
+     `(p
+       "Subscribe to the " (code "info-guix") " low-traffic mailing
 list to receive important announcements sent by the project maintainers (in
-English).")
+English)."))
     #:url "https://lists.gnu.org/mailman/listinfo/info-guix"
     #:log "https://lists.gnu.org/archive/html/info-guix")
 
    (contact
-    #:name "Help Mailing List"
+    #:name (G_ "Help Mailing List")
     #:description
-    `(("de"
-       "Melden Sie sich bei der „Help“-Mailingliste an, um per E-Mail
+    ;; Compute an association list from language code to blurb.
+    ;; If possible, look up translated blurbs from the PO file.
+    ;; Fall back to old hard-coded translations.
+    (let ((original '(G_
+                      "Subscribe to the Help mailing list to get support
+from the GNU Guix community via email.  You can post messages in English
+though we also accept other languages."))
+          (lang-code '(C_ "unique lingua code like en or zh-cn" "en")))
+      (sort
+       (delete-duplicates
+        (append
+         (delete ;delete untranslated blurbs other than "en"
+          (cons original lang-code)
+          (map-in-order
+           (lambda (lingua)
+             (begin
+               (setlocale LC_ALL (string-append lingua ".utf8"))
+               (let ((out (list (gettext (string-append
+                                          (cadr lang-code) ;msgctxt
+                                          (string #\eot) ;separates msgctxt
+                                          (caddr lang-code))) ;msgid
+                                (gettext (cadr original)))))
+                 (setlocale LC_ALL "")
+                 (if (string-index (car out) #\eot) ;if untranslated
+                     (list (caddr lang-code) (cadr original)) ;use original
+                     out)))) ;else use what has been looked up via gettext
+           %linguas)
+          (lambda (to-delete b) (and ;delete where text is equal to original
+                                 (string=? (cadar to-delete) (cadr b))
+                                 ;; but language code is different
+                                 (not (string=? (cadddr to-delete) (car b))))))
+         `(("de"
+            "Melden Sie sich bei der „Help“-Mailingliste an, um per E-Mail
 gemeinschaftlichen Rat zu GuixSD und Guix zu bekommen.  Sie können
 Nachrichten auch auf deutsch verfassen.")
-      ("en"
-       "Subscribe to the Help mailing list to get support from the
-GNU Guix community via email.  You can post messages in English though we
-also accept other languages.")
-      ("eo"
-       "Subskribu al la retmesaĝolisto \"Help\" por demandi helpon pri
+           ("eo"
+            "Subskribu al la retmesaĝolisto \"Help\" por demandi helpon pri
 GNU Guix al la grupo.  Vi povas skribi esperantlingve.")
-      ("es"
-       "Suscríbete a la lista de correo electrónico \"Help\" por pedir
+           ("es"
+            "Suscríbete a la lista de correo electrónico \"Help\" por pedir
 ayuda con Guix.  Puedes escribir mensajes en Español.")
-      ("fr"
-       "Abonnez-vous à la liste de diffusion « Help » pour obtenir l'aide
+           ("fr"
+             "Abonnez-vous à la liste de diffusion « Help » pour obtenir l'aide
 de la communauté sur GNU Guix par courrier électronique.  Vous
 pouvez envoyer des messages en français.")
-      ("hu"
-       "Iratkozzon fel a „Help“ levelezőlistára, hogy segítséget kaphasson
+           ("hu"
+            "Iratkozzon fel a „Help“ levelezőlistára, hogy segítséget kaphasson
 e-mailben a GuixSD és a GNU Guix közösségtől. Magyarul is küldhet
 üzeneteket.")
-      ("it"
-       "Iscrivetevi alla mailing list 'Help' per essere aiutati da altri
+           ("it"
+            "Iscrivetevi alla mailing list 'Help' per essere aiutati da altri
 utenti di Guix e GuixSD.  Potete scrivere sulla mailing list anche in
 italiano.")
-      ("ja"
-       "メールでGNU GuixとGuixSDのコミュニティからサポートを受けるには、
+           ("ja"
+            "メールでGNU GuixとGuixSDのコミュニティからサポートを受けるには、
 「Help」のメーリングリストに登録してください。
 メッセージ内容は日本語でも問題ございませんが、多言語でも受け付けております。")
-      ("nb"
-       "Meld deg på diskusjonslisten «Help» for å få råd og tips fra
+           ("nb"
+            "Meld deg på diskusjonslisten «Help» for å få råd og tips fra
 andre GuixSD- og GNU Guix-brukere via e-post.  Du kan legge inn
 meldinger på norsk.")
-      ("nl"
-       "Abonneer je op de discussielijst \"Help\" om hulp te vragen
+           ("nl"
+            "Abonneer je op de discussielijst \"Help\" om hulp te vragen
 van de GuixSD- en GNU Guix-gemeenschap.  Je kunt berichten sturen in
 het Nederlands.")
-      ("ru"
-       "Подпишитесь на список рассылки «Help», чтобы получить помощь от
+           ("ru"
+            "Подпишитесь на список рассылки «Help», чтобы получить помощь от
 сообщества GuixSD и GNU Guix по электронной почте.  Вы можете писать на русском
 языке.")
-      ("zh"
-       "訂閱「Help」郵件群組以電郵從GuixSD及GNU Guix社群取得支援。你可以使用
-正體、繁體中文發送訊息"))
-
+           ("zh"
+            "訂閱「Help」郵件群組以電郵從GuixSD及GNU Guix社群取得支援。你可以使用
+正體、繁體中文發送訊息")))
+        (lambda (a b) (string=? (car a) (car b))))
+       (lambda (a b) (string<? (car a) (car b)))))
     #:url "https://lists.gnu.org/mailman/listinfo/help-guix"
     #:log "https://lists.gnu.org/archive/html/help-guix")
 
    (contact
-    #:name "Bug Reporting"
+    #:name (G_ "Bug Reporting")
     #:description
-    '(p
-      "If you found a bug in Guix, check whether the bug is
-      already in the "
-      (a (@ (href "https://issues.guix.gnu.org"))
-	 "bug database")
-      ". If it is not, please "
-      (a (@ (href "mailto:bug-guix@HIDDEN")) "report it."))
+    (G_
+     `(p
+       "If you found a bug in Guix, check whether the bug is
+       already in the "
+       ,(G_ `(a (@ (href "https://issues.guix.gnu.org"))
+                "bug database"))
+       ". If it is not, please "
+       ,(G_ `(a (@ (href "mailto:bug-guix@HIDDEN")) "report it."))))
     #:url "https://lists.gnu.org/mailman/listinfo/bug-guix"
     #:log "https://issues.guix.gnu.org/")
 
    (contact
-    #:name "Development Mailing List"
+    #:name (G_ "Development Mailing List")
     #:description
-    '(p
-      "Discussion about the development of GNU Guix. "
-      (a (@ (href "https://lists.gnu.org/archive/html/bug-guix/2013-07/msg00039.html"))
-	 " Until July 2013")
-      ", the bug-Guix mailing list filled that role. ")
+    (G_
+     `(p
+       "Discussion about the development of GNU Guix. "
+       ,(G_ `(a (@ (href "https://lists.gnu.org/archive/html/bug-guix/2013-07/msg00039.html"))
+                " Until July 2013"))
+       ", the bug-Guix mailing list filled that role. "))
     #:url "https://lists.gnu.org/mailman/listinfo/guix-devel"
     #:log "https://lists.gnu.org/archive/html/guix-devel")
 
    (contact
-    #:name "Patches Mailing List"
+    #:name (G_ "Patches Mailing List")
     #:description
-    `(p
-      "Submission of patches.  Every message sent to this mailing list
-      leads to a new entry in our "
-      (a (@ (href "https://issues.guix.gnu.org"))
-	 "patch tracking tool")
-      ".  See "
-      (a (@ (href "https://debbugs.gnu.org/Advanced.html")) "this page")
-      " for more information on how to use it; see "
-      (a (@ (href ,(manual-url "Submitting-Patches.html")))
-         "the manual")
-      " for more information on how to submit a patch.  "
-      (a (@ (href "https://lists.gnu.org/archive/html/guix-devel/2017-02/msg00627.html"))
-	 "Until February 2017")
-      ", the guix-devel mailing list filled that role.")
+    (G_
+     `(p
+       "Submission of patches.  Every message sent to this mailing list
+       leads to a new entry in our "
+       ,(G_ `(a (@ (href "https://issues.guix.gnu.org"))
+                "patch tracking tool"))
+       ".  See "
+       ,(G_ `(a (@ (href "https://debbugs.gnu.org/Advanced.html")) "this page"))
+       " for more information on how to use it; see "
+       ,(G_ (manual-href "the manual" (G_ "en") (G_ "Submitting-Patches.html")))
+       " for more information on how to submit a patch.  "
+       ,(G_
+         `(a (@ (href "https://lists.gnu.org/archive/html/guix-devel/2017-02/msg00627.html"))
+             "Until February 2017"))
+       ", the guix-devel mailing list filled that role."))
     #:url "https://lists.gnu.org/mailman/listinfo/guix-patches"
     #:log "https://issues.guix.gnu.org")
 
    (contact
-    #:name "Commits Mailing List"
+    #:name (G_ "Commits Mailing List")
     #:description
-    `(p
-      "Notifications of commits made to the "
-      (a (@ (href ,(guix-url "contribute/"))) "Git repositories")
-      ".")
+    (G_
+     `(p
+       "Notifications of commits made to the "
+       ,(G_ `(a (@ (href ,(guix-url "contribute/"))) "Git repositories"))
+       "."))
     #:url "https://lists.gnu.org/mailman/listinfo/guix-commits"
     #:log "https://lists.gnu.org/archive/html/guix-commits")
 
    (contact
-    #:name "Security Mailing List"
+    #:name (G_ "Security Mailing List")
     #:description
-    `(p
-      "This is a private mailing list that anyone can post to to "
-      (a (@ (href ,(guix-url "security/"))) "report security issues")
-      " in Guix itself or in "
-      "the " (a (@ (href ,(guix-url "packages/"))) "packages")
-      " it provides.  Posting here allows Guix developers to address
-      the problem before it is widely publicized.")
+    (G_
+     `(p
+       "This is a private mailing list that anyone can post to to "
+       ,(G_ `(a (@ (href ,(guix-url "security/"))) "report security issues"))
+       " in Guix itself or in "
+       "the " ,(G_ `(a (@ (href ,(guix-url "packages/"))) "packages"))
+       " it provides.  Posting here allows Guix developers to address
+       the problem before it is widely publicized."))
     #:url "https://lists.gnu.org/mailman/listinfo/guix-security"
     #:log "")
 
    (contact
-    #:name "Sysadmin Mailing List"
+    #:name (G_ "Sysadmin Mailing List")
     #:description
-    '(p
-      "Private mailing list for the "
-      (a (@ (href "https://hydra.gnu.org/")) "build farm")
-      " system administration.")
+    (G_
+     `(p
+       "Private mailing list for the "
+       ,(G_ `(a (@ (href "https://hydra.gnu.org/")) "build farm"))
+       " system administration."))
     #:url "https://lists.gnu.org/mailman/listinfo/guix-sysadmin"
     #:log "")
 
@@ -168,23 +210,23 @@ het Nederlands.")
    ;; Non-Guix lists.
 
    (contact
-    #:name "GNU System Discuss Mailing List"
+    #:name (G_ "GNU System Discuss Mailing List")
     #:description
-    '(p "Discussion about the development of the broader GNU system.")
+    (G_ '(p "Discussion about the development of the broader GNU system."))
     #:url "https://lists.gnu.org/mailman/listinfo/gnu-system-discuss"
     #:log "https://lists.gnu.org/archive/html/gnu-system-discuss/")
 
    (contact
-    #:name "GNU/Linux-libre Mailing List"
+    #:name (G_ "GNU/Linux-libre Mailing List")
     #:description
-    '(p "Workgroup for fully free GNU/Linux distributions.")
+    (G_ '(p "Workgroup for fully free GNU/Linux distributions."))
     #:url "https://lists.nongnu.org/mailman/listinfo/gnu-linux-libre"
     #:log "https://lists.nongnu.org/archive/html/gnu-linux-libre/")
 
    (contact
-    #:name "GNU Info Mailing List"
+    #:name (G_ "GNU Info Mailing List")
     #:description
-    '(p "GNU software announcements.")
+    (G_ '(p "GNU software announcements."))
     #:url "https://lists.gnu.org/mailman/listinfo/info-gnu"
     #:log "https://lists.gnu.org/archive/html/info-gnu/")))
 
@@ -193,36 +235,36 @@ het Nederlands.")
 (define screenshots
   (list
    (screenshot
-    #:title "Graphical log-in"
+    #:title (C_ "screenshot title" "Graphical log-in")
     #:slug "slim"
     #:image (guix-url "static/media/img/gdm-sessions.png")
     #:preview (guix-url "static/media/img/gdm-sessions.mini.png")
-    #:caption "Graphical log-in screen")
+    #:caption (G_ "Graphical log-in screen"))
 
    (screenshot
-    #:title "GNOME"
+    #:title (C_ "screenshot title" "GNOME")
     #:slug "gnome"
     #:image (guix-url "static/media/img/gnome-totem-epiphany.png")
     #:preview (guix-url "static/media/img/gnome-totem-epiphany.mini.png")
-    #:caption "Control your computer with the GNOME desktop environment")
+    #:caption (G_ "Control your computer with the GNOME desktop environment"))
 
    (screenshot
-    #:title "Xfce"
+    #:title (C_ "screenshot title" "Xfce")
     #:slug "xfce"
     #:image (guix-url "static/media/img/guixsd-xfce-icecat-emacs.png")
     #:preview (guix-url "static/media/img/guixsd-xfce-icecat-emacs.mini.png")
-    #:caption "The Xfce desktop environment with GNU Emacs and IceCat")
+    #:caption (G_ "The Xfce desktop environment with GNU Emacs and IceCat"))
 
    (screenshot
-    #:title "Virtual machine"
+    #:title (C_ "screenshot title" "Virtual machine")
     #:slug "virtual-machine"
     #:image (guix-url "static/media/img/guix-system-vm.png")
     #:preview (guix-url "static/media/img/guix-system-vm.mini.png")
-    #:caption "Virtual machine started with 'guix system vm'")
+    #:caption (G_ "Virtual machine started with 'guix system vm'"))
 
    (screenshot
-    #:title "Enlightenment"
+    #:title (C_ "screenshot title" "Enlightenment")
     #:slug "enlightenment"
     #:image (guix-url "static/media/img/enlightenment-inkscape.png")
     #:preview (guix-url "static/media/img/enlightenment-inkscape.mini.png")
-    #:caption "Enlightenment, Inkscape, and Serbian text")))
+    #:caption (G_ "Enlightenment, Inkscape, and Serbian text"))))
diff --git a/website/apps/base/templates/about.scm b/website/apps/base/templates/about.scm
index a654e2f..ab81cb2 100644
--- a/website/apps/base/templates/about.scm
+++ b/website/apps/base/templates/about.scm
@@ -3,105 +3,124 @@
 ;;; copyright interest on this file.
 
 (define-module (apps base templates about)
+  #:use-module (apps base templates components)
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (about-t))
 
 
 (define (about-t)
   "Return the About page in SHTML."
   (theme
-   #:title '("About")
+   #:title (C_ "webpage title" '("About"))
    #:description
-   "Guix is an advanced distribution of the GNU operating system.
-    Guix is technology that respects the freedom of computer users.
-    You are free to run the system for any purpose, study how it
-    works, improve it, and share it with the whole world."
+   (G_ "Guix is an advanced distribution of the GNU operating system.
+   Guix is technology that respects the freedom of computer users.
+   You are free to run the system for any purpose, study how it
+   works, improve it, and share it with the whole world.")
    #:keywords
-   (list "GNU" "Linux" "Unix" "Free software" "Libre software"
-	 "Operating system" "GNU Hurd" "GNU Guix package manager")
-   #:active-menu-item "About"
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+    (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager") #\|)
+   #:active-menu-item (C_ "website menu" "About")
    #:css (list
 	  (guix-url "static/base/css/page.css"))
-   #:crumbs (list (crumb "About" "./"))
+   #:crumbs (list (crumb (C_ "website menu" "About") "./"))
    #:content
    `(main
      (section
       (@ (class "page centered-block limit-width"))
-      (h2 "About the Project")
+      ,(G_ `(h2 "About the Project"))
 
-      (p
-       "The " (em "GNU Guix") " package and system manager is a "
-       (a (@ (href ,(gnu-url "philosophy/free-sw.html")))
-	  "free software")
-       " project developed by volunteers around the world under the
-       umbrella of the " (a (@ (href ,(gnu-url))) "GNU Project") ". ")
+      ,(G_
+        `(p
+          "The " ,(G_ `(em "GNU Guix")) " package and system manager is a "
+          ,(G_ `(a (@ (href ,(gnu-url "philosophy/free-sw.html")))
+                   "free software"))
+          " project developed by volunteers around the world under the
+            umbrella of the "
+          ,(G_ `(a (@ (href ,(gnu-url))) "GNU Project")) ". "))
 
-      (p
-       "Guix System is an advanced distribution of the "
-       (a (@ (href ,(gnu-url))) "GNU operating system")
-       ".  It uses the "
-       (a (@ (href ,(gnu-url "software/linux-libre"))) "Linux-libre")
-       " kernel, and support for "
-       (a (@ (href ,(gnu-url "software/hurd"))) "the Hurd")
-       " is being worked on.  As a GNU distribution, it is committed
-       to respecting and enhancing "
-       (a (@ (href ,(gnu-url "philosophy/free-sw.html")))
-	  "the freedom of its users")
-       ".  As such, it adheres to the "
-       (a (@ (href ,(gnu-url "distros/free-system-distribution-guidelines.html")))
-	  "GNU Free System Distribution Guidelines") ".")
+      ,(G_
+        `(p
+          "Guix System is an advanced distribution of the "
+          ,(G_ `(a (@ (href ,(gnu-url))) "GNU operating system"))
+          ".  It uses the "
+          ,(G_ `(a (@ (href ,(gnu-url "software/linux-libre"))) "Linux-libre"))
+          " kernel, and support for "
+          ,(G_ `(a (@ (href ,(gnu-url "software/hurd"))) "the Hurd"))
+          " is being worked on.  As a GNU distribution, it is committed
+            to respecting and enhancing "
+          ,(G_ `(a (@ (href ,(gnu-url "philosophy/free-sw.html")))
+                   "the freedom of its users"))
+          ".  As such, it adheres to the "
+          ,(G_ `(a (@ (href ,(gnu-url "distros/free-system-distribution-guidelines.html")))
+                   "GNU Free System Distribution Guidelines")) "."))
 
-      (p
-       "GNU Guix provides "
-       (a (@ (href ,(manual-url "Features.html")))
-	  "state-of-the-art package management features")
-       " such as transactional upgrades and roll-backs, reproducible
-       build environments, unprivileged package management, and
-       per-user profiles.  It uses low-level mechanisms from the "
-       (a (@ (href "https://nixos.org/nix/")) "Nix")
-       " package manager, but packages are "
-       (a (@ (href ,(manual-url "Defining-Packages.html"))) "defined")
-       " as native "
-       (a (@ (href ,(gnu-url "software/guile"))) "Guile")
-       " modules, using extensions to the "
-       (a (@ (href "http://schemers.org")) "Scheme")
-       " language—which makes it nicely hackable.")
+      ;; TRANSLATORS: Features and Defining Packages are section names
+      ;; in the English (en) manual.
+      ,(G_
+        `(p
+          "GNU Guix provides "
+          ,(G_ (manual-href "state-of-the-art package management features"
+                            (G_ "en")
+                            (G_ "Features.html")))
+          " such as transactional upgrades and roll-backs, reproducible
+            build environments, unprivileged package management, and
+            per-user profiles.  It uses low-level mechanisms from the "
+          ,(G_ `(a (@ (href "https://nixos.org/nix/")) "Nix"))
+          " package manager, but packages are "
+          ,(G_ (manual-href "defined" (G_ "en") (G_ "Defining-Packages.html")))
+          " as native "
+          ,(G_ `(a (@ (href ,(gnu-url "software/guile"))) "Guile"))
+          " modules, using extensions to the "
+          ,(G_ `(a (@ (href "http://schemers.org")) "Scheme"))
+          " language—which makes it nicely hackable."))
 
-      (p
-       "Guix takes that a step further by additionally supporting stateless,
-       reproducible "
-       (a (@ (href ,(manual-url "Using-the-Configuration-System.html")))
-	  "operating system configurations")
-       ". This time the whole system is hackable in Scheme, from the "
-       (a (@ (href ,(manual-url "Initial-RAM-Disk.html")))
-	  "initial RAM disk")
-       " to the "
-       (a (@ (href ,(gnu-url "software/shepherd")))
-	  "initialization system")
-       ", and to the "
-       (a (@ (href ,(manual-url "Defining-Services.html")))
-	  "system services")
-       ".")
+      ;; TRANSLATORS: Using the Configuration System, Initial RAM Disk
+      ;; and Defining Services are section names in the English (en)
+      ;; manual.
+      ,(G_
+        `(p
+          "Guix takes that a step further by additionally supporting stateless,
+           reproducible "
+          ,(G_ (manual-href "operating system configurations"
+                            (G_ "en")
+                            (G_ "Using-the-Configuration-System.html")))
+          ". This time the whole system is hackable in Scheme, from the "
+          ,(G_ (manual-href "initial RAM disk"
+                            (G_ "en")
+                            (G_ "Initial-RAM-Disk.html")))
+          " to the "
+          ,(G_ `(a (@ (href ,(gnu-url "software/shepherd")))
+                   "initialization system"))
+          ", and to the "
+          ,(G_ (manual-href "system services"
+                            (G_ "en")
+                            (G_ "Defining-Services.html")))
+          "."))
 
 
-      (h3 (@ (id "mantainer")) "Maintainer")
+      ,(G_ `(h3 (@ (id "mantainer")) "Maintainer"))
 
-      (p
-       "Guix is currently maintained by Ludovic Courtès and Ricardo
-       Wurmus.  Please use the "
-       (a (@ (href ,(guix-url "contact/"))) "mailing lists")
-       " for contact. ")
+      ,(G_
+        `(p
+          "Guix is currently maintained by Ludovic Courtès and Ricardo
+          Wurmus.  Please use the "
+          ,(G_ `(a (@ (href ,(guix-url "contact/"))) "mailing lists"))
+          " for contact. "))
 
 
-      (h3 (@ (id "license")) "Licensing")
+      ,(G_ `(h3 (@ (id "license")) "Licensing"))
 
-      (p
-       "Guix is free software; you can redistribute it and/or modify
-       it under the terms of the "
-       (a (@ (rel "license") (href ,(gnu-url "licenses/gpl.html")))
-	  "GNU General Public License")
-       " as published by the Free Software Foundation; either
-       version\xa03 of the License, or (at your option) any later
-       version. ")))))
+      ,(G_
+        `(p
+          "Guix is free software; you can redistribute it and/or modify
+          it under the terms of the "
+          ,(G_ `(a (@ (rel "license") (href ,(gnu-url "licenses/gpl.html")))
+                   "GNU General Public License"))
+          " as published by the Free Software Foundation; either
+          version\xa03 of the License, or (at your option) any later
+          version. "))))))
diff --git a/website/apps/base/templates/components.scm b/website/apps/base/templates/components.scm
index d3f6af1..6b5ec21 100644
--- a/website/apps/base/templates/components.scm
+++ b/website/apps/base/templates/components.scm
@@ -1,4 +1,5 @@
 ;;; GNU Guix web site
+;;; Copyright © 2019 Florian Pelz <pelzflorian@HIDDEN>
 ;;; Initially written by sirgazil who waves all
 ;;; copyright interest on this file.
 
@@ -12,6 +13,7 @@
   #:use-module (apps aux web)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:use-module (srfi srfi-1)
   #:use-module (ice-9 match)
   #:export (breadcrumbs
@@ -23,6 +25,8 @@
 	    link-more
 	    link-subtle
 	    link-yellow
+            manual-href
+            manual-link-yellow
 	    navbar
 	    page-indicator
 	    page-selector
@@ -41,9 +45,9 @@
      (apps base types)."
   `(nav
     (@ (class "breadcrumbs"))
-    (h2 (@ (class "a11y-offset")) "Your location:")
+    ,(G_ `(h2 (@ (class "a11y-offset")) "Your location:"))
 
-    (a (@ (class "crumb") (href ,(guix-url))) "Home") (span " → ")
+    ,(G_ `(a (@ (class "crumb") (href ,(guix-url))) "Home")) (span " → ")
     ,@(separate (crumbs->shtml crumbs) '(span " → "))))
 
 
@@ -121,8 +125,9 @@
        (sxml->string*
         (match (contact-description contact)
           ((and multilingual (((? string?) (? string?)) ...))
-           (match (assoc "en" multilingual)
-             (("en" blurb) blurb)))
+           (let ((code %current-lang))
+             (match (assoc code multilingual)
+               ((code blurb) blurb))))
           (blurb
            blurb)))
        30)
@@ -145,7 +150,7 @@
     ,(if (string=? (contact-log contact) "")
 	 ""
 	 `(small
-	   " (" (a (@ (href ,(contact-log contact))) "archive") ") "))
+	   " (" ,(G_ `(a (@ (href ,(contact-log contact))) "archive")) ") "))
 
     ;; The description can be a list of language/blurb pairs.
     ,(match (contact-description contact)
@@ -216,6 +221,51 @@
   `(a (@ (class "link-yellow") (href ,url)) ,label))
 
 
+
+
+(define (manual-href label manual-lang _1 subpath _2)
+  "Return an HTML a element with its href attribute pointing to the
+manual.  It can be marked for translation as:
+
+  (G_ (manual-href \"some-text\" (G_ \"en\") (G_ \"Some-section.html\")))
+
+   LABEL (string)
+     The content of the a element.
+
+   MANUAL-LANG (string)
+     The normalized language for the Guix manual as produced by
+'doc/build.scm' in the Guix source tree, i.e. \"en\" for the English
+manual.
+
+   SUBPATH (string)
+     The same as in the manual-url procedure."
+  ;; The _ arguments are placeholders for args added by G_, cf. i18n-howto.txt.
+  `(a (@ (href ,(manual-url subpath #:language manual-lang))) label))
+
+(define* (manual-link-yellow label manual-lang _1 #:optional (subpath "") _2)
+  "Return a link-yellow component pointing to the manual.  It can be
+used like this:
+
+  (manual-link-yellow \"some-text\" (G_ \"en\") \"Package-Management.html\")
+
+   LABEL (string)
+     The label of the link-yellow.
+
+   MANUAL-LANG (string)
+     The normalized language for the Guix manual as produced by
+'doc/build.scm' in the Guix source tree, i.e. \"en\" for the English
+manual.
+
+   SUBPATH (string)
+     The same as in the manual-url procedure."
+  ;; The _ arguments are placeholders for args added by G_, cf. i18n-howto.txt.
+  (link-yellow
+   #:label label
+   #:url (manual-url subpath #:language manual-lang)))
+
+
+
+
 (define* (menu-dropdown #:key (label "Item") (active-item "") (url "#") (items '()))
   "Return an SHTML li element representing a dropdown for the navbar.
 
@@ -284,26 +334,26 @@
     (h1
      (a
       (@ (class "branding") (href ,(guix-url)))
-      (span (@ (class "a11y-offset")) "Guix")))
+      ,(C_ "website menu" `(span (@ (class "a11y-offset")) "Guix"))))
 
     ;; Menu.
     (nav (@ (class "menu"))
-     (h2 (@ (class "a11y-offset")) "Website menu:")
+         ,(G_ `(h2 (@ (class "a11y-offset")) "website menu:"))
      (ul
-      ,(menu-item #:label "Overview" #:active-item active-item #:url (guix-url))
-      ,(menu-item #:label "Download" #:active-item active-item #:url (guix-url "download/"))
-      ,(menu-item #:label "Packages" #:active-item active-item #:url (guix-url "packages/"))
-      ,(menu-item #:label "Blog" #:active-item active-item #:url (guix-url "blog/"))
-      ,(menu-item #:label "Help" #:active-item active-item #:url (guix-url "help/"))
-      ,(menu-item #:label "Donate" #:active-item active-item #:url (guix-url "donate/"))
-
-      ,(menu-dropdown #:label "About" #:active-item active-item #:url (guix-url "about/")
+      ,(C_ "website menu" (menu-item #:label "Overview" #:active-item active-item #:url (guix-url)))
+      ,(C_ "website menu" (menu-item #:label "Download" #:active-item active-item #:url (guix-url "download/")))
+      ,(C_ "website menu" (menu-item #:label "Packages" #:active-item active-item #:url (guix-url "packages/")))
+      ,(C_ "website menu" (menu-item #:label "Blog" #:active-item active-item #:url (guix-url "blog/")))
+      ,(C_ "website menu" (menu-item #:label "Help" #:active-item active-item #:url (guix-url "help/")))
+      ,(C_ "website menu" (menu-item #:label "Donate" #:active-item active-item #:url (guix-url "donate/")))
+
+      ,(menu-dropdown #:label (C_ "website menu" "About") #:active-item active-item #:url (guix-url "about/")
 	#:items
-	(list
-	 (menu-item #:label "Contact" #:active-item active-item #:url (guix-url "contact/"))
-	 (menu-item #:label "Contribute" #:active-item active-item #:url (guix-url "contribute/"))
-	 (menu-item #:label "Security" #:active-item active-item #:url (guix-url "security/"))
-	 (menu-item #:label "Graphics" #:active-item active-item #:url (guix-url "graphics/"))))))
+        (list
+         (C_ "website menu" (menu-item #:label "Contact" #:active-item active-item #:url (guix-url "contact/")))
+         (C_ "website menu" (menu-item #:label "Contribute" #:active-item active-item #:url (guix-url "contribute/")))
+         (C_ "website menu" (menu-item #:label "Security" #:active-item active-item #:url (guix-url "security/")))
+         (C_ "website menu" (menu-item #:label "Graphics" #:active-item active-item #:url (guix-url "graphics/")))))))
 
     ;; Menu button.
     (a
@@ -321,10 +371,10 @@
    TOTAL-PAGES (number)
      The total number of pages that should be displayed."
   (if (> total-pages 1)
-      `(span
-	(@ (class "page-number-indicator"))
-	" (Page " ,(number->string page-number)
-	" of " ,(number->string total-pages) ")")
+      (G_ `(span
+            (@ (class "page-number-indicator"))
+            " (Page " ,(number->string page-number)
+            " of " ,(number->string total-pages) ")"))
       ""))
 
 
@@ -345,8 +395,8 @@
     (@ (class "page-selector"))
     (h3
      (@ (class "a11y-offset"))
-     ,(string-append "Page " (number->string active-page) " of "
-		     (number->string pages) ". Go to another page: "))
+     ,(G_ (string-append "Page " (number->string active-page) " of "
+                         (number->string pages) ". Go to another page: ")))
     ,(if (> pages 1)
 	 (map
 	  (lambda (page-number)
diff --git a/website/apps/base/templates/contact.scm b/website/apps/base/templates/contact.scm
index d4ee2f2..44dbabb 100644
--- a/website/apps/base/templates/contact.scm
+++ b/website/apps/base/templates/contact.scm
@@ -7,31 +7,33 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (contact-t))
 
 
 (define (contact-t context)
   "Return the Contact page in SHTML with the data in CONTEXT."
   (theme
-   #:title '("Contact")
+   #:title (C_ "webpage title" '("Contact"))
    #:description
-   "A list of channels to communicate with GNU Guix users
-   and developers about anything you want."
+   (G_ "A list of channels to communicate with GNU Guix users
+   and developers about anything you want.")
    #:keywords
-   '("GNU" "Linux" "Unix" "Free software" "Libre software"
-     "Operating system" "GNU Hurd" "GNU Guix package manager"
-     "Community" "Mailing lists" "IRC channels" "Bug reports" "Help")
-   #:active-menu-item "About"
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+    (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|Community|Mailing lists|IRC \
+channels|Bug reports|Help") #\|)
+   #:active-menu-item (C_ "website menu" "About")
    #:css (list
 	  (guix-url "static/base/css/page.css")
           (guix-url "static/base/css/buttons.css")
 	  (guix-url "static/base/css/contact.css"))
-   #:crumbs (list (crumb "Contact" "./"))
+   #:crumbs (list (crumb (C_ "website menu" "Contact") "./"))
    #:content
    `(main
      (section
       (@ (class "page centered-block limit-width"))
-      (h2 "Contact")
+      ,(G_ `(h2 "Contact"))
 
       ,@(map
 	 contact->shtml
diff --git a/website/apps/base/templates/contribute.scm b/website/apps/base/templates/contribute.scm
index 4d68e87..ff12815 100644
--- a/website/apps/base/templates/contribute.scm
+++ b/website/apps/base/templates/contribute.scm
@@ -7,248 +7,289 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (contribute-t))
 
 
 (define (contribute-t)
   "Return the Contribute page in SHTML."
   (theme
-   #:title '("Contribute")
+   #:title (C_ "webpage title" '("Contribute"))
    #:description
-   "Check all the ways you can contribute to make GNU Guix
-   better, and join the world-wide community of volunteers."
+   (G_ "Check all the ways you can contribute to make GNU Guix
+   better, and join the world-wide community of volunteers.")
    #:keywords
-   '("GNU" "Linux" "Unix" "Free software" "Libre software"
-     "Operating system" "GNU Hurd" "GNU Guix package manager"
-     "Volunteer" "Development" "Translation" "I18N" "L10N"
-     "Artwork")
-   #:active-menu-item "About"
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+    (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|Volunteer|Development|\
+Translation|I18N|L10N|Artwork") #\|)
+   #:active-menu-item (C_ "website menu" "About")
    #:css (list
 	  (guix-url "static/base/css/page.css")
 	  (guix-url "static/base/css/item-preview.css"))
-   #:crumbs (list (crumb "Contribute" "./"))
+   #:crumbs (list (crumb (C_ "website menu" "Contribute") "./"))
    #:content
    `(main
      (section
       (@ (class "page centered-block limit-width"))
-      (h2 "Contribute")
-
-      (p
-       "GNU Guix is a large project developed
-       mostly by volunteers from all around the world. You are welcome
-       to join us in the "
-       (a (@ (href "https://lists.gnu.org/mailman/listinfo/guix-devel"))
-	  "development mailing list")
-       " or in the "
-       (a (@ (href ,(guix-url "contact/irc/"))) "#guix channel")
-       " in IRC Freenode. Tell us how would you like to help, and we
-       will do our best to guide you. ")
-
-      (p
-       "We want to provide a warm, friendly, and harassment-free environment,
-	so that anyone can contribute to the best of their abilities.  To this
-	end our project uses a “Contributor Covenant”, which was adapted from "
-       (a (@ (href "https://contributor-covenant.org/"))
-          "https://contributor-covenant.org/")
-       ".  You can find the full pledge in the "
-       (a (@ (href "//git.savannah.gnu.org/cgit/guix.git/tree/CODE-OF-CONDUCT")
-	     (class "mono"))
-          "CODE-OF-CONDUCT") " file.")
+      ,(G_ `(h2 "Contribute"))
+
+      ,(G_
+        `(p
+          "GNU Guix is a large project developed
+           mostly by volunteers from all around the world. You are welcome
+           to join us in the "
+          ,(G_
+            `(a (@ (href "https://lists.gnu.org/mailman/listinfo/guix-devel"))
+                "development mailing list"))
+          " or in the "
+          ,(G_
+            `(a (@ (href ,(guix-url "contact/irc/"))) "#guix channel"))
+          " in IRC Freenode. Tell us how would you like to help, and we
+          will do our best to guide you. "))
+
+      ,(G_
+        `(p
+          "We want to provide a warm, friendly, and harassment-free environment,
+           so that anyone can contribute to the best of their abilities.  To
+           this end our project uses a “Contributor Covenant”, which was adapted
+           from "
+          ,(G_ ((lambda (url)
+                  `(a (@ (href ,url)) url))
+                "https://contributor-covenant.org/"))
+          ".  You can find the full pledge in the "
+          ,(G_
+            `(a (@ (href "//git.savannah.gnu.org/cgit/guix.git/tree/CODE-OF-CONDUCT")
+                   (class "mono"))
+                "CODE-OF-CONDUCT"))
+          " file."))
 
       (div
        (@ (class "centered-text"))
 
        (div
 	(@ (class "summary-box"))
-	(h3 (@ (id "pms")) "Project Management")
-	(p
-	 "We use "
-	 (a (@ (href "https://savannah.gnu.org/")) "Savannah")
-	 " as the central point for development, maintenance and
-         distribution of the Guix System Distribution and GNU Guix.")
-	(p
-	 "The source files for all the components of the project,
-         including software, web site, documentation, and artwork, are
-         available in "
-	 (a (@ (href "https://savannah.gnu.org/git/?group=guix"))
-	    "Git repositories")
-	 " at Savannah. ")
+        ,(G_ `(h3 (@ (id "pms")) "Project Management"))
+        ,(G_
+          `(p
+            "We use "
+            ,(G_ `(a (@ (href "https://savannah.gnu.org/")) "Savannah"))
+            " as the central point for development, maintenance and
+            distribution of the Guix System Distribution and GNU Guix."))
+        ,(G_
+          `(p
+            "The source files for all the components of the project,
+            including software, web site, documentation, and artwork, are
+            available in "
+            ,(G_ `(a (@ (href "https://savannah.gnu.org/git/?group=guix"))
+                     "Git repositories"))
+            " at Savannah. "))
 	(p
 	 ,(link-more
-	   #:label "Access Savannah"
+           #:label (G_ "Access Savannah")
 	   #:url "https://savannah.gnu.org/projects/guix")))
 
        (div
 	(@ (class "summary-box"))
-	(h3 (@ (id "art")) "Art")
-	(p
-	 "We are always looking for artists to help us design and
-         improve user interfaces, and create multimedia material for
-         documentation, presentations, and promotional items. ")
-	(p
-	 "The artwork used in the different components of the project
-         is available in the "
-	 (a (@ (href "//git.savannah.gnu.org/cgit/guix/guix-artwork.git"))
-	    "guix-artwork")
-	 " repository. ")
+        ,(G_ `(h3 (@ (id "art")) "Art"))
+        ,(G_
+          `(p
+            "We are always looking for artists to help us design and
+            improve user interfaces, and create multimedia material for
+            documentation, presentations, and promotional items. "))
+        ,(G_
+          `(p
+            "The artwork used in the different components of the project
+            is available in the "
+            ,(G_
+              `(a (@ (href "//git.savannah.gnu.org/cgit/guix/guix-artwork.git"))
+                  "guix-artwork"))
+            " repository. "))
 	(p
 	 ,(link-more
-	   #:label "Contribute"
+           #:label (G_ "Contribute")
 	   #:url "https://lists.gnu.org/mailman/listinfo/guix-devel")))
 
 
        (div
 	(@ (class "summary-box"))
-	(h3 (@ (id "documentation")) "Documentation")
-	(p
-	 "You can read the "
-	 (a (@ (href ,(guix-url "help/"))) "project documentation")
-	 " already available in the system and in the website, and
-         help us identify any errors or omissions. Creating new
-         manuals, tutorials, and blog entries will also help users and
-         developers discover what we do. ")
-	(p
-	 "Helping improve the documentation of the "
-	 (a (@ (href ,(guix-url "packages/"))) "packaged software")
-	 " is another way to contribute. ")
+        ,(G_ `(h3 (@ (id "documentation")) "Documentation"))
+        ,(G_
+          `(p
+            "You can read the "
+            ,(G_ `(a (@ (href ,(guix-url "help/"))) "project documentation"))
+            " already available in the system and in the website, and
+            help us identify any errors or omissions. Creating new
+            manuals, tutorials, and blog entries will also help users and
+            developers discover what we do. "))
+        ,(G_
+          `(p
+            "Helping improve the documentation of the "
+            ,(G_ `(a (@ (href ,(guix-url "packages/"))) "packaged software"))
+            " is another way to contribute. "))
 	(p
 	 ,(link-more
-	   #:label "Start writing"
+           #:label (G_ "Start writing")
 	   #:url "https://lists.gnu.org/mailman/listinfo/guix-devel")))
 
 
        (div
 	(@ (class "summary-box"))
-	(h3 (@ (id "packages")) "Packages")
-	(p
-	 "Hundreds of software, documentation, and assets need to be
-         packaged to make it easier for users to install their
-         favorite tools with the Guix package manager, and be
-         productive using the system. ")
-	(p
-	 "Information on how to add packages to the distribution can
-         be found "
-	 (a (@ (href ,(manual-url "Packaging-Guidelines.html")))
-	    "in the manual")
-	 ". ")
-	(p
-	 "Check out the "
-	 (a (@ (href ,(guix-url "packages/")))
-	    "package database")
-	 " for a list of available packages, and the "
-	 (a (@ (href "//bugs.gnu.org/guix-patches"))
-	    "patch-tracking database")
-	 " for a list of pending submissions.")
+        ,(G_ `(h3 (@ (id "packages")) "Packages"))
+        ,(G_
+          `(p
+            "Hundreds of software, documentation, and assets need to be
+            packaged to make it easier for users to install their
+            favorite tools with the Guix package manager, and be
+            productive using the system. "))
+        ;; TRANSLATORS: Packaging Guidelines is a section name in the
+        ;; English (en) manual.
+        ,(G_
+          `(p
+            "Information on how to add packages to the distribution can
+            be found "
+            ,(G_
+              (manual-href
+               "in the manual"
+               (G_ "en")
+               (G_ "Packaging-Guidelines.html")))
+            ". "))
+        ,(G_
+          `(p
+            "Check out the "
+            ,(G_ `(a (@ (href ,(guix-url "packages/")))
+                     "package database"))
+            " for a list of available packages, and the "
+            ,(G_ `(a (@ (href "//bugs.gnu.org/guix-patches"))
+                     "patch-tracking database"))
+            " for a list of pending submissions."))
 	(p
 	 ,(link-more
-	   #:label "Send a new package"
+           #:label (G_ "Send a new package")
 	   #:url "https://lists.gnu.org/mailman/listinfo/guix-patches")))
 
 
        (div
 	(@ (class "summary-box"))
-	(h3 (@ (id "programming")) "Programming")
-	(p
-	 "Source code is in the "
-	 (a (@ (href "//git.savannah.gnu.org/cgit/guix.git/"))
-	    "main Git repository")
-	 ".  "
-	 "We use "
-	 (a (@ (href ,(gnu-url "software/guile"))) "GNU Guile")
-	 " as the main programming and extension language for the
-         components of the system. ")
-	(p
-	 "You will find it useful to browse the "
-	 (a (@ (href ,(gnu-url "software/guile/manual")))
-	    "Guile manual")
-	 " or other "
-	 (a (@ (href "http://www.schemers.org/Documents/#intro-texts"))
-	    "introductory material about Scheme")
-	 ". Also, make sure to read the "
-	 (a (@ (href ,(manual-url "Contributing.html")))
-	    "Contributing")
-	 " section of the manual for more details on the development
-         setup, as well as the coding and cooperation conventions used
-         in the project. ")
+        ,(G_ `(h3 (@ (id "programming")) "Programming"))
+        ,(G_
+          `(p
+            "Source code is in the "
+            ,(G_ `(a (@ (href "//git.savannah.gnu.org/cgit/guix.git/"))
+                     "main Git repository"))
+            ".  "
+            "We use "
+            ,(G_ `(a (@ (href ,(gnu-url "software/guile"))) "GNU Guile"))
+            " as the main programming and extension language for the
+            components of the system. "))
+        ;; TRANSLATORS: Contributing is a section name in the English
+        ;; (en) manual.
+        ,(G_
+          `(p
+            "You will find it useful to browse the "
+            ,(G_
+              `(a (@ (href ,(gnu-url "software/guile/manual")))
+                  "Guile manual"))
+            " or other "
+            ,(G_ `(a (@ (href "http://www.schemers.org/Documents/#intro-texts"))
+                     "introductory material about Scheme"))
+            ". Also, make sure to read the "
+            ,(G_ (manual-href "Contributing"
+                              (G_ "en")
+                              (G_ "Contributing.html")))
+            " section of the manual for more details on the development
+            setup, as well as the coding and cooperation conventions used
+            in the project. "))
 	(p
 	 ,(link-more
-	   #:label "Send a patch"
+           #:label (G_ "Send a patch")
 	   #:url "https://lists.gnu.org/mailman/listinfo/guix-patches")))
 
 
        (div
 	(@ (class "summary-box"))
-	(h3 (@ (id "sysadmin")) "System Administration")
-	(p
-	 "Our system infrastructure makes it possible for all the
-         contributors to communicate and collaborate in the project,
-         and users to be able to download and install packages. Help
-         us keep the system up and running smoothly. ")
-	(p
-	 "You can also "
-	 (a (@ (href ,(guix-url "donate/")))
-	    "donate hardware or hosting")
-	 " for our "
-	 (a (@ (href "https://hydra.gnu.org")) "build farm") ".  ")
+        ,(G_ `(h3 (@ (id "sysadmin")) "System Administration"))
+        ,(G_
+          `(p
+            "Our system infrastructure makes it possible for all the
+            contributors to communicate and collaborate in the project,
+            and users to be able to download and install packages. Help
+            us keep the system up and running smoothly. "))
+        ,(G_
+          `(p
+            "You can also "
+            ,(G_ `(a (@ (href ,(guix-url "donate/")))
+                     "donate hardware or hosting"))
+            " for our "
+            ,(G_ `(a (@ (href "https://hydra.gnu.org")) "build farm")) ".  "))
 	(p
 	 ,(link-more
-	   #:label "Contribute"
+           #:label (G_ "Contribute")
 	   #:url "https://lists.gnu.org/mailman/listinfo/guix-devel")))
 
 
        (div
 	(@ (class "summary-box"))
-	(h3 (@ (id "testing")) "Test and Bug Reports")
-	(p
-	 "Install the software and send feedback to the community
-         about your experience. Help the project by reporting bugs.")
-	(p
-	 "Before reporting a bug, please check whether the bug is
-         already "
-	 (a (@ (href "https://issues.guix.gnu.org"))
-	    "in the bug database")
-	 ". See "
-	 (a (@ (href "https://debbugs.gnu.org/Developer.html"))
-	    "the developer information page")
-	 " for more information on how to manipulate bug reports. ")
+        ,(G_ `(h3 (@ (id "testing")) "Test and Bug Reports"))
+        ,(G_
+          `(p
+            "Install the software and send feedback to the community
+            about your experience. Help the project by reporting bugs."))
+        ,(G_
+          `(p
+            "Before reporting a bug, please check whether the bug is
+            already "
+            ,(G_ `(a (@ (href "https://issues.guix.gnu.org"))
+                     "in the bug database"))
+            ". See "
+            ,(G_ `(a (@ (href "https://debbugs.gnu.org/Developer.html"))
+                     "the developer information page"))
+            " for more information on how to manipulate bug reports. "))
 	(p
 	 ,(link-more
-	   #:label "Report a bug"
+           #:label (G_ "Report a bug")
 	   #:url "https://lists.gnu.org/mailman/listinfo/bug-guix")))
 
 
        (div
 	(@ (class "summary-box"))
-	(h3 (@ (id "translation")) "Translation")
-	(p
-	 "You can help translate the "
-	 (a (@ (href "https://translationproject.org/domain/guix.html"))
-	    "software")
-	 ", the "
-	 (a (@ (href "https://translationproject.org/domain/guix-packages.html"))
-	    "package descriptions")
-         ", and the "
-            (a (@ (href "https://translationproject.org/domain/guix-manual.html"))
-	       "manual")
-	 " into your language.  See the "
-	 (a (@ (href "https://translationproject.org/html/translators.html"))
-	    "Translation Project")
-	 " for information on how you can help.")
-	(p
-	 (a (@ (href ,(guix-url "packages"))) "Software packages")
-	 " provided by the system may have their own translation
-         tools.  Visit their websites and help translate. ")
-	(p
+        ,(G_ `(h3 (@ (id "translation")) "Translation"))
+        ,(G_
+          `(p
+            "You can help translate the "
+            ,(G_
+              `(a (@ (href "https://translationproject.org/domain/guix.html"))
+                  "software"))
+            ", the "
+            ,(G_
+              `(a (@ (href "https://translationproject.org/domain/guix-packages.html"))
+                  "package descriptions"))
+            ", and the "
+            ,(G_
+              `(a (@ (href "https://translationproject.org/domain/guix-manual.html"))
+                  "manual"))
+            " into your language.  See the "
+            ,(G_
+              `(a (@ (href "https://translationproject.org/html/translators.html"))
+                  "Translation Project"))
+            " for information on how you can help."))
+        ,(G_
+          `(p
+            ,(G_ `(a (@ (href ,(guix-url "packages"))) "Software packages"))
+            " provided by the system may have their own translation
+            tools.  Visit their websites and help translate. "))
+        (p
 	 ,(link-more
-	   #:label "Start translating"
+           #:label (G_ "Start translating")
 	   #:url "https://translationproject.org/"))))
 
 
-      (h3 (@ (id "resources")) "Other resources for contributors")
-      (p
-       "Documents, supporting material of previous talks, and
-       auxiliary information useful to hackers and maintainers is
-       available at "
-       (a (@ (href "//git.savannah.gnu.org/cgit/guix/maintenance.git"))
-	  "git://git.sv.gnu.org/guix/maintenance.git")
-       ".")))))
+      ,(G_ `(h3 (@ (id "resources")) "Other resources for contributors"))
+      ,(G_
+        `(p
+          "Documents, supporting material of previous talks, and
+          auxiliary information useful to hackers and maintainers is
+          available at "
+          (a (@ (href "//git.savannah.gnu.org/cgit/guix/maintenance.git"))
+             "git://git.sv.gnu.org/guix/maintenance.git")
+          "."))))))
diff --git a/website/apps/base/templates/donate.scm b/website/apps/base/templates/donate.scm
index 8babaec..301e801 100644
--- a/website/apps/base/templates/donate.scm
+++ b/website/apps/base/templates/donate.scm
@@ -7,206 +7,267 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (donate-t))
 
 
 (define (donate-t)
   "Return the Donate page in SHTML."
   (theme
-   #:title '("Donate")
+   #:title (C_ "webpage title" '("Donate"))
    #:description
-   "We are looking for donations of hardware and optionally hosting
-   for machines (they should be usable with exclusively free
-   software)."
+   (G_ "We are looking for donations of hardware and optionally
+   hosting for machines (they should be usable with exclusively
+   free software).")
    #:keywords
-   '("GNU" "Linux" "Unix" "Free software" "Libre software"
-     "Operating system" "GNU Hurd" "GNU Guix package manager"
-     "Donations")
-   #:active-menu-item "Donate"
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+    (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|Donations") #\|)
+   #:active-menu-item (C_ "website menu" "Donate")
    #:css (list
 	  (guix-url "static/base/css/page.css"))
-   #:crumbs (list (crumb "Donate" "./"))
+   #:crumbs (list (crumb (C_ "website menu" "Donate") "./"))
    #:content
    `(main
      (section
       (@ (class "page centered-block limit-width"))
-      (h2 "Donate")
+      ,(G_ `(h2 "Donate"))
 
-      (p
-       "The "
-       (a (@ (href "https://hydra.gnu.org/jobset/gnu/master"))
-	  "build farm")
-       " of the Guix System Distribution runs on donated hardware and"
-       " hosting. As the distribution grows (see the "
-       (a (@ (href ,(guix-url "packages/"))) "package list")
-       "), so do the computing and storage needs.")
+      ,(G_
+        `(p
+          "The "
+          ,(G_
+            `(a (@ (href "https://hydra.gnu.org/jobset/gnu/master"))
+                "build farm"))
+          " of the Guix System Distribution runs on donated hardware and"
+          " hosting. As the distribution grows (see the "
+          ,(G_ `(a (@ (href ,(guix-url "packages/"))) "package list"))
+          "), so do the computing and storage needs."))
 
-      (p
-       "We have "
-       (a (@ (href "https://savannah.gnu.org/forum/forum.php?forum_id=8423"))
-	  "started a fundraising campaign")
-       " to strengthen our build farm, with "
-       (a (@ (href "https://www.fsf.org/blogs/community/fsf-announces-support-for-gnu-guix"))
-	  "support from the Free Software Foundation (FSF)")
-       ".  Please consider helping out by making a donation on this
-       FSF-hosted page:")
+      ,(G_
+        `(p
+          "We have "
+          ,(G_
+            `(a (@ (href "https://savannah.gnu.org/forum/forum.php?forum_id=8423"))
+                "started a fundraising campaign"))
+          " to strengthen our build farm, with "
+          ,(G_
+            `(a (@ (href "https://www.fsf.org/blogs/community/fsf-announces-support-for-gnu-guix"))
+                "support from the Free Software Foundation (FSF)"))
+          ".  Please consider helping out by making a donation on this
+          FSF-hosted page:"))
 
       (p
        (@ (class "centered-text"))
        ,(button-big
-	 #:label "♥ DONATE!"
+         #:label (C_ "button" "♥ DONATE!")
 	 #:url "https://my.fsf.org/civicrm/contribute/transact?reset=1&id=50"))
 
-      (h3
-       (@ (id "hardware-and-hosting"))
-       "Hardware and Hosting")
+      ,(G_
+        `(h3
+          (@ (id "hardware-and-hosting"))
+          "Hardware and Hosting"))
 
-      (p
-       "We are also looking for donations of hardware and optionally
-        hosting for the following kinds of machines (they should be
-        usable with exclusively free software): ")
+      ,(G_
+        `(p
+          "We are also looking for donations of hardware and optionally
+           hosting for the following kinds of machines (they should be
+           usable with exclusively free software): "))
 
       (ul
-       (li "x86_64 machines, with on the order of 1\xa0TiB of storage
-            and 4\xa0GiB of RAM;")
-       (li "armv7 machines (such as the Novena) to more quickly test
-            and provide binaries for the armhf-linux port;")
-       (li "mips64el machines to strengthen this port."))
+       ,(G_
+         `(li "x86_64 machines, with on the order of 1\xa0TiB of storage
+               and 4\xa0GiB of RAM;"))
+       ,(G_
+         `(li "armv7 machines (such as the Novena) to more quickly test
+               and provide binaries for the armhf-linux port;"))
+       ,(G_
+         `(li "mips64el machines to strengthen this port.")))
 
-      (p
-       "Please get in touch with us through the "
-       (a (@ (href ,(guix-url "contact/"))) "usual channels")
-       " or using the " (b "guix-hardware@HIDDEN") " private alias to
-        discuss any opportunities. ")
+      ,(G_
+        `(p
+          "Please get in touch with us through the "
+          ,(G_ `(a (@ (href ,(guix-url "contact/"))) "usual channels"))
+          " or using the " (b "guix-hardware@HIDDEN") " private alias to
+           discuss any opportunities. "))
 
 
-      (h3
-       (@ (id "hardware-donors"))
-       "Thanks to the donors!")
+      ,(G_
+        `(h3
+          (@ (id "hardware-donors"))
+          "Thanks to the donors!"))
 
-      (p
-       "The table below summarizes hardware and hosting donations that
-        make the " (a (@ (href "https://hydra.gnu.org")) "build farm")
-	" for the Guix System Distribution a reality.")
+      ,(G_
+        `(p
+          "The table below summarizes hardware and hosting donations that
+           make the " ,(G_ `(a (@ (href "https://hydra.gnu.org")) "build farm"))
+           " for the Guix System Distribution a reality."))
 
       (div
        (@ (class "table-box"))
        (table
 	(thead
-	 (tr (th "machine")
-	     (th "system")
-	     (th "donors")))
+         ,(G_ `(tr ,(G_ `(th "machine"))
+                   ,(G_ `(th "system"))
+                   ,(G_ `(th "donors")))))
 	(tbody
-	 (tr
-	  (td "hydra.gnu.org")
-	  (td "build farm front-end")
-	  (td
-	   (ul
-	    (li
-	     (a (@ (href "https://www.fsf.org/"))
-            "Free Software Foundation")))))
-     (tr
-      (td "berlin.guixsd.org")
-      (td "build farm with 25 build nodes for x86_64-linux and
-i686-linux, and dedicated storage")
-      (td
-       (ul
-        (li
-         (a (@ (href "https://www.mdc-berlin.de/"))
-            "Max Delbrück Center for Molecular Medicine")
-         " (hardware and hosting)"))))
-	 (tr
-	  (td "overdrive1.guixsd.org")
-	  (td "aarch64-linux")
-	  (td
-	   (ul
-	    (li (a (@ (href "https://www.arm.com/"))
-		   "ARM Holdings") " (hardware)"))))
-	 (tr
-	  (td "bayfront.guixsd.org")
-	  (td "new build farm front-end (WIP)")
-	  (td
-	   (ul
-	    (li
-	     (a (@ (href ,(guix-url "news/growing-our-build-farm.html")))
-		"Igalia")))))
-	 (tr
-	  (td "hydra.gnunet.org")
-	  (td "x86_64-linux, i686-linux")
-	  (td (ul (li (a (@ (href "https://gnunet.org/fsnsg"))
-			 "Free Secure Network Systems Group")
-		      " at the "
-		      (a (@ (href "https://www.tum.de/"))
-			 "Technische Universität München")))))
-	 (tr
-	  (td "chapters.gnu.org")
-	  (td "x86_64-linux, i686-linux")
-	  (td
-	   (ul
-	    (li (a (@ (href "https://es.gnu.org"))
-		   "GNU\xa0España") " (hardware)")
-	    (li (a (@ (href "https://fsffrance.org/index.en.html"))
-		   "FSF\xa0France")
-		" (hosting)"))))
-	 (tr
-	  (td "librenote")
-	  (td "mips64el-linux")
-	  (td (ul (li "Daniel Clark (hardware)")
-		  (li "Mark H Weaver (hosting)"))))
-	 (tr
-	  (td "hydra-slave0")
-	  (td "mips64el-linux")
-	  (td
-	   (ul
-	    (li (a (@ (href "https://www.fsf.org/"))
-		   "Free Software Foundation")))))
-	 (tr
-	  (td "guix.sjd.se")
-	  (td "x86_64-linux, i686-linux")
-	  (td
-	   (ul
-	    (li (a (@ (href "http://josefsson.org"))
-		   "Simon Josefsson")))))
-	 (tr
-	  (td "x15.sjd.se")
-	  (td "armhf-linux")
-	  (td
-	   (ul
-	    (li (a (@ (href "http://josefsson.org"))
-		   "Simon Josefsson")))))
-	 (tr
-	  (td "hydra-slave1")
-	  (td "armhf-linux")
-	  (td
-	   (ul
-	    (li "Steve Sprang (hardware)")
-	    ;; XXX: Eventually move to the FSF?
-	    (li "Mark H Weaver (hosting)"))))
-	 (tr
-	  (td "hydra-slave2")
-	  (td "armhf-linux")
-	  (td
-	   (ul
-	    (li (a (@ (href "http://harmoninstruments.com/"))
-		   "Harmon Instruments")
-		" (hardware)")
-	    ;; XXX: Eventually move to the FSF?
-	    (li "Mark H Weaver (hosting)"))))
-	 (tr
-	  (td "hydra-slave3")
-	  (td "armhf-linux")
-	  (td
-	   (ul
-	    (li (a (@ (href "http://www.kosagi.com/w/index.php?title=Novena_Main_Page"))
-		   "Kosagi (Sutajio Ko-Usagi Pte Ltd)")
-		" (hardware)")
-	    (li "Mark H Weaver (hosting)"))))
-	 (tr
-	  (td "redhill")
-	  (td "armhf-linux")
-	  (td
-	   (ul
-	    (li (a (@ (href "http://www.kosagi.com/w/index.php?title=Novena_Main_Page"))
-		   "Kosagi (Sutajio Ko-Usagi Pte Ltd)")
-		" (hardware)")
-	    (li "Andreas Enge (hosting)")))))))))))
+         ,(G_ `(tr
+                ,(G_ `(td "hydra.gnu.org"))
+                ,(G_ `(td "build farm front-end"))
+                ,(G_ ((lambda (content)
+                        `(td
+                          (ul
+                           (li
+                            (a (@ (href "https://www.fsf.org/"))
+                               ,content)))))
+                      "Free Software Foundation"))))
+         ,(G_ `(tr
+                ,(G_ `(td "berlin.guixsd.org"))
+                ,(G_ `(td "build farm with 25 build nodes for x86_64-linux and
+i686-linux, and dedicated storage"))
+                ,(G_ ((lambda content
+                        `(td
+                          (ul
+                           (li
+                            ,@content))))
+                      (G_ `(a (@ (href "https://www.mdc-berlin.de/"))
+                              "Max Delbrück Center for Molecular Medicine"))
+                      " (hardware and hosting)"))))
+         ,(G_ `(tr
+                ,(G_ `(td "overdrive1.guixsd.org"))
+                ,(G_ `(td "aarch64-linux"))
+                ,(G_ ((lambda content
+                        `(td
+                          (ul
+                           (li
+                            ,@content))))
+                      (G_ `(a (@ (href "https://www.arm.com/"))
+                              "ARM Holdings") " (hardware)")))))
+         ,(G_
+           `(tr
+             ,(G_ `(td "bayfront.guixsd.org"))
+             ,(G_ `(td "new build farm front-end (WIP)"))
+             ,(G_ ((lambda (content)
+                        `(td
+                          (ul
+                           (li
+                            (a
+                             (@ (href ,(guix-url "news/growing-our-build-farm.html")))
+                             ,content)))))
+                   "Igalia"))))
+         ,(G_ `(tr
+                ,(G_ `(td "hydra.gnunet.org"))
+                ,(G_ `(td "x86_64-linux, i686-linux"))
+                ,(G_ ((lambda content
+                        `(td
+                          (ul
+                           (li
+                            ,@content))))
+                      (G_ `(a (@ (href "https://gnunet.org/fsnsg"))
+                              "Free Secure Network Systems Group"))
+                      " at the "
+                      (G_ `(a (@ (href "https://www.tum.de/"))
+                              "Technische Universität München"))))))
+         ,(G_ `(tr
+                ,(G_ `(td "chapters.gnu.org"))
+                ,(G_ `(td "x86_64-linux, i686-linux"))
+                ,(G_ ((lambda content
+                        `(td
+                          (ul
+                           ,@content)))
+                      (G_ `(li
+                            ,(G_ `(a (@ (href "https://es.gnu.org"))
+                                     "GNU\xa0España"))
+                            " (hardware)"))
+                      (G_ `(li
+                            ,(G_ `(a (@ (href "https://fsffrance.org/index.en.html"))
+                                     "FSF\xa0France"))
+                            " (hosting)"))))))
+         ,(G_ `(tr
+                ,(G_ `(td "librenote"))
+                ,(G_ `(td "mips64el-linux"))
+                ,(G_ ((lambda content
+                        `(td
+                          (ul
+                           ,@content)))
+                      (G_ `(li "Daniel Clark (hardware)"))
+                      (G_ `(li "Mark H Weaver (hosting)"))))))
+         ,(G_ `(tr
+                ,(G_ `(td "hydra-slave0"))
+                ,(G_ `(td "mips64el-linux"))
+                ,(G_ ((lambda (content)
+                        `(td
+                          (ul
+                           (li
+                            (a (@ (href "https://www.fsf.org/"))
+                               ,content)))))
+                      "Free Software Foundation"))))
+         ,(G_ `(tr
+                ,(G_ `(td "guix.sjd.se"))
+                ,(G_ `(td "x86_64-linux, i686-linux"))
+                ,(G_ ((lambda (content)
+                        `(td
+                          (ul
+                           (li
+                            (a (@ (href "http://josefsson.org"))
+                               ,content)))))
+                      "Simon Josefsson"))))
+         ,(G_ `(tr
+                ,(G_ `(td "x15.sjd.se"))
+                ,(G_ `(td "armhf-linux"))
+                ,(G_ ((lambda (content)
+                        `(td
+                          (ul
+                           (li
+                            (a (@ (href "http://josefsson.org"))
+                               ,content)))))
+                      "Simon Josefsson"))))
+         ,(G_ `(tr
+                ,(G_ `(td "hydra-slave1"))
+                ,(G_ `(td "armhf-linux"))
+                ,(G_ ((lambda content
+                        `(td
+                          (ul
+                           ,@content)))
+                      (G_ `(li "Steve Sprang (hardware)"))
+                      ;; XXX: Eventually move to the FSF?
+                      (G_ `(li "Mark H Weaver (hosting)"))))))
+         ,(G_ `(tr
+                ,(G_ `(td "hydra-slave2"))
+                ,(G_ `(td "armhf-linux"))
+                ,(G_ ((lambda content
+                        `(td
+                          (ul
+                           ,@content)))
+                      (G_ `(li
+                            ,(G_ `(a (@ (href "http://harmoninstruments.com/"))
+                                     "Harmon Instruments"))
+                            " (hardware)"))
+                      ;; XXX: Eventually move to the FSF?
+                      (G_ `(li "Mark H Weaver (hosting)"))))))
+         ,(G_
+           `(tr
+             ,(G_ `(td "hydra-slave3"))
+             ,(G_ `(td "armhf-linux"))
+             ,(G_ ((lambda content
+                     `(td
+                       (ul
+                        ,@content)))
+                   (G_ `(li
+                    ,(G_ `(a (@ (href "http://www.kosagi.com/w/index.php?title=Novena_Main_Page"))
+                             "Kosagi (Sutajio Ko-Usagi Pte Ltd)"))
+                    " (hardware)"))
+                   (G_ `(li "Mark H Weaver (hosting)"))))))
+         ,(G_
+           `(tr
+             ,(G_ `(td "redhill"))
+             ,(G_ `(td "armhf-linux"))
+             ,(G_ ((lambda content
+                     `(td
+                       (ul
+                        ,@content)))
+                   (G_ `(li
+                    ,(G_ `(a (@ (href "http://www.kosagi.com/w/index.php?title=Novena_Main_Page"))
+                             "Kosagi (Sutajio Ko-Usagi Pte Ltd)"))
+                    " (hardware)"))
+                   (G_ `(li "Andreas Enge (hosting)")))))))))))))
diff --git a/website/apps/base/templates/graphics.scm b/website/apps/base/templates/graphics.scm
index 80b6532..6c1d70f 100644
--- a/website/apps/base/templates/graphics.scm
+++ b/website/apps/base/templates/graphics.scm
@@ -6,66 +6,73 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (graphics-t))
 
 
 (define (graphics-t)
   "Return the Graphics page in SHTML."
   (theme
-   #:title '("Graphics")
+   #:title (C_ "webpage title" '("Graphics"))
    #:description
-   "Information about images used for the graphical identity of
-   GNU Guix and Guix System (formerly “GuixSD”)."
+   (G_ "Information about images used for the graphical identity
+   of GNU Guix and Guix System (formerly “GuixSD”).")
    #:keywords
-   '("GNU" "Linux" "Unix" "Free software" "Libre software"
-     "Operating system" "GNU Hurd" "GNU Guix package manager"
-     "Branding" "Logo")
-   #:active-menu-item "About"
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+    (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|Donations|Branding|Logo") #\|)
+   #:active-menu-item (C_ "website menu" "About")
    #:css (list
 	  (guix-url "static/base/css/page.css"))
-   #:crumbs (list (crumb "Graphics" "./"))
+   #:crumbs (list (crumb (C_ "website menu" "Graphics") "./"))
    #:content
    `(main
      (section
       (@ (class "page centered-block limit-width"))
-      (h2 "Graphics")
+      ,(G_ `(h2 "Graphics"))
 
-      (p
-       "For questions regarding the graphics listed in this page,
-       please contact "
-       (a (@ (href "https://lists.gnu.org/mailman/listinfo/help-guix"))
-	  ("help-guix@HIDDEN"))
-       ".")
+      ,(G_
+        `(p
+          "For questions regarding the graphics listed in this page,
+          please contact "
+          ,(G_ `(a (@ (href "https://lists.gnu.org/mailman/listinfo/help-guix"))
+                   "help-guix@HIDDEN"))
+          "."))
       (p
        (@ (class "centered-text"))
        (img (@ (src ,(guix-url "static/base/img/Guix.png"))
-	       (alt "GNU Guix logotype"))))
-      (p
-       "The standalone Guix, formerly known as the “Guix System
-       Distribution” or GuixSD, had its own logo, which is now
-       deprecated.")
+               ,(G_ `(alt "GNU Guix logotype")))))
+      ,(G_
+        `(p
+          "The standalone Guix, formerly known as the “Guix System
+          Distribution” or GuixSD, had its own logo, which is now
+          deprecated."))
 
-      (p
-       "The GNU Guix and GuixSD
-       logotypes were designed by Luis Felipe López Acevedo
-       (a.k.a. sirgazil).  They are available under the following
-       terms:")
+      ,(G_
+        `(p
+          "The GNU Guix and GuixSD
+          logotypes were designed by Luis Felipe López Acevedo
+          (a.k.a. sirgazil).  They are available under the following
+          terms:"))
       (blockquote
        (p "Copyright © 2015 Luis Felipe López Acevedo")
        (p
-	"Permission is granted to copy, distribute and/or modify this
+        "Permission is granted to copy, distribute and/or modify this
         work under the terms of the "
-	(a (@ (href "https://creativecommons.org/licenses/by-sa/4.0/"))
-	   "Creative Commons Attribution-ShareAlike 4.0 International License")
-	"."))
-      (p
-       "The source files (SVG) for these logotypes, their variants, and
-       other artwork used in the different components of the GNU Guix
-       project are available in the "
-       (a (@ (href "//git.savannah.gnu.org/cgit/guix/guix-artwork.git/tree/logo"))
-	  "guix-artwork")
-       " repository, including the previous GNU Guix logotype designed
-       by Nikita Karetnikov in 2013 and "
-       (a (@ (href "https://debbugs.gnu.org/cgi/bugreport.cgi?bug=25205"))
-	  "superseded")
-       " by the golden GNU in 2016.")))))
+        `(a (@ (href "https://creativecommons.org/licenses/by-sa/4.0/"))
+            "Creative Commons Attribution-ShareAlike 4.0 International License")
+        "."))
+      ,(G_
+        `(p
+          "The source files (SVG) for these logotypes, their variants, and
+          other artwork used in the different components of the GNU Guix
+          project are available in the "
+          ,(G_
+            `(a (@ (href "//git.savannah.gnu.org/cgit/guix/guix-artwork.git/tree/logo"))
+                "guix-artwork"))
+          " repository, including the previous GNU Guix logotype designed
+          by Nikita Karetnikov in 2013 and "
+          ,(G_
+            `(a (@ (href "https://debbugs.gnu.org/cgi/bugreport.cgi?bug=25205"))
+                "superseded"))
+          " by the golden GNU in 2016."))))))
diff --git a/website/apps/base/templates/help.scm b/website/apps/base/templates/help.scm
index 8117957..c9d6ab2 100644
--- a/website/apps/base/templates/help.scm
+++ b/website/apps/base/templates/help.scm
@@ -7,31 +7,32 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (help-t))
 
 
 (define (help-t)
   "Return the Help page in SHTML."
   (theme
-   #:title '("Help")
+   #:title (C_ "webpage title" '("Help"))
    #:description
-   "A list of resources about how to use GNU Guix, plus
+   (G_ "A list of resources about how to use GNU Guix, plus
    information about getting help from the community of users and
-   developers."
+   developers.")
    #:keywords
-   '("GNU" "Linux" "Unix" "Free software" "Libre software"
-     "Operating system" "GNU Hurd" "GNU Guix package manager"
-     "Help resources")
-   #:active-menu-item "Help"
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+    (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|Help resources") #\|)
+   #:active-menu-item (C_ "website menu" "Help")
    #:css (list
 	  (guix-url "static/base/css/page.css")
 	  (guix-url "static/base/css/item-preview.css"))
-   #:crumbs (list (crumb "Help" "./"))
+   #:crumbs (list (crumb (C_ "website menu" "Help") "./"))
    #:content
    `(main
      (section
       (@ (class "page"))
-      (h2 "Help")
+      ,(G_ `(h2 "Help"))
 
       (div
        (@ (class "centered-text"))
@@ -42,24 +43,25 @@
 	(img
 	 (@ (src ,(guix-url "static/base/img/manual-icon.png"))
 	    (alt "")))
-	(h3 "GNU Guix Manual")
-	(p
-	 "Documentation for GNU Guix is available
-         online.  You may also find more information about Guix by running "
-	 (code "info guix") ".")
-	(p
-         ,(link-more #:label "Read Guix manual"
-                     #:url (guix-url "manual/en")))
+        ,(G_ `(h3 "GNU Guix Manual"))
+        ,(G_
+          `(p
+            "Documentation for GNU Guix is available
+            online.  You may also find more information about Guix by running "
+            ,(G_ `(code "info guix")) "."))
         (p
-         (a (@ (href ,(guix-url "manual/de"))) "Deutsch") " | "
-         (a (@ (href ,(guix-url "manual/en"))) "English") " | "
-         (a (@ (href ,(guix-url "manual/es"))) "español") " | "
-         (a (@ (href ,(guix-url "manual/fr"))) "français") " | "
-         (a (@ (href ,(guix-url "manual/ru"))) "русский")  " | "
-         (a (@ (href ,(guix-url "manual/zh-cn"))) "简体中文"))
+         ,(link-more #:label (G_ "Read Guix manual")
+                     #:url (guix-url "manual/en" #:localize #f)))
+        (p
+         (a (@ (href ,(guix-url "manual/de" #:localize #f))) "Deutsch") " | "
+         (a (@ (href ,(guix-url "manual/en" #:localize #f))) "English") " | "
+         (a (@ (href ,(guix-url "manual/es" #:localize #f))) "español") " | "
+         (a (@ (href ,(guix-url "manual/fr" #:localize #f))) "français") " | "
+         (a (@ (href ,(guix-url "manual/ru" #:localize #f))) "русский")  " | "
+         (a (@ (href ,(guix-url "manual/zh-cn" #:localize #f))) "简体中文"))
 
         ,(link-more
-	  #:label "Get Guix reference card"
+          #:label (G_ "Get Guix reference card")
 	  #:url (guix-url "guix-refcard.pdf")))
 
 
@@ -67,15 +69,16 @@
 	(@ (class "summary-box"))
 	(img (@ (src ,(guix-url "static/base/img/library-icon.png"))
 		(alt "")))
-	(h3 "GNU Manuals")
-	(p
-	 "Guix is a distribution of the "
-	 (a (@ (href ,(gnu-url))) "GNU operating system")
-	 ".  Documentation for GNU packages is
-         available online in various formats. ")
+        ,(G_ `(h3 "GNU Manuals"))
+        ,(G_
+          `(p
+            "Guix is a distribution of the "
+            ,(G_ `(a (@ (href ,(gnu-url))) "GNU operating system"))
+            ".  Documentation for GNU packages is
+            available online in various formats. "))
 	(p
 	 ,(link-more
-	   #:label "Browse GNU manuals"
+           #:label (G_ "Browse GNU manuals")
 	   #:url (gnu-url "manual"))))
 
 
@@ -83,18 +86,20 @@
 	(@ (class "summary-box"))
 	(img (@ (src ,(guix-url "static/base/img/chat-icon.png"))
 		(alt "")))
-	(h3 "IRC Chat")
-	(p
-	 "For real-time support from the community, you can connect
-         to the " (code "#guix") " channel on irc.freenode.net. There
-         you can get help about anything related to GNU Guix.")
-	(p
-	 "The " (code "#guix") " channel is logged. Previous
-         conversations can be browsed online. See the "
-	 (a (@ (href ,guix-irc-log-url)) "channel logs") ". ")
+        ,(G_ `(h3 "IRC Chat"))
+        ,(G_
+          `(p
+            "For real-time support from the community, you can connect
+            to the " (code "#guix") " channel on irc.freenode.net. There
+            you can get help about anything related to GNU Guix."))
+        ,(G_
+          `(p
+            "The " (code "#guix") " channel is logged. Previous
+            conversations can be browsed online. See the "
+            ,(G_ `(a (@ (href ,guix-irc-log-url)) "channel logs")) ". "))
 	(p
 	 ,(link-more
-	   #:label "Connect"
+           #:label (G_ "Connect")
 	   #:url (guix-url "contact/irc/"))))
 
 
@@ -102,13 +107,14 @@
 	(@ (class "summary-box"))
 	(img (@ (src ,(guix-url "static/base/img/email-icon.png"))
 		(alt "")))
-	(h3 "Mailing lists")
-	(p
-	 "Email support from the community is also available through
-         several mailing list. The messages sent to the lists are
-         public and archived online.")
+        ,(G_ `(h3 "Mailing lists"))
+        ,(G_
+          `(p
+            "Email support from the community is also available through
+            several mailing list. The messages sent to the lists are
+            public and archived online."))
 
 	(p
 	 ,(link-more
-	   #:label "See all lists"
+           #:label (G_ "See all lists")
 	   #:url (guix-url "contact/")))))))))
diff --git a/website/apps/base/templates/home.scm b/website/apps/base/templates/home.scm
index 5cb3bf5..f0f889e 100644
--- a/website/apps/base/templates/home.scm
+++ b/website/apps/base/templates/home.scm
@@ -8,24 +8,27 @@
   #:use-module (apps base types)
   #:use-module (apps base utils)
   #:use-module (apps blog templates components)
+  #:use-module (apps i18n)
   #:export (home-t))
 
 
 (define (home-t context)
   "Return the Home page in SHTML using the data in CONTEXT."
   (theme
-   #:title '("GNU's advanced distro and transactional package manager")
+   #:title (C_ "webpage title"
+               '("GNU's advanced distro and transactional package manager"))
    #:description
-   "Guix is an advanced distribution of the GNU operating system.
+   (G_ "Guix is an advanced distribution of the GNU operating system.
    Guix is technology that respects the freedom of computer users.
-   You are free to run the system for any purpose, study how it works,
-   improve it, and share it with the whole world."
+   You are free to run the system for any purpose, study how it
+   works, improve it, and share it with the whole world.")
    #:keywords
-   '("GNU" "Linux" "Unix" "Free software" "Libre software"
-     "Operating system" "GNU Hurd" "GNU Guix package manager"
-     "GNU Guile" "Guile Scheme" "Transactional upgrades"
-     "Functional package management" "Reproducibility")
-   #:active-menu-item "Overview"
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+    (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile \
+Scheme|Transactional upgrades|Functional package \
+management|Reproducibility") #\|)
+   #:active-menu-item (C_ "website menu" "Overview")
    #:css (list
 	  (guix-url "static/base/css/item-preview.css")
 	  (guix-url "static/base/css/index.css"))
@@ -34,83 +37,94 @@
      ;; Featured content.
      (section
       (@ (class "featured-content"))
-      (h2 (@ (class "a11y-offset")) "Summary")
+      ,(G_ `(h2 (@ (class "a11y-offset")) "Summary"))
       (ul
-       (li
-	(b "Liberating.")
-	" Guix is an advanced
-        distribution of the "
-	,(link-yellow
-	  #:label "GNU operating system"
-	  #:url (gnu-url "gnu/about-gnu.html"))
-	" developed by the "
-	,(link-yellow
-	  #:label "GNU Project"
-	  #:url (gnu-url))
-	"—which respects the "
-	,(link-yellow
-	  #:label "freedom of computer users"
-	  #:url (gnu-url "distros/free-system-distribution-guidelines.html"))
-	". ")
-
-       (li
-	(b "Dependable.")
-        " Guix "
-	,(link-yellow
-	  #:label "supports"
-	  #:url (manual-url "Package-Management.html"))
-        " transactional upgrades and roll-backs, unprivileged
-        package management, "
-	,(link-yellow
-	  #:label "and more"
-	  #:url (manual-url "Features.html"))
-	".  When used as a standalone distribution, Guix supports "
-        ,(link-yellow
-          #:label "declarative system configuration"
-          #:url (manual-url "Using-the-Configuration-System.html"))
-        " for transparent and reproducible operating systems.")
-
-       (li
-	(b "Hackable.")
-	" It provides "
-	,(link-yellow
-	  #:label "Guile Scheme"
-	  #:url (gnu-url "software/guile/"))
-	" APIs, including high-level embedded domain-specific
-        languages (EDSLs) to "
-	,(link-yellow
-	  #:label "define packages"
-	  #:url (manual-url "Defining-Packages.html"))
-	" and "
-	,(link-yellow
-	  #:label "whole-system configurations"
-	  #:url (manual-url "System-Configuration.html"))
-	"."))
+       ,(G_
+         `(li
+           ,(G_ `(b "Liberating."))
+           " Guix is an advanced distribution of the "
+           ,(G_ (link-yellow
+                 #:label "GNU operating system"
+                 #:url (gnu-url "gnu/about-gnu.html")))
+           " developed by the "
+           ,(G_ (link-yellow
+                 #:label "GNU Project"
+                 #:url (gnu-url)))
+           "—which respects the "
+           ,(G_ (link-yellow
+                 #:label "freedom of computer users"
+                 #:url (gnu-url "distros/free-system-distribution-\
+guidelines.html")))
+           ". "))
+
+       ;; TRANSLATORS: Package Management, Features and Using the
+       ;; Configuration System are section names in the English (en)
+       ;; manual.
+       ,(G_
+         `(li
+           ,(G_ `(b "Dependable."))
+           " Guix "
+           ,(G_ (manual-link-yellow "supports"
+                                    (G_ "en")
+                                    (G_ "Package-Management.html")))
+           " transactional upgrades and roll-backs, unprivileged \
+package management, "
+           ,(G_ (manual-link-yellow "and more"
+                                    (G_ "en")
+                                    (G_ "Features.html")))
+           ".  When used as a standalone distribution, Guix supports "
+           ,(G_ (manual-link-yellow "declarative system configuration"
+                                    (G_ "en")
+                                    (G_ "Using-the-Configuration-System.html")))
+           " for transparent and reproducible operating systems."))
+
+       ;; TRANSLATORS: Defining Packages and System Configuration are
+       ;; section names in the English (en) manual.
+       ,(G_
+         `(li
+           ,(G_ `(b "Hackable."))
+           " It provides "
+           ,(G_ (link-yellow
+                 #:label "Guile Scheme"
+                 #:url (gnu-url "software/guile/")))
+           " APIs, including high-level embedded domain-specific \
+languages (EDSLs) to "
+           ,(G_ (manual-link-yellow "define packages"
+                                    (G_ "en")
+                                    (G_ "Defining-Packages.html")))
+           " and "
+           ,(G_ (manual-link-yellow "whole-system configurations"
+                                    (G_ "en")
+                                    (G_ "System-Configuration.html")))
+           ".")))
 
       (div
        (@ (class "action-box centered-text"))
        ,(button-big
-	 #:label (string-append "DOWNLOAD v" (latest-guix-version))
+         #:label (apply string-append
+                        (C_ "button" `("DOWNLOAD v" ,(latest-guix-version) "")))
 	 #:url (guix-url "download/")
 	 #:light #true)
        " " ; A space for readability in non-CSS browsers.
        ,(button-big
-	 #:label "CONTRIBUTE"
+         #:label (C_ "button" "CONTRIBUTE")
 	 #:url (guix-url "contribute/")
 	 #:light #true)))
 
      ;; Discover Guix.
      (section
       (@ (class "discovery-box"))
-      (h2 "Discover Guix")
-
-      (p
-       (@ (class "limit-width centered-block"))
-       "Guix comes with thousands of packages which include
-       applications, system tools, documentation, fonts, and other
-       digital goods readily available for installing with the "
-       ,(link-yellow #:label "GNU Guix" #:url "#guix-in-other-distros")
-       " package manager.")
+      ,(G_ `(h2 "Discover Guix"))
+
+      ,(G_
+        `(p
+          (@ (class "limit-width centered-block"))
+          "Guix comes with thousands of packages which include \
+applications, system tools, documentation, fonts, and other digital \
+goods readily available for installing with the "
+          ,(G_ (link-yellow #:label "GNU Guix"
+                            #:url (identity "#guix-in-other-distros")))
+          " package manager."))
 
       (div
        (@ (class "screenshots-box"))
@@ -119,55 +133,57 @@
       (div
        (@ (class "action-box centered-text"))
        ,(button-big
-	 #:label "ALL PACKAGES"
+         #:label (C_ "button" "ALL PACKAGES")
 	 #:url (guix-url "packages/")
 	 #:light #true))
 
       ,(horizontal-separator #:light #true)
 
       ;; Guix in different fields.
-      (h3 "GNU Guix in your field")
+      ,(G_ `(h3 "GNU Guix in your field"))
 
-      (p
-       (@ (class "limit-width centered-block"))
-       "Read some stories about how people are using GNU Guix in their daily
-       lives.")
+      ,(G_
+        `(p
+          (@ (class "limit-width centered-block"))
+          "Read some stories about how people are using GNU Guix in
+their daily lives."))
 
       (div
        (@ (class "fields-box"))
 
        " " ; A space for readability in non-CSS browsers (same below).
        ,(button-big
-	 #:label "SOFTWARE DEVELOPMENT"
-	 #:url (guix-url "blog/tags/software-development/")
-	 #:light #true)
+         #:label (C_ "button" "SOFTWARE DEVELOPMENT")
+         #:url (guix-url "blog/tags/software-development/")
+         #:light #true)
        " "
        ,(button-big
-	 #:label "BIOINFORMATICS"
-	 #:url (guix-url "blog/tags/bioinformatics/")
-	 #:light #true)
+         #:label (C_ "button" "BIOINFORMATICS")
+         #:url (guix-url "blog/tags/bioinformatics/")
+         #:light #true)
        " "
        ,(button-big
-	 #:label "HIGH PERFORMANCE COMPUTING"
-	 #:url (guix-url "blog/tags/high-performance-computing/")
-	 #:light #true)
+         #:label (C_ "button" "HIGH PERFORMANCE COMPUTING")
+         #:url (guix-url "blog/tags/high-performance-computing/")
+         #:light #true)
        " "
        ,(button-big
-	 #:label "RESEARCH"
-	 #:url (guix-url "blog/tags/research/")
-	 #:light #true)
+         #:label (C_ "button" "RESEARCH")
+         #:url (guix-url "blog/tags/research/")
+         #:light #true)
        " "
        ,(button-big
-	 #:label "ALL FIELDS..."
-	 #:url (guix-url "blog/")
-	 #:light #true))
+         #:label (C_ "button" "ALL FIELDS...")
+         #:url (guix-url "blog/")
+         #:light #true))
 
       ,(horizontal-separator #:light #true)
 
       ;; Using Guix in other distros.
-      (h3
-       (@ (id "guix-in-other-distros"))
-       "GNU Guix in other GNU/Linux distros")
+      ,(G_
+        `(h3
+          (@ (id "guix-in-other-distros"))
+          "GNU Guix in other GNU/Linux distros"))
 
       (div
        (@ (class "info-box"))
@@ -176,54 +192,55 @@
 	   (src "https://audio-video.gnu.org/video/misc/2016-07__GNU_Guix_Demo_2.webm")
 	   (poster ,(guix-url "static/media/img/guix-demo.png"))
 	   (controls "controls"))
-	(p
-	 "Video: "
-	 ,(link-yellow
-	   #:label "Demo of Guix in another GNU/Linux distribution"
-	   #:url "https://audio-video.gnu.org/video/misc/2016-07__GNU_Guix_Demo_2.webm")
-	 " (1 minute, 30 seconds).")))
+        ,(G_
+          `(p
+            "Video: "
+            ,(G_ (link-yellow
+                  #:label "Demo of Guix in another GNU/Linux distribution"
+                  #:url "https://audio-video.gnu.org/video/misc/\
+2016-07__GNU_Guix_Demo_2.webm"))
+            " (1 minute, 30 seconds)."))))
 
       (div
        (@ (class "info-box justify-left"))
-       (p
-	"If you don't use GNU Guix as a standalone GNU/Linux distribution,
-        you still can use it as a
-	package manager on top of any GNU/Linux distribution. This
-        way, you can benefit from all its conveniences.")
+       ,(G_ `(p
+              "If you don't use GNU Guix as a standalone GNU/Linux \
+distribution, you still can use it as a package manager on top of any \
+GNU/Linux distribution. This way, you can benefit from all its conveniences."))
 
-       (p
-	"Guix won't interfere with the package manager that comes
-        with your distribution. They can live together."))
+       ,(G_ `(p
+              "Guix won't interfere with the package manager that comes \
+with your distribution. They can live together.")))
 
       (div
        (@ (class "action-box centered-text"))
        ,(button-big
-	 #:label "TRY IT OUT!"
+         #:label (C_ "button" "TRY IT OUT!")
 	 #:url (guix-url "download/")
 	 #:light #true)))
 
      ;; Latest Blog posts.
      (section
       (@ (class "centered-text"))
-      (h2 "Blog")
+      ,(G_ `(h2 "Blog"))
 
       ,@(map post-preview (context-datum context "posts"))
 
       (div
        (@ (class "action-box centered-text"))
        ,(button-big
-	 #:label "ALL POSTS"
+         #:label (C_ "button" "ALL POSTS")
 	 #:url (guix-url "blog/"))))
 
      ;; Contact info.
      (section
       (@ (class "contact-box centered-text"))
-      (h2 "Contact")
+      ,(G_ `(h2 "Contact"))
 
       ,@(map contact-preview (context-datum context "contact-media"))
 
       (div
        (@ (class "action-box centered-text"))
        ,(button-big
-	 #:label "ALL CONTACT MEDIA"
+         #:label (C_ "button" "ALL CONTACT MEDIA")
 	 #:url (guix-url "contact/")))))))
diff --git a/website/apps/base/templates/irc.scm b/website/apps/base/templates/irc.scm
index c21f77e..5674d1f 100644
--- a/website/apps/base/templates/irc.scm
+++ b/website/apps/base/templates/irc.scm
@@ -6,45 +6,49 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (irc-t))
 
 
 (define (irc-t)
   "Return the Kiwi IRC widget page in SHTML."
   (theme
-   #:title '("IRC" "Contact")
+   #:title
+   (list (C_ "webpage title" "IRC")
+         (C_ "webpage title" "Contact"))
    #:description
-   "Internet relay chat."
+   (G_ "Internet relay chat.")
    #:keywords
-   '("GNU" "Linux" "Unix" "Free software" "Libre software"
-     "Operating system" "GNU Hurd" "GNU Guix package manager"
-     "IRC" "chat")
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+    (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|IRC|chat") #\|)
    #:active-menu-item "About"
    #:css (list
 	  (guix-url "static/base/css/page.css")
 	  (guix-url "static/base/css/irc.css"))
-   #:crumbs (list (crumb "Contact" (guix-url "contact/"))
-		  (crumb "IRC" "./"))
+   #:crumbs (list (crumb (C_ "webpage title" "Contact") (guix-url "contact/"))
+		  (crumb (C_ "webpage title" "IRC") "./"))
    #:content
    `(main
      (section
       (@ (class "page"))
-      (h2 "IRC")
+      ,(G_ `(h2 "IRC"))
 
-      (p
-       (@ (class "centered-block limit-width"))
-       "Join the " (code "#guix") " channel on the "
-       (a (@ (href "https://en.wikipedia.org/wiki/Freenode"))
-	"Freenode IRC network")
-       " to chat with the GNU Guix community or to get help
-       in real-time. You can use the chat widget below, or just use
-       the "
-       (a (@ (href "https://en.wikipedia.org/wiki/Comparison_of_Internet_Relay_Chat_clients"))
-	  "IRC client")
-       " of your preference. Note that the conversations that happen
-       on the " (code "#guix") " channel are logged ("
-       (a (@ (href ,guix-irc-log-url)) "browse the log")
-       ").")
+      ,(G_
+        `(p
+          (@ (class "centered-block limit-width"))
+          "Join the " (code "#guix") " channel on the "
+          ,(G_ `(a (@ (href "https://en.wikipedia.org/wiki/Freenode"))
+                   "Freenode IRC network"))
+          " to chat with the GNU Guix community or to get help
+          in real-time. You can use the chat widget below, or just use
+          the "
+          ,(G_ `(a (@ (href "https://en.wikipedia.org/wiki/Comparison_of_Internet_Relay_Chat_clients"))
+                   "IRC client"))
+          " of your preference. Note that the conversations that happen
+          on the " (code "#guix") " channel are logged ("
+          ,(G_ `(a (@ (href ,guix-irc-log-url)) "browse the log"))
+          ")."))
 
       (iframe
        (@ (class "chat-widget centered-block")
diff --git a/website/apps/base/templates/menu.scm b/website/apps/base/templates/menu.scm
index b87387f..ce6b54e 100644
--- a/website/apps/base/templates/menu.scm
+++ b/website/apps/base/templates/menu.scm
@@ -6,17 +6,20 @@
   #:use-module (apps base templates components)
   #:use-module (apps base templates theme)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (menu-t))
 
 
 (define (menu-t)
   "Return the Menu page in SHTML."
   (theme
-   #:title '("Menu")
-   #:description "Website menu."
-   #:keywords '("GNU" "Linux" "Unix" "Free software" "Libre software"
-		"Operating system" "GNU Hurd" "GNU Guix package manager"
-		"GNU Guile" "Guile Scheme" "Transactional upgrades"
-		"Functional package management" "Reproducibility")
-   #:active-menu-item "Menu"
+   #:title (C_ "webpage title" '("Menu"))
+   #:description (G_ "Website menu.")
+   #:keywords
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+    (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile \
+Scheme|Transactional upgrades|Functional package \
+management|Reproducibility") #\|)
+   #:active-menu-item (C_ "website menu" "Menu")
    #:css (list (guix-url "static/base/css/menu.css"))))
diff --git a/website/apps/base/templates/screenshot.scm b/website/apps/base/templates/screenshot.scm
index 41a3a07..60662fa 100644
--- a/website/apps/base/templates/screenshot.scm
+++ b/website/apps/base/templates/screenshot.scm
@@ -7,6 +7,7 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (screenshot-t))
 
 
@@ -15,14 +16,15 @@
   (let ((shot (context-datum context "screenshot"))
 	(shots (context-datum context "screenshots")))
     (theme
-     #:title (list (screenshot-title shot) "Screenshots")
+     #:title (list (screenshot-title shot) (C_ "webpage title" "Screenshots"))
      #:description (screenshot-caption shot)
      #:keywords
-     '("GNU" "Linux" "Unix" "Free software" "Libre software"
-       "Operating system" "GNU Hurd" "GNU Guix package manager"
-       "GNU Guile" "Guile Scheme" "Transactional upgrades"
-       "Functional package management" "Reproducibility")
-     #:active-menu-item "Overview"
+     (string-split ;TRANSLATORS: |-separated list of webpage keywords
+      (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile \
+Scheme|Transactional upgrades|Functional package \
+management|Reproducibility") #\|)
+     #:active-menu-item (C_ "website menu" "Overview")
      #:css (list (guix-url "static/base/css/index.css")
 		 (guix-url "static/base/css/screenshots.css"))
      #:content
diff --git a/website/apps/base/templates/security.scm b/website/apps/base/templates/security.scm
index b772912..d28b548 100644
--- a/website/apps/base/templates/security.scm
+++ b/website/apps/base/templates/security.scm
@@ -3,9 +3,11 @@
 ;;; copyright interest on this file.
 
 (define-module (apps base templates security)
+  #:use-module (apps base templates components)
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (security-t))
 
 (define ludovics-key
@@ -14,36 +16,38 @@
 (define (security-t)
   "Return the Security page in SHTML."
   (theme
-   #:title '("Security")
+   #:title (C_ "webpage title" '("Security"))
    #:description
-   "Important information about getting security updates for your
-   GNU Guix installation, and instructions on how to report
-   security issues."
+   (G_ "Important information about getting security updates
+   for your GNU Guix installation, and instructions on how
+   to report security issues.")
    #:keywords
-   '("GNU" "Linux" "Unix" "Free software" "Libre software"
-     "Operating system" "GNU Hurd" "GNU Guix package manager"
-     "Security updates")
-   #:active-menu-item "About"
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+      (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|Security updates") #\|)
+   #:active-menu-item (C_ "website menu" "About")
    #:css (list
 	  (guix-url "static/base/css/page.css"))
-   #:crumbs (list (crumb "Security" "./"))
+   #:crumbs (list (crumb (C_ "website menu" "Security") "./"))
    #:content
    `(main
      (section
       (@ (class "page centered-block limit-width"))
-      (h2 "Security")
+      ,(G_ `(h2 "Security"))
 
-      (h3 "How to report security issues")
-      (p
-       "To report sensitive security issues in Guix itself or the
-        packages it provides, you can write to the private mailing list "
-       (a (@ (href "https://lists.gnu.org/mailman/listinfo/guix-security"))
-	  ("guix-security@HIDDEN")) ".  This list is monitored by a
-        small team of Guix developers.")
-      (p
-       "If you prefer to send your report using OpenPGP encrypted email,
-        please send it to one of the following Guix developers using their
-        respective OpenPGP key:")
+      ,(G_ `(h3 "How to report security issues"))
+      ,(G_
+        `(p
+          "To report sensitive security issues in Guix itself or the
+           packages it provides, you can write to the private mailing list "
+          (a (@ (href "https://lists.gnu.org/mailman/listinfo/guix-security"))
+             ("guix-security@HIDDEN")) ".  This list is monitored by a
+           small team of Guix developers."))
+      ,(G_
+        `(p
+          "If you prefer to send your report using OpenPGP encrypted email,
+           please send it to one of the following Guix developers using their
+           respective OpenPGP key:"))
       (ul
         (li "Leo Famulari"
           (ul (@ (class "mono"))
@@ -58,23 +62,30 @@
           (ul (@ (class "mono"))
             (li "BCA6 89B6 3655 3801 C3C6 2150 197A 5888 235F ACAC"))))
 
-      (h3 "Release signatures")
-      (p
-       "Releases of Guix are signed using the OpenPGP "
-       "key with the fingerprint "
-       (span (@ (class "mono")) ,ludovics-key)
-       ".  "
-       "Users should "
-       (a (@ (href ,(manual-url "Binary-Installation.html"))) "verify")
-       " their downloads before extracting or running them.")
+      ,(G_ `(h3 "Release signatures"))
+      ,(G_
+        `(p
+          "Releases of Guix are signed using the OpenPGP "
+          "key with the fingerprint "
+          (span (@ (class "mono")) ,ludovics-key)
+          ".  "
+          "Users should "
+          ,(G_ (manual-href "verify"
+                            (G_ "en")
+                            (G_ "Binary-Installation.html")))
+          " their downloads before extracting or running them."))
 
-      (h3 "Security updates")
-      (p
-       "When security vulnerabilities are found in Guix or the "
-       "packages provided by Guix, we will provide "
-       (a (@ (href ,(manual-url "Security-Updates.html"))) "security updates")
-       " quickly and with minimal disruption for users.")
-      (p
-       "Guix uses a “rolling release” model.  All security "
-       "bug-fixes are pushed directly to the master branch.  There"
-       " is no “stable” branch that only receives security fixes.")))))
+      ,(G_ `(h3 "Security updates"))
+      ,(G_
+        `(p
+          "When security vulnerabilities are found in Guix or the "
+          "packages provided by Guix, we will provide "
+          ,(G_ (manual-href "security updates"
+                            (G_ "en")
+                            (G_ "Security-Updates.html")))
+          " quickly and with minimal disruption for users."))
+      ,(G_
+        `(p
+          "Guix uses a “rolling release” model.  All security "
+          "bug-fixes are pushed directly to the master branch.  There"
+          " is no “stable” branch that only receives security fixes."))))))
diff --git a/website/apps/base/templates/theme.scm b/website/apps/base/templates/theme.scm
index ecb27ef..e33c0d3 100644
--- a/website/apps/base/templates/theme.scm
+++ b/website/apps/base/templates/theme.scm
@@ -5,15 +5,16 @@
 (define-module (apps base templates theme)
   #:use-module (apps base templates components)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:export (theme))
 
 
 (define* (theme #:key
-		(lang-tag "en")
+                (lang-tag %current-ietf-tag)
 		(title '())
 		(description "")
 		(keywords '())
-		(active-menu-item "About")
+                (active-menu-item (C_ "website menu" "About"))
 		(css '())
 		(scripts '())
 		(crumbs '())
@@ -23,7 +24,8 @@
    LANG-TAG (string)
      IETF language tag. This is used to specify the language of the
      document. For example: en, en-CA. If not provided, the value
-     defaults to English (en).
+     defaults to the currently built language, i.e. the
+     %current-ietf-tag from (apps i18n).
 
    TITLE (list)
      A list of strings to form the value of the title element of the
@@ -65,12 +67,14 @@
   `((doctype "html")
 
     (html
-     (@ (lang "en"))
+     (@ (lang lang-tag))
 
      (head
       ,(if (null? title)
-	   `(title "GNU Guix")
-	   `(title ,(string-join (append title '("GNU Guix")) " — ")))
+           `(title ,(C_ "webpage title" "GNU Guix"))
+           `(title ,(string-join (append title
+                                         (C_ "webpage title" '("GNU Guix")))
+                                 " — ")))
       (meta (@ (charset "UTF-8")))
       (meta (@ (name "keywords") (content ,(string-join keywords ", "))))
       (meta (@ (name "description") (content ,description)))
@@ -91,7 +95,7 @@
 	     css)
       ;; Feeds.
       (link (@ (type "application/atom+xml") (rel "alternate")
-	       (title "GNU Guix — Activity Feed")
+	       (title (C_ "webpage title" "GNU Guix — Activity Feed"))
 	       (href ,(guix-url "feeds/blog.atom"))))
       (link (@ (rel "icon") (type "image/png")
 	       (href ,(guix-url "static/base/img/icon.png"))))
@@ -108,17 +112,22 @@
       ,(if (null? crumbs) "" (breadcrumbs crumbs))
 
       ,content
-      (footer
-       "Made with " (span (@ (class "metta")) "♥")
-       " by humans and powered by "
-       (a (@ (class "link-yellow") (href ,(gnu-url "software/guile/")))
-	  "GNU Guile") ".  "
-	  (a
-	   (@ (class "link-yellow")
-	      (href "//git.savannah.gnu.org/cgit/guix/guix-artwork.git/tree/website"))
-	   "Source code")
-	  " under the "
-	  (a
-	   (@ (class "link-yellow")
-	      (href ,(gnu-url "licenses/agpl-3.0.html")))
-	   "GNU AGPL") ".")))))
+      ,(G_
+        `(footer
+          "Made with " ,(G_ `(span (@ (class "metta")) "♥"))
+          " by humans and powered by "
+          ,(G_ `(a
+                 (@ (class "link-yellow")
+                    (href ,(gnu-url "software/guile/")))
+                 "GNU Guile"))
+          ".  "
+          ,(G_ `(a
+                 (@ (class "link-yellow")
+                    (href "//git.savannah.gnu.org/cgit/guix/guix-artwork.git/tree/website"))
+                 "Source code"))
+          " under the "
+          ,(G_ `(a
+                 (@ (class "link-yellow")
+                    (href ,(gnu-url "licenses/agpl-3.0.html")))
+                 "GNU AGPL"))
+          "."))))))
diff --git a/website/apps/base/utils.scm b/website/apps/base/utils.scm
index d57ec7c..4201bf6 100644
--- a/website/apps/base/utils.scm
+++ b/website/apps/base/utils.scm
@@ -3,6 +3,7 @@
 ;;; Copyright © 2015 Mathieu Lirzin <mthl@HIDDEN>
 ;;; Copyright © 2013 Alex Sassmannshausen <alex.sassmannshausen@HIDDEN>
 ;;; Copyright © 2017 Eric Bavier <bavier@HIDDEN>
+;;; Copyright © 2019 Florian Pelz <pelzflorian@HIDDEN>
 ;;; Initially written by sirgazil who waives all copyright interest on this
 ;;; file.
 ;;;
@@ -25,6 +26,7 @@
   #:use-module (apps aux lists)
   #:use-module (apps aux system)
   #:use-module (apps base types)
+  #:use-module (apps i18n)
   #:use-module (haunt page)
   #:use-module (ice-9 i18n)
   #:use-module (ice-9 match)
@@ -34,7 +36,9 @@
 	    guix-irc-log-url
 	    guix-url
 	    latest-guix-version
+            locale-display-name
 	    manual-url
+            manual-url-with-language
 	    number*
 	    paginate))
 
@@ -51,6 +55,14 @@
 (define latest-guix-version
   (make-parameter "1.0.1"))
 
+(define (locale-display-name)
+  "Return the display name of the current locale."
+  ;; TRANSLATORS: The locale’s display name; please include a country
+  ;; code like in English (US) *only* if there are multiple
+  ;; Translation Project teams for the same language.
+  (let ((str '(G_ "English (US)")))
+    (gettext (cadr str))))
+
 
 
 ;;;
@@ -83,20 +95,24 @@
   (string-append "https://git.savannah.gnu.org/cgit/guix.git/tree/" subpath))
 
 
-(define* (guix-url #:optional (subpath ""))
+(define* (guix-url #:optional (subpath "") #:key (localize #t))
   "Append SUBPATH to GNU Guix root URL path (see guix-root-url-path).
 
    SUBPATH (string)
      An optional relative URL path to a resource in the GNU Guix path.
      For example: 'packages/icecat-XYZ/'.
 
+   LOCALIZE (boolean)
+     Whether to call localize-url on the URL path.
+
    RETURN VALUE (string)
      A URL path. For example: /software/guix/packages/icecat-XYZ/."
-  ;; If we are trying out the website locally, use "/" as the root.
-  ;; Otherwise use guix-root-url-path for deployment to gnu.org.
-  (if (getenv "GUIX_WEB_SITE_LOCAL")
-      (string-append "/" subpath)
-      (string-append (guix-root-url-path) subpath)))
+  ((if localize localize-url identity)
+   ;; If we are trying out the website locally, use "/" as the root.
+   ;; Otherwise use guix-root-url-path for deployment to gnu.org.
+   (if (getenv "GUIX_WEB_SITE_LOCAL")
+       (string-append "/" subpath)
+       (string-append (guix-root-url-path) subpath))))
 
 
 (define* (manual-url #:optional (subpath "")
@@ -115,6 +131,27 @@
                                            "/html_node/")
                             subpath))))
 
+(define* (manual-url-with-language _ language #:optional (subpath ""))
+  "Shorthand for manual-url without keywords for prettier output
+PO files when marked for translation.  It can be marked for translation
+as:
+
+  (G_ (manual-url-with-language (G_ \"en\") (G_ \"Some-section.html\")))
+
+   LANGUAGE (string)
+     Normalized language for the Guix manual as produced by
+'doc/build.scm' in the Guix source tree, i.e. \"en\" for the English
+manual.
+
+   SUBPATH (string)
+     Like manual-url.
+
+   RETURN VALUE (string)
+     A URL path. For example:
+     /software/guix/manual/en/html_node/System-installation.html."
+  ;; The _ argument is a placeholder for an arg added by G_, cf. i18n-howto.txt.
+  (manual-url subpath #:language language))
+
 
 
 ;;;
diff --git a/website/apps/blog/templates/components.scm b/website/apps/blog/templates/components.scm
index fe67f29..38d02ac 100644
--- a/website/apps/blog/templates/components.scm
+++ b/website/apps/blog/templates/components.scm
@@ -8,6 +8,7 @@
   #:use-module (apps aux web)
   #:use-module (apps base utils)
   #:use-module (apps blog utils)
+  #:use-module (apps i18n)
   #:use-module (haunt post)
   #:use-module (srfi srfi-19)
   #:export (post-preview
@@ -29,11 +30,12 @@
     (h3 ,(post-ref post 'title))
     (p
      (@ (class "item-date"))
-     ,(date->string (post-date post) "~B ~e, ~Y"))
+     ,(date->string (post-date post) (C_ "SRFI-19 date->string format"
+                                         "~B ~e, ~Y")))
     (p
      (@ (class "item-summary"))
      ,(string-summarize (sxml->string* (post-sxml post)) 30)
-     "…")))
+     (C_ "blog post summary ellipsis" "…"))))
 
 
 (define* (sidebar tags #:optional (current-tag #false))
@@ -44,13 +46,13 @@
      Haunt's 'posts/group-by-tag' procedure in (haunt post) module."
   `(section
     (@ (class "side-bar"))
-    (h3 (@ (class "a11y-offset")) "Blog menu: ")
+    (h3 (@ (class "a11y-offset")) (G_ "Blog menu: "))
 
     (h4
      (@ (class "bar-title bar-title-top"))
      ,(if current-tag
-	  "Get topic updates"
-	  "Get blog updates"))
+          (G_ "Get topic updates")
+          (G_ "Get blog updates")))
     (ul
      (@ (class "bar-list"))
      (li (@ (class "bar-item"))
@@ -62,9 +64,9 @@
 					     (slugify current-tag)
 					     ".atom"))))
 		    `(href ,(guix-url (url-path-join "feeds" "blog.atom")))))
-	    " Atom feed")))
+            (C_ "button" "Atom feed"))))
 
-    (h4 (@ (class "bar-title")) "Posts by topic")
+    (h4 (@ (class "bar-title")) (G_ "Posts by topic"))
     (ul
      (@ (class "bar-list"))
      ,@(map
diff --git a/website/apps/blog/templates/feed.scm b/website/apps/blog/templates/feed.scm
index 5e015d0..0392345 100644
--- a/website/apps/blog/templates/feed.scm
+++ b/website/apps/blog/templates/feed.scm
@@ -10,6 +10,7 @@
   #:use-module (apps base types)
   #:use-module (apps base utils)
   #:use-module (apps blog utils)
+  #:use-module (apps i18n)
   #:use-module (haunt html)
   #:use-module (haunt post)
   #:use-module (srfi srfi-19)
@@ -28,7 +29,7 @@
       (@ (xmlns "http://www.w3.org/2005/Atom"))
       (id ,id)
       (title ,title)
-      (author (name "GNU Guix") (uri ,domain))
+      (author (name (C_ "feed author name" "GNU Guix")) (uri ,domain))
       (icon ,(guix-url "static/base/img/icon.png"))
       (updated ,(date->string (current-date) "~4"))
       (link (@ (rel "alternate") (href ,alternate)))
diff --git a/website/apps/blog/templates/post-list.scm b/website/apps/blog/templates/post-list.scm
index a64e33a..5b3f73f 100644
--- a/website/apps/blog/templates/post-list.scm
+++ b/website/apps/blog/templates/post-list.scm
@@ -9,6 +9,7 @@
   #:use-module (apps base types)
   #:use-module (apps base utils)
   #:use-module ((apps blog templates components) #:prefix blog:)
+  #:use-module (apps i18n)
   #:export (post-list-t))
 
 
@@ -19,22 +20,24 @@
 	(total-pages
 	 (number->string (context-datum context "total-pages"))))
     (theme
-     #:title (list (string-append "Page " page-number) "Blog")
+     #:title (list (G_ (string-append "Page " page-number ""))
+                   (C_ "webpage title" "Blog"))
      #:description
-     "Blog posts about GNU Guix."
+     (G_ "Blog posts about GNU Guix.")
      #:keywords
-     '("GNU" "Linux" "Unix" "Free software" "Libre software"
-       "Operating system" "GNU Hurd" "GNU Guix package manager"
-       "GNU Guile" "Guile Scheme" "Transactional upgrades"
-       "Functional package management" "Reproducibility")
-     #:active-menu-item "Blog"
+     (string-split ;TRANSLATORS: |-separated list of webpage keywords
+      (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile \
+Scheme|Transactional upgrades|Functional package \
+management|Reproducibility") #\|)
+     #:active-menu-item (C_ "website menu" "Blog")
      #:css
      (list (guix-url "static/base/css/page.css")
 	   (guix-url "static/base/css/item-preview.css")
 	   (guix-url "static/base/css/sidebar.css"))
      #:crumbs
-     (list (crumb "Blog" (guix-url "blog/"))
-	   (crumb (string-append "Page " page-number)
+     (list (crumb (C_ "website menu" "Blog") (guix-url "blog/"))
+           (crumb (G_ (string-append "Page " page-number ""))
 		  (guix-url (url-path-join "blog"
 					   "page"
 					   page-number
@@ -43,7 +46,7 @@
      `(main
        (section
 	(@ (class "page centered-text"))
-	(h2 "Blog"
+        (h2 (G_ "Blog")
 	    ,(page-indicator (string->number page-number)
 			     (string->number total-pages)))
 
diff --git a/website/apps/blog/templates/post.scm b/website/apps/blog/templates/post.scm
index fe90ba0..2871431 100644
--- a/website/apps/blog/templates/post.scm
+++ b/website/apps/blog/templates/post.scm
@@ -9,6 +9,7 @@
   #:use-module (apps base utils)
   #:use-module (apps blog utils)
   #:use-module ((apps blog templates components) #:prefix blog:)
+  #:use-module (apps i18n)
   #:use-module (haunt post)
   #:use-module (srfi srfi-19)
   #:export (post-t))
@@ -21,17 +22,17 @@
     (theme
      #:title (list (post-ref post 'title)
 		   (date->string (post-date post) "~Y")
-		   "Blog")
+                   (C_ "webpage title" "Blog"))
      #:description
-     "Blog posts about GNU Guix."
+     (G_ "Blog posts about GNU Guix.")
      #:keywords tags
-     #:active-menu-item "Blog"
+     #:active-menu-item (C_ "website menu" "Blog")
      #:css
      (list (guix-url "static/base/css/page.css")
 	   (guix-url "static/base/css/code.css")
 	   (guix-url "static/blog/css/post.css"))
      #:crumbs
-     (list (crumb "Blog" (guix-url "blog/"))
+     (list (crumb (C_ "website menu" "Blog") (guix-url "blog/"))
 	   (crumb (post-ref post 'title)
 		  (guix-url (post-url-path post))))
      #:content
@@ -42,13 +43,14 @@
 	(p
 	 (@ (class "post-metadata centered-text"))
 	 ,(post-ref post 'author) " — "
-	 ,(date->string (post-date post) "~B ~e, ~Y"))
+         ,(date->string (post-date post) (C_ "SRFI-19 date->string format"
+                                             "~B ~e, ~Y")))
 
 	,(syntax-highlight (post-sxml post))
 
 	(div
 	 (@ (class "tag-list"))
-	 (p "Related topics:")
+         ,(G_ `(p "Related topics:"))
 
 	 ,@(map
 	    (lambda (tag)
diff --git a/website/apps/blog/templates/tag.scm b/website/apps/blog/templates/tag.scm
index 7d9c88b..7bd7570 100644
--- a/website/apps/blog/templates/tag.scm
+++ b/website/apps/blog/templates/tag.scm
@@ -10,6 +10,7 @@
   #:use-module (apps base utils)
   #:use-module ((apps blog templates components) #:prefix blog:)
   #:use-module (apps blog utils)
+  #:use-module (apps i18n)
   #:export (tag-t))
 
 
@@ -21,25 +22,27 @@
 	(total-pages
 	 (number->string (context-datum context "total-pages"))))
     (theme
-     #:title (list (string-append "Page " page-number) tag "Blog")
+     #:title (list (G_ (string-append "Page " page-number ""))
+                   tag (C_ "webpage title" "Blog"))
      #:description
-     (string-append "Blog posts about "
-		    tag
-		    " on GNU Guix.")
+     (G_ (string-append "Blog posts about "
+                        tag
+                        " on GNU Guix."))
      #:keywords
-     '("GNU" "Linux" "Unix" "Free software" "Libre software"
-       "Operating system" "GNU Hurd" "GNU Guix package manager"
-       "GNU Guile" "Guile Scheme" "Transactional upgrades"
-       "Functional package management" "Reproducibility")
-     #:active-menu-item "Blog"
+     (string-split ;TRANSLATORS: |-separated list of webpage keywords
+      (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile \
+Scheme|Transactional upgrades|Functional package \
+management|Reproducibility") #\|)
+     #:active-menu-item (C_ "website menu" "Blog")
      #:css
      (list (guix-url "static/base/css/page.css")
 	   (guix-url "static/base/css/item-preview.css")
 	   (guix-url "static/base/css/sidebar.css"))
      #:crumbs
-     (list (crumb "Blog" (guix-url "blog/"))
+     (list (crumb (C_ "website menu" "Blog") (guix-url "blog/"))
 	   (crumb tag (guix-url (tag-url-path tag)))
-	   (crumb (string-append "Page " page-number)
+           (crumb (G_ (string-append "Page " page-number ""))
 		  (guix-url (url-path-join (tag-url-path tag)
 					   "page"
 					   page-number
@@ -48,7 +51,7 @@
      `(main
        (section
 	(@ (class "page centered-text"))
-	(h2 "Blog — " ,tag
+        (h2 ,(G_ "Blog — ") ,tag
 	    ,(page-indicator (string->number page-number)
 			     (string->number total-pages)))
 
diff --git a/website/apps/download/data.scm b/website/apps/download/data.scm
index 8e432db..34c50df 100644
--- a/website/apps/download/data.scm
+++ b/website/apps/download/data.scm
@@ -5,6 +5,7 @@
 (define-module (apps download data)
   #:use-module (apps base utils)
   #:use-module (apps download types)
+  #:use-module (apps i18n)
   #:export (system-downloads))
 
 
@@ -16,34 +17,44 @@
 (define system-downloads
   (list
    (download
-    #:title (string-append "GNU Guix System " (latest-guix-version))
+    #:title (C_ "download page title"
+                (string-append "GNU Guix System " (latest-guix-version) ""))
     #:description
     `(div
-      (p "USB/DVD ISO installer of the standalone Guix System."))
+      ,(G_ `(p "USB/DVD ISO installer of the standalone Guix System.")))
     #:image (guix-url "static/base/img/GuixSD-package.png")
     #:base-url (string-append "https://ftp.gnu.org/gnu/guix/guix-system-install-"
 			      (latest-guix-version) ".")
     #:variants (list (variant "x86_64" "x86_64-linux.iso.xz")
 		     (variant "i686" "i686-linux.iso.xz"))
-    #:manual (manual-url "System-Installation.html"))
+    ;; TRANSLATORS: System installation is a section name in the
+    ;; English (en) manual.
+    #:manual (G_ (manual-url-with-language (G_ "en")
+                                           "System-Installation.html")))
 
    (download
-    #:title (string-append "GNU Guix " (latest-guix-version) " QEMU Image")
+    #:title (C_ "download page title"
+                (string-append "GNU Guix " (latest-guix-version) " QEMU Image"))
     #:description
     `(div
-      (p "QCOW2 virtual machine (VM) image."))
+      ,(G_ `(p "QCOW2 virtual machine (VM) image.")))
     #:image (guix-url "static/base/img/QEMU-package.png")
     #:base-url (string-append "https://ftp.gnu.org/gnu/guix/guix-system-vm-image-"
 			      (latest-guix-version) ".")
     #:variants (list (variant "x86_64" "x86_64-linux.xz"))
-    #:manual (manual-url "Running-Guix-in-a-VM.html"))
+    ;; TRANSLATORS: Running Guix in a VM is a section name in the
+    ;; English (en) manual.
+    #:manual (G_ (manual-url-with-language (G_ "en")
+                                           "Running-Guix-in-a-VM.html")))
 
    (download
-    #:title (string-append "GNU Guix " (latest-guix-version) " Binary")
+    #:title (C_ "download page title"
+                (string-append "GNU Guix " (latest-guix-version) " Binary"))
     #:description
-    '(p
-      "Self-contained tarball providing binaries for Guix and its
-      dependencies, to be installed on top of your Linux-based system.")
+    (G_
+     '(p
+       "Self-contained tarball providing binaries for Guix and its
+       dependencies, to be installed on top of your Linux-based system."))
     #:image (guix-url "static/base/img/Guix-package.png")
     #:base-url (string-append "https://ftp.gnu.org/gnu/guix/guix-binary-"
 			      (latest-guix-version) ".")
@@ -51,13 +62,20 @@
 		     (variant "i686" "i686-linux.tar.xz")
 		     (variant "armhf" "armhf-linux.tar.xz")
                      (variant "aarch64" "aarch64-linux.tar.xz"))
-    #:manual (manual-url "Binary-Installation.html"))
+    ;; TRANSLATORS: Binary Installation is a section name in the
+    ;; English (en) manual.
+    #:manual (G_ (manual-url-with-language (G_ "en")
+                                           "Binary-Installation.html")))
 
    (download
-    #:title (string-append "GNU Guix " (latest-guix-version) " Source")
-    #:description '(p "Source code distribution.")
+    #:title (C_ "download page title"
+                (string-append "GNU Guix " (latest-guix-version) " Source"))
+    #:description (G_ '(p "Source code distribution."))
     #:image (guix-url "static/base/img/src-package.png")
     #:base-url (string-append "https://ftp.gnu.org/gnu/guix/guix-"
 			      (latest-guix-version) ".")
     #:variants (list (variant "tarball" "tar.gz"))
-    #:manual (manual-url "Requirements.html"))))
+    ;; TRANSLATORS: Requirements is a section name in the English (en)
+    ;; manual.
+    #:manual (G_ (manual-url-with-language (G_ "en")
+                                           "Requirements.html")))))
diff --git a/website/apps/download/templates/components.scm b/website/apps/download/templates/components.scm
index bbd46b0..60e7330 100644
--- a/website/apps/download/templates/components.scm
+++ b/website/apps/download/templates/components.scm
@@ -4,6 +4,7 @@
 
 (define-module (apps download templates components)
   #:use-module (apps download types)
+  #:use-module (apps i18n)
   #:export (download))
 
 
@@ -21,7 +22,7 @@
     (img (@ (src ,(download-image dnd)) (alt "")))
     (h3 ,(download-title dnd))
     ,(download-description dnd)
-    (p "Download options:")
+    ,(G_ `(p "Download options:"))
     ,@(map (lambda (variant)
 	     `(a
 	       (@ (class "download-btn")
@@ -34,7 +35,7 @@
 	  (download-variants dnd))
 
     (p
-     "Signatures: "
+     ,(G_ "Signatures: ")
      ,@(map (lambda (variant)
 	     `(a
 	       (@ (class "signature-btn")
@@ -46,4 +47,9 @@
 	       " ")) ; Force a space for readability in non-CSS browsers.
 	    (download-variants dnd)))
 
-    (p (a (@ (href ,(download-manual dnd))) "Installation instructions") ".")))
+    ,(G_
+      `(p
+        ,(G_
+          `(a (@ (href ,(download-manual dnd)))
+              "Installation instructions"))
+        "."))))
diff --git a/website/apps/download/templates/download.scm b/website/apps/download/templates/download.scm
index f888a0b..ffa6ce0 100644
--- a/website/apps/download/templates/download.scm
+++ b/website/apps/download/templates/download.scm
@@ -23,56 +23,60 @@
   #:use-module (apps base types)
   #:use-module (apps base utils)
   #:use-module (apps download templates components)
+  #:use-module (apps i18n)
   #:export (download-t))
 
 
 (define (download-t context)
   "Return the Download page in SHTML."
   (theme
-   #:title '("Download")
+   #:title (C_ "webpage title" '("Download"))
    #:description
-   "Installers and source files for GNU Guix.  GNU Guix can be
-   installed on different GNU/Linux distributions."
+   (G_ "Installers and source files for GNU Guix.  GNU Guix can be
+   installed on different GNU/Linux distributions.")
    #:keywords
-   '("GNU" "Linux" "Unix" "Free software" "Libre software"
-     "Operating system" "GNU Hurd" "GNU Guix package manager"
-     "Installer" "Source code" "Package manager")
-   #:active-menu-item "Download"
+   (string-split ;TRANSLATORS: |-separated list of webpage keywords
+    (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|Installer|Source code|\
+Package manager") #\|)
+   #:active-menu-item (C_ "website menu" "Download")
    #:css (list
 	  (guix-url "static/base/css/page.css")
 	  (guix-url "static/base/css/download.css"))
-   #:crumbs (list (crumb "Download" "./"))
+   #:crumbs (list (crumb (C_ "website menu" "Download") "./"))
    #:content
    `(main
      (section
       (@ (class "page"))
-      (h2 "Download")
+      ,(G_ `(h2 "Download"))
 
-      (p
-       (@ (class "centered-block limit-width"))
-       "As of version " ,(latest-guix-version)
-       ", the standalone Guix System "
-       (a
-	(@ (href ,(manual-url "System-Installation.html")))
-	"can be installed")
-       " on an i686, x86_64, ARMv7, or AArch64 machine.  It uses the "
-       (a (@ (href ,(gnu-url "software/linux-libre"))) "Linux-Libre")
-       " kernel and the "
-       (a (@ (href ,(gnu-url "software/shepherd"))) "GNU Shepherd")
-       " init system. Alternately, GNU Guix
-       can be installed as an additional package manager on top of an
-       installed Linux-based system.")
+      ,(G_
+        `(p
+          (@ (class "centered-block limit-width"))
+          "As of version " ,(latest-guix-version)
+          ", the standalone Guix System "
+          ,(G_ `(a
+                 (@ (href ,(manual-url "System-Installation.html")))
+                 "can be installed"))
+          " on an i686, x86_64, ARMv7, or AArch64 machine.  It uses the "
+          ,(G_ `(a (@ (href ,(gnu-url "software/linux-libre"))) "Linux-Libre"))
+          " kernel and the "
+          ,(G_ `(a (@ (href ,(gnu-url "software/shepherd"))) "GNU Shepherd"))
+          " init system. Alternately, GNU Guix
+          can be installed as an additional package manager on top of an
+          installed Linux-based system."))
 
       (div
        (@ (class "centered-text"))
        ,@(map download (context-datum context "downloads")))
 
-      (p
-       (@ (class "centered-block limit-width"))
-       "Source code and binaries for the Guix System distribution ISO
-       image as well as GNU Guix can be found on the GNU servers at "
-       (a (@ (href "https://ftp.gnu.org/gnu/guix/"))
-	  "https://ftp.gnu.org/gnu/guix/")
-       ".  Older releases can still be found on "
-       (a (@ (href "https://alpha.gnu.org/gnu/guix/"))
-          "alpha.gnu.org") ".")))))
+      ,(G_
+        `(p
+          (@ (class "centered-block limit-width"))
+          "Source code and binaries for the Guix System distribution ISO
+          image as well as GNU Guix can be found on the GNU servers at "
+          (a (@ (href "https://ftp.gnu.org/gnu/guix/"))
+             "https://ftp.gnu.org/gnu/guix/")
+          ".  Older releases can still be found on "
+          (a (@ (href "https://alpha.gnu.org/gnu/guix/"))
+             "alpha.gnu.org") "."))))))
diff --git a/website/apps/packages/templates/components.scm b/website/apps/packages/templates/components.scm
index 96e4296..926ec0b 100644
--- a/website/apps/packages/templates/components.scm
+++ b/website/apps/packages/templates/components.scm
@@ -8,6 +8,7 @@
   #:use-module (apps aux web)
   #:use-module (apps base templates components)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:use-module (apps packages data)
   #:use-module (apps packages types)
   #:use-module (apps packages utils)
@@ -55,37 +56,38 @@
      ;; 'gnu-package?' might fetch stuff from the network.  Assume #f if that
      ;; doesn't work.
      ,(if (false-if-exception (gnu-package? package))
-          '(p (i "This is a GNU package.  "))
+          `(p (i ,(G_ "This is a GNU package.  ")))
           "")
 
      ,(package-description-shtml package))
 
     (ul
      (@ (class "package-info"))
-     (li (b "License:") " "
-	 ,(license->shtml (package-license package))
-	 ".")
-
-     (li (b "Website:") " "
-	 ,(link-subtle #:label (package-home-page package)
-		       #:url (package-home-page package)) ".")
-
-     (li (b "Package source:") " "
-	 ,(location->shtml (package-location package))
-	 ".")
-
-     (li (b "Patches:") " "
-	 ,(patches->shtml (package-patches package))
-	 ".")
-
-     (li (b "Lint issues:") " "
-     	 ,(if (null? (package-lint-issues package))
-     	      "No"
-     	      (link-subtle #:label "Yes"
-     	 		   #:url (guix-url "packages/issues/")))
-     	 ".")
-
-     (li (b "Builds:") " " ,(supported-systems->shtml package) ".")
+     ,(G_ `(li ,(G_ `(b "License:")) " "
+               ,(license->shtml (package-license package))
+               "."))
+
+     ,(G_ `(li ,(G_ `(b "Website:")) " "
+               ,(link-subtle #:label (package-home-page package)
+                             #:url (package-home-page package)) "."))
+
+     ,(G_ `(li ,(G_ `(b "Package source:")) " "
+               ,(location->shtml (package-location package))
+               "."))
+
+     ,(G_ `(li ,(G_ `(b "Patches:")) " "
+               ,(patches->shtml (package-patches package))
+               "."))
+
+     ,(G_ `(li ,(G_ `(b "Lint issues:")) " "
+               ,(if (null? (package-lint-issues package))
+                    (G_ "No")
+                    (link-subtle #:label (G_ "Yes")
+                                 #:url (guix-url "packages/issues/")))
+               "."))
+
+     ,(G_ `(li ,(G_ `(b "Builds:")) " "
+               ,(supported-systems->shtml package) "."))
      "\n")))
 
 
@@ -99,7 +101,7 @@
      A span element if the count is 0. A mark element otherwise."
   `(,(if (> count 0) 'mark 'span)
     ,(number->string count)
-    ,(if (= count 1) " issue" " issues")))
+    ,(N_ " issue" " issues" count)))
 
 
 (define* (letter-selector #:optional (active-letter ""))
@@ -110,10 +112,10 @@
      The letter that should be displayed as active."
   `(section
     (@ (class "letter-selector"))
-    (h3 (@ (class "a11y-offset")) "Packages menu: ")
+    ,(G_ `(h3 (@ (class "a11y-offset")) "Packages menu: "))
 
-    (h4 (@ (class "selector-title selector-title-top"))
-	"Browse alphabetically")
+    ,(G_ `(h4 (@ (class "selector-title selector-title-top"))
+              "Browse alphabetically"))
     (div
      (@ (class "selector-box-padded"))
      ,@(map
@@ -199,7 +201,7 @@
      If the list of patches is empty, return the string 'None'.
      Otherwise, return a list of links to patches."
   (if (null? patches)
-      "None"
+      (G_ "None")
       (separate
        (map (lambda (patch)
 	      (link-subtle #:label (ilink-name patch)
@@ -216,9 +218,9 @@
      The letter in which the current packages are listed."
   `(section
     (@ (class "side-bar"))
-    (h3 (@ (class "a11y-offset")) "Packages menu: ")
+    ,(G_ `(h3 (@ (class "a11y-offset")) "Packages menu: "))
 
-    (h4 (@ (class "bar-title bar-title-top")) "Browse alphabetically")
+    ,(G_ `(h4 (@ (class "bar-title bar-title-top")) "Browse alphabetically"))
     (div
      (@ (class "bar-box-padded"))
      ,@(map
@@ -233,16 +235,16 @@
 
     ;; FIXME: This is currently too costly to produce so we just disable it.
 
-    ;; (h4 (@ (class "bar-title")) "Packages Issues")
+    ;; ,(G_ `(h4 (@ (class "bar-title")) "Packages Issues"))
     ;; (ul
     ;;  (@ (class "bar-list"))
     ;;  (li (@ (class "bar-item"))
-    ;;      (a (@ (class "bar-link")
-    ;;            (href ,(guix-url "packages/issues/lint/"))) "Lint"))
+    ;;      ,(G_ `(a (@ (class "bar-link")
+    ;;                  (href ,(guix-url "packages/issues/lint/"))) "Lint")))
     ;;  (li (@ (class "bar-item"))
-    ;;      (a (@ (class "bar-link")
-    ;;            (href ,(guix-url "packages/issues/reproducibility/")))
-    ;;         "Reproducibility")))
+    ;;      ,(G_ `(a (@ (class "bar-link")
+    ;;                  (href ,(guix-url "packages/issues/reproducibility/")))
+    ;;               "Reproducibility"))))
     ))
 
 
@@ -265,7 +267,7 @@
                   %hydra-supported-systems
                   (package-transitive-supported-systems package))))
     (if (null? systems)
-	"None"
+        (G_ "None")
 	(separate
 	 (map (lambda (system)
 		(link-subtle #:label system
diff --git a/website/apps/packages/templates/detailed-index.scm b/website/apps/packages/templates/detailed-index.scm
index 81dfdd6..68dc9de 100644
--- a/website/apps/packages/templates/detailed-index.scm
+++ b/website/apps/packages/templates/detailed-index.scm
@@ -8,6 +8,7 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:use-module (apps packages templates components)
   #:use-module (srfi srfi-19)
   #:export (detailed-index-t))
@@ -18,39 +19,45 @@
 packages to advertise."
   (let ((packages (context-datum context "packages")))
     (theme
-     #:title (list "Packages")
+     #:title (C_ "webpage title" (list "Packages"))
      #:description
-     "List of packages available through GNU Guix."
+     (G_ "List of packages available through GNU Guix.")
      #:keywords
-     (list "GNU" "Linux" "Unix" "Free software" "Libre software"
-	   "Operating system" "GNU Hurd" "GNU Guix package manager"
-	   "GNU Guile" "Guile Scheme" "Transactional upgrades"
-	   "Functional package management" "Reproducibility")
-     #:active-menu-item "Packages"
+     (string-split ;TRANSLATORS: |-separated list of webpage keywords
+      (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile \
+Scheme|Transactional upgrades|Functional package \
+management|Reproducibility") #\|)
+     #:active-menu-item (C_ "website menu" "Packages")
      #:css
      (list (guix-url "static/base/css/page.css")
 	   (guix-url "static/base/css/item-preview.css")
 	   (guix-url "static/packages/css/letter-selector.css")
 	   (guix-url "static/packages/css/package-list.css"))
      #:crumbs
-     (list (crumb "Packages" (guix-url "packages/")))
+     (list (crumb (C_ "website menu" "Packages") (guix-url "packages/")))
      #:content
      `(main
        (section
 	(@ (class "page centered-text"))
-	(h2 "Packages")
+        ,(G_ `(h2 "Packages"))
 
-	(p
-	 (@ (class "limit-width centered-block"))
-	 "GNU Guix provides " ,(number* (or total (length packages)))
-	 " packages transparently "
-	 (a (@ (href "https://hydra.gnu.org/jobset/gnu/master#tabs-status"))
-	    "available as pre-built binaries")
-	 ". These pages provide a complete list of the packages.  Our "
-	 (a (@ (href "https://hydra.gnu.org/jobset/gnu/master"))
-	    "continuous integration system")
-	 " shows their current build status "
-	 "(updated " ,(date->string (current-date) "~B ~e, ~Y") ").")
+        ,(G_
+          `(p
+            (@ (class "limit-width centered-block"))
+            "GNU Guix provides " ,(number* (or total (length packages)))
+            " packages transparently "
+            ,(G_
+              `(a (@ (href "https://hydra.gnu.org/jobset/gnu/master#tabs-status"))
+                  "available as pre-built binaries"))
+            ". These pages provide a complete list of the packages.  Our "
+            ,(G_
+              `(a (@ (href "https://hydra.gnu.org/jobset/gnu/master"))
+                  "continuous integration system"))
+            " shows their current build status "
+            "(updated " ,(date->string (current-date)
+                                       (C_ "SRFI-19 date->string format"
+                                           "~B ~e, ~Y")) ")."))
 
 	(div
 	 (@ (class "sheet sheet-padded justify-left"))
diff --git a/website/apps/packages/templates/detailed-package-list.scm b/website/apps/packages/templates/detailed-package-list.scm
index c0a60de..9b23ed1 100644
--- a/website/apps/packages/templates/detailed-package-list.scm
+++ b/website/apps/packages/templates/detailed-package-list.scm
@@ -8,6 +8,7 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:use-module (apps packages templates components)
   #:export (detailed-package-list-t))
 
@@ -20,15 +21,17 @@
 	(total-pages
 	 (number->string (context-datum context "total-pages"))))
     (theme
-     #:title (list (string-append "Page " page-number) letter "Packages")
+     #:title (list (G_ (string-append "Page " page-number ""))
+                   letter (C_ "webpage title" "Packages"))
      #:description
-     "List of packages available through GNU Guix."
+     (G_ "List of packages available through GNU Guix.")
      #:keywords
-     '("GNU" "Linux" "Unix" "Free software" "Libre software"
-       "Operating system" "GNU Hurd" "GNU Guix package manager"
-       "GNU Guile" "Guile Scheme" "Transactional upgrades"
-       "Functional package management" "Reproducibility")
-     #:active-menu-item "Packages"
+     (string-split ;TRANSLATORS: |-separated list of webpage keywords
+      (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile \
+Scheme|Transactional upgrades|Functional package \
+management|Reproducibility") #\|)
+     #:active-menu-item (C_ "website menu" "Packages")
      #:css
      (list (guix-url "static/base/css/page.css")
 	   (guix-url "static/base/css/item-preview.css")
@@ -37,11 +40,11 @@
      #:scripts
      (list (guix-url "static/packages/js/build-status.js"))
      #:crumbs
-     (list (crumb "Packages" (guix-url "packages/"))
+     (list (crumb (C_ "website menu" "Packages") (guix-url "packages/"))
 	   (crumb letter (guix-url (url-path-join "packages"
 						  letter
 						  "")))
-	   (crumb (string-append "Page " page-number)
+           (crumb (G_ (string-append "Page " page-number ""))
 		  (guix-url (url-path-join "packages"
 					   "page"
 					   page-number
@@ -50,7 +53,7 @@
      `(main
        (section
 	(@ (class "page centered-text"))
-	(h2 "Packages — " ,letter
+        (h2 (G_ "Packages — ") ,letter
 	    ,(page-indicator (string->number page-number)
 			     (string->number total-pages)))
 
diff --git a/website/apps/packages/templates/index.scm b/website/apps/packages/templates/index.scm
index afd10d9..aa0a91d 100644
--- a/website/apps/packages/templates/index.scm
+++ b/website/apps/packages/templates/index.scm
@@ -8,6 +8,7 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:use-module (apps packages templates components)
   #:use-module (srfi srfi-19)
   #:export (index-t))
@@ -18,37 +19,43 @@
   (let ((packages (context-datum context "packages"))
 	(total    (context-datum context "total")))
     (theme
-     #:title (list "Packages")
+     #:title (C_ "webpage title" (list "Packages"))
      #:description
-     "List of packages available through GNU Guix."
+     (G_ "List of packages available through GNU Guix.")
      #:keywords
-     (list "GNU" "Linux" "Unix" "Free software" "Libre software"
-	   "Operating system" "GNU Hurd" "GNU Guix package manager"
-	   "GNU Guile" "Guile Scheme" "Transactional upgrades"
-	   "Functional package management" "Reproducibility")
-     #:active-menu-item "Packages"
+     (string-split ;TRANSLATORS: |-separated list of webpage keywords
+      (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile \
+Scheme|Transactional upgrades|Functional package \
+management|Reproducibility") #\|)
+     #:active-menu-item (C_ "website menu" "Packages")
      #:css
      (list (guix-url "static/base/css/page.css")
 	   (guix-url "static/base/css/item-preview.css")
 	   (guix-url "static/packages/css/letter-selector.css"))
      #:crumbs
-     (list (crumb "Packages" (guix-url "packages/")))
+     (list (crumb (C_ "website menu" "Packages") (guix-url "packages/")))
      #:content
      `(main
        (section
 	(@ (class "page centered-text"))
-	(h2 "Packages")
+        ,(G_ `(h2 "Packages"))
 
-	(p
-	 (@ (class "limit-width centered-block"))
-	 "GNU Guix provides " ,(number* total) " packages transparently "
-	 (a (@ (href "https://hydra.gnu.org/jobset/gnu/master#tabs-status"))
-	    "available as pre-built binaries")
-	 ". These pages provide a complete list of the packages.  Our "
-	 (a (@ (href "https://hydra.gnu.org/jobset/gnu/master"))
-	    "continuous integration system")
-	 " shows their current build status "
-	 "(updated " ,(date->string (current-date) "~B ~e, ~Y") ").")
+        ,(G_
+          `(p
+            (@ (class "limit-width centered-block"))
+            "GNU Guix provides " ,(number* total) " packages transparently "
+            ,(G_
+              `(a (@ (href "https://hydra.gnu.org/jobset/gnu/master#tabs-status"))
+                  "available as pre-built binaries"))
+            ". These pages provide a complete list of the packages.  Our "
+            ,(G_
+              `(a (@ (href "https://hydra.gnu.org/jobset/gnu/master"))
+                  "continuous integration system"))
+            " shows their current build status "
+            "(updated " ,(date->string (current-date)
+                                       (C_ "SRFI-19 date->string format"
+                                           "~B ~e, ~Y")) ")."))
 
 	(div
 	 (@ (class "sheet"))
diff --git a/website/apps/packages/templates/package-list.scm b/website/apps/packages/templates/package-list.scm
index e047812..d77ed17 100644
--- a/website/apps/packages/templates/package-list.scm
+++ b/website/apps/packages/templates/package-list.scm
@@ -8,6 +8,7 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:use-module (apps packages templates components)
   #:export (package-list-t))
 
@@ -20,25 +21,27 @@
 	(total-pages
 	 (number->string (context-datum context "total-pages"))))
     (theme
-     #:title (list (string-append "Page " page-number) letter "Packages")
+     #:title (list (G_ (string-append "Page " page-number ""))
+                   letter (C_ "webpage title" "Packages"))
      #:description
      "List of packages available through GNU Guix."
      #:keywords
-     '("GNU" "Linux" "Unix" "Free software" "Libre software"
-       "Operating system" "GNU Hurd" "GNU Guix package manager"
-       "GNU Guile" "Guile Scheme" "Transactional upgrades"
-       "Functional package management" "Reproducibility")
-     #:active-menu-item "Packages"
+     (string-split ;TRANSLATORS: |-separated list of webpage keywords
+      (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile \
+Scheme|Transactional upgrades|Functional package \
+management|Reproducibility") #\|)
+     #:active-menu-item (C_ "website menu" "Packages")
      #:css
      (list (guix-url "static/base/css/page.css")
 	   (guix-url "static/base/css/item-preview.css")
 	   (guix-url "static/packages/css/letter-selector.css"))
      #:crumbs
-     (list (crumb "Packages" (guix-url "packages/"))
+     (list (crumb (C_ "website menu" "Packages") (guix-url "packages/"))
 	   (crumb letter (guix-url (url-path-join "packages"
 						  letter
 						  "")))
-	   (crumb (string-append "Page " page-number)
+           (crumb (G_ (string-append "Page " page-number ""))
 		  (guix-url (url-path-join "packages"
 					   "page"
 					   page-number
@@ -47,7 +50,7 @@
      `(main
        (section
 	(@ (class "page centered-text"))
-	(h2 "Packages — " ,letter
+	(h2 (G_ "Packages — ") ,letter
 	    ,(page-indicator (string->number page-number)
 			     (string->number total-pages)))
 
diff --git a/website/apps/packages/templates/package.scm b/website/apps/packages/templates/package.scm
index 9dfb2fa..814700f 100644
--- a/website/apps/packages/templates/package.scm
+++ b/website/apps/packages/templates/package.scm
@@ -8,6 +8,7 @@
   #:use-module (apps base templates theme)
   #:use-module (apps base types)
   #:use-module (apps base utils)
+  #:use-module (apps i18n)
   #:use-module (apps packages templates components)
   #:use-module (apps packages types)
   #:use-module (apps packages utils)
@@ -24,19 +25,20 @@
 				    (package-version package)))
 	 (lint-issues (package-lint-issues package)))
     (theme
-     #:title (list package-id "Packages")
+     #:title (C_ "webpage title" (list package-id "Packages"))
      #:description (package-synopsis-shtml package)
      #:keywords
-     '("GNU" "Linux" "Unix" "Free software" "Libre software"
-       "Operating system" "GNU Hurd" "GNU Guix package manager"
-       "GNU Guile" "Guile Scheme" "Transactional upgrades"
-       "Functional package management" "Reproducibility")
-     #:active-menu-item "Packages"
+     (string-split ;TRANSLATORS: |-separated list of webpage keywords
+      (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \
+system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile \
+Scheme|Transactional upgrades|Functional package \
+management|Reproducibility") #\|)
+     #:active-menu-item (C_ "website menu" "Packages")
      #:css
      (list (guix-url "static/base/css/page.css")
 	   (guix-url "static/packages/css/package.css"))
      #:crumbs
-     (list (crumb "Packages" (guix-url "packages/"))
+     (list (crumb (C_ "website menu" "Packages") (guix-url "packages/"))
 	   (crumb package-id
 		  (guix-url (package-url-path package))))
      #:content
@@ -51,31 +53,35 @@
         ;; 'gnu-package?' might fetch stuff from the network.  Assume #f if
         ;; that doesn't work.
 	(p ,(if (false-if-exception (gnu-package? package))
-                '(it "This is a GNU package.  ")
+                (G_ '(it "This is a GNU package.  "))
                 "")
            ,(package-description-shtml package))
 
 	(ul
 	 (@ (class "package-info"))
-	 (li (b "Website: ")
-	     (a (@ (href ,(package-home-page package)))
-		,(package-home-page package)))
-	 (li (b "License: ")
-	     ,(license->shtml (package-license package)))
-	 (li (b "Package source: ")
-	     ,(location->shtml (package-location package)))
-	 (li (b "Patches: ")
-	     ,(patches->shtml (package-patches package)))
-	 (li (b "Builds: ")
-	     ,(supported-systems->shtml package)))
+         ,(G_ `(li ,(G_ `(b "Website: "))
+                   (a (@ (href ,(package-home-page package)))
+                      ,(package-home-page package))))
+         ,(G_ `(li ,(G_ `(b "License: "))
+                   ,(license->shtml (package-license package))))
+         ,(G_ `(li ,(G_ `(b "Package source: "))
+                   ,(location->shtml (package-location package))))
+         ,(G_ `(li ,(G_ `(b "Patches: "))
+                   ,(patches->shtml (package-patches package))))
+         ,(G_ `(li ,(G_ `(b "Builds: "))
+                   ,(supported-systems->shtml package))))
 
 	;; Lint issues.
 	,(if (null? lint-issues)
 	     ""
-	     `((h3 "Lint issues")
-	       (p
-		,(issue-count->shtml (length lint-issues)) ". "
-		"See " (a (@ (href "#")) "package definition")
-		" in Guix source code.")
+             (G_ `(,(G_ `(h3 "Lint issues"))
+                   ,(G_
+                     `(p
+                       ""
+                       ,(issue-count->shtml
+                         (length lint-issues))
+                       ". "
+                       "See " ,(G_ `(a (@ (href "#")) "package definition"))
+                       " in Guix source code."))
 
-	       ,@(map lint-issue->shtml lint-issues))))))))
+                   ,@(map lint-issue->shtml lint-issues)))))))))
diff --git a/website/po/guix-website.pot b/website/po/guix-website.pot
new file mode 100644
index 0000000..350ca1b
--- /dev/null
+++ b/website/po/guix-website.pot
@@ -0,0 +1,1216 @@
+# 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: ludo@HIDDEN\n"
+"POT-Creation-Date: 2019-09-15 14:15+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@HIDDEN>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. TRANSLATORS: The locale’s display name; please include a country
+#. code like in English (US) *only* if there are multiple
+#. Translation Project teams for the same language.
+#: apps/base/utils.scm:63
+msgid "English (US)"
+msgstr ""
+
+#: apps/base/templates/home.scm:18
+msgctxt "webpage title"
+msgid "GNU's advanced distro and transactional package manager"
+msgstr ""
+
+#: apps/base/templates/home.scm:20 apps/base/templates/about.scm:19
+msgid "Guix is an advanced distribution of the GNU operating system.\n   Guix is technology that respects the freedom of computer users.\n   You are free to run the system for any purpose, study how it\n   works, improve it, and share it with the whole world."
+msgstr ""
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/home.scm:26 apps/base/templates/menu.scm:20 apps/base/templates/screenshot.scm:23 apps/blog/templates/post-list.scm:29 apps/blog/templates/tag.scm:33 apps/packages/templates/detailed-index.scm:27 apps/packages/templates/detailed-package-list.scm:30 apps/packages/templates/index.scm:27 apps/packages/templates/package-list.scm:30 apps/packages/templates/package.scm:32
+msgid "GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile Scheme|Transactional upgrades|Functional package management|Reproducibility"
+msgstr ""
+
+#: apps/base/templates/home.scm:30 apps/base/templates/components.scm:343 apps/base/templates/screenshot.scm:27
+msgctxt "website menu"
+msgid "Overview"
+msgstr ""
+
+#: apps/base/templates/home.scm:39
+msgid "Summary"
+msgstr ""
+
+#: apps/base/templates/home.scm:41
+msgid "<1>Liberating.</1> Guix is an advanced distribution of the <2>GNU operating system</2> developed by the <3>GNU Project</3>—which respects the <4>freedom of computer users</4>. "
+msgstr ""
+
+#. TRANSLATORS: Package Management, Features and Using the
+#. Configuration System are section names in the English (en)
+#. manual.
+#: apps/base/templates/home.scm:62
+msgid "<1>Dependable.</1> Guix <2>supports<2.1>en</2.1><2.2>Package-Management.html</2.2></2> transactional upgrades and roll-backs, unprivileged package management, <3>and more<3.1>en</3.1><3.2>Features.html</3.2></3>.  When used as a standalone distribution, Guix supports <4>declarative system configuration<4.1>en</4.1><4.2>Using-the-Configuration-System.html</4.2></4> for transparent and reproducible operating systems."
+msgstr ""
+
+#. TRANSLATORS: Defining Packages and System Configuration are
+#. section names in the English (en) manual.
+#: apps/base/templates/home.scm:82
+msgid "<1>Hackable.</1> It provides <2>Guile Scheme</2> APIs, including high-level embedded domain-specific languages (EDSLs) to <3>define packages<3.1>en</3.1><3.2>Defining-Packages.html</3.2></3> and <4>whole-system configurations<4.1>en</4.1><4.2>System-Configuration.html</4.2></4>."
+msgstr ""
+
+#: apps/base/templates/home.scm:104
+msgctxt "button"
+msgid "DOWNLOAD v<1/>"
+msgstr ""
+
+#: apps/base/templates/home.scm:109
+msgctxt "button"
+msgid "CONTRIBUTE"
+msgstr ""
+
+#: apps/base/templates/home.scm:116
+msgid "Discover Guix"
+msgstr ""
+
+#: apps/base/templates/home.scm:118
+msgid "Guix comes with thousands of packages which include applications, system tools, documentation, fonts, and other digital goods readily available for installing with the <1>GNU Guix</1> package manager."
+msgstr ""
+
+#: apps/base/templates/home.scm:135
+msgctxt "button"
+msgid "ALL PACKAGES"
+msgstr ""
+
+#: apps/base/templates/home.scm:142
+msgid "GNU Guix in your field"
+msgstr ""
+
+#: apps/base/templates/home.scm:144
+msgid "Read some stories about how people are using GNU Guix in\ntheir daily lives."
+msgstr ""
+
+#: apps/base/templates/home.scm:155
+msgctxt "button"
+msgid "SOFTWARE DEVELOPMENT"
+msgstr ""
+
+#: apps/base/templates/home.scm:160
+msgctxt "button"
+msgid "BIOINFORMATICS"
+msgstr ""
+
+#: apps/base/templates/home.scm:165
+msgctxt "button"
+msgid "HIGH PERFORMANCE COMPUTING"
+msgstr ""
+
+#: apps/base/templates/home.scm:170
+msgctxt "button"
+msgid "RESEARCH"
+msgstr ""
+
+#: apps/base/templates/home.scm:175
+msgctxt "button"
+msgid "ALL FIELDS..."
+msgstr ""
+
+#: apps/base/templates/home.scm:182
+msgid "GNU Guix in other GNU/Linux distros"
+msgstr ""
+
+#: apps/base/templates/home.scm:194
+msgid "Video: <1>Demo of Guix in another GNU/Linux distribution<1.1/>https://audio-video.gnu.org/video/misc/2016-07__GNU_Guix_Demo_2.webm</1> (1 minute, 30 seconds)."
+msgstr ""
+
+#: apps/base/templates/home.scm:205
+msgid "If you don't use GNU Guix as a standalone GNU/Linux distribution, you still can use it as a package manager on top of any GNU/Linux distribution. This way, you can benefit from all its conveniences."
+msgstr ""
+
+#: apps/base/templates/home.scm:210
+msgid "Guix won't interfere with the package manager that comes with your distribution. They can live together."
+msgstr ""
+
+#: apps/base/templates/home.scm:217
+msgctxt "button"
+msgid "TRY IT OUT!"
+msgstr ""
+
+#: apps/base/templates/home.scm:224 apps/blog/templates/post-list.scm:49
+msgid "Blog"
+msgstr ""
+
+#: apps/base/templates/home.scm:231
+msgctxt "button"
+msgid "ALL POSTS"
+msgstr ""
+
+#: apps/base/templates/home.scm:237 apps/base/templates/contact.scm:36
+msgid "Contact"
+msgstr ""
+
+#: apps/base/templates/home.scm:244
+msgctxt "button"
+msgid "ALL CONTACT MEDIA"
+msgstr ""
+
+#: apps/base/templates/theme.scm:17 apps/base/templates/components.scm:350 apps/base/templates/about.scm:27 apps/base/templates/about.scm:30 apps/base/templates/contact.scm:26 apps/base/templates/contribute.scm:26 apps/base/templates/graphics.scm:24 apps/base/templates/security.scm:28
+msgctxt "website menu"
+msgid "About"
+msgstr ""
+
+#: apps/base/templates/theme.scm:74 apps/base/templates/theme.scm:76
+msgctxt "webpage title"
+msgid "GNU Guix"
+msgstr ""
+
+#: apps/base/templates/theme.scm:98
+msgctxt "webpage title"
+msgid "GNU Guix — Activity Feed"
+msgstr ""
+
+#: apps/base/templates/theme.scm:115
+msgid "Made with <1>♥</1> by humans and powered by <2>GNU Guile</2>.  <3>Source code</3> under the <4>GNU AGPL</4>."
+msgstr ""
+
+#: apps/base/templates/components.scm:48
+msgid "Your location:"
+msgstr ""
+
+#: apps/base/templates/components.scm:50
+msgid "Home"
+msgstr ""
+
+#: apps/base/templates/components.scm:153
+msgid "archive"
+msgstr ""
+
+#: apps/base/templates/components.scm:337
+msgctxt "website menu"
+msgid "Guix"
+msgstr ""
+
+#: apps/base/templates/components.scm:341
+msgid "website menu:"
+msgstr ""
+
+#: apps/base/templates/components.scm:344 apps/download/templates/download.scm:42 apps/download/templates/download.scm:46 apps/download/templates/download.scm:42 apps/download/templates/download.scm:46
+msgctxt "website menu"
+msgid "Download"
+msgstr ""
+
+#: apps/base/templates/components.scm:345 apps/packages/templates/detailed-index.scm:31 apps/packages/templates/detailed-index.scm:38 apps/packages/templates/detailed-package-list.scm:34 apps/packages/templates/detailed-package-list.scm:43 apps/packages/templates/index.scm:31 apps/packages/templates/index.scm:37 apps/packages/templates/package-list.scm:34 apps/packages/templates/package-list.scm:40 apps/packages/templates/package.scm:36 apps/packages/templates/package.scm:41
+msgctxt "website menu"
+msgid "Packages"
+msgstr ""
+
+#: apps/base/templates/components.scm:346 apps/blog/templates/post-list.scm:33 apps/blog/templates/post-list.scm:39 apps/blog/templates/post.scm:29 apps/blog/templates/post.scm:35 apps/blog/templates/tag.scm:37 apps/blog/templates/tag.scm:43
+msgctxt "website menu"
+msgid "Blog"
+msgstr ""
+
+#: apps/base/templates/components.scm:347 apps/base/templates/help.scm:26 apps/base/templates/help.scm:30
+msgctxt "website menu"
+msgid "Help"
+msgstr ""
+
+#: apps/base/templates/components.scm:348 apps/base/templates/donate.scm:26 apps/base/templates/donate.scm:29
+msgctxt "website menu"
+msgid "Donate"
+msgstr ""
+
+#: apps/base/templates/components.scm:353 apps/base/templates/contact.scm:31
+msgctxt "website menu"
+msgid "Contact"
+msgstr ""
+
+#: apps/base/templates/components.scm:354 apps/base/templates/contribute.scm:30
+msgctxt "website menu"
+msgid "Contribute"
+msgstr ""
+
+#: apps/base/templates/components.scm:355 apps/base/templates/security.scm:31
+msgctxt "website menu"
+msgid "Security"
+msgstr ""
+
+#: apps/base/templates/components.scm:356 apps/base/templates/graphics.scm:27
+msgctxt "website menu"
+msgid "Graphics"
+msgstr ""
+
+#: apps/base/templates/components.scm:374
+msgid " (Page <1/> of <2/>)"
+msgstr ""
+
+#: apps/base/templates/components.scm:398
+msgid "Page <1/> of <2/>. Go to another page: "
+msgstr ""
+
+#: apps/base/templates/about.scm:17
+msgctxt "webpage title"
+msgid "About"
+msgstr ""
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/about.scm:25
+msgid "GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU Guix package manager"
+msgstr ""
+
+#: apps/base/templates/about.scm:35
+msgid "About the Project"
+msgstr ""
+
+#: apps/base/templates/about.scm:37
+msgid "The <1>GNU Guix</1> package and system manager is a <2>free software</2> project developed by volunteers around the world under the\n            umbrella of the <3>GNU Project</3>. "
+msgstr ""
+
+#: apps/base/templates/about.scm:46
+msgid "Guix System is an advanced distribution of the <1>GNU operating system</1>.  It uses the <2>Linux-libre</2> kernel, and support for <3>the Hurd</3> is being worked on.  As a GNU distribution, it is committed\n            to respecting and enhancing <4>the freedom of its users</4>.  As such, it adheres to the <5>GNU Free System Distribution Guidelines</5>."
+msgstr ""
+
+#. TRANSLATORS: Features and Defining Packages are section names
+#. in the English (en) manual.
+#: apps/base/templates/about.scm:64
+msgid "GNU Guix provides <1>state-of-the-art package management features<1.1>en</1.1><1.2>Features.html</1.2></1> such as transactional upgrades and roll-backs, reproducible\n            build environments, unprivileged package management, and\n            per-user profiles.  It uses low-level mechanisms from the <2>Nix</2> package manager, but packages are <3>defined<3.1>en</3.1><3.2>Defining-Packages.html</3.2></3> as native <4>Guile</4> modules, using extensions to the <5>Scheme</5> language—which makes it nicely hackable."
+msgstr ""
+
+#. TRANSLATORS: Using the Configuration System, Initial RAM Disk
+#. and Defining Services are section names in the English (en)
+#. manual.
+#: apps/base/templates/about.scm:85
+msgid "Guix takes that a step further by additionally supporting stateless,\n           reproducible <1>operating system configurations<1.1>en</1.1><1.2>Using-the-Configuration-System.html</1.2></1>. This time the whole system is hackable in Scheme, from the <2>initial RAM disk<2.1>en</2.1><2.2>Initial-RAM-Disk.html</2.2></2> to the <3>initialization system</3>, and to the <4>system services<4.1>en</4.1><4.2>Defining-Services.html</4.2></4>."
+msgstr ""
+
+#: apps/base/templates/about.scm:106
+msgid "Maintainer"
+msgstr ""
+
+#: apps/base/templates/about.scm:108
+msgid "Guix is currently maintained by Ludovic Courtès and Ricardo\n          Wurmus.  Please use the <1>mailing lists</1> for contact. "
+msgstr ""
+
+#: apps/base/templates/about.scm:116
+msgid "Licensing"
+msgstr ""
+
+#: apps/base/templates/about.scm:118
+msgid "Guix is free software; you can redistribute it and/or modify\n          it under the terms of the <1>GNU General Public License</1> as published by the Free Software Foundation; either\n          version 3 of the License, or (at your option) any later\n          version. "
+msgstr ""
+
+#: apps/base/data.scm:25
+msgid "IRC Channel"
+msgstr ""
+
+#: apps/base/data.scm:27
+msgid "Join the <1/> channel on the Freenode IRC network to chat\n       with the community about GNU Guix or to get help in\n       real-time."
+msgstr ""
+
+#: apps/base/data.scm:36
+msgid "Info Mailing List"
+msgstr ""
+
+#: apps/base/data.scm:38
+msgid "Subscribe to the <1/> low-traffic mailing\nlist to receive important announcements sent by the project maintainers (in\nEnglish)."
+msgstr ""
+
+#: apps/base/data.scm:47
+msgid "Help Mailing List"
+msgstr ""
+
+#: apps/base/data.scm:52
+msgid "Subscribe to the Help mailing list to get support\nfrom the GNU Guix community via email.  You can post messages in English\nthough we also accept other languages."
+msgstr ""
+
+#: apps/base/data.scm:56
+msgctxt "unique lingua code like en or zh-cn"
+msgid "en"
+msgstr ""
+
+#: apps/base/data.scm:127
+msgid "Bug Reporting"
+msgstr ""
+
+#: apps/base/data.scm:129
+msgid "If you found a bug in Guix, check whether the bug is\n       already in the <1>bug database</1>. If it is not, please <2>report it.</2>"
+msgstr ""
+
+#: apps/base/data.scm:141
+msgid "Development Mailing List"
+msgstr ""
+
+#: apps/base/data.scm:143
+msgid "Discussion about the development of GNU Guix. <1> Until July 2013</1>, the bug-Guix mailing list filled that role. "
+msgstr ""
+
+#: apps/base/data.scm:153
+msgid "Patches Mailing List"
+msgstr ""
+
+#: apps/base/data.scm:155
+msgid "Submission of patches.  Every message sent to this mailing list\n       leads to a new entry in our <1>patch tracking tool</1>.  See <2>this page</2> for more information on how to use it; see <3>the manual<3.1>en</3.1><3.2>Submitting-Patches.html</3.2></3> for more information on how to submit a patch.  <4>Until February 2017</4>, the guix-devel mailing list filled that role."
+msgstr ""
+
+#: apps/base/data.scm:174
+msgid "Commits Mailing List"
+msgstr ""
+
+#: apps/base/data.scm:176
+msgid "Notifications of commits made to the <1>Git repositories</1>."
+msgstr ""
+
+#: apps/base/data.scm:185
+msgid "Security Mailing List"
+msgstr ""
+
+#: apps/base/data.scm:187
+msgid "This is a private mailing list that anyone can post to to <1>report security issues</1> in Guix itself or in the <2>packages</2> it provides.  Posting here allows Guix developers to address\n       the problem before it is widely publicized."
+msgstr ""
+
+#: apps/base/data.scm:199
+msgid "Sysadmin Mailing List"
+msgstr ""
+
+#: apps/base/data.scm:201
+msgid "Private mailing list for the <1>build farm</1> system administration."
+msgstr ""
+
+#: apps/base/data.scm:213
+msgid "GNU System Discuss Mailing List"
+msgstr ""
+
+#: apps/base/data.scm:215
+msgid "Discussion about the development of the broader GNU system."
+msgstr ""
+
+#: apps/base/data.scm:220
+msgid "GNU/Linux-libre Mailing List"
+msgstr ""
+
+#: apps/base/data.scm:222
+msgid "Workgroup for fully free GNU/Linux distributions."
+msgstr ""
+
+#: apps/base/data.scm:227
+msgid "GNU Info Mailing List"
+msgstr ""
+
+#: apps/base/data.scm:229
+msgid "GNU software announcements."
+msgstr ""
+
+#: apps/base/data.scm:238
+msgctxt "screenshot title"
+msgid "Graphical log-in"
+msgstr ""
+
+#: apps/base/data.scm:242
+msgid "Graphical log-in screen"
+msgstr ""
+
+#: apps/base/data.scm:245
+msgctxt "screenshot title"
+msgid "GNOME"
+msgstr ""
+
+#: apps/base/data.scm:249
+msgid "Control your computer with the GNOME desktop environment"
+msgstr ""
+
+#: apps/base/data.scm:252
+msgctxt "screenshot title"
+msgid "Xfce"
+msgstr ""
+
+#: apps/base/data.scm:256
+msgid "The Xfce desktop environment with GNU Emacs and IceCat"
+msgstr ""
+
+#: apps/base/data.scm:259
+msgctxt "screenshot title"
+msgid "Virtual machine"
+msgstr ""
+
+#: apps/base/data.scm:263
+msgid "Virtual machine started with 'guix system vm'"
+msgstr ""
+
+#: apps/base/data.scm:266
+msgctxt "screenshot title"
+msgid "Enlightenment"
+msgstr ""
+
+#: apps/base/data.scm:270
+msgid "Enlightenment, Inkscape, and Serbian text"
+msgstr ""
+
+#: apps/base/templates/help.scm:17
+msgctxt "webpage title"
+msgid "Help"
+msgstr ""
+
+#: apps/base/templates/help.scm:19
+msgid "A list of resources about how to use GNU Guix, plus\n   information about getting help from the community of users and\n   developers."
+msgstr ""
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/help.scm:24
+msgid "GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU Guix package manager|Help resources"
+msgstr ""
+
+#: apps/base/templates/help.scm:35
+msgid "Help"
+msgstr ""
+
+#: apps/base/templates/help.scm:46
+msgid "GNU Guix Manual"
+msgstr ""
+
+#: apps/base/templates/help.scm:47
+msgid "Documentation for GNU Guix is available\n            online.  You may also find more information about Guix by running <1>info guix</1>."
+msgstr ""
+
+#: apps/base/templates/help.scm:53
+msgid "Read Guix manual"
+msgstr ""
+
+#: apps/base/templates/help.scm:64
+msgid "Get Guix reference card"
+msgstr ""
+
+#: apps/base/templates/help.scm:72
+msgid "GNU Manuals"
+msgstr ""
+
+#: apps/base/templates/help.scm:73
+msgid "Guix is a distribution of the <1>GNU operating system</1>.  Documentation for GNU packages is\n            available online in various formats. "
+msgstr ""
+
+#: apps/base/templates/help.scm:81
+msgid "Browse GNU manuals"
+msgstr ""
+
+#: apps/base/templates/help.scm:89
+msgid "IRC Chat"
+msgstr ""
+
+#: apps/base/templates/help.scm:90
+msgid "For real-time support from the community, you can connect\n            to the <1/> channel on irc.freenode.net. There\n            you can get help about anything related to GNU Guix."
+msgstr ""
+
+#: apps/base/templates/help.scm:95
+msgid "The <1/> channel is logged. Previous\n            conversations can be browsed online. See the <2>channel logs</2>. "
+msgstr ""
+
+#: apps/base/templates/help.scm:102
+msgid "Connect"
+msgstr ""
+
+#: apps/base/templates/help.scm:110
+msgid "Mailing lists"
+msgstr ""
+
+#: apps/base/templates/help.scm:111
+msgid "Email support from the community is also available through\n            several mailing list. The messages sent to the lists are\n            public and archived online."
+msgstr ""
+
+#: apps/base/templates/help.scm:119
+msgid "See all lists"
+msgstr ""
+
+#: apps/base/templates/contact.scm:17 apps/base/templates/irc.scm:18 apps/base/templates/irc.scm:29
+msgctxt "webpage title"
+msgid "Contact"
+msgstr ""
+
+#: apps/base/templates/contact.scm:19
+msgid "A list of channels to communicate with GNU Guix users\n   and developers about anything you want."
+msgstr ""
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/contact.scm:23
+msgid "GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU Guix package manager|Community|Mailing lists|IRC channels|Bug reports|Help"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:17
+msgctxt "webpage title"
+msgid "Contribute"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:19
+msgid "Check all the ways you can contribute to make GNU Guix\n   better, and join the world-wide community of volunteers."
+msgstr ""
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/contribute.scm:23
+msgid "GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU Guix package manager|Volunteer|Development|Translation|I18N|L10N|Artwork"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:35 apps/base/templates/contribute.scm:110 apps/base/templates/contribute.scm:227
+msgid "Contribute"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:37
+msgid "GNU Guix is a large project developed\n           mostly by volunteers from all around the world. You are welcome\n           to join us in the <1>development mailing list</1> or in the <2>#guix channel</2> in IRC Freenode. Tell us how would you like to help, and we\n          will do our best to guide you. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:51
+msgid "We want to provide a warm, friendly, and harassment-free environment,\n           so that anyone can contribute to the best of their abilities.  To\n           this end our project uses a “Contributor Covenant”, which was adapted\n           from <1>https://contributor-covenant.org/</1>.  You can find the full pledge in the <2>CODE-OF-CONDUCT</2> file."
+msgstr ""
+
+#: apps/base/templates/contribute.scm:72
+msgid "Project Management"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:73
+msgid "We use <1>Savannah</1> as the central point for development, maintenance and\n            distribution of the Guix System Distribution and GNU Guix."
+msgstr ""
+
+#: apps/base/templates/contribute.scm:79
+msgid "The source files for all the components of the project,\n            including software, web site, documentation, and artwork, are\n            available in <1>Git repositories</1> at Savannah. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:89
+msgid "Access Savannah"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:94
+msgid "Art"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:95
+msgid "We are always looking for artists to help us design and\n            improve user interfaces, and create multimedia material for\n            documentation, presentations, and promotional items. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:100
+msgid "The artwork used in the different components of the project\n            is available in the <1>guix-artwork</1> repository. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:116
+msgid "Documentation"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:117
+msgid "You can read the <1>project documentation</1> already available in the system and in the website, and\n            help us identify any errors or omissions. Creating new\n            manuals, tutorials, and blog entries will also help users and\n            developers discover what we do. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:125
+msgid "Helping improve the documentation of the <1>packaged software</1> is another way to contribute. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:132
+msgid "Start writing"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:138 apps/packages/templates/detailed-index.scm:43 apps/packages/templates/index.scm:42
+msgid "Packages"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:139
+msgid "Hundreds of software, documentation, and assets need to be\n            packaged to make it easier for users to install their\n            favorite tools with the Guix package manager, and be\n            productive using the system. "
+msgstr ""
+
+#. TRANSLATORS: Packaging Guidelines is a section name in the
+#. English (en) manual.
+#: apps/base/templates/contribute.scm:147
+msgid "Information on how to add packages to the distribution can\n            be found <1>in the manual<1.1>en</1.1><1.2>Packaging-Guidelines.html</1.2></1>. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:157
+msgid "Check out the <1>package database</1> for a list of available packages, and the <2>patch-tracking database</2> for a list of pending submissions."
+msgstr ""
+
+#: apps/base/templates/contribute.scm:168
+msgid "Send a new package"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:174
+msgid "Programming"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:175
+msgid "Source code is in the <1>main Git repository</1>.  We use <2>GNU Guile</2> as the main programming and extension language for the\n            components of the system. "
+msgstr ""
+
+#. TRANSLATORS: Contributing is a section name in the English
+#. (en) manual.
+#: apps/base/templates/contribute.scm:187
+msgid "You will find it useful to browse the <1>Guile manual</1> or other <2>introductory material about Scheme</2>. Also, make sure to read the <3>Contributing<3.1>en</3.1><3.2>Contributing.html</3.2></3> section of the manual for more details on the development\n            setup, as well as the coding and cooperation conventions used\n            in the project. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:205
+msgid "Send a patch"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:211
+msgid "System Administration"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:212
+msgid "Our system infrastructure makes it possible for all the\n            contributors to communicate and collaborate in the project,\n            and users to be able to download and install packages. Help\n            us keep the system up and running smoothly. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:218
+msgid "You can also <1>donate hardware or hosting</1> for our <2>build farm</2>.  "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:233
+msgid "Test and Bug Reports"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:234
+msgid "Install the software and send feedback to the community\n            about your experience. Help the project by reporting bugs."
+msgstr ""
+
+#: apps/base/templates/contribute.scm:238
+msgid "Before reporting a bug, please check whether the bug is\n            already <1>in the bug database</1>. See <2>the developer information page</2> for more information on how to manipulate bug reports. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:250
+msgid "Report a bug"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:256
+msgid "Translation"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:257
+msgid "You can help translate the <1>software</1>, the <2>package descriptions</2>, and the <3>manual</3> into your language.  See the <4>Translation Project</4> for information on how you can help."
+msgstr ""
+
+#: apps/base/templates/contribute.scm:276
+msgid "<1>Software packages</1> provided by the system may have their own translation\n            tools.  Visit their websites and help translate. "
+msgstr ""
+
+#: apps/base/templates/contribute.scm:283
+msgid "Start translating"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:287
+msgid "Other resources for contributors"
+msgstr ""
+
+#: apps/base/templates/contribute.scm:288
+msgid "Documents, supporting material of previous talks, and\n          auxiliary information useful to hackers and maintainers is\n          available at <1/>."
+msgstr ""
+
+#: apps/base/templates/donate.scm:17
+msgctxt "webpage title"
+msgid "Donate"
+msgstr ""
+
+#: apps/base/templates/donate.scm:19
+msgid "We are looking for donations of hardware and optionally\n   hosting for machines (they should be usable with exclusively\n   free software)."
+msgstr ""
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/donate.scm:24
+msgid "GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU Guix package manager|Donations"
+msgstr ""
+
+#: apps/base/templates/donate.scm:34
+msgid "Donate"
+msgstr ""
+
+#: apps/base/templates/donate.scm:36
+msgid "The <1>build farm</1> of the Guix System Distribution runs on donated hardware and hosting. As the distribution grows (see the <2>package list</2>), so do the computing and storage needs."
+msgstr ""
+
+#: apps/base/templates/donate.scm:47
+msgid "We have <1>started a fundraising campaign</1> to strengthen our build farm, with <2>support from the Free Software Foundation (FSF)</2>.  Please consider helping out by making a donation on this\n          FSF-hosted page:"
+msgstr ""
+
+#: apps/base/templates/donate.scm:63
+msgctxt "button"
+msgid "♥ DONATE!"
+msgstr ""
+
+#: apps/base/templates/donate.scm:66
+msgid "Hardware and Hosting"
+msgstr ""
+
+#: apps/base/templates/donate.scm:71
+msgid "We are also looking for donations of hardware and optionally\n           hosting for the following kinds of machines (they should be\n           usable with exclusively free software): "
+msgstr ""
+
+#: apps/base/templates/donate.scm:78
+msgid "x86_64 machines, with on the order of 1 TiB of storage\n               and 4 GiB of RAM;"
+msgstr ""
+
+#: apps/base/templates/donate.scm:81
+msgid "armv7 machines (such as the Novena) to more quickly test\n               and provide binaries for the armhf-linux port;"
+msgstr ""
+
+#: apps/base/templates/donate.scm:84
+msgid "mips64el machines to strengthen this port."
+msgstr ""
+
+#: apps/base/templates/donate.scm:87
+msgid "Please get in touch with us through the <1>usual channels</1> or using the <2/> private alias to\n           discuss any opportunities. "
+msgstr ""
+
+#: apps/base/templates/donate.scm:95
+msgid "Thanks to the donors!"
+msgstr ""
+
+#: apps/base/templates/donate.scm:100
+msgid "The table below summarizes hardware and hosting donations that\n           make the <1>build farm</1> for the Guix System Distribution a reality."
+msgstr ""
+
+#: apps/base/templates/donate.scm:110
+msgid "<1>machine</1><2>system</2><3>donors</3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:114
+msgid "<1>hydra.gnu.org</1><2>build farm front-end</2><3>Free Software Foundation</3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:124
+msgid "<1>berlin.guixsd.org</1><2>build farm with 25 build nodes for x86_64-linux and\ni686-linux, and dedicated storage</2><3><3.1>Max Delbrück Center for Molecular Medicine</3.1> (hardware and hosting)</3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:136
+msgid "<1>overdrive1.guixsd.org</1><2>aarch64-linux</2><3><3.1>ARM Holdings</3.1></3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:146
+msgid "<1>bayfront.guixsd.org</1><2>new build farm front-end (WIP)</2><3>Igalia</3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:158
+msgid "<1>hydra.gnunet.org</1><2>x86_64-linux, i686-linux</2><3><3.1>Free Secure Network Systems Group</3.1> at the <3.2>Technische Universität München</3.2></3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:171
+msgid "<1>chapters.gnu.org</1><2>x86_64-linux, i686-linux</2><3><3.1><3.1.1>GNU España</3.1.1> (hardware)</3.1><3.2><3.2.1>FSF France</3.2.1> (hosting)</3.2></3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:186
+msgid "<1>librenote</1><2>mips64el-linux</2><3><3.1>Daniel Clark (hardware)</3.1><3.2>Mark H Weaver (hosting)</3.2></3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:195
+msgid "<1>hydra-slave0</1><2>mips64el-linux</2><3>Free Software Foundation</3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:205
+msgid "<1>guix.sjd.se</1><2>x86_64-linux, i686-linux</2><3>Simon Josefsson</3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:215
+msgid "<1>x15.sjd.se</1><2>armhf-linux</2><3>Simon Josefsson</3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:225
+msgid "<1>hydra-slave1</1><2>armhf-linux</2><3><3.1>Steve Sprang (hardware)</3.1><3.2>Mark H Weaver (hosting)</3.2></3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:235
+msgid "<1>hydra-slave2</1><2>armhf-linux</2><3><3.1><3.1.1>Harmon Instruments</3.1.1> (hardware)</3.1><3.2>Mark H Weaver (hosting)</3.2></3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:248
+msgid "<1>hydra-slave3</1><2>armhf-linux</2><3><3.1><3.1.1>Kosagi (Sutajio Ko-Usagi Pte Ltd)</3.1.1> (hardware)</3.1><3.2>Mark H Weaver (hosting)</3.2></3>"
+msgstr ""
+
+#: apps/base/templates/donate.scm:261
+msgid "<1>redhill</1><2>armhf-linux</2><3><3.1><3.1.1>Kosagi (Sutajio Ko-Usagi Pte Ltd)</3.1.1> (hardware)</3.1><3.2>Andreas Enge (hosting)</3.2></3>"
+msgstr ""
+
+#: apps/base/templates/graphics.scm:16
+msgctxt "webpage title"
+msgid "Graphics"
+msgstr ""
+
+#: apps/base/templates/graphics.scm:18
+msgid "Information about images used for the graphical identity\n   of GNU Guix and Guix System (formerly “GuixSD”)."
+msgstr ""
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/graphics.scm:22
+msgid "GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU Guix package manager|Donations|Branding|Logo"
+msgstr ""
+
+#: apps/base/templates/graphics.scm:32
+msgid "Graphics"
+msgstr ""
+
+#: apps/base/templates/graphics.scm:34
+msgid "For questions regarding the graphics listed in this page,\n          please contact <1>help-guix@HIDDEN</1>."
+msgstr ""
+
+#: apps/base/templates/graphics.scm:44
+msgid "GNU Guix logotype"
+msgstr ""
+
+#: apps/base/templates/graphics.scm:45
+msgid "The standalone Guix, formerly known as the “Guix System\n          Distribution” or GuixSD, had its own logo, which is now\n          deprecated."
+msgstr ""
+
+#: apps/base/templates/graphics.scm:51
+msgid "The GNU Guix and GuixSD\n          logotypes were designed by Luis Felipe López Acevedo\n          (a.k.a. sirgazil).  They are available under the following\n          terms:"
+msgstr ""
+
+#: apps/base/templates/graphics.scm:65
+msgid "The source files (SVG) for these logotypes, their variants, and\n          other artwork used in the different components of the GNU Guix\n          project are available in the <1>guix-artwork</1> repository, including the previous GNU Guix logotype designed\n          by Nikita Karetnikov in 2013 and <2>superseded</2> by the golden GNU in 2016."
+msgstr ""
+
+#: apps/base/templates/irc.scm:17 apps/base/templates/irc.scm:30
+msgctxt "webpage title"
+msgid "IRC"
+msgstr ""
+
+#: apps/base/templates/irc.scm:20
+msgid "Internet relay chat."
+msgstr ""
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/irc.scm:23
+msgid "GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU Guix package manager|IRC|chat"
+msgstr ""
+
+#: apps/base/templates/irc.scm:35
+msgid "IRC"
+msgstr ""
+
+#: apps/base/templates/irc.scm:37
+msgid "Join the <1/> channel on the <2>Freenode IRC network</2> to chat with the GNU Guix community or to get help\n          in real-time. You can use the chat widget below, or just use\n          the <3>IRC client</3> of your preference. Note that the conversations that happen\n          on the <4/> channel are logged (<5>browse the log</5>)."
+msgstr ""
+
+#: apps/base/templates/menu.scm:16
+msgctxt "webpage title"
+msgid "Menu"
+msgstr ""
+
+#: apps/base/templates/menu.scm:17
+msgid "Website menu."
+msgstr ""
+
+#: apps/base/templates/menu.scm:24
+msgctxt "website menu"
+msgid "Menu"
+msgstr ""
+
+#: apps/base/templates/screenshot.scm:19
+msgctxt "webpage title"
+msgid "Screenshots"
+msgstr ""
+
+#: apps/base/templates/security.scm:19
+msgctxt "webpage title"
+msgid "Security"
+msgstr ""
+
+#: apps/base/templates/security.scm:21
+msgid "Important information about getting security updates\n   for your GNU Guix installation, and instructions on how\n   to report security issues."
+msgstr ""
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/security.scm:26
+msgid "GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU Guix package manager|Security updates"
+msgstr ""
+
+#: apps/base/templates/security.scm:36
+msgid "Security"
+msgstr ""
+
+#: apps/base/templates/security.scm:38
+msgid "How to report security issues"
+msgstr ""
+
+#: apps/base/templates/security.scm:39
+msgid "To report sensitive security issues in Guix itself or the\n           packages it provides, you can write to the private mailing list <1/>.  This list is monitored by a\n           small team of Guix developers."
+msgstr ""
+
+#: apps/base/templates/security.scm:46
+msgid "If you prefer to send your report using OpenPGP encrypted email,\n           please send it to one of the following Guix developers using their\n           respective OpenPGP key:"
+msgstr ""
+
+#: apps/base/templates/security.scm:65
+msgid "Release signatures"
+msgstr ""
+
+#: apps/base/templates/security.scm:66
+msgid "Releases of Guix are signed using the OpenPGP key with the fingerprint <1/>.  Users should <2>verify<2.1>en</2.1><2.2>Binary-Installation.html</2.2></2> their downloads before extracting or running them."
+msgstr ""
+
+#: apps/base/templates/security.scm:78
+msgid "Security updates"
+msgstr ""
+
+#: apps/base/templates/security.scm:79
+msgid "When security vulnerabilities are found in Guix or the packages provided by Guix, we will provide <1>security updates<1.1>en</1.1><1.2>Security-Updates.html</1.2></1> quickly and with minimal disruption for users."
+msgstr ""
+
+#: apps/base/templates/security.scm:87
+msgid "Guix uses a “rolling release” model.  All security bug-fixes are pushed directly to the master branch.  There is no “stable” branch that only receives security fixes."
+msgstr ""
+
+#: apps/download/data.scm:20 apps/download/data.scm:20
+msgctxt "download page title"
+msgid "GNU Guix System <1/>"
+msgstr ""
+
+#: apps/download/data.scm:23 apps/download/data.scm:23
+msgid "USB/DVD ISO installer of the standalone Guix System."
+msgstr ""
+
+#. TRANSLATORS: System installation is a section name in the
+#. English (en) manual.
+#. TRANSLATORS: System installation is a section name in the
+#. English (en) manual.
+#: apps/download/data.scm:31 apps/download/data.scm:31
+msgid "<1>en</1>System-Installation.html"
+msgstr ""
+
+#: apps/download/data.scm:35 apps/download/data.scm:35
+msgctxt "download page title"
+msgid "GNU Guix <1/> QEMU Image"
+msgstr ""
+
+#: apps/download/data.scm:38 apps/download/data.scm:38
+msgid "QCOW2 virtual machine (VM) image."
+msgstr ""
+
+#. TRANSLATORS: Running Guix in a VM is a section name in the
+#. English (en) manual.
+#. TRANSLATORS: Running Guix in a VM is a section name in the
+#. English (en) manual.
+#: apps/download/data.scm:45 apps/download/data.scm:45
+msgid "<1>en</1>Running-Guix-in-a-VM.html"
+msgstr ""
+
+#: apps/download/data.scm:49 apps/download/data.scm:49
+msgctxt "download page title"
+msgid "GNU Guix <1/> Binary"
+msgstr ""
+
+#: apps/download/data.scm:51 apps/download/data.scm:51
+msgid "Self-contained tarball providing binaries for Guix and its\n       dependencies, to be installed on top of your Linux-based system."
+msgstr ""
+
+#. TRANSLATORS: Binary Installation is a section name in the
+#. English (en) manual.
+#. TRANSLATORS: Binary Installation is a section name in the
+#. English (en) manual.
+#: apps/download/data.scm:64 apps/download/data.scm:64
+msgid "<1>en</1>Binary-Installation.html"
+msgstr ""
+
+#: apps/download/data.scm:68 apps/download/data.scm:68
+msgctxt "download page title"
+msgid "GNU Guix <1/> Source"
+msgstr ""
+
+#: apps/download/data.scm:69 apps/download/data.scm:69
+msgid "Source code distribution."
+msgstr ""
+
+#. TRANSLATORS: Requirements is a section name in the English (en)
+#. manual.
+#. TRANSLATORS: Requirements is a section name in the English (en)
+#. manual.
+#: apps/download/data.scm:76 apps/download/data.scm:76
+msgid "<1>en</1>Requirements.html"
+msgstr ""
+
+#: apps/download/templates/components.scm:25 apps/download/templates/components.scm:25
+msgid "Download options:"
+msgstr ""
+
+#: apps/download/templates/components.scm:38 apps/download/templates/components.scm:38
+msgid "Signatures: "
+msgstr ""
+
+#: apps/download/templates/components.scm:50 apps/download/templates/components.scm:50
+msgid "<1>Installation instructions</1>."
+msgstr ""
+
+#: apps/download/templates/download.scm:33 apps/download/templates/download.scm:33
+msgctxt "webpage title"
+msgid "Download"
+msgstr ""
+
+#: apps/download/templates/download.scm:35 apps/download/templates/download.scm:35
+msgid "Installers and source files for GNU Guix.  GNU Guix can be\n   installed on different GNU/Linux distributions."
+msgstr ""
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/download/templates/download.scm:39 apps/download/templates/download.scm:39
+msgid "GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU Guix package manager|Installer|Source code|Package manager"
+msgstr ""
+
+#: apps/download/templates/download.scm:51 apps/download/templates/download.scm:51
+msgid "Download"
+msgstr ""
+
+#: apps/download/templates/download.scm:53 apps/download/templates/download.scm:53
+msgid "As of version <1/>, the standalone Guix System <2>can be installed</2> on an i686, x86_64, ARMv7, or AArch64 machine.  It uses the <3>Linux-Libre</3> kernel and the <4>GNU Shepherd</4> init system. Alternately, GNU Guix\n          can be installed as an additional package manager on top of an\n          installed Linux-based system."
+msgstr ""
+
+#: apps/download/templates/download.scm:73 apps/download/templates/download.scm:73
+msgid "Source code and binaries for the Guix System distribution ISO\n          image as well as GNU Guix can be found on the GNU servers at <1/>.  Older releases can still be found on <2/>."
+msgstr ""
+
+#: apps/blog/templates/components.scm:33 apps/blog/templates/post.scm:46
+msgctxt "SRFI-19 date->string format"
+msgid "~B ~e, ~Y"
+msgstr ""
+
+#: apps/blog/templates/components.scm:37
+msgctxt "blog post summary ellipsis"
+msgid "…"
+msgstr ""
+
+#: apps/blog/templates/components.scm:48
+msgid "Blog menu: "
+msgstr ""
+
+#: apps/blog/templates/components.scm:53
+msgid "Get topic updates"
+msgstr ""
+
+#: apps/blog/templates/components.scm:54
+msgid "Get blog updates"
+msgstr ""
+
+#: apps/blog/templates/components.scm:66
+msgctxt "button"
+msgid "Atom feed"
+msgstr ""
+
+#: apps/blog/templates/components.scm:68
+msgid "Posts by topic"
+msgstr ""
+
+#: apps/blog/templates/feed.scm:32
+msgctxt "feed author name"
+msgid "GNU Guix"
+msgstr ""
+
+#: apps/blog/templates/post-list.scm:23 apps/blog/templates/post-list.scm:40 apps/blog/templates/tag.scm:25 apps/blog/templates/tag.scm:45 apps/packages/templates/detailed-package-list.scm:24 apps/packages/templates/detailed-package-list.scm:47 apps/packages/templates/package-list.scm:24 apps/packages/templates/package-list.scm:44
+msgid "Page <1/>"
+msgstr ""
+
+#: apps/blog/templates/post-list.scm:24 apps/blog/templates/post.scm:25 apps/blog/templates/tag.scm:26
+msgctxt "webpage title"
+msgid "Blog"
+msgstr ""
+
+#: apps/blog/templates/post-list.scm:26 apps/blog/templates/post.scm:27
+msgid "Blog posts about GNU Guix."
+msgstr ""
+
+#: apps/blog/templates/post.scm:52
+msgid "Related topics:"
+msgstr ""
+
+#: apps/blog/templates/tag.scm:28
+msgid "Blog posts about <1/> on GNU Guix."
+msgstr ""
+
+#: apps/blog/templates/tag.scm:54
+msgid "Blog — "
+msgstr ""
+
+#: apps/packages/templates/components.scm:59 apps/packages/templates/package.scm:56
+msgid "This is a GNU package.  "
+msgstr ""
+
+#: apps/packages/templates/components.scm:66
+msgid "<1>License:</1> <2/>."
+msgstr ""
+
+#: apps/packages/templates/components.scm:70
+msgid "<1>Website:</1> <2/>."
+msgstr ""
+
+#: apps/packages/templates/components.scm:74
+msgid "<1>Package source:</1> <2/>."
+msgstr ""
+
+#: apps/packages/templates/components.scm:78
+msgid "<1>Patches:</1> <2/>."
+msgstr ""
+
+#: apps/packages/templates/components.scm:82
+msgid "<1>Lint issues:</1> <2/>."
+msgstr ""
+
+#: apps/packages/templates/components.scm:89
+msgid "<1>Builds:</1> <2/>."
+msgstr ""
+
+#: apps/packages/templates/components.scm:104
+msgid " issue"
+msgid_plural " issues"
+msgstr[0] ""
+msgstr[1] ""
+
+#: apps/packages/templates/components.scm:115 apps/packages/templates/components.scm:221
+msgid "Packages menu: "
+msgstr ""
+
+#: apps/packages/templates/components.scm:117 apps/packages/templates/components.scm:223
+msgid "Browse alphabetically"
+msgstr ""
+
+#: apps/packages/templates/components.scm:204 apps/packages/templates/components.scm:270
+msgid "None"
+msgstr ""
+
+#: apps/packages/templates/detailed-index.scm:22 apps/packages/templates/detailed-package-list.scm:25 apps/packages/templates/index.scm:22 apps/packages/templates/package-list.scm:25 apps/packages/templates/package.scm:28
+msgctxt "webpage title"
+msgid "Packages"
+msgstr ""
+
+#: apps/packages/templates/detailed-index.scm:24 apps/packages/templates/detailed-package-list.scm:27 apps/packages/templates/index.scm:24
+msgid "List of packages available through GNU Guix."
+msgstr ""
+
+#: apps/packages/templates/detailed-index.scm:45 apps/packages/templates/index.scm:44
+msgid "GNU Guix provides <1/> packages transparently <2>available as pre-built binaries</2>. These pages provide a complete list of the packages.  Our <3>continuous integration system</3> shows their current build status (updated <4/>)."
+msgstr ""
+
+#: apps/packages/templates/detailed-package-list.scm:56 apps/packages/templates/package-list.scm:53
+msgid "Packages — "
+msgstr ""
+
+#: apps/packages/templates/package.scm:62
+msgid "<1>Website: </1>"
+msgstr ""
+
+#: apps/packages/templates/package.scm:65
+msgid "<1>License: </1>"
+msgstr ""
+
+#: apps/packages/templates/package.scm:67
+msgid "<1>Package source: </1>"
+msgstr ""
+
+#: apps/packages/templates/package.scm:69
+msgid "<1>Patches: </1>"
+msgstr ""
+
+#: apps/packages/templates/package.scm:71
+msgid "<1>Builds: </1>"
+msgstr ""
+
+#: apps/packages/templates/package.scm:77
+msgid "<1>Lint issues</1><2><2.1/>. See <2.2>package definition</2.2> in Guix source code.</2>"
+msgstr ""
-- 
2.23.0


--uvu3qehc3367oshy
Content-Type: text/plain; charset=utf-8
Content-Disposition: attachment; filename="0006-website-Add-German-translation.patch"
Content-Transfer-Encoding: 8bit

From c9e923a60eb4f58c863b468133e09684e5bdc418 Mon Sep 17 00:00:00 2001
From: Florian Pelz <pelzflorian@HIDDEN>
Date: Sun, 15 Sep 2019 14:30:11 +0200
Subject: [PATCH 6/8] website: Add German translation.

* website/po/de.po: New file.
* website/po/LINGUAS: Add de_DE lingua.
* website/po/ietf-tags.scm: Add association for de_DE lingua.
* website/apps/base/data.scm (contact-media): Remove German blurb.
---
 website/apps/base/data.scm |    6 +-
 website/po/LINGUAS         |    1 +
 website/po/de.po           | 1895 ++++++++++++++++++++++++++++++++++++
 website/po/ietf-tags.scm   |    3 +-
 4 files changed, 1899 insertions(+), 6 deletions(-)
 create mode 100644 website/po/de.po

diff --git a/website/apps/base/data.scm b/website/apps/base/data.scm
index 1a4217c..ff5939e 100644
--- a/website/apps/base/data.scm
+++ b/website/apps/base/data.scm
@@ -77,11 +77,7 @@ though we also accept other languages."))
                                  (string=? (cadar to-delete) (cadr b))
                                  ;; but language code is different
                                  (not (string=? (cadddr to-delete) (car b))))))
-         `(("de"
-            "Melden Sie sich bei der „Help“-Mailingliste an, um per E-Mail
-gemeinschaftlichen Rat zu GuixSD und Guix zu bekommen.  Sie können
-Nachrichten auch auf deutsch verfassen.")
-           ("eo"
+         `(("eo"
             "Subskribu al la retmesaĝolisto \"Help\" por demandi helpon pri
 GNU Guix al la grupo.  Vi povas skribi esperantlingve.")
            ("es"
diff --git a/website/po/LINGUAS b/website/po/LINGUAS
index d4dd759..dc8e711 100644
--- a/website/po/LINGUAS
+++ b/website/po/LINGUAS
@@ -1,3 +1,4 @@
 # Translation with sexp-xgettext requires the full LL_CC locale name
 # to be specified.
+de_DE
 en_US
diff --git a/website/po/de.po b/website/po/de.po
new file mode 100644
index 0000000..0779692
--- /dev/null
+++ b/website/po/de.po
@@ -0,0 +1,1895 @@
+# 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.
+# Florian Pelz <pelzflorian@HIDDEN>, 2019.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: guix-website\n"
+"Report-Msgid-Bugs-To: ludo@HIDDEN\n"
+"POT-Creation-Date: 2019-09-15 14:15+0200\n"
+"PO-Revision-Date: 2019-09-15 14:29+0200\n"
+"Last-Translator: Florian Pelz <pelzflorian@HIDDEN>\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"
+
+#. TRANSLATORS: The locale’s display name; please include a country
+#. code like in English (US) *only* if there are multiple
+#. Translation Project teams for the same language.
+#: apps/base/utils.scm:63
+msgid "English (US)"
+msgstr "Deutsch"
+
+#: apps/base/templates/home.scm:18
+msgctxt "webpage title"
+msgid "GNU's advanced distro and transactional package manager"
+msgstr "GNUs fortgeschrittene Distribution und transaktionelle Paketverwaltung"
+
+#: apps/base/templates/home.scm:20 apps/base/templates/about.scm:19
+msgid ""
+"Guix is an advanced distribution of the GNU operating system.\n"
+"   Guix is technology that respects the freedom of computer users.\n"
+"   You are free to run the system for any purpose, study how it\n"
+"   works, improve it, and share it with the whole world."
+msgstr ""
+"Guix ist eine fortgeschrittene Distribution des GNU-Betriebssystems.\n"
+"   Guix ist eine Technologie, die die Freiheit der Benutzer von "
+"Rechengeräten respektiert.\n"
+"   Es steht Ihnen frei, das System zu jedem Zweck auszuführen, seine "
+"Funktionsweise zu studieren,\n"
+"   es zu verbessern und es mit der ganzen Welt zu teilen."
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/home.scm:26 apps/base/templates/menu.scm:20
+#: apps/base/templates/screenshot.scm:23 apps/blog/templates/post-list.scm:29
+#: apps/blog/templates/tag.scm:33 apps/packages/templates/detailed-index.scm:27
+#: apps/packages/templates/detailed-package-list.scm:30
+#: apps/packages/templates/index.scm:27
+#: apps/packages/templates/package-list.scm:30
+#: apps/packages/templates/package.scm:32
+msgid ""
+"GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU "
+"Guix package manager|GNU Guile|Guile Scheme|Transactional upgrades|"
+"Functional package management|Reproducibility"
+msgstr ""
+"GNU|Linux|Unix|Freie Software|Libre-Software|Betriebssystem|GNU Hurd|GNU-"
+"Guix-Paketverwaltung|GNU Guile|Guile Scheme|Transaktionelle Aktualisierungen|"
+"Funktionale Paketverwaltung|Reproduzierbarkeit"
+
+#: apps/base/templates/home.scm:30 apps/base/templates/components.scm:343
+#: apps/base/templates/screenshot.scm:27
+msgctxt "website menu"
+msgid "Overview"
+msgstr "Übersicht"
+
+#: apps/base/templates/home.scm:39
+msgid "Summary"
+msgstr "Zusammenfassung"
+
+#: apps/base/templates/home.scm:41
+msgid ""
+"<1>Liberating.</1> Guix is an advanced distribution of the <2>GNU operating "
+"system</2> developed by the <3>GNU Project</3>—which respects the <4>freedom "
+"of computer users</4>. "
+msgstr ""
+"<1>Befreiend.</1> Guix ist eine fortgeschrittende Distribution des <2>GNU-"
+"Betriebssystems</2>, das vom <3>GNU-Projekt</3> entwickelt wurde und die "
+"<4>Freiheit der Benutzer von Rechengeräten</4> respektiert. "
+
+#. TRANSLATORS: Package Management, Features and Using the
+#. Configuration System are section names in the English (en)
+#. manual.
+#: apps/base/templates/home.scm:62
+msgid ""
+"<1>Dependable.</1> Guix <2>supports<2.1>en</2.1><2.2>Package-Management."
+"html</2.2></2> transactional upgrades and roll-backs, unprivileged package "
+"management, <3>and more<3.1>en</3.1><3.2>Features.html</3.2></3>.  When used "
+"as a standalone distribution, Guix supports <4>declarative system "
+"configuration<4.1>en</4.1><4.2>Using-the-Configuration-System.html</4.2></4> "
+"for transparent and reproducible operating systems."
+msgstr ""
+"<1>Verlässlich.</1> Guix <2>unterstützt<2.1>de</2.1><2.2>Paketverwaltung."
+"html</2.2></2> transaktionelle Aktualisierungen und Rücksetzungen, "
+"„unprivilegierte“ Paketverwaltung für Nutzer ohne besondere Berechtigungen "
+"<3>und noch mehr<3.1>de</3.1><3.2>Funktionalitaten.html</3.2></3>. Wenn es "
+"als eigenständige Distribution verwendet wird, unterstützt Guix eine "
+"<4>deklarative Konfiguration des Systems<4.1>de</4.1><4.2>Das-"
+"Konfigurationssystem-nutzen.html</4.2></4> für transparente und "
+"reproduzierbare Betriebssysteme."
+
+#. TRANSLATORS: Defining Packages and System Configuration are
+#. section names in the English (en) manual.
+#: apps/base/templates/home.scm:82
+msgid ""
+"<1>Hackable.</1> It provides <2>Guile Scheme</2> APIs, including high-level "
+"embedded domain-specific languages (EDSLs) to <3>define "
+"packages<3.1>en</3.1><3.2>Defining-Packages.html</3.2></3> and <4>whole-"
+"system configurations<4.1>en</4.1><4.2>System-Configuration.html</4.2></4>."
+msgstr ""
+"<1>Hackbar.</1> Programmierschnittstellen (APIs) in <2>Guile Scheme</2> "
+"werden zur Verfügung gestellt, einschließlich hochsprachlicher eingebetteter "
+"domänenspezifischer Sprachen (Embedded Domain-Specific Languages, EDSLs), "
+"mit denen Sie <3>Pakete definieren<3.1>de</3.1><3.2>Pakete-definieren."
+"html</3.2></3> und <4>Konfigurationen des gesamten "
+"Systems<4.1>de</4.1><4.2>Systemkonfiguration.html</4.2></4> festlegen können."
+
+#: apps/base/templates/home.scm:104
+msgctxt "button"
+msgid "DOWNLOAD v<1/>"
+msgstr "v<1/> HERUNTERLADEN"
+
+#: apps/base/templates/home.scm:109
+msgctxt "button"
+msgid "CONTRIBUTE"
+msgstr "MITMACHEN"
+
+#: apps/base/templates/home.scm:116
+msgid "Discover Guix"
+msgstr "Entdecken Sie Guix"
+
+#: apps/base/templates/home.scm:118
+msgid ""
+"Guix comes with thousands of packages which include applications, system "
+"tools, documentation, fonts, and other digital goods readily available for "
+"installing with the <1>GNU Guix</1> package manager."
+msgstr ""
+"Mit Guix kommen Tausende von Paketen. Dazu gehören Anwendungen, "
+"Systemwerkzeuge, Dokumentation, Schriftarten sowie andere digitale Güter, "
+"die jederzeit zur Installation mit dem Paketverwaltungswerkzeug <1>GNU "
+"Guix</1> bereitstehen."
+
+#: apps/base/templates/home.scm:135
+msgctxt "button"
+msgid "ALL PACKAGES"
+msgstr "ALLE PAKETE"
+
+#: apps/base/templates/home.scm:142
+msgid "GNU Guix in your field"
+msgstr "GNU Guix in Ihrem Bereich"
+
+#: apps/base/templates/home.scm:144
+msgid ""
+"Read some stories about how people are using GNU Guix in\n"
+"their daily lives."
+msgstr ""
+"Lesen Sie ein paar Erfahrungen, wie die Leute GNU Guix in\n"
+"ihrem täglichen Leben benutzen."
+
+#: apps/base/templates/home.scm:155
+msgctxt "button"
+msgid "SOFTWARE DEVELOPMENT"
+msgstr "SOFTWARE-ENTWICKLUNG"
+
+#: apps/base/templates/home.scm:160
+msgctxt "button"
+msgid "BIOINFORMATICS"
+msgstr "BIOINFORMATIK"
+
+#: apps/base/templates/home.scm:165
+msgctxt "button"
+msgid "HIGH PERFORMANCE COMPUTING"
+msgstr "HOCHLEISTUNGSRECHNEN"
+
+#: apps/base/templates/home.scm:170
+msgctxt "button"
+msgid "RESEARCH"
+msgstr "FORSCHUNG"
+
+#: apps/base/templates/home.scm:175
+msgctxt "button"
+msgid "ALL FIELDS..."
+msgstr "ALLE BEREICHE …"
+
+#: apps/base/templates/home.scm:182
+msgid "GNU Guix in other GNU/Linux distros"
+msgstr "GNU Guix auf anderen GNU/Linux-Distributionen"
+
+#: apps/base/templates/home.scm:194
+msgid ""
+"Video: <1>Demo of Guix in another GNU/Linux distribution<1.1/>https://audio-"
+"video.gnu.org/video/misc/2016-07__GNU_Guix_Demo_2.webm</1> (1 minute, 30 "
+"seconds)."
+msgstr ""
+"Video: <1>Vorführung von Guix auf einer anderen GNU/Linux-Distribution<1.1/"
+">https://audio-video.gnu.org/video/misc/2016-07__GNU_Guix_Demo_2.webm</1> (1 "
+"Minute, 30 Sekunden)."
+
+#: apps/base/templates/home.scm:205
+msgid ""
+"If you don't use GNU Guix as a standalone GNU/Linux distribution, you still "
+"can use it as a package manager on top of any GNU/Linux distribution. This "
+"way, you can benefit from all its conveniences."
+msgstr ""
+"Wenn Sie GNU Guix nicht als eine eigenständige GNU/Linux-Distribution "
+"verwenden, können Sie es trotzdem zur Paketverwaltung benutzen, aufgesetzt "
+"auf eine beliebige bestehende GNU/Linux-Distribution. Auf diese Weise können "
+"Sie all seine Vorteile genießen."
+
+#: apps/base/templates/home.scm:210
+msgid ""
+"Guix won't interfere with the package manager that comes with your "
+"distribution. They can live together."
+msgstr ""
+"Guix und das Paketverwaltungswerkzeug, das mit Ihrer Distribution "
+"ausgeliefert wird, werden sich gegenseitig nicht stören. Sie können "
+"friedlich koexistieren."
+
+#: apps/base/templates/home.scm:217
+msgctxt "button"
+msgid "TRY IT OUT!"
+msgstr "PROBIEREN SIE ES AUS!"
+
+#: apps/base/templates/home.scm:224 apps/blog/templates/post-list.scm:49
+msgid "Blog"
+msgstr "Blog"
+
+#: apps/base/templates/home.scm:231
+msgctxt "button"
+msgid "ALL POSTS"
+msgstr "ALLE EINTRÄGE"
+
+#: apps/base/templates/home.scm:237 apps/base/templates/contact.scm:36
+msgid "Contact"
+msgstr "Kontakt"
+
+#: apps/base/templates/home.scm:244
+msgctxt "button"
+msgid "ALL CONTACT MEDIA"
+msgstr "ALLE KONTAKTMÖGLICHKEITEN"
+
+#: apps/base/templates/theme.scm:17 apps/base/templates/components.scm:350
+#: apps/base/templates/about.scm:27 apps/base/templates/about.scm:30
+#: apps/base/templates/contact.scm:26 apps/base/templates/contribute.scm:26
+#: apps/base/templates/graphics.scm:24 apps/base/templates/security.scm:28
+msgctxt "website menu"
+msgid "About"
+msgstr "Über Guix"
+
+#: apps/base/templates/theme.scm:74 apps/base/templates/theme.scm:76
+msgctxt "webpage title"
+msgid "GNU Guix"
+msgstr "GNU Guix"
+
+#: apps/base/templates/theme.scm:98
+msgctxt "webpage title"
+msgid "GNU Guix — Activity Feed"
+msgstr "GNU Guix — Aktivitäten-Feed"
+
+#: apps/base/templates/theme.scm:115
+msgid ""
+"Made with <1>♥</1> by humans and powered by <2>GNU Guile</2>.  <3>Source "
+"code</3> under the <4>GNU AGPL</4>."
+msgstr ""
+"Mit <1>♥</1> von Menschen gemacht und durch <2>GNU Guile</2> ermöglicht. "
+"<3>Quellcode</3> unter der <4>GNU AGPL</4>."
+
+#: apps/base/templates/components.scm:48
+msgid "Your location:"
+msgstr "Sie befinden sich hier:"
+
+#: apps/base/templates/components.scm:50
+msgid "Home"
+msgstr "Hauptseite"
+
+#: apps/base/templates/components.scm:153
+msgid "archive"
+msgstr "Archiv"
+
+#: apps/base/templates/components.scm:337
+msgctxt "website menu"
+msgid "Guix"
+msgstr "Guix"
+
+#: apps/base/templates/components.scm:341
+msgid "website menu:"
+msgstr "Menü des Webauftritts:"
+
+#: apps/base/templates/components.scm:344
+#: apps/download/templates/download.scm:42
+#: apps/download/templates/download.scm:46
+msgctxt "website menu"
+msgid "Download"
+msgstr "Herunterladen"
+
+#: apps/base/templates/components.scm:345
+#: apps/packages/templates/detailed-index.scm:31
+#: apps/packages/templates/detailed-index.scm:38
+#: apps/packages/templates/detailed-package-list.scm:34
+#: apps/packages/templates/detailed-package-list.scm:43
+#: apps/packages/templates/index.scm:31 apps/packages/templates/index.scm:37
+#: apps/packages/templates/package-list.scm:34
+#: apps/packages/templates/package-list.scm:40
+#: apps/packages/templates/package.scm:36
+#: apps/packages/templates/package.scm:41
+msgctxt "website menu"
+msgid "Packages"
+msgstr "Pakete"
+
+#: apps/base/templates/components.scm:346 apps/blog/templates/post-list.scm:33
+#: apps/blog/templates/post-list.scm:39 apps/blog/templates/post.scm:29
+#: apps/blog/templates/post.scm:35 apps/blog/templates/tag.scm:37
+#: apps/blog/templates/tag.scm:43
+msgctxt "website menu"
+msgid "Blog"
+msgstr "Blog"
+
+#: apps/base/templates/components.scm:347 apps/base/templates/help.scm:26
+#: apps/base/templates/help.scm:30
+msgctxt "website menu"
+msgid "Help"
+msgstr "Hilfe"
+
+#: apps/base/templates/components.scm:348 apps/base/templates/donate.scm:26
+#: apps/base/templates/donate.scm:29
+msgctxt "website menu"
+msgid "Donate"
+msgstr "Spenden"
+
+#: apps/base/templates/components.scm:353 apps/base/templates/contact.scm:31
+msgctxt "website menu"
+msgid "Contact"
+msgstr "Kontakt"
+
+#: apps/base/templates/components.scm:354 apps/base/templates/contribute.scm:30
+msgctxt "website menu"
+msgid "Contribute"
+msgstr "Mitmachen"
+
+#: apps/base/templates/components.scm:355 apps/base/templates/security.scm:31
+msgctxt "website menu"
+msgid "Security"
+msgstr "Sicherheit"
+
+#: apps/base/templates/components.scm:356 apps/base/templates/graphics.scm:27
+msgctxt "website menu"
+msgid "Graphics"
+msgstr "Grafiken"
+
+#: apps/base/templates/components.scm:374
+msgid " (Page <1/> of <2/>)"
+msgstr " (Seite <1/> von <2/>)"
+
+#: apps/base/templates/components.scm:398
+msgid "Page <1/> of <2/>. Go to another page: "
+msgstr "Seite <1/> von <2/>. Besuchen Sie eine andere Seite: "
+
+#: apps/base/templates/about.scm:17
+msgctxt "webpage title"
+msgid "About"
+msgstr "Über Guix"
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/about.scm:25
+msgid ""
+"GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU "
+"Guix package manager"
+msgstr ""
+"GNU|Linux|Unix|Freie Software|Libre-Software|Betriebssystem|GNU Hurd|GNU-"
+"Guix-Paketverwaltung"
+
+#: apps/base/templates/about.scm:35
+msgid "About the Project"
+msgstr "Über das Projekt"
+
+#: apps/base/templates/about.scm:37
+msgid ""
+"The <1>GNU Guix</1> package and system manager is a <2>free software</2> "
+"project developed by volunteers around the world under the\n"
+"            umbrella of the <3>GNU Project</3>. "
+msgstr ""
+"<1>GNU Guix</1>, ein Programm zur Verwaltung von Paketen und Systemen, ist "
+"ein <2>Freie-Software-Projekt</2>, das von Freiwilligen aus der ganzen Welt "
+"im Rahmen des <3>GNU-Projekts</3> entwickelt wird. "
+
+#: apps/base/templates/about.scm:46
+msgid ""
+"Guix System is an advanced distribution of the <1>GNU operating system</1>.  "
+"It uses the <2>Linux-libre</2> kernel, and support for <3>the Hurd</3> is "
+"being worked on.  As a GNU distribution, it is committed\n"
+"            to respecting and enhancing <4>the freedom of its users</4>.  As "
+"such, it adheres to the <5>GNU Free System Distribution Guidelines</5>."
+msgstr ""
+"„Guix System“ ist eine fortgeschrittene Distribution des <1>GNU-"
+"Betriebssystems</1>. Es verwendet <2>Linux-libre</2> als seinen Kernel; an "
+"Unterstützung für <3>GNU Hurd</3> wird gearbeitet. Als GNU-Distribution "
+"gehört es zu seiner Zielsetzung, <4>die Freiheit seiner Nutzer</4> zu "
+"respektieren und zu vermehren. Daher folgt es den <5>Richtlinien für Freie "
+"Systemdistributionen</5>."
+
+#. TRANSLATORS: Features and Defining Packages are section names
+#. in the English (en) manual.
+#: apps/base/templates/about.scm:64
+msgid ""
+"GNU Guix provides <1>state-of-the-art package management "
+"features<1.1>en</1.1><1.2>Features.html</1.2></1> such as transactional "
+"upgrades and roll-backs, reproducible\n"
+"            build environments, unprivileged package management, and\n"
+"            per-user profiles.  It uses low-level mechanisms from the "
+"<2>Nix</2> package manager, but packages are "
+"<3>defined<3.1>en</3.1><3.2>Defining-Packages.html</3.2></3> as native "
+"<4>Guile</4> modules, using extensions to the <5>Scheme</5> language—which "
+"makes it nicely hackable."
+msgstr ""
+"GNU Guix bietet <1>Paketverwaltungsfunktionalitäten auf dem Stand der "
+"Technik<1.1>de</1.1><1.2>Funktionalitaten.html</1.2></1>, wie etwa "
+"transaktionelle Aktualisierungen und Rücksetzungen, reproduzierbare "
+"Erstellungsumgebungen, eine „unprivilegierte“ Paketverwaltung für Nutzer "
+"ohne besondere Berechtigungen sowie ein eigenes Paketprofil für jeden "
+"Nutzer. Dazu verwendet es dieselben Mechanismen, die dem "
+"Paketverwaltungsprogramm <2>Nix</2> zu Grunde liegen, jedoch werden Pakete "
+"als reine <4>Guile</4>-Module <3>definiert<3.1>de</3.1><3.2>Pakete-"
+"definieren.html</3.2></3>. Dazu erweitert Guix die <5>Scheme</5>-"
+"Programmiersprache, wodurch es leicht ist, selbst an diesen zu hacken."
+
+#. TRANSLATORS: Using the Configuration System, Initial RAM Disk
+#. and Defining Services are section names in the English (en)
+#. manual.
+#: apps/base/templates/about.scm:85
+msgid ""
+"Guix takes that a step further by additionally supporting stateless,\n"
+"           reproducible <1>operating system "
+"configurations<1.1>en</1.1><1.2>Using-the-Configuration-System."
+"html</1.2></1>. This time the whole system is hackable in Scheme, from the "
+"<2>initial RAM disk<2.1>en</2.1><2.2>Initial-RAM-Disk.html</2.2></2> to the "
+"<3>initialization system</3>, and to the <4>system "
+"services<4.1>en</4.1><4.2>Defining-Services.html</4.2></4>."
+msgstr ""
+"Guix geht dabei noch einen Schritt weiter, indem es zusätzlich noch "
+"zustandslose, reproduzierbare "
+"<1>Betriebssystemkonfigurationen<1.1>de</1.1><1.2>Das-Konfigurationssystem-"
+"nutzen.html</1.2></1> unterstützt. In diesem Fall kann am ganzen System in "
+"Scheme gehackt werden, von der <2>initialen RAM-"
+"Disk<2.1>de</2.1><2.2>Initiale-RAM_002dDisk.html</2.2></2> bis hin zum "
+"<3>Initialisierungssystem</3> und den "
+"<4>Systemdiensten<4.1>de</4.1><4.2>Dienste-definieren.html</4.2></4>."
+
+#: apps/base/templates/about.scm:106
+msgid "Maintainer"
+msgstr "Betreuer"
+
+#: apps/base/templates/about.scm:108
+msgid ""
+"Guix is currently maintained by Ludovic Courtès and Ricardo\n"
+"          Wurmus.  Please use the <1>mailing lists</1> for contact. "
+msgstr ""
+"Die Betreuer („Maintainer“) von Guix sind zur Zeit Ludovic Courtès und "
+"Ricardo Wurmus. Benutzen Sie bitte die <1>Mailing-Listen</1>, um Kontakt "
+"aufzunehmen."
+
+#: apps/base/templates/about.scm:116
+msgid "Licensing"
+msgstr "Lizenzierung"
+
+#: apps/base/templates/about.scm:118
+msgid ""
+"Guix is free software; you can redistribute it and/or modify\n"
+"          it under the terms of the <1>GNU General Public License</1> as "
+"published by the Free Software Foundation; either\n"
+"          version 3 of the License, or (at your option) any later\n"
+"          version. "
+msgstr ""
+"Guix ist freie Software. Sie können es weitergeben und/oder verändern, "
+"solange Sie sich an die Regeln der <1>GNU General Public License</1> halten, "
+"so wie sie von der Free Software Foundation festgelegt wurden; entweder in "
+"Version 3 der Lizenz oder (nach Ihrem Ermessen) in jeder neueren Version."
+
+#: apps/base/data.scm:25
+msgid "IRC Channel"
+msgstr "IRC-Kanal"
+
+#: apps/base/data.scm:27
+msgid ""
+"Join the <1/> channel on the Freenode IRC network to chat\n"
+"       with the community about GNU Guix or to get help in\n"
+"       real-time."
+msgstr ""
+"Treten Sie dem <1/>-Kanal auf dem Freenode-IRC-Netzwerk bei, um mit der "
+"Gemeinde über GNU Guix zu reden oder im Gespräch Hilfe zu bekommen."
+
+#: apps/base/data.scm:36
+msgid "Info Mailing List"
+msgstr "Info-Mailing-Liste"
+
+#: apps/base/data.scm:38
+msgid ""
+"Subscribe to the <1/> low-traffic mailing\n"
+"list to receive important announcements sent by the project maintainers (in\n"
+"English)."
+msgstr ""
+"Tragen Sie sich auf der Mailing-Liste <1/> ein, um wichtige Ankündigungen "
+"durch die Projektbetreuer zu empfangen (auf Englisch). Diese Liste hat ein "
+"geringes E-Mail-Aufkommen."
+
+#: apps/base/data.scm:47
+msgid "Help Mailing List"
+msgstr "„Help“-Mailing-Liste"
+
+# Übernommen von Andreas Enge:
+# https://lists.gnu.org/archive/html/guix-devel/2018-03/msg00042.html
+#: apps/base/data.scm:52
+msgid ""
+"Subscribe to the Help mailing list to get support\n"
+"from the GNU Guix community via email.  You can post messages in English\n"
+"though we also accept other languages."
+msgstr ""
+"Melden Sie sich bei der „Help“-Mailingliste an, um per E-Mail "
+"gemeinschaftlichen Rat zu GNU Guix zu bekommen. Sie können Nachrichten auch "
+"auf Deutsch verfassen."
+
+#: apps/base/data.scm:56
+msgctxt "unique lingua code like en or zh-cn"
+msgid "en"
+msgstr "de"
+
+#: apps/base/data.scm:127
+msgid "Bug Reporting"
+msgstr "Fehler melden"
+
+#: apps/base/data.scm:129
+msgid ""
+"If you found a bug in Guix, check whether the bug is\n"
+"       already in the <1>bug database</1>. If it is not, please <2>report it."
+"</2>"
+msgstr ""
+"Wenn Sie einen Fehler in Guix gefunden haben, schauen Sie bitte, ob er "
+"bereits in der <1>Fehlerdatenbank</1> steht. Wenn nicht, sind wir dankbar, "
+"wenn Sie <2>ihn melden</2>."
+
+#: apps/base/data.scm:141
+msgid "Development Mailing List"
+msgstr "Entwicklungs-Mailing-Liste"
+
+#: apps/base/data.scm:143
+msgid ""
+"Discussion about the development of GNU Guix. <1> Until July 2013</1>, the "
+"bug-Guix mailing list filled that role. "
+msgstr ""
+"Hier finden Diskussionen über die Entwicklung von GNU Guix statt. <1>Bis zum "
+"Juli 2013</1> hat die Mailing-Liste bug-Guix diese Rolle übernommen. "
+
+#: apps/base/data.scm:153
+msgid "Patches Mailing List"
+msgstr "Patches-Mailing-Liste"
+
+#: apps/base/data.scm:155
+msgid ""
+"Submission of patches.  Every message sent to this mailing list\n"
+"       leads to a new entry in our <1>patch tracking tool</1>.  See <2>this "
+"page</2> for more information on how to use it; see <3>the "
+"manual<3.1>en</3.1><3.2>Submitting-Patches.html</3.2></3> for more "
+"information on how to submit a patch.  <4>Until February 2017</4>, the guix-"
+"devel mailing list filled that role."
+msgstr ""
+"Hier werden Patches eingereicht. Jede E-Mail, die an diese Liste geschickt "
+"wird, hat die Erzeugung eines neuen Eintrags in unserem <1>Werkzeug zur "
+"Erfassung von Patches</1> zur Folge. Auf <2>dieser Seite</2> finden Sie "
+"weitere Informationen darüber, wie Sie mit der Liste umgehen; <3>im "
+"Handbuch<3.1>de</3.1><3.2>Einreichen-von-Patches.html</3.2></3> sind "
+"Informationen zu finden, wie Sie einen Patch einreichen. <4>Bis zum 4. "
+"Februar 2017</4> hatte die Mailing-Liste guix-devel diese Rolle inne."
+
+#: apps/base/data.scm:174
+msgid "Commits Mailing List"
+msgstr "Commits-Mailing-Liste"
+
+#: apps/base/data.scm:176
+msgid "Notifications of commits made to the <1>Git repositories</1>."
+msgstr "Benachrichtigt über Commits auf den <1>Git-Repositorys</1>."
+
+#: apps/base/data.scm:185
+msgid "Security Mailing List"
+msgstr "Sicherheits-Mailing-Liste"
+
+#: apps/base/data.scm:187
+msgid ""
+"This is a private mailing list that anyone can post to to <1>report security "
+"issues</1> in Guix itself or in the <2>packages</2> it provides.  Posting "
+"here allows Guix developers to address\n"
+"       the problem before it is widely publicized."
+msgstr ""
+"Dies ist eine private Mailing-Liste, an die jeder schreiben kann, um "
+"<1>Sicherheitslücken zu melden</1>, die sich in Guix selbst oder in den zur "
+"Verfügung gestellten <2>Paketen</2> befinden. Eine E-Mail an diese Liste "
+"gibt den Guix-Entwicklern die Gelegenheit, Lücken zu beseitigen, bevor sie "
+"weithin bekannt werden."
+
+#: apps/base/data.scm:199
+msgid "Sysadmin Mailing List"
+msgstr "Sysadmin-Mailing-Liste"
+
+#: apps/base/data.scm:201
+msgid "Private mailing list for the <1>build farm</1> system administration."
+msgstr ""
+"Private Mailing-Liste für Systemadministratoren der <1>Erstellungsfarm</1>."
+
+#: apps/base/data.scm:213
+msgid "GNU System Discuss Mailing List"
+msgstr "Mailing-Liste für GNU-System-Diskussionen"
+
+#: apps/base/data.scm:215
+msgid "Discussion about the development of the broader GNU system."
+msgstr "Für Diskussionen über die Entwicklung des GNU-Systems allgemein."
+
+#: apps/base/data.scm:220
+msgid "GNU/Linux-libre Mailing List"
+msgstr "GNU/Linux-libre-Mailing-Liste"
+
+#: apps/base/data.scm:222
+msgid "Workgroup for fully free GNU/Linux distributions."
+msgstr "Arbeitsgruppe für völlig freie GNU/Linux-Distributionen."
+
+#: apps/base/data.scm:227
+msgid "GNU Info Mailing List"
+msgstr "GNU-Info-Mailing-Liste"
+
+#: apps/base/data.scm:229
+msgid "GNU software announcements."
+msgstr "Ankündigungen für GNU-Software."
+
+#: apps/base/data.scm:238
+msgctxt "screenshot title"
+msgid "Graphical log-in"
+msgstr "Grafische Anmeldung"
+
+#: apps/base/data.scm:242
+msgid "Graphical log-in screen"
+msgstr "Grafischer Anmeldebildschirm"
+
+#: apps/base/data.scm:245
+msgctxt "screenshot title"
+msgid "GNOME"
+msgstr "GNOME"
+
+#: apps/base/data.scm:249
+msgid "Control your computer with the GNOME desktop environment"
+msgstr "Steuern Sie Ihren Rechner mit der GNOME-Arbeitsumgebung"
+
+#: apps/base/data.scm:252
+msgctxt "screenshot title"
+msgid "Xfce"
+msgstr "Xfce"
+
+#: apps/base/data.scm:256
+msgid "The Xfce desktop environment with GNU Emacs and IceCat"
+msgstr "Die Xfce-Arbeitsumgebung mit GNU Emacs und IceCat"
+
+#: apps/base/data.scm:259
+msgctxt "screenshot title"
+msgid "Virtual machine"
+msgstr "Virtuelle Maschine"
+
+#: apps/base/data.scm:263
+msgid "Virtual machine started with 'guix system vm'"
+msgstr "Über ‚guix system vm‘ gestartete Virtuelle Maschine"
+
+#: apps/base/data.scm:266
+msgctxt "screenshot title"
+msgid "Enlightenment"
+msgstr "Enlightenment"
+
+#: apps/base/data.scm:270
+msgid "Enlightenment, Inkscape, and Serbian text"
+msgstr "Enlightenment, Inkscape und serbische Schrift"
+
+#: apps/base/templates/help.scm:17
+msgctxt "webpage title"
+msgid "Help"
+msgstr "Hilfe"
+
+#: apps/base/templates/help.scm:19
+msgid ""
+"A list of resources about how to use GNU Guix, plus\n"
+"   information about getting help from the community of users and\n"
+"   developers."
+msgstr ""
+"Eine Liste von Ressourcen, wie man GNU Guix benutzt, sowie Informationen "
+"darüber, wie Sie Hilfe von der Nutzer- und Entwicklergemeinde bekommen "
+"können."
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/help.scm:24
+msgid ""
+"GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU "
+"Guix package manager|Help resources"
+msgstr ""
+"GNU|Linux|Unix|Freie Software|Libre-Software|Betriebssystem|GNU Hurd|GNU-"
+"Guix-Paketverwaltung|Hilfe-Ressourcen"
+
+#: apps/base/templates/help.scm:35
+msgid "Help"
+msgstr "Hilfe"
+
+#: apps/base/templates/help.scm:46
+msgid "GNU Guix Manual"
+msgstr "Handbuch von GNU Guix"
+
+#: apps/base/templates/help.scm:47
+msgid ""
+"Documentation for GNU Guix is available\n"
+"            online.  You may also find more information about Guix by "
+"running <1>info guix</1>."
+msgstr ""
+"Sie können Dokumentation für GNU Guix online lesen. Sie können weitere "
+"Informationen über Guix auch bekommen, indem Sie <1>info guix</1> ausführen."
+
+#: apps/base/templates/help.scm:53
+msgid "Read Guix manual"
+msgstr "Lesen Sie das Guix-Handbuch"
+
+#: apps/base/templates/help.scm:64
+msgid "Get Guix reference card"
+msgstr "Guix-Referenzkarte herunterladen"
+
+#: apps/base/templates/help.scm:72
+msgid "GNU Manuals"
+msgstr "GNU-Handbücher"
+
+#: apps/base/templates/help.scm:73
+msgid ""
+"Guix is a distribution of the <1>GNU operating system</1>.  Documentation "
+"for GNU packages is\n"
+"            available online in various formats. "
+msgstr ""
+"Guix ist eine Distribution des <1>GNU-Betriebssystems</1>. Dokumentation für "
+"GNU-Pakete gibt es online in verschiedenen Formaten."
+
+#: apps/base/templates/help.scm:81
+msgid "Browse GNU manuals"
+msgstr "GNU-Handbücher lesen"
+
+#: apps/base/templates/help.scm:89
+msgid "IRC Chat"
+msgstr "IRC-Chat"
+
+#: apps/base/templates/help.scm:90
+msgid ""
+"For real-time support from the community, you can connect\n"
+"            to the <1/> channel on irc.freenode.net. There\n"
+"            you can get help about anything related to GNU Guix."
+msgstr ""
+"Sie können Hilfe von der Guix-Gemeinde per Chat bekommen, indem Sie sich mit "
+"dem <1/>-Kanal auf irc.freenode.net verbinden. Dort bekommen Sie Hilfe zu "
+"allem, was mit GNU Guix zu tun hat."
+
+#: apps/base/templates/help.scm:95
+msgid ""
+"The <1/> channel is logged. Previous\n"
+"            conversations can be browsed online. See the <2>channel "
+"logs</2>. "
+msgstr ""
+"Der <1/>-Kanal wird protokolliert. Vergangene Kommunikation kann online "
+"eingesehen werden; siehe die <2>Kanalprotokolle</2>. "
+
+#: apps/base/templates/help.scm:102
+msgid "Connect"
+msgstr "Verbinden"
+
+#: apps/base/templates/help.scm:110
+msgid "Mailing lists"
+msgstr "Mailing-Listen"
+
+#: apps/base/templates/help.scm:111
+msgid ""
+"Email support from the community is also available through\n"
+"            several mailing list. The messages sent to the lists are\n"
+"            public and archived online."
+msgstr ""
+"E-Mail-Hilfe aus der Gemeinde bekommen Sie auch auf mehreren Mailing-Listen. "
+"Die Nachrichten, die an die Listen geschickt werden, sind öffentlich "
+"einsehbar und werden online archiviert."
+
+#: apps/base/templates/help.scm:119
+msgid "See all lists"
+msgstr "Alle Listen sehen"
+
+#: apps/base/templates/contact.scm:17 apps/base/templates/irc.scm:18
+#: apps/base/templates/irc.scm:29
+msgctxt "webpage title"
+msgid "Contact"
+msgstr "Kontakt"
+
+#: apps/base/templates/contact.scm:19
+msgid ""
+"A list of channels to communicate with GNU Guix users\n"
+"   and developers about anything you want."
+msgstr ""
+"Eine Liste der Kanäle, auf denen Sie mit Nutzern und Entwicklern von "
+"GNU Guix reden können, worüber Sie möchten."
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/contact.scm:23
+msgid ""
+"GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU "
+"Guix package manager|Community|Mailing lists|IRC channels|Bug reports|Help"
+msgstr ""
+"GNU|Linux|Unix|Freie Software|Libre-Software|Betriebssystem|GNU Hurd|GNU-"
+"Guix-Paketverwaltung|Gemeinde|Community|Mailing-Listen|IRC-Kanäle|Probleme "
+"melden|Hilfe"
+
+#: apps/base/templates/contribute.scm:17
+msgctxt "webpage title"
+msgid "Contribute"
+msgstr "Mitmachen"
+
+#: apps/base/templates/contribute.scm:19
+msgid ""
+"Check all the ways you can contribute to make GNU Guix\n"
+"   better, and join the world-wide community of volunteers."
+msgstr ""
+"Sehen Sie, wo Sie mitmachen können, um GNU Guix zu verbessern, und treten "
+"Sie der weltweiten Gemeinschaft der Freiwilligen bei."
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/contribute.scm:23
+msgid ""
+"GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU "
+"Guix package manager|Volunteer|Development|Translation|I18N|L10N|Artwork"
+msgstr ""
+"GNU|Linux|Unix|Freie Software|Libre-Software|Betriebssystem|GNU Hurd|GNU-"
+"Guix-Paketverwaltung|Mitmachen|Entwicklung|Übersetzung|I18N|L10N|Grafiken|"
+"Medien|Design"
+
+#: apps/base/templates/contribute.scm:35 apps/base/templates/contribute.scm:110
+#: apps/base/templates/contribute.scm:227
+msgid "Contribute"
+msgstr "Mitmachen"
+
+#: apps/base/templates/contribute.scm:37
+msgid ""
+"GNU Guix is a large project developed\n"
+"           mostly by volunteers from all around the world. You are welcome\n"
+"           to join us in the <1>development mailing list</1> or in the "
+"<2>#guix channel</2> in IRC Freenode. Tell us how would you like to help, "
+"and we\n"
+"          will do our best to guide you. "
+msgstr ""
+"GNU Guix ist ein großes Projekt, das hauptsächlich von Freiwilligen aus "
+"aller Welt entwickelt wird. Sie sind bei uns auf der <1>Mailing-Liste zur "
+"Guix-Entwicklung</1> oder auf dem <2>„#guix“-Kanal</2> im IRC von Freenode "
+"herzlich willkommen. Sagen Sie uns, wie Sie uns helfen möchten, und wir tun "
+"unser Bestes, um Sie dabei zu begleiten."
+
+#: apps/base/templates/contribute.scm:51
+msgid ""
+"We want to provide a warm, friendly, and harassment-free environment,\n"
+"           so that anyone can contribute to the best of their abilities.  "
+"To\n"
+"           this end our project uses a “Contributor Covenant”, which was "
+"adapted\n"
+"           from <1>https://contributor-covenant.org/</1>.  You can find the "
+"full pledge in the <2>CODE-OF-CONDUCT</2> file."
+msgstr ""
+"Wir möchten eine warme, freundliche Umgebung frei von Belästigungen bieten, "
+"damit jeder so gut er kann mithelfen kann. Deshalb folgt dieses Projekt "
+"einer Vereinbarung („Contributor Covenant“), die auf <1>https://www."
+"contributor-covenant.org/translations</1> basiert. Sie können unser "
+"vollständiges Versprechen in der Datei <2>CODE-OF-CONDUCT</2> nachlesen."
+
+#: apps/base/templates/contribute.scm:72
+msgid "Project Management"
+msgstr "Projektverwaltung"
+
+#: apps/base/templates/contribute.scm:73
+msgid ""
+"We use <1>Savannah</1> as the central point for development, maintenance "
+"and\n"
+"            distribution of the Guix System Distribution and GNU Guix."
+msgstr ""
+"Wir verwenden <1>Savannah</1> als zentralen Sammlungspunkt für die "
+"Entwicklung, Wartung und Verteilung der Guix-System-Distribution und von "
+"GNU Guix."
+
+#: apps/base/templates/contribute.scm:79
+msgid ""
+"The source files for all the components of the project,\n"
+"            including software, web site, documentation, and artwork, are\n"
+"            available in <1>Git repositories</1> at Savannah. "
+msgstr ""
+"Die Quelldateien für alle Komponenten des Projekts, einschließlich seiner "
+"Software, seines Webauftritts, seiner Dokumentation, seiner Grafiken und "
+"Mediendateien, befinden sich in <1>Git-Repositorys</1> bei Savannah. "
+
+#: apps/base/templates/contribute.scm:89
+msgid "Access Savannah"
+msgstr "Zu Savannah"
+
+#: apps/base/templates/contribute.scm:94
+msgid "Art"
+msgstr "Grafiken und Medien"
+
+#: apps/base/templates/contribute.scm:95
+msgid ""
+"We are always looking for artists to help us design and\n"
+"            improve user interfaces, and create multimedia material for\n"
+"            documentation, presentations, and promotional items. "
+msgstr ""
+"Wir sind immer auf der Suche nach Künstlern, die uns beim Design und der "
+"Verbesserung von Benutzeroberflächen unterstützen und Multimedia-Material "
+"für die Dokumentation, für Präsentationen und Werbeartikel erschaffen."
+
+#: apps/base/templates/contribute.scm:100
+msgid ""
+"The artwork used in the different components of the project\n"
+"            is available in the <1>guix-artwork</1> repository. "
+msgstr ""
+"Die Grafiken und Mediendateien, die in den verschiedenen Komponenten des "
+"Projekts zum Einsatz kommen, stehen im <1>guix-artwork</1>-Repository zur "
+"Verfügung."
+
+#: apps/base/templates/contribute.scm:116
+msgid "Documentation"
+msgstr "Dokumentation"
+
+#: apps/base/templates/contribute.scm:117
+msgid ""
+"You can read the <1>project documentation</1> already available in the "
+"system and in the website, and\n"
+"            help us identify any errors or omissions. Creating new\n"
+"            manuals, tutorials, and blog entries will also help users and\n"
+"            developers discover what we do. "
+msgstr ""
+"Sie können die <1>Projektdokumentation</1>, die es schon im System und auf "
+"dem Webauftritt gibt, lesen und uns dabei helfen, Fehler zu finden und "
+"Unvollständiges zu ergänzen. Wenn Sie neue Handbücher, Anleitungen und Blog-"
+"Einträge schreiben, können Nutzer und Entwickler leichter erkennen, was wir "
+"tun."
+
+#: apps/base/templates/contribute.scm:125
+msgid ""
+"Helping improve the documentation of the <1>packaged software</1> is another "
+"way to contribute. "
+msgstr ""
+"Hilfe bei der Verbesserung der Dokumentation der von uns <1>in Paketen "
+"angebotenen Software</1> ist eine weitere Möglichkeit, GNU Guix zu "
+"unterstützen."
+
+#: apps/base/templates/contribute.scm:132
+msgid "Start writing"
+msgstr "Schreiben Sie Texte"
+
+#: apps/base/templates/contribute.scm:138
+#: apps/packages/templates/detailed-index.scm:43
+#: apps/packages/templates/index.scm:42
+msgid "Packages"
+msgstr "Pakete"
+
+#: apps/base/templates/contribute.scm:139
+msgid ""
+"Hundreds of software, documentation, and assets need to be\n"
+"            packaged to make it easier for users to install their\n"
+"            favorite tools with the Guix package manager, and be\n"
+"            productive using the system. "
+msgstr ""
+"Für Hunderte von Programmen, Dokumentation und Medien müssen noch Pakete "
+"geschrieben werden, damit es Benutzer leichter haben, ihre "
+"Lieblingswerkzeuge mit dem Guix-Paketverwaltungsprogramm zu installieren und "
+"das System produktiv zu nutzen."
+
+#. TRANSLATORS: Packaging Guidelines is a section name in the
+#. English (en) manual.
+#: apps/base/templates/contribute.scm:147
+msgid ""
+"Information on how to add packages to the distribution can\n"
+"            be found <1>in the manual<1.1>en</1.1><1.2>Packaging-Guidelines."
+"html</1.2></1>. "
+msgstr ""
+"Informationen, wie Sie Pakete zur Distribution hinzufügen können, finden Sie "
+"<1>im Handbuch<1.1>de</1.1><1.2>Paketrichtlinien.html</1.2></1>. "
+
+#: apps/base/templates/contribute.scm:157
+msgid ""
+"Check out the <1>package database</1> for a list of available packages, and "
+"the <2>patch-tracking database</2> for a list of pending submissions."
+msgstr ""
+"Schauen Sie in die <1>Paketdatenbank</1>, wenn Sie eine Liste der "
+"verfügbaren Pakete sehen wollen, und in die <2>Datenbank zur Patch-"
+"Erfassung</2> für eine Liste unbearbeiteter Einreichungen."
+
+#: apps/base/templates/contribute.scm:168
+msgid "Send a new package"
+msgstr "Senden Sie ein neues Paket"
+
+#: apps/base/templates/contribute.scm:174
+msgid "Programming"
+msgstr "Programmierung"
+
+#: apps/base/templates/contribute.scm:175
+msgid ""
+"Source code is in the <1>main Git repository</1>.  We use <2>GNU Guile</2> "
+"as the main programming and extension language for the\n"
+"            components of the system. "
+msgstr ""
+"Der Quellcode ist im <1>Haupt-Git-Repository</1> zu finden. Wir benutzen die "
+"Programmier- und Erweiterungssprache <2>GNU Guile</2> für den Großteil der "
+"Programmierung und der Komponenten des Systems."
+
+#. TRANSLATORS: Contributing is a section name in the English
+#. (en) manual.
+#: apps/base/templates/contribute.scm:187
+msgid ""
+"You will find it useful to browse the <1>Guile manual</1> or other "
+"<2>introductory material about Scheme</2>. Also, make sure to read the "
+"<3>Contributing<3.1>en</3.1><3.2>Contributing.html</3.2></3> section of the "
+"manual for more details on the development\n"
+"            setup, as well as the coding and cooperation conventions used\n"
+"            in the project. "
+msgstr ""
+"Sie werden es hilfreich finden, das <1>Guile-Handbuch</1> oder andere "
+"<2>einführende Texte über Scheme</2> zu lesen. Sie sollten außerdem den "
+"Abschnitt <3>Mitwirken<3.1>de</3.1><3.2>Mitwirken.html</3.2></3> im Handbuch "
+"lesen, um mehr Details über die Einrichtung Ihrer Entwicklungsumgebung sowie "
+"die Konventionen für Programmierung und Zusammenarbeit zu erfahren, die im "
+"Projekt gelten."
+
+#: apps/base/templates/contribute.scm:205
+msgid "Send a patch"
+msgstr "Einen Patch senden"
+
+#: apps/base/templates/contribute.scm:211
+msgid "System Administration"
+msgstr "Systemadministration"
+
+#: apps/base/templates/contribute.scm:212
+msgid ""
+"Our system infrastructure makes it possible for all the\n"
+"            contributors to communicate and collaborate in the project,\n"
+"            and users to be able to download and install packages. Help\n"
+"            us keep the system up and running smoothly. "
+msgstr ""
+"Dank unserer Systeminfrastruktur ist es allen Beteiligten möglich, im "
+"Projekt zu kommunizieren und zusammenzuarbeiten, und Nutzer können Pakete "
+"herunterladen und installieren. Helfen Sie uns dabei, dass das System weiter "
+"gut läuft."
+
+#: apps/base/templates/contribute.scm:218
+msgid ""
+"You can also <1>donate hardware or hosting</1> for our <2>build farm</2>.  "
+msgstr ""
+"Sie können für unsere <2>Erstellungsfarm</2> auch <1>Hardware spenden oder "
+"sie bei Ihnen aufstellen („Hosting“)</1>."
+
+#: apps/base/templates/contribute.scm:233
+msgid "Test and Bug Reports"
+msgstr "Testen und Fehlerberichte"
+
+#: apps/base/templates/contribute.scm:234
+msgid ""
+"Install the software and send feedback to the community\n"
+"            about your experience. Help the project by reporting bugs."
+msgstr ""
+"Installieren Sie die Software und geben Sie der Gemeinde Rückmeldung über "
+"Ihre Erfahrungen. Helfen Sie dem Projekt, indem Sie Fehler melden."
+
+#: apps/base/templates/contribute.scm:238
+msgid ""
+"Before reporting a bug, please check whether the bug is\n"
+"            already <1>in the bug database</1>. See <2>the developer "
+"information page</2> for more information on how to manipulate bug reports. "
+msgstr ""
+"Bevor Sie einen Fehler melden, schauen Sie bitte, ob es den Fehler schon in "
+"der <1>Fehlerdatenbank</1> gibt. Siehe <2>die Informationsseite für "
+"Entwickler</2>, um weitere Informationen zu bekommen, wie Sie Fehlerberichte "
+"ergänzen."
+
+#: apps/base/templates/contribute.scm:250
+msgid "Report a bug"
+msgstr "Einen Fehler melden"
+
+#: apps/base/templates/contribute.scm:256
+msgid "Translation"
+msgstr "Übersetzung"
+
+#: apps/base/templates/contribute.scm:257
+msgid ""
+"You can help translate the <1>software</1>, the <2>package descriptions</2>, "
+"and the <3>manual</3> into your language.  See the <4>Translation "
+"Project</4> for information on how you can help."
+msgstr ""
+"Sie können dabei helfen, die <1>Software</1>, die <2>Paketbeschreibungen</2> "
+"oder das <3>Handbuch</3> auf Ihre Sprache zu übersetzen. Siehe das "
+"<4>Translation Project</4> für Informationen, wie Sie helfen können."
+
+#: apps/base/templates/contribute.scm:276
+msgid ""
+"<1>Software packages</1> provided by the system may have their own "
+"translation\n"
+"            tools.  Visit their websites and help translate. "
+msgstr ""
+"Die vom System bereitgestellten <1>Software-Pakete</1> können ihre eigenen "
+"Werkzeuge haben, mit denen sie übersetzt werden können. Besuchen Sie deren "
+"Webauftritte und helfen Sie dort bei deren Übersetzung."
+
+#: apps/base/templates/contribute.scm:283
+msgid "Start translating"
+msgstr "Übersetzen Sie mit"
+
+#: apps/base/templates/contribute.scm:287
+msgid "Other resources for contributors"
+msgstr "Andere Ressourcen für Mitwirkende"
+
+#: apps/base/templates/contribute.scm:288
+msgid ""
+"Documents, supporting material of previous talks, and\n"
+"          auxiliary information useful to hackers and maintainers is\n"
+"          available at <1/>."
+msgstr ""
+"Dokumente, unterstützendes Material vergangener Vorträge sowie zusätzliche "
+"Informationen, die für Hacker und Betreuer nützlich sein können, sind auf <1/"
+"> zu finden."
+
+#: apps/base/templates/donate.scm:17
+msgctxt "webpage title"
+msgid "Donate"
+msgstr "Spenden"
+
+#: apps/base/templates/donate.scm:19
+msgid ""
+"We are looking for donations of hardware and optionally\n"
+"   hosting for machines (they should be usable with exclusively\n"
+"   free software)."
+msgstr ""
+"Wir suchen gespendete Hardware und optional auch Hosting für Maschinen (sie "
+"sollten mit ausschließlich freier Software nutzbar sein)."
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/donate.scm:24
+msgid ""
+"GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU "
+"Guix package manager|Donations"
+msgstr ""
+"GNU|Linux|Unix|Freie Software|Libre-Software|Betriebssystem|GNU Hurd|GNU-"
+"Guix-Paketverwaltung|Spenden"
+
+#: apps/base/templates/donate.scm:34
+msgid "Donate"
+msgstr "Spenden"
+
+#: apps/base/templates/donate.scm:36
+msgid ""
+"The <1>build farm</1> of the Guix System Distribution runs on donated "
+"hardware and hosting. As the distribution grows (see the <2>package "
+"list</2>), so do the computing and storage needs."
+msgstr ""
+"Die <1>Erstellungsfarm</1> der Guix-System-Distribution läuft mit "
+"gespendeter Hardware und Hosting. So wie die Distribution wächst (siehe die "
+"<2>Liste der Pakete</2>), so wachsen auch die nötigen Rechen- und "
+"Speicherkapazitäten."
+
+#: apps/base/templates/donate.scm:47
+msgid ""
+"We have <1>started a fundraising campaign</1> to strengthen our build farm, "
+"with <2>support from the Free Software Foundation (FSF)</2>.  Please "
+"consider helping out by making a donation on this\n"
+"          FSF-hosted page:"
+msgstr ""
+"Wir haben eine <1>Spendensammlung gestartet</1>, um unsere Erstellungsfarm "
+"zu verstärken, mit <2>Unterstützung durch die Free Software Foundation "
+"(FSF)</2>. Bitte denken Sie darüber nach, ob Sie uns mit einer Spende auf "
+"dieser von der FSF betriebenen Seite unterstützen möchten:"
+
+#: apps/base/templates/donate.scm:63
+msgctxt "button"
+msgid "♥ DONATE!"
+msgstr "♥ SPENDEN!"
+
+#: apps/base/templates/donate.scm:66
+msgid "Hardware and Hosting"
+msgstr "Hardware und Hosting"
+
+#: apps/base/templates/donate.scm:71
+msgid ""
+"We are also looking for donations of hardware and optionally\n"
+"           hosting for the following kinds of machines (they should be\n"
+"           usable with exclusively free software): "
+msgstr ""
+"Wir suchen auch Hardware-Spenden und optional auch Hosting für die folgenden "
+"Arten von Maschinen (sie sollten mit ausschließlich freier Software nutzbar "
+"sein):"
+
+#: apps/base/templates/donate.scm:78
+msgid ""
+"x86_64 machines, with on the order of 1 TiB of storage\n"
+"               and 4 GiB of RAM;"
+msgstr ""
+"x86_64-Maschinen mit in der Größenordnung von 1 TiB an Plattenspeicher und "
+"4 GiB Arbeitsspeicher,"
+
+#: apps/base/templates/donate.scm:81
+msgid ""
+"armv7 machines (such as the Novena) to more quickly test\n"
+"               and provide binaries for the armhf-linux port;"
+msgstr ""
+"ARMv7-Maschinen (wie Novena), um schnell Binärdateien für die Portierung auf "
+"armhf-linux testen und bereitstellen zu können,"
+
+#: apps/base/templates/donate.scm:84
+msgid "mips64el machines to strengthen this port."
+msgstr "MIPS64el-Maschinen, um diese Portierung zu verstärken."
+
+#: apps/base/templates/donate.scm:87
+msgid ""
+"Please get in touch with us through the <1>usual channels</1> or using the "
+"<2/> private alias to\n"
+"           discuss any opportunities. "
+msgstr ""
+"Bitte treten Sie mit uns über die <1>üblichen Kanäle</1> oder über die "
+"private Alias-Adresse <2/> in Kontakt, um Möglichkeiten zu diskutieren."
+
+#: apps/base/templates/donate.scm:95
+msgid "Thanks to the donors!"
+msgstr "Danke an die Spender!"
+
+#: apps/base/templates/donate.scm:100
+msgid ""
+"The table below summarizes hardware and hosting donations that\n"
+"           make the <1>build farm</1> for the Guix System Distribution a "
+"reality."
+msgstr ""
+"Die folgende Tabelle fasst Hardware- und Hosting-Spenden zusammen, die die "
+"<1>Erstellungsfarm</1> für die Guix-System-Distribution Wirklichkeit werden "
+"lassen."
+
+#: apps/base/templates/donate.scm:110
+msgid "<1>machine</1><2>system</2><3>donors</3>"
+msgstr "<1>Maschine</1><2>System</2><3>Spender</3>"
+
+#: apps/base/templates/donate.scm:114
+msgid ""
+"<1>hydra.gnu.org</1><2>build farm front-end</2><3>Free Software "
+"Foundation</3>"
+msgstr ""
+"<1>hydra.gnu.org</1><2>Vordergrundsystem („Front-end“) für die "
+"Erstellungsfarm</2><3>Free Software Foundation</3>"
+
+#: apps/base/templates/donate.scm:124
+msgid ""
+"<1>berlin.guixsd.org</1><2>build farm with 25 build nodes for x86_64-linux "
+"and\n"
+"i686-linux, and dedicated storage</2><3><3.1>Max Delbrück Center for "
+"Molecular Medicine</3.1> (hardware and hosting)</3>"
+msgstr ""
+"<1>berlin.guixsd.org</1><2>Erstellungsfarm mit 25 Erstellungsknoten für "
+"x86_64-linux und i686-linux, mit dediziertem Speicher</2><3><3.1>Max-"
+"Delbrück-Centrum für Molekulare Medizin</3.1> (Hardware und Hosting)</3>"
+
+#: apps/base/templates/donate.scm:136
+msgid ""
+"<1>overdrive1.guixsd.org</1><2>aarch64-linux</2><3><3.1>ARM "
+"Holdings</3.1></3>"
+msgstr ""
+"<1>overdrive1.guixsd.org</1><2>aarch64-linux</2><3><3.1>ARM "
+"Holdings</3.1></3>"
+
+#: apps/base/templates/donate.scm:146
+msgid ""
+"<1>bayfront.guixsd.org</1><2>new build farm front-end (WIP)</2><3>Igalia</3>"
+msgstr ""
+"<1>bayfront.guixsd.org</1><2>Neues Vordergrundsystem („Front-end“), in "
+"Arbeit</2><3>Igalia</3>"
+
+#: apps/base/templates/donate.scm:158
+msgid ""
+"<1>hydra.gnunet.org</1><2>x86_64-linux, i686-linux</2><3><3.1>Free Secure "
+"Network Systems Group</3.1> at the <3.2>Technische Universität "
+"München</3.2></3>"
+msgstr ""
+"<1>hydra.gnunet.org</1><2>x86_64-linux, i686-linux</2><3><3.1>Free Secure "
+"Network Systems Group</3.1> an der <3.2>Technischen Universität "
+"München</3.2></3>"
+
+#: apps/base/templates/donate.scm:171
+msgid ""
+"<1>chapters.gnu.org</1><2>x86_64-linux, i686-"
+"linux</2><3><3.1><3.1.1>GNU España</3.1.1> "
+"(hardware)</3.1><3.2><3.2.1>FSF France</3.2.1> (hosting)</3.2></3>"
+msgstr ""
+"<1>chapters.gnu.org</1><2>x86_64-linux, i686-"
+"linux</2><3><3.1><3.1.1>GNU España</3.1.1> "
+"(Hardware)</3.1><3.2><3.2.1>FSF France</3.2.1> (Hosting)</3.2></3>"
+
+#: apps/base/templates/donate.scm:186
+msgid ""
+"<1>librenote</1><2>mips64el-linux</2><3><3.1>Daniel Clark "
+"(hardware)</3.1><3.2>Mark H Weaver (hosting)</3.2></3>"
+msgstr ""
+"<1>librenote</1><2>mips64el-linux</2><3><3.1>Daniel Clark "
+"(Hardware)</3.1><3.2>Mark H Weaver (Hosting)</3.2></3>"
+
+#: apps/base/templates/donate.scm:195
+msgid "<1>hydra-slave0</1><2>mips64el-linux</2><3>Free Software Foundation</3>"
+msgstr ""
+"<1>hydra-slave0</1><2>mips64el-linux</2><3>Free Software Foundation</3>"
+
+#: apps/base/templates/donate.scm:205
+msgid "<1>guix.sjd.se</1><2>x86_64-linux, i686-linux</2><3>Simon Josefsson</3>"
+msgstr ""
+"<1>guix.sjd.se</1><2>x86_64-linux, i686-linux</2><3>Simon Josefsson</3>"
+
+#: apps/base/templates/donate.scm:215
+msgid "<1>x15.sjd.se</1><2>armhf-linux</2><3>Simon Josefsson</3>"
+msgstr "<1>x15.sjd.se</1><2>armhf-linux</2><3>Simon Josefsson</3>"
+
+#: apps/base/templates/donate.scm:225
+msgid ""
+"<1>hydra-slave1</1><2>armhf-linux</2><3><3.1>Steve Sprang "
+"(hardware)</3.1><3.2>Mark H Weaver (hosting)</3.2></3>"
+msgstr ""
+"<1>hydra-slave1</1><2>armhf-linux</2><3><3.1>Steve Sprang "
+"(Hardware)</3.1><3.2>Mark H Weaver (Hosting)</3.2></3>"
+
+#: apps/base/templates/donate.scm:235
+msgid ""
+"<1>hydra-slave2</1><2>armhf-linux</2><3><3.1><3.1.1>Harmon "
+"Instruments</3.1.1> (hardware)</3.1><3.2>Mark H Weaver (hosting)</3.2></3>"
+msgstr ""
+"<1>hydra-slave2</1><2>armhf-linux</2><3><3.1><3.1.1>Harmon "
+"Instruments</3.1.1> (Hardware)</3.1><3.2>Mark H Weaver (Hosting)</3.2></3>"
+
+#: apps/base/templates/donate.scm:248
+msgid ""
+"<1>hydra-slave3</1><2>armhf-linux</2><3><3.1><3.1.1>Kosagi (Sutajio Ko-Usagi "
+"Pte Ltd)</3.1.1> (hardware)</3.1><3.2>Mark H Weaver (hosting)</3.2></3>"
+msgstr ""
+"<1>hydra-slave3</1><2>armhf-linux</2><3><3.1><3.1.1>Kosagi (Sutajio Ko-Usagi "
+"Pte Ltd)</3.1.1> (Hardware)</3.1><3.2>Mark H Weaver (Hosting)</3.2></3>"
+
+#: apps/base/templates/donate.scm:261
+msgid ""
+"<1>redhill</1><2>armhf-linux</2><3><3.1><3.1.1>Kosagi (Sutajio Ko-Usagi Pte "
+"Ltd)</3.1.1> (hardware)</3.1><3.2>Andreas Enge (hosting)</3.2></3>"
+msgstr ""
+"<1>redhill</1><2>armhf-linux</2><3><3.1><3.1.1>Kosagi (Sutajio Ko-Usagi Pte "
+"Ltd)</3.1.1> (Hardware)</3.1><3.2>Andreas Enge (Hosting)</3.2></3>"
+
+#: apps/base/templates/graphics.scm:16
+msgctxt "webpage title"
+msgid "Graphics"
+msgstr "Grafiken"
+
+#: apps/base/templates/graphics.scm:18
+msgid ""
+"Information about images used for the graphical identity\n"
+"   of GNU Guix and Guix System (formerly “GuixSD”)."
+msgstr ""
+"Informationen über benutzte Bilder und die grafische Identität von GNU Guix "
+"und Guix System (ehemals “GuixSD”)."
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/graphics.scm:22
+msgid ""
+"GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU "
+"Guix package manager|Donations|Branding|Logo"
+msgstr ""
+"GNU|Linux|Unix|Freie Software|Libre-Software|Betriebssystem|GNU Hurd|GNU-"
+"Guix-Paketverwaltung|Spenden|Gestaltung|Logo"
+
+#: apps/base/templates/graphics.scm:32
+msgid "Graphics"
+msgstr "Grafiken"
+
+#: apps/base/templates/graphics.scm:34
+msgid ""
+"For questions regarding the graphics listed in this page,\n"
+"          please contact <1>help-guix@HIDDEN</1>."
+msgstr ""
+"Bei Fragen zu den auf dieser Seite aufgeführten Grafiken kontaktieren Sie "
+"bitte <1>help-guix@HIDDEN</1>."
+
+#: apps/base/templates/graphics.scm:44
+msgid "GNU Guix logotype"
+msgstr "Logotype von GNU Guix"
+
+#: apps/base/templates/graphics.scm:45
+msgid ""
+"The standalone Guix, formerly known as the “Guix System\n"
+"          Distribution” or GuixSD, had its own logo, which is now\n"
+"          deprecated."
+msgstr ""
+"Eine eigenständige Guix-Installation, ehemals bekannt als die „Guix-System-"
+"Distribution“ oder GuixSD, hatte ihr eigenes Logo, das nicht länger gültig "
+"ist."
+
+#: apps/base/templates/graphics.scm:51
+msgid ""
+"The GNU Guix and GuixSD\n"
+"          logotypes were designed by Luis Felipe López Acevedo\n"
+"          (a.k.a. sirgazil).  They are available under the following\n"
+"          terms:"
+msgstr ""
+"Die Logotypen von GNU Guix und GuixSD wurden von Luis Felipe López Acevedo "
+"gestaltet (auch bekannt als sirgazil). Sie sind unter den folgenden "
+"Bedingungen verfügbar:"
+
+#: apps/base/templates/graphics.scm:65
+msgid ""
+"The source files (SVG) for these logotypes, their variants, and\n"
+"          other artwork used in the different components of the GNU Guix\n"
+"          project are available in the <1>guix-artwork</1> repository, "
+"including the previous GNU Guix logotype designed\n"
+"          by Nikita Karetnikov in 2013 and <2>superseded</2> by the golden "
+"GNU in 2016."
+msgstr ""
+"Die Quelldateien (SVG) für diese Logotypen, ihre Varianten und andere "
+"Grafiken und Mediendateien, die in den verschiedenen Komponenten des GNU-"
+"Guix-Projekts benutzt werden, sind im <1>guix-artwork</1>-Repository "
+"verfügbar, einschließlich der vorherigen Logotype von GNU Guix, die von "
+"Nikita Karetnikov 2013 gestaltet wurde und 2016 durch das goldene GNU "
+"<2>ersetzt wurde</2>."
+
+#: apps/base/templates/irc.scm:17 apps/base/templates/irc.scm:30
+msgctxt "webpage title"
+msgid "IRC"
+msgstr "IRC"
+
+#: apps/base/templates/irc.scm:20
+msgid "Internet relay chat."
+msgstr "Internet Relay Chat."
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/irc.scm:23
+msgid ""
+"GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU "
+"Guix package manager|IRC|chat"
+msgstr ""
+"GNU|Linux|Unix|Freie Software|Libre-Software|Betriebssystem|GNU Hurd|GNU-"
+"Guix-Paketverwaltung|IRC|Chat"
+
+#: apps/base/templates/irc.scm:35
+msgid "IRC"
+msgstr "IRC"
+
+#: apps/base/templates/irc.scm:37
+msgid ""
+"Join the <1/> channel on the <2>Freenode IRC network</2> to chat with the "
+"GNU Guix community or to get help\n"
+"          in real-time. You can use the chat widget below, or just use\n"
+"          the <3>IRC client</3> of your preference. Note that the "
+"conversations that happen\n"
+"          on the <4/> channel are logged (<5>browse the log</5>)."
+msgstr ""
+"Kommen Sie auf den <1/>-Kanal auf dem <2>Freenode-IRC-Netzwerk</2>, um mit "
+"der GNU-Guix-Gemeinde live zu chatten. Sie können das Chatfeld unten "
+"benutzen oder einfach Ihren bevorzugten <3>IRC-Client</3> dorthin verbinden. "
+"Beachten Sie, dass Kommunikation auf dem <4/>-Kanal protokolliert wird "
+"(<5>lesen Sie das Protokoll</5>)."
+
+#: apps/base/templates/menu.scm:16
+msgctxt "webpage title"
+msgid "Menu"
+msgstr "Menü"
+
+#: apps/base/templates/menu.scm:17
+msgid "Website menu."
+msgstr "Menü des Webauftritts."
+
+#: apps/base/templates/menu.scm:24
+msgctxt "website menu"
+msgid "Menu"
+msgstr "Menü"
+
+#: apps/base/templates/screenshot.scm:19
+msgctxt "webpage title"
+msgid "Screenshots"
+msgstr "Screenshots"
+
+#: apps/base/templates/security.scm:19
+msgctxt "webpage title"
+msgid "Security"
+msgstr "Sicherheit"
+
+#: apps/base/templates/security.scm:21
+msgid ""
+"Important information about getting security updates\n"
+"   for your GNU Guix installation, and instructions on how\n"
+"   to report security issues."
+msgstr ""
+"Wichtige Informationen, wie Sie Sicherheitsaktualisierungen für Ihre "
+"Installation von GNU Guix bekommen, und eine Anleitung, wie Sie "
+"Sicherheitslücken melden."
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/base/templates/security.scm:26
+msgid ""
+"GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU "
+"Guix package manager|Security updates"
+msgstr ""
+"GNU|Linux|Unix|Freie Software|Libre-Software|Betriebssystem|GNU Hurd|GNU-"
+"Guix-Paketverwaltung|Sicherheitsaktualisierungen"
+
+#: apps/base/templates/security.scm:36
+msgid "Security"
+msgstr "Sicherheit"
+
+#: apps/base/templates/security.scm:38
+msgid "How to report security issues"
+msgstr "Wie Sie Sicherheitsprobleme melden"
+
+#: apps/base/templates/security.scm:39
+msgid ""
+"To report sensitive security issues in Guix itself or the\n"
+"           packages it provides, you can write to the private mailing list "
+"<1/>.  This list is monitored by a\n"
+"           small team of Guix developers."
+msgstr ""
+"Um sensible Sicherheitslücken in Guix selbst oder den bereitgestellten "
+"Paketen zu melden, können Sie eine Nachricht an die private Mailing-Liste <1/"
+"> schicken. Diese Liste wird von einer kleinen Gruppe von Guix-Entwicklern "
+"beobachtet."
+
+#: apps/base/templates/security.scm:46
+msgid ""
+"If you prefer to send your report using OpenPGP encrypted email,\n"
+"           please send it to one of the following Guix developers using "
+"their\n"
+"           respective OpenPGP key:"
+msgstr ""
+"Wenn Sie es bevorzugen, Ihre Meldung in einer mit OpenPGP verschlüsselten E-"
+"Mail zu übermitteln, senden Sie diese bitte einem der folgenden Guix-"
+"Entwickler unter Nutzung des entsprechenden OpenPGP-Schlüssels:"
+
+#: apps/base/templates/security.scm:65
+msgid "Release signatures"
+msgstr "Signaturen der Veröffentlichungen"
+
+#: apps/base/templates/security.scm:66
+msgid ""
+"Releases of Guix are signed using the OpenPGP key with the fingerprint <1/"
+">.  Users should <2>verify<2.1>en</2.1><2.2>Binary-Installation."
+"html</2.2></2> their downloads before extracting or running them."
+msgstr ""
+"Veröffentlichungen von Guix werden mit dem OpenPGP-Schlüssel mit dem "
+"Fingerabdruck <1/> signiert. Benutzer sollten heruntergeladene Dateien "
+"<2>verifizieren<2.1>de</2.1><2.2>Aus-Binardatei-installieren.html</2.2></2>, "
+"bevor sie diese entpacken oder ausführen."
+
+#: apps/base/templates/security.scm:78
+msgid "Security updates"
+msgstr "Sicherheitsaktualisierungen"
+
+#: apps/base/templates/security.scm:79
+msgid ""
+"When security vulnerabilities are found in Guix or the packages provided by "
+"Guix, we will provide <1>security updates<1.1>en</1.1><1.2>Security-Updates."
+"html</1.2></1> quickly and with minimal disruption for users."
+msgstr ""
+"Wenn Sicherheitslücken in Guix oder den von Guix bereitgestellten Paketen "
+"gefunden werden, werden wir schnell "
+"<1>Sicherheitsaktualisierungen<1.1>de</1.1><1.2>Sicherheitsaktualisierungen."
+"html</1.2></1> ausliefern, mit minimaler Beeinträchtigung für die Nutzer."
+
+#: apps/base/templates/security.scm:87
+msgid ""
+"Guix uses a “rolling release” model.  All security bug-fixes are pushed "
+"directly to the master branch.  There is no “stable” branch that only "
+"receives security fixes."
+msgstr ""
+"Guix verfolgt ein Rolling-Release-Modell. Jeder Patch, der eine "
+"Sicherheitslücke beseitigt, wird direkt auf den „master“-Branch gepusht. Es "
+"gibt keinen „stable“-Branch, der nur Sicherheitsaktualisierungen erhält."
+
+#: apps/download/data.scm:20
+msgctxt "download page title"
+msgid "GNU Guix System <1/>"
+msgstr "GNU Guix System <1/>"
+
+#: apps/download/data.scm:23
+msgid "USB/DVD ISO installer of the standalone Guix System."
+msgstr "USB/DVD-ISO-Installationsabbild des eigenständigen „Guix System“."
+
+#. TRANSLATORS: System installation is a section name in the
+#. English (en) manual.
+#. TRANSLATORS: System installation is a section name in the
+#. English (en) manual.
+#: apps/download/data.scm:31
+msgid "<1>en</1>System-Installation.html"
+msgstr "<1>de</1>Systeminstallation.html"
+
+#: apps/download/data.scm:35
+msgctxt "download page title"
+msgid "GNU Guix <1/> QEMU Image"
+msgstr "QEMU-Abbild mit GNU Guix <1/>"
+
+#: apps/download/data.scm:38
+msgid "QCOW2 virtual machine (VM) image."
+msgstr "Image für eine virtuelle Maschine (VM) im QCOW2-Format."
+
+#. TRANSLATORS: Running Guix in a VM is a section name in the
+#. English (en) manual.
+#. TRANSLATORS: Running Guix in a VM is a section name in the
+#. English (en) manual.
+#: apps/download/data.scm:45
+msgid "<1>en</1>Running-Guix-in-a-VM.html"
+msgstr "<1>de</1>Guix-in-einer-VM-starten.html"
+
+#: apps/download/data.scm:49
+msgctxt "download page title"
+msgid "GNU Guix <1/> Binary"
+msgstr "GNU Guix <1/> als Binärdatei"
+
+#: apps/download/data.scm:51
+msgid ""
+"Self-contained tarball providing binaries for Guix and its\n"
+"       dependencies, to be installed on top of your Linux-based system."
+msgstr ""
+"Tarball mit Binärdateien für Guix und dessen Abhängigkeiten, die Ihr "
+"bestehendes Linux-basiertes System ergänzen können."
+
+#. TRANSLATORS: Binary Installation is a section name in the
+#. English (en) manual.
+#. TRANSLATORS: Binary Installation is a section name in the
+#. English (en) manual.
+#: apps/download/data.scm:64
+msgid "<1>en</1>Binary-Installation.html"
+msgstr "<1>de</1>Aus-Binardatei-installieren.html"
+
+#: apps/download/data.scm:68
+msgctxt "download page title"
+msgid "GNU Guix <1/> Source"
+msgstr "Quellcode von GNU Guix <1/>"
+
+#: apps/download/data.scm:69
+msgid "Source code distribution."
+msgstr "Quellcode-Distribution."
+
+#. TRANSLATORS: Requirements is a section name in the English (en)
+#. manual.
+#. TRANSLATORS: Requirements is a section name in the English (en)
+#. manual.
+#: apps/download/data.scm:76
+msgid "<1>en</1>Requirements.html"
+msgstr "<1>de</1>Voraussetzungen.html"
+
+#: apps/download/templates/components.scm:25
+msgid "Download options:"
+msgstr "Herunterladen für:"
+
+#: apps/download/templates/components.scm:38
+msgid "Signatures: "
+msgstr "Signaturen:"
+
+#: apps/download/templates/components.scm:50
+msgid "<1>Installation instructions</1>."
+msgstr "<1>Installationsanleitung</1>."
+
+#: apps/download/templates/download.scm:33
+msgctxt "webpage title"
+msgid "Download"
+msgstr "Herunterladen"
+
+#: apps/download/templates/download.scm:35
+msgid ""
+"Installers and source files for GNU Guix.  GNU Guix can be\n"
+"   installed on different GNU/Linux distributions."
+msgstr ""
+"Installationsprogramme und Quelldateien für GNU Guix. GNU Guix kann auf "
+"verschiedenen GNU/Linux-Distributionen installiert werden."
+
+#. TRANSLATORS: |-separated list of webpage keywords
+#. TRANSLATORS: |-separated list of webpage keywords
+#: apps/download/templates/download.scm:39
+msgid ""
+"GNU|Linux|Unix|Free software|Libre software|Operating system|GNU Hurd|GNU "
+"Guix package manager|Installer|Source code|Package manager"
+msgstr ""
+"GNU|Linux|Unix|Freie Software|Libre-Software|Betriebssystem|GNU Hurd|GNU-"
+"Guix-Paketverwaltung|Installationsprogramm|Installationsabbild|Installation|"
+"Quellcode|Paketverwaltung"
+
+#: apps/download/templates/download.scm:51
+msgid "Download"
+msgstr "Herunterladen"
+
+#: apps/download/templates/download.scm:53
+msgid ""
+"As of version <1/>, the standalone Guix System <2>can be installed</2> on an "
+"i686, x86_64, ARMv7, or AArch64 machine.  It uses the <3>Linux-Libre</3> "
+"kernel and the <4>GNU Shepherd</4> init system. Alternately, GNU Guix\n"
+"          can be installed as an additional package manager on top of an\n"
+"          installed Linux-based system."
+msgstr ""
+"Stand Version <1/> kann das eigenständige Guix System auf einer Maschine mit "
+"i686-, x86_64-, ARMv7- oder AArch64-Architektur <2>installiert werden</2>. "
+"Als Kernel wird <3>Linux-Libre</3> benutzt und <4>GNU Shepherd</4> als Init-"
+"System. Alternativ kann GNU Guix als zusätzliches Paketverwaltungsprogramm "
+"auf einem bereits installierten Linux-basierten System installiert werden."
+
+#: apps/download/templates/download.scm:73
+msgid ""
+"Source code and binaries for the Guix System distribution ISO\n"
+"          image as well as GNU Guix can be found on the GNU servers at <1/"
+">.  Older releases can still be found on <2/>."
+msgstr ""
+"Den Quellcode und Binärdateien für die „Guix System“-Distribution als ISO-"
+"Abbild sowie für GNU Guix finden Sie auf den GNU-Servern unter <1/>. Ältere "
+"Veröffentlichungen können weiterhin auf <2/> gefunden werden."
+
+#: apps/blog/templates/components.scm:33 apps/blog/templates/post.scm:46
+msgctxt "SRFI-19 date->string format"
+msgid "~B ~e, ~Y"
+msgstr "~e. ~B ~Y"
+
+#: apps/blog/templates/components.scm:37
+msgctxt "blog post summary ellipsis"
+msgid "…"
+msgstr "…"
+
+#: apps/blog/templates/components.scm:48
+msgid "Blog menu: "
+msgstr "Blog-Menü: "
+
+#: apps/blog/templates/components.scm:53
+msgid "Get topic updates"
+msgstr "Neues zum Thema abonnieren"
+
+#: apps/blog/templates/components.scm:54
+msgid "Get blog updates"
+msgstr "Neue Blog-Einträge abonnieren"
+
+#: apps/blog/templates/components.scm:66
+msgctxt "button"
+msgid "Atom feed"
+msgstr "Atom-Feed"
+
+#: apps/blog/templates/components.scm:68
+msgid "Posts by topic"
+msgstr "Einträge nach Thema"
+
+#: apps/blog/templates/feed.scm:32
+msgctxt "feed author name"
+msgid "GNU Guix"
+msgstr "GNU Guix"
+
+#: apps/blog/templates/post-list.scm:23 apps/blog/templates/post-list.scm:40
+#: apps/blog/templates/tag.scm:25 apps/blog/templates/tag.scm:45
+#: apps/packages/templates/detailed-package-list.scm:24
+#: apps/packages/templates/detailed-package-list.scm:47
+#: apps/packages/templates/package-list.scm:24
+#: apps/packages/templates/package-list.scm:44
+msgid "Page <1/>"
+msgstr "Seite <1/>"
+
+#: apps/blog/templates/post-list.scm:24 apps/blog/templates/post.scm:25
+#: apps/blog/templates/tag.scm:26
+msgctxt "webpage title"
+msgid "Blog"
+msgstr "Blog"
+
+#: apps/blog/templates/post-list.scm:26 apps/blog/templates/post.scm:27
+msgid "Blog posts about GNU Guix."
+msgstr "Blog-Einträge über GNU Guix."
+
+#: apps/blog/templates/post.scm:52
+msgid "Related topics:"
+msgstr "Ähnliche Themen:"
+
+#: apps/blog/templates/tag.scm:28
+msgid "Blog posts about <1/> on GNU Guix."
+msgstr "Blog-Einträge über <1/> bei GNU Guix."
+
+#: apps/blog/templates/tag.scm:54
+msgid "Blog — "
+msgstr "Blog — "
+
+#: apps/packages/templates/components.scm:59
+#: apps/packages/templates/package.scm:56
+msgid "This is a GNU package.  "
+msgstr "Dies ist ein GNU-Paket.  "
+
+#: apps/packages/templates/components.scm:66
+msgid "<1>License:</1> <2/>."
+msgstr "<1>Lizenz:</1> <2/>."
+
+#: apps/packages/templates/components.scm:70
+msgid "<1>Website:</1> <2/>."
+msgstr "<1>Webauftritt:</1> <2/>."
+
+#: apps/packages/templates/components.scm:74
+msgid "<1>Package source:</1> <2/>."
+msgstr "<1>Paketquellcode:</1> <2/>."
+
+#: apps/packages/templates/components.scm:78
+msgid "<1>Patches:</1> <2/>."
+msgstr "<1>Patches:</1> <2/>."
+
+#: apps/packages/templates/components.scm:82
+msgid "<1>Lint issues:</1> <2/>."
+msgstr "<1>Automatisch erkannte Paketfehler:</1> <2/>."
+
+#: apps/packages/templates/components.scm:89
+msgid "<1>Builds:</1> <2/>."
+msgstr "<1>Erstellungen:</1> <2/>."
+
+#: apps/packages/templates/components.scm:104
+msgid " issue"
+msgid_plural " issues"
+msgstr[0] " Fehler"
+msgstr[1] " Fehler"
+
+#: apps/packages/templates/components.scm:115
+#: apps/packages/templates/components.scm:221
+msgid "Packages menu: "
+msgstr "Paketmenü: "
+
+#: apps/packages/templates/components.scm:117
+#: apps/packages/templates/components.scm:223
+msgid "Browse alphabetically"
+msgstr "Alphabetisch anzeigen"
+
+#: apps/packages/templates/components.scm:204
+#: apps/packages/templates/components.scm:270
+msgid "None"
+msgstr "Keine"
+
+#: apps/packages/templates/detailed-index.scm:22
+#: apps/packages/templates/detailed-package-list.scm:25
+#: apps/packages/templates/index.scm:22
+#: apps/packages/templates/package-list.scm:25
+#: apps/packages/templates/package.scm:28
+msgctxt "webpage title"
+msgid "Packages"
+msgstr "Pakete"
+
+#: apps/packages/templates/detailed-index.scm:24
+#: apps/packages/templates/detailed-package-list.scm:27
+#: apps/packages/templates/index.scm:24
+msgid "List of packages available through GNU Guix."
+msgstr "Liste der mit GNU Guix verfügbaren Pakete."
+
+#: apps/packages/templates/detailed-index.scm:45
+#: apps/packages/templates/index.scm:44
+msgid ""
+"GNU Guix provides <1/> packages transparently <2>available as pre-built "
+"binaries</2>. These pages provide a complete list of the packages.  Our "
+"<3>continuous integration system</3> shows their current build status "
+"(updated <4/>)."
+msgstr ""
+"Mit GNU Guix sind <1/> Pakete <2>als vorerstellte Binärdateien</2> "
+"transparent verfügbar. Auf diesen Seiten finden Sie eine vollständige Liste "
+"aller Pakete. Unser <3>System zur kontinuierlichen Integration</3> zeigt "
+"Ihnen deren aktuellen Status (Stand <4/>)."
+
+#: apps/packages/templates/detailed-package-list.scm:56
+#: apps/packages/templates/package-list.scm:53
+msgid "Packages — "
+msgstr "Pakete — "
+
+#: apps/packages/templates/package.scm:62
+msgid "<1>Website: </1>"
+msgstr "<1>Webauftritt: </1>"
+
+#: apps/packages/templates/package.scm:65
+msgid "<1>License: </1>"
+msgstr "<1>Lizenz: </1>"
+
+#: apps/packages/templates/package.scm:67
+msgid "<1>Package source: </1>"
+msgstr "<1>Paketquellcode: </1>"
+
+#: apps/packages/templates/package.scm:69
+msgid "<1>Patches: </1>"
+msgstr "<1>Patches: </1>"
+
+#: apps/packages/templates/package.scm:71
+msgid "<1>Builds: </1>"
+msgstr "<1>Erstellungen: </1>"
+
+#: apps/packages/templates/package.scm:77
+msgid ""
+"<1>Lint issues</1><2><2.1/>. See <2.2>package definition</2.2> in Guix "
+"source code.</2>"
+msgstr ""
+"<1>Automatisch erkannte Paketfehler</1><2><2.1/>. Siehe die "
+"<2.2>Paketdefinition</2.2> im Quellcode von Guix.</2>"
diff --git a/website/po/ietf-tags.scm b/website/po/ietf-tags.scm
index 8102a49..e447bc7 100644
--- a/website/po/ietf-tags.scm
+++ b/website/po/ietf-tags.scm
@@ -6,4 +6,5 @@
 ;;; in the team’s code is replaced by a hyphen.  For example, az would
 ;;; be used for the Azerbaijani language (not az-Latn) and zh-CN would
 ;;; be used for mainland Chinese (not zh-Hans-CN).
-(("en_US" . "en"))
+(("en_US" . "en")
+ ("de_DE" . "de"))
-- 
2.23.0


--uvu3qehc3367oshy
Content-Type: text/plain; charset=utf-8
Content-Disposition: attachment; filename="0007-website-Make-dropdowns-accessible-to-keyboard-and-to.patch"
Content-Transfer-Encoding: 8bit

From a53732d132ecdb91d5a8bc9f792aaf96d86cbcb0 Mon Sep 17 00:00:00 2001
From: Florian Pelz <pelzflorian@HIDDEN>
Date: Sun, 15 Sep 2019 21:42:01 +0200
Subject: [PATCH 7/8] website: Make dropdowns accessible to keyboard and touch
 input.

* website/apps/base/templates/components.scm (horizontal-line): New procedure.
(navbar, menu-dropdown): Adapt to use CSS for accessibility.
* website/static/base/css/navbar.css: Adapt CSS to new dropdowns.
---
 website/apps/base/templates/components.scm | 77 +++++++++++++++++-----
 website/static/base/css/navbar.css         | 61 ++++++++++++-----
 2 files changed, 108 insertions(+), 30 deletions(-)

diff --git a/website/apps/base/templates/components.scm b/website/apps/base/templates/components.scm
index 6b5ec21..1653c1e 100644
--- a/website/apps/base/templates/components.scm
+++ b/website/apps/base/templates/components.scm
@@ -21,6 +21,7 @@
 	    button-little
 	    contact-preview
 	    contact->shtml
+            horizontal-line
 	    horizontal-separator
 	    link-more
 	    link-subtle
@@ -179,6 +180,13 @@
 	    `(src ,(guix-url "static/base/img/h-separator-dark.png")))
        (alt ""))))
 
+(define (horizontal-line)
+  "Return SHTML for a visible separator to be used in a dropdown menu
+like a menu item."
+  `(img (@ (class "hline")
+           (src ,(guix-url "static/base/img/h-separator.png"))
+           (alt ""))))
+
 
 (define* (link-more #:key (label "More") (url "#") (light #false))
   "Return an SHTML a element that looks like a 'more →' link.
@@ -285,19 +293,52 @@ manual.
    ITEMS (list of menu items)
      A list of menu items as returned by the menu-item procedure in this
      same module. If not provided, the value defaults to an empty list."
-  `(li
-    (@ (class "dropdown"))
-    (a
-     (@ (class
-	 ,(if (string=? (string-downcase label) (string-downcase active-item))
-	      "menu-item menu-item-active dropdown-btn"
-	      "menu-item dropdown-btn"))
-	(href ,url))
-     ,label)
-    (div
-     (@ (class "submenu"))
-     (div (@ (class "submenu-triangle")) " ")
-     (ul ,@items))))
+  (let ((label-hash (number->string (string-hash label))))
+    `(li
+      (@ (class ,(if (string=? (string-downcase label)
+                               (string-downcase active-item))
+                     "menu-item menu-item-active dropdown dropdown-btn"
+                     "menu-item dropdown dropdown-btn")))
+      ,@(let ((id (string-append "visible-dropdown-" label-hash)))
+          `(;; show dropdown when button is checked:
+            (style ,(string-append "#" id ":checked ~ #submenu-" label-hash "
+{
+    width: initial;
+    height: initial;
+    min-width: 150px;
+    overflow: initial;
+}"))
+            ;; show uncheck version of button iff button is checked
+            (style ,(string-append "#" id ":checked \
+~ label[for=all-dropdowns-hidden]
+{
+    display: initial;
+}"))
+            (style "label[for=all-dropdowns-hidden]
+{
+    display: none;
+}")
+            ;; show check version of button iff button is unchecked
+            (style ,(string-append "#" id ":checked ~ label[for=" id "]
+{
+    display: none;
+}"))
+            (input (@ (class "menu-hidden-input")
+                      (type "radio")
+                      (name "dropdown")
+                      (id ,id)))
+            (label
+             (@ (for ,id))
+             ,label)
+            (label
+             (@ (for "all-dropdowns-hidden"))
+             ,label)))
+      (div
+       (@ (class "submenu")
+          (id ,(string-append "submenu-" label-hash)))
+       (div (@ (class "submenu-triangle"))
+            " ")
+       (ul ,@items)))))
 
 
 (define* (menu-item #:key (label "Item") (active-item "") (url "#"))
@@ -338,7 +379,11 @@ manual.
 
     ;; Menu.
     (nav (@ (class "menu"))
-         ,(G_ `(h2 (@ (class "a11y-offset")) "website menu:"))
+     ,(G_ `(h2 (@ (class "a11y-offset")) "website menu:"))
+     (input (@ (class "menu-hidden-input")
+               (type "radio")
+               (name "dropdown")
+               (id "all-dropdowns-hidden")))
      (ul
       ,(C_ "website menu" (menu-item #:label "Overview" #:active-item active-item #:url (guix-url)))
       ,(C_ "website menu" (menu-item #:label "Download" #:active-item active-item #:url (guix-url "download/")))
@@ -347,9 +392,11 @@ manual.
       ,(C_ "website menu" (menu-item #:label "Help" #:active-item active-item #:url (guix-url "help/")))
       ,(C_ "website menu" (menu-item #:label "Donate" #:active-item active-item #:url (guix-url "donate/")))
 
-      ,(menu-dropdown #:label (C_ "website menu" "About") #:active-item active-item #:url (guix-url "about/")
+      ,(menu-dropdown #:label (C_ "website menu" "About") #:active-item active-item
 	#:items
         (list
+         (C_ "website menu" (menu-item #:label "About" #:active-item active-item #:url (guix-url "about/")))
+         (horizontal-line)
          (C_ "website menu" (menu-item #:label "Contact" #:active-item active-item #:url (guix-url "contact/")))
          (C_ "website menu" (menu-item #:label "Contribute" #:active-item active-item #:url (guix-url "contribute/")))
          (C_ "website menu" (menu-item #:label "Security" #:active-item active-item #:url (guix-url "security/")))
diff --git a/website/static/base/css/navbar.css b/website/static/base/css/navbar.css
index d699d89..c8a6bd8 100644
--- a/website/static/base/css/navbar.css
+++ b/website/static/base/css/navbar.css
@@ -53,8 +53,13 @@
     position: relative;
 }
 
+.menu-hidden-input {
+    display: none;
+}
+
 .menu-item:link,
-.menu-item:visited {
+.menu-item:visited,
+label.menu-item {
     background-color: transparent;
     background-image: url("../img/link-arrow.png");
     background-position: 97% 50%;
@@ -104,6 +109,10 @@
     background-position: top;
 }
 
+.hline {
+    display: none;
+}
+
 
 
 
@@ -134,11 +143,11 @@
         text-align: center;
     }
 
-    .menu-item:active,
-    .menu-item:focus,
-    .menu-item:hover,
-    .menu-item-active:link,
-    .menu-item-active:visited {
+    a.menu-item:active,
+    a.menu-item:focus,
+    a.menu-item:hover,
+    a.menu-item-active:link,
+    a.menu-item-active:visited {
 	background-image: url("../img/menu-item-active-bg.png");
 	background-position: bottom center;
 	background-repeat: no-repeat;
@@ -149,31 +158,53 @@
     }
 
     .dropdown:hover .submenu {
-	display: block;
-	right: 0px;
+        width: initial;
+        height: initial;
+        min-width: 150px;
+        overflow: initial;
     }
 
-    .dropdown-btn:link,
-    .dropdown-btn:visited {
+    .dropdown-btn {
 	background-image: url("../img/dropdown-bg.png");
 	background-position: bottom right;
 	background-repeat: no-repeat;
 	padding-right: 13px;
+        cursor: pointer;
     }
 
     .dropdown-btn:active,
-    .dropdown-btn:focus,
     .dropdown-btn:hover {
-	background-position: top right;
+        background-image: url("../img/dropdown-bg.png");
+        background-position: top right;
+    }
+
+    label[for=all-dropdowns-hidden] {
+        text-shadow: #fff 0px -2px 15px, #fff 0px -2px 10px;
+    }
+
+    .hline {
+        display: block;
+        width: 100%;
+        height: 1px;
     }
 
     .submenu {
 	background-color: transparent;
-	display: none;
-	min-width: 150px;
+        z-index: 10;
+        display: block;
+        overflow: hidden;
+        width: 0;
+        height: 0;
 	padding-top: 20px;
 	position: absolute;
-	z-index: 10;
+        right: 0px;
+    }
+
+    .submenu:focus-within {
+        width: initial;
+        height: initial;
+        min-width: 150px;
+        overflow: initial;
     }
 
     .submenu-triangle {
-- 
2.23.0


--uvu3qehc3367oshy
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="0008-website-Add-language-selection-dropdown-to-navbar.patch"

From 88e8c06927411a814809be8126491144653e86b3 Mon Sep 17 00:00:00 2001
From: Florian Pelz <pelzflorian@HIDDEN>
Date: Sun, 15 Sep 2019 22:03:26 +0200
Subject: [PATCH 8/8] website: Add language selection dropdown to navbar.

* website/apps/base/templates/components.scm (navbar): Add it.
(horizontal-skip): New procedure.
* website/static/base/css/navbar.css: Add CSS for horizontal-skip.
Increase size at which website switches to mobile mode.
---
 website/apps/base/templates/components.scm | 30 +++++++++++++++++++---
 website/static/base/css/navbar.css         |  6 ++++-
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/website/apps/base/templates/components.scm b/website/apps/base/templates/components.scm
index 1653c1e..278036c 100644
--- a/website/apps/base/templates/components.scm
+++ b/website/apps/base/templates/components.scm
@@ -23,6 +23,7 @@
 	    contact->shtml
             horizontal-line
 	    horizontal-separator
+            horizontal-skip
 	    link-more
 	    link-subtle
 	    link-yellow
@@ -180,6 +181,10 @@
 	    `(src ,(guix-url "static/base/img/h-separator-dark.png")))
        (alt ""))))
 
+(define (horizontal-skip)
+  "Return SHTML for a small horizontal space."
+  `(span (@ (class "hskip"))))
+
 (define (horizontal-line)
   "Return SHTML for a visible separator to be used in a dropdown menu
 like a menu item."
@@ -400,13 +405,32 @@ manual.
          (C_ "website menu" (menu-item #:label "Contact" #:active-item active-item #:url (guix-url "contact/")))
          (C_ "website menu" (menu-item #:label "Contribute" #:active-item active-item #:url (guix-url "contribute/")))
          (C_ "website menu" (menu-item #:label "Security" #:active-item active-item #:url (guix-url "security/")))
-         (C_ "website menu" (menu-item #:label "Graphics" #:active-item active-item #:url (guix-url "graphics/")))))))
+         (C_ "website menu" (menu-item #:label "Graphics" #:active-item active-item #:url (guix-url "graphics/")))))
+      ,(horizontal-skip)
+      ;; Languages dropdown.
+      ,(menu-dropdown #:label (locale-display-name) #:active-item active-item
+        #:items
+        (map-in-order
+         (lambda (ietf-info)
+           (let ((lingua (car ietf-info))
+                 (code (cdr ietf-info)))
+             (setlocale LC_ALL (string-append lingua ".utf8"))
+             (let ((out (menu-item #:label (locale-display-name)
+                                   #:active-item active-item
+                                   #:url (guix-url (string-append code "/")
+                                                   #:localize #f))))
+               (setlocale LC_ALL "")
+               out)))
+         (sort (delete %current-lingua
+                       ietf-tags-file-contents
+                       (lambda (a b) (string=? a (car b))))
+               (lambda (a b) string<?))))))
+
 
     ;; Menu button.
     (a
      (@ (class "menu-btn")
-	(href ,(guix-url "menu/"))) "")))
-
+        (href ,(guix-url "menu/"))) "")))
 
 (define (page-indicator page-number total-pages)
   "Return an SHTML span element in the form 'page X of Y' if there is
diff --git a/website/static/base/css/navbar.css b/website/static/base/css/navbar.css
index c8a6bd8..1146f13 100644
--- a/website/static/base/css/navbar.css
+++ b/website/static/base/css/navbar.css
@@ -109,6 +109,10 @@ label.menu-item {
     background-position: top;
 }
 
+.hskip {
+    padding-left: 10px;
+}
+
 .hline {
     display: none;
 }
@@ -116,7 +120,7 @@ label.menu-item {
 
 
 
-@media screen and (min-width: 850px) {
+@media screen and (min-width: 900px) {
     .navbar {
 	position: relative;
 	overflow: visible;
-- 
2.23.0


--uvu3qehc3367oshy--




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Wed, 18 Sep 2019 13:01:02 +0000
Resent-Message-ID: <handler.26302.B26302.15688116603153 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: sirgazil <sirgazil@HIDDEN>
Cc: 26302 <26302 <at> debbugs.gnu.org>
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.15688116603153
          (code B ref 26302); Wed, 18 Sep 2019 13:01:02 +0000
Received: (at 26302) by debbugs.gnu.org; 18 Sep 2019 13:01:00 +0000
Received: from localhost ([127.0.0.1]:53727 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1iAZZr-0000on-L6
	for submit <at> debbugs.gnu.org; Wed, 18 Sep 2019 09:00:59 -0400
Received: from pelzflorian.de ([5.45.111.108]:40432 helo=mail.pelzflorian.de)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pelzflorian@HIDDEN>) id 1iAZZp-0000oe-9n
 for 26302 <at> debbugs.gnu.org; Wed, 18 Sep 2019 09:00:58 -0400
Received: from pelzflorian.localdomain (unknown [5.45.111.108])
 by mail.pelzflorian.de (Postfix) with ESMTPSA id D200B3602A4;
 Wed, 18 Sep 2019 15:00:55 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=pelzflorian.de;
 s=mail; t=1568811656;
 bh=27VFdJoMWVjm3xaSj7noyrjQ8vDL089taPfLQqNS3sg=;
 h=Date:From:To:Cc:Subject:References:In-Reply-To;
 b=JGnFaAh5xHDeIK/rsK9fg7w5/13K9Ost4Ltd2ebmjgWXN7erhihSfmyD31CUreJUL
 cYuT4YCBj/gtpmH3FOMlarvIh/PLuVDaTHHl/fvSKFAJO/aJ7BDb6LDSQRcarn//vZ
 ZKouPho3ktwgSA0Z0OQ0pRPOWppy7OPFB9fUDayk=
Date: Wed, 18 Sep 2019 15:00:55 +0200
From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Message-ID: <20190918130055.gvx2z2iqh7i3qn6h@HIDDEN>
References: <20170329154040.ddscahwp2agknihb@abyayala>
 <16d07cb5a1d.ca69255821627.8144164908931126811@HIDDEN>
 <20190908171638.cna67eearj4rbn2k@HIDDEN>
 <16d18a5a9e8.12ab66c8254154.2756956535677606704@HIDDEN>
 <20190915201819.3yxm25fayvbxwdpl@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: 8bit
In-Reply-To: <20190915201819.3yxm25fayvbxwdpl@HIDDEN>
User-Agent: NeoMutt/20180716
X-Spam-Score: 0.0 (/)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

On Sun, Sep 15, 2019 at 10:18:20PM +0200, pelzflorian (Florian Pelz) wrote:
> What’s missing is code for adding the nginx plugin
> 
> https://www.nginx.com/resources/wiki/modules/accept_language/
> 
> to Guix so it can be used on berlin.scm.  It seems to offer all that
> is required for redirecting existing URLs.
> 
> Regards,
> Florian

Help is welcome.  If berlin.scm uses the above module, a package like
<https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=nginx-mod-dav-ext>
but for the accept_language module and for Guix would be needed.
I would prefer someone more into nginx and its Guix service to do this
or suggest an alternative.  If not, I will try making a package in a few days.

Regards,
Florian




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Wed, 18 Sep 2019 13:58:02 +0000
Resent-Message-ID: <handler.26302.B26302.15688150799465 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: "pelzflorian \(Florian Pelz\)" <pelzflorian@HIDDEN>
Cc: Mark H Weaver <mhw@HIDDEN>, GNU Guix maintainers <guix-maintainers@HIDDEN>, 26302 <at> debbugs.gnu.org
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.15688150799465
          (code B ref 26302); Wed, 18 Sep 2019 13:58:02 +0000
Received: (at 26302) by debbugs.gnu.org; 18 Sep 2019 13:57:59 +0000
Received: from localhost ([127.0.0.1]:54667 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1iAaT1-0002Sa-3I
	for submit <at> debbugs.gnu.org; Wed, 18 Sep 2019 09:57:59 -0400
Received: from eggs.gnu.org ([209.51.188.92]:56255)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <ludo@HIDDEN>) id 1iAaSz-0002SJ-4g
 for 26302 <at> debbugs.gnu.org; Wed, 18 Sep 2019 09:57:57 -0400
Received: from fencepost.gnu.org ([2001:470:142:3::e]:60227)
 by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from <ludo@HIDDEN>)
 id 1iAaSs-0003Jk-N9; Wed, 18 Sep 2019 09:57:50 -0400
Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=51120 helo=ribbon)
 by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256)
 (Exim 4.82) (envelope-from <ludo@HIDDEN>)
 id 1iAaSr-0006Uf-8C; Wed, 18 Sep 2019 09:57:50 -0400
From: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
References: <20170329154040.ddscahwp2agknihb@abyayala>
 <8760e8l3bd.fsf@HIDDEN> <20170731215448.6zsu2qcfykuzbcd2@abyayala>
 <20190906142548.4crfjgvxilgalgrs@HIDDEN>
Date: Wed, 18 Sep 2019 15:57:47 +0200
In-Reply-To: <20190906142548.4crfjgvxilgalgrs@HIDDEN>
 (pelzflorian@HIDDEN's message of "Fri, 6 Sep 2019 16:25:48
 +0200")
Message-ID: <87ef0daeqs.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]
X-Spam-Score: -2.3 (--)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -3.3 (---)

Hi Florian,

Could you create an account on Savannah so we can give you commit
access?

That=E2=80=99d allow you for you to push these patches first in a branch so=
 we
can test, and it should make it easier for you.

Once you=E2=80=99ve created an account, please make sure to add the OpenPGP=
 key
you=E2=80=99ll use to sign commits on Savannah and on key servers, and repl=
y to
this message signed with that key.

"pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN> skribis:

> I am not entirely certain in my use of macros, but believe it is
> right.  See my discussion with Mark H Weaver at
> <https://lists.gnu.org/archive/html/guile-user/2019-09/msg00008.html>.

I have a couple of comments on this specific issue below.

> +;; NOTE: The sgettext macros have no hygiene because they use
> +;; datum->syntax and do not preserve the semantics of anything looking
> +;; like an sgettext macro.  This is an exceptional use case; do not
> +;; try this at home.

:-)

> +(define (sgettext x)
> +  "After choosing an identifier for marking s-expressions for
> +translation, make it usable by defining a macro with it calling
> +sgettext.  If for example the chosen identifier is G_,
> +use (define-syntax G_ sgettext)."
> +  (syntax-case x ()
> +    ((id exp)
> +     (let* ((msgid (sexp->msgid (syntax->datum #'exp)))
> +            (new-exp (deconstruct (syntax->datum #'exp)
> +                                  (gettext msgid))))
> +       (datum->syntax #'id new-exp)))))

For this and other similar macros you must use =E2=80=98define-syntax=E2=80=
=99, not
=E2=80=98define=E2=80=99, so that they are defined at expansion time, not a=
t run time.
(It doesn=E2=80=99t make any difference when you=E2=80=99re evaluating code=
 since both
phases run in the same module, but it does make a difference when these
phases happen at different times, in different processes.)

Consequently, you must arrange for =E2=80=98sexp->msgid=E2=80=99 and =E2=80=
=98deconstruct=E2=80=99 to be
available at expansion time too.  This can be done by wrapping their
definition in =E2=80=98eval-when=E2=80=99:

  (eval-when (load expand eval)
    (define (sexp->msgid =E2=80=A6) =E2=80=A6)
    (define (deconstruct =E2=80=A6) =E2=80=A6))

But actually it=E2=80=99s not clear to me why these are macros.  I think th=
ey
could be regular procedures and it=E2=80=99d work just fine, no?

> +(define %plural-numbers
> +  ;; Hard-coded list of input numbers such that for each language=E2=80=
=99s
> +  ;; plural formula, for each possible output grammatical number,
> +  ;; there is an n among %plural-numbers that yields this output
> +  ;; (cf. section Plural forms in the gettext manual), except 1 is
> +  ;; omitted from this list because it is a special case for
> +  ;; sngettext.  That is, calling ngettext with each number from
> +  ;; %plural-numbers and with 1 in any locale is guaranteed to return
> +  ;; each plural form at least once.  It would be more resilient
> +  ;; towards new languages if instead of hard-coding we computed this
> +  ;; from the Plural-Forms in the MO file header entry, but that is
> +  ;; not worth the incurred code complexity.
> +  '(0 2 3 11 100))

I don=E2=80=99t understand this: are these the only plural numbers in all
languages, or=E2=80=A6?

Thanks!

Ludo=E2=80=99.




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Thu, 19 Sep 2019 07:49:02 +0000
Resent-Message-ID: <handler.26302.B26302.15688793167434 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Cc: Mark H Weaver <mhw@HIDDEN>, GNU Guix maintainers <guix-maintainers@HIDDEN>, 26302 <at> debbugs.gnu.org
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.15688793167434
          (code B ref 26302); Thu, 19 Sep 2019 07:49:02 +0000
Received: (at 26302) by debbugs.gnu.org; 19 Sep 2019 07:48:36 +0000
Received: from localhost ([127.0.0.1]:55089 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1iArB5-0001vp-CL
	for submit <at> debbugs.gnu.org; Thu, 19 Sep 2019 03:48:35 -0400
Received: from pelzflorian.de ([5.45.111.108]:41488 helo=mail.pelzflorian.de)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pelzflorian@HIDDEN>) id 1iArB2-0001ve-5V
 for 26302 <at> debbugs.gnu.org; Thu, 19 Sep 2019 03:48:33 -0400
Received: from florianbeaglebone.fritz.box
 (ip5b42d6e2.dynamic.kabel-deutschland.de [91.66.214.226])
 by mail.pelzflorian.de (Postfix) with ESMTPSA id AD60D3602A4;
 Thu, 19 Sep 2019 09:48:30 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=pelzflorian.de;
 s=mail; t=1568879310;
 bh=oHzC7nXj3QpFkKLaAUAqigUuJJYHMzgx3EiNN29BFSg=;
 h=Date:From:To:Cc:Subject:References:In-Reply-To;
 b=sxE/N1YEKcyOD845cclsd2PsRN0WJy5QW92PZKQRKtmnZcfhCU3Hyv/lroue0cKDE
 fXLEpqcD/7d47LHLdbl83yNl77iC5FWJ/LoHPpdyHLWve10cX3YraMBPW1Z3SrZzdw
 sRoRP6nFV+mo/ZVmsv9P59mKWntNC9QjRk2SRex8=
Date: Thu, 19 Sep 2019 07:48:29 +0000
From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Message-ID: <20190919074829.hu3c7yy3bmeudfsw@HIDDEN>
References: <20170329154040.ddscahwp2agknihb@abyayala> <8760e8l3bd.fsf@HIDDEN>
 <20170731215448.6zsu2qcfykuzbcd2@abyayala>
 <20190906142548.4crfjgvxilgalgrs@HIDDEN>
 <87ef0daeqs.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: multipart/signed; micalg=pgp-sha256;
 protocol="application/pgp-signature"; boundary="wxpibp5tboksjfbf"
Content-Disposition: inline
In-Reply-To: <87ef0daeqs.fsf@HIDDEN>
User-Agent: NeoMutt/20180716
X-Spam-Score: 0.0 (/)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)


--wxpibp5tboksjfbf
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Wed, Sep 18, 2019 at 03:57:47PM +0200, Ludovic Court=C3=A8s wrote:
> Hi Florian,
>=20
> Could you create an account on Savannah so we can give you commit
> access?
>=20

Done.  My username is pelzflorian.


> > +(define (sgettext x)
> > +  "After choosing an identifier for marking s-expressions for
> > +translation, make it usable by defining a macro with it calling
> > +sgettext.  If for example the chosen identifier is G_,
> > +use (define-syntax G_ sgettext)."
> > +  (syntax-case x ()
> > +    ((id exp)
> > +     (let* ((msgid (sexp->msgid (syntax->datum #'exp)))
> > +            (new-exp (deconstruct (syntax->datum #'exp)
> > +                                  (gettext msgid))))
> > +       (datum->syntax #'id new-exp)))))
>=20
> For this and other similar macros you must use =E2=80=98define-syntax=E2=
=80=99, not
> =E2=80=98define=E2=80=99, so that they are defined at expansion time, not=
 at run time.

As per the above docstring, I already have a definition

  (define-syntax G_ sgettext)

in (apps i18n).  Possibly I should just move it here.



> (It doesn=E2=80=99t make any difference when you=E2=80=99re evaluating co=
de since both
> phases run in the same module, but it does make a difference when these
> phases happen at different times, in different processes.)
>=20
> Consequently, you must arrange for =E2=80=98sexp->msgid=E2=80=99 and =E2=
=80=98deconstruct=E2=80=99 to be
> available at expansion time too.  This can be done by wrapping their
> definition in =E2=80=98eval-when=E2=80=99:
>=20
>   (eval-when (load expand eval)
>     (define (sexp->msgid =E2=80=A6) =E2=80=A6)
>     (define (deconstruct =E2=80=A6) =E2=80=A6))
>=20
> But actually it=E2=80=99s not clear to me why these are macros.  I think =
they
> could be regular procedures and it=E2=80=99d work just fine, no?
>=20

I do not understand.  sexp->msgid and deconstruct are procedures, not
syntax transformers.  I can add eval-when, but the current code runs
as expected for me.




> > +(define %plural-numbers
> > +  ;; Hard-coded list of input numbers such that for each language=E2=
=80=99s
> > +  ;; plural formula, for each possible output grammatical number,
> > +  ;; there is an n among %plural-numbers that yields this output
> > +  ;; (cf. section Plural forms in the gettext manual), except 1 is
> > +  ;; omitted from this list because it is a special case for
> > +  ;; sngettext.  That is, calling ngettext with each number from
> > +  ;; %plural-numbers and with 1 in any locale is guaranteed to return
> > +  ;; each plural form at least once.  It would be more resilient
> > +  ;; towards new languages if instead of hard-coding we computed this
> > +  ;; from the Plural-Forms in the MO file header entry, but that is
> > +  ;; not worth the incurred code complexity.
> > +  '(0 2 3 11 100))
>=20
> I don=E2=80=99t understand this: are these the only plural numbers in all
> languages, or=E2=80=A6?
>=20

Yes, in all languages for which a plural=3D formula is documented in the
gettext manual.

For example, Arabic has

          Plural-Forms: nplurals=3D6; \
              plural=3Dn=3D=3D0 ? 0 : n=3D=3D1 ? 1 : n=3D=3D2 ? 2 : n%100>=
=3D3 && n%100<=3D10 ? 3 \
              : n%100>=3D11 ? 4 : 5;

with input plural numbers 0, 1, 2, 3, 11, 100 mapping to all outputs
0, 1, 2, 3, 4, 5.

Maybe I should add this example to the code comment.

Regards,
Florian
--wxpibp5tboksjfbf
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQEzBAEBCAAdFiEEzvTLkUhWujgKIKfiMAiIyznGOBcFAl2DMsQACgkQMAiIyznG
OBdwMQf/Z4wLkn/4STj/7S08bRf9dIa8ksRXrAJ1wgJgkvXEkkLz9QBEH9RSF+WY
0EJgUwcRNMG7va+Knxb7ISwarDuRdTOP5zD8aAvEyVHzDUCut/kUDn1Fj7DEpoD/
9JVWRBNMhmpZ7oTYD1olktB6yci8nHZDJIQL16d8OJ8BDRhD+80X6ECpbNSULALC
uFdgUSEdiA7raBrzH9+ahhfyMwu6powhPvP8kXJQ6eRG4AZQrOwwIOkp26mUlnej
P4kgKTtovrrWHJVNofkRbUiQoSacxVZnSuGgFboUP8+l5JK2eJ6XwOweG7mbp2Yv
md/AA+VgzHAZF9oIeWpaPcKdlPOEfw==
=m9xB
-----END PGP SIGNATURE-----

--wxpibp5tboksjfbf--




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: Adding Florian as a committer
Resent-From: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Thu, 19 Sep 2019 11:43:02 +0000
Resent-Message-ID: <handler.26302.B26302.156889334313515 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: "pelzflorian \(Florian Pelz\)" <pelzflorian@HIDDEN>
Cc: Mark H Weaver <mhw@HIDDEN>, GNU Guix maintainers <guix-maintainers@HIDDEN>, 26302 <at> debbugs.gnu.org
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.156889334313515
          (code B ref 26302); Thu, 19 Sep 2019 11:43:02 +0000
Received: (at 26302) by debbugs.gnu.org; 19 Sep 2019 11:42:23 +0000
Received: from localhost ([127.0.0.1]:55227 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1iAupK-0003Vv-Vz
	for submit <at> debbugs.gnu.org; Thu, 19 Sep 2019 07:42:23 -0400
Received: from eggs.gnu.org ([209.51.188.92]:52673)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <ludo@HIDDEN>) id 1iAupJ-0003Vg-FS
 for 26302 <at> debbugs.gnu.org; Thu, 19 Sep 2019 07:42:21 -0400
Received: from fencepost.gnu.org ([2001:470:142:3::e]:49394)
 by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from <ludo@HIDDEN>)
 id 1iAupD-0003dZ-SK; Thu, 19 Sep 2019 07:42:15 -0400
Received: from [2001:660:6102:320:e120:2c8f:8909:cdfe] (port=33498 helo=ribbon)
 by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256)
 (Exim 4.82) (envelope-from <ludo@HIDDEN>)
 id 1iAupD-0004Ve-0b; Thu, 19 Sep 2019 07:42:15 -0400
From: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
References: <20170329154040.ddscahwp2agknihb@abyayala>
 <8760e8l3bd.fsf@HIDDEN> <20170731215448.6zsu2qcfykuzbcd2@abyayala>
 <20190906142548.4crfjgvxilgalgrs@HIDDEN>
 <87ef0daeqs.fsf@HIDDEN>
 <20190919074829.hu3c7yy3bmeudfsw@HIDDEN>
X-URL: http://www.fdn.fr/~lcourtes/
X-Revolutionary-Date: Jour du Travail de =?UTF-8?Q?l'Ann=C3=A9e?= 227 de la
 =?UTF-8?Q?R=C3=A9volution?=
X-PGP-Key-ID: 0x090B11993D9AEBB5
X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc
X-PGP-Fingerprint: 3CE4 6455 8A84 FDC6 9DB4  0CFB 090B 1199 3D9A EBB5
X-OS: x86_64-pc-linux-gnu
Date: Thu, 19 Sep 2019 13:42:11 +0200
In-Reply-To: <20190919074829.hu3c7yy3bmeudfsw@HIDDEN>
 (pelzflorian@HIDDEN's message of "Thu, 19 Sep 2019 07:48:29
 +0000")
Message-ID: <87zhj03430.fsf_-_@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: multipart/signed; boundary="=-=-=";
 micalg=pgp-sha256; protocol="application/pgp-signature"
X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]
X-Spam-Score: -2.3 (--)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -3.3 (---)

--=-=-=
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Hi Florian,

"pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN> skribis:

> On Wed, Sep 18, 2019 at 03:57:47PM +0200, Ludovic Court=C3=A8s wrote:
>> Hi Florian,
>>=20
>> Could you create an account on Savannah so we can give you commit
>> access?
>>=20
>
> Done.  My username is pelzflorian.

I=E2=80=99ve added you now.  I assume you=E2=80=99ll be signing commits wit=
h key
CEF4CB914856BA380A20A7E2300888CB39C63817.  (You may want to set an
expiration date on the key, and to periodically update the expiration
date and re-upload the key.)

Please make sure to read =E2=80=98HACKING=E2=80=99 regarding the convention=
s and rules
that apply.

Thank you for your work, and welcome aboard!  :-)

Ludo=E2=80=99.

--=-=-=
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEEPORkVYqE/cadtAz7CQsRmT2a67UFAl2DaZMACgkQCQsRmT2a
67VTHRAAmSzpBpKU5Xp2WbyFL7p/NQxnvaD2xnLq41YueoHYyuHpiBFXWr4rRVwG
vu/q8Hf6f/YBMKp4zjA9cQWUe1L9rssxTXfDLcv4NYRpIcQwh4+OrsJVcKqbZFC6
KwWQkHv1SQQ5jtSQEVMUo3tUoViCqGC2VkXZHAOfrwb+k9dp7gy9pqB8vNbjwj26
RQUw/oAx7pmFdIUBk2qQ4GtLTn9DRIxA9Hg8y72GCCpbgpBErcVQc4TcXwpTNHT7
bokTL7v8LD42KD70xvYkSYIXhtY95Rhh4/u2/uSbn4Uq/emsbei30WQEogKHznnX
G7Gnxpcp4YvtHHqjsz5LP0jVJJNNCQvTDHe7KB1/hiVf/oiZKUhVnUYL59Fy519q
2sfKZLaoAJA9+/BsiWNsh8iDvOW1n0cFgMd1SIkg4iNJSwwRKi7vPbiZmDo8tJih
ktXYziOm/if4gl84Uvf1jSM/0TdULpsliuna1d59yn/CEDB1XF7IYF6UtSgj+OZZ
aw77Fmj7/kYzH2Jsel+f8hPIuATBzBMBsUQUEPOTJ45IZ0KI3LfUM0++I48H0ZJx
zU4EPsHLXLG550Zd8UIWYkTx/a7Do9Bx6G3J0jfYFGtRkWKHcEmxZmA0njmNmZV3
TDLRSjKRFDeXa9k7pY1cfJchyfQOMhxhUcenR1whF+Mg0gpJSvA=
=o1xL
-----END PGP SIGNATURE-----
--=-=-=--




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Thu, 19 Sep 2019 11:51:01 +0000
Resent-Message-ID: <handler.26302.B26302.156889382114321 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: "pelzflorian \(Florian Pelz\)" <pelzflorian@HIDDEN>
Cc: Mark H Weaver <mhw@HIDDEN>, 26302 <at> debbugs.gnu.org
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.156889382114321
          (code B ref 26302); Thu, 19 Sep 2019 11:51:01 +0000
Received: (at 26302) by debbugs.gnu.org; 19 Sep 2019 11:50:21 +0000
Received: from localhost ([127.0.0.1]:55231 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1iAux2-0003iv-RI
	for submit <at> debbugs.gnu.org; Thu, 19 Sep 2019 07:50:21 -0400
Received: from eggs.gnu.org ([209.51.188.92]:53126)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <ludo@HIDDEN>) id 1iAux1-0003ii-RP
 for 26302 <at> debbugs.gnu.org; Thu, 19 Sep 2019 07:50:20 -0400
Received: from fencepost.gnu.org ([2001:470:142:3::e]:49422)
 by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from <ludo@HIDDEN>)
 id 1iAuww-0006cl-Lb; Thu, 19 Sep 2019 07:50:14 -0400
Received: from [2001:660:6102:320:e120:2c8f:8909:cdfe] (port=33502 helo=ribbon)
 by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256)
 (Exim 4.82) (envelope-from <ludo@HIDDEN>)
 id 1iAuwv-0004xz-Q7; Thu, 19 Sep 2019 07:50:14 -0400
From: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
References: <20170329154040.ddscahwp2agknihb@abyayala>
 <8760e8l3bd.fsf@HIDDEN> <20170731215448.6zsu2qcfykuzbcd2@abyayala>
 <20190906142548.4crfjgvxilgalgrs@HIDDEN>
 <87ef0daeqs.fsf@HIDDEN>
 <20190919074829.hu3c7yy3bmeudfsw@HIDDEN>
X-URL: http://www.fdn.fr/~lcourtes/
X-Revolutionary-Date: Jour du Travail de =?UTF-8?Q?l'Ann=C3=A9e?= 227 de la
 =?UTF-8?Q?R=C3=A9volution?=
X-PGP-Key-ID: 0x090B11993D9AEBB5
X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc
X-PGP-Fingerprint: 3CE4 6455 8A84 FDC6 9DB4  0CFB 090B 1199 3D9A EBB5
X-OS: x86_64-pc-linux-gnu
Date: Thu, 19 Sep 2019 13:50:10 +0200
In-Reply-To: <20190919074829.hu3c7yy3bmeudfsw@HIDDEN>
 (pelzflorian@HIDDEN's message of "Thu, 19 Sep 2019 07:48:29
 +0000")
Message-ID: <87muf033pp.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]
X-Spam-Score: -2.3 (--)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -3.3 (---)

Hi,

"pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN> skribis:

>> > +(define (sgettext x)
>> > +  "After choosing an identifier for marking s-expressions for
>> > +translation, make it usable by defining a macro with it calling
>> > +sgettext.  If for example the chosen identifier is G_,
>> > +use (define-syntax G_ sgettext)."
>> > +  (syntax-case x ()
>> > +    ((id exp)
>> > +     (let* ((msgid (sexp->msgid (syntax->datum #'exp)))
>> > +            (new-exp (deconstruct (syntax->datum #'exp)
>> > +                                  (gettext msgid))))
>> > +       (datum->syntax #'id new-exp)))))
>>=20
>> For this and other similar macros you must use =E2=80=98define-syntax=E2=
=80=99, not
>> =E2=80=98define=E2=80=99, so that they are defined at expansion time, no=
t at run time.
>
> As per the above docstring, I already have a definition
>
>   (define-syntax G_ sgettext)
>
> in (apps i18n).  Possibly I should just move it here.

Hmmm right.  It works, but it=E2=80=99s surprising and =E2=80=9Cborderline=
=E2=80=9D.

If all you want is an alias, I=E2=80=99d recommend writing, say:

  (define-syntax sgettext =E2=80=A6)
  (define-syntax G_
    (identifier-syntax sgettext))

>> (It doesn=E2=80=99t make any difference when you=E2=80=99re evaluating c=
ode since both
>> phases run in the same module, but it does make a difference when these
>> phases happen at different times, in different processes.)
>>=20
>> Consequently, you must arrange for =E2=80=98sexp->msgid=E2=80=99 and =E2=
=80=98deconstruct=E2=80=99 to be
>> available at expansion time too.  This can be done by wrapping their
>> definition in =E2=80=98eval-when=E2=80=99:
>>=20
>>   (eval-when (load expand eval)
>>     (define (sexp->msgid =E2=80=A6) =E2=80=A6)
>>     (define (deconstruct =E2=80=A6) =E2=80=A6))
>>=20
>> But actually it=E2=80=99s not clear to me why these are macros.  I think=
 they
>> could be regular procedures and it=E2=80=99d work just fine, no?
>>=20
>
> I do not understand.  sexp->msgid and deconstruct are procedures, not
> syntax transformers.  I can add eval-when, but the current code runs
> as expected for me.

I tried to explain above but you can check the Guile manual on
=E2=80=98eval-when=E2=80=99 (info "(guile) Eval When").  The example there =
hopefully
clarifies what the problem is.

>> > +(define %plural-numbers
>> > +  ;; Hard-coded list of input numbers such that for each language=E2=
=80=99s
>> > +  ;; plural formula, for each possible output grammatical number,
>> > +  ;; there is an n among %plural-numbers that yields this output
>> > +  ;; (cf. section Plural forms in the gettext manual), except 1 is
>> > +  ;; omitted from this list because it is a special case for
>> > +  ;; sngettext.  That is, calling ngettext with each number from
>> > +  ;; %plural-numbers and with 1 in any locale is guaranteed to return
>> > +  ;; each plural form at least once.  It would be more resilient
>> > +  ;; towards new languages if instead of hard-coding we computed this
>> > +  ;; from the Plural-Forms in the MO file header entry, but that is
>> > +  ;; not worth the incurred code complexity.
>> > +  '(0 2 3 11 100))
>>=20
>> I don=E2=80=99t understand this: are these the only plural numbers in all
>> languages, or=E2=80=A6?
>>=20
>
> Yes, in all languages for which a plural=3D formula is documented in the
> gettext manual.
>
> For example, Arabic has
>
>           Plural-Forms: nplurals=3D6; \
>               plural=3Dn=3D=3D0 ? 0 : n=3D=3D1 ? 1 : n=3D=3D2 ? 2 : n%100=
>=3D3 && n%100<=3D10 ? 3 \
>               : n%100>=3D11 ? 4 : 5;
>
> with input plural numbers 0, 1, 2, 3, 11, 100 mapping to all outputs
> 0, 1, 2, 3, 4, 5.
>
> Maybe I should add this example to the code comment.

Oh I see.  Maybe just link to the relevant section of the manual ("info
(gettext) Plural forms").

I think you can go ahead and push this series to a branch, say
=E2=80=98wip-i18n=E2=80=99 (the =E2=80=98wip-=E2=80=99 prefix meaning that =
you reserve the right to
rebase the branch as you will.)

We can then maybe set up a =E2=80=98static-web-site=E2=80=99 service on ber=
lin, with
appropriate nginx rules, to build and publish the manual at a separate
URL so we can all test it.  See hydra/berlin.scm in maintenance.git.

Thoughts?

Thank you!

Ludo=E2=80=99.




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Thu, 19 Sep 2019 22:09:02 +0000
Resent-Message-ID: <handler.26302.B26302.15689309148589 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Cc: Mark H Weaver <mhw@HIDDEN>, 26302 <at> debbugs.gnu.org
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.15689309148589
          (code B ref 26302); Thu, 19 Sep 2019 22:09:02 +0000
Received: (at 26302) by debbugs.gnu.org; 19 Sep 2019 22:08:34 +0000
Received: from localhost ([127.0.0.1]:56549 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1iB4bJ-0002ET-SY
	for submit <at> debbugs.gnu.org; Thu, 19 Sep 2019 18:08:34 -0400
Received: from pelzflorian.de ([5.45.111.108]:42386 helo=mail.pelzflorian.de)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pelzflorian@HIDDEN>) id 1iB4bI-0002EL-7t
 for 26302 <at> debbugs.gnu.org; Thu, 19 Sep 2019 18:08:33 -0400
Received: from florianbeaglebone.fritz.box
 (ip5b42d6e2.dynamic.kabel-deutschland.de [91.66.214.226])
 by mail.pelzflorian.de (Postfix) with ESMTPSA id 7A4653602A4;
 Fri, 20 Sep 2019 00:08:30 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=pelzflorian.de;
 s=mail; t=1568930910;
 bh=AEnPf1k0FcSYj05xTR7KvDGRbukxNWQih6pEY661Ako=;
 h=Date:From:To:Cc:Subject:References:In-Reply-To;
 b=lWF2cQgMflGF0lnu8MNfJKRmJBh/vqxE+yyQSN2H5QleZ+BaWEvZ15ceGOc/EzQr2
 dbvOX/hzh/7Km2QcrLMCPJjbsP0XcEPJv69dnn0jXK3ogNd0G9d2NiyqSO4wHo8upp
 48Gt5bkRvfSHO4Vko2xhns5yQxOQXKcngJkkAFdc=
Date: Thu, 19 Sep 2019 22:08:28 +0000
From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Message-ID: <20190919220828.voohijutgmi6sd3w@HIDDEN>
References: <20170329154040.ddscahwp2agknihb@abyayala> <8760e8l3bd.fsf@HIDDEN>
 <20170731215448.6zsu2qcfykuzbcd2@abyayala>
 <20190906142548.4crfjgvxilgalgrs@HIDDEN>
 <87ef0daeqs.fsf@HIDDEN>
 <20190919074829.hu3c7yy3bmeudfsw@HIDDEN>
 <87muf033pp.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: multipart/signed; micalg=pgp-sha256;
 protocol="application/pgp-signature"; boundary="gyhfxphw2bppya2p"
Content-Disposition: inline
In-Reply-To: <87muf033pp.fsf@HIDDEN>
User-Agent: NeoMutt/20180716
X-Spam-Score: 0.0 (/)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)


--gyhfxphw2bppya2p
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

The branch wip-i18n is pushed now.

On Thu, Sep 19, 2019 at 01:50:10PM +0200, Ludovic Court=C3=A8s wrote:
> Hi,
>=20
> "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN> skribis:
>=20
> >> > +(define (sgettext x)
> >> > +  "After choosing an identifier for marking s-expressions for
> >> > +translation, make it usable by defining a macro with it calling
> >> > +sgettext.  If for example the chosen identifier is G_,
> >> > +use (define-syntax G_ sgettext)."
> >> > +  (syntax-case x ()
> >> > +    ((id exp)
> >> > +     (let* ((msgid (sexp->msgid (syntax->datum #'exp)))
> >> > +            (new-exp (deconstruct (syntax->datum #'exp)
> >> > +                                  (gettext msgid))))
> >> > +       (datum->syntax #'id new-exp)))))
> >>=20
> >> For this and other similar macros you must use =E2=80=98define-syntax=
=E2=80=99, not
> >> =E2=80=98define=E2=80=99, so that they are defined at expansion time, =
not at run time.
> >
> > As per the above docstring, I already have a definition
> >
> >   (define-syntax G_ sgettext)
> >
> > in (apps i18n).  Possibly I should just move it here.
>=20
> Hmmm right.  It works, but it=E2=80=99s surprising and =E2=80=9Cborderlin=
e=E2=80=9D.
>=20
> If all you want is an alias,

Yes, an alias is what I wanted, like gettext.


> I=E2=80=99d recommend writing, say:
>=20
>   (define-syntax sgettext =E2=80=A6)
>   (define-syntax G_
>     (identifier-syntax sgettext))
>=20

This breaks the code, I think because the sgettext result gets
evaluated in a clean environment which lacks surrounding variables.
For example,

(let ((i 5) (G_ `("There are " ,i " apples"))))

fails to resolve i.

I have left this borderline code as it is.


> >> (It doesn=E2=80=99t make any difference when you=E2=80=99re evaluating=
 code since both
> >> phases run in the same module, but it does make a difference when these
> >> phases happen at different times, in different processes.)
> >>=20
> >> Consequently, you must arrange for =E2=80=98sexp->msgid=E2=80=99 and =
=E2=80=98deconstruct=E2=80=99 to be
> >> available at expansion time too.  This can be done by wrapping their
> >> definition in =E2=80=98eval-when=E2=80=99:
> >>=20
> >>   (eval-when (load expand eval)
> >>     (define (sexp->msgid =E2=80=A6) =E2=80=A6)
> >>     (define (deconstruct =E2=80=A6) =E2=80=A6))
> >>=20
> >> But actually it=E2=80=99s not clear to me why these are macros.  I thi=
nk they
> >> could be regular procedures and it=E2=80=99d work just fine, no?
> >>=20
> >
> > I do not understand.  sexp->msgid and deconstruct are procedures, not
> > syntax transformers.  I can add eval-when, but the current code runs
> > as expected for me.
>=20
> I tried to explain above but you can check the Guile manual on
> =E2=80=98eval-when=E2=80=99 (info "(guile) Eval When").  The example ther=
e hopefully
> clarifies what the problem is.
>

I had read that Guile manual section, but it is hard to understand
when eval-when is needed and when it is not needed, because the
manual=E2=80=99s negative example for wrong code runs just as fine for me as
the eval-when version, even when saved to a separate module.

I have not used eval-when for now.

> >> > +(define %plural-numbers
> >> > +  ;; Hard-coded list of input numbers such that for each language=
=E2=80=99s
> >> > +  ;; plural formula, for each possible output grammatical number,
> >> > +  ;; there is an n among %plural-numbers that yields this output
> >> > +  ;; (cf. section Plural forms in the gettext manual), except 1 is
> >> > +  ;; omitted from this list because it is a special case for
> >> > +  ;; sngettext.  That is, calling ngettext with each number from
> >> > +  ;; %plural-numbers and with 1 in any locale is guaranteed to retu=
rn
> >> > +  ;; each plural form at least once.  It would be more resilient
> >> > +  ;; towards new languages if instead of hard-coding we computed th=
is
> >> > +  ;; from the Plural-Forms in the MO file header entry, but that is
> >> > +  ;; not worth the incurred code complexity.
> >> > +  '(0 2 3 11 100))
> >>=20
> >> I don=E2=80=99t understand this: are these the only plural numbers in =
all
> >> languages, or=E2=80=A6?
> >>=20
> >
> > Yes, in all languages for which a plural=3D formula is documented in the
> > gettext manual.
> >
> > For example, Arabic has
> >
> >           Plural-Forms: nplurals=3D6; \
> >               plural=3Dn=3D=3D0 ? 0 : n=3D=3D1 ? 1 : n=3D=3D2 ? 2 : n%1=
00>=3D3 && n%100<=3D10 ? 3 \
> >               : n%100>=3D11 ? 4 : 5;
> >
> > with input plural numbers 0, 1, 2, 3, 11, 100 mapping to all outputs
> > 0, 1, 2, 3, 4, 5.
> >
> > Maybe I should add this example to the code comment.
>=20
> Oh I see.  Maybe just link to the relevant section of the manual ("info
> (gettext) Plural forms").
>

I made the reference more clear in the %plural-forms comment now.

> [=E2=80=A6]
> We can then maybe set up a =E2=80=98static-web-site=E2=80=99 service on b=
erlin, with
> appropriate nginx rules, to build and publish the manual at a separate
> URL so we can all test it.  See hydra/berlin.scm in maintenance.git.
>=20
> Thoughts?
>=20

I=E2=80=99ll leave this to you. :)

Regards,
Florian

--gyhfxphw2bppya2p
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQEzBAEBCAAdFiEEzvTLkUhWujgKIKfiMAiIyznGOBcFAl2D/FUACgkQMAiIyznG
OBfcEAf/dQDz/sQ3per0SfQ9/BbZtWX8zq2XPZzDCPQuIqOQki4gOZzi/181T8x9
1agtLzhgiJLW6NmLmHyOchYZO3MLKUBSgjcQOs6mD+wMwkc1o/rjaiKy+EuOUaVN
37T0yKrnM7dSMuRim+iRpREkZHf/q0/KcglbXaEQHm6O0Qpp8ikLORhQkPlSpe3o
nTJLSODcwkLOIkdhYx8sCLZf5Y46PYk7Rg26CM7ssG+0djQER0uEiye4D9Vno7nD
PfK707UAh97hdCnrQv2mgWYl3iOo7We+KIX30X3RExJY/tYgIKMMhmDb2ss2C9KF
5olG81ug7D9PbdtMG6xb51zO+pFsRw==
=Lmyr
-----END PGP SIGNATURE-----

--gyhfxphw2bppya2p--




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Mon, 07 Oct 2019 08:16:02 +0000
Resent-Message-ID: <handler.26302.B26302.157043611730101 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: sirgazil <sirgazil@HIDDEN>, Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Cc: 26302 <26302 <at> debbugs.gnu.org>
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.157043611730101
          (code B ref 26302); Mon, 07 Oct 2019 08:16:02 +0000
Received: (at 26302) by debbugs.gnu.org; 7 Oct 2019 08:15:17 +0000
Received: from localhost ([127.0.0.1]:47344 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1iHOAe-0007pF-F1
	for submit <at> debbugs.gnu.org; Mon, 07 Oct 2019 04:15:17 -0400
Received: from pelzflorian.de ([5.45.111.108]:45088 helo=mail.pelzflorian.de)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pelzflorian@HIDDEN>) id 1iHOAb-0007p4-BH
 for 26302 <at> debbugs.gnu.org; Mon, 07 Oct 2019 04:15:07 -0400
Received: from pelzflorian.localdomain (unknown [5.45.111.108])
 by mail.pelzflorian.de (Postfix) with ESMTPSA id 962993602A4;
 Mon,  7 Oct 2019 10:15:03 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=pelzflorian.de;
 s=mail; t=1570436103;
 bh=n3emTI3HGmhddHMPUNrRkRQTTrWUWf0bE6eDQt0rYpU=;
 h=Date:From:To:Cc:Subject:References:In-Reply-To;
 b=U3+/bmy1ZNo7WNfNBt5kHNrlRirzhWB9hpWIj2xZgYDS+poLxuin7q8sCUavZ22Oe
 WPpYcm6o7ULRgHaNMptmMe4+KWo4TaCcl9zrGUASJuvkXkj24FZtuOlQMKS/A5Bo4K
 MX5zC6uon4uxk42v26SCIxPnkxvWC0fZxvbWcSJo=
Date: Mon, 7 Oct 2019 10:15:03 +0200
From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Message-ID: <20191007081502.wog4q4wjptvhmejf@HIDDEN>
References: <20170329154040.ddscahwp2agknihb@abyayala>
 <16d07cb5a1d.ca69255821627.8144164908931126811@HIDDEN>
 <20190908171638.cna67eearj4rbn2k@HIDDEN>
 <16d18a5a9e8.12ab66c8254154.2756956535677606704@HIDDEN>
 <20190915201819.3yxm25fayvbxwdpl@HIDDEN>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="sdu57zujk3qaqzhp"
Content-Disposition: inline
Content-Transfer-Encoding: 8bit
In-Reply-To: <20190915201819.3yxm25fayvbxwdpl@HIDDEN>
User-Agent: NeoMutt/20180716
X-Spam-Score: 0.0 (/)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)


--sdu57zujk3qaqzhp
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: 8bit

On Sun, Sep 15, 2019 at 10:18:20PM +0200, pelzflorian (Florian Pelz) wrote:
> What’s missing is code for adding the nginx plugin
> 
> https://www.nginx.com/resources/wiki/modules/accept_language/
> 
> to Guix so it can be used on berlin.scm.  It seems to offer all that
> is required for redirecting existing URLs.
> 

Please review the attached patch to Guix that adds
nginx-mod-accept-language.  (This is not the upstream name; various
nginx modules use no consistent naming scheme for nginx modules.)  I
have put it in a separate module from (gnu packages web) due to an
import cycle with tar/(gnu packages base).  The second patch allows
using dynamic modules with the nginx service.

Using these patches, the attached slightly wrong patch to
guix/maintenance.git is meant to make the web server default to
serving the language configured in the browser when no language code
is specified in the URL, so old URLs remain functional.  (Redirects of
non-html URLs are wrong and nginx does not run with this config,
perhaps I should use rewrite instead of try_files.  I can try later
today.)

Nonetheless, href links on the website point to the localized pages on
purpose so if someone changes the language the change remains in
effect when following a link.

Some people on the internet (I forgot who) preferred having a cookie
store the preferred language.  That would make it possible to continue
using the old URLs in href links on the website.  However, I am not
sure how it would affect SEO.

On Thu, Sep 19, 2019 at 01:50:10PM +0200, Ludovic Courtès wrote:
> We can then maybe set up a ‘static-web-site’ service on berlin, with
> appropriate nginx rules, to build and publish the manual at a separate
> URL so we can all test it.  See hydra/berlin.scm in maintenance.git.
> 

I see you @Ludo added such a service, but I cannot reach it.  Perhaps
I am using the wrong URL.


Regards,
Florian

--sdu57zujk3qaqzhp
Content-Type: text/plain; charset=utf-8
Content-Disposition: attachment; filename="0001-wip-gnu-Add-ngx_http_accept_language_module.patch"
Content-Transfer-Encoding: 8bit

From 9ec69c888b978cb870a5873af8e327541fe4ef7a Mon Sep 17 00:00:00 2001
From: Florian Pelz <pelzflorian@HIDDEN>
Date: Sun, 6 Oct 2019 20:45:34 +0200
Subject: [PATCH 1/2] [wip] gnu: Add ngx_http_accept_language_module.

* gnu/packages/web-xyz.scm: New file.
* gnu/local.mk (GNU_SYSTEM_MODULES): Add package.
---
 gnu/local.mk             |   1 +
 gnu/packages/web-xyz.scm | 175 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 176 insertions(+)
 create mode 100644 gnu/packages/web-xyz.scm

diff --git a/gnu/local.mk b/gnu/local.mk
index 54ae09f619..96a6c0087a 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -497,6 +497,7 @@ GNU_SYSTEM_MODULES =				\
   %D%/packages/wdiff.scm			\
   %D%/packages/web.scm				\
   %D%/packages/web-browsers.scm			\
+  %D%/packages/web-xyz.scm			\
   %D%/packages/webkit.scm			\
   %D%/packages/wget.scm				\
   %D%/packages/wicd.scm				\
diff --git a/gnu/packages/web-xyz.scm b/gnu/packages/web-xyz.scm
new file mode 100644
index 0000000000..61e7f847a7
--- /dev/null
+++ b/gnu/packages/web-xyz.scm
@@ -0,0 +1,175 @@
+;;; GNU Guix --- Functional package management for GNU
+;;;; TODO should I really add copyright lines for people I copied from??
+;;; Copyright © 2014, 2015 Mark H Weaver <mhw@HIDDEN>
+;;; Copyright © 2016 Tobias Geerinckx-Rice <me@HIDDEN>
+;;; Copyright © 2017, 2018 Marius Bakke <mbakke@HIDDEN>
+
+;;; Copyright © 2019 Florian Pelz <pelzflorian@HIDDEN>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix 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 General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu packages web-xyz)
+  #:use-module (guix build-system gnu)
+  #:use-module (guix gexp)
+  #:use-module (guix git-download)
+  #:use-module ((guix licenses) #:prefix license:)
+  #:use-module (guix packages)
+  #:use-module (gnu packages base)
+  #:use-module (gnu packages compression)
+  #:use-module (gnu packages pcre)
+  #:use-module (gnu packages tls)
+  #:use-module (gnu packages web)
+  #:use-module (ice-9 match)
+  #:use-module ((srfi srfi-1) #:select (delete-duplicates)))
+
+(define-public nginx-mod-accept-language
+  (let ((commit "2f69842f83dac77f7d98b41a2b31b13b87aeaba7")
+        (revision "1"))
+    (package
+      (name "nginx-mod-accept-language")
+      (version (git-version "0.0.0" ;upstream has no version number
+                            revision commit))
+      (source
+       (origin
+         (method git-fetch)
+         (uri (git-reference
+               (url "https://github.com/giom/nginx_accept_language_module.git")
+               (commit commit)))
+         (file-name (git-file-name name version))
+         (sha256
+          (base32 "1hjysrl15kh5233w7apq298cc2bp4q1z5mvaqcka9pdl90m0vhbw"))
+         (modules '((guix build utils)
+                    (ice-9 popen)))
+         (snippet
+          #~(begin
+              ;; the nginx source code is part of the module’s source
+              (format #t "decompressing nginx source code~%")
+              (call-with-output-file "nginx.tar"
+                (lambda (out)
+                  (let ((pipe (open-pipe* OPEN_READ
+                                          #+(file-append gzip "/bin/gzip") "-cd"
+                                          #$(package-source nginx))))
+                    (dump-port pipe out)
+                    (unless (= (status:exit-val (close-pipe pipe)) 0)
+                      (error "gzip decompress failed")))))
+              (invoke #+(file-append tar "/bin/tar") "xvf" "nginx.tar"
+                      "--strip-components=1")
+              (delete-file "nginx.tar")
+              #t))))
+      (build-system gnu-build-system)
+      (inputs `(("openssl" ,openssl)
+                ("pcre" ,pcre)
+                ("zlib" ,zlib)))
+      (arguments
+       `(#:tests? #f                      ; no test target
+         #:make-flags (list "modules")
+         #:modules ((guix build utils)
+                    (guix build gnu-build-system)
+                    (ice-9 regex)
+                    (ice-9 textual-ports))
+         #:phases
+         (modify-phases %standard-phases
+           (add-after 'unpack 'convert-to-dynamic-module
+             (lambda _
+               (begin
+                 (with-atomic-file-replacement "config"
+                   (lambda (in out)
+                     ;; cf. https://www.nginx.com/resources/wiki/extending/new_config/
+                     (format out "ngx_module_type=HTTP~%")
+                     (format out "ngx_module_name=\
+ngx_http_accept_language_module~%")
+                     (let* ((str (get-string-all in))
+                            (rx (make-regexp
+                                 "NGX_ADDON_SRCS=\"\\$NGX_ADDON_SRCS (.*)\""))
+                            (m (regexp-exec rx str))
+                            (srcs (match:substring m 1)))
+                       (format out (string-append "ngx_module_srcs=\""
+                                                  srcs "\"~%")))
+                     (format out ". auto/module~%")
+                     (format out "ngx_addon_name=$ngx_module_name~%"))))))
+           (add-before 'configure 'patch-/bin/sh
+             (lambda _
+               (substitute* "auto/feature"
+                 (("/bin/sh") (which "sh")))
+               #t))
+           (replace 'configure
+             (lambda* (#:key outputs #:allow-other-keys)
+               (let ((flags
+                      (list ;; A copy of nginx’ flags follows, otherwise we
+                            ;; get a binary compatibility error.  FIXME: Code
+                            ;; duplication is bad.
+                       (string-append "--prefix=" (assoc-ref outputs "out"))
+                       "--with-http_ssl_module"
+                       "--with-http_v2_module"
+                       "--with-pcre-jit"
+                       "--with-debug"
+                       ;; Even when not cross-building, we pass the
+                       ;; --crossbuild option to avoid customizing for the
+                       ;; kernel version on the build machine.
+                       ,(let ((system "Linux")    ; uname -s
+                              (release "3.2.0")   ; uname -r
+                              ;; uname -m
+                              (machine (match (or (%current-target-system)
+                                                  (%current-system))
+                                         ("x86_64-linux"   "x86_64")
+                                         ("i686-linux"     "i686")
+                                         ("mips64el-linux" "mips64")
+                                         ;; Prevent errors when querying
+                                         ;; this package on unsupported
+                                         ;; platforms, e.g. when running
+                                         ;; "guix package --search="
+                                         (_                "UNSUPPORTED"))))
+                          (string-append "--crossbuild="
+                                         system ":" release ":" machine))
+                       ;; The following are the args decribed on
+                       ;; <https://www.nginx.com/blog/compiling-dynamic-modules-nginx-plus>.
+                       ;; Enabling --with-compat here and in the nginx package
+                       ;; would ensure binary compatibility even when using
+                       ;; different configure options from the main nginx
+                       ;; package.  This is not needed for Guix.
+                       ;; "--with-compat"
+                       "--add-dynamic-module=.")))
+                 (setenv "CC" "gcc")
+                 (format #t "environment variable `CC' set to `gcc'~%")
+                 (format #t "configure flags: ~s~%" flags)
+                 (apply invoke "./configure" flags)
+                 #t)))
+           (replace 'install
+             (lambda* (#:key outputs #:allow-other-keys)
+               (let* ((out (assoc-ref outputs "out"))
+                      (modules-dir (string-append out "/etc/nginx/modules"))
+                      (doc-dir (string-append
+                                out "/share/doc/nginx-mod-accept-language")))
+                 (mkdir-p modules-dir)
+                 (copy-file "objs/ngx_http_accept_language_module.so"
+                            (string-append
+                             modules-dir "/ngx_http_accept_language_module.so"))
+                 (mkdir-p doc-dir)
+                 (copy-file "README.textile"
+                            (string-append doc-dir "/README.textile"))
+                 #t))))))
+      (home-page
+       "https://www.nginx.com/resources/wiki/modules/accept_language/")
+      (synopsis "Nginx module for parsing the Accept-Language HTTP header")
+      (description
+       "Nginx module that parses the Accept-Language field in HTTP headers and
+chooses the most suitable locale for the user from the list of locales
+supported at your website.")
+      (license (delete-duplicates
+                (cons license:bsd-2 ;license of nginx-mod-accept-language
+                      (package-license nginx))))))) ;the module’s code is linked
+                                        ;statically with nginx, therefore
+                                        ;nginx’ licenses apply to its binary
-- 
2.23.0


--sdu57zujk3qaqzhp
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: attachment; filename="0002-services-Make-it-possible-to-include-dynamic-modules.patch"
Content-Transfer-Encoding: 8bit

From 7747a416feae7139c2b2661ffeb37f2eb03eb2f9 Mon Sep 17 00:00:00 2001
From: Florian Pelz <pelzflorian@HIDDEN>
Date: Sun, 6 Oct 2019 15:31:23 +0200
Subject: [PATCH 2/2] services: Make it possible to include dynamic modules in
 nginx.

* gnu/services/web.scm (<nginx-configuration>): Add load-modules field.
(nginx-configuration-load-modules): New field accessor.
(emit-load-module): New procedure.
(default-nginx-config): Add support for the load-modules field.
* doc/guix.texi (NGINX): Document it.
---
 doc/guix.texi        | 4 ++++
 gnu/services/web.scm | 8 ++++++++
 2 files changed, 12 insertions(+)

diff --git a/doc/guix.texi b/doc/guix.texi
index 42d2d77ae6..5c39e26155 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -19718,6 +19718,10 @@ use the size of the processors cache line.
 @item @code{server-names-hash-bucket-max-size} (default: @code{#f})
 Maximum bucket size for the server names hash tables.
 
+@item @code{load-modules} (default: @code{'()})
+List of nginx dynamic modules to load.  Should be a list of strings or
+string valued G-expressions.
+
 @item @code{extra-content} (default: @code{""})
 Extra content for the @code{http} block.  Should be string or a string
 valued G-expression.
diff --git a/gnu/services/web.scm b/gnu/services/web.scm
index 899be1c168..a68f0235b7 100644
--- a/gnu/services/web.scm
+++ b/gnu/services/web.scm
@@ -9,6 +9,7 @@
 ;;; Copyright  2018 Pierre-Antoine Rouby <pierre-antoine.rouby@HIDDEN>
 ;;; Copyright  2017, 2018, 2019 Christopher Baines <mail@HIDDEN>
 ;;; Copyright  2018 Marius Bakke <mbakke@HIDDEN>
+;;; Copyright  2019 Florian Pelz <pelzflorian@HIDDEN>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -95,6 +96,7 @@
             nginx-configuration-upstream-blocks
             nginx-configuration-server-names-hash-bucket-size
             nginx-configuration-server-names-hash-bucket-max-size
+            nginx-configuration-load-modules
             nginx-configuration-extra-content
             nginx-configuration-file
 
@@ -522,6 +524,7 @@
                                  (default #f))
   (server-names-hash-bucket-max-size nginx-configuration-server-names-hash-bucket-max-size
                                      (default #f))
+  (load-modules nginx-configuration-load-modules (default '()))
   (extra-content nginx-configuration-extra-content
                  (default ""))
   (file          nginx-configuration-file         ;#f | string | file-like
@@ -542,6 +545,9 @@ of index files."
         ((? string? str) (list str " ")))
       names))
 
+(define (emit-load-module module)
+  (list "load_module " module ";\n"))
+
 (define emit-nginx-location-config
   (match-lambda
     (($ <nginx-location-configuration> uri body)
@@ -615,12 +621,14 @@ of index files."
                  server-blocks upstream-blocks
                  server-names-hash-bucket-size
                  server-names-hash-bucket-max-size
+                 load-modules
                  extra-content)
    (apply mixed-text-file "nginx.conf"
           (flatten
            "user nginx nginx;\n"
            "pid " run-directory "/pid;\n"
            "error_log " log-directory "/error.log info;\n"
+           (map emit-load-module load-modules)
            "http {\n"
            "    client_body_temp_path " run-directory "/client_body_temp;\n"
            "    proxy_temp_path " run-directory "/proxy_temp;\n"
-- 
2.23.0


--sdu57zujk3qaqzhp
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="0001-berlin-Redirect-to-localized-website-depending-on-Ac.patch"

From ea5edd15586722b3557912e81171e69f7be339fa Mon Sep 17 00:00:00 2001
From: Florian Pelz <pelzflorian@HIDDEN>
Date: Mon, 7 Oct 2019 07:58:30 +0200
Subject: [PATCH] berlin: Redirect to localized website depending on
 Accept-Language header.

* hydra/nginx/berlin.scm (guix.gnu.org-locations): Redirect html URLs.
(%nginx-configuration): Load required nginx dynamic module.
---
 hydra/nginx/berlin.scm | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/hydra/nginx/berlin.scm b/hydra/nginx/berlin.scm
index df90873..9085183 100644
--- a/hydra/nginx/berlin.scm
+++ b/hydra/nginx/berlin.scm
@@ -1,6 +1,7 @@
 ;; Nginx configuration for ci.guix.info
 
-(use-modules (gnu services web))
+(use-modules (gnu packages web-xyz)
+             (gnu services web))
 
 ;; TODO: these settings cannot currently expressed with Guix:
 
@@ -462,6 +463,16 @@ PUBLISH-URL."
    (nginx-location-configuration
     (uri "~ \\.pdf$")                             ;*.pdf at the top level
     (body (list "root /srv/guix-pdfs;")))
+   (nginx-location-configuration
+    (uri "~ (.*)/$")
+    (body (list
+           "try_files $1/index.html;")))
+   (nginx-location-configuration
+    (uri "~ (.html|.htm)$")
+    (body (list
+           ;; put en first so it is the default:
+           "set_from_accept_language $lang en de;"
+           "try_files /$lang/$uri $uri =404;")))
 
    (nginx-location-configuration                  ;certbot
     (uri "/.well-known")
@@ -758,5 +769,11 @@ PUBLISH-URL."
 (define %nginx-configuration
   (nginx-configuration
    (server-blocks %berlin-servers)
+   (load-modules
+    (list
+     ;; We need this module for redirecting users to the localized
+     ;; website of their choice.
+     (file-append nginx-mod-accept-language "\
+/etc/nginx/modules/ngx_http_accept_language_module.so")))
    (extra-content
     (string-join %extra-content "\n"))))
-- 
2.23.0


--sdu57zujk3qaqzhp--




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Tue, 08 Oct 2019 09:38:01 +0000
Resent-Message-ID: <handler.26302.B26302.157052745511500 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: sirgazil <sirgazil@HIDDEN>, Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Cc: 26302 <26302 <at> debbugs.gnu.org>
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.157052745511500
          (code B ref 26302); Tue, 08 Oct 2019 09:38:01 +0000
Received: (at 26302) by debbugs.gnu.org; 8 Oct 2019 09:37:35 +0000
Received: from localhost ([127.0.0.1]:49590 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1iHlvq-0002zH-A9
	for submit <at> debbugs.gnu.org; Tue, 08 Oct 2019 05:37:35 -0400
Received: from pelzflorian.de ([5.45.111.108]:46648 helo=mail.pelzflorian.de)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pelzflorian@HIDDEN>) id 1iHlvm-0002z6-2e
 for 26302 <at> debbugs.gnu.org; Tue, 08 Oct 2019 05:37:24 -0400
Received: from pelzflorian.localdomain (unknown [5.45.111.108])
 by mail.pelzflorian.de (Postfix) with ESMTPSA id 8352E3602A4;
 Tue,  8 Oct 2019 11:37:20 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=pelzflorian.de;
 s=mail; t=1570527440;
 bh=tH4w2p0v8eqazGUWVQ5OZ02rM9vrHJelG2MTR3w2M8A=;
 h=Date:From:To:Cc:Subject:References:In-Reply-To;
 b=ODmEPa7pOMXJTrwDJFT9TR0Rfl63Tr4tCwmt0s0a+sfoxQ+qL5IfR++FbXimK2330
 p/c4vZcTNWBNe1ELQUybdw82FaaZsudfbpOJarq5/9jAFWEcRBLxgEtEPuIxaN+qdq
 /Mmh3qmtVt5D65y516ho5NrooEhkPB9oCG4BxZow=
Date: Tue, 8 Oct 2019 11:37:19 +0200
From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Message-ID: <20191008093719.duvx26l2ods3fg75@HIDDEN>
References: <20170329154040.ddscahwp2agknihb@abyayala>
 <16d07cb5a1d.ca69255821627.8144164908931126811@HIDDEN>
 <20190908171638.cna67eearj4rbn2k@HIDDEN>
 <16d18a5a9e8.12ab66c8254154.2756956535677606704@HIDDEN>
 <20190915201819.3yxm25fayvbxwdpl@HIDDEN>
 <20191007081502.wog4q4wjptvhmejf@HIDDEN>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="t5yszdt4gakmziuy"
Content-Disposition: inline
In-Reply-To: <20191007081502.wog4q4wjptvhmejf@HIDDEN>
User-Agent: NeoMutt/20180716
X-Spam-Score: 0.0 (/)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)


--t5yszdt4gakmziuy
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Mon, Oct 07, 2019 at 10:15:03AM +0200, pelzflorian (Florian Pelz) wrote:
> (Redirects of
> non-html URLs are wrong and nginx does not run with this config,
> perhaps I should use rewrite instead of try_files.  I can try later
> today.)
>

I changed the patch and while nginx loads, redirects for files without
html suffix still fail.  I will stop and wait for smarter people with
more nginx experience.  Attached is the current patch and changes I
make to berlin for testing in a local VM using

GUILE_LOAD_PATH=$(readlink -f ~/git/maintenance/hydra/modules):$GUILE_LOAD_PATH guix system vm-image --image-size=14G berlin.scm --fallback

Regards,
Florian

--t5yszdt4gakmziuy
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="0001-berlin-Redirect-to-localized-website-depending-on-Ac.patch"

From ef1d268cd75219c18ef098389a8ea5ef460ee542 Mon Sep 17 00:00:00 2001
From: Florian Pelz <pelzflorian@HIDDEN>
Date: Tue, 8 Oct 2019 08:30:59 +0200
Subject: [PATCH] berlin: Redirect to localized website depending on
 Accept-Language header.

* hydra/nginx/berlin.scm (guix.gnu.org-locations): Redirect html URLs.
(%nginx-configuration): Load required nginx dynamic module.
---
 hydra/nginx/berlin.scm | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/hydra/nginx/berlin.scm b/hydra/nginx/berlin.scm
index df90873..c716103 100644
--- a/hydra/nginx/berlin.scm
+++ b/hydra/nginx/berlin.scm
@@ -1,6 +1,7 @@
 ;; Nginx configuration for ci.guix.info
 
-(use-modules (gnu services web))
+(use-modules (gnu packages web-xyz)
+             (gnu services web))
 
 ;; TODO: these settings cannot currently expressed with Guix:
 
@@ -462,6 +463,16 @@ PUBLISH-URL."
    (nginx-location-configuration
     (uri "~ \\.pdf$")                             ;*.pdf at the top level
     (body (list "root /srv/guix-pdfs;")))
+   (nginx-location-configuration
+    (uri "~ (.*)/$")
+    (body (list
+           "try_files $1/index.html =404;")))
+   (nginx-location-configuration
+    (uri "~ (.html|.htm)$")
+    (body (list
+           ;; put en first so it is the default:
+           "set_from_accept_language $lang en de;"
+           "try_files /$lang/$uri $uri =404;")))
 
    (nginx-location-configuration                  ;certbot
     (uri "/.well-known")
@@ -758,5 +769,11 @@ PUBLISH-URL."
 (define %nginx-configuration
   (nginx-configuration
    (server-blocks %berlin-servers)
+   (load-modules
+    (list
+     ;; We need this module for redirecting users to the localized
+     ;; website of their choice.
+     (file-append nginx-mod-accept-language "\
+/etc/nginx/modules/ngx_http_accept_language_module.so")))
    (extra-content
     (string-join %extra-content "\n"))))
-- 
2.23.0


--t5yszdt4gakmziuy
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="test-berlin-vm.patch"

diff --git a/hydra/berlin.scm b/hydra/berlin.scm
index 172c9cd..d965770 100644
--- a/hydra/berlin.scm
+++ b/hydra/berlin.scm
@@ -90,29 +90,29 @@ Happy hacking!\n"))
                  ;; The root file system resides on just a single
                  ;; disk, no RAID :-/
                  (file-system
-                   (device (file-system-label "my-root"))
+                   (device "/dev/sda");(file-system-label "my-root"))
                    (mount-point "/")
                    (type "ext4"))
-                 ;; This is a large external storage array
-                 ;; connected via 2 HBA cards.  We only mount it
-                 ;; through one of the HBA cards.  We would need
-                 ;; to use multipathd otherwise.
-                 (file-system
-                   (device (uuid "a6455b66-59d2-40bd-bddb-0c572bb62a2f"))
-                   (mount-point "/gnu")
-                   (type "ext4"))
-                 ;; Bind mount cache to large external storage.
-                 (file-system
-                   (device "/gnu/cache")
-                   (mount-point "/var/cache")
-                   (flags '(bind-mount))
-                   (type "none"))
-                 ;; Access root file system without bind mounts.
-                 (file-system
-                   (device "/")
-                   (mount-point "/mnt/root-fs")
-                   (flags '(bind-mount))
-                   (type "none"))
+                 ;; ;; This is a large external storage array
+                 ;; ;; connected via 2 HBA cards.  We only mount it
+                 ;; ;; through one of the HBA cards.  We would need
+                 ;; ;; to use multipathd otherwise.
+                 ;; (file-system
+                 ;;   (device (uuid "a6455b66-59d2-40bd-bddb-0c572bb62a2f"))
+                 ;;   (mount-point "/gnu")
+                 ;;   (type "ext4"))
+                 ;; ;; Bind mount cache to large external storage.
+                 ;; (file-system
+                 ;;   (device "/gnu/cache")
+                 ;;   (mount-point "/var/cache")
+                 ;;   (flags '(bind-mount))
+                 ;;   (type "none"))
+                 ;; ;; Access root file system without bind mounts.
+                 ;; (file-system
+                 ;;   (device "/")
+                 ;;   (mount-point "/mnt/root-fs")
+                 ;;   (flags '(bind-mount))
+                 ;;   (type "none"))
                  %base-file-systems))
 
   ;; Local admin account for MDC maintenance.
@@ -134,129 +134,118 @@ Happy hacking!\n"))
   (services (cons*
              ;; Connection to the DMZ for public access
              ;; This is a 1G port only
-             (static-networking-service "eno1"
-                                        "141.80.181.41"
-                                        #:netmask "255.255.255.0"
-                                        #:gateway "141.80.181.1")
-             ;; This is a 10G port.
-             (static-networking-service "enp129s0f0"
-                                        "141.80.181.40"
-                                        #:netmask "255.255.255.0")
-             ;; Connection to build nodes
-             (static-networking-service "eno3"
-                                        "141.80.167.131"
-                                        #:netmask "255.255.255.192")
-
-             ;; Allow login over serial console.
-             (agetty-service (agetty-configuration
-                              (tty "ttyS0")
-                              (baud-rate "115200")))
-
-             ;; DNS
-             (service knot-service-type
-                      (knot-configuration
-                        (zones (list (knot-zone-configuration
-                                       (domain "guix.gnu.org")
-                                       (master '("bayfront-master"))
-                                       (acl '("notify-allow")))))
-                        (acls (list (knot-acl-configuration
-                                      (id "notify-allow")
-                                      (address (list bayfront-ip4))
-                                      (action '(notify)))))
-                        (remotes (list (knot-remote-configuration
-                                         (id "bayfront-master")
-                                         (address (list bayfront-ip4)))))))
-
-             ;; Monitoring
-             (service zabbix-agent-service-type)
-             (service zabbix-server-service-type
-                      (zabbix-server-configuration
-                       (include-files '("/root/zabbix-pass"))))
-             (service zabbix-front-end-service-type
-                      (zabbix-front-end-configuration
-                       (nginx (list
-                               (nginx-server-configuration
-                                (root #~(string-append #$zabbix-server:front-end "/share/zabbix/php"))
-                                (listen '("127.0.0.1:7878"))
-                                (index '("index.php"))
-                                (locations
-                                 (let ((php-location (nginx-php-location)))
-                                   (list (nginx-location-configuration
-                                          (inherit php-location)
-                                          (body (append (nginx-location-configuration-body php-location)
-                                                        (list "
-fastcgi_param PHP_VALUE \"post_max_size = 16M
-                          max_execution_time = 300\";
-"))))))))))
-                       (db-secret-file "/root/zabbix-front-end-secrets")))
-
-             ;; For the Zabbix database.  It was created by manually
-             ;; following the instructions here:
-             ;; https://www.zabbix.com/documentation/3.0/manual/appendix/install/db_scripts
-             (postgresql-service)
+             (service dhcp-client-service-type)
+;; 
+;;              ;; Allow login over serial console.
+;;              (agetty-service (agetty-configuration
+;;                               (tty "ttyS0")
+;;                               (baud-rate "115200")))
+;; 
+;;              ;; DNS
+;;              (service knot-service-type
+;;                       (knot-configuration
+;;                         (zones (list (knot-zone-configuration
+;;                                        (domain "guix.gnu.org")
+;;                                        (master '("bayfront-master"))
+;;                                        (acl '("notify-allow")))))
+;;                         (acls (list (knot-acl-configuration
+;;                                       (id "notify-allow")
+;;                                       (address (list bayfront-ip4))
+;;                                       (action '(notify)))))
+;;                         (remotes (list (knot-remote-configuration
+;;                                          (id "bayfront-master")
+;;                                          (address (list bayfront-ip4)))))))
+;; 
+;;              ;; Monitoring
+;;              (service zabbix-agent-service-type)
+;;              (service zabbix-server-service-type
+;;                       (zabbix-server-configuration
+;;                        (include-files '("/root/zabbix-pass"))))
+;;              (service zabbix-front-end-service-type
+;;                       (zabbix-front-end-configuration
+;;                        (nginx (list
+;;                                (nginx-server-configuration
+;;                                 (root #~(string-append #$zabbix-server:front-end "/share/zabbix/php"))
+;;                                 (listen '("127.0.0.1:7878"))
+;;                                 (index '("index.php"))
+;;                                 (locations
+;;                                  (let ((php-location (nginx-php-location)))
+;;                                    (list (nginx-location-configuration
+;;                                           (inherit php-location)
+;;                                           (body (append (nginx-location-configuration-body php-location)
+;;                                                         (list "
+;; fastcgi_param PHP_VALUE \"post_max_size = 16M
+;;                           max_execution_time = 300\";
+;; "))))))))))
+;;                        (db-secret-file "/root/zabbix-front-end-secrets")))
+;; 
+;;              ;; For the Zabbix database.  It was created by manually
+;;              ;; following the instructions here:
+;;              ;; https://www.zabbix.com/documentation/3.0/manual/appendix/install/db_scripts
+;;              (postgresql-service)
 
              (service ntp-service-type)
 
-             ;; Make SSH and HTTP/HTTPS available over Tor.
-             (tor-hidden-service "http"
-                                 '((22 "127.0.0.1:22")
-                                   (80 "127.0.0.1:80")
-                                   (443 "127.0.0.1:443")))
-             (service tor-service-type)
-
+             ;; ;; Make SSH and HTTP/HTTPS available over Tor.
+             ;; (tor-hidden-service "http"
+             ;;                     '((22 "127.0.0.1:22")
+             ;;                       (80 "127.0.0.1:80")
+             ;;                       (443 "127.0.0.1:443")))
+             ;; (service tor-service-type)
+            ;; 
              (service nginx-service-type %nginx-configuration)
 
              ;; Runnning guix.gnu.org.
              (service static-web-site-service-type
                       (static-web-site-configuration
                        (git-url
-                        "https://git.savannah.gnu.org/git/guix/guix-artwork.git")
+                        "git://pelzflorian.de/guix-artwork.git")
                        (directory "/srv/guix.gnu.org")
                        (build-file "website/.guix.scm")))
 
-             ;; 'wip-i18n' branch of guix.gnu.org.
-             (service static-web-site-service-type
-                      (static-web-site-configuration
-                       (git-url
-                        "https://git.savannah.gnu.org/git/guix/guix-artwork.git")
-                       (git-ref '(branch . "wip-i18n"))
-                       (directory "/srv/guix.gnu.org-i18n")
-                       (build-file "website/.guix.scm")
-                       (cache-directory "guix.gnu.org-i18n") ;avoid collision
-                       (environment-variables
-                        '(("GUIX_WEB_SITE_ROOT_PATH" . "/.i18n")))))
-
-             ;; Manual for the latest stable release.
-             (service static-web-site-service-type
-                      (static-web-site-configuration
-                       (git-url "https://git.savannah.gnu.org/git/guix.git")
-                       (git-ref '(branch . "version-1.0.1"))
-                       (directory "/srv/guix-manual")
-                       (build-file "doc/build.scm")
-                       (environment-variables
-                         '(("GUIX_MANUAL_VERSION" . "1.0.1")
-                           ("GUIX_WEB_SITE_URL" . "/")))))
-
-             ;; Manual for 'master'.
-             (service static-web-site-service-type
-                      (static-web-site-configuration
-                       (git-url "https://git.savannah.gnu.org/git/guix.git")
-                       (directory "/srv/guix-manual-devel")
-
-                       ;; XXX: Use a different cache directory to work around
-                       ;; the fact that (guix git) would use a same-named
-                       ;; checkout directory for 'master' and for the branch
-                       ;; above.  Since both mcron jobs run at the same time,
-                       ;; they would end up using one branch or the other, in
-                       ;; a non-deterministic way.
-                       (cache-directory "guix-master-manual")
-
-                       (build-file "doc/build.scm")
-                       (environment-variables
-                        '(("GUIX_WEB_SITE_URL" . "/")))))
-
-             ;; GWL web site.
-             (service gwl-web-service-type)
+             ;; ;; 'wip-i18n' branch of guix.gnu.org.
+             ;; (service static-web-site-service-type
+             ;;          (static-web-site-configuration
+             ;;           (git-url
+             ;;            "https://git.savannah.gnu.org/git/guix/guix-artwork.git")
+             ;;           (git-ref '(branch . "wip-i18n"))
+             ;;           (directory "/srv/guix.gnu.org-i18n")
+             ;;           (build-file "website/.guix.scm")
+             ;;           (cache-directory "guix.gnu.org-i18n") ;avoid collision
+             ;;           (environment-variables
+             ;;            '(("GUIX_WEB_SITE_ROOT_PATH" . "/.i18n")))))
+            ;; 
+             ;; ;; Manual for the latest stable release.
+             ;; (service static-web-site-service-type
+             ;;          (static-web-site-configuration
+             ;;           (git-url "https://git.savannah.gnu.org/git/guix.git")
+             ;;           (git-ref '(branch . "version-1.0.1"))
+             ;;           (directory "/srv/guix-manual")
+             ;;           (build-file "doc/build.scm")
+             ;;           (environment-variables
+             ;;             '(("GUIX_MANUAL_VERSION" . "1.0.1")
+             ;;               ("GUIX_WEB_SITE_URL" . "/")))))
+            ;; 
+             ;; ;; Manual for 'master'.
+             ;; (service static-web-site-service-type
+             ;;          (static-web-site-configuration
+             ;;           (git-url "https://git.savannah.gnu.org/git/guix.git")
+             ;;           (directory "/srv/guix-manual-devel")
+            ;; 
+             ;;           ;; XXX: Use a different cache directory to work around
+             ;;           ;; the fact that (guix git) would use a same-named
+             ;;           ;; checkout directory for 'master' and for the branch
+             ;;           ;; above.  Since both mcron jobs run at the same time,
+             ;;           ;; they would end up using one branch or the other, in
+             ;;           ;; a non-deterministic way.
+             ;;           (cache-directory "guix-master-manual")
+            ;; 
+             ;;           (build-file "doc/build.scm")
+             ;;           (environment-variables
+             ;;            '(("GUIX_WEB_SITE_URL" . "/")))))
+            ;; 
+             ;; ;; GWL web site.
+             ;; (service gwl-web-service-type)
 
              (frontend-services %sysadmins
                                 #:systems '("x86_64-linux" "i686-linux"
diff --git a/hydra/modules/sysadmin/services.scm b/hydra/modules/sysadmin/services.scm
index 943df8a..a7c63bc 100644
--- a/hydra/modules/sysadmin/services.scm
+++ b/hydra/modules/sysadmin/services.scm
@@ -90,19 +90,19 @@
 (define* (guix-daemon-config #:key (max-jobs 5) (cores 4))
   (guix-configuration
    ;; Disable substitutes altogether.
-   (use-substitutes? #f)
-   (substitute-urls '())
-   (authorized-keys '())
-
-   ;; We don't want to let builds get stuck for too long, but we still want
-   ;; to allow building, say, Guile 2.2 on armhf-linux, which takes < 3h on
-   ;; an OverDrive 1000.
-   (max-silent-time 3600)
-   (timeout (* 6 3600))
-
-   (log-compression 'gzip)               ;be friendly to 'guix publish' users
-
-   (build-accounts (* 2 max-jobs))
+   ;; (use-substitutes? #f)
+   ;; (substitute-urls '())
+   ;; (authorized-keys '())
+  ;; 
+   ;; ;; We don't want to let builds get stuck for too long, but we still want
+   ;; ;; to allow building, say, Guile 2.2 on armhf-linux, which takes < 3h on
+   ;; ;; an OverDrive 1000.
+   ;; (max-silent-time 3600)
+   ;; (timeout (* 6 3600))
+  ;; 
+   ;; (log-compression 'gzip)               ;be friendly to 'guix publish' users
+  ;; 
+   ;; (build-accounts (* 2 max-jobs))
    (extra-options (list "--max-jobs" (number->string max-jobs)
                         "--cores" (number->string cores)
                         "--cache-failures"
@@ -261,27 +261,27 @@
                   (mcron-configuration
                    (jobs (cons %certbot-job %gc-jobs))))
 
-         firewall-service
-
-         ;; The Web service.
-         (service guix-publish-service-type
-                  (guix-publish-configuration
-                   (port 3000)
-                   (cache "/var/cache/guix/publish")
-                   (ttl nar-ttl)
-                   (compression '(("gzip" 9) ("lzip" 9)))
-                   (workers publish-workers)))
+         ;; firewall-service
+        ;; 
+         ;; ;; The Web service.
+         ;; (service guix-publish-service-type
+         ;;          (guix-publish-configuration
+         ;;           (port 3000)
+         ;;           (cache "/var/cache/guix/publish")
+         ;;           (ttl nar-ttl)
+         ;;           (compression '(("gzip" 9) ("lzip" 9)))
+         ;;           (workers publish-workers)))
 
          %nginx-mime-types
          %nginx-cache-activation
 
-         (service cuirass-service-type
-                  (cuirass-configuration
-                   (interval (* 5 60))
-                   (ttl (quotient nar-ttl 2))
-                   (specifications (cuirass-specs systems))))
-
-         (service openssh-service-type)
+         ;; (service cuirass-service-type
+         ;;          (cuirass-configuration
+         ;;           (interval (* 5 60))
+         ;;           (ttl (quotient nar-ttl 2))
+         ;;           (specifications (cuirass-specs systems))))
+        ;; 
+         ;; (service openssh-service-type)
          (service sysadmin-service-type sysadmins)
 
          (append (if nginx-config-file
@@ -290,9 +290,9 @@
                                      (file nginx-config-file))))
                      '())
                  (modify-services %base-services
-                   (guix-service-type
-                    config => (guix-daemon-config #:max-jobs max-jobs
-                                                  #:cores cores))
+                   ;; (guix-service-type
+                   ;;  config => (guix-daemon-config #:max-jobs max-jobs
+                   ;;                                #:cores cores))
                    (login-service-type
                     config => (login-configuration
                                (inherit config)
diff --git a/hydra/nginx/berlin.scm b/hydra/nginx/berlin.scm
index c716103..fa2d13b 100644
--- a/hydra/nginx/berlin.scm
+++ b/hydra/nginx/berlin.scm
@@ -491,27 +491,27 @@ PUBLISH-URL."
 (define %berlin-servers
   (list
    ;; Plain HTTP
-   (nginx-server-configuration
-    (listen '("80"))
-    (server-name '("berlin.guixsd.org"
-                   "ci.guix.info"
-                   "ci.guix.gnu.org"))
-    (locations (berlin-locations %publish-url))
-    (raw-content
-     (list
-      "access_log  /var/log/nginx/http.access.log;"
-      "proxy_set_header X-Forwarded-Host $host;"
-      "proxy_set_header X-Forwarded-Port $server_port;"
-      "proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;")))
-
-   (nginx-server-configuration
-    (listen '("80"))
-    (server-name '("bootstrappable.org"
-                   "www.bootstrappable.org"))
-    (root "/home/rekado/bootstrappable.org")
-    (raw-content
-     (list
-      "access_log /var/log/nginx/bootstrappable.access.log;")))
+   ;; (nginx-server-configuration
+   ;;  (listen '("80"))
+   ;;  (server-name '("berlin.guixsd.org"
+   ;;                 "ci.guix.info"
+   ;;                 "ci.guix.gnu.org"))
+   ;;  (locations (berlin-locations %publish-url))
+   ;;  (raw-content
+   ;;   (list
+   ;;    "access_log  /var/log/nginx/http.access.log;"
+   ;;    "proxy_set_header X-Forwarded-Host $host;"
+   ;;    "proxy_set_header X-Forwarded-Port $server_port;"
+   ;;    "proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;")))
+  ;; 
+   ;; (nginx-server-configuration
+   ;;  (listen '("80"))
+   ;;  (server-name '("bootstrappable.org"
+   ;;                 "www.bootstrappable.org"))
+   ;;  (root "/home/rekado/bootstrappable.org")
+   ;;  (raw-content
+   ;;   (list
+   ;;    "access_log /var/log/nginx/bootstrappable.access.log;")))
 
    (nginx-server-configuration
     (listen '("80"))
@@ -522,192 +522,194 @@ PUBLISH-URL."
      (list
       "access_log /var/log/nginx/guix-info.access.log;")))
 
-   (nginx-server-configuration
-    (listen '("80"))
-    (server-name '("guix.info"
-                   "www.guix.info"))
-    (locations guix.info-locations)
-    (raw-content
-     (append
-      %tls-settings
-      (list
-       "access_log /var/log/nginx/guix-info.https.access.log;"))))
-
-   (nginx-server-configuration
-    (listen '("80"))
-    (server-name '("issues.guix.info"
-                   "issues.guix.gnu.org"))
-    (root "/home/rekado/mumi/")
-    (locations
-     (list (nginx-location-configuration ;certbot
-            (uri "/.well-known")
-            (body (list "root /var/www;")))
-           (nginx-location-configuration
-            (uri "/")
-            (body '("proxy_pass http://localhost:1234;")))))
-    (raw-content
-     (list
-      "access_log /var/log/nginx/issues-guix-info.access.log;")))
-
-   (nginx-server-configuration
-    (listen '("80"))
-    (server-name '("workflows.guix.info"
-                   "workflow.guix.info"
-                   "guixwl.org"
-                   "www.guixwl.org"))
-    (root "/home/rekado/gwl/")
-    (locations
-     (list (nginx-location-configuration ;certbot
-            (uri "/.well-known")
-            (body (list "root /var/www;")))
-
-           ;; Pass requests to 'guix workflow --web-interface'.
-           (nginx-location-configuration
-            (uri "/")
-            (body '("proxy_pass http://localhost:5000;")))))
-    (raw-content
-     (list
-      "access_log /var/log/nginx/workflows-guix-info.access.log;")))
-        
-   ;; HTTPS servers
-   (nginx-server-configuration
-    (listen '("443 ssl"))
-    (server-name '("berlin.guixsd.org"
-                   "ci.guix.info"
-                   "ci.guix.gnu.org"))
-    (ssl-certificate (le "berlin.guixsd.org"))
-    (ssl-certificate-key (le "berlin.guixsd.org" 'key))
-    (locations (berlin-locations %publish-url))
-    (raw-content
-     (append
-      %tls-settings
-      (list
-       "access_log  /var/log/nginx/https.access.log;"
-       "proxy_set_header X-Forwarded-Host $host;"
-       "proxy_set_header X-Forwarded-Port $server_port;"
-       "proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;"))))
-
-   (nginx-server-configuration
-    (listen '("443 ssl"))
-    (server-name '("qualif.ci.guix.gnu.org"))
-    (locations (berlin-locations "http://localhost:3003"))
-    (raw-content
-     (append %tls-settings
-             '("access_log  /var/log/nginx/qualif.access.log;"))))
-
-   (nginx-server-configuration
-    (listen '("443 ssl"))
-    (server-name '("bootstrappable.org"
-                   "www.bootstrappable.org"))
-    (ssl-certificate (le "bootstrappable.org"))
-    (ssl-certificate-key (le "bootstrappable.org" 'key))
-    (root "/home/rekado/bootstrappable.org")
-    (raw-content
-     (append
-      %tls-settings
-      (list
-       "access_log /var/log/nginx/bootstrappable.https.access.log;"))))
-
-   (nginx-server-configuration
-    (listen '("443 ssl"))
-    (server-name '("guix.info"
-                   "www.guix.info"))
-    (ssl-certificate (le "guix.info"))
-    (ssl-certificate-key (le "guix.info" 'key))
-    (locations guix.info-locations)
-    (raw-content
-     (append
-      %tls-settings
-      (list
-       "access_log /var/log/nginx/guix-info.https.access.log;"))))
-
-   (nginx-server-configuration
-    (listen '("443 ssl"))
-    (server-name '("guix.gnu.org"))
-    (ssl-certificate (le "guix.gnu.org"))
-    (ssl-certificate-key (le "guix.gnu.org" 'key))
-    (root "/srv/guix.gnu.org")
-    (locations guix.gnu.org-locations)
-    (raw-content
-     (append
-      %tls-settings
-      (list
-       "access_log /var/log/nginx/guix-gnu-org.https.access.log;"))))
-
-   (nginx-server-configuration
-    (listen '("443 ssl"))
-    (server-name '("issues.guix.info"))
-    (ssl-certificate (le "issues.guix.info"))
-    (ssl-certificate-key (le "issues.guix.info" 'key))
-    (root "/home/rekado/mumi/")
-    (locations
-     (list (nginx-location-configuration
-            (uri "/")
-            (body '("proxy_pass http://localhost:1234;")))))
-    (raw-content
-     (append
-      %tls-settings
-      (list
-       "proxy_set_header X-Forwarded-Host $host;"
-       "proxy_set_header X-Forwarded-Port $server_port;"
-       "proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;"
-       "proxy_connect_timeout       600;"
-       "proxy_send_timeout          600;"
-       "proxy_read_timeout          600;"
-       "send_timeout                600;"
-       "access_log /var/log/nginx/issues-guix-info.https.access.log;"))))
-
-   (nginx-server-configuration
-    (listen '("443 ssl"))
-    (server-name '("issues.guix.gnu.org"))
-    (ssl-certificate (le "issues.guix.gnu.org"))
-    (ssl-certificate-key (le "issues.guix.gnu.org" 'key))
-    (root "/home/rekado/mumi/")
-    (locations
-     (list (nginx-location-configuration
-            (uri "/")
-            (body '("proxy_pass http://localhost:1234;")))))
-    (raw-content
-     (append
-      %tls-settings
-      (list
-       "proxy_set_header X-Forwarded-Host $host;"
-       "proxy_set_header X-Forwarded-Port $server_port;"
-       "proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;"
-       "proxy_connect_timeout       600;"
-       "proxy_send_timeout          600;"
-       "proxy_read_timeout          600;"
-       "send_timeout                600;"
-       "access_log /var/log/nginx/issues-guix-gnu-org.https.access.log;"))))
-
-   (nginx-server-configuration
-    (listen '("443 ssl"))
-    (server-name '("workflows.guix.info"
-                   "workflow.guix.info"
-                   "guixwl.org"
-                   "www.guixwl.org"))
-    (ssl-certificate (le "www.guixwl.org"))
-    (ssl-certificate-key (le "www.guixwl.org" 'key))
-    (root "/home/rekado/gwl/")
-    (locations
-     (list (nginx-location-configuration
-            (uri "/")
-            (body '("proxy_pass http://localhost:5000;")))))
-    (raw-content
-     (append
-      %tls-settings
-      (list
-       "proxy_set_header X-Forwarded-Host $host;"
-       "proxy_set_header X-Forwarded-Port $server_port;"
-       "proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;"
-       "proxy_connect_timeout       600;"
-       "proxy_send_timeout          600;"
-       "proxy_read_timeout          600;"
-       "send_timeout                600;"
-       "access_log /var/log/nginx/workflows-guix-info.https.access.log;"))))))
+   ;; (nginx-server-configuration
+   ;;  (listen '("80"))
+   ;;  (server-name '("guix.info"
+   ;;                 "www.guix.info"))
+   ;;  (locations guix.info-locations)
+   ;;  (raw-content
+   ;;   (append
+   ;;    %tls-settings
+   ;;    (list
+   ;;     "access_log /var/log/nginx/guix-info.https.access.log;"))))
+  ;; 
+   ;; (nginx-server-configuration
+   ;;  (listen '("80"))
+   ;;  (server-name '("issues.guix.info"
+   ;;                 "issues.guix.gnu.org"))
+   ;;  (root "/home/rekado/mumi/")
+   ;;  (locations
+   ;;   (list (nginx-location-configuration ;certbot
+   ;;          (uri "/.well-known")
+   ;;          (body (list "root /var/www;")))
+   ;;         (nginx-location-configuration
+   ;;          (uri "/")
+   ;;          (body '("proxy_pass http://localhost:1234;")))))
+   ;;  (raw-content
+   ;;   (list
+   ;;    "access_log /var/log/nginx/issues-guix-info.access.log;")))
+  ;; 
+   ;; (nginx-server-configuration
+   ;;  (listen '("80"))
+   ;;  (server-name '("workflows.guix.info"
+   ;;                 "workflow.guix.info"
+   ;;                 "guixwl.org"
+   ;;                 "www.guixwl.org"))
+   ;;  (root "/home/rekado/gwl/")
+   ;;  (locations
+   ;;   (list (nginx-location-configuration ;certbot
+   ;;          (uri "/.well-known")
+   ;;          (body (list "root /var/www;")))
+  ;; 
+   ;;         ;; Pass requests to 'guix workflow --web-interface'.
+   ;;         (nginx-location-configuration
+   ;;          (uri "/")
+   ;;          (body '("proxy_pass http://localhost:5000;")))))
+   ;;  (raw-content
+   ;;   (list
+   ;;    "access_log /var/log/nginx/workflows-guix-info.access.log;")))
+   ;;      
+   ;; ;; HTTPS servers
+   ;; (nginx-server-configuration
+   ;;  (listen '("80"))
+   ;;  (server-name '("berlin.guixsd.org"
+   ;;                 "ci.guix.info"
+   ;;                 "ci.guix.gnu.org"))
+   ;;  ;;(ssl-certificate (le "berlin.guixsd.org"))
+   ;;  ;;(ssl-certificate-key (le "berlin.guixsd.org" 'key))
+   ;;  (locations (berlin-locations %publish-url))
+   ;;  (raw-content
+   ;;   (append
+   ;;    %tls-settings
+   ;;    (list
+   ;;     "access_log  /var/log/nginx/https.access.log;"
+   ;;     "proxy_set_header X-Forwarded-Host $host;"
+   ;;     "proxy_set_header X-Forwarded-Port $server_port;"
+   ;;     "proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;"))))
+  ;; 
+   ;; (nginx-server-configuration
+   ;;  (listen '("80"))
+   ;;  (server-name '("qualif.ci.guix.gnu.org"))
+   ;;  (locations (berlin-locations "http://localhost:3003"))
+   ;;  (raw-content
+   ;;   (append %tls-settings
+   ;;           '("access_log  /var/log/nginx/qualif.access.log;"))))
+  ;; 
+   ;; (nginx-server-configuration
+   ;;  (listen '("80"))
+   ;;  (server-name '("bootstrappable.org"
+   ;;                 "www.bootstrappable.org"))
+   ;;  ;;(ssl-certificate (le "bootstrappable.org"))
+   ;;  ;;(ssl-certificate-key (le "bootstrappable.org" 'key))
+   ;;  (root "/home/rekado/bootstrappable.org")
+   ;;  (raw-content
+   ;;   (append
+   ;;    %tls-settings
+   ;;    (list
+   ;;     "access_log /var/log/nginx/bootstrappable.https.access.log;"))))
+  ;; 
+   ;; (nginx-server-configuration
+   ;;  (listen '("80"))
+   ;;  (server-name '("guix.info"
+   ;;                 "www.guix.info"))
+   ;;  ;;(ssl-certificate (le "guix.info"))
+   ;;  ;;(ssl-certificate-key (le "guix.info" 'key))
+   ;;  (locations guix.info-locations)
+   ;;  (raw-content
+   ;;   (append
+   ;;    %tls-settings
+   ;;    (list
+   ;;     "access_log /var/log/nginx/guix-info.https.access.log;"))))
+
+   ;; (nginx-server-configuration
+   ;;  (listen '("80"))
+   ;;  (server-name '("guix.gnu.org"))
+   ;;  ;;(ssl-certificate (le "guix.gnu.org"))
+   ;;  ;;(ssl-certificate-key (le "guix.gnu.org" 'key))
+   ;;  (root "/srv/guix.gnu.org")
+   ;;  (locations guix.gnu.org-locations)
+   ;;  (raw-content
+   ;;   (append
+   ;;    %tls-settings
+   ;;    (list
+   ;;     "access_log /var/log/nginx/guix-gnu-org.https.access.log;"))))
+  ;; 
+   ;; (nginx-server-configuration
+   ;;  (listen '("80"))
+   ;;  (server-name '("issues.guix.info"))
+   ;;  ;;(ssl-certificate (le "issues.guix.info"))
+   ;;  ;;(ssl-certificate-key (le "issues.guix.info" 'key))
+   ;;  (root "/home/rekado/mumi/")
+   ;;  (locations
+   ;;   (list (nginx-location-configuration
+   ;;          (uri "/")
+   ;;          (body '("proxy_pass http://localhost:1234;")))))
+   ;;  (raw-content
+   ;;   (append
+   ;;    %tls-settings
+   ;;    (list
+   ;;     "proxy_set_header X-Forwarded-Host $host;"
+   ;;     "proxy_set_header X-Forwarded-Port $server_port;"
+   ;;     "proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;"
+   ;;     "proxy_connect_timeout       600;"
+   ;;     "proxy_send_timeout          600;"
+   ;;     "proxy_read_timeout          600;"
+   ;;     "send_timeout                600;"
+   ;;     "access_log /var/log/nginx/issues-guix-info.https.access.log;"))))
+  ;; 
+   ;; (nginx-server-configuration
+   ;;  (listen '("80"))
+   ;;  (server-name '("issues.guix.gnu.org"))
+   ;;  ;;(ssl-certificate (le "issues.guix.gnu.org"))
+   ;;  ;;(ssl-certificate-key (le "issues.guix.gnu.org" 'key))
+   ;;  (root "/home/rekado/mumi/")
+   ;;  (locations
+   ;;   (list (nginx-location-configuration
+   ;;          (uri "/")
+   ;;          (body '("proxy_pass http://localhost:1234;")))))
+   ;;  (raw-content
+   ;;   (append
+   ;;    %tls-settings
+   ;;    (list
+   ;;     "proxy_set_header X-Forwarded-Host $host;"
+   ;;     "proxy_set_header X-Forwarded-Port $server_port;"
+   ;;     "proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;"
+   ;;     "proxy_connect_timeout       600;"
+   ;;     "proxy_send_timeout          600;"
+   ;;     "proxy_read_timeout          600;"
+   ;;     "send_timeout                600;"
+   ;;     "access_log /var/log/nginx/issues-guix-gnu-org.https.access.log;"))))
+  ;; 
+   ;; (nginx-server-configuration
+   ;;  (listen '("80"))
+   ;;  (server-name '("workflows.guix.info"
+   ;;                 "workflow.guix.info"
+   ;;                 "guixwl.org"
+   ;;                 "www.guixwl.org"))
+   ;;  ;;(ssl-certificate (le "www.guixwl.org"))
+   ;;  ;;(ssl-certificate-key (le "www.guixwl.org" 'key))
+   ;;  (root "/home/rekado/gwl/")
+   ;;  (locations
+   ;;   (list (nginx-location-configuration
+   ;;          (uri "/")
+   ;;          (body '("proxy_pass http://localhost:5000;")))))
+   ;;  (raw-content
+   ;;   (append
+   ;;    %tls-settings
+   ;;    (list
+   ;;     "proxy_set_header X-Forwarded-Host $host;"
+   ;;     "proxy_set_header X-Forwarded-Port $server_port;"
+   ;;     "proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;"
+   ;;     "proxy_connect_timeout       600;"
+   ;;     "proxy_send_timeout          600;"
+   ;;     "proxy_read_timeout          600;"
+   ;;     "send_timeout                600;"
+   ;;     "access_log /var/log/nginx/workflows-guix-info.https.access.log;"))))))
+   ))
 
 (define %extra-content
   (list
+      "server_names_hash_bucket_size  64;" ;hack does not belong here
    "default_type  application/octet-stream;"
    "sendfile        on;"
 

--t5yszdt4gakmziuy--




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Tue, 22 Oct 2019 12:12:01 +0000
Resent-Message-ID: <handler.26302.B26302.157174627021125 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: "pelzflorian \(Florian Pelz\)" <pelzflorian@HIDDEN>
Cc: Julien Lepiller <julien@HIDDEN>, sirgazil <sirgazil@HIDDEN>, 26302 <at> debbugs.gnu.org
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.157174627021125
          (code B ref 26302); Tue, 22 Oct 2019 12:12:01 +0000
Received: (at 26302) by debbugs.gnu.org; 22 Oct 2019 12:11:10 +0000
Received: from localhost ([127.0.0.1]:58320 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1iMt0I-0005Uf-8g
	for submit <at> debbugs.gnu.org; Tue, 22 Oct 2019 08:11:10 -0400
Received: from eggs.gnu.org ([209.51.188.92]:41623)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <ludo@HIDDEN>) id 1iMt0G-0005UQ-AC
 for 26302 <at> debbugs.gnu.org; Tue, 22 Oct 2019 08:11:08 -0400
Received: from fencepost.gnu.org ([2001:470:142:3::e]:55258)
 by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from <ludo@HIDDEN>)
 id 1iMt0A-0003YU-IC; Tue, 22 Oct 2019 08:11:02 -0400
Received: from [2001:660:6102:320:e120:2c8f:8909:cdfe] (port=39272 helo=ribbon)
 by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256)
 (Exim 4.82) (envelope-from <ludo@HIDDEN>)
 id 1iMt0A-0007uF-1k; Tue, 22 Oct 2019 08:11:02 -0400
From: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
References: <20170329154040.ddscahwp2agknihb@abyayala>
 <8760e8l3bd.fsf@HIDDEN> <20170731215448.6zsu2qcfykuzbcd2@abyayala>
 <20190906142548.4crfjgvxilgalgrs@HIDDEN>
 <87ef0daeqs.fsf@HIDDEN>
 <20190919074829.hu3c7yy3bmeudfsw@HIDDEN>
 <87muf033pp.fsf@HIDDEN>
Date: Tue, 22 Oct 2019 14:10:59 +0200
In-Reply-To: <87muf033pp.fsf@HIDDEN> ("Ludovic
 \=\?utf-8\?Q\?Court\=C3\=A8s\=22'\?\=
 \=\?utf-8\?Q\?s\?\= message of "Thu, 19 Sep 2019 13:50:10 +0200")
Message-ID: <87a79t56b0.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]
X-Spam-Score: -2.3 (--)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -3.3 (---)

Hello Florian and all!

(Cc: sirgazil + Julien.)

Ludovic Court=C3=A8s <ludo@HIDDEN> skribis:

> I think you can go ahead and push this series to a branch, say
> =E2=80=98wip-i18n=E2=80=99 (the =E2=80=98wip-=E2=80=99 prefix meaning tha=
t you reserve the right to
> rebase the branch as you will.)
>
> We can then maybe set up a =E2=80=98static-web-site=E2=80=99 service on b=
erlin, with
> appropriate nginx rules, to build and publish the manual at a separate
> URL so we can all test it.  See hydra/berlin.scm in maintenance.git.

Sorry that it=E2=80=99s taken this long, but I=E2=80=99m happy to say that =
the
=E2=80=98wip-i18n=E2=80=99 branch of the manual is now visible at:

  https://guix.gnu.org/.i18n/de/
  https://guix.gnu.org/.i18n/en/

Whenever you push to that branch, the web site should be automatically
updated within an hour.

In IceCat the navigation bar at the top with =E2=80=9Cradio buttons=E2=80=
=9D gets
incorrectly displayed for some reason.

We=E2=80=99ll need the nginx magic to honor =E2=80=98Accept-Language=E2=80=
=99 and such; I think
you submitted something that I may have overlooked, don=E2=80=99t hesitate =
to
refresh my mind.  :-)

Anyway, we have a good starting point, and perhaps we=E2=80=99ll be able to
switch quickly; what else do we need?


For the record, the changes to the config of berlin.guix.gnu.org to make
it possible were:

  https://git.savannah.gnu.org/cgit/guix/maintenance.git/commit/?id=3De86c6=
86b607a0f772ae004db021181607ba805ee

Thanks,
Ludo=E2=80=99.




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Tue, 22 Oct 2019 12:29:02 +0000
Resent-Message-ID: <handler.26302.B26302.157174732422709 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Cc: Julien Lepiller <julien@HIDDEN>, sirgazil <sirgazil@HIDDEN>, 26302 <at> debbugs.gnu.org
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.157174732422709
          (code B ref 26302); Tue, 22 Oct 2019 12:29:02 +0000
Received: (at 26302) by debbugs.gnu.org; 22 Oct 2019 12:28:44 +0000
Received: from localhost ([127.0.0.1]:58328 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1iMtHH-0005uC-Rx
	for submit <at> debbugs.gnu.org; Tue, 22 Oct 2019 08:28:44 -0400
Received: from pelzflorian.de ([5.45.111.108]:47496 helo=mail.pelzflorian.de)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pelzflorian@HIDDEN>) id 1iMtHF-0005u4-KX
 for 26302 <at> debbugs.gnu.org; Tue, 22 Oct 2019 08:28:42 -0400
Received: from pelzflorian.localdomain (unknown [5.45.111.108])
 by mail.pelzflorian.de (Postfix) with ESMTPSA id 501FE3604C5;
 Tue, 22 Oct 2019 14:28:40 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=pelzflorian.de;
 s=mail; t=1571747320;
 bh=TkXwUw5B3M9ADK0lKySXGqpz68O1kD8ZS7pN8ErUmuU=;
 h=Date:From:To:Cc:Subject:References:In-Reply-To;
 b=b/KNNCZWpm9dPNMKxNeAxZ1Mcfe0JIcQQu7Tqvgd2fzN67QS4KVUtB4Hz/sQ4dXvy
 J8tOBKGtKuj9IOkBHUGdVn+ilVKidoJu/U7Mzu6jpUWsCDjeKoNdN7ecNK+939o1yU
 XamKlG++FN5PmhBgQd0aXq0pB8TbC9yP18JwEJiY=
Date: Tue, 22 Oct 2019 14:28:40 +0200
From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Message-ID: <20191022122840.xwrrfvqm6t7uby6s@HIDDEN>
References: <20170329154040.ddscahwp2agknihb@abyayala> <8760e8l3bd.fsf@HIDDEN>
 <20170731215448.6zsu2qcfykuzbcd2@abyayala>
 <20190906142548.4crfjgvxilgalgrs@HIDDEN>
 <87ef0daeqs.fsf@HIDDEN>
 <20190919074829.hu3c7yy3bmeudfsw@HIDDEN>
 <87muf033pp.fsf@HIDDEN> <87a79t56b0.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: 8bit
In-Reply-To: <87a79t56b0.fsf@HIDDEN>
User-Agent: NeoMutt/20180716
X-Spam-Score: 0.0 (/)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

On Tue, Oct 22, 2019 at 02:10:59PM +0200, Ludovic Courtès wrote:
> Sorry that it’s taken this long, but I’m happy to say that the
> ‘wip-i18n’ branch of the manual is now visible at:
> 
>   https://guix.gnu.org/.i18n/de/
>   https://guix.gnu.org/.i18n/en/
> 

Thank you. :)


> Whenever you push to that branch, the web site should be automatically
> updated within an hour.
> 

I will rebase wip-i18n later this week and when the documentation
videos are decided.



> In IceCat the navigation bar at the top with “radio buttons” gets
> incorrectly displayed for some reason.
>

The CSS is not loaded from the .i18n subdirectory, it seems.


> We’ll need the nginx magic to honor ‘Accept-Language’ and such; I think
> you submitted something that I may have overlooked, don’t hesitate to
> refresh my mind.  :-)
>
> Anyway, we have a good starting point, and perhaps we’ll be able to
> switch quickly; what else do we need?
> 
> 


I would be happy if you could review my Guix patches at

https://lists.gnu.org/archive/html/bug-guix/2019-10/msg00068.html

After that I also sent maintenance patches, but redirection only works
for URLs ending in .html right now…


Regards,
Florian




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Tue, 22 Oct 2019 12:42:01 +0000
Resent-Message-ID: <handler.26302.B26302.157174809424012 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Cc: sirgazil <sirgazil@HIDDEN>, 26302 <at> debbugs.gnu.org
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.157174809424012
          (code B ref 26302); Tue, 22 Oct 2019 12:42:01 +0000
Received: (at 26302) by debbugs.gnu.org; 22 Oct 2019 12:41:34 +0000
Received: from localhost ([127.0.0.1]:58350 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1iMtTf-0006F7-Ak
	for submit <at> debbugs.gnu.org; Tue, 22 Oct 2019 08:41:33 -0400
Received: from pelzflorian.de ([5.45.111.108]:47518 helo=mail.pelzflorian.de)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pelzflorian@HIDDEN>) id 1iMtTe-0006Ez-2j
 for 26302 <at> debbugs.gnu.org; Tue, 22 Oct 2019 08:41:30 -0400
Received: from pelzflorian.localdomain (unknown [5.45.111.108])
 by mail.pelzflorian.de (Postfix) with ESMTPSA id EF2763604C5;
 Tue, 22 Oct 2019 14:41:28 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=pelzflorian.de;
 s=mail; t=1571748089;
 bh=9RQn17iJnfYdzMl0c6MuYO/9RssHg+bqCzpKOZc19GA=;
 h=Date:From:To:Cc:Subject:References:In-Reply-To;
 b=3sb7me1iXH5JIDWrnx5bVm6Bhxp95wB+9IaWWoeFxWv9stEIdBgAtfG74p3jk847s
 tiDVEtdlzvQbqDimRvF0R9ERVNW8TLRng3O7dl7OqhTonH89FzkLXY0nwAbPDrOqAu
 AIbEUhb9XjZCa2p8CxNy9gSJUpfvoBpMZlfoxu3E=
Date: Tue, 22 Oct 2019 14:41:28 +0200
From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Message-ID: <20191022124128.zi4siz76kdluxr5u@HIDDEN>
References: <20170329154040.ddscahwp2agknihb@abyayala> <8760e8l3bd.fsf@HIDDEN>
 <20170731215448.6zsu2qcfykuzbcd2@abyayala>
 <20190906142548.4crfjgvxilgalgrs@HIDDEN>
 <87ef0daeqs.fsf@HIDDEN>
 <20190919074829.hu3c7yy3bmeudfsw@HIDDEN>
 <87muf033pp.fsf@HIDDEN> <87a79t56b0.fsf@HIDDEN>
 <20191022122840.xwrrfvqm6t7uby6s@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <20191022122840.xwrrfvqm6t7uby6s@HIDDEN>
User-Agent: NeoMutt/20180716
X-Spam-Score: 0.0 (/)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

On Tue, Oct 22, 2019 at 02:28:40PM +0200, pelzflorian (Florian Pelz) wrote:
> The CSS is not loaded from the .i18n subdirectory, it seems.
> 

I suppose your fix at

https://git.savannah.gnu.org/cgit/guix/guix-artwork.git/commit/?id=0d627303680ef21efd63fba0728e39afc08d67eb

would address it had I rebased.

Regards,
Florian




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Tue, 22 Oct 2019 13:02:02 +0000
Resent-Message-ID: <handler.26302.B26302.157174928325893 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Cc: sirgazil <sirgazil@HIDDEN>, 26302 <at> debbugs.gnu.org
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.157174928325893
          (code B ref 26302); Tue, 22 Oct 2019 13:02:02 +0000
Received: (at 26302) by debbugs.gnu.org; 22 Oct 2019 13:01:23 +0000
Received: from localhost ([127.0.0.1]:58360 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1iMtmq-0006jW-4s
	for submit <at> debbugs.gnu.org; Tue, 22 Oct 2019 09:01:22 -0400
Received: from pelzflorian.de ([5.45.111.108]:47564 helo=mail.pelzflorian.de)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pelzflorian@HIDDEN>) id 1iMtmo-0006jO-K3
 for 26302 <at> debbugs.gnu.org; Tue, 22 Oct 2019 09:01:19 -0400
Received: from pelzflorian.localdomain (unknown [5.45.111.108])
 by mail.pelzflorian.de (Postfix) with ESMTPSA id 6D5DD3604C5;
 Tue, 22 Oct 2019 15:01:17 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=pelzflorian.de;
 s=mail; t=1571749277;
 bh=K7hWYp94++kBsp3WbH5wE+lPogGEQjN6o6JcY8G7qi8=;
 h=Date:From:To:Cc:Subject:References:In-Reply-To;
 b=AnburbofMGvrHGOKeVtjj/bxxNKlqtT7NVQ08unR+NMfFFW6JRgL4J/0vsjMrms4A
 gHkTgDxosuphJ+3im0bm5ZaELE+5kCsUK6iPrinmQpMyCLLowdfDn6LSTxXFwD0hnX
 +rqLIw+tvVwbEsWBeiSEBpCdPw2t9icqmcefdXvc=
Date: Tue, 22 Oct 2019 15:01:17 +0200
From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Message-ID: <20191022130116.avmtflgnlcoxryt2@HIDDEN>
References: <20170329154040.ddscahwp2agknihb@abyayala> <8760e8l3bd.fsf@HIDDEN>
 <20170731215448.6zsu2qcfykuzbcd2@abyayala>
 <20190906142548.4crfjgvxilgalgrs@HIDDEN>
 <87ef0daeqs.fsf@HIDDEN>
 <20190919074829.hu3c7yy3bmeudfsw@HIDDEN>
 <87muf033pp.fsf@HIDDEN> <87a79t56b0.fsf@HIDDEN>
 <20191022122840.xwrrfvqm6t7uby6s@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <20191022122840.xwrrfvqm6t7uby6s@HIDDEN>
User-Agent: NeoMutt/20180716
X-Spam-Score: 0.0 (/)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

On Tue, Oct 22, 2019 at 02:28:40PM +0200, pelzflorian (Florian Pelz) wrote:
> > Whenever you push to that branch, the web site should be automatically
> > updated within an hour.
> > 
> 
> I will rebase wip-i18n later this week and when the documentation
> videos are decided.
> 

Also it appears I broke URLs to the manual.




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
Resent-CC: bug-guix@HIDDEN
Resent-Date: Wed, 23 Oct 2019 14:17:02 +0000
Resent-Message-ID: <handler.26302.B26302.15718402022754 <at> debbugs.gnu.org>
Resent-Sender: help-debbugs@HIDDEN
X-GNU-PR-Message: followup 26302
X-GNU-PR-Package: guix
X-GNU-PR-Keywords: 
To: "pelzflorian \(Florian Pelz\)" <pelzflorian@HIDDEN>
Cc: sirgazil <sirgazil@HIDDEN>, 26302 <at> debbugs.gnu.org
Received: via spool by 26302-submit <at> debbugs.gnu.org id=B26302.15718402022754
          (code B ref 26302); Wed, 23 Oct 2019 14:17:02 +0000
Received: (at 26302) by debbugs.gnu.org; 23 Oct 2019 14:16:42 +0000
Received: from localhost ([127.0.0.1]:34752 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1iNHRJ-0000iL-CB
	for submit <at> debbugs.gnu.org; Wed, 23 Oct 2019 10:16:42 -0400
Received: from eggs.gnu.org ([209.51.188.92]:45552)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <ludo@HIDDEN>) id 1iNHRH-0000i8-DQ
 for 26302 <at> debbugs.gnu.org; Wed, 23 Oct 2019 10:16:39 -0400
Received: from fencepost.gnu.org ([2001:470:142:3::e]:52793)
 by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from <ludo@HIDDEN>)
 id 1iNHRC-00028a-7Z; Wed, 23 Oct 2019 10:16:34 -0400
Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=56034 helo=ribbon)
 by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256)
 (Exim 4.82) (envelope-from <ludo@HIDDEN>)
 id 1iNHRB-0006Ol-Ky; Wed, 23 Oct 2019 10:16:33 -0400
From: Ludovic =?UTF-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
References: <20170329154040.ddscahwp2agknihb@abyayala>
 <8760e8l3bd.fsf@HIDDEN> <20170731215448.6zsu2qcfykuzbcd2@abyayala>
 <20190906142548.4crfjgvxilgalgrs@HIDDEN>
 <87ef0daeqs.fsf@HIDDEN>
 <20190919074829.hu3c7yy3bmeudfsw@HIDDEN>
 <87muf033pp.fsf@HIDDEN> <87a79t56b0.fsf@HIDDEN>
 <20191022122840.xwrrfvqm6t7uby6s@HIDDEN>
 <20191022124128.zi4siz76kdluxr5u@HIDDEN>
X-URL: http://www.fdn.fr/~lcourtes/
X-Revolutionary-Date: 2 Brumaire an 228 de la =?UTF-8?Q?R=C3=A9volution?=
X-PGP-Key-ID: 0x090B11993D9AEBB5
X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc
X-PGP-Fingerprint: 3CE4 6455 8A84 FDC6 9DB4  0CFB 090B 1199 3D9A EBB5
X-OS: x86_64-pc-linux-gnu
Date: Wed, 23 Oct 2019 16:16:30 +0200
In-Reply-To: <20191022124128.zi4siz76kdluxr5u@HIDDEN>
 (pelzflorian@HIDDEN's message of "Tue, 22 Oct 2019 14:41:28
 +0200")
Message-ID: <87imoftum9.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]
X-Spam-Score: -2.3 (--)
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -3.3 (---)

Hi,

"pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN> skribis:

> On Tue, Oct 22, 2019 at 02:28:40PM +0200, pelzflorian (Florian Pelz) wrot=
e:
>> The CSS is not loaded from the .i18n subdirectory, it seems.
>>=20
>
> I suppose your fix at
>
> https://git.savannah.gnu.org/cgit/guix/guix-artwork.git/commit/?id=3D0d62=
7303680ef21efd63fba0728e39afc08d67eb
>
> would address it had I rebased.

I rebased some time ago and I think this fix is included (I added it
specifically for this purpose).

> Also it appears I broke URLs to the manual.

Which URLs specifically?

BTW, feel free to rebase =E2=80=98wip-i18n=E2=80=99 and to fix issues you s=
tumble upon
in that branch.  With this setup we should be able to see the changes
on-line automatically, so it=E2=80=99s a great way to get the ball rolling!

Thanks,
Ludo=E2=80=99.




Message sent to bug-guix@HIDDEN:


X-Loop: help-debbugs@HIDDEN
Subject: bug#26302: [website] translations
Resent-From: "pelzflorian (Florian Pelz)" <pelzflorian@HIDDEN>
Original-Sender: "Debbugs-submit"