Afficher la galerie¶
Objectif : lire toutes les images rattachées à une entité et les afficher
ensemble, miniatures comprises.
Ce que vous allez apprendre : get_media_gallery renvoie, pour chaque image
de rôle gallery d'une entité, l'URL de l'original et celles de ses
variantes (medium, thumbnail), prêtes à poser dans des balises <img>.
Deuxième palier du niveau intermédiaire de la progression images.
Module opt-in et table media
Ce starter suppose forge-mvc-images installé (palier « Installation ») et
la table media appliquée (forge migration:apply). Si elle manque, la
page reste pédagogique.
Ce que ce starter montre¶
- la lecture de la galerie d'une entité avec
get_media_gallery; - l'affichage de chaque image et de sa miniature ;
- une page pédagogique si la table
median'existe pas encore.
Classes Forge utilisées¶
| Classe / fonction | Rôle dans ce starter | Référence |
|---|---|---|
forge_mvc_images.get_media_gallery |
Lire les médias gallery d'une entité, variantes incluses. |
Médias |
BaseController.render |
Rendre la vue de la galerie. | BaseController |
Tester¶
Ouvrez https://localhost:8000/image-gallery : la page affiche les images
rattachées à l'entité de démo, chacune avec sa miniature.
Le contrôleur¶
# mvc/controllers/image_gallery_controller.py
from core.http.request import Request
from core.http.response import Response
from core.mvc.controller.base_controller import BaseController
from forge_mvc_images import get_media_gallery
_ENTITY_NAME = "gallery-demo"
_ENTITY_ID = 1
_TABLE_NOT_READY = (
"La table media n'est pas encore disponible. Applique la migration livrée "
"avec le starter : forge migration:apply."
)
class ImageGalleryController(BaseController):
"""Starter pédagogique : afficher la galerie d'images d'une entité."""
@staticmethod
def index(request: Request) -> Response:
try:
items = get_media_gallery(_ENTITY_NAME, _ENTITY_ID, role="gallery")
except Exception:
return BaseController.render(
"image_gallery/index.html",
context={"error": _TABLE_NOT_READY},
request=request,
)
return BaseController.render(
"image_gallery/index.html",
context={"items": items},
request=request,
)
Comprendre ce code¶
get_media_galleryfiltre sur le rôlegalleryet trie parPosition: la
galerie respecte l'ordre que vous fixerez au palier suivant.- Chaque élément expose
url,medium_url,thumbnail_urletalt_text: la
vue n'a plus qu'à choisir la bonne taille selon le contexte. - On entoure la lecture d'un
try/except: un starter de découverte ne plante
pas si la table manque, il explique.
La vue¶
Le contrôleur rend image_gallery/index.html : créez ce fichier.
<!-- mvc/views/image_gallery/index.html -->
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Galerie d'images — Forge</title>
</head>
<body>
<h1>Galerie d'images</h1>
{% if error %}
<p data-level="error"><strong>{{ error }}</strong></p>
{% endif %}
{% if items %}
<ul>
{% for item in items %}
<li>
<img src="{{ item.thumbnail_url or item.url }}" alt="{{ item.alt_text or '' }}">
<code>{{ item.path }}</code>
{% if item.alt_text %}<em>{{ item.alt_text }}</em>{% endif %}
</li>
{% endfor %}
</ul>
{% elif not error %}
<p>Aucune image dans la galerie pour l'instant. Téléversez-en une via le palier
« Rattacher une image à une entité ».</p>
{% endif %}
</body>
</html>
La migration¶
Ce palier lit la table media. Si vous ne l'avez pas encore créée au palier
précédent, créez le fichier de migration suivant sous mvc/migrations/, puis
appliquez-le avec forge migration:apply.
-- mvc/migrations/20260605101000_create_media.sql
CREATE TABLE IF NOT EXISTS media (
Id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
EntityName VARCHAR(100) NOT NULL,
EntityId INT NOT NULL,
Path VARCHAR(500) NOT NULL,
OriginalName VARCHAR(255) NOT NULL,
MimeType VARCHAR(120) NOT NULL,
Size INT NOT NULL,
Role VARCHAR(50) NOT NULL DEFAULT 'default',
Position INT NOT NULL DEFAULT 0,
AltText VARCHAR(255) NULL,
CreatedAt DATETIME NOT NULL,
PRIMARY KEY (Id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
La route¶
Déclarez la route dans mvc/routes.py, à l'intérieur du groupe public.
# mvc/routes.py
from mvc.controllers.image_gallery_controller import ImageGalleryController
with router.group("", public=True) as public:
public.add("GET", "/image-gallery", ImageGalleryController.index, name="image_gallery_index")
À retenir¶
get_media_galleryrenvoie les images d'une entité avec leurs variantes.- L'ordre d'affichage suit la colonne
Position. - Afficher une miniature plutôt que l'original économise de la bande passante.
Après ce starter¶
La galerie s'affiche. La suite : la rendre accessible et ordonnée.