Ver código fonte

Gettext internationalization and english translation

Miraty 2 anos atrás
pai
commit
335b826559
83 arquivos alterados com 2666 adições e 776 exclusões
  1. 1 0
      .gitignore
  2. 38 0
      DOCS/translation.md
  3. 2 0
      config.ini
  4. 4 4
      fn/common.php
  5. 2 2
      fn/dns.php
  6. 1 1
      fn/ht.php
  7. 5 5
      fn/ns.php
  8. 1 1
      fn/reg.php
  9. 1094 0
      locales/fr/C/LC_MESSAGES/messages.po
  10. 1094 0
      locales/messages.pot
  11. 79 79
      pages.php
  12. 3 3
      pg-act/auth/approval.php
  13. 2 2
      pg-act/auth/login.php
  14. 2 2
      pg-act/auth/password.php
  15. 1 1
      pg-act/auth/register.php
  16. 2 2
      pg-act/auth/unregister.php
  17. 2 2
      pg-act/auth/username.php
  18. 8 8
      pg-act/ht/add-dns.php
  19. 1 1
      pg-act/ht/add-onion.php
  20. 3 3
      pg-act/ht/add-subdomain.php
  21. 3 3
      pg-act/ht/add-subpath.php
  22. 1 1
      pg-act/ht/del.php
  23. 1 1
      pg-act/ns/caa.php
  24. 1 1
      pg-act/ns/cname.php
  25. 1 1
      pg-act/ns/dname.php
  26. 6 6
      pg-act/ns/edit.php
  27. 1 1
      pg-act/ns/ip.php
  28. 1 1
      pg-act/ns/loc.php
  29. 1 1
      pg-act/ns/mx.php
  30. 1 1
      pg-act/ns/ns.php
  31. 1 1
      pg-act/ns/srv.php
  32. 1 1
      pg-act/ns/sshfp.php
  33. 1 1
      pg-act/ns/tlsa.php
  34. 1 1
      pg-act/ns/txt.php
  35. 4 4
      pg-act/ns/zone-add.php
  36. 1 1
      pg-act/ns/zone-del.php
  37. 1 1
      pg-act/reg/ds.php
  38. 1 1
      pg-act/reg/glue.php
  39. 1 1
      pg-act/reg/ns.php
  40. 4 4
      pg-act/reg/register.php
  41. 4 4
      pg-act/reg/transfer.php
  42. 1 1
      pg-act/reg/unregister.php
  43. 3 3
      pg-view/auth/approval.php
  44. 18 15
      pg-view/auth/index.php
  45. 5 5
      pg-view/auth/login.php
  46. 3 7
      pg-view/auth/password.php
  47. 6 8
      pg-view/auth/register.php
  48. 3 10
      pg-view/auth/unregister.php
  49. 3 7
      pg-view/auth/username.php
  50. 5 5
      pg-view/ht/add-dns.php
  51. 2 6
      pg-view/ht/add-onion.php
  52. 3 7
      pg-view/ht/add-subdomain.php
  53. 3 7
      pg-view/ht/add-subpath.php
  54. 2 6
      pg-view/ht/del.php
  55. 30 29
      pg-view/ht/index.php
  56. 4 11
      pg-view/ns/caa.php
  57. 3 8
      pg-view/ns/cname.php
  58. 3 8
      pg-view/ns/dname.php
  59. 11 12
      pg-view/ns/edit.php
  60. 13 14
      pg-view/ns/form.ns.php
  61. 16 13
      pg-view/ns/index.php
  62. 2 6
      pg-view/ns/ip.php
  63. 20 26
      pg-view/ns/loc.php
  64. 3 14
      pg-view/ns/mx.php
  65. 2 7
      pg-view/ns/ns.php
  66. 14 15
      pg-view/ns/print.php
  67. 5 12
      pg-view/ns/srv.php
  68. 5 11
      pg-view/ns/sshfp.php
  69. 14 15
      pg-view/ns/tlsa.php
  70. 3 8
      pg-view/ns/txt.php
  71. 3 13
      pg-view/ns/zone-add.php
  72. 2 2
      pg-view/ns/zone-del.php
  73. 11 15
      pg-view/reg/ds.php
  74. 11 15
      pg-view/reg/glue.php
  75. 3 3
      pg-view/reg/index.php
  76. 6 10
      pg-view/reg/ns.php
  77. 6 6
      pg-view/reg/print.php
  78. 3 3
      pg-view/reg/register.php
  79. 0 242
      pg-view/reg/reserved.txt
  80. 4 4
      pg-view/reg/transfer.php
  81. 3 3
      pg-view/reg/unregister.php
  82. 22 5
      router.php
  83. 5 6
      view.php

+ 1 - 0
.gitignore

@@ -1 +1,2 @@
 /db/niver.db
 /db/niver.db
+/locales/*/C/LC_MESSAGES/messages.mo

+ 38 - 0
DOCS/translation.md

@@ -0,0 +1,38 @@
+# Translation with gettext
+
+## As a developer
+
+Extract messages to be translated from the source files and into a Portable Object Template file:
+```
+xgettext --from-code=UTF-8 --no-wrap -d messages -p locales/ --from-code=UTF-8 *.php */*.php */*/*.php
+mv locales/messages.po locales/messages.pot
+```
+
+Merge messages into existing Portable Objects:
+```
+msgmerge --no-wrap locales/fr/C/LC_MESSAGES/messages.po locales/messages.pot -o locales/fr/C/LC_MESSAGES/messages.po
+```
+
+## As a translator
+
+### To start a new translation
+
+```
+mkdir -p locales/fr/C/LC_MESSAGES/
+msginit -i locales/messages.pot -o locales/fr/C/LC_MESSAGES/messages.po
+```
+
+### To translate
+
+Edit `locales/fr/C/LC_MESSAGES/messages.po` using either
+* any text editor
+* a dedicated translation software like [Poedit](https://poedit.net/), [KDE's Lokalize](https://apps.kde.org/lokalize/) or [GNOME Translation Editor](https://wiki.gnome.org/Apps/Gtranslator).
+
+## As an administrator
+
+To compile Portable Objects into Machine Objects:
+```
+msgfmt locales/fr/C/LC_MESSAGES/messages.po -o locales/fr/C/LC_MESSAGES/messages.mo
+```
+
+Machine Objects files are kept in cache by the Gettext extension, so PHP-FPM needs to be restarted to update translations.

+ 2 - 0
config.ini

@@ -4,6 +4,8 @@ docs_prefix = "/docs/"
 ; Prefix in URL, if any
 ; Prefix in URL, if any
 prefix = ""
 prefix = ""
 public_domains[] = "niver.test"
 public_domains[] = "niver.test"
+service_name = "Niver"
+service_emoji = "🪐"
 
 
 [dns]
 [dns]
 knotc_path = "/usr/sbin/knotc"
 knotc_path = "/usr/sbin/knotc"

+ 4 - 4
fn/common.php

@@ -6,9 +6,9 @@ function output($code, $msg = '', $logs = ['']) {
 	if ($shortCode === 5)
 	if ($shortCode === 5)
 		error_log('Niver internal error: ' . strip_tags($msg) . implode(LF, $logs));
 		error_log('Niver internal error: ' . strip_tags($msg) . implode(LF, $logs));
 	$final_message = match ($shortCode) {
 	$final_message = match ($shortCode) {
-		2 => ($msg === '') ? '' : '<p><output><strong>Succès</strong> : <em>' . $msg . '</em></output></p>' . LF,
-		4 => '<p><output><strong>Erreur utilisataire</strong> : <em>' . $msg . '</em></output></p>' . LF,
-		5 => '<p><output><strong>Server error</strong>: The server encountered an error: <em>' . $msg . '</em></output></p>' . LF,
+		2 => ($msg === '') ? '' : '<p><output>' . _('<strong>Success</strong>: ') . '<em>' . $msg . '</em></output></p>' . LF,
+		4 => '<p><output>' . _('<strong>User error</strong>: ') . '<em>' . $msg . '</em></output></p>' . LF,
+		5 => '<p><output>' . _('<strong>Server error</strong>: ') . '<em>' . $msg . '</em></output></p>' . LF,
 	};
 	};
 	displayPage(['final_message' => $final_message]);
 	displayPage(['final_message' => $final_message]);
 }
 }
@@ -130,5 +130,5 @@ function getAuthToken() {
 function checkAuthToken($salt, $hash) {
 function checkAuthToken($salt, $hash) {
 	$correctProof = substr(hash_hmac('sha256', $salt . $_SESSION['id'], SECRET_KEY), 0, 32);
 	$correctProof = substr(hash_hmac('sha256', $salt . $_SESSION['id'], SECRET_KEY), 0, 32);
 	if (hash_equals($correctProof, $hash) !== true)
 	if (hash_equals($correctProof, $hash) !== true)
-		output(403, 'Preuve incorrecte');
+		output(403, _('Wrong proof.'));
 }
 }

+ 2 - 2
fn/dns.php

@@ -59,12 +59,12 @@ function checkIpFormat($ip) {
 		return 'A';
 		return 'A';
 	if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))
 	if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))
 		return 'AAAA';
 		return 'AAAA';
-	output(403, 'IP address malformed.');
+	output(403, _('IP address malformed.'));
 }
 }
 
 
 function checkAbsoluteDomainFormat($domain) { // If the domain must end with a dot
 function checkAbsoluteDomainFormat($domain) { // If the domain must end with a dot
 	if (!filter_var($domain, FILTER_VALIDATE_DOMAIN) OR preg_match('/^([a-z0-9_-]{1,63}\.){2,127}$/D', $domain) !== 1)
 	if (!filter_var($domain, FILTER_VALIDATE_DOMAIN) OR preg_match('/^([a-z0-9_-]{1,63}\.){2,127}$/D', $domain) !== 1)
-		output(403, 'Domain malformed.');
+		output(403, _('Domain malformed.'));
 }
 }
 
 
 function formatEndWithDot($str) {
 function formatEndWithDot($str) {

+ 1 - 1
fn/ht.php

@@ -3,7 +3,7 @@
 function checkDomainFormat($domain) {
 function checkDomainFormat($domain) {
 	// If the domain must end without a dot
 	// If the domain must end without a dot
 	if (!filter_var($domain, FILTER_VALIDATE_DOMAIN) OR !preg_match('/^([a-z0-9_-]{1,63}\.){1,126}[a-z0-9]{1,63}$/D', $domain))
 	if (!filter_var($domain, FILTER_VALIDATE_DOMAIN) OR !preg_match('/^([a-z0-9_-]{1,63}\.){1,126}[a-z0-9]{1,63}$/D', $domain))
-		output(403, 'Domain malformed.');
+		output(403, _('Domain malformed.'));
 }
 }
 
 
 function formatDomain($domain) {
 function formatDomain($domain) {

+ 5 - 5
fn/ns.php

@@ -37,9 +37,9 @@ function nsParseCommonRequirements() {
 	$values['ttl'] = $_POST['ttl-value'] * $_POST['ttl-multiplier'];
 	$values['ttl'] = $_POST['ttl-value'] * $_POST['ttl-multiplier'];
 
 
 	if ($values['ttl'] < MIN_TTL)
 	if ($values['ttl'] < MIN_TTL)
-		output(403, 'Les TTLs inférieurs à ' . MIN_TTL . ' secondes ne sont pas autorisés.');
+		output(403, sprintf(_('TTLs shorter than %s seconds are forbidden.'), MIN_TTL));
 	if ($values['ttl'] > MAX_TTL)
 	if ($values['ttl'] > MAX_TTL)
-		output(403, 'Les TTLs supérieurs à ' . MAX_TTL . ' secondes ne sont pas autorisés.');
+		output(403, sprintf(_('TTLs longer than %s seconds are forbidden.'), MAX_TTL));
 
 
 	return $values;
 	return $values;
 }
 }
@@ -53,8 +53,8 @@ function nsListUserZones() {
 function nsCheckZonePossession($zone) {
 function nsCheckZonePossession($zone) {
 	checkAbsoluteDomainFormat($zone);
 	checkAbsoluteDomainFormat($zone);
 
 
-	if (!in_array($zone, query('select', 'zones', ['username' => $_SESSION['id']], 'zone'), true))
-		output(403, 'You don\'t own this zone on the nameserver.');
+	if (!in_array($zone, nsListUserZones(), true))
+		output(403, 'You don\'t own this zone on the name server.');
 }
 }
 
 
 function nsDeleteZone($zone) {
 function nsDeleteZone($zone) {
@@ -62,7 +62,7 @@ function nsDeleteZone($zone) {
 	knotcConfExec(["unset 'zone[$zone]'"]);
 	knotcConfExec(["unset 'zone[$zone]'"]);
 
 
 	// Remove Knot zone file
 	// Remove Knot zone file
-	if(unlink(CONF['ns']['knot_zones_path'] . '/' . $zone . 'zone') !== true)
+	if (unlink(CONF['ns']['knot_zones_path'] . '/' . $zone . 'zone') !== true)
 		output(500, 'Failed to remove Knot zone file.');
 		output(500, 'Failed to remove Knot zone file.');
 
 
 	// Remove Knot related data
 	// Remove Knot related data

+ 1 - 1
fn/reg.php

@@ -10,7 +10,7 @@ function regListUserDomains() {
 
 
 function regCheckDomainPossession($domain) {
 function regCheckDomainPossession($domain) {
 	if (in_array($domain, regListUserDomains(), true) !== true)
 	if (in_array($domain, regListUserDomains(), true) !== true)
-		output(403, 'You don\'t own this domain.');
+		output(403, 'You don\'t own this domain on the registry.');
 }
 }
 
 
 function regDeleteDomain($domain) {
 function regDeleteDomain($domain) {

+ 1094 - 0
locales/fr/C/LC_MESSAGES/messages.po

@@ -0,0 +1,1094 @@
+#: pages.php:9
+msgid "Authentication"
+msgstr "Authentification"
+
+#: pages.php:10
+msgid "Manage account"
+msgstr "Gérer son compte"
+
+#: pages.php:13 view.php:21 pg-view/auth/login.php:12
+#: pg-view/auth/register.php:1
+msgid "Log in"
+msgstr "Se connecter"
+
+#: pages.php:14
+msgid "Start a new navigation session with an existing account"
+msgstr "Démarrer une nouvelle session avec un compte existant"
+
+#: pages.php:18 view.php:19
+msgid "Log out"
+msgstr "Se déconnecter"
+
+#: pages.php:19
+msgid "End the current session and delete cookies and cache"
+msgstr "Terminer la session actuelle et supprimer les cookies et le cache"
+
+#: pages.php:22
+msgid "Create account"
+msgstr "Créer un compte"
+
+#: pages.php:23
+msgid "Create a new account, and log in with it"
+msgstr "Créer un nouveau compte, et se connecter avec"
+
+#: pages.php:28
+msgid "Delete account"
+msgstr "Supprimer son compte"
+
+#: pages.php:29
+msgid "Erase all current account's data"
+msgstr "Effacer toutes les données du compte actuel"
+
+#: pages.php:32
+msgid "Switch to an approved account"
+msgstr "Passer à un compte approuvé"
+
+#: pages.php:33
+msgid "Switch to an approved account using an approval key"
+msgstr "Utiliser une clé d'approbation pour passer à un compte approuvé"
+
+#: pages.php:36
+msgid "Change password"
+msgstr "Changer la clé de passe"
+
+#: pages.php:37
+msgid "Change the character string used to authenticate yourself"
+msgstr "Changer la chaîne de caractères utilisée pour s'authentifier"
+
+#: pages.php:40
+msgid "Change username"
+msgstr "Changer l'identifiant"
+
+#: pages.php:41
+msgid "Change the name used to identify your account when logging in and displayed at the start of every page"
+msgstr "Changer le nom utilisé pour identifier le compte à la connexion et affiché au début de toutes les pages"
+
+#: pages.php:46
+#, php-format
+msgid "%s registry"
+msgstr "Registre %s"
+
+#: pages.php:47
+#, php-format
+msgid "Register and delegate a %s subdomain"
+msgstr "Obtenir et déléguer un domaine %s"
+
+#: pages.php:50
+msgid "Register domain"
+msgstr "Enregistrer un domaine"
+
+#: pages.php:51
+#, php-format
+msgid "Get a %s subdomain"
+msgstr "Obtenir un sous-domaine de %s"
+
+#: pages.php:55
+msgid "Unregister domain"
+msgstr "Désenregistrer un domaine"
+
+#: pages.php:56
+msgid "Delete all data related to a domain and make it available to the public again"
+msgstr "Supprimer toutes les informations liées à un domaine et le redisponibiliser au public"
+
+#: pages.php:59
+msgid "Display domain records"
+msgstr "Afficher les enregistrements"
+
+#: pages.php:60
+msgid "Print every record related to a domain and served by the registry"
+msgstr "Montrer tous les enregistrements liés à un domaine et servis par le registre"
+
+#: pages.php:63 pages.php:67 pages.php:107 pages.php:111 pages.php:115
+#: pages.php:119 pages.php:123 pages.php:127 pages.php:131 pages.php:135
+#: pages.php:139 pages.php:143
+#, php-format
+msgid "%s records"
+msgstr "Enregistrements %s"
+
+#: pages.php:64
+#, php-format
+msgid "Indicate the name servers of a %s subdomain"
+msgstr "Indiquer les serveurs de nom d'un sous-domaine de %s"
+
+#: pages.php:68
+msgid "Delegate <abbr title=\"Domain Name System Security Extensions\">DNSSEC</abbr> trust"
+msgstr "Déléguer la confiance <abbr title=\"Domain Name System Security Extensions\">DNSSEC</abbr>"
+
+#: pages.php:71
+msgid "Receive a domain transfer"
+msgstr "Recevoir un transfert de domaine"
+
+#: pages.php:72
+msgid "Transfer a domain owned by another account to the current account"
+msgstr "Transférer vers le compte actuel un domaine possédé par un autre compte"
+
+#: pages.php:75
+msgid "Glue records"
+msgstr "Glue records"
+
+#: pages.php:76
+msgid "Advanced: store the IP address of a name server whose domain is inside the domain it serves"
+msgstr "Avancé&nbsp;: indiquer l'adresse IP d'un serveur de nom dont le domaine descend de la zone qu'il sert"
+
+#: pages.php:81 pg-view/ns/index.php:24
+msgid "Name servers"
+msgstr "Serveurs de nom"
+
+#: pages.php:82
+msgid "Host and manage domain's records"
+msgstr "Héberger et gérer les enregistrements d'un domaine"
+
+#: pages.php:85
+msgid "Add zone"
+msgstr "Ajouter une zone"
+
+#: pages.php:86
+#, php-format
+msgid "The zone will be managed by %s name servers"
+msgstr "La zone sera gérée par les serveurs de nom de %s"
+
+#: pages.php:90
+msgid "Delete zone"
+msgstr "Supprimer une zone"
+
+#: pages.php:91
+msgid "Erase all zone data"
+msgstr "Effacer tous les enregistrements d'une zone"
+
+#: pages.php:94
+msgid "Display zone"
+msgstr "Afficher une zone"
+
+#: pages.php:95
+msgid "Print zonefile content"
+msgstr "Montrer le contenu d'un fichier de zone"
+
+#: pages.php:98
+msgid "Edit zone"
+msgstr "Modifier une zone"
+
+#: pages.php:99
+msgid "Change zonefile content"
+msgstr "Éditer le contenu d'un fichier de zone"
+
+#: pages.php:103
+msgid "AAAA and A records"
+msgstr "Enregistrements AAAA et A"
+
+#: pages.php:104
+msgid "Store domain's IP address"
+msgstr "Indiquer l'adresse IP d'un domaine"
+
+#: pages.php:108
+msgid "Store zone's name server"
+msgstr "Indiquer les serveurs de nom d'une zone"
+
+#: pages.php:112
+msgid "Associate text to domain"
+msgstr "Associer du texte à un domaine"
+
+#: pages.php:116
+msgid "Limit the certificate authorities allowed to certify the domain"
+msgstr "Limiter les autorités de certification autorisées à certifier un domaine"
+
+#: pages.php:120
+msgid "Store the location of a domain's service"
+msgstr "Indiquer l'adresse exacte d'un service pour un domaine"
+
+#: pages.php:124
+msgid "Store the email server's address"
+msgstr "Indiquer l'adresse d'un serveur de courriels"
+
+#: pages.php:128
+msgid "Store <abbr title=\"Secure SHell\">SSH</abbr> public keys fingerprints"
+msgstr "Indiquer les empreintes de clés publiques <abbr title=\"Secure SHell\">SSH</abbr>"
+
+#: pages.php:132
+msgid "Setup <abbr title=\"DNS-based Authentication of Named Entities\">DANE</abbr> by publishing the <abbr title=\"Transport Layer Security\">TLS</abbr> certificate fingerprint"
+msgstr "Mettre en place <abbr title=\"DNS-based Authentication of Named Entities\">DANE</abbr> et publiant l'empreinte d'un certificat <abbr title=\"Transport Layer Security\">TLS</abbr>"
+
+#: pages.php:136
+msgid "Define a domain as an alias of another"
+msgstr "Définir un domaine comme étant l'alias d'un autre"
+
+#: pages.php:140
+msgid "Define all subdomains of a domain as aliases of subdomains of another domain"
+msgstr "Définir la descendance d'un domain comme alias de la descendance d'un autre domaine"
+
+#: pages.php:144
+msgid "Store geographic coordinates"
+msgstr "Indiquer des coordonnées géographiques"
+
+#: pages.php:149
+msgid "Web"
+msgstr "Web"
+
+#: pages.php:150
+msgid "Upload a static website into an <abbr title=\"SSH File Transfer Protocol\">SFTP</abbr> space"
+msgstr "Téléverser un site statique dans un espace <abbr title=\"SSH File Transfert Protocol\">SFTP</abbr>"
+
+#: pages.php:153
+#, php-format
+msgid "%s subpath access"
+msgstr "Accès par sous-chemin de %s"
+
+#: pages.php:154 pages.php:159 pages.php:164
+#, php-format
+msgid "Its URL will look like %s"
+msgstr "Son URL ressemblera à %s"
+
+#: pages.php:154 pages.php:159 pages.php:164
+msgid "mysite"
+msgstr "monsite"
+
+#: pages.php:158
+#, php-format
+msgid "%s subdomain access"
+msgstr "Accès par sous-domaine de %s"
+
+#: pages.php:163
+msgid "Dedicated domain with Let's Encrypt certificate access"
+msgstr "Accès par domaine dédié avec certificat Let's Encrypt"
+
+#: pages.php:168
+msgid "Onion service access"
+msgstr "Accès par service Onion"
+
+#: pages.php:169
+#, php-format
+msgid "Its URL will look like %s, and work only through the Tor network"
+msgstr "Son URL ressemblera à %s, et ne fonctionnera que par le réseau Tor"
+
+#: pages.php:173 pg-view/ht/del.php:18
+msgid "Delete access"
+msgstr "Supprimer un accès"
+
+#: pages.php:174
+msgid "Delete an existing HTTP access from a subdirectory of the SFTP space"
+msgstr "Retirer un accès HTTP existant d'un sous-dossier de l'espace SFTP"
+
+#: router.php:120
+msgid "You need to be logged in to do this."
+msgstr "Vous devez être connecté·e à un compte pour faire cela."
+
+#: router.php:122
+msgid "This account doesn't exist anymore. Log out to end this ghost session."
+msgstr "Ce compte n'existe plus. Déconnectez-vous pour terminer cette session fantôme."
+
+#: view.php:21
+msgid "Anonymous"
+msgstr "Anonyme"
+
+#: view.php:41
+#, php-format
+msgid "This form won't be accepted because you need to %slog in%s first."
+msgstr "Ce forumulaire ne sera pas accepté car il faut %sse connecter%s d'abord."
+
+#: view.php:48
+#, php-format
+msgid "%sSource code%s available under %s."
+msgstr "%sCode source%s disponible sous %s."
+
+#: fn/auth.php:108
+msgid "Account rate limit reached, try again later."
+msgstr "Limite de taux pour ce compte atteinte, réessayez plus tard."
+
+#: fn/auth.php:130
+msgid "Global rate limit reached, try again later."
+msgstr "Limite de taux globale atteinte, réessayez plus tard."
+
+#: fn/common.php:9
+msgid "<strong>Success</strong>: "
+msgstr "<strong>Succès</strong>&nbsp;: "
+
+#: fn/common.php:10
+msgid "<strong>User error</strong>: "
+msgstr "<strong>Erreur de l'utilisataire</strong>&nbsp;: "
+
+#: fn/common.php:11
+msgid "<strong>Server error</strong>: "
+msgstr "<strong>Erreur du serveur</strong>&nbsp;: "
+
+#: fn/common.php:133
+msgid "Wrong proof."
+msgstr "Preuve incorrecte."
+
+#: fn/dns.php:62
+msgid "IP address malformed."
+msgstr "Adresse IP malformée."
+
+#: fn/dns.php:67 fn/ht.php:6
+msgid "Domain malformed."
+msgstr "Domaine malformé."
+
+#: fn/ns.php:40 pg-act/ns/edit.php:25
+#, php-format
+msgid "TTLs shorter than %s seconds are forbidden."
+msgstr "Les TTLs plus courts que %s secondes sont interdits."
+
+#: fn/ns.php:42 pg-act/ns/edit.php:27
+#, php-format
+msgid "TTLs longer than %s seconds are forbidden."
+msgstr "Les TTLs plus longs que %s secondes sont interdits."
+
+#: pg-act/auth/approval.php:4
+msgid "This account is already approved."
+msgstr "Ce compte est déjà approuvé."
+
+#: pg-act/auth/approval.php:7
+msgid "This approval key is not available. It has been mistyped, used for another account, or has expired."
+msgstr "Cette clé d'approbation n'est pas disponible. Elle a pu être mal saisie, utilisée pour un autre compte, ou a expiré."
+
+#: pg-act/auth/approval.php:18
+msgid "Account approved."
+msgstr "Compte approuvé."
+
+#: pg-act/auth/login.php:10
+msgid "This account does not exist."
+msgstr "Ce compte n'existe pas."
+
+#: pg-act/auth/login.php:15
+msgid "Wrong password."
+msgstr "Clé de passe incorrecte."
+
+#: pg-act/auth/password.php:6
+msgid "Wrong current password."
+msgstr "Clé de passe actuelle incorrecte."
+
+#: pg-act/auth/password.php:10
+msgid "Password updated."
+msgstr "Clé de passe mise à jour."
+
+#: pg-act/auth/register.php:10 pg-act/auth/username.php:8
+msgid "This username is already taken."
+msgstr "Cet identifiant est déjà pris."
+
+#: pg-act/auth/unregister.php:4
+msgid "Account deletion must be confirmed."
+msgstr "La suppression du compte doit être confirmée."
+
+#: pg-act/auth/unregister.php:29
+msgid "Account deleted."
+msgstr "Compte supprimé."
+
+#: pg-act/auth/username.php:17
+msgid "Username updated."
+msgstr "Identifiant mis à jour."
+
+#: pg-act/ht/add-dns.php:9 pg-act/ht/add-subdomain.php:10
+msgid "This domain already exists on this service. Use another one."
+msgstr "Ce domaine existe déjà sur ce service. Utilisez-en un autre."
+
+#: pg-act/ht/add-dns.php:13 pg-act/ht/add-dns.php:19 pg-act/ht/add-dns.php:25
+#, php-format
+msgid "Can't retrieve the %s record."
+msgstr "Impossible de récupérer l'enregistrement %s."
+
+#: pg-act/ht/add-dns.php:15 pg-act/ht/add-dns.php:21
+#, php-format
+msgid "This domain must have %2$s as its only %1$s record."
+msgstr "Ce domain doit avoir %2$s pour unique enregistrement %1$s."
+
+#: pg-act/ht/add-dns.php:27
+msgid "No TXT record with the expected format has been found."
+msgstr "Aucun enregistrement TXT avec le format attendu n'a été trouvé."
+
+#: pg-act/ht/add-dns.php:59 pg-act/ht/add-onion.php:47
+#: pg-act/ht/add-subdomain.php:19 pg-act/ht/add-subpath.php:19
+#, php-format
+msgid "%s added on this directory."
+msgstr "%s ajouté sur ce dossier."
+
+#: pg-act/ht/add-onion.php:47
+#, php-format
+msgid "Its address is: %s"
+msgstr "Son adresse est&nbsp;: %s"
+
+#: pg-act/ht/add-subdomain.php:7
+msgid "Invalid domain label."
+msgstr "Label de domaine invalide."
+
+#: pg-act/ht/add-subpath.php:7
+msgid "Invalid path."
+msgstr "Chemin invalide."
+
+#: pg-act/ht/add-subpath.php:10
+msgid "This path already exists on this service. Use another one."
+msgstr "Ce chemin est déjà pris sur ce service. Utilisez-en un autre."
+
+#: pg-act/ht/del.php:11
+msgid "Access removed."
+msgstr "Accès retiré."
+
+#: pg-act/ns/caa.php:23 pg-act/ns/cname.php:14 pg-act/ns/dname.php:14
+#: pg-act/ns/ip.php:14 pg-act/ns/loc.php:70 pg-act/ns/mx.php:18
+#: pg-act/ns/ns.php:14 pg-act/ns/srv.php:26 pg-act/ns/sshfp.php:23
+#: pg-act/ns/tlsa.php:27 pg-act/ns/txt.php:15 pg-act/reg/ds.php:30
+#: pg-act/reg/glue.php:16 pg-act/reg/ns.php:13
+msgid "Modification done."
+msgstr "Modification effectuée."
+
+#: pg-act/ns/edit.php:17
+#, php-format
+msgid "The zone is limited to %s characters."
+msgstr "La zone est limitée à %s caractères."
+
+#: pg-act/ns/edit.php:21
+msgid "The following line does not match the expected format: "
+msgstr "La ligne suivante ne correspond pas au format attendu&nbsp;: "
+
+#: pg-act/ns/edit.php:23
+#, php-format
+msgid "The %s type is not allowed."
+msgstr "Le type %s n'est pas autorisé."
+
+#: pg-act/ns/edit.php:38
+msgid "Sent zone content is not correct (according to <code>kzonecheck</code>)."
+msgstr "Le contenu de zone envoyé n'est pas correct (selon <code>kzonecheck</code>)."
+
+#: pg-act/ns/zone-add.php:6
+msgid "This zone already exists on the service."
+msgstr "Cette zone existe déjà sur ce service."
+
+#: pg-act/ns/zone-add.php:10
+msgid "Parent zone's name servers not found."
+msgstr "Serveurs de nom de la zone parente introuvables."
+
+#: pg-act/ns/zone-add.php:16 pg-act/reg/transfer.php:13
+msgid "NS authentication record not found."
+msgstr "Enregistrement d'authentification NS introuvable."
+
+#: pg-act/ns/zone-add.php:52
+msgid "Zone created."
+msgstr "Zone créée."
+
+#: pg-act/ns/zone-del.php:7
+msgid "Zone deleted."
+msgstr "Zone supprimée."
+
+#: pg-act/reg/register.php:4
+msgid "This format of subdomain is not allowed."
+msgstr "Ce format de sous-domaine n'est pas autorisé."
+
+#: pg-act/reg/register.php:9
+msgid "This domain is already registered."
+msgstr "Ce domain est déjà enregistré."
+
+#: pg-act/reg/register.php:12
+msgid "This domain is reserved."
+msgstr "Ce domain est réservé."
+
+#: pg-act/reg/register.php:22
+msgid "Domain registered."
+msgstr "Domaine enregistré."
+
+#: pg-act/reg/transfer.php:9
+msgid "The current account already owns this domain."
+msgstr "Le compte actuel possède déjà ce domaine."
+
+#: pg-act/reg/transfer.php:26
+msgid "The domain has been transferred to the current account ; the NS authentication record has been automatically deleted."
+msgstr "Le domaine a été transféré vers le compte actuel ; l'enregistrement d'authentification NS a été automatiquement supprimé."
+
+#: pg-act/reg/unregister.php:7
+msgid "Domain unregistered."
+msgstr "Domaine désenregistré."
+
+#: pg-view/auth/approval.php:2
+msgid "This form allows to use an approval key to validate your account. Approval keys are distributed by an administrator upon request."
+msgstr "Ce formulaire permet d'utiliser une clé d'approbation pour valider son compte. Les clés d'approbation sont distribuées par ane administrataire sur demande."
+
+#: pg-view/auth/approval.php:6
+msgid "Approval key"
+msgstr "Clé d'approbation"
+
+#: pg-view/auth/approval.php:9
+msgid "Use for this account"
+msgstr "Utiliser pour ce compte"
+
+#: pg-view/auth/index.php:5
+msgid "You are currently using a testing account."
+msgstr "Vous utilisez actuellement un compte de test."
+
+#: pg-view/auth/index.php:6
+msgid "You are currently using an approved account."
+msgstr "Vous utilisez actuellement un compte approuvé."
+
+#: pg-view/auth/index.php:7
+#, php-format
+msgid "It's internal ID is %s."
+msgstr "Son identifiant interne est %s."
+
+#: pg-view/auth/index.php:9
+msgid "You are not logged in."
+msgstr "Vous n'êtes connecté·e à aucun compte."
+
+#: pg-view/auth/index.php:13
+msgid "Account types"
+msgstr "Types de comptes"
+
+#: pg-view/auth/index.php:16
+msgid "Testing"
+msgstr "De test"
+
+#: pg-view/auth/index.php:18
+msgid "It's the default account type, with limited capabilities in order to avoid abuses:"
+msgstr "C'est le type de compte par défaut, avec des capacités limitées afin de limiter les abus&nbsp;:"
+
+#: pg-view/auth/index.php:20
+msgid "May be deleted anytime"
+msgstr "Peut être supprimé n'importe quand"
+
+#: pg-view/auth/index.php:21 pg-view/auth/index.php:29
+#, php-format
+msgid "%s of SFTP quota"
+msgstr "Quota SFTP de %s"
+
+#: pg-view/auth/index.php:21 pg-view/auth/index.php:29 pg-view/ht/index.php:51
+msgid "<abbr title=\"gibibyte\">GiB</abbr>"
+msgstr "<abbr title=\"gibioctet\">Gio</abbr>"
+
+#: pg-view/auth/index.php:21 pg-view/auth/index.php:29 pg-view/ht/index.php:51
+msgid "<abbr title=\"mebibyte\">MiB</abbr>"
+msgstr "<abbr title=\"mébioctet\">Mio</abbr>"
+
+#: pg-view/auth/index.php:22
+msgid "Let's Encrypt certificate from the staging environment (not trusted by clients)"
+msgstr "Certificat Let's Encrypt de test (n'est pas reconnu par les clients)"
+
+#: pg-view/auth/index.php:25
+msgid "Approved"
+msgstr "Approuvé"
+
+#: pg-view/auth/index.php:27
+msgid "It was originally a testing account, but has been approved by an administrator, and is suited for stable usecases:"
+msgstr "C'est originellement un compte de test, mais qui a été approuvé par ane administrataire, et qui permet une utilisation stable&nbsp;:"
+
+#: pg-view/auth/index.php:30
+msgid "Stable Let's Encrypt certificates"
+msgstr "Vrai certificat Let's Encrypt"
+
+#: pg-view/auth/login.php:1
+msgid "Need an accout?"
+msgstr "Nouvele ?"
+
+#: pg-view/auth/login.php:1 pg-view/reg/register.php:10
+msgid "Register"
+msgstr "Créer un compte"
+
+#: pg-view/auth/login.php:4 pg-view/auth/register.php:4 pg-view/ht/index.php:94
+msgid "Username"
+msgstr "Identifiant"
+
+#: pg-view/auth/login.php:8 pg-view/auth/register.php:9 pg-view/ht/index.php:98
+msgid "Password"
+msgstr "Clé de passe"
+
+#: pg-view/auth/password.php:2
+msgid "Current password"
+msgstr "Clé de passe actuelle"
+
+#: pg-view/auth/password.php:5
+msgid "New password"
+msgstr "Nouvelle clé de passe"
+
+#: pg-view/auth/password.php:8
+msgid "Update password"
+msgstr "Mettre à jour la clé de passe"
+
+#: pg-view/auth/register.php:1
+msgid "Already have an account?"
+msgstr "Déjà un compte ?"
+
+#: pg-view/auth/register.php:10
+#, php-format
+msgid "Minimum %1$s characters, or %2$s characters if it contains lowercase, uppercase and digit."
+msgstr "Minimum %1$s caractères, ou %2$s caractères si elle contient minuscule, majuscule et chiffre."
+
+#: pg-view/auth/register.php:14
+msgid "Create an account"
+msgstr "Se créer un nouveau compte"
+
+#: pg-view/auth/unregister.php:2
+msgid "This will delete every resource managed by the current account, including registered domains, hosted DNS records, websites files and cryptographic keys for Onion services and DNSSEC."
+msgstr "Ceci supprimera toutes les ressources gérées par le compte actuel, y compris les domaines enregistrés, les enregistrements DNS hébergés, les fichiers des sites et les clés cryptographiques des services Onion et de DNSSEC."
+
+#: pg-view/auth/unregister.php:7
+msgid "Delete the current account and everything related (required)"
+msgstr "Supprimer le compte actuel et tout ce qui y est lié (requis)"
+
+#: pg-view/auth/unregister.php:9 pg-view/ns/form.ns.php:4 pg-view/reg/ds.php:5
+#: pg-view/reg/glue.php:5 pg-view/reg/ns.php:5
+msgid "Delete"
+msgstr "Supprimer"
+
+#: pg-view/auth/username.php:2
+msgid "New username"
+msgstr "Nouvel identifiant"
+
+#: pg-view/auth/username.php:5
+msgid "Update username"
+msgstr "Mettre à jour l'identifiant"
+
+#: pg-view/ht/add-dns.php:2
+msgid "A Let's Encrypt certificate will be obtained."
+msgstr "Un certificat Let's Encrypt sera obtenu."
+
+#: pg-view/ht/add-dns.php:6
+msgid "The domain must have the following records when the form is being processed."
+msgstr "Le domaine doit avoir les enregistrements suivant pendant le traitement du formulaire."
+
+#: pg-view/ht/add-dns.php:25 pg-view/ns/form.ns.php:8 pg-view/ns/print.php:32
+#: pg-view/ns/zone-add.php:6 pg-view/reg/ds.php:8 pg-view/reg/glue.php:8
+#: pg-view/reg/glue.php:15 pg-view/reg/ns.php:8 pg-view/reg/print.php:2
+#: pg-view/reg/print.php:16 pg-view/reg/unregister.php:6
+msgid "Domain"
+msgstr "Domaine"
+
+#: pg-view/ht/add-dns.php:27 pg-view/ht/add-onion.php:2
+#: pg-view/ht/add-subdomain.php:4 pg-view/ht/add-subpath.php:4
+msgid "Target directory"
+msgstr "Dossier ciblé"
+
+#: pg-view/ht/add-dns.php:36 pg-view/ht/add-onion.php:11
+#: pg-view/ht/add-subdomain.php:13 pg-view/ht/add-subpath.php:13
+msgid "Setup access"
+msgstr "Créer l'accès"
+
+#: pg-view/ht/add-subdomain.php:2 pg-view/ns/form.ns.php:10
+#: pg-view/reg/glue.php:10 pg-view/reg/register.php:6
+msgid "Subdomain"
+msgstr "Sous-domaine"
+
+#: pg-view/ht/add-subpath.php:2
+msgid "Path"
+msgstr "Chemin"
+
+#: pg-view/ht/del.php:2
+msgid "Access to delete"
+msgstr "Accès à retirer"
+
+#: pg-view/ht/index.php:2
+msgid "This service allows you to send files on the server using SFTP, and to make them publicly available with HTTP."
+msgstr "Ce service permet d'envoyer des fichiers sur le serveur par SFTP, et de les rendre publiquement accessibles par HTTP."
+
+#: pg-view/ht/index.php:8
+msgid "Currently hosted sites"
+msgstr "Sites actuellement hébergés"
+
+#: pg-view/ht/index.php:38
+msgid "Adding a site access"
+msgstr "Ajouter un accès de site"
+
+#: pg-view/ht/index.php:40
+#, php-format
+msgid "In order to be able to setup an HTTP site with this service, a subdirectory for this site must be created inside the SFTP space first. The name of this subdirectory can only contain %1$s, %2$s, %3$s, %4$s and %5$s."
+msgstr "Pour pouvoir créer un site HTTP avec ce service, un sous-dossier pour ce site doit d'abord être créé dans l'espace SFTP. Le nom de ce sous-dossier ne peut contenir que %1$s, %2$s, %3$s, %4$s et %5$s."
+
+#: pg-view/ht/index.php:51
+#, php-format
+msgid "The SFTP space is limited to %s. Indicate the following values to your SFTP client to access it."
+msgstr "L'espace SFTP est limité à %s. Indiquez les valeurs suivantes à votre client pour y accéder."
+
+#: pg-view/ht/index.php:55
+msgid "Authenticating the server"
+msgstr "Authentifier le serveur"
+
+#: pg-view/ht/index.php:57
+msgid "An SSHFP record is available."
+msgstr "Un enregistrement SSHFP est disponible."
+
+#: pg-view/ht/index.php:60
+msgid "Plain public key"
+msgstr "Clé publique"
+
+#: pg-view/ht/index.php:65
+msgid "Public key fingerprint"
+msgstr "Empreinte de la clé publique"
+
+#: pg-view/ht/index.php:70
+msgid "ASCII art"
+msgstr "Art ASCII"
+
+#: pg-view/ht/index.php:77
+msgid "Connecting to the server"
+msgstr "Se connecter au serveur"
+
+#: pg-view/ht/index.php:82
+msgid "Server"
+msgstr "Serveur"
+
+#: pg-view/ht/index.php:86 pg-view/ns/srv.php:16
+msgid "Port"
+msgstr "Port"
+
+#: pg-view/ht/index.php:90
+msgid "Directory"
+msgstr "Dossier"
+
+#: pg-view/ht/index.php:100
+msgid "The one of your account"
+msgstr "Celle de votre compte"
+
+#: pg-view/ht/index.php:111
+msgid "A content security policy (CSP) forbids Web browsers from loading JavaScript or third-party resources."
+msgstr "Une politique de sécurité du contenu (CSP) interdit l'intégration de ressources tierces ou de JavaScript."
+
+#: pg-view/ht/index.php:114
+msgid "gzip compression"
+msgstr "Compression gzip"
+
+#: pg-view/ht/index.php:116
+msgid "Static <em>gzip</em> compression is supported: if the client supports it and the file is available, <code>path.gz</code> is served instead of <code>path</code>."
+msgstr "La compression <em>gzip</em> statique est supportée&nbsp;: si le client le supporte et que le fichier est disponible, <code>chemin.gz</code> est servi au lieu de <code>chemin</code>."
+
+#: pg-view/ht/index.php:119
+msgid "Index page"
+msgstr "Page d'index"
+
+#: pg-view/ht/index.php:121
+msgid "When a request hits a directory, the first of the following files that exists <em>inside this directory</em> is served:"
+msgstr "Lors d'une requête sur un dossier, le premier des fichiers suivants qui existe <em>dans ce dossier</em> est répondu&nbsp;:"
+
+#: pg-view/ht/index.php:129
+msgid "404 error page"
+msgstr "Page d'erreur 404"
+
+#: pg-view/ht/index.php:131
+msgid "When a request ends in a <code>404</code> error, the first of the following files that exists <em>at the root of the site</em> is served:"
+msgstr "Lors d'une requête aboutissant à une erreur <code>404</code>, le premier des fichiers suivants qui existe <em>à la racine du site</em> est répondu&nbsp;:"
+
+#: pg-view/ns/caa.php:3
+msgid "Flag"
+msgstr "Flag"
+
+#: pg-view/ns/caa.php:7 pg-view/ns/print.php:56
+msgid "Tag"
+msgstr "Tag"
+
+#: pg-view/ns/caa.php:11 pg-view/ns/form.ns.php:31 pg-view/ns/print.php:35
+#: pg-view/ns/tlsa.php:37 pg-view/reg/print.php:19
+msgid "Value"
+msgstr "Valeur"
+
+#: pg-view/ns/caa.php:15 pg-view/ns/cname.php:7 pg-view/ns/dname.php:7
+#: pg-view/ns/ip.php:5 pg-view/ns/loc.php:75 pg-view/ns/mx.php:11
+#: pg-view/ns/ns.php:7 pg-view/ns/srv.php:27 pg-view/ns/sshfp.php:29
+#: pg-view/ns/tlsa.php:43 pg-view/ns/txt.php:7 pg-view/reg/ds.php:56
+#: pg-view/reg/glue.php:29 pg-view/reg/ns.php:22
+msgid "Apply"
+msgstr "Appliquer"
+
+#: pg-view/ns/cname.php:3
+msgid "Canonical name"
+msgstr "Nom canonique"
+
+#: pg-view/ns/dname.php:3
+msgid "Delegation name"
+msgstr "Nom délégué"
+
+#: pg-view/ns/edit.php:2
+msgid "Zone to be changed"
+msgstr "Zone à modifier"
+
+#: pg-view/ns/edit.php:12 pg-view/ns/print.php:20 pg-view/reg/print.php:11
+msgid "Display"
+msgstr "Afficher"
+
+#: pg-view/ns/edit.php:23
+#, php-format
+msgid "New content of the %s zone"
+msgstr "Nouveau contenu de la zone %s"
+
+#: pg-view/ns/edit.php:27
+msgid "Replace"
+msgstr "Remplacer"
+
+#: pg-view/ns/edit.php:38
+msgid "Default values"
+msgstr "Valeurs par défaut"
+
+#: pg-view/ns/edit.php:40
+#, php-format
+msgid "If the TTL is omitted, it will default to %s seconds."
+msgstr "Si le TTL est omis, is sera définit à %s secondes."
+
+#: pg-view/ns/edit.php:42
+msgid "Precising the class (<code>IN</code>) is optional."
+msgstr "La précision de la classe (<code>IN</code>) est facultative."
+
+#: pg-view/ns/edit.php:44
+msgid "Allowed values"
+msgstr "Valeurs autorisées"
+
+#: pg-view/ns/edit.php:46
+#, php-format
+msgid "Submitted zone content is limited to %s characters."
+msgstr "La zone n'est pas autorisée à dépasser %s caractères."
+
+#: pg-view/ns/edit.php:48
+#, php-format
+msgid "TTLs must last between %1$s and %2$s seconds."
+msgstr "Les TTLs ne sont autorisés qu'entre %1$s et %2$s secondes."
+
+#: pg-view/ns/edit.php:50
+msgid "The only types that can be defined are:"
+msgstr "Les seuls types dont l'édition est autorisée sont&nbsp;:"
+
+#: pg-view/ns/form.ns.php:1 pg-view/reg/ds.php:2 pg-view/reg/glue.php:2
+#: pg-view/reg/ns.php:2
+msgid "Action"
+msgstr "Action"
+
+#: pg-view/ns/form.ns.php:3 pg-view/ns/zone-add.php:8 pg-view/reg/ds.php:4
+#: pg-view/reg/glue.php:4 pg-view/reg/ns.php:4
+msgid "Add"
+msgstr "Ajouter"
+
+#: pg-view/ns/form.ns.php:15 pg-view/ns/print.php:52 pg-view/ns/zone-del.php:2
+msgid "Zone"
+msgstr "Zone"
+
+#: pg-view/ns/form.ns.php:29 pg-view/ns/print.php:33 pg-view/reg/print.php:17
+msgid "TTL"
+msgstr "TTL"
+
+#: pg-view/ns/form.ns.php:45
+msgid "Unit"
+msgstr "Unité"
+
+#: pg-view/ns/form.ns.php:48
+msgid "second"
+msgstr "seconde"
+
+#: pg-view/ns/form.ns.php:49
+msgid "minute"
+msgstr "minute"
+
+#: pg-view/ns/form.ns.php:50
+msgid "hour"
+msgstr "heure"
+
+#: pg-view/ns/form.ns.php:51
+msgid "day"
+msgstr "jour"
+
+#: pg-view/ns/index.php:2
+msgid "This service allows to host and manage DNS records inside a DNS zone."
+msgstr "Ce service permet d'héberger et de gérer les enregistrements DNS à l'intérieur d'une zone DNS."
+
+#: pg-view/ns/index.php:8
+msgid "Currently hosted zones"
+msgstr "Zones actuellement hébergées"
+
+#: pg-view/ns/index.php:26
+msgid "A zone hosted on this service is served by these name servers:"
+msgstr "Une zone hébergée sur ce service est servie par les serveurs suivants&nbsp;:"
+
+#: pg-view/ns/ip.php:3 pg-view/reg/glue.php:26
+msgid "IP address"
+msgstr "Adresse IP"
+
+#: pg-view/ns/loc.php:4
+msgid "Latitude"
+msgstr "Latitude"
+
+#: pg-view/ns/loc.php:6 pg-view/ns/loc.php:34
+msgid "Degrees"
+msgstr "Dégrés"
+
+#: pg-view/ns/loc.php:11 pg-view/ns/loc.php:39
+msgid "Minutes"
+msgstr "Minutes"
+
+#: pg-view/ns/loc.php:16 pg-view/ns/loc.php:44
+msgid "Seconds"
+msgstr "Secondes"
+
+#: pg-view/ns/loc.php:21 pg-view/ns/loc.php:49
+msgid "Direction"
+msgstr "Direction"
+
+#: pg-view/ns/loc.php:25
+msgid "North"
+msgstr "Nord"
+
+#: pg-view/ns/loc.php:26
+msgid "South"
+msgstr "Sud"
+
+#: pg-view/ns/loc.php:32
+msgid "Longitude"
+msgstr "Longitude"
+
+#: pg-view/ns/loc.php:53
+msgid "East"
+msgstr "Est"
+
+#: pg-view/ns/loc.php:54
+msgid "West"
+msgstr "Ouest"
+
+#: pg-view/ns/loc.php:59
+msgid "Altitude"
+msgstr "Altitude"
+
+#: pg-view/ns/loc.php:63
+msgid "Size"
+msgstr "Taille"
+
+#: pg-view/ns/loc.php:67
+msgid "Horizontal precision"
+msgstr "Précision horizontale"
+
+#: pg-view/ns/loc.php:71
+msgid "Vertical precision"
+msgstr "Précision verticale"
+
+#: pg-view/ns/mx.php:3 pg-view/ns/srv.php:4
+msgid "Priority"
+msgstr "Priorité"
+
+#: pg-view/ns/mx.php:7
+msgid "Host"
+msgstr "Hôte"
+
+#: pg-view/ns/ns.php:3 pg-view/reg/ns.php:18
+msgid "Name server"
+msgstr "Serveur de nom"
+
+#: pg-view/ns/print.php:3
+msgid "Records table"
+msgstr "Tableau des enregistrements"
+
+#: pg-view/ns/print.php:6
+msgid "DS record"
+msgstr "Enregistrement DS"
+
+#: pg-view/ns/print.php:9
+msgid "Raw zonefile"
+msgstr "Fichier de zone brut"
+
+#: pg-view/ns/print.php:11
+msgid "Selected zone"
+msgstr "Zone"
+
+#: pg-view/ns/print.php:34 pg-view/reg/print.php:18
+msgid "Type"
+msgstr "Type"
+
+#: pg-view/ns/print.php:60 pg-view/ns/sshfp.php:4 pg-view/reg/ds.php:22
+msgid "Algorithm"
+msgstr "Algorithme"
+
+#: pg-view/ns/print.php:64 pg-view/reg/ds.php:41
+msgid "Digest type"
+msgstr "Type de condensat"
+
+#: pg-view/ns/print.php:68
+msgid "Digest"
+msgstr "Condensat"
+
+#: pg-view/ns/srv.php:10
+msgid "Weight"
+msgstr "Poids"
+
+#: pg-view/ns/srv.php:22
+msgid "Target"
+msgstr "Cible"
+
+#: pg-view/ns/sshfp.php:15
+msgid "Hash type"
+msgstr "Type de hash"
+
+#: pg-view/ns/sshfp.php:24
+msgid "Fingerprint"
+msgstr "Empreinte"
+
+#: pg-view/ns/tlsa.php:4
+msgid "Use"
+msgstr "Utilisation"
+
+#: pg-view/ns/tlsa.php:16
+msgid "Selector"
+msgstr "Selecteur"
+
+#: pg-view/ns/tlsa.php:20
+msgid "the full certificate must match"
+msgstr "le certificat entier doit correspondre"
+
+#: pg-view/ns/tlsa.php:21
+msgid "the certificate public key must match"
+msgstr "la clé publique du certificat doit correspondre"
+
+#: pg-view/ns/tlsa.php:26
+msgid "Match type"
+msgstr "Type de correspondance"
+
+#: pg-view/ns/tlsa.php:30
+msgid "full certificate"
+msgstr "certificat entier"
+
+#: pg-view/ns/txt.php:3
+msgid "Text"
+msgstr "Texte"
+
+#: pg-view/ns/txt.php:5
+msgid "Some text…"
+msgstr "Du texte…"
+
+#: pg-view/ns/zone-add.php:2
+#, php-format
+msgid "To prove that you own this domain, it must have a NS record equal to %s when the form is being processed."
+msgstr "Pour prouver que vous possédez bien ce domaine, il doit posséder un enregistrement NS égal à %s lors du traitement de ce formulaire."
+
+#: pg-view/ns/zone-del.php:11
+msgid "Delete everything related to this zone"
+msgstr "Supprimer tout de cette zone"
+
+#: pg-view/reg/ds.php:18
+msgid "Key tag"
+msgstr "Tag de la clé"
+
+#: pg-view/reg/ds.php:52
+msgid "Key"
+msgstr "Condensat"
+
+#: pg-view/reg/glue.php:27
+#, php-format
+msgid "%1$s or %2$s"
+msgstr "%1$s ou %2$s"
+
+#: pg-view/reg/index.php:2
+#, php-format
+msgid "This domain name registry allows to register domains ending with <code>%1$s</code>, for instance <code><em>domain</em>%1$s</code>."
+msgstr "Ce registre de noms de domaine permet d'enregistrer des domaines se terminant par <code>%1$s</code>, par exemple <code><em>domaine</em>%1$s</code>."
+
+#: pg-view/reg/index.php:7
+msgid "Currently registered domains"
+msgstr "Domaines actuellement enregistrés"
+
+#: pg-view/reg/register.php:2
+msgid "Register a new domain on your account. It must consist of between 4 and 63 letters and digits."
+msgstr "Enregistrer un nouveau domaine sur son compte. Il doit être composé d'entre 4 et 63 lettres et chiffres."
+
+#: pg-view/reg/transfer.php:2
+#, php-format
+msgid "To prove that you are allowed to receive the domain by its current owner, the domain must have an NS record equal to %s when the form is being processed. The NS record will be automatically deleted once validated."
+msgstr "Pour prouver que vous êtes autorisé à recevoir le domaine par san possessaire actuele, ledit domaine doit posséder un enregistrement NS égal à %s lors du traitement de ce formulaire. Cet enregistrement sera automatiquement retiré une fois validé."
+
+#: pg-view/reg/transfer.php:6
+msgid "Subdomain that will be transferred to this account"
+msgstr "Sous-domaine à transférer vers ce compte"
+
+#: pg-view/reg/transfer.php:10
+msgid "Receive the domain"
+msgstr "Recevoir le domaine"
+
+#: pg-view/reg/unregister.php:2
+msgid "This will unregister the domain, making it registerable by anyone again."
+msgstr "Ceci désenregistrera le domaine, ce qui le re-disponibilisera à tout le monde."
+
+#: pg-view/reg/unregister.php:16
+msgid "Unregister"
+msgstr "Désenregistrer"

+ 1094 - 0
locales/messages.pot

@@ -0,0 +1,1094 @@
+#: pages.php:9
+msgid "Authentication"
+msgstr ""
+
+#: pages.php:10
+msgid "Manage account"
+msgstr ""
+
+#: pages.php:13 view.php:21 pg-view/auth/login.php:12
+#: pg-view/auth/register.php:1
+msgid "Log in"
+msgstr ""
+
+#: pages.php:14
+msgid "Start a new navigation session with an existing account"
+msgstr ""
+
+#: pages.php:18 view.php:19
+msgid "Log out"
+msgstr ""
+
+#: pages.php:19
+msgid "End the current session and delete cookies and cache"
+msgstr ""
+
+#: pages.php:22
+msgid "Create account"
+msgstr ""
+
+#: pages.php:23
+msgid "Create a new account, and log in with it"
+msgstr ""
+
+#: pages.php:28
+msgid "Delete account"
+msgstr ""
+
+#: pages.php:29
+msgid "Erase all current account's data"
+msgstr ""
+
+#: pages.php:32
+msgid "Switch to an approved account"
+msgstr ""
+
+#: pages.php:33
+msgid "Switch to an approved account using an approval key"
+msgstr ""
+
+#: pages.php:36
+msgid "Change password"
+msgstr ""
+
+#: pages.php:37
+msgid "Change the character string used to authenticate yourself"
+msgstr ""
+
+#: pages.php:40
+msgid "Change username"
+msgstr ""
+
+#: pages.php:41
+msgid "Change the name used to identify your account when logging in and displayed at the start of every page"
+msgstr ""
+
+#: pages.php:46
+#, php-format
+msgid "%s registry"
+msgstr ""
+
+#: pages.php:47
+#, php-format
+msgid "Register and delegate a %s subdomain"
+msgstr ""
+
+#: pages.php:50
+msgid "Register domain"
+msgstr ""
+
+#: pages.php:51
+#, php-format
+msgid "Get a %s subdomain"
+msgstr ""
+
+#: pages.php:55
+msgid "Unregister domain"
+msgstr ""
+
+#: pages.php:56
+msgid "Delete all data related to a domain and make it available to the public again"
+msgstr ""
+
+#: pages.php:59
+msgid "Display domain records"
+msgstr ""
+
+#: pages.php:60
+msgid "Print every record related to a domain and served by the registry"
+msgstr ""
+
+#: pages.php:63 pages.php:67 pages.php:107 pages.php:111 pages.php:115
+#: pages.php:119 pages.php:123 pages.php:127 pages.php:131 pages.php:135
+#: pages.php:139 pages.php:143
+#, php-format
+msgid "%s records"
+msgstr ""
+
+#: pages.php:64
+#, php-format
+msgid "Indicate the name servers of a %s subdomain"
+msgstr ""
+
+#: pages.php:68
+msgid "Delegate <abbr title=\"Domain Name System Security Extensions\">DNSSEC</abbr> trust"
+msgstr ""
+
+#: pages.php:71
+msgid "Receive a domain transfer"
+msgstr ""
+
+#: pages.php:72
+msgid "Transfer a domain owned by another account to the current account"
+msgstr ""
+
+#: pages.php:75
+msgid "Glue records"
+msgstr ""
+
+#: pages.php:76
+msgid "Advanced: store the IP address of a name server whose domain is inside the domain it serves"
+msgstr ""
+
+#: pages.php:81 pg-view/ns/index.php:24
+msgid "Name servers"
+msgstr ""
+
+#: pages.php:82
+msgid "Host and manage domain's records"
+msgstr ""
+
+#: pages.php:85
+msgid "Add zone"
+msgstr ""
+
+#: pages.php:86
+#, php-format
+msgid "The zone will be managed by %s name servers"
+msgstr ""
+
+#: pages.php:90
+msgid "Delete zone"
+msgstr ""
+
+#: pages.php:91
+msgid "Erase all zone data"
+msgstr ""
+
+#: pages.php:94
+msgid "Display zone"
+msgstr ""
+
+#: pages.php:95
+msgid "Print zonefile content"
+msgstr ""
+
+#: pages.php:98
+msgid "Edit zone"
+msgstr ""
+
+#: pages.php:99
+msgid "Change zonefile content"
+msgstr ""
+
+#: pages.php:103
+msgid "AAAA and A records"
+msgstr ""
+
+#: pages.php:104
+msgid "Store domain's IP address"
+msgstr ""
+
+#: pages.php:108
+msgid "Store zone's name server"
+msgstr ""
+
+#: pages.php:112
+msgid "Associate text to domain"
+msgstr ""
+
+#: pages.php:116
+msgid "Limit the certificate authorities allowed to certify the domain"
+msgstr ""
+
+#: pages.php:120
+msgid "Store the location of a domain's service"
+msgstr ""
+
+#: pages.php:124
+msgid "Store the email server's address"
+msgstr ""
+
+#: pages.php:128
+msgid "Store <abbr title=\"Secure SHell\">SSH</abbr> public keys fingerprints"
+msgstr ""
+
+#: pages.php:132
+msgid "Setup <abbr title=\"DNS-based Authentication of Named Entities\">DANE</abbr> by publishing the <abbr title=\"Transport Layer Security\">TLS</abbr> certificate fingerprint"
+msgstr ""
+
+#: pages.php:136
+msgid "Define a domain as an alias of another"
+msgstr ""
+
+#: pages.php:140
+msgid "Define all subdomains of a domain as aliases of subdomains of another domain"
+msgstr ""
+
+#: pages.php:144
+msgid "Store geographic coordinates"
+msgstr ""
+
+#: pages.php:149
+msgid "Web"
+msgstr ""
+
+#: pages.php:150
+msgid "Upload a static website into an <abbr title=\"SSH File Transfer Protocol\">SFTP</abbr> space"
+msgstr ""
+
+#: pages.php:153
+#, php-format
+msgid "%s subpath access"
+msgstr ""
+
+#: pages.php:154 pages.php:159 pages.php:164
+#, php-format
+msgid "Its URL will look like %s"
+msgstr ""
+
+#: pages.php:154 pages.php:159 pages.php:164
+msgid "mysite"
+msgstr ""
+
+#: pages.php:158
+#, php-format
+msgid "%s subdomain access"
+msgstr ""
+
+#: pages.php:163
+msgid "Dedicated domain with Let's Encrypt certificate access"
+msgstr ""
+
+#: pages.php:168
+msgid "Onion service access"
+msgstr ""
+
+#: pages.php:169
+#, php-format
+msgid "Its URL will look like %s, and work only through the Tor network"
+msgstr ""
+
+#: pages.php:173 pg-view/ht/del.php:18
+msgid "Delete access"
+msgstr ""
+
+#: pages.php:174
+msgid "Delete an existing HTTP access from a subdirectory of the SFTP space"
+msgstr ""
+
+#: router.php:120
+msgid "You need to be logged in to do this."
+msgstr ""
+
+#: router.php:122
+msgid "This account doesn't exist anymore. Log out to end this ghost session."
+msgstr ""
+
+#: view.php:21
+msgid "Anonymous"
+msgstr ""
+
+#: view.php:41
+#, php-format
+msgid "This form won't be accepted because you need to %slog in%s first."
+msgstr ""
+
+#: view.php:48
+#, php-format
+msgid "%sSource code%s available under %s."
+msgstr ""
+
+#: fn/auth.php:108
+msgid "Account rate limit reached, try again later."
+msgstr ""
+
+#: fn/auth.php:130
+msgid "Global rate limit reached, try again later."
+msgstr ""
+
+#: fn/common.php:9
+msgid "<strong>Success</strong>: "
+msgstr ""
+
+#: fn/common.php:10
+msgid "<strong>User error</strong>: "
+msgstr ""
+
+#: fn/common.php:11
+msgid "<strong>Server error</strong>: "
+msgstr ""
+
+#: fn/common.php:133
+msgid "Wrong proof."
+msgstr ""
+
+#: fn/dns.php:62
+msgid "IP address malformed."
+msgstr ""
+
+#: fn/dns.php:67 fn/ht.php:6
+msgid "Domain malformed."
+msgstr ""
+
+#: fn/ns.php:40 pg-act/ns/edit.php:25
+#, php-format
+msgid "TTLs shorter than %s seconds are forbidden."
+msgstr ""
+
+#: fn/ns.php:42 pg-act/ns/edit.php:27
+#, php-format
+msgid "TTLs longer than %s seconds are forbidden."
+msgstr ""
+
+#: pg-act/auth/approval.php:4
+msgid "This account is already approved."
+msgstr ""
+
+#: pg-act/auth/approval.php:7
+msgid "This approval key is not available. It has been mistyped, used for another account, or has expired."
+msgstr ""
+
+#: pg-act/auth/approval.php:18
+msgid "Account approved."
+msgstr ""
+
+#: pg-act/auth/login.php:10
+msgid "This account does not exist."
+msgstr ""
+
+#: pg-act/auth/login.php:15
+msgid "Wrong password."
+msgstr ""
+
+#: pg-act/auth/password.php:6
+msgid "Wrong current password."
+msgstr ""
+
+#: pg-act/auth/password.php:10
+msgid "Password updated."
+msgstr ""
+
+#: pg-act/auth/register.php:10 pg-act/auth/username.php:8
+msgid "This username is already taken."
+msgstr ""
+
+#: pg-act/auth/unregister.php:4
+msgid "Account deletion must be confirmed."
+msgstr ""
+
+#: pg-act/auth/unregister.php:29
+msgid "Account deleted."
+msgstr ""
+
+#: pg-act/auth/username.php:17
+msgid "Username updated."
+msgstr ""
+
+#: pg-act/ht/add-dns.php:9 pg-act/ht/add-subdomain.php:10
+msgid "This domain already exists on this service. Use another one."
+msgstr ""
+
+#: pg-act/ht/add-dns.php:13 pg-act/ht/add-dns.php:19 pg-act/ht/add-dns.php:25
+#, php-format
+msgid "Can't retrieve the %s record."
+msgstr ""
+
+#: pg-act/ht/add-dns.php:15 pg-act/ht/add-dns.php:21
+#, php-format
+msgid "This domain must have %2$s as its only %1$s record."
+msgstr ""
+
+#: pg-act/ht/add-dns.php:27
+msgid "No TXT record with the expected format has been found."
+msgstr ""
+
+#: pg-act/ht/add-dns.php:59 pg-act/ht/add-onion.php:47
+#: pg-act/ht/add-subdomain.php:19 pg-act/ht/add-subpath.php:19
+#, php-format
+msgid "%s added on this directory."
+msgstr ""
+
+#: pg-act/ht/add-onion.php:47
+#, php-format
+msgid "Its address is: %s"
+msgstr ""
+
+#: pg-act/ht/add-subdomain.php:7
+msgid "Invalid domain label."
+msgstr ""
+
+#: pg-act/ht/add-subpath.php:7
+msgid "Invalid path."
+msgstr ""
+
+#: pg-act/ht/add-subpath.php:10
+msgid "This path already exists on this service. Use another one."
+msgstr ""
+
+#: pg-act/ht/del.php:11
+msgid "Access removed."
+msgstr ""
+
+#: pg-act/ns/caa.php:23 pg-act/ns/cname.php:14 pg-act/ns/dname.php:14
+#: pg-act/ns/ip.php:14 pg-act/ns/loc.php:70 pg-act/ns/mx.php:18
+#: pg-act/ns/ns.php:14 pg-act/ns/srv.php:26 pg-act/ns/sshfp.php:23
+#: pg-act/ns/tlsa.php:27 pg-act/ns/txt.php:15 pg-act/reg/ds.php:30
+#: pg-act/reg/glue.php:16 pg-act/reg/ns.php:13
+msgid "Modification done."
+msgstr ""
+
+#: pg-act/ns/edit.php:17
+#, php-format
+msgid "The zone is limited to %s characters."
+msgstr ""
+
+#: pg-act/ns/edit.php:21
+msgid "The following line does not match the expected format: "
+msgstr ""
+
+#: pg-act/ns/edit.php:23
+#, php-format
+msgid "The %s type is not allowed."
+msgstr ""
+
+#: pg-act/ns/edit.php:38
+msgid "Sent zone content is not correct (according to <code>kzonecheck</code>)."
+msgstr ""
+
+#: pg-act/ns/zone-add.php:6
+msgid "This zone already exists on the service."
+msgstr ""
+
+#: pg-act/ns/zone-add.php:10
+msgid "Parent zone's name servers not found."
+msgstr ""
+
+#: pg-act/ns/zone-add.php:16 pg-act/reg/transfer.php:13
+msgid "NS authentication record not found."
+msgstr ""
+
+#: pg-act/ns/zone-add.php:52
+msgid "Zone created."
+msgstr ""
+
+#: pg-act/ns/zone-del.php:7
+msgid "Zone deleted."
+msgstr ""
+
+#: pg-act/reg/register.php:4
+msgid "This format of subdomain is not allowed."
+msgstr ""
+
+#: pg-act/reg/register.php:9
+msgid "This domain is already registered."
+msgstr ""
+
+#: pg-act/reg/register.php:12
+msgid "This domain is reserved."
+msgstr ""
+
+#: pg-act/reg/register.php:22
+msgid "Domain registered."
+msgstr ""
+
+#: pg-act/reg/transfer.php:9
+msgid "The current account already owns this domain."
+msgstr ""
+
+#: pg-act/reg/transfer.php:26
+msgid "The domain has been transferred to the current account ; the NS authentication record has been automatically deleted."
+msgstr ""
+
+#: pg-act/reg/unregister.php:7
+msgid "Domain unregistered."
+msgstr ""
+
+#: pg-view/auth/approval.php:2
+msgid "This form allows to use an approval key to validate your account. Approval keys are distributed by an administrator upon request."
+msgstr ""
+
+#: pg-view/auth/approval.php:6
+msgid "Approval key"
+msgstr ""
+
+#: pg-view/auth/approval.php:9
+msgid "Use for this account"
+msgstr ""
+
+#: pg-view/auth/index.php:5
+msgid "You are currently using a testing account."
+msgstr ""
+
+#: pg-view/auth/index.php:6
+msgid "You are currently using an approved account."
+msgstr ""
+
+#: pg-view/auth/index.php:7
+#, php-format
+msgid "It's internal ID is %s."
+msgstr ""
+
+#: pg-view/auth/index.php:9
+msgid "You are not logged in."
+msgstr ""
+
+#: pg-view/auth/index.php:13
+msgid "Account types"
+msgstr ""
+
+#: pg-view/auth/index.php:16
+msgid "Testing"
+msgstr ""
+
+#: pg-view/auth/index.php:18
+msgid "It's the default account type, with limited capabilities in order to avoid abuses:"
+msgstr ""
+
+#: pg-view/auth/index.php:20
+msgid "May be deleted anytime"
+msgstr ""
+
+#: pg-view/auth/index.php:21 pg-view/auth/index.php:29
+#, php-format
+msgid "%s of SFTP quota"
+msgstr ""
+
+#: pg-view/auth/index.php:21 pg-view/auth/index.php:29 pg-view/ht/index.php:51
+msgid "<abbr title=\"gibibyte\">GiB</abbr>"
+msgstr ""
+
+#: pg-view/auth/index.php:21 pg-view/auth/index.php:29 pg-view/ht/index.php:51
+msgid "<abbr title=\"mebibyte\">MiB</abbr>"
+msgstr ""
+
+#: pg-view/auth/index.php:22
+msgid "Let's Encrypt certificate from the staging environment (not trusted by clients)"
+msgstr ""
+
+#: pg-view/auth/index.php:25
+msgid "Approved"
+msgstr ""
+
+#: pg-view/auth/index.php:27
+msgid "It was originally a testing account, but has been approved by an administrator, and is suited for stable usecases:"
+msgstr ""
+
+#: pg-view/auth/index.php:30
+msgid "Stable Let's Encrypt certificates"
+msgstr ""
+
+#: pg-view/auth/login.php:1
+msgid "Need an accout?"
+msgstr ""
+
+#: pg-view/auth/login.php:1 pg-view/reg/register.php:10
+msgid "Register"
+msgstr ""
+
+#: pg-view/auth/login.php:4 pg-view/auth/register.php:4 pg-view/ht/index.php:94
+msgid "Username"
+msgstr ""
+
+#: pg-view/auth/login.php:8 pg-view/auth/register.php:9 pg-view/ht/index.php:98
+msgid "Password"
+msgstr ""
+
+#: pg-view/auth/password.php:2
+msgid "Current password"
+msgstr ""
+
+#: pg-view/auth/password.php:5
+msgid "New password"
+msgstr ""
+
+#: pg-view/auth/password.php:8
+msgid "Update password"
+msgstr ""
+
+#: pg-view/auth/register.php:1
+msgid "Already have an account?"
+msgstr ""
+
+#: pg-view/auth/register.php:10
+#, php-format
+msgid "Minimum %1$s characters, or %2$s characters if it contains lowercase, uppercase and digit."
+msgstr ""
+
+#: pg-view/auth/register.php:14
+msgid "Create an account"
+msgstr ""
+
+#: pg-view/auth/unregister.php:2
+msgid "This will delete every resource managed by the current account, including registered domains, hosted DNS records, websites files and cryptographic keys for Onion services and DNSSEC."
+msgstr ""
+
+#: pg-view/auth/unregister.php:7
+msgid "Delete the current account and everything related (required)"
+msgstr ""
+
+#: pg-view/auth/unregister.php:9 pg-view/ns/form.ns.php:4 pg-view/reg/ds.php:5
+#: pg-view/reg/glue.php:5 pg-view/reg/ns.php:5
+msgid "Delete"
+msgstr ""
+
+#: pg-view/auth/username.php:2
+msgid "New username"
+msgstr ""
+
+#: pg-view/auth/username.php:5
+msgid "Update username"
+msgstr ""
+
+#: pg-view/ht/add-dns.php:2
+msgid "A Let's Encrypt certificate will be obtained."
+msgstr ""
+
+#: pg-view/ht/add-dns.php:6
+msgid "The domain must have the following records when the form is being processed."
+msgstr ""
+
+#: pg-view/ht/add-dns.php:25 pg-view/ns/form.ns.php:8 pg-view/ns/print.php:32
+#: pg-view/ns/zone-add.php:6 pg-view/reg/ds.php:8 pg-view/reg/glue.php:8
+#: pg-view/reg/glue.php:15 pg-view/reg/ns.php:8 pg-view/reg/print.php:2
+#: pg-view/reg/print.php:16 pg-view/reg/unregister.php:6
+msgid "Domain"
+msgstr ""
+
+#: pg-view/ht/add-dns.php:27 pg-view/ht/add-onion.php:2
+#: pg-view/ht/add-subdomain.php:4 pg-view/ht/add-subpath.php:4
+msgid "Target directory"
+msgstr ""
+
+#: pg-view/ht/add-dns.php:36 pg-view/ht/add-onion.php:11
+#: pg-view/ht/add-subdomain.php:13 pg-view/ht/add-subpath.php:13
+msgid "Setup access"
+msgstr ""
+
+#: pg-view/ht/add-subdomain.php:2 pg-view/ns/form.ns.php:10
+#: pg-view/reg/glue.php:10 pg-view/reg/register.php:6
+msgid "Subdomain"
+msgstr ""
+
+#: pg-view/ht/add-subpath.php:2
+msgid "Path"
+msgstr ""
+
+#: pg-view/ht/del.php:2
+msgid "Access to delete"
+msgstr ""
+
+#: pg-view/ht/index.php:2
+msgid "This service allows you to send files on the server using SFTP, and to make them publicly available with HTTP."
+msgstr ""
+
+#: pg-view/ht/index.php:8
+msgid "Currently hosted sites"
+msgstr ""
+
+#: pg-view/ht/index.php:38
+msgid "Adding a site access"
+msgstr ""
+
+#: pg-view/ht/index.php:40
+#, php-format
+msgid "In order to be able to setup an HTTP site with this service, a subdirectory for this site must be created inside the SFTP space first. The name of this subdirectory can only contain %1$s, %2$s, %3$s, %4$s and %5$s."
+msgstr ""
+
+#: pg-view/ht/index.php:51
+#, php-format
+msgid "The SFTP space is limited to %s. Indicate the following values to your SFTP client to access it."
+msgstr ""
+
+#: pg-view/ht/index.php:55
+msgid "Authenticating the server"
+msgstr ""
+
+#: pg-view/ht/index.php:57
+msgid "An SSHFP record is available."
+msgstr ""
+
+#: pg-view/ht/index.php:60
+msgid "Plain public key"
+msgstr ""
+
+#: pg-view/ht/index.php:65
+msgid "Public key fingerprint"
+msgstr ""
+
+#: pg-view/ht/index.php:70
+msgid "ASCII art"
+msgstr ""
+
+#: pg-view/ht/index.php:77
+msgid "Connecting to the server"
+msgstr ""
+
+#: pg-view/ht/index.php:82
+msgid "Server"
+msgstr ""
+
+#: pg-view/ht/index.php:86 pg-view/ns/srv.php:16
+msgid "Port"
+msgstr ""
+
+#: pg-view/ht/index.php:90
+msgid "Directory"
+msgstr ""
+
+#: pg-view/ht/index.php:100
+msgid "The one of your account"
+msgstr ""
+
+#: pg-view/ht/index.php:111
+msgid "A content security policy (CSP) forbids Web browsers from loading JavaScript or third-party resources."
+msgstr ""
+
+#: pg-view/ht/index.php:114
+msgid "gzip compression"
+msgstr ""
+
+#: pg-view/ht/index.php:116
+msgid "Static <em>gzip</em> compression is supported: if the client supports it and the file is available, <code>path.gz</code> is served instead of <code>path</code>."
+msgstr ""
+
+#: pg-view/ht/index.php:119
+msgid "Index page"
+msgstr ""
+
+#: pg-view/ht/index.php:121
+msgid "When a request hits a directory, the first of the following files that exists <em>inside this directory</em> is served:"
+msgstr ""
+
+#: pg-view/ht/index.php:129
+msgid "404 error page"
+msgstr ""
+
+#: pg-view/ht/index.php:131
+msgid "When a request ends in a <code>404</code> error, the first of the following files that exists <em>at the root of the site</em> is served:"
+msgstr ""
+
+#: pg-view/ns/caa.php:3
+msgid "Flag"
+msgstr ""
+
+#: pg-view/ns/caa.php:7 pg-view/ns/print.php:56
+msgid "Tag"
+msgstr ""
+
+#: pg-view/ns/caa.php:11 pg-view/ns/form.ns.php:31 pg-view/ns/print.php:35
+#: pg-view/ns/tlsa.php:37 pg-view/reg/print.php:19
+msgid "Value"
+msgstr ""
+
+#: pg-view/ns/caa.php:15 pg-view/ns/cname.php:7 pg-view/ns/dname.php:7
+#: pg-view/ns/ip.php:5 pg-view/ns/loc.php:75 pg-view/ns/mx.php:11
+#: pg-view/ns/ns.php:7 pg-view/ns/srv.php:27 pg-view/ns/sshfp.php:29
+#: pg-view/ns/tlsa.php:43 pg-view/ns/txt.php:7 pg-view/reg/ds.php:56
+#: pg-view/reg/glue.php:29 pg-view/reg/ns.php:22
+msgid "Apply"
+msgstr ""
+
+#: pg-view/ns/cname.php:3
+msgid "Canonical name"
+msgstr ""
+
+#: pg-view/ns/dname.php:3
+msgid "Delegation name"
+msgstr ""
+
+#: pg-view/ns/edit.php:2
+msgid "Zone to be changed"
+msgstr ""
+
+#: pg-view/ns/edit.php:12 pg-view/ns/print.php:20 pg-view/reg/print.php:11
+msgid "Display"
+msgstr ""
+
+#: pg-view/ns/edit.php:23
+#, php-format
+msgid "New content of the %s zone"
+msgstr ""
+
+#: pg-view/ns/edit.php:27
+msgid "Replace"
+msgstr ""
+
+#: pg-view/ns/edit.php:38
+msgid "Default values"
+msgstr ""
+
+#: pg-view/ns/edit.php:40
+#, php-format
+msgid "If the TTL is omitted, it will default to %s seconds."
+msgstr ""
+
+#: pg-view/ns/edit.php:42
+msgid "Precising the class (<code>IN</code>) is optional."
+msgstr ""
+
+#: pg-view/ns/edit.php:44
+msgid "Allowed values"
+msgstr ""
+
+#: pg-view/ns/edit.php:46
+#, php-format
+msgid "Submitted zone content is limited to %s characters."
+msgstr ""
+
+#: pg-view/ns/edit.php:48
+#, php-format
+msgid "TTLs must last between %1$s and %2$s seconds."
+msgstr ""
+
+#: pg-view/ns/edit.php:50
+msgid "The only types that can be defined are:"
+msgstr ""
+
+#: pg-view/ns/form.ns.php:1 pg-view/reg/ds.php:2 pg-view/reg/glue.php:2
+#: pg-view/reg/ns.php:2
+msgid "Action"
+msgstr ""
+
+#: pg-view/ns/form.ns.php:3 pg-view/ns/zone-add.php:8 pg-view/reg/ds.php:4
+#: pg-view/reg/glue.php:4 pg-view/reg/ns.php:4
+msgid "Add"
+msgstr ""
+
+#: pg-view/ns/form.ns.php:15 pg-view/ns/print.php:52 pg-view/ns/zone-del.php:2
+msgid "Zone"
+msgstr ""
+
+#: pg-view/ns/form.ns.php:29 pg-view/ns/print.php:33 pg-view/reg/print.php:17
+msgid "TTL"
+msgstr ""
+
+#: pg-view/ns/form.ns.php:45
+msgid "Unit"
+msgstr ""
+
+#: pg-view/ns/form.ns.php:48
+msgid "second"
+msgstr ""
+
+#: pg-view/ns/form.ns.php:49
+msgid "minute"
+msgstr ""
+
+#: pg-view/ns/form.ns.php:50
+msgid "hour"
+msgstr ""
+
+#: pg-view/ns/form.ns.php:51
+msgid "day"
+msgstr ""
+
+#: pg-view/ns/index.php:2
+msgid "This service allows to host and manage DNS records inside a DNS zone."
+msgstr ""
+
+#: pg-view/ns/index.php:8
+msgid "Currently hosted zones"
+msgstr ""
+
+#: pg-view/ns/index.php:26
+msgid "A zone hosted on this service is served by these name servers:"
+msgstr ""
+
+#: pg-view/ns/ip.php:3 pg-view/reg/glue.php:26
+msgid "IP address"
+msgstr ""
+
+#: pg-view/ns/loc.php:4
+msgid "Latitude"
+msgstr ""
+
+#: pg-view/ns/loc.php:6 pg-view/ns/loc.php:34
+msgid "Degrees"
+msgstr ""
+
+#: pg-view/ns/loc.php:11 pg-view/ns/loc.php:39
+msgid "Minutes"
+msgstr ""
+
+#: pg-view/ns/loc.php:16 pg-view/ns/loc.php:44
+msgid "Seconds"
+msgstr ""
+
+#: pg-view/ns/loc.php:21 pg-view/ns/loc.php:49
+msgid "Direction"
+msgstr ""
+
+#: pg-view/ns/loc.php:25
+msgid "North"
+msgstr ""
+
+#: pg-view/ns/loc.php:26
+msgid "South"
+msgstr ""
+
+#: pg-view/ns/loc.php:32
+msgid "Longitude"
+msgstr ""
+
+#: pg-view/ns/loc.php:53
+msgid "East"
+msgstr ""
+
+#: pg-view/ns/loc.php:54
+msgid "West"
+msgstr ""
+
+#: pg-view/ns/loc.php:59
+msgid "Altitude"
+msgstr ""
+
+#: pg-view/ns/loc.php:63
+msgid "Size"
+msgstr ""
+
+#: pg-view/ns/loc.php:67
+msgid "Horizontal precision"
+msgstr ""
+
+#: pg-view/ns/loc.php:71
+msgid "Vertical precision"
+msgstr ""
+
+#: pg-view/ns/mx.php:3 pg-view/ns/srv.php:4
+msgid "Priority"
+msgstr ""
+
+#: pg-view/ns/mx.php:7
+msgid "Host"
+msgstr ""
+
+#: pg-view/ns/ns.php:3 pg-view/reg/ns.php:18
+msgid "Name server"
+msgstr ""
+
+#: pg-view/ns/print.php:3
+msgid "Records table"
+msgstr ""
+
+#: pg-view/ns/print.php:6
+msgid "DS record"
+msgstr ""
+
+#: pg-view/ns/print.php:9
+msgid "Raw zonefile"
+msgstr ""
+
+#: pg-view/ns/print.php:11
+msgid "Selected zone"
+msgstr ""
+
+#: pg-view/ns/print.php:34 pg-view/reg/print.php:18
+msgid "Type"
+msgstr ""
+
+#: pg-view/ns/print.php:60 pg-view/ns/sshfp.php:4 pg-view/reg/ds.php:22
+msgid "Algorithm"
+msgstr ""
+
+#: pg-view/ns/print.php:64 pg-view/reg/ds.php:41
+msgid "Digest type"
+msgstr ""
+
+#: pg-view/ns/print.php:68
+msgid "Digest"
+msgstr ""
+
+#: pg-view/ns/srv.php:10
+msgid "Weight"
+msgstr ""
+
+#: pg-view/ns/srv.php:22
+msgid "Target"
+msgstr ""
+
+#: pg-view/ns/sshfp.php:15
+msgid "Hash type"
+msgstr ""
+
+#: pg-view/ns/sshfp.php:24
+msgid "Fingerprint"
+msgstr ""
+
+#: pg-view/ns/tlsa.php:4
+msgid "Use"
+msgstr ""
+
+#: pg-view/ns/tlsa.php:16
+msgid "Selector"
+msgstr ""
+
+#: pg-view/ns/tlsa.php:20
+msgid "the full certificate must match"
+msgstr ""
+
+#: pg-view/ns/tlsa.php:21
+msgid "the certificate public key must match"
+msgstr ""
+
+#: pg-view/ns/tlsa.php:26
+msgid "Match type"
+msgstr ""
+
+#: pg-view/ns/tlsa.php:30
+msgid "full certificate"
+msgstr ""
+
+#: pg-view/ns/txt.php:3
+msgid "Text"
+msgstr ""
+
+#: pg-view/ns/txt.php:5
+msgid "Some text…"
+msgstr ""
+
+#: pg-view/ns/zone-add.php:2
+#, php-format
+msgid "To prove that you own this domain, it must have a NS record equal to %s when the form is being processed."
+msgstr ""
+
+#: pg-view/ns/zone-del.php:11
+msgid "Delete everything related to this zone"
+msgstr ""
+
+#: pg-view/reg/ds.php:18
+msgid "Key tag"
+msgstr ""
+
+#: pg-view/reg/ds.php:52
+msgid "Key"
+msgstr ""
+
+#: pg-view/reg/glue.php:27
+#, php-format
+msgid "%1$s or %2$s"
+msgstr ""
+
+#: pg-view/reg/index.php:2
+#, php-format
+msgid "This domain name registry allows to register domains ending with <code>%1$s</code>, for instance <code><em>domain</em>%1$s</code>."
+msgstr ""
+
+#: pg-view/reg/index.php:7
+msgid "Currently registered domains"
+msgstr ""
+
+#: pg-view/reg/register.php:2
+msgid "Register a new domain on your account. It must consist of between 4 and 63 letters and digits."
+msgstr ""
+
+#: pg-view/reg/transfer.php:2
+#, php-format
+msgid "To prove that you are allowed to receive the domain by its current owner, the domain must have an NS record equal to %s when the form is being processed. The NS record will be automatically deleted once validated."
+msgstr ""
+
+#: pg-view/reg/transfer.php:6
+msgid "Subdomain that will be transferred to this account"
+msgstr ""
+
+#: pg-view/reg/transfer.php:10
+msgid "Receive the domain"
+msgstr ""
+
+#: pg-view/reg/unregister.php:2
+msgid "This will unregister the domain, making it registerable by anyone again."
+msgstr ""
+
+#: pg-view/reg/unregister.php:16
+msgid "Unregister"
+msgstr ""

+ 79 - 79
pages.php

@@ -2,176 +2,176 @@
 
 
 define('PAGES', [
 define('PAGES', [
 	'index' => [
 	'index' => [
-		'title' => '<span aria-hidden="true">🪐 </span>Niver',
+		'title' => '<span aria-hidden="true">' . CONF['common']['service_emoji'] . ' </span>' . CONF['common']['service_name'],
 	],
 	],
 	'auth' => [
 	'auth' => [
 		'index' => [
 		'index' => [
-			'title' => '<span aria-hidden="true">🔐 </span>Authentification',
-			'description' => 'Gérer son compte',
+			'title' => '<span aria-hidden="true">🔐 </span>' . _('Authentication'),
+			'description' => _('Manage account'),
 		],
 		],
 		'login' => [
 		'login' => [
-			'title' => 'Se connecter',
-			'description' => 'Démarrer une nouvelle session avec un compte existant',
+			'title' => _('Log in'),
+			'description' => _('Start a new navigation session with an existing account'),
 			'require-login' => false,
 			'require-login' => false,
 		],
 		],
+		'logout' => [
+			'title' => _('Log out'),
+			'description' => _('End the current session and delete cookies and cache'),
+		],
 		'register' => [
 		'register' => [
-			'title' => 'Créer un compte',
-			'description' => 'Créer un nouveau compte Niver',
+			'title' => _('Create account'),
+			'description' => _('Create a new account, and log in with it'),
 			'require-login' => false,
 			'require-login' => false,
 			'tokens_instance_cost' => 7200,
 			'tokens_instance_cost' => 7200,
 		],
 		],
 		'unregister' => [
 		'unregister' => [
-			'title' => 'Supprimer son compte',
-			'description' => 'Effacer toutes les données de son compte',
+			'title' => _('Delete account'),
+			'description' => _('Erase all current account\'s data'),
 		],
 		],
 		'approval' => [
 		'approval' => [
-			'title' => 'Approuver son compte',
-			'description' => 'Utiliser une clé d\'approbation pour passer à un compte approuvé.',
+			'title' => _('Switch to an approved account'),
+			'description' => _('Switch to an approved account using an approval key'),
 		],
 		],
 		'password' => [
 		'password' => [
-			'title' => 'Changer la clé de passe',
-			'description' => 'Changer la chaîne de caractères permettant de vous authentifier.',
+			'title' => _('Change password'),
+			'description' => _('Change the character string used to authenticate yourself'),
 		],
 		],
 		'username' => [
 		'username' => [
-			'title' => 'Changer l\'identifiant',
-			'description' => 'Changer la chaîne de caractères permettant d\'identifier votre compte.',
-		],
-		'logout' => [
-			'title' => 'Déconnexion',
-			'description' => 'Terminer la session et effacer ses cookies',
+			'title' => _('Change username'),
+			'description' => _('Change the name used to identify your account when logging in and displayed at the start of every page'),
 		],
 		],
 	],
 	],
 	'reg' => [
 	'reg' => [
 		'index' => [
 		'index' => [
-			'title' => '<span aria-hidden="true">🏷️ </span>Registre <code>' . CONF['reg']['registry'] . '</code>',
-			'description' => 'Obtenir et gérer la délégation d\'un sous-domaine de <code>' . CONF['reg']['registry'] . '</code>',
+			'title' => '<span aria-hidden="true">🏷️ </span>' . sprintf(_('%s registry'), '<code>' . CONF['reg']['registry'] . '</code>'),
+			'description' => sprintf(_('Register and delegate a %s subdomain'), '<code>' . CONF['reg']['registry'] . '</code>'),
 		],
 		],
 		'register' => [
 		'register' => [
-			'title' => 'Enregistrer un nouveau domaine',
-			'description' => 'Prendre possession d\'un sous-domaine de <code>' . CONF['reg']['registry'] . '</code>',
+			'title' => _('Register domain'),
+			'description' => sprintf(_('Get a %s subdomain'), '<code>' . CONF['reg']['registry'] . '</code>'),
 			'tokens_account_cost' => 3600,
 			'tokens_account_cost' => 3600,
 		],
 		],
 		'unregister' => [
 		'unregister' => [
-			'title' => 'Effacer un domaine',
-			'description' => 'Effacer toutes les données d\'un domaine',
+			'title' => _('Unregister domain'),
+			'description' => _('Delete all data related to a domain and make it available to the public again'),
 		],
 		],
 		'print' => [
 		'print' => [
-			'title' => 'Afficher les données',
-			'description' => 'Afficher les enregistrements relatifs à un domaine',
+			'title' => _('Display domain records'),
+			'description' => _('Print every record related to a domain and served by the registry'),
 		],
 		],
 		'ns' => [
 		'ns' => [
-			'title' => 'Enregistrements <abbr title="Name Server">NS</abbr>',
-			'description' => 'Indiquer les serveurs de noms de son sous-domaine de <code>' . CONF['reg']['registry'] . '</code>',
+			'title' => sprintf(_('%s records'), '<abbr title="Name Server">NS</abbr>'),
+			'description' => sprintf(_('Indicate the name servers of a %s subdomain'), '<code>' . CONF['reg']['registry'] . '</code>'),
 		],
 		],
 		'ds' => [
 		'ds' => [
-			'title' => 'Enregistrements <abbr title="Delegation Signer">DS</abbr>',
-			'description' => 'Déléguer la confiance <abbr title="Domain Name System Security Extensions">DNSSEC</abbr>',
+			'title' => sprintf(_('%s records'), '<abbr title="Delegation Signer">DS</abbr>'),
+			'description' => _('Delegate <abbr title="Domain Name System Security Extensions">DNSSEC</abbr> trust'),
 		],
 		],
 		'transfer' => [
 		'transfer' => [
-			'title' => 'Recevoir un transfert de domaine',
-			'description' => 'Transférer un domaine vers ce compte',
+			'title' => _('Receive a domain transfer'),
+			'description' => _('Transfer a domain owned by another account to the current account'),
 		],
 		],
 		'glue' => [
 		'glue' => [
-			'title' => 'Glue Records',
-			'description' => 'Avancé : Indiquer l\'IP d\'un serveur de noms dont l\'adresse dépend de la zone qu\'il sert',
+			'title' => _('Glue records'),
+			'description' => _('Advanced: store the IP address of a name server whose domain is inside the domain it serves'),
 		],
 		],
 	],
 	],
 	'ns' => [
 	'ns' => [
 		'index' => [
 		'index' => [
-			'title' => '<span aria-hidden="true">📖 </span>Serveurs de noms',
-			'description' => 'Héberger et gérer les données liées à un domaine',
+			'title' => '<span aria-hidden="true">📖 </span>' . _('Name servers'),
+			'description' => _('Host and manage domain\'s records'),
 		],
 		],
 		'zone-add' => [
 		'zone-add' => [
-			'title' => 'Ajouter une zone',
-			'description' => 'Pour qu\'elle soit gérée par le serveur de noms de Niver',
+			'title' => _('Add zone'),
+			'description' => sprintf(_('The zone will be managed by %s name servers'), CONF['common']['service_name']),
 			'tokens_account_cost' => 1800,
 			'tokens_account_cost' => 1800,
 		],
 		],
 		'zone-del' => [
 		'zone-del' => [
-			'title' => 'Effacer une zone',
-			'description' => 'Effacer toutes les données d\'une zone',
+			'title' => _('Delete zone'),
+			'description' => _('Erase all zone data'),
 		],
 		],
 		'print' => [
 		'print' => [
-			'title' => 'Afficher les données',
-			'description' => 'Afficher le contenu de la zone',
+			'title' => _('Display zone'),
+			'description' => _('Print zonefile content'),
 		],
 		],
 		'edit' => [
 		'edit' => [
-			'title' => 'Modifier une zone',
-			'description' => 'Éditer un fichier de zone',
+			'title' => _('Edit zone'),
+			'description' => _('Change zonefile content'),
 			'tokens_account_cost' => 300,
 			'tokens_account_cost' => 300,
 		],
 		],
 		'ip' => [
 		'ip' => [
-			'title' => 'Enregistrements A et AAAA',
-			'description' => 'Indiquer l\'adresse IP d\'un domaine',
+			'title' => _('AAAA and A records'),
+			'description' => _('Store domain\'s IP address'),
 		],
 		],
 		'ns' => [
 		'ns' => [
-			'title' => 'Enregistrement <abbr title="Name Server">NS</abbr>',
-			'description' => 'Indiquer le serveur de noms d\'une zone',
+			'title' => sprintf(_('%s records'), '<abbr title="Name Server">NS</abbr>'),
+			'description' => _('Store zone\'s name server'),
 		],
 		],
 		'txt' => [
 		'txt' => [
-			'title' => 'Enregistrement <abbr title="TeXT">TXT</abbr>',
-			'description' => 'Associer du texte à un domaine',
+			'title' => sprintf(_('%s records'), '<abbr title="TeXT">TXT</abbr>'),
+			'description' => _('Associate text to domain'),
 		],
 		],
 		'caa' => [
 		'caa' => [
-			'title' => 'Enregistrement <abbr title="Certification Authority Authorization">CAA</abbr>',
-			'description' => 'Limiter les autorités de certification autorisées à émettre des certificats',
+			'title' => sprintf(_('%s records'), '<abbr title="Certification Authority Authorization">CAA</abbr>'),
+			'description' => _('Limit the certificate authorities allowed to certify the domain'),
 		],
 		],
 		'srv' => [
 		'srv' => [
-			'title' => 'Enregistrement <abbr title="SeRVice">SRV</abbr>',
-			'description' => 'Indiquer l\'adresse d\'un service spécifique',
+			'title' => sprintf(_('%s records'), '<abbr title="SeRVice">SRV</abbr>'),
+			'description' => _('Store the location of a domain\'s service'),
 		],
 		],
 		'mx' => [
 		'mx' => [
-			'title' => 'Enregistrement <abbr title="Mail eXchanger">MX</abbr>',
-			'description' => 'Indiquer l\'adresse du serveur recevant les courriels',
+			'title' => sprintf(_('%s records'), '<abbr title="Mail eXchanger">MX</abbr>'),
+			'description' => _('Store the email server\'s address'),
 		],
 		],
 		'sshfp' => [
 		'sshfp' => [
-			'title' => 'Enregistrement <abbr title="Secure SHell FingerPrint">SSHFP</abbr>',
-			'description' => 'Indiquer les empreintes des clés <abbr title="Secure SHell">SSH</abbr>',
+			'title' => sprintf(_('%s records'), '<abbr title="Secure SHell FingerPrint">SSHFP</abbr>'),
+			'description' => _('Store <abbr title="Secure SHell">SSH</abbr> public keys fingerprints'),
 		],
 		],
 		'tlsa' => [
 		'tlsa' => [
-			'title' => 'Enregistrement <abbr title="Transport Layer Security Association">TLSA</abbr>',
-			'description' => 'Mettre en place <abbr title="DNS-based Authentication of Named Entities">DANE</abbr> en indiquant l\'empreinte d\'un certificat <abbr title="Transport Layer Security">TLS</abbr>',
+			'title' => sprintf(_('%s records'), '<abbr title="Transport Layer Security Association">TLSA</abbr>'),
+			'description' => _('Setup <abbr title="DNS-based Authentication of Named Entities">DANE</abbr> by publishing the <abbr title="Transport Layer Security">TLS</abbr> certificate fingerprint'),
 		],
 		],
 		'cname' => [
 		'cname' => [
-			'title' => 'Enregistrement <abbr title="Canonical NAME">CNAME</abbr>',
-			'description' => 'Définir un domaine comme étant l\'alias d\'un autre',
+			'title' => sprintf(_('%s records'), '<abbr title="Canonical NAME">CNAME</abbr>'),
+			'description' => _('Define a domain as an alias of another'),
 		],
 		],
 		'dname' => [
 		'dname' => [
-			'title' => 'Enregistrement <abbr title="Delegation NAME">DNAME</abbr>',
-			'description' => 'Définir les sous-domaines d\'un domaine comme étant les alias des sous-domaines d\'un autre domaine',
+			'title' => sprintf(_('%s records'), '<abbr title="Delegation NAME">DNAME</abbr>'),
+			'description' => _('Define all subdomains of a domain as aliases of subdomains of another domain'),
 		],
 		],
 		'loc' => [
 		'loc' => [
-			'title' => 'Enregistrement <abbr title="LOCation">LOC</abbr>',
-			'description' => 'Indiquer des coordonnées géographiques',
+			'title' => sprintf(_('%s records'), '<abbr title="LOCation">LOC</abbr>'),
+			'description' => _('Store geographic coordinates'),
 		],
 		],
 	],
 	],
 	'ht' => [
 	'ht' => [
 		'index' => [
 		'index' => [
-			'title' => '<span aria-hidden="true">🕸️ </span>Hypertexte',
-			'description' => 'Mettre en ligne son site statique sur un espace <abbr title="SSH File Transfert Protocol">SFTP</abbr>, et le faire répondre en <abbr title="HyperText Transfert Protocol">HTTP</abbr> par DNS ou Tor',
+			'title' => '<span aria-hidden="true">🕸️ </span>' . _('Web'),
+			'description' => _('Upload a static website into an <abbr title="SSH File Transfer Protocol">SFTP</abbr> space'),
 		],
 		],
 		'add-subpath' => [
 		'add-subpath' => [
-			'title' => 'Accès par sous-chemin <code>' . CONF['ht']['subpath_domain'] . '/</code>',
-			'description' => 'Son URL ressemblera à <code>https://' . CONF['ht']['subpath_domain'] . '/monsite/</code>',
+			'title' => sprintf(_('%s subpath access'), '<code>' . CONF['ht']['subpath_domain'] . '/</code>'),
+			'description' => sprintf(_('Its URL will look like %s'), '<code>https://' . CONF['ht']['subpath_domain'] . '/<em>' . _('mysite') . '</em>/</code>'),
 			'tokens_account_cost' => 900,
 			'tokens_account_cost' => 900,
 		],
 		],
 		'add-subdomain' => [
 		'add-subdomain' => [
-			'title' => 'Accès par sous-domaine de <code>.' . CONF['ht']['subdomain_domain'] . '</code>',
-			'description' => 'Son URL ressemblera à <code>https://monsite.' . CONF['ht']['subpath_domain'] . '/</code>',
+			'title' => sprintf(_('%s subdomain access'), '<code>.' . CONF['ht']['subdomain_domain'] . '</code>'),
+			'description' => sprintf(_('Its URL will look like %s'), '<code>https://<em>' . _('mysite') . '</em>.' . CONF['ht']['subpath_domain'] . '/</code>'),
 			'tokens_account_cost' => 1800,
 			'tokens_account_cost' => 1800,
 		],
 		],
 		'add-dns' => [
 		'add-dns' => [
-			'title' => 'Accès par domaine dédié et certificat Let\'s Encrypt',
-			'description' => 'Son URL ressemblera à <code>https://monsite.example/</code>',
+			'title' => _('Dedicated domain with Let\'s Encrypt certificate access'),
+			'description' => sprintf(_('Its URL will look like %s'), '<code>https://<em>' . _('mysite') . '</em>.' . PLACEHOLDER_DOMAIN . '/</code>'),
 			'tokens_account_cost' => 3600,
 			'tokens_account_cost' => 3600,
 		],
 		],
 		'add-onion' => [
 		'add-onion' => [
-			'title' => 'Accès par service Onion',
-			'description' => 'Son URL ressemblera à <code>http://nrdselxjgryq5fwek2xh3pxg4b26z26eyzlbs4y5lownk465jhaamayd.onion/</code>, qui ne fonctionnera que par le réseau Tor',
+			'title' => _('Onion service access'),
+			'description' => sprintf(_('Its URL will look like %s, and work only through the Tor network'), '<code>http://nrdselxjgryq5fwek2xh3pxg4b26z26eyzlbs4y5lownk465jhaamayd.onion/</code>'),
 			'tokens_account_cost' => 1800,
 			'tokens_account_cost' => 1800,
 		],
 		],
 	    'del' => [
 	    'del' => [
-			'title' => 'Retirer un accès',
-			'description' => 'Retirer un accès HTTP déjà existant d\'un sous-dossier de l\'espace SFTP',
+			'title' => _('Delete access'),
+			'description' => _('Delete an existing HTTP access from a subdirectory of the SFTP space'),
 		],
 		],
 	],
 	],
 ]);
 ]);

+ 3 - 3
pg-act/auth/approval.php

@@ -1,10 +1,10 @@
 <?php
 <?php
 
 
 if ($_SESSION['type'] !== 'testing')
 if ($_SESSION['type'] !== 'testing')
-	output(403, 'Approbation impossible : votre compte est déjà approuvé.');
+	output(403, _('This account is already approved.'));
 
 
 if (isset(query('select', 'approval-keys', ['key' => $_POST['key']], 'key')[0]) !== true)
 if (isset(query('select', 'approval-keys', ['key' => $_POST['key']], 'key')[0]) !== true)
-	output(403, 'Approbation impossible : cette clé d\'approbation n\'est pas disponible. Elle a été mal saisie, a expiré ou a déjà été utilisée pour un autre compte.');
+	output(403, _('This approval key is not available. It has been mistyped, used for another account, or has expired.');
 
 
 query('delete', 'approval-keys', ['key' => $_POST['key']]);
 query('delete', 'approval-keys', ['key' => $_POST['key']]);
 
 
@@ -15,4 +15,4 @@ $_SESSION['type'] = 'approved';
 
 
 insert('approval-keys', ['key' => bin2hex(random_bytes(16))]);
 insert('approval-keys', ['key' => bin2hex(random_bytes(16))]);
 
 
-output(200, 'Compte approuvé.');
+output(200, _('Account approved.'));

+ 2 - 2
pg-act/auth/login.php

@@ -7,12 +7,12 @@ checkUsernameFormat($_POST['username']);
 $username = hashUsername($_POST['username']);
 $username = hashUsername($_POST['username']);
 
 
 if (usernameExists($username) !== true)
 if (usernameExists($username) !== true)
-	output(403, 'Connexion impossible : ce compte n\'existe pas.');
+	output(403, _('This account does not exist.'));
 
 
 $id = query('select', 'users', ['username' => $username], 'id')[0];
 $id = query('select', 'users', ['username' => $username], 'id')[0];
 
 
 if (checkPassword($id, $_POST['password']) !== true)
 if (checkPassword($id, $_POST['password']) !== true)
-	output(403, 'Connexion impossible : clé de passe invalide.');
+	output(403, _('Wrong password.'));
 
 
 if (outdatedPasswordHash($id))
 if (outdatedPasswordHash($id))
 	changePassword($id, $_POST['password']);
 	changePassword($id, $_POST['password']);

+ 2 - 2
pg-act/auth/password.php

@@ -3,8 +3,8 @@
 checkPasswordFormat($_POST['new-password']);
 checkPasswordFormat($_POST['new-password']);
 
 
 if (checkPassword($_SESSION['id'], $_POST['current-password']) !== true)
 if (checkPassword($_SESSION['id'], $_POST['current-password']) !== true)
-	output(403, 'Changement impossible : clé de passe invalide.');
+	output(403, _('Wrong current password.'));
 
 
 changePassword($_SESSION['id'], $_POST['new-password']);
 changePassword($_SESSION['id'], $_POST['new-password']);
 
 
-output(200, 'Clé de passe changée.');
+output(200, _('Password updated.'));

+ 1 - 1
pg-act/auth/register.php

@@ -7,7 +7,7 @@ checkUsernameFormat($_POST['username']);
 $username = hashUsername($_POST['username']);
 $username = hashUsername($_POST['username']);
 
 
 if (usernameExists($username) !== false)
 if (usernameExists($username) !== false)
-	output(403, 'Ce nom de compte est déjà utilisé.');
+	output(403, _('This username is already taken.'));
 
 
 rateLimit();
 rateLimit();
 
 

+ 2 - 2
pg-act/auth/unregister.php

@@ -1,7 +1,7 @@
 <?php
 <?php
 
 
 if (!isset($_POST['delete']))
 if (!isset($_POST['delete']))
-	output(403, 'Il faut confirmer la suppression du compte');
+	output(403, _('Account deletion must be confirmed.'));
 
 
 foreach (query('select', 'registry', ['username' => $_SESSION['id']], 'domain') as $domain)
 foreach (query('select', 'registry', ['username' => $_SESSION['id']], 'domain') as $domain)
 	regDeleteDomain($domain);
 	regDeleteDomain($domain);
@@ -26,4 +26,4 @@ query('delete', 'users', ['id' => $_SESSION['id']]);
 
 
 logout();
 logout();
 
 
-output(200, 'Compte supprimé.');
+output(200, _('Account deleted.'));

+ 2 - 2
pg-act/auth/username.php

@@ -5,7 +5,7 @@ checkUsernameFormat($_POST['new-username']);
 $username = hashUsername($_POST['new-username']);
 $username = hashUsername($_POST['new-username']);
 
 
 if (usernameExists($username) !== false)
 if (usernameExists($username) !== false)
-	output(403, 'Ce nom de compte est déjà utilisé.');
+	output(403, _('This username is already taken.'));
 
 
 DB->prepare('UPDATE users SET username = :username WHERE id = :id')
 DB->prepare('UPDATE users SET username = :username WHERE id = :id')
 ->execute([':username' => $username, ':id' => $_SESSION['id']]);
 ->execute([':username' => $username, ':id' => $_SESSION['id']]);
@@ -14,4 +14,4 @@ setupDisplayUsername($_POST['new-username']);
 
 
 redir('auth/username');
 redir('auth/username');
 
 
-output(200, 'Identifiant changé.');
+output(200, _('Username updated.'));

+ 8 - 8
pg-act/ht/add-dns.php

@@ -6,25 +6,25 @@ if (dirsStatuses('dns')[$_POST['dir']] !== false)
 	output(403, 'Wrong value for <code>dir</code>.');
 	output(403, 'Wrong value for <code>dir</code>.');
 
 
 if (query('select', 'sites', ['domain' => $_POST['domain']], 'domain') !== [])
 if (query('select', 'sites', ['domain' => $_POST['domain']], 'domain') !== [])
-	output(403, 'Ce domaine existe déjà sur ce service.');
+	output(403, _('This domain already exists on this service. Use another one.');
 
 
 $remoteAaaaRecords = dns_get_record($_POST['domain'], DNS_AAAA);
 $remoteAaaaRecords = dns_get_record($_POST['domain'], DNS_AAAA);
 if (is_array($remoteAaaaRecords) !== true)
 if (is_array($remoteAaaaRecords) !== true)
-	output(500, 'Erreur lors de la récupération de l\'enregistrement AAAA.');
+	output(500, sprintf(_('Can\'t retrieve the %s record.'), 'AAAA');
 if (equalArrays([CONF['ht']['ipv6_address']], array_column($remoteAaaaRecords, 'ipv6')) !== true)
 if (equalArrays([CONF['ht']['ipv6_address']], array_column($remoteAaaaRecords, 'ipv6')) !== true)
-	output(403, 'Ce domaine doit avoir pour unique enregistrement AAAA <code>' . CONF['ht']['ipv6_address'] . '</code>.');
+	output(403, sprintf(_('This domain must have %2$s as its only %1$s record.'), 'AAAA', '<code>' . CONF['ht']['ipv6_address'] . '</code>'));
 
 
 $remoteARecords = dns_get_record($_POST['domain'], DNS_A);
 $remoteARecords = dns_get_record($_POST['domain'], DNS_A);
 if (is_array($remoteARecords) !== true)
 if (is_array($remoteARecords) !== true)
-	output(500, 'Erreur lors de la récupération de l\'enregistrement A.');
+	output(500, sprintf(_('Can\'t retrieve the %s record.'), 'A');
 if (equalArrays([CONF['ht']['ipv4_address']], array_column($remoteARecords, 'ip')) !== true)
 if (equalArrays([CONF['ht']['ipv4_address']], array_column($remoteARecords, 'ip')) !== true)
-	output(403, 'Ce domaine doit avoir pour unique enregistrement A <code>' . CONF['ht']['ipv4_address'] . '</code>.');
+	output(403, sprintf(_('This domain must have %2$s as its only %1$s record.'), 'A', '<code>' . CONF['ht']['ipv4_address'] . '</code>'));
 
 
 $remoteTXTRecords = dns_get_record($_POST['domain'], DNS_TXT);
 $remoteTXTRecords = dns_get_record($_POST['domain'], DNS_TXT);
 if (is_array($remoteTXTRecords) !== true)
 if (is_array($remoteTXTRecords) !== true)
-	output(500, 'Erreur lors de la récupération de l\'enregistrement TXT.');
+	output(500, sprintf(_('Can\'t retrieve the %s record.'), 'TXT');
 if (preg_match('/^' . preg_quote(SERVER_NAME, '/') . '_domain-verification=([0-9a-f]{8})-([0-9a-f]{32})$/Dm', implode(LF, array_column($remoteTXTRecords, 'txt')), $matches) !== 1)
 if (preg_match('/^' . preg_quote(SERVER_NAME, '/') . '_domain-verification=([0-9a-f]{8})-([0-9a-f]{32})$/Dm', implode(LF, array_column($remoteTXTRecords, 'txt')), $matches) !== 1)
-	output(403, 'Aucun enregistrement TXT au format correct trouvé.');
+	output(403, _('No TXT record with the expected format has been found.'));
 
 
 checkAuthToken($matches[1], $matches[2]);
 checkAuthToken($matches[1], $matches[2]);
 
 
@@ -56,4 +56,4 @@ exec(CONF['ht']['sudo_path'] . ' ' . CONF['ht']['nginx_reload_cmd'], result_code
 if ($code !== 0)
 if ($code !== 0)
 	output(500, 'Failed to reload Nginx.');
 	output(500, 'Failed to reload Nginx.');
 
 
-output(200, 'Accès HTTP par domaine dédié ajouté sur ce dossier !');
+output(200, sprintf(_('%s added on this directory.'), PAGE_METADATA['title']);

+ 1 - 1
pg-act/ht/add-onion.php

@@ -44,4 +44,4 @@ if ($code !== 0)
 	output(500, 'Failed to reload Nginx.');
 	output(500, 'Failed to reload Nginx.');
 
 
 // Tell the user their site address
 // Tell the user their site address
-output(200, 'L\'adresse de votre service Onion HTTP est : <a href="http://' . $onion . '/"><code>http://' . $onion . '/</code></a>');
+output(200, sprintf(_('%s added on this directory.'), PAGE_METADATA['title'] . sprintf(_('Its address is: %s'), '<a href="http://' . $onion . '/"><code>http://' . $onion . '/</code></a>');

+ 3 - 3
pg-act/ht/add-subdomain.php

@@ -4,10 +4,10 @@ if (dirsStatuses('subdomain')[$_POST['dir']] !== false)
 	output(403, 'Wrong value for <code>dir</code>.');
 	output(403, 'Wrong value for <code>dir</code>.');
 
 
 if (preg_match('/^[a-z0-9]{1,32}$/D', $_POST['subdomain']) !== 1)
 if (preg_match('/^[a-z0-9]{1,32}$/D', $_POST['subdomain']) !== 1)
-	output(403, 'Label de domaine invalide.');
+	output(403, _('Invalid domain label.'));
 
 
 if (query('select', 'sites', ['address' => $_POST['subdomain'], 'type' => 'subdomain']) !== [])
 if (query('select', 'sites', ['address' => $_POST['subdomain'], 'type' => 'subdomain']) !== [])
-	output(403, 'Ce domaine est déjà utilisé sur ce service. Utilisez-en un autre.');
+	output(403, _('This domain already exists on this service. Use another one.'));
 
 
 rateLimit();
 rateLimit();
 
 
@@ -16,4 +16,4 @@ addSite($_SESSION['id'], $_POST['dir'], $_POST['subdomain'], 'subdomain');
 if (symlink(CONF['ht']['ht_path'] . '/' . $_SESSION['id'] . '/' . $_POST['dir'], CONF['ht']['subdomain_path'] . '/' . $_POST['subdomain']) !== true)
 if (symlink(CONF['ht']['ht_path'] . '/' . $_SESSION['id'] . '/' . $_POST['dir'], CONF['ht']['subdomain_path'] . '/' . $_POST['subdomain']) !== true)
 	output(500, 'Unable to create symlink.');
 	output(500, 'Unable to create symlink.');
 
 
-output(200, 'Accès HTTP par sous-chemin ajouté sur ce dossier !');
+output(200, sprintf(_('%s added on this directory.'), PAGE_METADATA['title']));

+ 3 - 3
pg-act/ht/add-subpath.php

@@ -4,10 +4,10 @@ if (dirsStatuses('subpath')[$_POST['dir']] !== false)
 	output(403, 'Wrong value for <code>dir</code>.');
 	output(403, 'Wrong value for <code>dir</code>.');
 
 
 if (preg_match('/^[a-z0-9]{1,32}$/D', $_POST['path']) !== 1)
 if (preg_match('/^[a-z0-9]{1,32}$/D', $_POST['path']) !== 1)
-	output(403, 'Chemin invalide.');
+	output(403, _('Invalid path.'));
 
 
 if (query('select', 'sites', ['address' => $_POST['path'], 'type' => 'subpath']) !== [])
 if (query('select', 'sites', ['address' => $_POST['path'], 'type' => 'subpath']) !== [])
-	output(403, 'Ce chemin est déjà utilisé sur ce service. Utilisez-en un autre.');
+	output(403, _('This path already exists on this service. Use another one.'));
 
 
 rateLimit();
 rateLimit();
 
 
@@ -16,4 +16,4 @@ addSite($_SESSION['id'], $_POST['dir'], $_POST['path'], 'subpath');
 if (symlink(CONF['ht']['ht_path'] . '/' . $_SESSION['id'] . '/' . $_POST['dir'], CONF['ht']['subpath_path'] . '/' . $_POST['path']) !== true)
 if (symlink(CONF['ht']['ht_path'] . '/' . $_SESSION['id'] . '/' . $_POST['dir'], CONF['ht']['subpath_path'] . '/' . $_POST['path']) !== true)
 	output(500, 'Unable to create symlink.');
 	output(500, 'Unable to create symlink.');
 
 
-output(200, 'Accès HTTP par sous-chemin ajouté sur ce dossier !');
+output(200, sprintf(_('%s added on this directory.'), PAGE_METADATA['title']));

+ 1 - 1
pg-act/ht/del.php

@@ -8,4 +8,4 @@ if (isset(query('select', 'sites', ['username' => $_SESSION['id'], 'address' =>
 
 
 htDeleteSite($site['address'], $site['type']);
 htDeleteSite($site['address'], $site['type']);
 
 
-output(200, 'Accès retiré.');
+output(200, _('Access removed.'));

+ 1 - 1
pg-act/ns/caa.php

@@ -20,4 +20,4 @@ knotcZoneExec($_POST['zone'], [
 	$_POST['value']
 	$_POST['value']
 ]);
 ]);
 
 
-output(200, 'Enregistrement ajouté/retiré.');
+output(200, _('Modification done.'));

+ 1 - 1
pg-act/ns/cname.php

@@ -11,4 +11,4 @@ knotcZoneExec($_POST['zone'], [
 	$_POST['cname']
 	$_POST['cname']
 ]);
 ]);
 
 
-output(200, 'Enregistrement ajouté/retiré.');
+output(200, _('Modification done.'));

+ 1 - 1
pg-act/ns/dname.php

@@ -11,4 +11,4 @@ knotcZoneExec($_POST['zone'], [
 	$_POST['dname']
 	$_POST['dname']
 ]);
 ]);
 
 
-output(200, 'Enregistrement ajouté/retiré.');
+output(200, _('Modification done.'));

+ 6 - 6
pg-act/ns/edit.php

@@ -14,17 +14,17 @@ if (isset($_POST['zone-content'])) { // Update zone
 	// Generate new zone content
 	// Generate new zone content
 	$new_zone_content = $matches['soa'] . LF;
 	$new_zone_content = $matches['soa'] . LF;
 	if (strlen($_POST['zone-content']) > ZONE_MAX_CHARACTERS)
 	if (strlen($_POST['zone-content']) > ZONE_MAX_CHARACTERS)
-		output(403, 'La zone n\'est pas autorisée à dépasser ' . ZONE_MAX_CHARACTERS . ' caractères.');
+		output(403, sprintf(_('The zone is limited to %s characters.'), ZONE_MAX_CHARACTERS));
 	foreach (explode("\r\n", $_POST['zone-content']) as $line) {
 	foreach (explode("\r\n", $_POST['zone-content']) as $line) {
 		if ($line === '') continue;
 		if ($line === '') continue;
 		if (preg_match('/^(?<domain>[a-z0-9@._-]+)(?:[\t ]+(?<ttl>[0-9]{1,16}))?(?:[\t ]+IN)?[\t ]+(?<type>[A-Z]{1,16})[\t ]+(?<value>.+)$/D', $line, $matches) !== 1)
 		if (preg_match('/^(?<domain>[a-z0-9@._-]+)(?:[\t ]+(?<ttl>[0-9]{1,16}))?(?:[\t ]+IN)?[\t ]+(?<type>[A-Z]{1,16})[\t ]+(?<value>.+)$/D', $line, $matches) !== 1)
-			output(403, 'La zone est mal formatée (selon Niver).');
+			output(403, _('The following line does not match the expected format: ') . '<code>' . htmlspecialchars($line) . '</code>');
 		if (in_array($matches['type'], ALLOWED_TYPES, true) !== true)
 		if (in_array($matches['type'], ALLOWED_TYPES, true) !== true)
-			output(403, 'Le type <code>' . $matches['type'] . '</code> n\'est pas autorisé.');
+			output(403, sprintf(_('The %s type is not allowed.'), '<code>' . $matches['type'] . '</code>'));
 		if ($matches['ttl'] !== '' AND $matches['ttl'] < MIN_TTL)
 		if ($matches['ttl'] !== '' AND $matches['ttl'] < MIN_TTL)
-			output(403, 'Les TTLs inférieurs à ' . MIN_TTL . ' secondes ne sont pas autorisés.');
+			output(403, sprintf(_('TTLs shorter than %s seconds are forbidden.'), MIN_TTL));
 		if ($matches['ttl'] !== '' AND $matches['ttl'] > MAX_TTL)
 		if ($matches['ttl'] !== '' AND $matches['ttl'] > MAX_TTL)
-			output(403, 'Les TTLs supérieurs à ' . MAX_TTL . ' secondes ne sont pas autorisés.');
+			output(403, sprintf(_('TTLs longer than %s seconds are forbidden.'), MAX_TTL));
 		$new_zone_content .= $matches['domain'] . ' ' . (($matches['ttl'] === '') ? DEFAULT_TTL : $matches['ttl']) . ' ' . $matches['type'] . ' ' . $matches['value'] . LF;
 		$new_zone_content .= $matches['domain'] . ' ' . (($matches['ttl'] === '') ? DEFAULT_TTL : $matches['ttl']) . ' ' . $matches['type'] . ' ' . $matches['value'] . LF;
 	}
 	}
 
 
@@ -35,7 +35,7 @@ if (isset($_POST['zone-content'])) { // Update zone
 	fwrite($pipes[0], $new_zone_content);
 	fwrite($pipes[0], $new_zone_content);
 	fclose($pipes[0]);
 	fclose($pipes[0]);
 	if (proc_close($process) !== 0)
 	if (proc_close($process) !== 0)
-		output(403, 'Le contenu de zone envoyé n\'est pas valide (selon <code>kzonecheck</code>).');
+		output(403, _('Sent zone content is not correct (according to <code>kzonecheck</code>).'));
 
 
 	ratelimit();
 	ratelimit();
 
 

+ 1 - 1
pg-act/ns/ip.php

@@ -11,4 +11,4 @@ knotcZoneExec($_POST['zone'], [
 	$_POST['ip']
 	$_POST['ip']
 ]);
 ]);
 
 
-output(200, 'Enregistrement ajouté/retiré.');
+output(200, _('Modification done.'));

+ 1 - 1
pg-act/ns/loc.php

@@ -67,4 +67,4 @@ knotcZoneExec($_POST['zone'], [
 	$_POST['vp'] . 'm',
 	$_POST['vp'] . 'm',
 ]);
 ]);
 
 
-output(200, 'Enregistrement ajouté/retiré.');
+output(200, _('Modification done.'));

+ 1 - 1
pg-act/ns/mx.php

@@ -15,4 +15,4 @@ knotcZoneExec($_POST['zone'], [
 	$_POST['host']
 	$_POST['host']
 ]);
 ]);
 
 
-output(200, 'Enregistrement ajouté/retiré.');
+output(200, _('Modification done.'));

+ 1 - 1
pg-act/ns/ns.php

@@ -11,4 +11,4 @@ knotcZoneExec($_POST['zone'], [
 	$_POST['ns']
 	$_POST['ns']
 ]);
 ]);
 
 
-output(200, 'Enregistrement ajouté/retiré.');
+output(200, _('Modification done.'));

+ 1 - 1
pg-act/ns/srv.php

@@ -23,4 +23,4 @@ knotcZoneExec($_POST['zone'], [
 	$_POST['target']
 	$_POST['target']
 ]);
 ]);
 
 
-output(200, 'Enregistrement ajouté/retiré.');
+output(200, _('Modification done.'));

+ 1 - 1
pg-act/ns/sshfp.php

@@ -20,4 +20,4 @@ knotcZoneExec($_POST['zone'], [
 	$_POST['fp']
 	$_POST['fp']
 ]);
 ]);
 
 
-output(200, 'Enregistrement ajouté/retiré.');
+output(200, _('Modification done.'));

+ 1 - 1
pg-act/ns/tlsa.php

@@ -24,4 +24,4 @@ knotcZoneExec($_POST['zone'], [
 	$_POST['content']
 	$_POST['content']
 ]);
 ]);
 
 
-output(200, 'Enregistrement ajouté/retiré.');
+output(200, _('Modification done.'));

+ 1 - 1
pg-act/ns/txt.php

@@ -12,4 +12,4 @@ knotcZoneExec($_POST['zone'], [
 	'"' . $_POST['txt'] . '"'
 	'"' . $_POST['txt'] . '"'
 ]);
 ]);
 
 
-output(200, 'Enregistrement ajouté/retiré.');
+output(200, _('Modification done.'));

+ 4 - 4
pg-act/ns/zone-add.php

@@ -3,17 +3,17 @@
 $_POST['domain'] = formatAbsoluteDomain($_POST['domain']);
 $_POST['domain'] = formatAbsoluteDomain($_POST['domain']);
 
 
 if (query('select', 'zones', ['zone' => $_POST['domain']], 'zone') !== [])
 if (query('select', 'zones', ['zone' => $_POST['domain']], 'zone') !== [])
-	output(403, 'Cette zone existe déjà sur ce service.');
+	output(403, _('This zone already exists on the service.'));
 
 
 exec(CONF['dns']['kdig_path'] . ' ' . ltrim(strstr($_POST['domain'], '.'), '.') . ' NS +short', $parentAuthoritatives);
 exec(CONF['dns']['kdig_path'] . ' ' . ltrim(strstr($_POST['domain'], '.'), '.') . ' NS +short', $parentAuthoritatives);
 if ($parentAuthoritatives === [])
 if ($parentAuthoritatives === [])
-	output(403, 'Serveurs de noms de la zone parente introuvables');
+	output(403, _('Parent zone\'s name servers not found.'));
 foreach ($parentAuthoritatives as $parentAuthoritative)
 foreach ($parentAuthoritatives as $parentAuthoritative)
 	checkAbsoluteDomainFormat($parentAuthoritative);
 	checkAbsoluteDomainFormat($parentAuthoritative);
 
 
 exec(CONF['dns']['kdig_path'] . ' ' . $_POST['domain'] . ' NS @' . $parentAuthoritatives[0] . ' +noidn', $results);
 exec(CONF['dns']['kdig_path'] . ' ' . $_POST['domain'] . ' NS @' . $parentAuthoritatives[0] . ' +noidn', $results);
 if (preg_match('/^' . preg_quote($_POST['domain'], '/') . '[\t ]+[0-9]{1,8}[\t ]+IN[\t ]+NS[\t ]+(?<salt>[0-9a-f]{8})-(?<hash>[0-9a-f]{32})\._domain-verification\.' . preg_quote(SERVER_NAME, '/') . '\.$/Dm', implode(LF, $results), $matches) !== 1)
 if (preg_match('/^' . preg_quote($_POST['domain'], '/') . '[\t ]+[0-9]{1,8}[\t ]+IN[\t ]+NS[\t ]+(?<salt>[0-9a-f]{8})-(?<hash>[0-9a-f]{32})\._domain-verification\.' . preg_quote(SERVER_NAME, '/') . '\.$/Dm', implode(LF, $results), $matches) !== 1)
-	output(403, 'Enregistrement d\'authentification introuvable');
+	output(403, _('NS authentication record not found.'));
 
 
 checkAuthToken($matches['salt'], $matches['hash']);
 checkAuthToken($matches['salt'], $matches['hash']);
 
 
@@ -49,4 +49,4 @@ knotcConfExec([
 	"set 'zone[" . $_POST['domain'] . "].template' 'niver'",
 	"set 'zone[" . $_POST['domain'] . "].template' 'niver'",
 ]);
 ]);
 
 
-output(200, 'La zone a été créée.');
+output(200, _('Zone created.'));

+ 1 - 1
pg-act/ns/zone-del.php

@@ -4,4 +4,4 @@ nsCheckZonePossession($_POST['zone']);
 
 
 nsDeleteZone($_POST['zone']);
 nsDeleteZone($_POST['zone']);
 
 
-output(200, 'La zone a été supprimée.');
+output(200, _('Zone deleted.'));

+ 1 - 1
pg-act/reg/ds.php

@@ -27,4 +27,4 @@ knotcZoneExec(CONF['reg']['registry'], [
 	$_POST['key']
 	$_POST['key']
 ]);
 ]);
 
 
-output(200, 'Enregistrement ajouté/retiré.');
+output(200, _('Modification done.'));

+ 1 - 1
pg-act/reg/glue.php

@@ -13,4 +13,4 @@ knotcZoneExec(CONF['reg']['registry'], [
 	$_POST['ip']
 	$_POST['ip']
 ]);
 ]);
 
 
-output(200, 'Glue ajouté/retiré.');
+output(200, _('Modification done.'));

+ 1 - 1
pg-act/reg/ns.php

@@ -10,4 +10,4 @@ knotcZoneExec(CONF['reg']['registry'], [
 	$_POST['ns']
 	$_POST['ns']
 ]);
 ]);
 
 
-output(200, 'Enregistrement ajouté/retiré.');
+output(200, _('Modification done.'));

+ 4 - 4
pg-act/reg/register.php

@@ -1,15 +1,15 @@
 <?php
 <?php
 
 
 if (preg_match('/' . SUBDOMAIN_REGEX . '/D', $_POST['subdomain']) !== 1)
 if (preg_match('/' . SUBDOMAIN_REGEX . '/D', $_POST['subdomain']) !== 1)
-	output(403, 'Le nom de domaine doit être composé uniquement d\'entre 4 et 63 lettres minuscules ou chiffre (a-z et 0-9)');
+	output(403, _('This format of subdomain is not allowed.'));
 
 
 $domain = formatAbsoluteDomain($_POST['subdomain'] . '.' . CONF['reg']['registry']);
 $domain = formatAbsoluteDomain($_POST['subdomain'] . '.' . CONF['reg']['registry']);
 
 
 if (query('select', 'registry', ['domain' => $domain], 'domain') !== [])
 if (query('select', 'registry', ['domain' => $domain], 'domain') !== [])
-	output(403, 'Ce domaine n\'est pas disponible à l\'enregistrement. Il est déjà enregistré.');
+	output(403, _('This domain is already registered.'));
 
 
 if (in_array($_POST['subdomain'], explode(LF, file_get_contents(CONF['common']['root_path'] . '/pg-act/reg/reserved.txt'))))
 if (in_array($_POST['subdomain'], explode(LF, file_get_contents(CONF['common']['root_path'] . '/pg-act/reg/reserved.txt'))))
-	output(403, 'Ce domaine n\'est pas disponible à l\'enregistrement. Il est réservé.');
+	output(403, _('This domain is reserved.'));
 
 
 rateLimit();
 rateLimit();
 
 
@@ -19,4 +19,4 @@ insert('registry', [
 	'last_renewal' => date('Y-m-d H:i:s'),
 	'last_renewal' => date('Y-m-d H:i:s'),
 ]);
 ]);
 
 
-output(200, 'Domaine ajouté au registre.');
+output(200, _('Domain registered.'));

+ 4 - 4
pg-act/reg/transfer.php

@@ -1,16 +1,16 @@
 <?php
 <?php
 
 
 if (preg_match('/' . SUBDOMAIN_REGEX . '/D', $_POST['domain']) !== 1)
 if (preg_match('/' . SUBDOMAIN_REGEX . '/D', $_POST['domain']) !== 1)
-	output(403, 'Le nom de domaine semble incorrect');
+	output(403, 'Wrong domain name format.');
 
 
 $domain = $_POST['domain'] . '.' . CONF['reg']['registry'];
 $domain = $_POST['domain'] . '.' . CONF['reg']['registry'];
 
 
 if (query('select', 'registry', ['username' => $_SESSION['id'], 'domain' => $domain], 'domain') !== [])
 if (query('select', 'registry', ['username' => $_SESSION['id'], 'domain' => $domain], 'domain') !== [])
-	output(403, 'Le compte présent possède déjà ce domaine.');
+	output(403, _('The current account already owns this domain.'));
 
 
 exec(CONF['dns']['kdig_path'] . ' ' . $domain . ' NS @' . CONF['reg']['address'] . ' +noidn', $results);
 exec(CONF['dns']['kdig_path'] . ' ' . $domain . ' NS @' . CONF['reg']['address'] . ' +noidn', $results);
 if (preg_match('/^' . preg_quote($domain, '/') . '[\t ]+[0-9]{1,8}[\t ]+IN[\t ]+NS[\t ]+(?<salt>[0-9a-f]{8})-(?<hash>[0-9a-f]{32})\._transfer-verification\.' . preg_quote(SERVER_NAME, '/') . '\.$/Dm', implode(LF, $results), $matches) !== 1)
 if (preg_match('/^' . preg_quote($domain, '/') . '[\t ]+[0-9]{1,8}[\t ]+IN[\t ]+NS[\t ]+(?<salt>[0-9a-f]{8})-(?<hash>[0-9a-f]{32})\._transfer-verification\.' . preg_quote(SERVER_NAME, '/') . '\.$/Dm', implode(LF, $results), $matches) !== 1)
-	output(403, 'Enregistrement d\'authentification introuvable');
+	output(403, _('NS authentication record not found.'));
 
 
 checkAuthToken($matches['salt'], $matches['hash']);
 checkAuthToken($matches['salt'], $matches['hash']);
 
 
@@ -23,4 +23,4 @@ knotcZoneExec(CONF['reg']['registry'], [
 	$matches['salt'] . '-' . $matches['hash'] . '._transfer-verification.' . SERVER_NAME . '.'
 	$matches['salt'] . '-' . $matches['hash'] . '._transfer-verification.' . SERVER_NAME . '.'
 ], 'delete');
 ], 'delete');
 
 
-output(200, 'Le domaine a été transféré vers le compte présent, l\'enregistrement d\'authentification a été automatiquement retiré.');
+output(200, _('The domain has been transferred to the current account ; the NS authentication record has been automatically deleted.'));

+ 1 - 1
pg-act/reg/unregister.php

@@ -4,4 +4,4 @@ regCheckDomainPossession($_POST['domain']);
 
 
 regDeleteDomain($_POST['domain']);
 regDeleteDomain($_POST['domain']);
 
 
-output(200, 'Domaine effacé du registre.');
+output(200, _('Domain unregistered.'));

+ 3 - 3
pg-view/auth/approval.php

@@ -1,10 +1,10 @@
 <p>
 <p>
-	Ce formulaire permet d'utiliser une clé d'approbation pour valider son compte. Une clé d'approbation est distribuée par l'administrataire sur demande.
+	<?= _('This form allows to use an approval key to validate your account. Approval keys are distributed by an administrator upon request.') ?>
 </p>
 </p>
 
 
 <form method="post">
 <form method="post">
-	<label for="key">Clé d'approbation</label><br>
+	<label for="key"><?= _('Approval key') ?></label><br>
 	<input required="" id="key" size="33" name="key" type="text" placeholder="27b81fbd8277b11ed1cf03d476cec503">
 	<input required="" id="key" size="33" name="key" type="text" placeholder="27b81fbd8277b11ed1cf03d476cec503">
 	<br>
 	<br>
-	<input type="submit" value="Utiliser pour ce compte">
+	<input type="submit" value="<?= _('Use for this account') ?>">
 </form>
 </form>

+ 18 - 15
pg-view/auth/index.php

@@ -1,30 +1,33 @@
 <?php displayIndex(); ?>
 <?php displayIndex(); ?>
 <p>
 <p>
-<?php if (isset($_SESSION['id'])) { ?>
-	Vous utilisez actuellement un compte <?= (($_SESSION['type'] === 'approved') ? 'approuvé' : 'de test') ?>. Son identifiant interne est <code><?= $_SESSION['id'] ?></code>.
-<?php } else { ?>
-	Vous n'utilisez actuellement aucun compte.
-<?php } ?>
+<?php if (isset($_SESSION['id'])) {
+	echo match ($_SESSION['type']) {
+		'testing' => _('You are currently using a testing account.'),
+		'approved' => _('You are currently using an approved account.'),
+	} . ' ' .  sprintf(_('It\'s internal ID is %s.'), '<small><code>' . $_SESSION['id'] . '</code></small>');
+} else {
+	echo _('You are not logged in.');
+} ?>
 </p>
 </p>
 
 
-<h2>Types de comptes</h2>
+<h2><?= _('Account types') ?></h2>
 
 
 <dl>
 <dl>
-	<dt><span aria-hidden="true">⏳ </span>De test</dt>
+	<dt><span aria-hidden="true">⏳ </span><em><?= _('Testing') ?></em></dt>
 	<dd>
 	<dd>
-		C'est le type de compte par défaut, avec des fonctionnalités limitées pour éviter les abus&nbsp;:
+		<?= _('It\'s the default account type, with limited capabilities in order to avoid abuses:') ?>
 		<ul>
 		<ul>
-			<li>Risque d'être supprimé n'importe quand</li>
-			<li><?= ((CONF['ht']['user_quota_testing'] >> 30) >= 1) ? CONF['ht']['user_quota_testing'] >> 30 . ' ' . linkToDocs('units', '<abbr title="gibioctet">Gio</abbr>') : CONF['ht']['user_quota_testing'] >> 20 . ' ' . linkToDocs('units', '<abbr title="mébioctet">Mio</abbr>') ?> de SFTP</li>
-			<li>Certificat Let's Encrypt de test</li>
+			<li><strong><?= _('May be deleted anytime') ?></strong></li>
+			<li><?= sprintf(_('%s of SFTP quota'), ((CONF['ht']['user_quota_testing'] >> 30) >= 1) ? CONF['ht']['user_quota_testing'] >> 30 . ' ' . _('<abbr title="gibibyte">GiB</abbr>') : CONF['ht']['user_quota_testing'] >> 20 . ' ' . _('<abbr title="mebibyte">MiB</abbr>')) ?></li>
+			<li><?= _('Let\'s Encrypt certificate from the staging environment (not trusted by clients)') ?></li>
 		</ul>
 		</ul>
 	</dd>
 	</dd>
-	<dt><span aria-hidden="true">👤 </span>Approuvé</dt>
+	<dt><span aria-hidden="true">👤 </span><em><?= _('Approved') ?></em></dt>
 	<dd>
 	<dd>
-		C'est originellement un compte de test mais qui a été approuvé par ane administrataire, et qui a pour but d'être utilisé de façon stable&nbsp;:
+		<?= _('It was originally a testing account, but has been approved by an administrator, and is suited for stable usecases:') ?>
 		<ul>
 		<ul>
-			<li><?= ((CONF['ht']['user_quota_approved'] >> 30) >= 1) ? CONF['ht']['user_quota_approved'] >> 30 . ' ' . linkToDocs('units', '<abbr title="gibioctet">Gio</abbr>') : CONF['ht']['user_quota_approved'] >> 20 . ' ' . linkToDocs('units', '<abbr title="mébioctet">Mio</abbr>') ?> de SFTP</li>
-			<li>Vrai certificat Let's Encrypt</li>
+			<li><?= sprintf(_('%s of SFTP quota'), ((CONF['ht']['user_quota_approved'] >> 30) >= 1) ? CONF['ht']['user_quota_approved'] >> 30 . ' ' . _('<abbr title="gibibyte">GiB</abbr>') : CONF['ht']['user_quota_approved'] >> 20 . ' ' . _('<abbr title="mebibyte">MiB</abbr>')) ?></li>
+			<li><?= _('Stable Let\'s Encrypt certificates') ?></li>
 		</ul>
 		</ul>
 	</dd>
 	</dd>
 </dl>
 </dl>

+ 5 - 5
pg-view/auth/login.php

@@ -1,13 +1,13 @@
-<p>Pas de compte ? <a href="register">En créer un</a></p>
+<p><?= _('Need an accout?') ?> <a href="register"><?= _('Register') ?></a></p>
 
 
 <form method="post">
 <form method="post">
-	<label for="username">Identifiant</label><br>
-	<input required="" minlength="1" maxlength="1024" pattern="<?= USERNAME_REGEX ?>" id="username" name="username" type="text" placeholder="<?= PLACEHOLDER_USERNAME ?>">
+	<label for="username"><?= _('Username') ?></label><br>
+	<input required="" autocomplete="username" minlength="1" maxlength="1024" pattern="<?= USERNAME_REGEX ?>" id="username" name="username" type="text" placeholder="<?= PLACEHOLDER_USERNAME ?>">
 	<br>
 	<br>
 
 
-	<label for="password">Clé de passe</label><br>
+	<label for="password"><?= _('Password') ?></label><br>
 	<input required="" autocomplete="current-password" minlength="8" maxlength="1024" pattern="<?= PASSWORD_REGEX ?>" id="password" name="password" type="password" placeholder="<?= PLACEHOLDER_PASSWORD ?>">
 	<input required="" autocomplete="current-password" minlength="8" maxlength="1024" pattern="<?= PASSWORD_REGEX ?>" id="password" name="password" type="password" placeholder="<?= PLACEHOLDER_PASSWORD ?>">
 	<br>
 	<br>
 
 
-	<input type="submit" value="Connexion">
+	<input type="submit" value="<?= _('Log in') ?>">
 </form>
 </form>

+ 3 - 7
pg-view/auth/password.php

@@ -1,13 +1,9 @@
-<p>
-	Vous pouvez ici changer la clé de passe permettant d'accéder à votre compte Niver.
-</p>
-
 <form method="post">
 <form method="post">
-	<label for="current-password">Clé de passe actuelle</label><br>
+	<label for="current-password"><?= _('Current password') ?></label><br>
 	<input required="" autocomplete="current-password" minlength="8" maxlength="1024" pattern="<?= PASSWORD_REGEX ?>" id="current-password" name="current-password" type="password" placeholder="<?= PLACEHOLDER_PASSWORD ?>"><br>
 	<input required="" autocomplete="current-password" minlength="8" maxlength="1024" pattern="<?= PASSWORD_REGEX ?>" id="current-password" name="current-password" type="password" placeholder="<?= PLACEHOLDER_PASSWORD ?>"><br>
 
 
-	<label for="new-password">Nouvelle clé de passe</label><br>
+	<label for="new-password"><?= _('New password') ?></label><br>
 	<input required="" autocomplete="new-password" minlength="8" maxlength="1024" pattern="<?= PASSWORD_REGEX ?>" id="new-password" name="new-password" type="password" placeholder="<?= PLACEHOLDER_PASSWORD ?>"><br>
 	<input required="" autocomplete="new-password" minlength="8" maxlength="1024" pattern="<?= PASSWORD_REGEX ?>" id="new-password" name="new-password" type="password" placeholder="<?= PLACEHOLDER_PASSWORD ?>"><br>
 
 
-	<input type="submit" value="Mettre à jour">
+	<input type="submit" value="<?= _('Update password') ?>">
 </form>
 </form>

+ 6 - 8
pg-view/auth/register.php

@@ -1,17 +1,15 @@
-<p>Déjà un compte ? <a href="login">Se connecter</a></p>
+<p><?= _('Already have an account?') ?> <a href="login"><?= _('Log in') ?></a></p>
 
 
 <form method="post">
 <form method="post">
-
-	<label for="username">Identifiant</label>
+	<label for="username"><?= _('Username') ?></label>
 	<br>
 	<br>
-	<input id="username" minlength="1" maxlength="1024" pattern="<?= USERNAME_REGEX ?>" required="" name="username" type="text" placeholder="<?= PLACEHOLDER_USERNAME ?>"><br>
+	<input id="username" autocomplete="username" minlength="1" maxlength="1024" pattern="<?= USERNAME_REGEX ?>" required="" name="username" type="text" placeholder="<?= PLACEHOLDER_USERNAME ?>"><br>
 
 
 	<details>
 	<details>
-		<summary><label for="password">Clé de passe</label></summary>
-		<p>Une clé de passe sécurisée est trop compliquée à deviner pour une attaque qui testerait automatiquement plein de clés de passe tout en connaissant d'autres informations et secrets sur vous.</p>
-		<p>Minimum 8 caractères si elle contient minuscule, majuscule et chiffre, ou minimum 10 caractères sinon.</p>
+		<summary><label for="password"><?= _('Password') ?></label></summary>
+		<?= sprintf(_('Minimum %1$s characters, or %2$s characters if it contains lowercase, uppercase and digit.'), 10, 8) ?>
 	</details>
 	</details>
 	<input autocomplete="new-password" id="password" minlength="8" maxlength="1024" pattern="<?= PASSWORD_REGEX ?>" required="" name="password" type="password" placeholder="<?= PLACEHOLDER_PASSWORD ?>">
 	<input autocomplete="new-password" id="password" minlength="8" maxlength="1024" pattern="<?= PASSWORD_REGEX ?>" required="" name="password" type="password" placeholder="<?= PLACEHOLDER_PASSWORD ?>">
 	<br>
 	<br>
-	<input type="submit" value="Créer ce compte">
+	<input type="submit" value="<?= _('Create an account') ?>">
 </form>
 </form>

+ 3 - 10
pg-view/auth/unregister.php

@@ -1,17 +1,10 @@
 <p>
 <p>
-	Cette action supprimera toutes les données appartenant à ce compte, y compris&nbsp;:
+	<?= _('This will delete every resource managed by the current account, including registered domains, hosted DNS records, websites files and cryptographic keys for Onion services and DNSSEC.') ?>
 </p>
 </p>
 
 
-<ul>
-	<li>la possession et la réservation des domaines dans le registre</li>
-	<li>les enregistrements DNS des zones hébergées sur le serveur de noms</li>
-	<li>le contenu des sites</li>
-	<li>les paires de clés des services Onion</li>
-</ul>
-
 <form method="post">
 <form method="post">
 	<input type="checkbox" name="delete" id="delete" required="">
 	<input type="checkbox" name="delete" id="delete" required="">
-	<label for="delete">Supprimer le compte actuel et toutes ses données (requis)</label>
+	<label for="delete"><?= _('Delete the current account and everything related (required)') ?></label>
 	<br>
 	<br>
-	<input type="submit" value="Supprimer">
+	<input type="submit" value="<?= _('Delete') ?>">
 </form>
 </form>

+ 3 - 7
pg-view/auth/username.php

@@ -1,10 +1,6 @@
-<p>
-	Vous pouvez ici changer l'identifiant permettant d'accéder à votre compte Niver.
-</p>
-
 <form method="post">
 <form method="post">
-	<label for="new-username">Nouvel identifiant</label><br>
-	<input required="" autocomplete="new-username" minlength="1" maxlength="1024" pattern="<?= USERNAME_REGEX ?>" id="new-username" name="new-username" type="text" placeholder="<?= PLACEHOLDER_USERNAME ?>"><br>
+	<label for="new-username"><?= _('New username') ?></label><br>
+	<input required="" autocomplete="username" minlength="1" maxlength="1024" pattern="<?= USERNAME_REGEX ?>" id="new-username" name="new-username" type="text" placeholder="<?= PLACEHOLDER_USERNAME ?>"><br>
 
 
-	<input type="submit" value="Mettre à jour">
+	<input type="submit" value="<?= _('Update username') ?>">
 </form>
 </form>

+ 5 - 5
pg-view/ht/add-dns.php

@@ -1,9 +1,9 @@
 <p>
 <p>
-	Ajouter sur un dossier de site un accès <?= linkToDocs('http', 'HTTP') ?> par <?= linkToDocs('dns', 'DNS') ?> et <?= linkToDocs('tls', 'TLS') ?> <?= linkToDocs('ca', 'authentifié par <em>Let\'s Encrypt</em>') ?>.
+	<?= _('A Let\'s Encrypt certificate will be obtained.') ?>
 </p>
 </p>
 
 
 <p>
 <p>
-	Le domaine doit posséder les enregistrements ci-après lors du traitement de ce formulaire.
+	<?= _('The domain must have the following records when the form is being processed.') ?>
 </p>
 </p>
 
 
 <dl>
 <dl>
@@ -22,9 +22,9 @@
 </dl>
 </dl>
 
 
 <form method="post">
 <form method="post">
-	<label for="domain">Domaine sur lequel répondre</label><br>
+	<label for="domain"><?= _('Domain') ?></label><br>
 	<input required="" placeholder="site.<?= PLACEHOLDER_DOMAIN ?>" id="domain" name="domain" type="text"><br>
 	<input required="" placeholder="site.<?= PLACEHOLDER_DOMAIN ?>" id="domain" name="domain" type="text"><br>
-	<label for="dir">Dossier ciblé</label><br>
+	<label for="dir"><?= _('Target directory') ?></label><br>
 	<select required="" name="dir" id="dir">
 	<select required="" name="dir" id="dir">
 		<option value="" disabled="" selected="">---</option>
 		<option value="" disabled="" selected="">---</option>
 <?php
 <?php
@@ -33,5 +33,5 @@ foreach (dirsStatuses('dns') as $dir => $alreadyEnabled)
 ?>
 ?>
 	</select>
 	</select>
 	<br>
 	<br>
-	<input type="submit" value="Ajouter l'accès">
+	<input type="submit" value="<?= _('Setup access') ?>">
 </form>
 </form>

+ 2 - 6
pg-view/ht/add-onion.php

@@ -1,9 +1,5 @@
-<p>
-	Ajouter un accès par <?= linkToDocs('tor', 'service Onion') ?> sur un dossier.
-</p>
-
 <form method="post">
 <form method="post">
-	<label for="dir">Dossier ciblé</label><br>
+	<label for="dir"><?= _('Target directory') ?></label><br>
 	<select required="" name="dir" id="dir">
 	<select required="" name="dir" id="dir">
 		<option value="" disabled="" selected="">---</option>
 		<option value="" disabled="" selected="">---</option>
 <?php
 <?php
@@ -12,5 +8,5 @@ foreach (dirsStatuses('onion') as $dir => $alreadyEnabled)
 ?>
 ?>
 	</select>
 	</select>
 	<br>
 	<br>
-	<input type="submit" value="Ajouter l'accès">
+	<input type="submit" value="<?= _('Setup access') ?>">
 </form>
 </form>

+ 3 - 7
pg-view/ht/add-subdomain.php

@@ -1,11 +1,7 @@
-<p>
-	Ajouter sur un dossier de site un accès <?= linkToDocs('http', 'HTTP') ?> par sous-domaine de <code><?= CONF['ht']['subdomain_domain'] ?></code>.
-</p>
-
 <form method="post">
 <form method="post">
-	<label for="subdomain">Sous-domaine sur lequel répondre</label><br>
+	<label for="subdomain"><?= _('Subdomain') ?></label><br>
 	<input required="" placeholder="label" id="subdomain" name="subdomain" type="text"><code>.<?= CONF['ht']['subdomain_domain'] ?></code><br>
 	<input required="" placeholder="label" id="subdomain" name="subdomain" type="text"><code>.<?= CONF['ht']['subdomain_domain'] ?></code><br>
-	<label for="dir">Dossier ciblé</label><br>
+	<label for="dir"><?= _('Target directory') ?></label><br>
 	<select required="" name="dir" id="dir">
 	<select required="" name="dir" id="dir">
 		<option value="" disabled="" selected="">---</option>
 		<option value="" disabled="" selected="">---</option>
 <?php
 <?php
@@ -14,5 +10,5 @@ foreach (dirsStatuses('subdomain') as $dir => $alreadyEnabled)
 ?>
 ?>
 	</select>
 	</select>
 	<br>
 	<br>
-	<input type="submit" value="Ajouter l'accès">
+	<input type="submit" value="<?= _('Setup access') ?>">
 </form>
 </form>

+ 3 - 7
pg-view/ht/add-subpath.php

@@ -1,11 +1,7 @@
-<p>
-	Ajouter sur un dossier de site un accès <?= linkToDocs('http', 'HTTP') ?> par sous-chemin de <code><?= CONF['ht']['subpath_domain'] ?>/</code>.
-</p>
-
 <form method="post">
 <form method="post">
-	<label for="path">Chemin sur lequel répondre</label><br>
+	<label for="path"><?= _('Path') ?></label><br>
 	<code>https://<?= CONF['ht']['subpath_domain'] ?>/</code><input required="" placeholder="path" id="path" name="path" type="text"><br>
 	<code>https://<?= CONF['ht']['subpath_domain'] ?>/</code><input required="" placeholder="path" id="path" name="path" type="text"><br>
-	<label for="dir">Dossier ciblé</label><br>
+	<label for="dir"><?= _('Target directory') ?></label><br>
 	<select required="" name="dir" id="dir">
 	<select required="" name="dir" id="dir">
 		<option value="" disabled="" selected="">---</option>
 		<option value="" disabled="" selected="">---</option>
 <?php
 <?php
@@ -14,5 +10,5 @@ foreach (dirsStatuses('subpath') as $dir => $alreadyEnabled)
 ?>
 ?>
 	</select>
 	</select>
 	<br>
 	<br>
-	<input type="submit" value="Ajouter l'accès">
+	<input type="submit" value="<?= _('Setup access') ?>">
 </form>
 </form>

+ 2 - 6
pg-view/ht/del.php

@@ -1,9 +1,5 @@
-<p>
-	Retirer un accès HTTP d'un dossier
-</p>
-
 <form method="post">
 <form method="post">
-	<label for="site">Accès à retirer</label><br>
+	<label for="site"><?= _('Access to delete') ?></label><br>
 	<select required="" name="site" id="site">
 	<select required="" name="site" id="site">
 		<option value="" disabled="" selected="">---</option>
 		<option value="" disabled="" selected="">---</option>
 <?php
 <?php
@@ -19,5 +15,5 @@ foreach (query('select', 'sites', ['username' => $_SESSION['id'] ?? '']) as $sit
 ?>
 ?>
 	</select>
 	</select>
 	<br>
 	<br>
-	<input type="submit" value="Retirer l'accès">
+	<input type="submit" value="<?= _('Delete access') ?>">
 </form>
 </form>

+ 30 - 29
pg-view/ht/index.php

@@ -1,17 +1,16 @@
 <p>
 <p>
-	Ce service permet d'envoyer des fichiers sur le serveur par <?= linkToDocs('sftp', 'SFTP') ?> afin de les rendre accessibles par <?= linkToDocs('http', 'HTTP') ?>.
+	<?= _('This service allows you to send files on the server using SFTP, and to make them publicly available with HTTP.') ?>
 </p>
 </p>
 
 
 <?php displayIndex(); ?>
 <?php displayIndex(); ?>
 
 
 <section>
 <section>
-	<h2>Sites actuellement hébergés</h2>
-	<dl>
+	<h2><?= _('Currently hosted sites') ?></h2>
 <?php
 <?php
 
 
 $sites = query('select', 'sites', ['username' => $_SESSION['id'] ?? '']);
 $sites = query('select', 'sites', ['username' => $_SESSION['id'] ?? '']);
 if ($sites === [])
 if ($sites === [])
-	echo '	<p>Ce compte n\'héberge aucun site sur cette instance.<p>' . LF;
+	echo '	<p><p>' . LF;
 else {
 else {
 	echo '	<dl>' . LF;
 	echo '	<dl>' . LF;
 	foreach ($sites as $site) {
 	foreach ($sites as $site) {
@@ -36,68 +35,69 @@ else {
 </section>
 </section>
 
 
 <section>
 <section>
-	<h2>Ajouter un accès de site</h2>
+	<h2><?= _('Adding a site access') ?></h2>
 
 
-	<p>Pour pouvoir y ajouter un accès par ce service, un site doit auparavent être téléversé dans un sous-dossier direct de l'espace SFTP. Le nom de ce sous-dossier ne peut contenir que <abbr title="abcdefghijklmnopqrstuvwxyz"><code>a</code>-<code>z</code></abbr>, <abbr title="ABCDEFGHIJKLMNOPQRSTUVWXYZ"><code>A</code>-<code>Z</code></abbr>, <abbr title="0123456789"><code>0</code>-<code>9</code></abbr>, <code>_</code> et <code>-</code>.</p>
+	<p><?= sprintf(_('In order to be able to setup an HTTP site with this service, a subdirectory for this site must be created inside the SFTP space first. The name of this subdirectory can only contain %1$s, %2$s, %3$s, %4$s and %5$s.'), '<abbr title="abcdefghijklmnopqrstuvwxyz"><code>a</code>-<code>z</code></abbr>', '<abbr title="ABCDEFGHIJKLMNOPQRSTUVWXYZ"><code>A</code>-<code>Z</code></abbr>', '<abbr title="0123456789"><code>0</code>-<code>9</code></abbr>', '<code>_</code>', '<code>-</code>') ?></p>
 </section>
 </section>
 
 
 <section>
 <section>
 	<h2>SFTP</h2>
 	<h2>SFTP</h2>
 
 
+<?php
+$quota = ($_SESSION['type'] ?? '' === 'approved') ? CONF['ht']['user_quota_approved'] : CONF['ht']['user_quota_testing'];
+?>
+
 	<p>
 	<p>
-		Vous avez accès à un espace <abbr title="SSH File Transfert Protocol">SFTP</abbr>, limité à <?php
-$quotaSize = ($_SESSION['type'] ?? '' === 'approved') ? CONF['ht']['user_quota_approved'] : CONF['ht']['user_quota_testing'];
-echo (($quotaSize >> 30) >= 1) ? $quotaSize >> 30 . ' ' . linkToDocs('units', '<abbr title="gibioctet">Gio</abbr>') : $quotaSize >> 20 . ' ' . linkToDocs('units', '<abbr title="mébioctet">Mio</abbr>')
-?>. Indiquez les données ci-dessous à votre client <abbr title="SSH File Transfert Protocol">SFTP</abbr> pour y accéder.
+		<?= sprintf(_('The SFTP space is limited to %s. Indicate the following values to your SFTP client to access it.'), (($quota >> 30) >= 1) ? $quota >> 30 . ' ' . _('<abbr title="gibibyte">GiB</abbr>') : $quota >> 20 . ' ' . _('<abbr title="mebibyte">MiB</abbr>')) ?>
 	</p>
 	</p>
 
 
 	<section>
 	<section>
-		<h3>Authentifier le serveur</h3>
+		<h3><?= _('Authenticating the server') ?></h3>
 
 
-		<p>Un enregistrement SSHFP est disponible.</p>
+		<p><?= _('An SSHFP record is available.') ?></p>
 
 
 		<details>
 		<details>
-			<summary>Clé publique</summary>
+			<summary><?= _('Plain public key') ?></summary>
 			<code><?= file_get_contents(CONF['ht']['sftp_pub']) ?></code>
 			<code><?= file_get_contents(CONF['ht']['sftp_pub']) ?></code>
 		</details>
 		</details>
 
 
 		<details open="">
 		<details open="">
-			<summary>Empreinte</summary>
+			<summary><?= _('Public key fingerprint') ?></summary>
 			<code><?= file_get_contents(CONF['ht']['sftp_fp']) ?></code>
 			<code><?= file_get_contents(CONF['ht']['sftp_fp']) ?></code>
 		</details>
 		</details>
 
 
 		<details>
 		<details>
-			<summary>Art ASCII</summary>
+			<summary><?= _('ASCII art') ?></summary>
 			<pre><?= file_get_contents(CONF['ht']['sftp_asciiart']) ?></pre>
 			<pre><?= file_get_contents(CONF['ht']['sftp_asciiart']) ?></pre>
 		</details>
 		</details>
 
 
 	</section>
 	</section>
 
 
 	<section>
 	<section>
-		<h3>Se connecter au serveur</h3>
+		<h3><?= _('Connecting to the server') ?></h3>
 
 
 		<a href="sftp://<?= isset($_SESSION['display-username']) ? $_SESSION['display-username'] : '&lt;username&gt;'; ?>@<?= CONF['ht']['sftp_domain'] ?>:<?= CONF['ht']['public_sftp_port'] ?>/">sftp://<?= isset($_SESSION['display-username']) ? $_SESSION['display-username'] : '&lt;username&gt;'; ?>@<?= CONF['ht']['sftp_domain'] ?>:<?= CONF['ht']['public_sftp_port'] ?>/</a>
 		<a href="sftp://<?= isset($_SESSION['display-username']) ? $_SESSION['display-username'] : '&lt;username&gt;'; ?>@<?= CONF['ht']['sftp_domain'] ?>:<?= CONF['ht']['public_sftp_port'] ?>/">sftp://<?= isset($_SESSION['display-username']) ? $_SESSION['display-username'] : '&lt;username&gt;'; ?>@<?= CONF['ht']['sftp_domain'] ?>:<?= CONF['ht']['public_sftp_port'] ?>/</a>
 
 
 		<dl>
 		<dl>
-			<dt>Serveur</dt>
+			<dt><?= _('Server') ?></dt>
 			<dd>
 			<dd>
 				<code><?= CONF['ht']['sftp_domain'] ?></code>
 				<code><?= CONF['ht']['sftp_domain'] ?></code>
 			</dd>
 			</dd>
-			<dt>Port</dt>
+			<dt><?= _('Port') ?></dt>
 			<dd>
 			<dd>
 				<code><?= CONF['ht']['public_sftp_port'] ?></code><?php if (CONF['ht']['public_sftp_port'] === 22) echo " (par défaut)"; ?>
 				<code><?= CONF['ht']['public_sftp_port'] ?></code><?php if (CONF['ht']['public_sftp_port'] === 22) echo " (par défaut)"; ?>
 			</dd>
 			</dd>
-			<dt>Dossier</dt>
+			<dt><?= _('Directory') ?></dt>
 			<dd>
 			<dd>
 				<code>/</code>
 				<code>/</code>
 			</dd>
 			</dd>
-			<dt>Utilisataire</dt>
+			<dt><?= _('Username') ?></dt>
 			<dd>
 			<dd>
 				<code><?= isset($_SESSION['display-username']) ? $_SESSION['display-username'] : '&lt;username&gt;'; ?></code>
 				<code><?= isset($_SESSION['display-username']) ? $_SESSION['display-username'] : '&lt;username&gt;'; ?></code>
 			</dd>
 			</dd>
-			<dt>Clé de passe</dt>
+			<dt><?= _('Password') ?></dt>
 			<dd>
 			<dd>
-				celle de votre compte
+				<?= _('The one of your account') ?>
 			</dd>
 			</dd>
 		</dl>
 		</dl>
 	</section>
 	</section>
@@ -108,16 +108,17 @@ echo (($quotaSize >> 30) >= 1) ? $quotaSize >> 30 . ' ' . linkToDocs('units', '<
 
 
 	<h3>CSP</h3>
 	<h3>CSP</h3>
 	<p>
 	<p>
-		Une politique de sécurité du contenu (<abbr title="Content-Security-Policy">CSP</abbr>) interdit l'intégration de JavaScript ou de ressources depuis des sites distants.
+		<?= _('A content security policy (CSP) forbids Web browsers from loading JavaScript or third-party resources.') ?>
 	</p>
 	</p>
-	<h3>Compression gzip</h3>
+
+	<h3><?= _('gzip compression') ?></h3>
 	<p>
 	<p>
-		La compression <em>gzip</em> statique est supportée, si le client le supporte et que le fichier est disponible, <code>chemin.gz</code> est servi au lieu de <code>chemin</code>.
+		<?= _('Static <em>gzip</em> compression is supported: if the client supports it and the file is available, <code>path.gz</code> is served instead of <code>path</code>.') ?>
 	</p>
 	</p>
 
 
-	<h3>Page d'index</h3>
+	<h3><?= _('Index page') ?></h3>
 	<p>
 	<p>
-		Lors d'une requête sur un dossier, le premier des fichiers suivants qui existe <em>dans ce dossier</em> est répondu&nbsp;:
+		<?= _('When a request hits a directory, the first of the following files that exists <em>inside this directory</em> is served:') ?>
 	</p>
 	</p>
 	<ol>
 	<ol>
 		<li><code>index.html</code></li>
 		<li><code>index.html</code></li>
@@ -125,9 +126,9 @@ echo (($quotaSize >> 30) >= 1) ? $quotaSize >> 30 . ' ' . linkToDocs('units', '<
 		<li><code>index.gmi</code></li>
 		<li><code>index.gmi</code></li>
 	</ol>
 	</ol>
 
 
-	<h3>Page d'erreur 404</h3>
+	<h3><?= _('404 error page') ?></h3>
 	<p>
 	<p>
-		Lors d'une requête aboutissant à une erreur <code>404</code>, le premier des fichiers suivants qui existe <em>à la racine du site</em> est répondu&nbsp;:
+		<?= _('When a request ends in a <code>404</code> error, the first of the following files that exists <em>at the root of the site</em> is served:') ?>
 	</p>
 	</p>
 	<ol>
 	<ol>
 		<li><code>404.html</code></li>
 		<li><code>404.html</code></li>

+ 4 - 11
pg-view/ns/caa.php

@@ -1,23 +1,16 @@
-<p>
-	<?= linkToDocs('record-caa', 'Documentation du type d\'enregistrement CAA') ?>
-</p>
-
 <form method="post">
 <form method="post">
-
 <?php require 'form.ns.php'; ?>
 <?php require 'form.ns.php'; ?>
-
-	<br>
-	<label for="flag">Flag</label>
+	<label for="flag"><?= _('Flag') ?></label>
 	<br>
 	<br>
 	<input id="flag" min="0" max="127" placeholder="0" name="flag" type="number">
 	<input id="flag" min="0" max="127" placeholder="0" name="flag" type="number">
 	<br>
 	<br>
-	<label for="tag">Tag</label>
+	<label for="tag"><?= _('Tag') ?></label>
 	<br>
 	<br>
 	<input id="tag" minlenght="1" maxlength="128" pattern="^[a-z]{1,128}$" placeholder="issue" name="tag" type="text">
 	<input id="tag" minlenght="1" maxlength="128" pattern="^[a-z]{1,128}$" placeholder="issue" name="tag" type="text">
 	<br>
 	<br>
-	<label for="value">Valeur</label>
+	<label for="value"><?= _('Value') ?></label>
 	<br>
 	<br>
 	<input id="value" minlenght="3" maxlength="1024" pattern="^[a-z0-9.-]{3,1024}$" placeholder="letsencrypt.org" name="value" type="text">
 	<input id="value" minlenght="3" maxlength="1024" pattern="^[a-z0-9.-]{3,1024}$" placeholder="letsencrypt.org" name="value" type="text">
 	<br>
 	<br>
-	<input type="submit" value="Appliquer">
+	<input type="submit" value="<?= _('Apply') ?>">
 </form>
 </form>

+ 3 - 8
pg-view/ns/cname.php

@@ -1,13 +1,8 @@
-<p>
-	<?= linkToDocs('record-cname', 'Documentation du type d\'enregistrement CNAME') ?>
-</p>
-
 <form method="post">
 <form method="post">
-	<?php require 'form.ns.php'; ?>
-	<br>
-	<label for="cname">Nom canonique</label>
+<?php require 'form.ns.php'; ?>
+	<label for="cname"><?= _('Canonical name') ?></label>
 	<br>
 	<br>
 	<input id="cname" placeholder="main.<?= PLACEHOLDER_DOMAIN ?>" name="cname" type="text">
 	<input id="cname" placeholder="main.<?= PLACEHOLDER_DOMAIN ?>" name="cname" type="text">
 	<br>
 	<br>
-	<input type="submit" value="Appliquer">
+	<input type="submit" value="<?= _('Apply') ?>">
 </form>
 </form>

+ 3 - 8
pg-view/ns/dname.php

@@ -1,13 +1,8 @@
-<p>
-	<?= linkToDocs('record-dname', 'Documentation du type d\'enregistrement DNAME') ?>
-</p>
-
 <form method="post">
 <form method="post">
-	<?php require 'form.ns.php'; ?>
-	<br>
-	<label for="dname">Nom délégué</label>
+<?php require 'form.ns.php'; ?>
+	<label for="dname"><?= _('Delegation name') ?></label>
 	<br>
 	<br>
 	<input id="dname" placeholder="main.<?= PLACEHOLDER_DOMAIN ?>" name="dname" type="text">
 	<input id="dname" placeholder="main.<?= PLACEHOLDER_DOMAIN ?>" name="dname" type="text">
 	<br>
 	<br>
-	<input type="submit" value="Appliquer">
+	<input type="submit" value="<?= _('Apply') ?>">
 </form>
 </form>

+ 11 - 12
pg-view/ns/edit.php

@@ -1,5 +1,5 @@
 <form method="post">
 <form method="post">
-	<label for="zone">Zone à modifier</label>
+	<label for="zone"><?= _('Zone to be changed') ?></label>
 	<br>
 	<br>
 	<select required="" name="zone" id="zone">
 	<select required="" name="zone" id="zone">
 		<option value="" disabled="" selected="">-</option>
 		<option value="" disabled="" selected="">-</option>
@@ -9,7 +9,7 @@ foreach (nsListUserZones() as $zone)
 ?>
 ?>
 	</select>
 	</select>
 	<br>
 	<br>
-	<input type="submit" value="Afficher">
+	<input type="submit" value="<?= _('Display') ?>">
 </form>
 </form>
 
 
 <?php
 <?php
@@ -20,11 +20,11 @@ if (isset($data['zone_content'])) { // Display zone
 <form method="post">
 <form method="post">
 	<input type="hidden" name="zone" value="<?= $_POST['zone'] ?>">
 	<input type="hidden" name="zone" value="<?= $_POST['zone'] ?>">
 
 
-	<label for="zone-content">Nouveau contenu de la zone <code><strong><?= $_POST['zone'] ?></strong></code></label>
+	<label for="zone-content"><?= sprintf(_('New content of the %s zone'), '<code><strong>' . $_POST['zone'] . '</strong></code>') ?></label>
 	<br>
 	<br>
 	<textarea id="zone-content" name="zone-content" wrap="off" rows="<?= substr_count($data['zone_content'], LF) + 1 ?>"><?= htmlspecialchars($data['zone_content']) ?></textarea>
 	<textarea id="zone-content" name="zone-content" wrap="off" rows="<?= substr_count($data['zone_content'], LF) + 1 ?>"><?= htmlspecialchars($data['zone_content']) ?></textarea>
 	<br>
 	<br>
-	<input type="submit" value="Remplacer">
+	<input type="submit" value="<?= _('Replace') ?>">
 </form>
 </form>
 
 
 <?php
 <?php
@@ -35,24 +35,23 @@ displayFinalMessage($data);
 
 
 ?>
 ?>
 
 
-<h2>Valeurs par défaut</h2>
+<h2><?= _('Default values') ?></h2>
 
 
-<p>Si le TTL est omis, il sera définit à <code><time datetime="PT<?= DEFAULT_TTL ?>S"><?= DEFAULT_TTL ?></time></code> secondes.</p>
+<p><?= sprintf(_('If the TTL is omitted, it will default to %s seconds.'), '<code><time datetime="PT' . DEFAULT_TTL . 'S">' . DEFAULT_TTL . '</time></code>') ?></p>
 
 
-<p>La précision de la classe (<code>IN</code>) est facultative.</p>
+<p><?= _('Precising the class (<code>IN</code>) is optional.') ?></p>
 
 
-<h2>Valeurs autorisées</h2>
+<h2><?= _('Allowed values') ?></h2>
 
 
-<p>La zone n'est pas autorisée à dépasser <?= ZONE_MAX_CHARACTERS ?> caractères.</p>
+<p><?= sprintf(_('Submitted zone content is limited to %s characters.'), ZONE_MAX_CHARACTERS) ?></p>
 
 
-<p>Les TTLs ne sont autorisés qu'entre <code><time datetime="PT<?= MIN_TTL ?>S"><?= MIN_TTL ?></time></code> et <code><time datetime="PT<?= MAX_TTL ?>S"><?= MAX_TTL ?></time></code> secondes.</p>
+<p><?= sprintf(_('TTLs must last between %1$s and %2$s seconds.'), '<code><time datetime="PT' . MIN_TTL . 'S">' . MIN_TTL . '</time></code>', '<code><time datetime="PT' . MAX_TTL . 'S">' . MAX_TTL . '</time></code>') ?></p>
 
 
-<p>Les seuls types dont l'édition est autorisée sont&nbsp;:</p>
+<p><?= _('The only types that can be defined are:') ?></p>
 
 
 <ul>
 <ul>
 <?php
 <?php
 	foreach (ALLOWED_TYPES as $allowed_type)
 	foreach (ALLOWED_TYPES as $allowed_type)
 		echo '	<li><code>' . $allowed_type . '</code></li>';
 		echo '	<li><code>' . $allowed_type . '</code></li>';
-
 ?>
 ?>
 </ul>
 </ul>

+ 13 - 14
form.ns.php → pg-view/ns/form.ns.php

@@ -1,19 +1,18 @@
-	<label for="action">Action</label>
+	<label for="action"><?= _('Action') ?></label>
 	<select name="action" id="action">
 	<select name="action" id="action">
-		<option value="add">Ajouter</option>
-		<option value="delete">Retirer</option>
+		<option value="add"><?= _('Add') ?></option>
+		<option value="delete"><?= _('Delete') ?></option>
 	</select>
 	</select>
-	<br>
 
 
 	<fieldset>
 	<fieldset>
-		<legend>Domaine</legend>
+		<legend><?= _('Domain') ?></legend>
 		<div>
 		<div>
-			<label for="subdomain">Sous-domaine</label>
+			<label for="subdomain"><?= _('Subdomain') ?></label>
 			<br>
 			<br>
 			<input id="subdomain" size="16" placeholder="www" pattern="^(([a-z0-9_-]{1,63}\.?){1,127})|(@){1}$" name="subdomain" type="text">
 			<input id="subdomain" size="16" placeholder="www" pattern="^(([a-z0-9_-]{1,63}\.?){1,127})|(@){1}$" name="subdomain" type="text">
 		</div>
 		</div>
 		<div>
 		<div>
-			<label for="zone">Zone</label>
+			<label for="zone"><?= _('Zone') ?></label>
 			<br>
 			<br>
 			<select required="" name="zone" id="zone">
 			<select required="" name="zone" id="zone">
 				<option value="" disabled="" selected="">-</option>
 				<option value="" disabled="" selected="">-</option>
@@ -27,9 +26,9 @@ foreach (nsListUserZones() as $zone)
 	</fieldset>
 	</fieldset>
 
 
 	<fieldset>
 	<fieldset>
-		<legend><abbr title="Time To Live">TTL</abbr></legend>
+		<legend><abbr title="Time To Live"><?= _('TTL') ?></abbr></legend>
 		<div>
 		<div>
-			<label for="ttl-value">Valeur</label>
+			<label for="ttl-value"><?= _('Value') ?></label>
 			<br>
 			<br>
 			<input required="" id="ttl-value" list="ttls" name="ttl-value" size="6" type="number" min="1" max="432000" value="<?= DEFAULT_TTL ?>" placeholder="<?= DEFAULT_TTL ?>">
 			<input required="" id="ttl-value" list="ttls" name="ttl-value" size="6" type="number" min="1" max="432000" value="<?= DEFAULT_TTL ?>" placeholder="<?= DEFAULT_TTL ?>">
 			<datalist id="ttls">
 			<datalist id="ttls">
@@ -43,13 +42,13 @@ foreach (nsListUserZones() as $zone)
 			</datalist>
 			</datalist>
 		</div>
 		</div>
 		<div>
 		<div>
-			<label for="ttl-multiplier">Unité</label>
+			<label for="ttl-multiplier"><?= _('Unit') ?></label>
 			<br>
 			<br>
 			<select required="" name="ttl-multiplier" id="ttl-multiplier">
 			<select required="" name="ttl-multiplier" id="ttl-multiplier">
-				<option value="1">seconde</option>
-				<option value="60">minute</option>
-				<option value="3600">heure</option>
-				<option value="86400">jour</option>
+				<option value="1"><?= _('second') ?></option>
+				<option value="60"><?= _('minute') ?></option>
+				<option value="3600"><?= _('hour') ?></option>
+				<option value="86400"><?= _('day') ?></option>
 			</select>
 			</select>
 		</div>
 		</div>
 	</fieldset>
 	</fieldset>

+ 16 - 13
pg-view/ns/index.php

@@ -1,30 +1,33 @@
 <p>
 <p>
-	Ce service permet d'héberger et de gérer les enregistrements DNS d'une <?= linkToDocs('zone', 'zone DNS') ?>.
+	<?= _('This service allows to host and manage DNS records inside a DNS zone.') ?>
 </p>
 </p>
 
 
 <?php displayIndex(); ?>
 <?php displayIndex(); ?>
 
 
-<h2>Serveurs de noms</h2>
 
 
-<p>Une zone hébergée sur ce service est servie par ces serveurs de noms&nbsp;:</p>
-
-<ul>
-<?php
-foreach (CONF['ns']['servers'] as $server)
-	echo '	<li><code>' . $server . '</code></li>';
-?>
-</ul>
-
-<h2>Zones actuellement hébergées</h2>
+<h2><?= _('Currently hosted zones') ?></h2>
 
 
 <?php
 <?php
 
 
 $zones = query('select', 'zones', ['username' => $_SESSION['id'] ?? ''], 'zone');
 $zones = query('select', 'zones', ['username' => $_SESSION['id'] ?? ''], 'zone');
 if ($zones === [])
 if ($zones === [])
-	echo '<p>Ce compte n\'héberge aucune zone sur cette instance.<p>' . LF;
+	echo '<p>∅<p>' . LF;
 else {
 else {
 	echo '<ul>' . LF;
 	echo '<ul>' . LF;
 	foreach ($zones as $zone)
 	foreach ($zones as $zone)
 		echo '	<code><li>' . $zone . '</li></code>' . LF;
 		echo '	<code><li>' . $zone . '</li></code>' . LF;
 	echo '</ul>' . LF;
 	echo '</ul>' . LF;
 }
 }
+
+?>
+
+<h2><?= _('Name servers') ?></h2>
+
+<p><?= _('A zone hosted on this service is served by these name servers:') ?></p>
+
+<ul>
+<?php
+foreach (CONF['ns']['servers'] as $server)
+	echo '	<li><code>' . $server . '</code></li>';
+?>
+</ul>

+ 2 - 6
pg-view/ns/ip.php

@@ -1,10 +1,6 @@
-<p>
-	<?= linkToDocs('record-ip', 'Documentation des types d\'enregistrements A et AAAA') ?>
-</p>
-
 <form method="post">
 <form method="post">
 <?php require 'form.ns.php'; ?>
 <?php require 'form.ns.php'; ?>
-	<label for="ip">Adresse IP</label><br>
+	<label for="ip"><?= _('IP address') ?></label><br>
 	<input required="" pattern="^[a-f0-9:.]+$" id="ip" name="ip" minlength="2" maxlength="39" size="40" type="text" placeholder="<?= PLACEHOLDER_IPV6 ?> ou <?= PLACEHOLDER_IPV4 ?>"><br>
 	<input required="" pattern="^[a-f0-9:.]+$" id="ip" name="ip" minlength="2" maxlength="39" size="40" type="text" placeholder="<?= PLACEHOLDER_IPV6 ?> ou <?= PLACEHOLDER_IPV4 ?>"><br>
-	<input type="submit" value="Appliquer">
+	<input type="submit" value="<?= _('Apply') ?>">
 </form>
 </form>

+ 20 - 26
pg-view/ns/loc.php

@@ -1,82 +1,76 @@
-<p>
-	<?= linkToDocs('record-loc', 'Documentation du type d\'enregistrement LOC') ?>
-</p>
-
 <form method="post">
 <form method="post">
-
-	<?php require 'form.ns.php'; ?>
-
+<?php require 'form.ns.php'; ?>
 	<fieldset>
 	<fieldset>
-		<legend>Latitude</legend>
+		<legend><?= _('Latitude') ?></legend>
 		<div>
 		<div>
-			<label for="lat-deg">Degrés</label>
+			<label for="lat-deg"><?= _('Degrees') ?></label>
 			<br>
 			<br>
 			<input name="lat-deg" id="lat-deg" min="0" max="90" type="number" required="">
 			<input name="lat-deg" id="lat-deg" min="0" max="90" type="number" required="">
 		</div>
 		</div>
 		<div>
 		<div>
-			<label for="lat-min">Minutes</label>
+			<label for="lat-min"><?= _('Minutes') ?></label>
 			<br>
 			<br>
 			<input name="lat-min" id="lat-min" min="0" max="59" placeholder="0" type="number" required="">
 			<input name="lat-min" id="lat-min" min="0" max="59" placeholder="0" type="number" required="">
 		</div>
 		</div>
 		<div>
 		<div>
-			<label for="lat-sec">Secondes</label>
+			<label for="lat-sec"><?= _('Seconds') ?></label>
 			<br>
 			<br>
 			<input name="lat-sec" id="lat-sec" step="0.001" min="0" max="59.999" placeholder="0" type="number" required="">
 			<input name="lat-sec" id="lat-sec" step="0.001" min="0" max="59.999" placeholder="0" type="number" required="">
 		</div>
 		</div>
 		<div>
 		<div>
-			<label for="lat-dir">Direction</label>
+			<label for="lat-dir"><?= _('Direction') ?></label>
 			<br>
 			<br>
 			<select required="" name="lat-dir" id="lat-dir">
 			<select required="" name="lat-dir" id="lat-dir">
 				<option value="" selected="" disabled="">-</option>
 				<option value="" selected="" disabled="">-</option>
-				<option value="N">N - Nord</option>
-				<option value="S">S - Sud</option>
+				<option value="N"><code>N</code> - <?= _('North') ?></option>
+				<option value="S"><code>S</code> - <?= _('South') ?></option>
 			</select>
 			</select>
 		</div>
 		</div>
 	</fieldset>
 	</fieldset>
 
 
 	<fieldset>
 	<fieldset>
-		<legend>Longitude</legend>
+		<legend><?= _('Longitude') ?></legend>
 		<div>
 		<div>
-			<label for="lon-deg">Degrés</label>
+			<label for="lon-deg"><?= _('Degrees') ?></label>
 			<br>
 			<br>
 			<input name="lon-deg" id="lon-deg" min="0" max="180" type="number" required="">
 			<input name="lon-deg" id="lon-deg" min="0" max="180" type="number" required="">
 		</div>
 		</div>
 		<div>
 		<div>
-			<label for="lon-min">Minutes</label>
+			<label for="lon-min"><?= _('Minutes') ?></label>
 			<br>
 			<br>
 			<input name="lon-min" id="lon-min" min="0" max="59" placeholder="0" type="number" required="">
 			<input name="lon-min" id="lon-min" min="0" max="59" placeholder="0" type="number" required="">
 		</div>
 		</div>
 		<div>
 		<div>
-			<label for="lon-sec">Secondes</label>
+			<label for="lon-sec"><?= _('Seconds') ?></label>
 			<br>
 			<br>
 			<input name="lon-sec" id="lon-sec" step="0.001" min="0" max="59.999" placeholder="0" type="number" required="">
 			<input name="lon-sec" id="lon-sec" step="0.001" min="0" max="59.999" placeholder="0" type="number" required="">
 		</div>
 		</div>
 		<div>
 		<div>
-			<label for="lon-dir">Direction</label>
+			<label for="lon-dir"><?= _('Direction') ?></label>
 			<br>
 			<br>
 			<select required="" name="lon-dir" id="lon-dir">
 			<select required="" name="lon-dir" id="lon-dir">
 				<option value="" selected="" disabled="">-</option>
 				<option value="" selected="" disabled="">-</option>
-				<option value="E">E - Est</option>
-				<option value="W">W - Ouest</option>
+				<option value="E"><code>E</code> - <?= _('East') ?></option>
+				<option value="W"><code>W</code> - <?= _('West') ?></option>
 			</select>
 			</select>
 		</div>
 		</div>
 	</fieldset>
 	</fieldset>
 
 
-	<label for="alt">Altitude</label>
+	<label for="alt"><?= _('Altitude') ?></label>
 	<br>
 	<br>
 	<input name="alt" id="alt" step="0.01" min="-100000.00" max="42849672.95" type="number" required="">m
 	<input name="alt" id="alt" step="0.01" min="-100000.00" max="42849672.95" type="number" required="">m
 	<br>
 	<br>
-	<label for="size">Taille</label>
+	<label for="size"><?= _('Size') ?></label>
 	<br>
 	<br>
 	<input name="size" id="size" min="0" max="90000000" placeholder="1" type="number">m
 	<input name="size" id="size" min="0" max="90000000" placeholder="1" type="number">m
 	<br>
 	<br>
-	<label for="hp">Précision horizontale</label>
+	<label for="hp"><?= _('Horizontal precision') ?></label>
 	<br>
 	<br>
 	<input name="hp" id="hp" min="0" max="90000000" placeholder="10000" type="number" required="">m
 	<input name="hp" id="hp" min="0" max="90000000" placeholder="10000" type="number" required="">m
 	<br>
 	<br>
-	<label for="vp">Précision verticale</label>
+	<label for="vp"><?= _('Vertical precision') ?></label>
 	<br>
 	<br>
 	<input name="vp" id="vp" min="0" max="90000000" placeholder="10" type="number" required="">m
 	<input name="vp" id="vp" min="0" max="90000000" placeholder="10" type="number" required="">m
 	<br>
 	<br>
-	<input type="submit" value="Appliquer">
+	<input type="submit" value="<?= _('Apply') ?>">
 </form>
 </form>

+ 3 - 14
pg-view/ns/mx.php

@@ -1,23 +1,12 @@
-<p>
-	<?= linkToDocs('record-mx', 'Documentation du type d\'enregistrement MX') ?>
-</p>
-
 <form method="post">
 <form method="post">
-
 <?php require 'form.ns.php'; ?>
 <?php require 'form.ns.php'; ?>
-
-	<br>
-
-	<label for="priority">Priorité</label>
+	<label for="priority"><?= _('Priority') ?></label>
 	<br>
 	<br>
 	<input id="priority" min="0" max="65535" value="0" placeholder="0" name="priority" type="number">
 	<input id="priority" min="0" max="65535" value="0" placeholder="0" name="priority" type="number">
-
 	<br>
 	<br>
-
-	<label for="host">Hôte</label>
+	<label for="host"><?= _('Host') ?></label>
 	<br>
 	<br>
 	<input id="host" placeholder="mail.<?= PLACEHOLDER_DOMAIN ?>." name="host" type="text">
 	<input id="host" placeholder="mail.<?= PLACEHOLDER_DOMAIN ?>." name="host" type="text">
-
 	<br>
 	<br>
-	<input type="submit" value="Appliquer">
+	<input type="submit" value="<?= _('Apply') ?>">
 </form>
 </form>

+ 2 - 7
pg-view/ns/ns.php

@@ -1,13 +1,8 @@
-<p>
-	<?= linkToDocs('record-ns', 'Documentation du type d\'enregistrement NS') ?>
-</p>
-
 <form method="post">
 <form method="post">
 <?php require 'form.ns.php'; ?>
 <?php require 'form.ns.php'; ?>
-	<br>
-	<label for="ns">Serveur de nom</label>
+	<label for="ns"><?= _('Name server') ?></label>
 	<br>
 	<br>
 	<input id="ns" placeholder="ns1.<?= PLACEHOLDER_DOMAIN ?>" name="ns" type="text">
 	<input id="ns" placeholder="ns1.<?= PLACEHOLDER_DOMAIN ?>" name="ns" type="text">
 	<br>
 	<br>
-	<input type="submit" value="Appliquer">
+	<input type="submit" value="<?= _('Apply') ?>">
 </form>
 </form>

+ 14 - 15
pg-view/ns/print.php

@@ -1,15 +1,14 @@
-
 <form method="post">
 <form method="post">
 	<input type="radio" name="print" id="table" value="table" checked="">
 	<input type="radio" name="print" id="table" value="table" checked="">
-	<label for="table">Tableau de mes enregistrements</label>
+	<label for="table"><?= _('Records table') ?></label>
 	<br>
 	<br>
 	<input type="radio" name="print" id="ds" value="ds">
 	<input type="radio" name="print" id="ds" value="ds">
-	<label for="ds">Enregistrement DS</label>
+	<label for="ds"><?= _('DS record') ?></label>
 	<br>
 	<br>
 	<input type="radio" name="print" id="raw" value="raw">
 	<input type="radio" name="print" id="raw" value="raw">
-	<label for="raw">Fichier de zone brut</label>
+	<label for="raw"><?= _('Raw zonefile') ?></label>
 	<br>
 	<br>
-	<label for="zone">Zone</label>
+	<label for="zone"><?= _('Selected zone') ?></label>
 	<select required="" name="zone" id="zone">
 	<select required="" name="zone" id="zone">
 		<option value="" disabled="" selected="">-</option>
 		<option value="" disabled="" selected="">-</option>
 <?php
 <?php
@@ -18,7 +17,7 @@ foreach (nsListUserZones() as $zone)
 ?>
 ?>
 	</select>
 	</select>
 	<br>
 	<br>
-	<input type="submit" value="Afficher">
+	<input type="submit" value="<?= _('Display') ?>">
 </form>
 </form>
 
 
 <?php
 <?php
@@ -30,10 +29,10 @@ if (isset($data['zone-table'])) { ?>
 
 
 <table>
 <table>
 	<tr>
 	<tr>
-		<th>Domaine</th>
-		<th>TTL</th>
-		<th>Type</th>
-		<th>Contenu</th>
+		<th><?= _('Domain') ?></th>
+		<th><?= _('TTL') ?></th>
+		<th><?= _('Type') ?></th>
+		<th><?= _('Value') ?></th>
 	</tr>
 	</tr>
 <?php
 <?php
 	foreach ($data['zone-table'] as $zone_line) {
 	foreach ($data['zone-table'] as $zone_line) {
@@ -50,23 +49,23 @@ if (isset($data['zone-table'])) { ?>
 if (isset($data['zone-ds'])) { ?>
 if (isset($data['zone-ds'])) { ?>
 
 
 <dl>
 <dl>
-	<dt>Zone</dt>
+	<dt><?= _('Zone') ?></dt>
 	<dd>
 	<dd>
 		<code><?= $_POST['zone'] ?></code>
 		<code><?= $_POST['zone'] ?></code>
 	</dd>
 	</dd>
-	<dt>Tag</dt>
+	<dt><?= _('Tag') ?></dt>
 	<dd>
 	<dd>
 		<code><?= $data['zone-ds']['tag'] ?></code>
 		<code><?= $data['zone-ds']['tag'] ?></code>
 	</dd>
 	</dd>
-	<dt>Algorithme</dt>
+	<dt><?= _('Algorithm') ?></dt>
 	<dd>
 	<dd>
 		<code><?= $data['zone-ds']['algo'] ?></code><?= ($data['zone-ds']['algo'] === '15') ? ' (Ed25519)' : '' ?>
 		<code><?= $data['zone-ds']['algo'] ?></code><?= ($data['zone-ds']['algo'] === '15') ? ' (Ed25519)' : '' ?>
 	</dd>
 	</dd>
-	<dt>Type de condensat</dt>
+	<dt><?= _('Digest type') ?></dt>
 	<dd>
 	<dd>
 		<code><?= $data['zone-ds']['digest_type'] ?></code><?= ($data['zone-ds']['digest_type'] === '2') ? ' (SHA-256)' : '' ?>
 		<code><?= $data['zone-ds']['digest_type'] ?></code><?= ($data['zone-ds']['digest_type'] === '2') ? ' (SHA-256)' : '' ?>
 	</dd>
 	</dd>
-	<dt>Condensat</dt>
+	<dt><?= _('Digest') ?></dt>
 	<dd>
 	<dd>
 		<code><?= $data['zone-ds']['digest'] ?></code>
 		<code><?= $data['zone-ds']['digest'] ?></code>
 	</dd>
 	</dd>

+ 5 - 12
pg-view/ns/srv.php

@@ -1,35 +1,28 @@
-<p>
-	<?= linkToDocs('record-srv', 'Documentation du type d\'enregistrement SRV') ?>
-</p>
-
 <form method="post">
 <form method="post">
-
 <?php require 'form.ns.php'; ?>
 <?php require 'form.ns.php'; ?>
 
 
-	<br>
-
-	<label for="priority">Priorité</label>
+	<label for="priority"><?= _('Priority') ?></label>
 	<br>
 	<br>
 	<input id="priority" min="0" max="65535" value="0" placeholder="0" name="priority" type="number">
 	<input id="priority" min="0" max="65535" value="0" placeholder="0" name="priority" type="number">
 
 
 	<br>
 	<br>
 
 
-	<label for="weight">Poids</label>
+	<label for="weight"><?= _('Weight') ?></label>
 	<br>
 	<br>
 	<input id="weight" min="0" max="65535" value="0" placeholder="0" name="weight" type="number">
 	<input id="weight" min="0" max="65535" value="0" placeholder="0" name="weight" type="number">
 
 
 	<br>
 	<br>
 
 
-	<label for="port">Port</label>
+	<label for="port"><?= _('Port') ?></label>
 	<br>
 	<br>
 	<input id="port" min="0" max="65535" placeholder="32768" name="port" type="number">
 	<input id="port" min="0" max="65535" placeholder="32768" name="port" type="number">
 
 
 	<br>
 	<br>
 
 
-	<label for="target">Cible</label>
+	<label for="target"><?= _('Target') ?></label>
 	<br>
 	<br>
 	<input id="target" minlenght="1" maxlength="128" placeholder="service.<?= PLACEHOLDER_DOMAIN ?>." name="target" type="text">
 	<input id="target" minlenght="1" maxlength="128" placeholder="service.<?= PLACEHOLDER_DOMAIN ?>." name="target" type="text">
 
 
 	<br>
 	<br>
-	<input type="submit" value="Appliquer">
+	<input type="submit" value="<?= _('Apply') ?>">
 </form>
 </form>

+ 5 - 11
pg-view/ns/sshfp.php

@@ -1,14 +1,7 @@
-<p>
-	<?= linkToDocs('record-sshfp', 'Documentation du type d\'enregistrement SSHFP') ?>
-</p>
-
 <form method="post">
 <form method="post">
-
 <?php require 'form.ns.php'; ?>
 <?php require 'form.ns.php'; ?>
 
 
-	<br>
-
-	<label for="algo">Algorithme</label>
+	<label for="algo"><?= _('Algorithm') ?></label>
 	<br>
 	<br>
 	<select required="" name="algo" id="algo">
 	<select required="" name="algo" id="algo">
 		<option value="1">1 (RSA)</option>
 		<option value="1">1 (RSA)</option>
@@ -19,18 +12,19 @@
 
 
 	<br>
 	<br>
 
 
-	<label for="type">Type de hash</label>
+	<label for="type"><?= _('Hash type') ?></label>
 	<br>
 	<br>
 	<select required="" name="type" id="type">
 	<select required="" name="type" id="type">
 		<option value="1" disabled="">1 (SHA-1)</option>
 		<option value="1" disabled="">1 (SHA-1)</option>
 		<option value="2" selected="">2 (SHA-256)</option>
 		<option value="2" selected="">2 (SHA-256)</option>
 	</select>
 	</select>
+
 	<br>
 	<br>
 
 
-	<label for="fp">Empreinte</label>
+	<label for="fp"><?= _('Fingerprint') ?></label>
 	<br>
 	<br>
 	<input required="" id="fp" size="65" minlenght="64" maxlength="64" placeholder="26e6bbb4796c4fb78632e737d31a8acaba43c3a92d9c047031f04e9b70826e1d" name="fp" type="text">
 	<input required="" id="fp" size="65" minlenght="64" maxlength="64" placeholder="26e6bbb4796c4fb78632e737d31a8acaba43c3a92d9c047031f04e9b70826e1d" name="fp" type="text">
 
 
 	<br>
 	<br>
-	<input type="submit" value="Appliquer">
+	<input type="submit" value="<?= _('Apply') ?>">
 </form>
 </form>

+ 14 - 15
pg-view/ns/tlsa.php

@@ -1,13 +1,7 @@
-<p>
-	<?= linkToDocs('record-tlsa', 'Documentation du type d\'enregistrement TLSA') ?>
-</p>
-
 <form method="post">
 <form method="post">
-
 <?php require 'form.ns.php'; ?>
 <?php require 'form.ns.php'; ?>
 
 
-	<br>
-	<label for="use">Utilisation</label>
+	<label for="use"><?= _('Use') ?></label>
 	<br>
 	<br>
 	<select required="" name="use" id="use">
 	<select required="" name="use" id="use">
 		<option value="" selected="" disabled="">-</option>
 		<option value="" selected="" disabled="">-</option>
@@ -16,30 +10,35 @@
 		<option value="2">2 (DANE-TA, <abbr title="also known as">aka<abbr> Trust Anchor Assertion)</option>
 		<option value="2">2 (DANE-TA, <abbr title="also known as">aka<abbr> Trust Anchor Assertion)</option>
 		<option value="3">3 (DANE-EE, <abbr title="also known as">aka<abbr> Domain issued certificate)</option>
 		<option value="3">3 (DANE-EE, <abbr title="also known as">aka<abbr> Domain issued certificate)</option>
 	</select>
 	</select>
+
 	<br>
 	<br>
 
 
-	<label for="selector">Selecteur</label>
+	<label for="selector"><?= _('Selector') ?></label>
 	<br>
 	<br>
 	<select required="" name="selector" id="selector">
 	<select required="" name="selector" id="selector">
 		<option value="" selected="" disabled="">-</option>
 		<option value="" selected="" disabled="">-</option>
-		<option value="0">0 (le certificat entier doit correspondre)</option>
-		<option value="1">1 (la clé publique du certificat doit correspondre)</option>
+		<option value="0">0 (<?= _('the full certificate must match') ?>)</option>
+		<option value="1">1 (<?= _('the certificate public key must match') ?>)</option>
 	</select>
 	</select>
+
 	<br>
 	<br>
 
 
-	<label for="type">Type de correspondance</label>
+	<label for="type"><?= _('Match type') ?></label>
 	<br>
 	<br>
 	<select required="" name="type" id="type">
 	<select required="" name="type" id="type">
 		<option value="" selected="" disabled="">-</option>
 		<option value="" selected="" disabled="">-</option>
-		<option value="0">0 (certificat entier)</option>
+		<option value="0">0 (<?= _('full certificate') ?>)</option>
 		<option value="1">1 (SHA-256)</option>
 		<option value="1">1 (SHA-256)</option>
 		<option value="2">2 (SHA-512)</option>
 		<option value="2">2 (SHA-512)</option>
 	</select>
 	</select>
+
 	<br>
 	<br>
 
 
-	<label for="content">Contenu</label>
+	<label for="content"><?= _('Value') ?></label>
 	<br>
 	<br>
-	<input id="content" minlenght="3" maxlength="1024" pattern="^[a-zA-Z0-9.-]{3,1024}$" placeholder="gjioerjgioer" name="content" type="text">
+	<input id="content" minlenght="3" maxlength="1024" pattern="^[a-zA-Z0-9.-]{3,1024}$" name="content" type="text">
+
 	<br>
 	<br>
-	<input type="submit" value="Appliquer">
+
+	<input type="submit" value="<?= _('Apply') ?>">
 </form>
 </form>

+ 3 - 8
pg-view/ns/txt.php

@@ -1,13 +1,8 @@
-<p>
-	<?= linkToDocs('record-txt', 'Documentation du type d\'enregistrement TXT') ?>
-</p>
-
 <form method="post">
 <form method="post">
 <?php require 'form.ns.php'; ?>
 <?php require 'form.ns.php'; ?>
+	<label for="txt"><?= _('Text') ?></label>
 	<br>
 	<br>
-	<label for="txt">Texte</label>
+	<input id="txt" minlenght="5" maxlength="8192" pattern="^[a-zA-Z0-9 .@=:!%$+/\()[\]_-]{5,8192}$" placeholder="<?= _('Some text…') ?>" name="txt" type="text">
 	<br>
 	<br>
-	<input id="txt" minlenght="5" maxlength="8192" pattern="^[a-zA-Z0-9 .@=:!%$+/\()[\]_-]{5,8192}$" placeholder="Du texte..." name="txt" type="text">
-	<br>
-	<input type="submit" value="Appliquer">
+	<input type="submit" value="<?= _('Apply') ?>">
 </form>
 </form>

+ 3 - 13
pg-view/ns/zone-add.php

@@ -1,19 +1,9 @@
 <p>
 <p>
-	Pour prouver que vous possédez bien ce domaine, il doit posséder un <?= linkToDocs('ns-record', 'enregistrement NS') ?> égal à <code><?= getAuthToken() ?>._domain-verification.<?= SERVER_NAME ?>.</code> lors du traitement de ce formulaire.
-</p>
-
-<p>
-	La zone sera servie par ces serveurs de noms&nbsp;:
-	<ul>
-<?php
-foreach (CONF['ns']['servers'] as $server)
-	echo '	<li><code>' . $server . '</code></li>';
-?>
-	</ul>
+	<?= sprintf(_('To prove that you own this domain, it must have a NS record equal to %s when the form is being processed.'), '<code>' . getAuthToken() . '._domain-verification.' . SERVER_NAME . '.</code>') ?>
 </p>
 </p>
 
 
 <form method="post">
 <form method="post">
-	<label for="domain">Domaine</label><br>
+	<label for="domain"><?= _('Domain') ?></label><br>
 	<input required="" placeholder="domain.<?= PLACEHOLDER_DOMAIN ?>." id="domain" name="domain" type="text"><br>
 	<input required="" placeholder="domain.<?= PLACEHOLDER_DOMAIN ?>." id="domain" name="domain" type="text"><br>
-	<input value="Ajouter" type="submit">
+	<input type="submit" value="<?= _('Add') ?>">
 </form>
 </form>

+ 2 - 2
pg-view/ns/zone-del.php

@@ -1,5 +1,5 @@
 <form method="post">
 <form method="post">
-	<label for="zone">Zone</label>
+	<label for="zone"><?= _('Zone') ?></label>
 	<select required="" name="zone" id="zone">
 	<select required="" name="zone" id="zone">
 		<option value="" disabled="" selected="">-</option>
 		<option value="" disabled="" selected="">-</option>
 <?php
 <?php
@@ -8,5 +8,5 @@ foreach (nsListUserZones() as $zone)
 ?>
 ?>
 	</select>
 	</select>
 	<br>
 	<br>
-	<input type="submit" value="Supprimer toutes les données liées à cette zone">
+	<input type="submit" value="<?= _('Delete everything related to this zone') ?>">
 </form>
 </form>

+ 11 - 15
pg-view/reg/ds.php

@@ -1,15 +1,11 @@
-<p>
-	Ici vous pouvez indiquer au registre l'enregistrement DS d'une zone afin de permettre de déléguer la confiance <?= linkToDocs('dnssec', 'DNSSEC') ?>.
-</p>
-
 <form method="post">
 <form method="post">
-	<label for="action">Action</label>
+	<label for="action"><?= _('Action') ?></label>
 	<select name="action" id="action">
 	<select name="action" id="action">
-		<option value="add">Ajouter</option>
-		<option value="delete">Retirer</option>
+		<option value="add"><?= _('Add') ?></option>
+		<option value="delete"><?= _('Delete') ?></option>
 	</select>
 	</select>
 	<br>
 	<br>
-	<label for="zone">Domaine</label>
+	<label for="zone"><?= _('Domain') ?></label>
 	<br>
 	<br>
 	<select required="" name="zone" id="zone">
 	<select required="" name="zone" id="zone">
 		<option value="" disabled="" selected="">---</option>
 		<option value="" disabled="" selected="">---</option>
@@ -19,14 +15,14 @@ foreach (regListUserDomains() as $domain)
 ?>
 ?>
 	</select>
 	</select>
 	<br>
 	<br>
-	<label for="keytag">Tag de la clé</label>
+	<label for="keytag"><?= _('Key tag') ?></label>
 	<br>
 	<br>
 	<input required="" id="keytag" placeholder="32768" min="1" max="65535" name="keytag" type="number"><span></span>
 	<input required="" id="keytag" placeholder="32768" min="1" max="65535" name="keytag" type="number"><span></span>
 	<br>
 	<br>
-	<label for="algo">Algorithme</label>
+	<label for="algo"><?= _('Algorithm') ?></label>
 	<br>
 	<br>
 	<select required="" name="algo" id="algo">
 	<select required="" name="algo" id="algo">
-		<!-- RFC 8624 : Algorithm Implementation Requirements and Usage Guidance for DNSSEC > Algorithm Selection > DNSKEY Algorithms -->
+		<!-- RFC 8624: Algorithm Implementation Requirements and Usage Guidance for DNSSEC > Algorithm Selection > DNSKEY Algorithms -->
 		<!-- https://tools.ietf.org/html/rfc8624.html#section-3.1 -->
 		<!-- https://tools.ietf.org/html/rfc8624.html#section-3.1 -->
 		<option value="1" disabled="">1 (RSAMD5)</option>
 		<option value="1" disabled="">1 (RSAMD5)</option>
 		<option value="3" disabled="">3 (DSA)</option>
 		<option value="3" disabled="">3 (DSA)</option>
@@ -42,10 +38,10 @@ foreach (regListUserDomains() as $domain)
 		<option value="16">16 (ED448)</option>
 		<option value="16">16 (ED448)</option>
 	</select>
 	</select>
 	<br>
 	<br>
-	<label for="dt">Type de condensat</label>
+	<label for="dt"><?= _('Digest type') ?></label>
 	<br>
 	<br>
 	<select required="" name="dt" id="dt">
 	<select required="" name="dt" id="dt">
-		<!-- RFC 8624 : Algorithm Implementation Requirements and Usage Guidance for DNSSEC > Algorithm Selection > DS and CDS Algorithms -->
+		<!-- RFC 8624: Algorithm Implementation Requirements and Usage Guidance for DNSSEC > Algorithm Selection > DS and CDS Algorithms -->
 		<!-- https://tools.ietf.org/html/rfc8624.html#section-3.3 -->
 		<!-- https://tools.ietf.org/html/rfc8624.html#section-3.3 -->
 		<option value="1" disabled="">1 (SHA-1)</option>
 		<option value="1" disabled="">1 (SHA-1)</option>
 		<option value="2" selected="">2 (SHA-256)</option>
 		<option value="2" selected="">2 (SHA-256)</option>
@@ -53,9 +49,9 @@ foreach (regListUserDomains() as $domain)
 		<option value="4">4 (SHA-384)</option>
 		<option value="4">4 (SHA-384)</option>
 	</select>
 	</select>
 	<br>
 	<br>
-	<label for="key">Condensat</label>
+	<label for="key"><?= _('Key') ?></label>
 	<br>
 	<br>
 	<input id="key" required="" name="key" type="text" placeholder="018F25E4A022463478C9E30136EC53771A1704A0F0B3CE5B883AC9C8A6A55D16B638B4DE70662ACA5295D3669E7CADD9">
 	<input id="key" required="" name="key" type="text" placeholder="018F25E4A022463478C9E30136EC53771A1704A0F0B3CE5B883AC9C8A6A55D16B638B4DE70662ACA5295D3669E7CADD9">
 	<br>
 	<br>
-	<input type="submit" value="Appliquer">
+	<input type="submit" value="<?= _('Apply') ?>">
 </form>
 </form>

+ 11 - 15
pg-view/reg/glue.php

@@ -1,22 +1,18 @@
-<p>
-	<?= linkToDocs('glue-record', 'Documentation sur le glue record'); ?>
-</p>
-
 <form method="post">
 <form method="post">
-	<label for="action">Action</label>
+	<label for="action"><?= _('Action') ?></label>
 	<select name="action" id="action">
 	<select name="action" id="action">
-		<option value="add">Ajouter</option>
-		<option value="delete">Retirer</option>
+		<option value="add"><?= _('Add') ?></option>
+		<option value="delete"><?= _('Delete') ?></option>
 	</select>
 	</select>
 	<fieldset>
 	<fieldset>
-		<legend>Domaine</legend>
-		<div class="elForm">
-			<label for="subdomain">Sous-domaine</label>
+		<legend><?= _('Domain') ?></legend>
+		<div>
+			<label for="subdomain"><?= _('Subdomain') ?></label>
 			<br>
 			<br>
 			<input required="" id="subdomain" placeholder="ns1" name="subdomain" type="text">
 			<input required="" id="subdomain" placeholder="ns1" name="subdomain" type="text">
 		</div>
 		</div>
-		<div class="elForm">
-			<label for="suffix">Domaine</label>
+		<div>
+			<label for="suffix"><?= _('Domain') ?></label>
 			<br>
 			<br>
 			<select required="" name="suffix" id="suffix">
 			<select required="" name="suffix" id="suffix">
 				<option value="" disabled="" selected="">---</option>
 				<option value="" disabled="" selected="">---</option>
@@ -27,8 +23,8 @@ foreach(regListUserDomains() as $suffix)
 			</select>
 			</select>
 		</div>
 		</div>
 	</fieldset>
 	</fieldset>
-	<label for="ip">IP</label><br>
-	<input required="" pattern="^[a-f0-9:.]+$" id="ip" name="ip" minlength="2" maxlength="39" size="40" type="text" placeholder="<?= PLACEHOLDER_IPV4 ?> ou <?= PLACEHOLDER_IPV6 ?>">
+	<label for="ip"><?= _('IP address') ?></label><br>
+	<input required="" pattern="^[a-f0-9:.]+$" id="ip" name="ip" minlength="2" maxlength="39" size="40" type="text" placeholder="<?= sprintf(_('%1$s or %2$s'), PLACEHOLDER_IPV6, PLACEHOLDER_IPV4) ?>">
 	<br>
 	<br>
-	<input type="submit" value="Appliquer">
+	<input type="submit" value="<?= _('Apply') ?>">
 </form>
 </form>

+ 3 - 3
pg-view/reg/index.php

@@ -1,16 +1,16 @@
 <p>
 <p>
-	Ce <?= linkToDocs('registry', 'registre') ?> permet d'obtenir un domaine se terminant par <code><?= CONF['reg']['registry'] ?></code>, par exemple <code><em>domaine</em>.<?= CONF['reg']['registry'] ?></code>.
+	<?= sprintf(_('This domain name registry allows to register domains ending with <code>%1$s</code>, for instance <code><em>domain</em>%1$s</code>.'), '.' . CONF['reg']['registry']) ?>
 </p>
 </p>
 
 
 <?php displayIndex(); ?>
 <?php displayIndex(); ?>
 
 
-<h2>Domaines actuellement enregistrés</h2>
+<h2><?= _('Currently registered domains') ?></h2>
 
 
 <?php
 <?php
 
 
 $domains = query('select', 'registry', ['username' => $_SESSION['id'] ?? ''], 'domain');
 $domains = query('select', 'registry', ['username' => $_SESSION['id'] ?? ''], 'domain');
 if ($domains === [])
 if ($domains === [])
-	echo '<p>Ce compte n\'a aucun domaine enregistré sur <code>' . CONF['reg']['registry'] . '</code><p>' . LF;
+	echo '<p>∅</p>' . LF;
 else {
 else {
 	echo '<ul>' . LF;
 	echo '<ul>' . LF;
 	foreach ($domains as $domain)
 	foreach ($domains as $domain)

+ 6 - 10
pg-view/reg/ns.php

@@ -1,15 +1,11 @@
-<p>
-	<?= linkToDocs('record-ns', 'Documentation du type d\'enregistrement NS') ?>
-</p>
-
 <form method="post">
 <form method="post">
-	<label for="action">Action</label>
+	<label for="action"><?= _('Action') ?></label>
 	<select name="action" id="action">
 	<select name="action" id="action">
-		<option value="add">Ajouter</option>
-		<option value="delete">Retirer</option>
+		<option value="add"><?= _('Add') ?></option>
+		<option value="delete"><?= _('Delete') ?></option>
 	</select>
 	</select>
 	<br>
 	<br>
-	<label for="domain">Domaine</label>
+	<label for="domain"><?= _('Domain') ?></label>
 	<br>
 	<br>
 	<select required="" name="domain" id="domain">
 	<select required="" name="domain" id="domain">
 		<option value="" disabled="" selected="">---</option>
 		<option value="" disabled="" selected="">---</option>
@@ -19,9 +15,9 @@ foreach (regListUserDomains() as $domain)
 ?>
 ?>
 	</select>
 	</select>
 	<br>
 	<br>
-	<label for="ns">Serveur de nom</label>
+	<label for="ns"><?= _('Name server') ?></label>
 	<br>
 	<br>
 	<input id="ns" placeholder="ns1.<?= PLACEHOLDER_DOMAIN ?>." name="ns" type="text">
 	<input id="ns" placeholder="ns1.<?= PLACEHOLDER_DOMAIN ?>." name="ns" type="text">
 	<br>
 	<br>
-	<input type="submit" value="Appliquer">
+	<input type="submit" value="<?= _('Apply') ?>">
 </form>
 </form>

+ 6 - 6
pg-view/reg/print.php

@@ -1,5 +1,5 @@
 <form method="post">
 <form method="post">
-	<label for="domain">Domaine</label>
+	<label for="domain"><?= _('Domain') ?></label>
 	<select required="" name="domain" id="domain">
 	<select required="" name="domain" id="domain">
 		<option value="" disabled="" selected="">-</option>
 		<option value="" disabled="" selected="">-</option>
 <?php
 <?php
@@ -8,15 +8,15 @@ foreach (regListUserDomains() as $domain)
 ?>
 ?>
 	</select>
 	</select>
 	<br>
 	<br>
-	<input type="submit" value="Afficher">
+	<input type="submit" value="<?= _('Display') ?>">
 </form>
 </form>
 
 
 <table>
 <table>
 	<tr>
 	<tr>
-		<th>Domaine</th>
-		<th>TTL</th>
-		<th>Type</th>
-		<th>Contenu</th>
+		<th><?= _('Domain') ?></th>
+		<th><?= _('TTL') ?></th>
+		<th><?= _('Type') ?></th>
+		<th><?= _('Value') ?></th>
 	</tr>
 	</tr>
 
 
 <?php
 <?php

+ 3 - 3
pg-view/reg/register.php

@@ -1,11 +1,11 @@
 <p>
 <p>
-	Enregistrer un nouveau domaine sur son compte. Ce domaine doit être composé uniquement d'au moins 4 lettres latines non accentuées (a-z).
+	<?= _('Register a new domain on your account. It must consist of between 4 and 63 letters and digits.') ?>
 </p>
 </p>
 
 
 <form method="post">
 <form method="post">
-	<label for="subdomain">Sous-domaine</label>
+	<label for="subdomain"><?= _('Subdomain') ?></label>
 	<br>
 	<br>
 	<code><input id="subdomain" pattern="<?= SUBDOMAIN_REGEX ?>" required="" placeholder="niver" name="subdomain" type="text">.<?= CONF['reg']['registry'] ?></code>
 	<code><input id="subdomain" pattern="<?= SUBDOMAIN_REGEX ?>" required="" placeholder="niver" name="subdomain" type="text">.<?= CONF['reg']['registry'] ?></code>
 	<br>
 	<br>
-	<input type="submit" value="Enregistrer">
+	<input type="submit" value="<?= _('Register') ?>">
 </form>
 </form>

+ 0 - 242
pg-view/reg/reserved.txt

@@ -1,242 +0,0 @@
-# List of subdomains not available to register
-#
-# They may be forbidden because:
-# - they may be privileged for impersonating Niver, spamming or fishing
-# - they are reserved for a project asking for it and deserving such a well-known name
-
-niver
-
-# Registry-related
-nic
-domain
-domains
-reg
-registry
-
-# Special subdomains
-autoconfig
-autodiscover
-
-# Special TLDs
-example
-invalid
-test
-local
-localhost
-onion
-
-# Standard-related
-ns0
-ns1
-ns2
-ns3
-ns4
-ns5
-ns6
-ns7
-ns8
-ns9
-dns
-dns0
-dns1
-dns2
-dns3
-dns4
-dns5
-dns6
-dns7
-dns8
-dns9
-www
-wwww
-www0
-www1
-www2
-www3
-www4
-www5
-www6
-www7
-www8
-www9
-srv
-srv0
-srv1
-srv2
-srv3
-srv4
-srv5
-srv6
-srv7
-srv8
-srv9
-ssh
-sftp
-http
-https
-ssl
-tls
-mtx
-matrix
-gmi
-gemini
-ftp
-ftps
-mx
-imap
-imaps
-smtp
-smtps
-pop
-xmpp
-fedi
-html
-rss
-ipv4
-ipv6
-
-# Prevent account fishing
-account
-accounts
-register
-profile
-signup
-login
-auth
-authenticate
-connect
-
-# Commercial
-com
-free
-trial
-ads
-bank
-banks
-business
-customer
-customers
-store
-stores
-shop
-shops
-job
-jobs
-marketing
-sales
-
-# Miscellaneous
-org
-net
-com
-gov
-gouv
-edu
-api
-cdn
-support
-admin
-web
-dev
-host
-portal
-beta
-alpha
-demo
-vpn
-temp
-root
-data
-stats
-chat
-about
-remote
-portal
-boost
-core
-learn
-community
-meta
-news
-public
-online
-join
-mobile
-tech
-space
-zone
-name
-access
-search
-static
-secure
-security
-bbs
-help
-info
-code
-doc
-docs
-server
-servers
-client
-clients
-mail
-mails
-email
-emails
-webmail
-site
-sites
-website
-websites
-blog
-blogs
-gemlog
-gemlogs
-capsule
-capsules
-source
-sources
-update
-updates
-forum
-forums
-service
-services
-ressource
-ressources
-image
-images
-video
-videos
-radio
-radios
-music
-map
-maps
-app
-apps
-dev
-devs
-developer
-developers
-social
-cloud
-clouds
-network
-networks
-survey
-surveys
-build
-builds
-upload
-uploads
-download
-downloads
-content
-contents
-drive
-drives
-home
-homes

+ 4 - 4
pg-view/reg/transfer.php

@@ -1,11 +1,11 @@
 <p>
 <p>
-	Pour prouver que vous êtes autorisé à recevoir le domaine par san possessaire actuele, ledit domaine doit posséder un <?= linkToDocs('ns-record', 'enregistrement NS') ?> égal à <code><?= getAuthToken() ?>._transfer-verification.<?= SERVER_NAME ?>.</code> lors du traitement de ce formulaire. Cet enregistrement sera automatiquement retiré une fois validé.
+	<?= sprintf(_('To prove that you are allowed to receive the domain by its current owner, the domain must have an NS record equal to %s when the form is being processed. The NS record will be automatically deleted once validated.'), '<code>' . getAuthToken() . '._transfer-verification.' . SERVER_NAME '.</code>') ?>
 </p>
 </p>
 
 
 <form method="post">
 <form method="post">
-	<label for="subdomain">Sous-domaine à recevoir</label>
+	<label for="subdomain"><?= _('Subdomain that will be transferred to this account') ?></label>
 	<br>
 	<br>
-	<code><input required="" placeholder="subdomain" id="subdomain" name="subdomain" type="text">.<?= CONF['reg']['registry'] ?></code>
+	<code><input required="" pattern="<?= SUBDOMAIN_REGEX ?>" placeholder="subdomain" id="subdomain" name="subdomain" type="text">.<?= CONF['reg']['registry'] ?></code>
 	<br>
 	<br>
-	<input type="submit" value="Recevoir ce domaine">
+	<input type="submit" value="<?= _('Receive the domain') ?>">
 </form>
 </form>

+ 3 - 3
pg-view/reg/unregister.php

@@ -1,9 +1,9 @@
 <p>
 <p>
-	Ceci désenregistrera le domaine, et le rendra ainsi à nouveau disponible à l'enregistrement par n'importe qui.
+	<?= _('This will unregister the domain, making it registerable by anyone again.') ?>
 </p>
 </p>
 
 
 <form method="post">
 <form method="post">
-	<label for="domain">Domaine</label>
+	<label for="domain"><?= _('Domain') ?></label>
 	<br>
 	<br>
 	<select required="" name="domain" id="domain">
 	<select required="" name="domain" id="domain">
 		<option value="" disabled="" selected="">---</option>
 		<option value="" disabled="" selected="">---</option>
@@ -13,5 +13,5 @@ foreach(regListUserDomains() as $domain)
 ?>
 ?>
 	</select>
 	</select>
 	<br>
 	<br>
-	<input type="submit" value="Effacer et redisponibiliser au public">
+	<input type="submit" value="<?= _('Unregister') ?>">
 </form>
 </form>

+ 22 - 5
router.php

@@ -3,9 +3,21 @@ define('CONF', parse_ini_file(__DIR__ . '/config.ini', true, INI_SCANNER_TYPED))
 
 
 define('DB', new PDO('sqlite:' . CONF['common']['root_path'] . '/db/niver.db'));
 define('DB', new PDO('sqlite:' . CONF['common']['root_path'] . '/db/niver.db'));
 
 
-foreach (array_diff(scandir(CONF['common']['root_path'] . '/fn'), array('..', '.')) as $file)
-	require CONF['common']['root_path'] . '/fn/' . $file;
-require 'pages.php';
+$locale = 'en';
+if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
+	$client_locales = explode(',', preg_replace('/[A-Z0-9]|q=|;|-|\./', '', $_SERVER['HTTP_ACCEPT_LANGUAGE']));
+	$available_locales = array_diff(scandir('locales'), ['..', '.']);
+	foreach ($client_locales as $client_locale) {
+		if (in_array($client_locale, $available_locales)) {
+			$locale = $client_locale;
+			break;
+		}
+	}
+}
+define('LOCALE', $locale);
+setlocale(LC_MESSAGES, 'C.UTF-8');
+bindtextdomain('messages', 'locales/' . LOCALE);
+header('Content-Language: ' . LOCALE);
 
 
 const LF = "\n";
 const LF = "\n";
 
 
@@ -13,6 +25,11 @@ const PLACEHOLDER_DOMAIN = 'example'; // From RFC2606: Reserved Top Level DNS Na
 const PLACEHOLDER_IPV6 = '2001:db8::3'; // From RFC3849: IPv6 Address Prefix Reserved for Documentation
 const PLACEHOLDER_IPV6 = '2001:db8::3'; // From RFC3849: IPv6 Address Prefix Reserved for Documentation
 const PLACEHOLDER_IPV4 = '203.0.113.42'; // From RFC5737: IPv4 Address Blocks Reserved for Documentation
 const PLACEHOLDER_IPV4 = '203.0.113.42'; // From RFC5737: IPv4 Address Blocks Reserved for Documentation
 
 
+foreach (array_diff(scandir(CONF['common']['root_path'] . '/fn'), array('..', '.')) as $file)
+	require CONF['common']['root_path'] . '/fn/' . $file;
+
+require 'pages.php';
+
 if ($_SERVER['REQUEST_URI'] === '/sftpgo-auth.php')
 if ($_SERVER['REQUEST_URI'] === '/sftpgo-auth.php')
 	return;
 	return;
 
 
@@ -100,9 +117,9 @@ function displayFinalMessage($data) {
 if ($_POST !== []) {
 if ($_POST !== []) {
 	if (PAGE_METADATA['require-login'] ?? true !== false) {
 	if (PAGE_METADATA['require-login'] ?? true !== false) {
 		if (isset($_SESSION['id']) !== true)
 		if (isset($_SESSION['id']) !== true)
-			output(403, 'Vous devez être connecté·e à un compte pour effectuer cette action.');
+			output(403, _('You need to be logged in to do this.'));
 		if (isset(query('select', 'users', ['id' => $_SESSION['id']], 'id')[0]) !== true)
 		if (isset(query('select', 'users', ['id' => $_SESSION['id']], 'id')[0]) !== true)
-			output(403, 'Ce compte n\'existe plus. Déconnectez-vous pour terminer cette session fantôme.');
+			output(403, _('This account doesn\'t exist anymore. Log out to end this ghost session.'));
 	}
 	}
 	if (file_exists('pg-act/' . PAGE_ADDRESS . '.php'))
 	if (file_exists('pg-act/' . PAGE_ADDRESS . '.php'))
 		require 'pg-act/' . PAGE_ADDRESS . '.php';
 		require 'pg-act/' . PAGE_ADDRESS . '.php';

+ 5 - 6
view.php

@@ -1,5 +1,5 @@
 <!DOCTYPE html>
 <!DOCTYPE html>
-<html lang="fr"<?php if (!empty(SERVICE)) echo ' class="' . SERVICE . '"'; ?>>
+<html lang="<?= LOCALE ?>"<?php if (!empty(SERVICE)) echo ' class="' . SERVICE . '"'; ?>>
 	<head>
 	<head>
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<title><?php
 		<title><?php
@@ -16,10 +16,9 @@
 		<header>
 		<header>
 			<p>
 			<p>
 <?php if (isset($_SESSION['id'])) { ?>
 <?php if (isset($_SESSION['id'])) { ?>
-				<?= ($_SESSION['type'] === 'approved') ? '<span title="Compte approuvé">👤 </span>' : '<span title="Compte de test">⏳ </span>' ?><strong><?= (defined('DISPLAY_USERNAME')
-				? DISPLAY_USERNAME : '<em>?</em>') ?></strong> <a class="auth" href="<?= CONF['common']['prefix'] ?>/auth/logout">Se déconnecter</a>
+				<span aria-hidden="true"><?= ($_SESSION['type'] === 'approved') ? '👤' : '⏳' ?> </span><strong><?= (defined('DISPLAY_USERNAME') ? DISPLAY_USERNAME : '<em>?</em>') ?></strong> <a class="auth" href="<?= CONF['common']['prefix'] ?>/auth/logout"><?= _('Log out') ?></a>
 <?php } else { ?>
 <?php } else { ?>
-				<span aria-hidden="true">👻 </span><em>Anonyme</em> <a class="auth" href="<?= redirUrl('auth/login') ?>">Se connecter</a>
+				<span aria-hidden="true">👻 </span><em><?= _('Anonymous') ?></em> <a class="auth" href="<?= redirUrl('auth/login') ?>"><?= _('Log in') ?></a>
 <?php } ?>
 <?php } ?>
 			</p>
 			</p>
 			<nav>
 			<nav>
@@ -39,14 +38,14 @@
 	require 'pg-view/' . PAGE_ADDRESS . '.php';
 	require 'pg-view/' . PAGE_ADDRESS . '.php';
 
 
 	if ($_POST === [] AND PAGE_METADATA['require-login'] ?? true !== false AND !isset($_SESSION['id']) AND PAGE_TERMINAL)
 	if ($_POST === [] AND PAGE_METADATA['require-login'] ?? true !== false AND !isset($_SESSION['id']) AND PAGE_TERMINAL)
-		echo '<p>Ce formulaire ne sera pas accepté car il faut <a class="auth" href="' . redirUrl('auth/login') . '">se connecter</a> avant.</p>';
+		echo '<p>' . sprintf(_('This form won\'t be accepted because you need to %slog in%s first.'), '<a class="auth" href="' . redirUrl('auth/login') . '">', '</a>') . '</p>';
 
 
 	displayFinalMessage($data);
 	displayFinalMessage($data);
 
 
 ?>
 ?>
 		</main>
 		</main>
 		<footer>
 		<footer>
-			<small><a rel="external" href="https://code.antopie.org/niver/niver" class="niver">Code source</a> sous <abbr title="Cooperative Nonviolent Public License No Attribution version 7 ou plus">CNPL-NAv7+</abbr>.</small>
+			<small><?= sprintf(_('%sSource code%s available under %s.'), '<a rel="external" href="https://code.antopie.org/niver/niver" class="niver">', '</a>', '<abbr title="Cooperative Nonviolent Public License No Attribution version 7 or more">CNPL-NAv7+</abbr>') ?></small>
 		</footer>
 		</footer>
 	</body>
 	</body>
 </html>
 </html>