Imports et usage¶
Objectif : exposer les trois façades sous un import unique et les utiliser
dans un contrôleur réel.
Ce que vous allez apprendre : ré-exporter les façades depuis le package, et
les combiner (session, flash, cookie) dans le flux d'un formulaire, en restant
cohérent avec les helpers déjà fournis par Forge.
Là où nous en sommes¶
Vous avez les quatre fichiers : _facade.py, session.py, cookies.py,
flash.py. Il reste à les rendre commodes à importer, puis à les employer.
L'ajout¶
Ré-exportez les façades dans mvc/helpers/__init__.py :
# mvc/helpers/__init__.py
from mvc.helpers.cookies import Cookies
from mvc.helpers.flash import Flash
from mvc.helpers.session import Session
__all__ = ["Session", "Cookies", "Flash"]
Un contrôleur peut alors tout importer en une ligne et composer le flux :
# mvc/controllers/note_controller.py (extrait)
from core.http.request import Request
from core.http.response import Response
from core.mvc.controller.base_controller import BaseController
from mvc.helpers import Cookies, Flash, Session
class NoteController(BaseController):
@staticmethod
def _ensure_session(request: Request):
"""Garantit une session et renvoie (session_id, data)."""
session_id = Session.current_id(request)
data = Session.get(session_id) if session_id else None
if data is None:
session_id = Session.new()
data = Session.get(session_id)
return session_id, data
@staticmethod
def form(request: Request) -> Response:
session_id, data = NoteController._ensure_session(request)
theme = Cookies.get(request, "theme", default="light") # lecture : sans risque
response = BaseController.render(
"note/form.html",
request=request,
context={
"csrf_token": data["csrf_token"],
"flash": Flash.get(session_id), # one-shot : lu puis supprimé
"theme": theme,
},
)
Session.set_cookie(response, session_id) # le SEUL Set-Cookie de cette réponse
return response
@staticmethod
def create(request: Request) -> Response:
# ... traitement de la création ...
# Motif POST -> redirect : Forge pose le flash ET redirige.
return BaseController.redirect("/note/form", request=request, flash="Note enregistrée")
Comprendre ce code¶
__init__.pyré-exporte les trois classes :from mvc.helpers import Session, Flash, Cookiessuffit, et__all__borne la surface publique du
package._ensure_sessioncompose les primitifs deSession(lire l'id, lire la
session, en créer une si besoin). On garde la logique get-or-create dans le
contrôleur ; les façades, elles, restent des primitifs.- Lecture du flash :
Flash.get(session_id)dans le rendu. S'il y a un
message en attente (posé par une action précédente), il s'affiche une fois. - Pose du flash : pour le cas POST→redirect, on utilise
BaseController.redirect(..., flash="…"), déjà fourni par Forge, qui pose
le message et redirige.Flash.set(...)de notre façade sert seulement aux
rares cas où l'on pose un flash sans rediriger. - Cookie : on lit un cookie applicatif (
theme) sans risque. On ne le
réécrit pas ici, car cette réponse pose déjà le cookie de session
(Session.set_cookie) ; rappel du palier 3 : un seulSet-Cookiepar
réponse. Pour changer le thème, on le ferait sur une réponse dédiée qui ne
pose pas la session.
Tester¶
Lancez l'application (forge run) et ouvrez le formulaire : le jeton CSRF est
rempli, le thème lu depuis le cookie, et après une création le message « Note
enregistrée » apparaît une seule fois au retour.
À retenir¶
mvc/helpers/__init__.pydonne un import unique pour les trois façades.- La logique get-or-create se compose dans le contrôleur ; les façades restent
des primitifs. - Réutilisez les helpers de Forge quand ils existent (
BaseController.redirect
pour flash+redirect) ; vos façades complètent, elles ne remplacent pas. - Respectez la limite un seul
Set-Cookiepar réponse.