Skip to content

Commit

Permalink
Merge pull request #3 from skorbut/8-use-localization-for-text
Browse files Browse the repository at this point in the history
8 use localization for text
  • Loading branch information
skorbut authored Aug 29, 2019
2 parents 4a130c3 + 933af1a commit f1551dd
Show file tree
Hide file tree
Showing 21 changed files with 642 additions and 62 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,11 @@ flask run
```

Point your browser at http://127.0.0.1:5000 to access the app

### Localization

Wrap all strings to be localized in `_l()` calls. For templates use: `{{ _() }}`

Initialize babel via `pybabel extract -F babel.cfg -k _l -o messages.pot .`. Generate the german language catalog via `pybabel init -i messages.pot -d app/translations -l de`. Compile the language files via `pybabel compile -d app/translations`.

To update the translation do `pybabel extract -F babel.cfg -k _l -o messages.pot .` to collect new translation, update the language files via `pybabel update -i messages.pot -d app/translations`. After that you need to recompile using `pybabel compile -d app/translations`.
10 changes: 9 additions & 1 deletion app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging
import os
from flask import Flask
from flask import Flask, request
from flask_babel import Babel
from config import Config
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
Expand All @@ -19,6 +20,7 @@
migrate = Migrate(app, db)
bootstrap = Bootstrap(app)
socketio = SocketIO(app, logger=True, engineio_logger=True)
babel = Babel(app)

if __name__ == '__main__':
socketio.run(app)
Expand All @@ -44,6 +46,12 @@
app.logger.info('Trackday App started successfully')


@babel.localeselector
def get_locale():
app.logger.info("trying to get texts in language {}".format(request.accept_languages.best_match(app.config['LANGUAGES'])))
return request.accept_languages.best_match(app.config['LANGUAGES'])


from app import routes, models, errors, services
# to re init database use this import
# from app import models
41 changes: 21 additions & 20 deletions app/forms.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from flask_wtf import FlaskForm
from flask_babel import lazy_gettext as _l
from wtforms import StringField, TextField, SubmitField, SelectField, FieldList, FormField, HiddenField
from wtforms.validators import ValidationError, DataRequired
from app.models import Racer, Car
Expand All @@ -7,50 +8,50 @@
class GridEntryForm(FlaskForm):
class Meta:
csrf = False
controller = SelectField('Controller', choices=[(0, 1), (1, 2), (2, 3), (3, 4), (6, 'Ghost')])
racer = SelectField('Fahrer', coerce=int)
car = SelectField('Auto', coerce=int)
controller = SelectField('Controller', choices=[(0, 1), (1, 2), (2, 3), (3, 4), (6, _l('Ghost'))])
racer = SelectField(_l('Racer'), coerce=int)
car = SelectField(_l('Car'), coerce=int)


class RaceRegistrationForm(FlaskForm):
type = SelectField(
'Art',
choices=[('0', 'Freie Fahrt'), ('1', 'Training'), ('2', 'Qualifikation'), ('3', 'Rennen'), ('4', 'Zeitmessung')]
choices=[('0', _l('Free roam')), ('1', _l('Training')), ('2', _l('Qualifying')), ('3', _l('Race')), ('4', _l('Time trial'))]
)
duration = SelectField(
'Dauer',
choices=[
('0', 'unbegrenzt'),
('5m', '5 Minuten'),
('10m', '10 Minuten'),
('20m', '20 Minuten'),
('100l', '100 Runden'),
('500l', '500 Runden')
('0', _l('unlimited')),
('5m', _l('5 Minutes')),
('10m', _l('10 Minutes')),
('20m', _l('20 Minutes')),
('100l', _l('100 Laps')),
('500l', _l('500 Laps'))
]
)
status = HiddenField("created")
grid = FieldList(FormField(GridEntryForm), min_entries=1)
submit = SubmitField('Rennen starten')
submit = SubmitField(_l('Start Race'))


class RacerRegistrationForm(FlaskForm):
name = StringField('Name', validators=[DataRequired()])
submit = SubmitField('Fahrer registrieren')
name = StringField(_l('Name'), validators=[DataRequired()])
submit = SubmitField(_l('Register Racer'))

def validate_name(self, name):
racer = Racer.query.filter_by(name=name.data).first()
if racer is not None:
raise ValidationError('Fahrer mit diesem Namen ist schon registriert.')
raise ValidationError(_l('Racer already registered.'))


class CarRegistrationForm(FlaskForm):
name = StringField('Name', validators=[DataRequired()])
description = TextField('Beschreibung', validators=[DataRequired()])
order_number = StringField('Bestellnummer')
image_link = StringField('Bildlink')
submit = SubmitField('In Fuhrpark aufnehmen')
name = StringField(_l('Name'), validators=[DataRequired()])
description = TextField(_l('description'), validators=[DataRequired()])
order_number = StringField(_l('Order No.'))
image_link = StringField(_l('Image URL'))
submit = SubmitField(_l('Add to Car Park'))

def validate_order_number(self, order_number):
car = Car.query.filter_by(order_number=order_number.data).first()
if car is not None:
raise ValidationError('Auto mit dieser Nummer ist schon registriert.')
raise ValidationError(_l('Car already registered'))
1 change: 1 addition & 0 deletions app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from sqlalchemy import inspect
from app import app, db


class Race(db.Model):
id = db.Column(db.Integer, primary_key=True)
type = db.Column(db.String(16))
Expand Down
9 changes: 5 additions & 4 deletions app/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import json

from flask import request, render_template, flash, redirect, url_for
from flask_babel import lazy_gettext as _l
from app import app, db, services
from app.forms import CarRegistrationForm, RaceRegistrationForm, RacerRegistrationForm
from app.models import Car, Race, Racer
Expand Down Expand Up @@ -43,7 +44,7 @@ def race_stop(race_id):
db.session.commit()
services.disconnect_control_unit()
app.logger.info('stopping race:' + repr(race))
flash('Rennen gestoppt')
flash(_l('Race stopped'))
return render_template('races.html', title='Erstellte Rennen', races=Race.query.all())


Expand All @@ -67,7 +68,7 @@ def racer_registration():
racer = Racer(name=form.name.data)
db.session.add(racer)
db.session.commit()
flash('Ein neuer Fahrer wurde registriert.')
flash(_l('New racer registered'))
return redirect(url_for('racers'))
return render_template('racer_registration.html', title='Fahrer registrieren', form=form)

Expand All @@ -88,7 +89,7 @@ def race_registration():
)
db.session.add(race)
db.session.commit()
flash('Ein neues Rennen wurde registriert.')
flash(_l('New race registered.'))
return redirect(url_for('current_race'))
return render_template('race_registration.html', title='Rennen anlegen', form=form)

Expand All @@ -100,7 +101,7 @@ def register():
car = Car(name=form.name.data, description=form.description.data, order_number=form.order_number.data, image_link=form.image_link.data)
db.session.add(car)
db.session.commit()
flash('Ein neues Auto wurde dem Fuhrpark hinzugefügt')
flash(_l('New car added to car park'))
return redirect(url_for('index'))
return render_template('car_registration.html', title='Neues Auto registrieren', form=form)

Expand Down
4 changes: 2 additions & 2 deletions app/templates/404.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{% extends "base.html" %}

{% block app_content %}
<h1>Seite nicht gefunden</h1>
<p><a href="{{ url_for('index') }}">Zurück</a></p>
<h1>{{ _('Page not found') }}</h1>
<p><a href="{{ url_for('index') }}">{{ _('Back to index') }}</a></p>
{% endblock %}
10 changes: 5 additions & 5 deletions app/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a href="{{ url_for('index') }}">Startseite</a></li>
<li><a href="{{ url_for('racers') }}">Ins Fahrerlager</a></li>
<li><a href="{{ url_for('cars') }}">In den Fuhrpark</a></li>
<li><a href="{{ url_for('current_race') }}">Zum Rennen</a></li>
<li><a href="{{ url_for('races') }}">Zu den vergangenen Rennen</a></li>
<li><a href="{{ url_for('index') }}">{{ _('Index') }}</a></li>
<li><a href="{{ url_for('racers') }}">{{ _('Racers') }}</a></li>
<li><a href="{{ url_for('cars') }}">{{ _('Car park') }}</a></li>
<li><a href="{{ url_for('current_race') }}">{{ _('Current race') }}</a></li>
<li><a href="{{ url_for('races') }}">{{ _('Previous races') }}</a></li>
</ul>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion app/templates/car_registration.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{% import 'bootstrap/wtf.html' as wtf %}

{% block app_content %}
<h1>Neues Auto zum Fuhrpark hinzufügen</h1>
<h1>{{ _('Add new car to car park') }}</h1>
<form action="" method="post">
{{ form.hidden_tag() }}
<p>
Expand Down
2 changes: 1 addition & 1 deletion app/templates/cars.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{% extends "base.html" %}
{% block app_content %}

<h1>Fuhrpark</h1>
<h1>{{ _('Car park') }}</h1>
<div class = "d-flex flex-column bd-highlight mb-3">
{% for car in cars %}
<div class = "p-2 bd-highlight car">
Expand Down
14 changes: 7 additions & 7 deletions app/templates/current_race.html
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
{% extends "base.html" %}
{% block app_content %}

<h1>Aktuelles Rennen</h1>
<h1>{{ _('Current race') }}</h1>

<div class="d-flex flex-row-reverse mb1 status">
<div class="p2 d-flex flex-row status-item">
<p class="p2 status-label">CU:</p>
<p class="p2 status-value" id="control_unit_status">nicht verbunden</p>
<p class="p2 status-label">{{ _('CU') }}:</p>
<p class="p2 status-value" id="control_unit_status"> {{ _('not connected') }}</p>
</div>
{% if current_race%}
<div class="p2 d-flex flex-row action-item">
<a href="{{ url_for('race_stop', race_id=current_race.id) }}">Rennen stoppen</a>
<a href="{{ url_for('race_stop', race_id=current_race.id) }}">{{ _('Cancel race') }}</a>
</div>
{% endif %}
</div>
Expand All @@ -33,13 +33,13 @@ <h1>Aktuelles Rennen</h1>
</div>
<div class = "d-flex flex-row lap-data">
<div class="p-2 flex-fill">
<p>Gefahrene Runden:</p>
<p>{{ _('Laps') }}:</p>
<p class="lap-number" id = "lap-number-{{ grid_entry['controller'] }}">0</p>
</div>
<div class="p-2 flex-fill">
<p>Letzte Rundenzeit:</p>
<p>{{ _('Last lap') }}:</p>
<p class="lap-time" id = "lap-time-{{ grid_entry['controller'] }}">0 s</p>
<p>Beste Rundenzeit:</p>
<p>{{ _('Best lap') }}:</p>
<p class="lap-time" id = "best-time-{{ grid_entry['controller'] }}">0 s</p>
</div>
</div>
Expand Down
24 changes: 22 additions & 2 deletions app/templates/index.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
{% extends "base.html" %}

{% block app_content %}
<h1>Hallo Racer!</h1>
<h1>{{ _('Greetings Racer') }}!</h1>
<p>
{{ _('Here you have access to all race information, registered racers, the car park and the history of previous races. And you can start a new race here.') }}
</p>

<a href="{{ url_for('race_registration') }}">Neues Rennen</a>
<h3><a href="{{ url_for('race_registration') }}">{{ _('New race') }}</a></h3>
<p>
{{ _('Click the headline to configure and start a new race.') }}

</p>
<h3><a href="{{ url_for('racers') }}">{{ _('Registered racers') }}</a></h3>
<p>
{{ _('Find all registered racers and add new racers.') }}
</p>
<h3><a href="{{ url_for('cars') }}">{{ _('Car park') }}</a></h3>
<p>
{{ _('Here you find all available race cars.') }}

</p>
<h3><a href="{{ url_for('races') }}">{{ _('Previous races') }}</a></h3>
<p>
{{ _('Have a look at past races.') }}
</p>
{% endblock %}
14 changes: 7 additions & 7 deletions app/templates/race_registration.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
{% import 'bootstrap/wtf.html' as wtf %}

{% block app_content %}
<h1>Neues Rennen</h1>
<h1>{{ _('New race') }}</h1>
<form action="" method="post" novalidate>
{{ form.hidden_tag() }}
<h2>Grundeinstellungen</h2>
<h2>{{ _('Settings') }}</h2>
{{ form.status }}
<p>
{{ form.type.label }}<br>
Expand All @@ -22,7 +22,7 @@ <h2>Grundeinstellungen</h2>
{% endfor %}
</p>

<h2>Fahrerfeld</h2>
<h2>{{ _('Grid') }}</h2>
{% for error in form.grid.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
Expand All @@ -35,8 +35,8 @@ <h2>Fahrerfeld</h2>
{% endfor %}
</p>
</div>
<button class="add_grid_entry">Fahrer hinzufügen</button>
<button class="remove_grid_entry">Letzten Fahrer entfernen</button>
<button class="add_grid_entry">{{ _('Add racer') }}</button>
<button class="remove_grid_entry">{{ _('Remove last racer') }}</button>

<p>{{ form.submit() }}</p>
</form>
Expand All @@ -58,14 +58,14 @@ <h2>Fahrerfeld</h2>
racer_counter++;
$("#grid").append(duplicate_grid_entry());
}
else { window.alert('Mehr Rennfahrer sind nicht möglich')}
else { window.alert(_('Cannot add more racers'))}
});
$(removeButton).click(function(e){ //on remove input button click
e.preventDefault();
if(racer_counter > 1){ //make sure at least one field is there
$('#grid_'+racer_counter).remove();
racer_counter--;}
else { window.alert('Mindestens ein Rennfahrer muß bleiben')}
else { window.alert(_('At least one racer must stay in the grid'))}
});
function duplicate_grid_entry() {
var first_grid_entry = $("#grid p").first().html();
Expand Down
2 changes: 1 addition & 1 deletion app/templates/racer_registration.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{% import 'bootstrap/wtf.html' as wtf %}

{% block app_content %}
<h1>Neuen Fahrer registrieren</h1>
<h1>{{ _('Register a new racer') }}</h1>
<form action="" method="post" novalidate>
{{ form.hidden_tag() }}
<p>
Expand Down
4 changes: 2 additions & 2 deletions app/templates/racers.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{% extends "base.html" %}
{% block app_content %}

<h1>Registrierte Fahrer</h1>
<h1>{{ _('Registered racers') }}</h1>

<a href="{{ url_for('racer_registration') }}">Neuen Rennfahrer registrieren</a>
<a href="{{ url_for('racer_registration') }}">{{ _('Register a new racer') }}</a>

{% for racer in racers %}
<div class = "racer">
Expand Down
16 changes: 8 additions & 8 deletions app/templates/races.html
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
{% extends "base.html" %}
{% block app_content %}

<h1>Erstellte Rennen</h1>
<h1>{{ _('Previous races') }}</h1>

<a href="{{ url_for('race_registration') }}">Neues Rennen starten</a>
<a href="{{ url_for('race_registration') }}">{{ _('Star a new race') }}</a>

<table width = "80%">
<tr>
<th>ID</th>
<th>Erstellt am</th>
<th>Typ</th>
<th>Dauer</th>
<th>Status</th>
<th>Fahrerfeld</th>
<th>{{ _('ID') }}</th>
<th>{{ _('Created at') }}</th>
<th>{{ _('Type') }}</th>
<th>{{ _('Duration') }}</th>
<th>{{ _('State') }}</th>
<th>{{ _('Grid') }}</th>
</tr>
{% for race in races %}
<tr>
Expand Down
Binary file added app/translations/de/LC_MESSAGES/messages.mo
Binary file not shown.
Loading

0 comments on commit f1551dd

Please sign in to comment.