Add locales

This commit is contained in:
gabatxo1312 2026-01-30 18:23:54 +01:00
commit 362beac856
No known key found for this signature in database
22 changed files with 519 additions and 103 deletions

View file

@ -1,8 +1,8 @@
{% extends "base.html" %}
{% block main %}
<div class="mt-4 text-center">
<h1>Oops ! This page does not exist</h1>
<h2 class="fst-italic">404 NOT FOUND</h2>
<a href="/" class="mt-3 btn btn-info">Back to home</a>
<h1>{{ t!("error.error_404.title") }}</h1>
<h2 class="fst-italic">{{ t!("error.error_404.subtitle") }}</h2>
<a href="/" class="mt-3 btn btn-info">{{ t!("error.error_404.button") }}</a>
</div>
{% endblock %}

View file

@ -2,7 +2,7 @@
<head>
<meta charset="utf-8">
<title>{% block title %}Book Forge{% endblock %}</title>
<title>{% block title %}{{ t!("name") }}{% endblock %}</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/assets/css/bootstrap.css">
<link rel="stylesheet" href="/assets/css/main.css">

View file

@ -3,22 +3,22 @@
{% import "components/cards.html" as cards %}
{% block main %}
{{ typography::heading("Editer") }}
{{ typography::heading(t!("book.edit.title")) }}
{% call cards::card() %}
<form method="post" action="/books/{{ book.id }}">
<div class="mb-3">
<label class="form-label" for="title">Name</label>
<label class="form-label" for="title">{{ t!("book.attributes.title") }}</label>
<input type="text" name="title" class="form-control" value="{{ book.title }}" required>
</div>
<div class="mb-3">
<label for="authors" class="form-label">Author(s)</label>
<label for="authors" class="form-label">{{ t!("book.attributes.authors") }}</label>
<input type="text" name="authors" class="form-control" value="{{ book.authors }}" required>
</div>
<div class="mb-3">
<label for="owner_id" class="form-label">Owner</label>
<label for="owner_id" class="form-label">{{ t!("book.attributes.owner") }}</label>
<select name="owner_id" class="form-control" required>
{% for user in users %}
{% if book.owner_id == user.id %}
@ -31,7 +31,7 @@
</div>
<div class="mb-3">
<label for="current_holder_id" class="form-label">Current Holder</label>
<label for="current_holder_id" class="form-label">{{ t!("book.attributes.current_holder") }}</label>
<select class="form-control" name="current_holder_id">
<option></option>
{% match book.current_holder_id %}
@ -52,7 +52,7 @@
</div>
<div class="mb-3">
<label for="description" class="form-label">Description</label>
<label for="description" class="form-label">{{ t!("book.attributes.description") }}</label>
{% match book.description %}
{% when Some with (description) %}
<textarea name="description" class="form-control">{{ description }}</textarea>
@ -62,7 +62,7 @@
</div>
<div class="mb-3">
<label class="form-label" for="comment">Comment</label>
<label class="form-label" for="comment">{{ t!("book.attributes.comment") }}</label>
{% match book.comment %}
{% when Some with (comment) %}
<textarea name="comment" class="form-control">{{ comment }}</textarea>
@ -72,7 +72,7 @@
</div>
<div class="mt-4 text-center">
<input type="submit" value="Edit book" class="btn btn-success">
<input type="submit" value='{{ t!("book.edit.button") }}' class="btn btn-success">
</div>
</form>
{% endcall %}

View file

@ -4,27 +4,27 @@
{% import "components/inputs.html" as form_helpers %}
{% block main %}
{{ typography::heading("New book") }}
{{ typography::heading(t!("book.new.title")) }}
{% call cards::card() %}
<form method="post" action="/books">
{{ form_helpers::input("title", "Name", is_required = true, placeholder = "Ex: La Petite Dernière") }}
{{ form_helpers::input("authors", "Author(s)", is_required = true, placeholder = "Ex: Fatima Daas") }}
{{ form_helpers::input("title", t!("book.attributes.title"), is_required = true, placeholder = "Ex: La Petite Dernière") }}
{{ form_helpers::input("authors", t!("book.attributes.authors"), is_required = true, placeholder = "Ex: Fatima Daas") }}
{% call(option) form_helpers::select("owner_id", "Owner", users, is_required = true) %}
{% call(option) form_helpers::select("owner_id", t!("book.attributes.owner"), users, is_required = true) %}
<option value="{{ option.id }}">{{ option.name }}</option>
{% endcall %}
{% call(option) form_helpers::select("current_holder_id", "Current Holder", users, is_required = false) %}
{% call(option) form_helpers::select("current_holder_id", t!("book.attributes.current_holder"), users, is_required = false) %}
<option value="{{ option.id }}">{{ option.name }}</option>
{% endcall %}
{{ form_helpers::textarea("description", "Description", rows = 5, is_required = false, placeholder = "Ex: Je mappelle Fatima Daas. Je suis la mazoziya, la petite dernière. Celle à laquelle on ne sest pas préparé. Française dorigine algérienne.") }}
{{ form_helpers::textarea("comment", "Comment", rows = 3, is_required = false, placeholder = "Ex: I recommend it, it's great!") }}
{{ form_helpers::textarea("description", t!("book.attributes.description"), rows = 5, is_required = false, placeholder = "Ex: Je mappelle Fatima Daas. Je suis la mazoziya, la petite dernière. Celle à laquelle on ne sest pas préparé. Française dorigine algérienne.") }}
{{ form_helpers::textarea("comment", t!("book.attributes.comment"), rows = 3, is_required = false, placeholder = "Ex: I recommend it, it's great!") }}
<div class="mt-4 text-center">
<input type="submit" value="Create book" class="btn btn-success">
<input type="submit" value='{{ t!("book.new.button") }}' class="btn btn-success">
</div>
</form>
{% endcall %}

View file

@ -9,34 +9,34 @@
{% call cards::card() %}
<div class="mt-4">
<h5 class="mt-4 fw-bold">Book details</h5>
{{ fields::field("Name", book.title) }}
{{ fields::field("Authors", book.authors) }}
<h5 class="mt-4 fw-bold">{{ t!("book.show.book_details") }}</h5>
{{ fields::field(t!("book.attributes.title"), book.title) }}
{{ fields::field(t!("book.attributes.authors"), book.authors) }}
{% match book.description %}
{% when Some with (description) %}
{{ fields::field("Description", description) }}
{{ fields::field(t!("book.attributes.description"), description) }}
{% when None %}
{{ fields::field("Description", "-") }}
{{ fields::field(t!("book.attributes.description"), "-") }}
{% endmatch %}
<h5 class="mt-50px fw-bold">User Details</h5>
{{ fields::field("Owner", owner.name) }}
<h5 class="mt-50px fw-bold">{{ t!("book.show.user_details") }}</h5>
{{ fields::field(t!("book.attributes.owner"), owner.name) }}
{% match current_holder %}
{% when Some with (current_holder) %}
{{ fields::field("Current Holder", current_holder.name) }}
{{ fields::field(t!("book.attributes.current_holder"), current_holder.name) }}
{% when None %}
{{ fields::field("Current Holder", "-") }}
{{ fields::field(t!("book.attributes.current_holder"), "-") }}
{% endmatch %}
<h5 class="mt-50px fw-bold">More Informations</h5>
<h5 class="mt-50px fw-bold">{{ t!("book.show.more_informations") }}</h5>
{% match book.comment %}
{% when Some with (comment) %}
{{ fields::field("Comment", comment) }}
{{ fields::field(t!("book.attributes.comment"), comment) }}
{% when None %}
{{ fields::field("Comment", "-") }}
{{ fields::field(t!("book.attributes.comment"), "-") }}
{% endmatch %}
</div>
{% endcall %}

View file

@ -14,15 +14,15 @@
{% macro crud_dropdown_button(book, label, sub_path, show = true) %}
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
Actions
{{ label }}
</button>
<ul class="dropdown-menu">
{% if show %}
<li><a class="dropdown-item" href="/{{ sub_path }}/{{ book.id }}">Show</a></li>
<li><a class="dropdown-item" href="/{{ sub_path }}/{{ book.id }}">{{ t!("common.show") }}</a></li>
{% endif %}
<li><a class="dropdown-item" href="/{{ sub_path }}/{{ book.id }}/edit">Edit</a></li>
<li><a class="dropdown-item" href="/{{ sub_path }}/{{ book.id }}/edit">{{ t!("common.edit") }}</a></li>
<li>
<a class="dropdown-item" href="#" data-bs-toggle="modal" data-bs-target="#deleteUserModal{{ book.id }}">Delete</a>
<a class="dropdown-item" href="#" data-bs-toggle="modal" data-bs-target="#deleteUserModal{{ book.id }}">{{ t!("common.delete") }}</a>
</li>
</ul>
</div>
@ -32,16 +32,16 @@
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">Confirmation</h1>
<h1 class="modal-title fs-5" id="exampleModalLabel">{{ t!("common.confirmation") }}</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Are you sure ?</p>
<p>{{ t!("common.are_you_sure") }}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ t!("common.close") }}</button>
<form method="post" action="/{{ sub_path }}/{{ book.id }}/delete" class="m-0">
<input class="btn btn-danger" type="submit" value="Delete">
<input class="btn btn-danger" type="submit" value='{{ t!("common.delete") }}'>
</form>
</div>
</div>

View file

@ -21,7 +21,7 @@
</h1>
<div>
{{ dropdown::crud_dropdown_button(book, "Actions", "books", show) }}
{{ dropdown::crud_dropdown_button(book, t!("common.actions"), "books", show) }}
</div>
</div>
{% endmacro %}

View file

@ -1,12 +1,12 @@
{% extends "base.html" %}
{% block main %}
<div class="mt-4 text-center">
<h1>Oops ! An Error occured</h1>
<h1>{{ t!("error.generic.title") }}</h1>
<div class="alert alert-danger">
{% for error in state.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
<a href="/" class="mt-3 btn btn-info">Back to home</a>
<a href="/" class="mt-3 btn btn-info">{{ t!("error.error_404.button") }}</a>
</div>
{% endblock %}

View file

@ -4,9 +4,9 @@
{% import "components/cards.html" as cards %}
{% block main %}
{% call typography::heading("All books") %}
{% call typography::heading(t!("book.index.title")) %}
<a href="/books/download_csv?{{ base_query }}" class="btn btn-info">
<i class="fa fa-download me-2" aria-hidden="true"></i> Download (csv)
<i class="fa fa-download me-2" aria-hidden="true"></i> {{ t!("common.download") }} (csv)
</a>
{% endcall %}
@ -14,7 +14,7 @@
<form method="get">
<div class="row">
<div class="col-md-3">
<label for="title" class="form-label">Name</label>
<label for="title" class="form-label">{{ t!("book.attributes.title") }}</label>
{% match query.title %}
{% when Some with (value) %}
<input type="text" name="title" value="{{ value }}" class="form-control" placeholder="Ex: La liberte ou rien">
@ -24,7 +24,7 @@
</div>
<div class="col-md-3">
<label for="authors" class="form-label">Authors</label>
<label for="authors" class="form-label">{{ t!("book.attributes.authors") }}</label>
{% match query.authors %}
{% when Some with (value) %}
@ -35,7 +35,7 @@
</div>
<div class="col-md-2">
<label for="owner_id" class="form-label">Owner</label>
<label for="owner_id" class="form-label">{{ t!("book.attributes.owner") }}</label>
<select name="owner_id" class="form-select">
<option></option>
@ -57,7 +57,7 @@
</div>
<div class="col-md-2">
<label for="current_holder_id" class="form-label">Current Holder</label>
<label for="current_holder_id" class="form-label">{{ t!("book.attributes.current_holder") }}</label>
<select name="current_holder_id" class="form-select">
<option></option>
@ -79,11 +79,11 @@
</div>
<div class="col-md-1 d-flex align-items-end">
<input type="submit" value="Search" class="btn btn-info w-100">
<input type="submit" value='{{ t!("common.search") }}' class="btn btn-info w-100">
</div>
<div class="col-md-1 d-flex align-items-end">
<a href="/" class="btn btn-light">Reset</a>
<a href="/" class="btn btn-light">{{ t!("common.reset") }}</a>
</div>
</div>
</form>
@ -94,11 +94,11 @@
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Author(s)</th>
<th scope="col">Owner</th>
<th scope="col">Current Holder</th>
<th scope="col">Actions</th>
<th scope="col">{{ t!("book.attributes.title") }}</th>
<th scope="col">{{ t!("book.attributes.authors") }}</th>
<th scope="col">{{ t!("book.attributes.owner") }}</th>
<th scope="col">{{ t!("book.attributes.current_holder") }}</th>
<th scope="col">{{ t!("common.actions") }}</th>
</tr>
</thead>
<tbody>
@ -117,21 +117,21 @@
{% endmatch %}
</td>
<td>
{{ dropdown::crud_dropdown_button(book_user.book, "Actions", "books") }}
{{ dropdown::crud_dropdown_button(book_user.book, t!("common.actions"), "books") }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if total_page > 1 %}
<div class="d-flex justify-content-center mt-1">
<nav aria-label="Page navigation">
<ul class="pagination">
<li class="page-item {% if current_page <= 1 %}disabled{% endif %}">
<a class="page-link" href="/?{{ base_query }}page={% if current_page > 1 %}{{ current_page - 1 }}{% else %}1{% endif %}">Prev</a>
<a class="page-link" href="/?{{ base_query }}page={% if current_page > 1 %}{{ current_page - 1 }}{% else %}1{% endif %}">{{ t!("common.prev") }}</a>
</li>
{% for page in 1..(total_page + 1) %}
{% if page >= current_page - 1 && page <= current_page + 1 %}
<li class="page-item {% if page == current_page %}active{% endif %}">
@ -141,7 +141,7 @@
{% endfor %}
<li class="page-item {% if current_page == total_page %}disabled{% endif %}">
<a class="page-link" href="/?{{ base_query }}page={{ current_page + 1 }}">Next</a>
<a class="page-link" href="/?{{ base_query }}page={{ current_page + 1 }}">{{ t!("common.next") }}</a>
</li>
</ul>
</nav>

View file

@ -1,5 +1,5 @@
<div class="container text-center mt-4">
<div class="d-flex flex-column flex-sm-row gap-0 gap-sm-3 justify-content-center">
<p>Made with Love & Fuck a Fascist !</p>
<p>{{ t!("footer.message") }}</p>
</div>
</div>

View file

@ -1,31 +1,31 @@
<nav class="navbar navbar-expand-lg bg-body-tertiary fixed-top shadow">
<div class="container">
<a class="navbar-brand" href="/">
BookForge
{{ t!("name") }}
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
aria-controls="navbarNav" aria-expanded="false" aria-label="{{ t!("nav.toggle") }}">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav me-auto">
<li class="nav-item">
<a class="nav-link" href="/">Books</a>
<a class="nav-link" href="/">{{ t!("nav.books") }}</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/users">Users</a>
<a class="nav-link" href="/users">{{ t!("nav.users") }}</a>
</li>
</ul>
<div class="d-flex align-items-center gap-2 py-3">
<select id="changeTheme" class="form-select">
<option value="light">light</option>
<option value="dark">dark</option>
<option value="light">{{ t!("theme.light") }}</option>
<option value="dark">{{ t!("theme.dark") }}</option>
</select>
<a class="btn btn-success text-white" href="/books/new">
Add&nbsp;book
<a class="btn btn-success text-white text-nowrap" href="/books/new">
{{ t!("book.new.button_short") }}
</a>
</div>
</div>

View file

@ -4,17 +4,17 @@
o{% import "components/inputs.html" as form_helpers %}
{% block main %}
{{ typography::heading("New User") }}
{{ typography::heading(t!("user.edit.title")) }}
{% call cards::card() %}
<form action="/users/{{ user.id }}" method="post">
<div class="row align-items-end">
<div class="col-md-10">
{{ form_helpers::input("name", "Name", value = user.name, is_required = true, placeholder = "Ex: Kropotkine", margin_bottom = false) }}
{{ form_helpers::input("name", t!("user.attributes.name"), value = user.name, is_required = true, placeholder = "Ex: Kropotkine", margin_bottom = false) }}
</div>
<div class="col-md-2">
<input type="submit" value="Edit user" class="btn btn-success">
<input type="submit" value='{{ t!("user.edit.button") }}' class="btn btn-success">
</div>
</div>
</form>

View file

@ -5,15 +5,15 @@
{% import "components/inputs.html" as form_helpers %}
{% block main %}
{% call typography::heading("All users") %}
<a class="btn-success btn" href="/users/new">Add User</a>
{% call typography::heading(t!("user.index.title")) %}
<a class="btn-success btn" href="/users/new">{{ t!("user.index.button") }}</a>
{% endcall %}
{% call cards::card() %}
<form method="get">
<div class="row">
<div class="col-md-3">
<label for="name" class="form-label">Name</label>
<label for="name" class="form-label">{{ t!("user.attributes.name") }}</label>
{% match query.name %}
{% when Some with (value) %}
<input type="text" name="name" value="{{ value }}" class="form-control" placeholder="Ex: Koprotkine">
@ -23,11 +23,11 @@
</div>
<div class="col-md-1 d-flex align-items-end">
<input type="submit" value="Search" class="btn btn-info w-100">
<input type="submit" value='{{ t!("common.search") }}' class="btn btn-info w-100">
</div>
<div class="col-md-1 d-flex align-items-end">
<a href="/users" class="btn btn-light">Reset</a>
<a href="/users" class="btn btn-light">{{ t!("common.reset") }}</a>
</div>
</div>
</form>
@ -38,10 +38,10 @@
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Owner book</th>
<th scope="col">Borrowed book</th>
<th scope="col">Actions</th>
<th scope="col">{{ t!("user.attributes.name") }}</th>
<th scope="col">{{ t!("user.attributes.owner_books") }}</th>
<th scope="col">{{ t!("user.attributes.borrowed_books") }}</th>
<th scope="col">{{ t!("common.actions") }}</th>
</tr>
</thead>
<tbody>
@ -52,7 +52,7 @@
<td>{{ user_information.owner_book_number }}</td>
<td>{{ user_information.borrowed_book_number }}</td>
<td>
{{ dropdown::crud_dropdown_button(user_information.user, "Actions", "users", show = false) }}
{{ dropdown::crud_dropdown_button(user_information.user, t!("common.actions"), "users", show = false) }}
</td>
</tr>
{% endfor %}

View file

@ -4,16 +4,16 @@
o{% import "components/inputs.html" as form_helpers %}
{% block main %}
{{ typography::heading("New User") }}
{{ typography::heading(t!("user.new.title")) }}
{% call cards::card() %}
<form action="/users" method="post">
<div class="row align-items-end">
<div class="col-md-10">
{{ form_helpers::input("name", "Name", is_required = true, placeholder = "Ex: Kropotkine", margin_bottom = false) }}
{{ form_helpers::input("name", t!("user.attributes.name"), is_required = true, placeholder = "Ex: Kropotkine", margin_bottom = false) }}
</div>
<div class="col-md-2">
<input type="submit" value="Create user" class="btn btn-success">
<input type="submit" value='{{ t!("user.new.button") }}' class="btn btn-success">
</div>
</div>
</form>