Centralized translations

This commit is contained in:
Jakub Kropáček 2024-01-29 20:52:57 +00:00
parent c55c9c87bd
commit 0d5335910f
15 changed files with 227 additions and 46 deletions

21
TODO.md Normal file
View file

@ -0,0 +1,21 @@
# TODO
## Localisation
- [ ] It would be nice to centralize the translations to some well-chosen singular directory
- [ ] Integrate it with some public translation project?
## DevOps Functionality
- [ ] I need to dockerize it
- [ ] It should be easily buildable and publishable using some kind of CI/CD
## Application Functionality
- [ ] I should be able to connect one (or many) subjects to a user, so they can start generating as the one
- This is meant so that the user is being the "connected subject"
- [ ] I need to be able to create the invoices as the connected subject to any subject in current database
- Automatically creating non-existing subjects might be nice to have
- [ ] I should be able to keep the invoices even if the subject is deleted (or changed) with the data in the day of the
creation
- [ ] Generating QR Payments is nice to have
- [ ] It would be great to automatically check `ares` for data changes from time to time

View file

@ -1,5 +1,6 @@
from crispy_forms import helper, layout
from django.contrib.auth.forms import AuthenticationForm, UserCreationForm
from django.utils.translation import gettext_lazy as _
from .models import User
@ -13,7 +14,7 @@ class LoginForm(AuthenticationForm):
self.helper = helper.FormHelper()
self.helper.form_action = "accounts:login"
self.helper.form_method = "post"
self.helper.add_input(layout.Submit('submit', 'Login'))
self.helper.add_input(layout.Submit('submit', _('Login')))
class RegisterForm(UserCreationForm):
@ -26,4 +27,4 @@ class RegisterForm(UserCreationForm):
self.helper = helper.FormHelper()
self.helper.form_action = "accounts:register"
self.helper.form_method = "post"
self.helper.add_input(layout.Submit('submit', 'Register'))
self.helper.add_input(layout.Submit('submit', _('Register')))

View file

@ -1,8 +1,9 @@
{% extends "facturio/base.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block title %}Login{% endblock %}
{% block title %}{% trans "Login" %}{% endblock %}
{% block content %}
{% crispy form form.helper %}

View file

@ -1,14 +1,22 @@
{% extends "facturio/base.html" %}
{% load i18n %}
{% block title %}About Me{% endblock %}
{% block title %}{% trans "About Me" %}{% endblock %}
{% block content %}
<h2 class="mb-4">About Me</h2>
<h2 class="mb-4">{% trans "About Me" %}</h2>
<div class="card">
<h5 class="card-header">Welcome, {{ request.user.first_name }} {{ request.user.last_name }}!</h5>
<h5 class="card-header">
{% blocktrans trimmed with firstname=request.user.first_name lastname=request.user.last_name %}Welcome,
{{ firstname }} {{ lastname }}!{% endblocktrans %}
</h5>
<ul class="list-group list-group-flush">
<li class="list-group-item">Username: {{ request.user.username }}</li>
<li class="list-group-item">Email: {{ request.user.email }}</li>
<li class="list-group-item">
{% blocktrans with username=request.user.username %}Username: {{ username }}{% endblocktrans %}
</li>
<li class="list-group-item">
{% blocktrans with email=request.user.email %}Email: {{ email }}{% endblocktrans %}
</li>
</ul>
</div>
{% endblock %}

View file

@ -1,10 +1,10 @@
{% extends "facturio/base.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block title %}Register{% endblock %}
{% block title %}{% trans "Register" %}{% endblock %}
{% block content %}
{# TODO: neukazovat všechny pičoviny hned najedou#}
{% crispy form form.helper %}
{% endblock %}

View file

@ -55,4 +55,5 @@ def auth_register(req: HttpRequest) -> HttpResponse:
@login_required
def me(req: HttpRequest) -> HttpResponse:
print(req.user.username)
return render(req, "account/me.html")

View file

@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/5.0/ref/settings/
"""
from pathlib import Path
from django.utils.translation import gettext_lazy as _
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
@ -44,6 +45,7 @@ INSTALLED_APPS = [
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.locale.LocaleMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
@ -102,7 +104,15 @@ AUTH_PASSWORD_VALIDATORS = [
# Internationalization
# https://docs.djangoproject.com/en/5.0/topics/i18n/
LANGUAGE_CODE = "en-us"
LANGUAGE_CODE = "cs"
LANGUAGES = [
("en", _("English")),
("cs", _("Czech"))
]
LOCALE_PATHS = [
BASE_DIR / "locale"
]
TIME_ZONE = "UTC"

View file

@ -1,32 +1,18 @@
"""
URL configuration for facturio project.
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/5.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.http import HttpRequest, HttpResponse
from django.shortcuts import render
from django.urls import path, include
from django.conf.urls.i18n import i18n_patterns
def landing_page(req: HttpRequest) -> HttpResponse:
return render(req, "facturio/index.html")
urlpatterns = [
urlpatterns = i18n_patterns(
path("", landing_page, name="main-page"),
path("accounts/", include("accounts.urls")),
path("subjects/", include("subjects.urls")),
path("admin/", admin.site.urls),
]
prefix_default_language=False
)

View file

@ -0,0 +1,142 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-01-29 20:46+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n "
"<= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n"
#: accounts/forms.py:17 accounts/templates/account/login.html:6
#: templates/facturio/base.html:39
msgid "Login"
msgstr "Přihlásit se"
#: accounts/forms.py:30 accounts/templates/account/register.html:6
#: templates/facturio/base.html:42
msgid "Register"
msgstr "Registrovat se"
#: accounts/models.py:9
msgid "first name"
msgstr "křestní jméno"
#: accounts/models.py:10
msgid "last name"
msgstr "přijmení"
#: accounts/models.py:11
msgid "email address"
msgstr "emailová adresa"
#: accounts/templates/account/me.html:4 accounts/templates/account/me.html:7
msgid "About Me"
msgstr "O mně"
#: accounts/templates/account/me.html:10
#, python-format
msgid "Welcome, %(firstname)s %(lastname)s!"
msgstr "Vítej, %(firstname)s %(lastname)s!"
#: accounts/templates/account/me.html:15
#, python-format
msgid "Username: %(username)s"
msgstr "Uživatelské jméno: %(username)s"
#: accounts/templates/account/me.html:18
#, python-format
msgid "Email: %(email)s"
msgstr "Email: %(email)s"
#: facturio/settings.py:109
msgid "English"
msgstr "Angličtina"
#: facturio/settings.py:110
msgid "Czech"
msgstr "Čeština"
#: subjects/forms.py:14
msgid "Your provided CIN is not correct."
msgstr "Vaše poskytnuté IČO není správné."
#: subjects/forms.py:15
msgid "Subject with provided CIN already exists."
msgstr "Subjekt s poskytnutým IČO již existuje."
#: subjects/forms.py:18 subjects/models.py:12
#: subjects/templates/subjects/index.html:11
msgid "CIN"
msgstr "IČO"
#: subjects/forms.py:20
msgid "Enter the subject CIN, rest will be generated automatically"
msgstr "Zadejte IČO subjektu, zbytek bude generován automaticky"
#: subjects/forms.py:28
msgid "Add"
msgstr "Vytvořit"
#: subjects/models.py:8
msgid "Subject"
msgstr "Subjekt"
#: subjects/models.py:9 subjects/templates/subjects/index.html:4
#: templates/facturio/base.html:19
msgid "Subjects"
msgstr "Subjekty"
#: subjects/models.py:18 subjects/templates/subjects/index.html:12
msgid "Name"
msgstr "Jméno"
#: subjects/models.py:23 subjects/templates/subjects/index.html:13
msgid "VAT ID"
msgstr "IČO"
#: subjects/models.py:30 subjects/templates/subjects/index.html:14
msgid "Street"
msgstr "Ulice"
#: subjects/models.py:35 subjects/templates/subjects/index.html:15
msgid "Zip Code"
msgstr "PSČ"
#: subjects/models.py:40 subjects/templates/subjects/index.html:16
msgid "City"
msgstr "Město"
#: subjects/models.py:45 subjects/templates/subjects/index.html:17
msgid "City part"
msgstr "Část města"
#: subjects/templates/subjects/create.html:6
msgid "Create Subjects"
msgstr "Vytvořit Subjekty"
#: subjects/templates/subjects/index.html:7
msgid "Add new"
msgstr "Přidat nový"
#: templates/facturio/base.html:8 templates/facturio/index.html:4
msgid "App"
msgstr "Aplikace"
#: templates/facturio/base.html:31
msgid "Profile"
msgstr "Profil"
#: templates/facturio/base.html:34
msgid "Logout"
msgstr "Odhlásit se"

View file

@ -25,7 +25,7 @@ class CreateSubjectForm(forms.Form):
self.helper = helper.FormHelper()
self.helper.form_action = "subjects:create"
self.helper.form_method = "post"
self.helper.add_input(layout.Submit('submit', 'Add'))
self.helper.add_input(layout.Submit('submit', _('Add')))
def clean_cin(self):
cin = self.cleaned_data.get("cin")

View file

@ -4,6 +4,10 @@ from django.utils.translation import gettext_lazy as _
class Subject(models.Model):
class Meta:
verbose_name = _("Subject")
verbose_name_plural = _("Subjects")
id = models.CharField(
_("CIN"),
max_length=8,

View file

@ -1,8 +1,9 @@
{% extends "facturio/base.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block title %}Create Subjects{% endblock %}
{% block title %}{% trans "Create Subjects" %}{% endblock %}
{% block content %}
{% crispy form form.helper %}

View file

@ -1,19 +1,20 @@
{% extends "facturio/base.html" %}
{% load i18n %}
{% block title %}Subjects{% endblock %}
{% block title %}{% trans "Subjects" %}{% endblock %}
{% block content %}
<a href="{% url "subjects:create" %}" class="btn btn-primary" role="button">Add new</a>
<a href="{% url "subjects:create" %}" class="btn btn-primary" role="button">{% trans "Add new" %}</a>
<table class="table">
<thead>
<tr>
<th>CIN</th>
<th>Name</th>
<th>VAT ID</th>
<th>Street</th>
<th>Zip Code</th>
<th>City</th>
<th>City part</th>
<th>{% trans "CIN" %}</th>
<th>{% trans "Name" %}</th>
<th>{% trans "VAT ID" %}</th>
<th>{% trans "Street" %}</th>
<th>{% trans "Zip Code" %}</th>
<th>{% trans "City" %}</th>
<th>{% trans "City part" %}</th>
</tr>
</thead>
<tbody>

View file

@ -1,9 +1,11 @@
{% load i18n %}
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Facturio - {% block title %}App{% endblock %}</title>
{# FIXME: this is not translating correctly!! #}
<title>Facturio - {% block title %}{% trans "App" %}{% endblock %}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
</head>
@ -14,7 +16,7 @@
<div class="collapse navbar-collapse">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="{% url "subjects:list" %}">Subjects</a>
<a class="nav-link" href="{% url "subjects:list" %}">{% trans "Subjects" %}</a>
</li>
{#<li class="nav-item">#}
{# <a class="nav-link" href="#">Item 2</a>#}
@ -26,17 +28,18 @@
<ul class="navbar-nav">
{% if request.user.is_authenticated %}
<li class="nav-item">
<a class="nav-link" href="{% url 'accounts:me' %}">Profile</a>
<a class="nav-link" href="{% url 'accounts:me' %}">{% trans "Profile" %}</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'accounts:logout' %}">Logout</a>
<a class="nav-link" href="{% url 'accounts:logout' %}">{% trans "Logout" %}</a>
</li>
{% else %}
{# FIXME: this is not translating correctly!! #}
<li class="nav-item">
<a class="nav-link" href="{% url 'accounts:login' %}">Login</a>
<a class="nav-link" href="{% url 'accounts:login' %}">{% trans "Login" %}</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'accounts:register' %}">Register</a>
<a class="nav-link" href="{% url 'accounts:register' %}">{% trans "Register" %}</a>
</li>
{% endif %}
</ul>

View file

@ -1,2 +1,4 @@
{% extends "facturio/base.html" %}
{% load i18n %}
{% block title %}{% trans "App" %}{% endblock %}