changeset 49:d3b943ac148f

Add translations Build script + {% trans %} in index.html
author mathieui
date Sat, 23 May 2020 20:33:38 +0200
parents 021185105e2f
children 78f3f79c911b
files build_website.py index.xhtml
diffstat 2 files changed, 138 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/build_website.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python3
+'''Locale build script for XAM'''
+
+import sys
+from os import makedirs, path
+from django.conf import settings
+from shutil import copytree, copy
+
+AVAILABLE_LANGUAGES = ['en', 'fr']
+
+
+def make_messages():
+    '''Extract translatable strings from the template.'''
+
+    from django.core.management.commands import makemessages
+
+    command = makemessages.Command()
+    command.stdout = sys.stdout
+    command.handle(
+        locale=AVAILABLE_LANGUAGES, exclude=[], domain='django', verbosity=True,
+        all=True, extensions=['xhtml', 'js'], symlinks=False, ignore_patterns=[],
+        use_default_ignore_patterns=True, no_wrap=True, no_location=True,
+        no_obsolete=True, keep_pot=True, add_location=False
+    )
+
+
+def compile_messages():
+    '''For each locale we support, compile the po file into a mo.'''
+
+    from django.core.management.commands import compilemessages
+
+    command = compilemessages.Command()
+    command.verbosity = 1
+    command.stdout = sys.stdout
+    command.compile_messages(('locale/%s/LC_MESSAGES' % lang, 'django.po')
+                             for lang in AVAILABLE_LANGUAGES)
+
+
+def main():
+    '''Call everything in the correct order.'''
+
+    from subprocess import call
+
+    settings.configure()
+    make_messages()
+    compile_messages()
+
+    for language in AVAILABLE_LANGUAGES:
+        call([sys.argv[0], language])
+
+
+def generate_pages(language):
+    '''Write a single page, and gzip it for lower network usage.'''
+
+    assert language in AVAILABLE_LANGUAGES
+    target_dir = path.join('.', 'build', language)
+    makedirs(target_dir, exist_ok=True)
+
+    import django
+    from django.template import Template, Context
+    import gzip
+
+    settings.configure(LANGUAGE_CODE=language, LOCALE_PATHS=['locale'], TEMPLATES=[{'BACKEND': 'django.template.backends.django.DjangoTemplates'}])
+
+    django.setup()
+
+    static = ['share', 'prosody.css', 'prosody.svg', 'spinner.svg', 'ok.svg', 'error.svg']
+    files = [
+        'index.xhtml', 'client.js', 'roster.js', 'avatar.js', 'client.js', 'index.xhtml',
+        'mam.js', 'nickname.js', 'pep.js', 'roster.js', 'strophe.js', 'strophe.mam.js',
+        'strophe.rsm.js', 'util.js', 'vcard.js'
+    ]
+    for file_to_localize in files:
+        with open(file_to_localize) as template_file:
+            template = Template(template_file.read())
+        rendered = template.render(Context({'AVAILABLE_LANGUAGES':
+                                            AVAILABLE_LANGUAGES}))
+        filename = path.join(target_dir, file_to_localize)
+        with open(filename, 'w') as out:
+            out.write(rendered)
+    for static_resource in static:
+        if path.isdir(static_resource):
+            copytree(static_resource, target_dir, dirs_exist_ok=True)
+        else:
+            copy(static_resource, target_dir)
+
+if __name__ == '__main__':
+    if len(sys.argv) == 1:
+        main()
+    else:
+        generate_pages(sys.argv[1])
--- a/index.xhtml
+++ b/index.xhtml
@@ -1,9 +1,9 @@
 <?xml version="1.0"?>
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="{% load i18n %}en">
 <head>
   <meta charset="utf-8"/>
   <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"/>
-  <title>Prosody IM account configuration</title>
+  <title>{% trans 'Prosody IM account configuration' %}</title>
   <link rel="canonical" content-type="text/html" href="https://prosody.im/index"/>
   <link rel="icon" href="prosody.svg"/>
   <link rel="apple-touch-icon" href="prosody.svg"/>
@@ -16,8 +16,8 @@
 
 <div class="row">
 <form id="connection">
-<input type="email" id="jid" placeholder="JID" title="Enter your JID (or XMPP address), on the form “you@your-server.tld”"/>
-<input type="password" id="pass" placeholder="Password" title="Enter the password used for this JID"/>
+<input type="email" id="jid" placeholder="JID" title="{% trans 'Enter your JID (or XMPP address), on the form “you@your-server.tld”' %}"/>
+<input type="password" id="pass" placeholder="Password" title="{% trans 'Enter the password used for this JID' %}"/>
 <input type="submit" id="connect" value="Log in"/>
 <img width="24" height="24" id="connect-spinner" hidden=""/>
 </form>
@@ -26,10 +26,10 @@
 <div id="connected" hidden="">
 
 <div id="navtabs" class="nav nav-tabs nav-justified">
-<li id="tab-profile" class="active"><a href="#profile">Profile</a></li>
-<li id="tab-mam"><a href="#mam">Message Archiving</a></li>
-<li id="tab-account"><a href="#account">Account</a></li>
-<li id="tab-pep"><a href="#pep">PEP (advanced)</a></li>
+<li id="tab-profile" class="active"><a href="#profile">{% trans 'Profile' %}</a></li>
+<li id="tab-mam"><a href="#mam">{% trans 'Message Archiving' %}</a></li>
+<li id="tab-account"><a href="#account">{% trans 'Account' %}</a></li>
+<li id="tab-pep"><a href="#pep">{% trans 'PEP (advanced)' %}</a></li>
 </div>
 
 <div class="row tab-profile">
@@ -38,16 +38,16 @@
 </div>
 <div class="col-sm-8">
 <p>
-<input class="form-control" id="nick" placeholder="Nickname"/>
+<input class="form-control" id="nick" placeholder="{% trans 'Nickname' %}"/>
 <img width="24" height="24" id="nick-spinner"/>
 </p>
-<p>Enter your nickname, so people you know can recognize you.</p>
+<p>{% trans 'Enter your nickname, so people you know can recognize you.' %}</p>
 <p class="form-group">
-<label for="nick-access">Who can see your nickname?</label>
+<label for="nick-access">{% trans 'Who can see your nickname?' %}</label>
 <img width="24" height="24" id="nick-access-spinner" hidden=""/>
 <select class="form-control" id="nick-access" disabled="">
-<option value="open">Anyone</option>
-<option value="presence">Only your contacts</option>
+<option value="open">{% trans 'Anyone' %}</option>
+<option value="presence">{% trans 'Only your contacts' %}</option>
 </select>
 </p>
 </div>
@@ -58,22 +58,22 @@
 <div class="row tab-profile">
 <div class="col-sm-4">
 <h2>Avatar</h2>
-<p>This image allows your contacts to quickly identify you.</p>
+<p>{% trans 'This image allows your contacts to quickly identify you.' %}</p>
 </div>
 <div class="col-sm-8">
 <img id="avatar" style="max-width:96px;max-height:96px"/> <span id="avatar-size"/> <img width="24" height="24" id="avatar-spinner"/><br/>
 <input type="file" style="display:none" accept="image/*" id="avatar-file"/>
 <p class="custom-file">
-<label class="custom-file-label" for="avatar-upload">Upload new avatar</label>
-<button id="avatar-upload">Choose file…</button>
-<button id="avatar-change">Use as your avatar</button>
+<label class="custom-file-label" for="avatar-upload">{% trans 'Upload new avatar' %}</label>
+<button id="avatar-upload">{% trans 'Choose file…' %}</button>
+<button id="avatar-change">{% trans 'Use as your avatar' %}</button>
 </p>
 <p class="form-group">
-<label for="avatar-access">Who can see your avatar?</label>
+<label for="avatar-access">{% trans 'Who can see your avatar?' %}</label>
 <img width="24" height="24" id="access-model-avatar-spinner" hidden=""/>
 <select class="form-control" id="avatar-access">
-<option value="open">Anyone (pick this if you use public groupchats)</option>
-<option value="presence">Only your contacts</option>
+<option value="open">{% trans 'Anyone (pick this if you use public groupchats)' %}</option>
+<option value="presence">{% trans 'Only your contacts' %}</option>
 </select>
 </p>
 </div>
@@ -83,30 +83,30 @@
 
 <div class="row tab-profile">
 <div class="col-sm-4">
-<h2>Personal Information</h2>
-<p>Who are you?</p>
+<h2>{% trans 'Personal Information' %}</h2>
+<p>{% trans 'Who are you?' %}</p>
 <img width="24" height="24" id="vcard-spinner" hidden=""/>
 </div>
 <div class="col-sm-8">
 <p>
-<label>Full name<br/>
+<label>{% trans 'Full name' %}<br/>
 <input id="vcard-fn" disabled=""/></label><br/>
-Enter your name, so people you know can recognize you.
+{% trans 'Enter your name, so people you know can recognize you.' %}
 </p>
 <p>
-<label>Email<br/>
+<label>{% trans 'Email' %}<br/>
 <input id="vcard-email" disabled=""/></label><br/>
-This can be used if you forget your password.
+{% trans 'This can be used if you forget your password.' %}
 </p>
 <p>
-<label>Birthday<br/>
+<label>{% trans 'Birthday' %}<br/>
 <input id="vcard-bday" type="date" disabled=""/></label>
 </p>
 <p>
-<label>Who can see your personal information?<br/>
+<label>{% trans 'Who can see your personal information?' %}<br/>
 <select id="vcard-access">
-<option value="open">Anyone</option>
-<option value="presence">Only your contacts</option>
+<option value="open">{% trans 'Anyone' %}</option>
+<option value="presence">{% trans 'Only your contacts' %}</option>
 </select></label> <img width="24" height="24" id="vcard-access-spinner" hidden=""/>
 </p>
 </div>
@@ -119,7 +119,7 @@ This can be used if you forget your pass
 <div class="col-sm-8">
 <table class="table">
 <thead>
-<tr><th>JID</th><th>Name</th><th>Subscription</th><th>Groups</th><th>⚠️ Delete</th></tr>
+    <tr><th>{% trans 'JID' %}</th><th>{% trans 'Name' %}</th><th>{% trans 'Subscription' %}</th><th>{% trans 'Groups' %}</th><th>{% trans '⚠️ Delete' %}</th></tr>
 </thead>
 <tbody id="roster-table"/>
 </table>
@@ -134,21 +134,21 @@ This can be used if you forget your pass
 </div>
 <div class="col-sm-8">
 <p>
-<button disabled="">Change my password</button>
-<button class="btn btn-danger" disabled="">⚠️ Delete my account</button>
+<button disabled="">{% trans 'Change my password' %}</button>
+<button class="btn btn-danger" disabled="">{% trans '⚠️ Delete my account' %}</button>
 </p>
 </div>
 </div>
 
 <div class="row tab-pep" hidden="">
 <div class="col-sm-4">
-<h2>PEP</h2>
+<h2>{% trans 'PEP' %}</h2>
 </div>
 <div class="col-sm-8">
-<div class="alert alert-warning">This section is for <b>advanced</b> users, use at your own risk!</div>
+    <div class="alert alert-warning">{% trans 'This section is for <b>advanced</b> users, use at your own risk!' %}</div>
 <table class="table">
 <thead>
-<tr><th>PEP node</th><th>Title</th><th>Description</th><th>Type</th><th>⚠️ Delete</th></tr>
+    <tr><th>{% trans 'PEP node' %}</th><th>{% trans 'Title' %}</th><th>{% trans 'Description' %}</th><th>{% trans 'Type' %}</th><th>{% trans '⚠️ Delete' %}</th></tr>
 </thead>
 <tbody id="pep-table"/>
 </table>
@@ -157,31 +157,31 @@ This can be used if you forget your pass
 
 <div class="row tab-mam" hidden="">
 <div class="col-sm-4">
-<h2>Message Archiving</h2>
+<h2>{% trans 'Message Archiving' %}</h2>
 </div>
 <div class="col-sm-8">
 <p>
-<label>Which messages to store in your archive?<br/>
+<label>{% trans 'Which messages to store in your archive?' %}<br/>
 <select id="mam-prefs-default" disabled="">
-<option value="always">All messages</option>
-<option value="never">No messages</option>
-<option value="roster">Messages from your contacts only</option>
+<option value="always">{% trans 'All messages' %}</option>
+<option value="never">{% trans 'No messages' %}</option>
+<option value="roster">{% trans 'Messages from your contacts only' %}</option>
 </select></label>
 <img width="24" height="24" id="mam-prefs-spinner" hidden=""/><br/>
 <table class="table" hidden="">
 <tr>
-<th>Always:</th>
-<th>Never:</th>
+<th>{% trans 'Always:' %}</th>
+<th>{% trans 'Never:' %}</th>
 </tr>
 <tr>
 <td><textarea id="mam-prefs-always"/></td>
 <td><textarea id="mam-prefs-never"/></td>
 </tr>
 </table>
-<button id="mam-retrieve">Retrieve my message archive</button> <img width="24" height="24" id="mam-retrieve-spinner" hidden=""/><br/>
-<button disabled="">View my message archive</button><br/>
-<button id="mam-download" disabled="">Download my entire message archive</button><br/>
-<button class="btn btn-danger" disabled="">⚠️ Purge my entire message archive</button>
+<button id="mam-retrieve">{% trans 'Retrieve my message archive' %}</button> <img width="24" height="24" id="mam-retrieve-spinner" hidden=""/><br/>
+<button disabled="">{% trans 'View my message archive' %}</button><br/>
+<button id="mam-download" disabled="">{% trans 'Download my entire message archive' %}</button><br/>
+<button class="btn btn-danger" disabled="">{% trans '⚠️ Purge my entire message archive' %}</button>
 </p>
 </div>
 </div>