Merge branch 'text-updates'

This commit is contained in:
James Valleroy 2016-01-25 19:06:49 -05:00
commit 863a187b23
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
36 changed files with 1208 additions and 798 deletions

View File

@ -13,9 +13,9 @@ personal servers running free software for private, personal
communications. It is a networking appliance designed to allow communications. It is a networking appliance designed to allow
interfacing with the rest of the Internet under conditions of interfacing with the rest of the Internet under conditions of
protected privacy and data security. It hosts applications such as protected privacy and data security. It hosts applications such as
blog, wiki, website, social network, email, web proxy and a Tor relay blog, wiki, website, social network, email, web proxy and a Tor relay,
on a device that can replace your Wi-Fi router so that your data stays on a device that can replace your Wi-Fi router, so that your data
with you. stays with you.
Plinth is a web interface to administer the functions of the Plinth is a web interface to administer the functions of the
FreedomBox. It is extensible and provides various applications of FreedomBox. It is extensible and provides various applications of

View File

@ -19,6 +19,7 @@
Django context processors to provide common data to templates. Django context processors to provide common data to templates.
""" """
from django.utils.translation import ugettext as _, ugettext_noop
import re import re
from plinth import cfg from plinth import cfg
@ -30,10 +31,15 @@ def common(request):
Any resources referenced in the return value are expected to have been Any resources referenced in the return value are expected to have been
initialized or configured externally beforehand. initialized or configured externally beforehand.
""" """
# Allow a value in configuration file to be translated. Allow
# the brand name 'FreedomBox' itself to be translated.
ugettext_noop('FreedomBox')
slash_indices = [match.start() for match in re.finditer('/', request.path)] slash_indices = [match.start() for match in re.finditer('/', request.path)]
active_menu_urls = [request.path[:index + 1] for index in slash_indices] active_menu_urls = [request.path[:index + 1] for index in slash_indices]
return { return {
'cfg': cfg, 'cfg': cfg,
'submenu': cfg.main_menu.active_item(request), 'submenu': cfg.main_menu.active_item(request),
'active_menu_urls': active_menu_urls 'active_menu_urls': active_menu_urls,
'box_name': _(cfg.box_name)
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,7 @@
<h2>{% trans "Services and Applications" %}</h2> <h2>{% trans "Services and Applications" %}</h2>
<p> <p>
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
You can install and run various services and applications on You can install and run various services and applications on
your {{ box_name }}. Click on any app page link on the left to your {{ box_name }}. Click on any app page link on the left to
read a description of the application and choose to install it. read a description of the application and choose to install it.

View File

@ -27,11 +27,11 @@
<p> <p>
{% blocktrans trimmed %} {% blocktrans trimmed %}
Service discovery allows other machines on the network to Service discovery allows other devices on the network to
discover your FreedomBox and services running on it. It also discover your {{ box_name }} and services running on it. It
allows FreedomBox to discover other machines and services also allows {{ box_name }} to discover other devices and
running on your local network. Service discovery is not services running on your local network. Service discovery is
essential and works only on internal networks. It may be not essential and works only on internal networks. It may be
disabled to improve security especially when connecting to a disabled to improve security especially when connecting to a
hostile local network. hostile local network.
{% endblocktrans %} {% endblocktrans %}

View File

@ -38,6 +38,7 @@ from plinth.modules.names import SERVICES
from plinth.signals import pre_hostname_change, post_hostname_change from plinth.signals import pre_hostname_change, post_hostname_change
from plinth.signals import domainname_change from plinth.signals import domainname_change
from plinth.signals import domain_added, domain_removed from plinth.signals import domain_added, domain_removed
from plinth.utils import format_lazy
HOSTNAME_REGEX = r'^[a-zA-Z0-9]([-a-zA-Z0-9]{,61}[a-zA-Z0-9])?$' HOSTNAME_REGEX = r'^[a-zA-Z0-9]([-a-zA-Z0-9]{,61}[a-zA-Z0-9])?$'
@ -92,12 +93,12 @@ class ConfigurationForm(forms.Form):
# https://tools.ietf.org/html/rfc2181#section-11 # https://tools.ietf.org/html/rfc2181#section-11
hostname = TrimmedCharField( hostname = TrimmedCharField(
label=ugettext_lazy('Hostname'), label=ugettext_lazy('Hostname'),
help_text=\ help_text=format_lazy(ugettext_lazy(
ugettext_lazy('Hostname is the local name by which other machines on ' 'Hostname is the local name by which other devices on the local '
'the local network reach your machine. It must start ' 'network can reach your {box_name}. It must start and end with '
'and end with an alphabet or a digit and have as ' 'an alphabet or a digit and have as interior characters only '
'interior characters only alphabets, digits and ' 'alphabets, digits and hyphens. Total length must be 63 '
'hyphens. Total length must be 63 characters or less.'), 'characters or less.'), box_name=ugettext_lazy(cfg.box_name)),
validators=[ validators=[
validators.RegexValidator( validators.RegexValidator(
HOSTNAME_REGEX, HOSTNAME_REGEX,
@ -105,14 +106,14 @@ class ConfigurationForm(forms.Form):
domainname = TrimmedCharField( domainname = TrimmedCharField(
label=ugettext_lazy('Domain Name'), label=ugettext_lazy('Domain Name'),
help_text=\ help_text=format_lazy(ugettext_lazy(
ugettext_lazy('Domain name is the global name by which other machines ' 'Domain name is the global name by which other devices on the '
'on the Internet can reach you. It must consist of ' 'Internet can reach your {box_name}. It must consist of labels '
'labels separated by dots. Each label must start and ' 'separated by dots. Each label must start and end with an '
'end with an alphabet or a digit and have as interior ' 'alphabet or a digit and have as interior characters only '
'characters only alphabets, digits and hyphens. Length ' 'alphabets, digits and hyphens. Length of each label must be 63 '
'of each label must be 63 characters or less. Total ' 'characters or less. Total length of domain name must be 253 '
'length of domain name must be 253 characters or less.'), 'characters or less.'), box_name=ugettext_lazy(cfg.box_name)),
required=False, required=False,
validators=[ validators=[
validators.RegexValidator( validators.RegexValidator(
@ -123,8 +124,7 @@ class ConfigurationForm(forms.Form):
language = forms.ChoiceField( language = forms.ChoiceField(
label=ugettext_lazy('Language'), label=ugettext_lazy('Language'),
help_text=\ help_text=\
ugettext_lazy('Language for this FreedomBox web administration ' ugettext_lazy('Language for this web administration interface'),
'interface'),
required=False, required=False,
choices=settings.LANGUAGES) choices=settings.LANGUAGES)

View File

@ -26,6 +26,7 @@ import logging
from plinth import actions from plinth import actions
from plinth import cfg from plinth import cfg
from plinth import package from plinth import package
from plinth.utils import format_lazy
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
EMPTYSTRING = 'none' EMPTYSTRING = 'none'
@ -78,9 +79,10 @@ class ConfigureForm(forms.Form):
help_server = \ help_server = \
ugettext_lazy('Please do not enter a URL here (like ' ugettext_lazy('Please do not enter a URL here (like '
'"https://example.com/") but only the hostname of the ' '"https://example.com/") but only the hostname of the '
'GnuDIP server (like "example.pcom").') 'GnuDIP server (like "example.com").')
help_domain = \ help_domain = format_lazy(
ugettext_lazy('The public domain name you want use to reach your box.') ugettext_lazy('The public domain name you want use to reach your '
'{box_name}.'), box_name=ugettext_lazy(cfg.box_name))
help_disable_ssl = \ help_disable_ssl = \
ugettext_lazy('Use this option if your provider uses self signed ' ugettext_lazy('Use this option if your provider uses self signed '
'certificates.') 'certificates.')
@ -90,13 +92,14 @@ class ConfigureForm(forms.Form):
help_secret = \ help_secret = \
ugettext_lazy('Leave this field empty if you want to keep your ' ugettext_lazy('Leave this field empty if you want to keep your '
'previous configured password.') 'previous configured password.')
help_ip_url = \ help_ip_url = format_lazy(
ugettext_lazy('Optional Value. If your FreedomBox is not connected ' ugettext_lazy('Optional Value. If your {box_name} is not connected '
'directly to the Internet (i.e. connected to a NAT ' 'directly to the Internet (i.e. connected to a NAT '
'router) this URL is used to figure out the real ' 'router) this URL is used to figure out the real '
'Internet IP. The URL should simply return the IP where' 'Internet IP. The URL should simply return the IP where '
'the client comes from. Example: ' 'the client comes from (example: '
'http://myip.datasystems24.de') 'http://myip.datasystems24.de).'),
box_name=ugettext_lazy(cfg.box_name))
help_user = \ help_user = \
ugettext_lazy('You should have been requested to select a username ' ugettext_lazy('You should have been requested to select a username '
'when you created the account.') 'when you created the account.')
@ -129,11 +132,11 @@ class ConfigureForm(forms.Form):
help_text=help_update_url) help_text=help_update_url)
disable_SSL_cert_check = forms.BooleanField( disable_SSL_cert_check = forms.BooleanField(
label=ugettext_lazy('accept all SSL certificates'), label=ugettext_lazy('Accept all SSL certificates'),
help_text=help_disable_ssl, required=False) help_text=help_disable_ssl, required=False)
use_http_basic_auth = forms.BooleanField( use_http_basic_auth = forms.BooleanField(
label=ugettext_lazy('use HTTP basic authentication'), label=ugettext_lazy('Use HTTP basic authentication'),
help_text=help_http_auth, required=False) help_text=help_http_auth, required=False)
dynamicdns_domain = TrimmedCharField( dynamicdns_domain = TrimmedCharField(
@ -151,7 +154,7 @@ class ConfigureForm(forms.Form):
label=ugettext_lazy('Password'), widget=forms.PasswordInput(), label=ugettext_lazy('Password'), widget=forms.PasswordInput(),
required=False, help_text=help_secret) required=False, help_text=help_secret)
showpw = forms.BooleanField(label=ugettext_lazy('show password'), showpw = forms.BooleanField(label=ugettext_lazy('Show password'),
required=False) required=False)
dynamicdns_ipurl = TrimmedCharField( dynamicdns_ipurl = TrimmedCharField(

View File

@ -22,14 +22,14 @@
{% block content %} {% block content %}
<h2>{% trans "DynamicDNS client" %}</h2> <h2>{% trans "Dynamic DNS Client" %}</h2>
<p> <p>
{% blocktrans trimmed %} {% blocktrans trimmed %}
If your internet provider changes your IP address periodic If your internet provider changes your IP address periodic
(i.e. every 24h) it may be hard for others to find you in the (i.e. every 24h) it may be hard for others to find you in the
WEB. And for this reason nobody may find the services which are WEB. And for this reason nobody may find the services which are
provided by FreedomBox (like your ownCloud). provided by {{ box_name }}, such as ownCloud.
{% endblocktrans %} {% endblocktrans %}
</p> </p>
@ -41,7 +41,7 @@
public IP address to an public IP address to an
<a href='http://gnudip2.sourceforge.net/' target='_blank'> gnudip </a> <a href='http://gnudip2.sourceforge.net/' target='_blank'> gnudip </a>
server. Afterwards the Server will assign your DNS name with the server. Afterwards the Server will assign your DNS name with the
new IP and if someone from the internet asks for your DNS name new IP and if someone from the Internet asks for your DNS name
he will get your current IP answered. he will get your current IP answered.
{% endblocktrans %} {% endblocktrans %}
</p> </p>
@ -59,9 +59,9 @@
<p> <p>
{% blocktrans trimmed %} {% blocktrans trimmed %}
If your freedombox is connected behind some NAT router, don't forget If your {{ box_name }} is connected behind some NAT router, don't forget
to add portforwarding (i.e. forward some standard ports like 80 and 443) to add port forwarding (i.e. forward some standard ports like 80 and
to your freedombox device. 443).
{% endblocktrans %} {% endblocktrans %}
</p> </p>
{% endblock %} {% endblock %}

View File

@ -32,14 +32,14 @@
{% endblocktrans %} {% endblocktrans %}
{% else %} {% else %}
{% if no_nat %} {% if no_nat %}
{% trans "Direct connection to the internet." %} {% trans "Direct connection to the Internet." %}
{% else %} {% else %}
{% blocktrans trimmed %} {% blocktrans trimmed %}
Behind NAT, this means that dynamic DNS service will poll Behind NAT. This means that Dynamic DNS service will poll
the "IP check URL" for changes (we need the "IP check URL" the "IP check URL" for changes (the "IP check URL" entry is
for this reason - otherwise we will not detect IP changes). needed for this - otherwise IP changes will not be
It may take up to {{ timer }} minutes until we update your detected). In case the WAN IP changes, it may take up to
DNS entry in case of WAN IP change. {{ timer }} minutes until your DNS entry is updated.
{% endblocktrans %} {% endblocktrans %}
{% endif %} {% endif %}
{% endif %} {% endif %}

View File

@ -25,20 +25,20 @@
<h2>{{ title }}</h2> <h2>{{ title }}</h2>
<p> <p>
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
Firewall is a network security system that controls the incoming Firewall is a security system that controls the incoming and
and outgoing network traffic on your {{ box_name }}. Keeping a outgoing network traffic on your {{ box_name }}. Keeping a
firewall enabled and properly configured reduces risk of firewall enabled and properly configured reduces risk of
security threat from the Internet. security threat from the Internet.
{% endblocktrans %} {% endblocktrans %}
</p> </p>
<p>{% trans "The following is the current status:" %}</p> <p>{% trans "Current status:" %}</p>
{% if firewall_status == 'not_running' %} {% if firewall_status == 'not_running' %}
<p> <p>
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
Firewall daemon is not running. Please run it. Firewall comes Firewall daemon is not running. Please run it. Firewall comes
enabled by default on {{ box_name }}. On any Debian based enabled by default on {{ box_name }}. On any Debian based
system (such as {{ box_name }}) you may run it using the system (such as {{ box_name }}) you may run it using the
@ -102,8 +102,8 @@
<em> <em>
{% blocktrans trimmed %} {% blocktrans trimmed %}
The operation of the firewall is automatic. When you enable The operation of the firewall is automatic. When you enable
a service it is automatically permitted in the firewall and a service it is also permitted in the firewall and when you
you disable a service is automatically disabled in the firewall. disable a service it is also disabled in the firewall.
{% endblocktrans %} {% endblocktrans %}
</em> </em>
</p> </p>

View File

@ -37,7 +37,7 @@
{% block content_row %} {% block content_row %}
<p class="text-center"> <p class="text-center">
<img src="{% static 'theme/img/FreedomBox-logo-standard.png' %}" <img src="{% static 'theme/img/FreedomBox-logo-standard.png' %}"
alt="{{ cfg.box_name }}" width="640"/> alt="{{ box_name }}" width="640"/>
</p> </p>
<p class="text-center"> <p class="text-center">
@ -46,7 +46,7 @@
</p> </p>
<p class="text-center" style="font-size: larger"> <p class="text-center" style="font-size: larger">
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
To complete the setup of your {{ box_name }}, please provide To complete the setup of your {{ box_name }}, please provide
some basic information. some basic information.
{% endblocktrans %} {% endblocktrans %}

View File

@ -29,10 +29,10 @@
<h2>{% trans "Setup Complete!" %}</h2> <h2>{% trans "Setup Complete!" %}</h2>
<p> <p>
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
{{ box_name }} setup is now complete. To make your {{ box_name }} {{ box_name }} setup is now complete. To make your {{ box_name }}
functional, you need some applications. Applications will be functional, you need some applications. They will be installed
installed the first time you access them. the first time you access them.
{% endblocktrans %} {% endblocktrans %}
</p> </p>

View File

@ -35,7 +35,7 @@ def init():
'glyphicon-book', 'help:index', 101) 'glyphicon-book', 'help:index', 101)
menu.add_urlname(ugettext_lazy('Where to Get Help'), 'glyphicon-search', menu.add_urlname(ugettext_lazy('Where to Get Help'), 'glyphicon-search',
'help:index_explicit', 5) 'help:index_explicit', 5)
menu.add_urlname(ugettext_lazy('FreedomBox Manual'), 'glyphicon-info-sign', menu.add_urlname(ugettext_lazy('Manual'), 'glyphicon-info-sign',
'help:manual', 10) 'help:manual', 10)
menu.add_urlname(ugettext_lazy('About'), 'glyphicon-star', 'help:about', menu.add_urlname(ugettext_lazy('About'), 'glyphicon-star', 'help:about',
100) 100)
@ -52,7 +52,7 @@ def index(request):
def about(request): def about(request):
"""Serve the about page""" """Serve the about page"""
context = { context = {
'title': _('About {box_name}').format(box_name=cfg.box_name), 'title': _('About {box_name}').format(box_name=_(cfg.box_name)),
'version': __version__ 'version': __version__
} }
return TemplateResponse(request, 'help_about.html', context) return TemplateResponse(request, 'help_about.html', context)
@ -68,6 +68,7 @@ def manual(request):
except IOError: except IOError:
raise Http404 raise Http404
return TemplateResponse(request, 'help_manual.html', return TemplateResponse(
{'title': _('FreedomBox Manual'), request, 'help_manual.html',
'content': content}) {'title': _('{box_name} Manual').format(box_name=_(cfg.box_name)),
'content': content})

View File

@ -28,14 +28,14 @@
<p> <p>
{% blocktrans trimmed %} {% blocktrans trimmed %}
FreedomBox is a community project to develop, design and promote {{ box_name }} is a community project to develop, design and
personal servers running free software for private, personal promote personal servers running free software for private,
communications. It is a networking appliance designed to allow personal communications. It is a networking appliance designed
interfacing with the rest of the Internet under conditions of to allow interfacing with the rest of the Internet under
protected privacy and data security. It hosts applications such conditions of protected privacy and data security. It hosts
as blog, wiki, website, social network, email, web proxy and a applications such as blog, wiki, website, social network, email,
Tor relay on a device that can replace your Wi-Fi router so that web proxy and a Tor relay, on a device that can replace your
your data stays with you. Wi-Fi router, so that your data stays with you.
{% endblocktrans %} {% endblocktrans %}
</p> </p>
@ -55,15 +55,16 @@
<p> <p>
{% blocktrans trimmed %} {% blocktrans trimmed %}
There are a number of projects working to realize a future of There are a number of projects working to realize a future of
distributed services; FreedomBox aims to bring them all together distributed services; {{ box_name }} aims to bring them all
in a convenient package. together in a convenient package.
{% endblocktrans %} {% endblocktrans %}
</p> </p>
<p> <p>
{% blocktrans trimmed %} {% blocktrans trimmed %}
For more information about the FreedomBox project, see the For more information about the {{ box_name }} project, see the
<a href="https://wiki.debian.org/FreedomBox">FreedomBox Wiki</a>. <a href="https://wiki.debian.org/FreedomBox">{{ box_name }}
Wiki</a>.
{% endblocktrans %} {% endblocktrans %}
</p> </p>

View File

@ -33,9 +33,7 @@
<img src="{% static 'theme/img/freedombox-logo-32px.png' %}" <img src="{% static 'theme/img/freedombox-logo-32px.png' %}"
alt="{{ cfg.box_name }}" /> alt="{{ cfg.box_name }}" />
<a href="{% url 'index' %}"> <a href="{% url 'index' %}">
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}{{ box_name }} Setup{% endblocktrans %}
{{ box_name }} Setup
{% endblocktrans %}
</a> </a>
</span> </span>

View File

@ -26,8 +26,8 @@
<p> <p>
{% url 'help:manual' as manual_url %} {% url 'help:manual' as manual_url %}
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
The <a href="{{ manual_url }}">FreedomBox Manual</a> is the The <a href="{{ manual_url }}">{{ box_name }} Manual</a> is the
best place to start for information regarding {{ box_name }}. best place to start for information regarding {{ box_name }}.
{% endblocktrans %} {% endblocktrans %}
</p> </p>
@ -35,13 +35,13 @@
<p> <p>
{% blocktrans trimmed %} {% blocktrans trimmed %}
<a href="http://wiki.debian.org/FreedomBox" target="_blank"> <a href="http://wiki.debian.org/FreedomBox" target="_blank">
FreedomBox project wiki </a> contains further information. {{ box_name }} project wiki </a> contains further information.
{% endblocktrans %} {% endblocktrans %}
</p> </p>
<p> <p>
{% blocktrans trimmed %} {% blocktrans trimmed %}
To seek help from FreedomBox community, queries may be posted on To seek help from {{ box_name }} community, queries may be posted on
the the
<a href="https://lists.alioth.debian.org/mailman/listinfo/freedombox-discuss"> <a href="https://lists.alioth.debian.org/mailman/listinfo/freedombox-discuss">
mailing list</a>. The list archives also contain information mailing list</a>. The list archives also contain information
@ -51,8 +51,8 @@
<p> <p>
{% blocktrans trimmed %} {% blocktrans trimmed %}
Many FreedomBox contributors and users are also available on the irc.oftc.net IRC network. Many {{ box_name }} contributors and users are also available on
Join and request help on the the irc.oftc.net IRC network. Join and request help on the
<a href="https://webchat.oftc.net/?randomnick=1&channels=freedombox&prompt=1"> <a href="https://webchat.oftc.net/?randomnick=1&channels=freedombox&prompt=1">
#freedombox</a> channel using the IRC web interface. #freedombox</a> channel using the IRC web interface.
{% endblocktrans %} {% endblocktrans %}

View File

@ -35,12 +35,12 @@ service = None
def init(): def init():
"""Initialize the ikiwiki module.""" """Initialize the ikiwiki module."""
menu = cfg.main_menu.get('apps:index') menu = cfg.main_menu.get('apps:index')
menu.add_urlname(_('Wiki & Blog (Ikiwiki)'), 'glyphicon-edit', menu.add_urlname(_('Wiki and Blog (ikiwiki)'), 'glyphicon-edit',
'ikiwiki:index', 1100) 'ikiwiki:index', 1100)
global service global service
service = service_module.Service( service = service_module.Service(
'ikiwiki', _('Ikiwiki wikis and blogs'), ['http', 'https'], 'ikiwiki', _('ikiwiki wikis and blogs'), ['http', 'https'],
is_external=True, enabled=is_enabled()) is_external=True, enabled=is_enabled())

View File

@ -26,7 +26,7 @@ from django.utils.translation import ugettext_lazy as _
class IkiwikiForm(forms.Form): class IkiwikiForm(forms.Form):
"""ikiwiki configuration form.""" """ikiwiki configuration form."""
enabled = forms.BooleanField( enabled = forms.BooleanField(
label=_('Enable Ikiwiki'), label=_('Enable ikiwiki'),
required=False) required=False)

View File

@ -25,14 +25,15 @@
<h3> <h3>
{% blocktrans trimmed %} {% blocktrans trimmed %}
Delete Wiki/Blog <em>{{ name }}</em> Delete Wiki or Blog <em>{{ name }}</em>
{% endblocktrans %} {% endblocktrans %}
</h3> </h3>
<p> <p>
{% blocktrans trimmed %} {% blocktrans trimmed %}
This action will remove all the posts, pages and comments This action will remove all the posts, pages and comments
including revision history. Delete this wiki/blog permanently? including revision history. Delete this wiki or blog
permanently?
{% endblocktrans %} {% endblocktrans %}
</p> </p>

View File

@ -41,7 +41,7 @@ subsubmenu = [{'url': reverse_lazy('ikiwiki:index'),
def on_install(): def on_install():
"""Enable Ikiwiki on install.""" """Enable ikiwiki on install."""
actions.superuser_run('ikiwiki', ['setup']) actions.superuser_run('ikiwiki', ['setup'])
ikiwiki.service.notify_enabled(None, True) ikiwiki.service.notify_enabled(None, True)
@ -70,7 +70,7 @@ def index(request):
form = IkiwikiForm(initial=status, prefix='ikiwiki') form = IkiwikiForm(initial=status, prefix='ikiwiki')
return TemplateResponse(request, 'ikiwiki.html', return TemplateResponse(request, 'ikiwiki.html',
{'title': _('Wiki & Blog'), {'title': _('Wiki and Blog'),
'status': status, 'status': status,
'form': form, 'form': form,
'subsubmenu': subsubmenu}) 'subsubmenu': subsubmenu})
@ -129,7 +129,7 @@ def create(request):
form = IkiwikiCreateForm(prefix='ikiwiki') form = IkiwikiCreateForm(prefix='ikiwiki')
return TemplateResponse(request, 'ikiwiki_create.html', return TemplateResponse(request, 'ikiwiki_create.html',
{'title': _('Create Wiki/Blog'), {'title': _('Create Wiki or Blog'),
'form': form, 'form': form,
'subsubmenu': subsubmenu}) 'subsubmenu': subsubmenu})
@ -179,6 +179,6 @@ def delete(request, name):
return redirect(reverse_lazy('ikiwiki:manage')) return redirect(reverse_lazy('ikiwiki:manage'))
return TemplateResponse(request, 'ikiwiki_delete.html', return TemplateResponse(request, 'ikiwiki_delete.html',
{'title': _('Delete Wiki/Blog'), {'title': _('Delete Wiki or Blog'),
'subsubmenu': subsubmenu, 'subsubmenu': subsubmenu,
'name': name}) 'name': name})

View File

@ -38,7 +38,7 @@
<h2>{% trans "Certificates (Let's Encrypt)" %}</h2> <h2>{% trans "Certificates (Let's Encrypt)" %}</h2>
<p> <p>
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
A digital certficate allows users of a web service to verify the A digital certficate allows users of a web service to verify the
identity of the service and to securely communicate with it. identity of the service and to securely communicate with it.
{{ box_name }} can automatically obtain and setup digital {{ box_name }} can automatically obtain and setup digital

View File

@ -317,10 +317,10 @@
<div class="alert alert-danger"> <div class="alert alert-danger">
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
{% blocktrans trimmed %} {% blocktrans trimmed %}
This interface is not maintained by FreedomBox. Its This interface is not maintained by {{ box_name }}. Its
security status is unknown to FreedomBox. Many FreedomBox security status is unknown to {{ box_name }}. Many {{ box_name }}
services may not be available on this interface. It is services may not be available on this interface. It is
recommended that you deactivate/delete this connection and recommended that you deactivate or delete this connection and
re-configure it. re-configure it.
{% endblocktrans %} {% endblocktrans %}
</div> </div>

View File

@ -94,7 +94,7 @@
</div> </div>
<div class="col-sm-2"> <div class="col-sm-2">
<img src="{% static 'theme/img/network-freedombox.svg' %}" <img src="{% static 'theme/img/network-freedombox.svg' %}"
class="col-image network-entity" alt="{{ cfg.box_name }}"/> class="col-image network-entity" alt="{{ box_name }}"/>
</div> </div>
<div class="col-sm-3"> <div class="col-sm-3">
<img src="{% static 'theme/img/network-spacing.svg' %}" <img src="{% static 'theme/img/network-spacing.svg' %}"

View File

@ -35,9 +35,9 @@
<h2>{% trans "Virtual Private Network (OpenVPN)" %}</h2> <h2>{% trans "Virtual Private Network (OpenVPN)" %}</h2>
<p> <p>
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
Virtual Private Network (VPN) is a technique for securely Virtual Private Network (VPN) is a technique for securely
connecting two machines in order to access resources of a connecting two devices in order to access resources of a
private network. While you are away from home, you can connect private network. While you are away from home, you can connect
to your {{ box_name }} in order to join your home network and to your {{ box_name }} in order to join your home network and
access private/internal services provided by {{ box_name }}. access private/internal services provided by {{ box_name }}.
@ -51,19 +51,19 @@
<h3>{% trans "Profile" %}</h3> <h3>{% trans "Profile" %}</h3>
<p> <p>
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
To connect to {{ box_name }}'s VPN, you need to download a To connect to {{ box_name }}'s VPN, you need to download a
profile and feed it to an OpenVPN client on your mobile or profile and feed it to an OpenVPN client on your mobile or
desktop machine. OpenVPN Clients are available for most desktop machine. OpenVPN Clients are available for most
platforms. See platforms. See
<a href="https://wiki.debian.org/FreedomBox/Manual/OpenVPN" <a href="https://wiki.debian.org/FreedomBox/Manual/OpenVPN"
title="FreedomBox Manual - OpenVPN">documentation</a> on title="{{ box_name }} Manual - OpenVPN">documentation</a> on
recommended clients and instructions on how to configure them. recommended clients and instructions on how to configure them.
{% endblocktrans %} {% endblocktrans %}
</p> </p>
<p> <p>
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
Profile is specific to each user of {{ box_name }}. Keep it a Profile is specific to each user of {{ box_name }}. Keep it a
secret. secret.
{% endblocktrans %} {% endblocktrans %}
@ -82,7 +82,7 @@
{% if not status.is_setup and not status.setup_running %} {% if not status.is_setup and not status.setup_running %}
<p> <p>
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
OpenVPN has not yet been setup. Performing a secure setup OpenVPN has not yet been setup. Performing a secure setup
takes a very long time. Depending on how fast your takes a very long time. Depending on how fast your
{{ box_name }} is, it may even take hours. If the setup {{ box_name }} is, it may even take hours. If the setup
@ -105,7 +105,7 @@
</p> </p>
<p> <p>
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
To perform a secure setup, this process takes a very long To perform a secure setup, this process takes a very long
time. Depending on how fast your {{ box_name }} is, it may time. Depending on how fast your {{ box_name }} is, it may
even take hours. If the setup is interrupted, you may start even take hours. If the setup is interrupted, you may start

View File

@ -23,7 +23,7 @@
{% block content %} {% block content %}
<p> <p>
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
PageKite is a system for exposing {{ box_name }} services when PageKite is a system for exposing {{ box_name }} services when
you don't have a direct connection to the Internet. You only you don't have a direct connection to the Internet. You only
need this if your {{ box_name }} services are unreachable from need this if your {{ box_name }} services are unreachable from
@ -34,13 +34,13 @@
<ul> <ul>
<li> <li>
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
{{ box_name }} is behind a restricted firewall. {{ box_name }} is behind a restricted firewall.
{% endblocktrans %} {% endblocktrans %}
</li> </li>
<li> <li>
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
{{ box_name }} is connected to a (wireless) router which you {{ box_name }} is connected to a (wireless) router which you
don't control. don't control.
{% endblocktrans %} {% endblocktrans %}
@ -64,7 +64,7 @@
</ul> </ul>
<p> <p>
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
PageKite works around NAT, firewalls and IP-address limitations PageKite works around NAT, firewalls and IP-address limitations
by using a combination of tunnels and reverse proxies. You can by using a combination of tunnels and reverse proxies. You can
use any pagekite service provider, for example use any pagekite service provider, for example

View File

@ -35,7 +35,7 @@
</p> </p>
<p> <p>
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
You can use Privoxy by modifying your browser proxy settings to You can use Privoxy by modifying your browser proxy settings to
your {{ box_name }} hostname (or IP address) with port 8118. your {{ box_name }} hostname (or IP address) with port 8118.
While using Privoxy, you can see its configuration details and While using Privoxy, you can see its configuration details and

View File

@ -26,7 +26,7 @@
<h2>{% trans "IRC Client (Quassel)" %}</h2> <h2>{% trans "IRC Client (Quassel)" %}</h2>
<p> <p>
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
Quassel is an IRC application that is split into two parts, a Quassel is an IRC application that is split into two parts, a
"core" and a "client". This allows the core to remain connected "core" and a "client". This allows the core to remain connected
to IRC servers, and to continue receiving messages, even when to IRC servers, and to continue receiving messages, even when

View File

@ -31,7 +31,7 @@
web applications. The idea is to uncouple web applications from web applications. The idea is to uncouple web applications from
data. No matter where a web application is served from, the data. No matter where a web application is served from, the
data can be stored on an unhosted storage server of user's data can be stored on an unhosted storage server of user's
choice. With reStore, your {{ cfg.box_name }} becomes your choice. With reStore, your {{ box_name }} becomes your
unhosted storage server. unhosted storage server.
{% endblocktrans %} {% endblocktrans %}
</p> </p>

View File

@ -25,14 +25,14 @@
<h2>{% trans "System Configuration" %}</h2> <h2>{% trans "System Configuration" %}</h2>
<p> <p>
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
Here you can administrate the underlying system of your Here you can administrate the underlying system of your
{{ box_name }}. {{ box_name }}.
{% endblocktrans %} {% endblocktrans %}
</p> </p>
<p> <p>
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
The options affect the {{ box_name }} at its most general level, The options affect the {{ box_name }} at its most general level,
so be careful! so be careful!
{% endblocktrans %} {% endblocktrans %}

View File

@ -85,7 +85,7 @@
<h3>{% trans "Bridge" %}</h3> <h3>{% trans "Bridge" %}</h3>
<p> <p>
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
Your {{ box_name }} is configured as a Tor bridge with obfsproxy, Your {{ box_name }} is configured as a Tor bridge with obfsproxy,
so it can help circumvent censorship. If your {{ box_name }} is so it can help circumvent censorship. If your {{ box_name }} is
behind a router or firewall, you should make sure the following behind a router or firewall, you should make sure the following
@ -117,7 +117,7 @@
<h3>{% trans "SOCKS" %}</h3> <h3>{% trans "SOCKS" %}</h3>
<p> <p>
{% blocktrans trimmed with box_name=cfg.box_name %} {% blocktrans trimmed %}
A Tor SOCKS port is available on your {{ box_name }} on TCP port A Tor SOCKS port is available on your {{ box_name }} on TCP port
9050. 9050.
{% endblocktrans %} {% endblocktrans %}

View File

@ -34,6 +34,7 @@ from plinth import package
from plinth.errors import ActionError from plinth.errors import ActionError
from plinth.modules.names import SERVICES from plinth.modules.names import SERVICES
from plinth.signals import domain_added, domain_removed from plinth.signals import domain_added, domain_removed
from plinth.utils import format_lazy
APT_SOURCES_URI_PATHS = ('/files/etc/apt/sources.list/*/uri', APT_SOURCES_URI_PATHS = ('/files/etc/apt/sources.list/*/uri',
'/files/etc/apt/sources.list.d/*/*/uri') '/files/etc/apt/sources.list.d/*/*/uri')
@ -48,9 +49,10 @@ class TorForm(forms.Form): # pylint: disable=W0232
hs_enabled = forms.BooleanField( hs_enabled = forms.BooleanField(
label=_('Enable Tor Hidden Service'), label=_('Enable Tor Hidden Service'),
required=False, required=False,
help_text=_('A hidden service will allow FreedomBox to provide ' help_text=format_lazy(_(
'selected services (such as ownCloud or Chat) without ' 'A hidden service will allow {box_name} to provide selected '
'revealing its location.')) 'services (such as ownCloud or chat) without revealing its '
'location.'), box_name=_(cfg.box_name)))
apt_transport_tor_enabled = forms.BooleanField( apt_transport_tor_enabled = forms.BooleanField(
label=_('Download software packages over Tor'), label=_('Download software packages over Tor'),
required=False, required=False,

View File

@ -19,12 +19,12 @@
Framework for working with servers and their services. Framework for working with servers and their services.
""" """
import collections
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
import collections from plinth import cfg
from plinth.signals import service_enabled from plinth.signals import service_enabled
from plinth.utils import format_lazy
services = {} services = {}
@ -75,5 +75,7 @@ def init():
is_external=True, enabled=True) is_external=True, enabled=True)
Service('ssh', _('Secure Shell (SSH) Server'), ['ssh'], is_external=True, Service('ssh', _('Secure Shell (SSH) Server'), ['ssh'], is_external=True,
enabled=True) enabled=True)
Service('plinth', _('FreedomBox Web Interface (Plinth)'), ['https'], Service('plinth',
is_external=True, enabled=True) format_lazy(_('{box_name} Web Interface (Plinth)'),
box_name=_(cfg.box_name)),
['https'], is_external=True, enabled=True)

View File

@ -46,10 +46,12 @@
<meta name="msnbot" content="noindex, nofollow, noarchive, noodp" /> <meta name="msnbot" content="noindex, nofollow, noarchive, noodp" />
<meta name="slurp" content="noindex, nofollow, noarchive, noodp, noydir" /> <meta name="slurp" content="noindex, nofollow, noarchive, noodp, noydir" />
<meta name="description" <meta name="description"
content="{% trans "Plinth administrative interface for the FreedomBox" %}" /> content="{% blocktrans trimmed %}
Plinth administrative interface for the {{ box_name }}
{% endblocktrans %}" />
{% block title %} {% block title %}
<title> <title>
{% if title %} {{ title }} {% else %} {% trans "FreedomBox" %} {% endif %} {% if title %} {{ title }} {% else %} {{ box_name }} {% endif %}
</title> </title>
{% endblock %} {% endblock %}
@ -86,7 +88,7 @@
{% block mainmenu_left %} {% block mainmenu_left %}
<span class="navbar-brand"> <span class="navbar-brand">
<img src="{% static 'theme/img/freedombox-logo-32px.png' %}" <img src="{% static 'theme/img/freedombox-logo-32px.png' %}"
alt="{{ cfg.box_name }}" /> alt="{{ box_name }}" />
</span> </span>
<a href="{% url 'index' %}" class="navbar-brand" title="{% trans "Applications" %}"> <a href="{% url 'index' %}" class="navbar-brand" title="{% trans "Applications" %}">
<span class="glyphicon glyphicon-th"></span> <span class="glyphicon glyphicon-th"></span>

View File

@ -42,6 +42,8 @@ class ContextProcessorsTestCase(TestCase):
self.assertIsNotNone(config) self.assertIsNotNone(config)
self.assertEqual('FreedomBox', config.box_name) self.assertEqual('FreedomBox', config.box_name)
self.assertEqual('FreedomBox', response['box_name'])
submenu = response['submenu'] submenu = response['submenu']
self.assertIsNone(submenu) self.assertIsNone(submenu)

View File

@ -20,6 +20,7 @@ Miscelleneous utility method.
""" """
import importlib import importlib
from django.utils.functional import lazy
def import_from_gi(library, version): def import_from_gi(library, version):
@ -34,3 +35,12 @@ def import_from_gi(library, version):
package.require_version(library, version) package.require_version(library, version)
return importlib.import_module(package_name + '.repository.' + library) return importlib.import_module(package_name + '.repository.' + library)
def _format_lazy(string, *args, **kwargs):
"""Lazily format a lazy string."""
string = str(string)
return string.format(*args, **kwargs)
format_lazy = lazy(_format_lazy, str)