Frappe Framework
Cycle de vie d’une requête
Du chemin demandé à la page rendue : prétraitement, résolveur de chemin, sélection du moteur de rendu (StaticPage, TemplatePage, WebformPage, DocumentPage…) et hook page_renderer.
Les types de requêtes
L’utilisateur d’une application web visite différentes URL, comme /about, /posts ou /api/resources. Chaque requête est traitée selon son type :
- Les requêtes d’API, qui commencent par
/api, sont prises en charge par le gestionnaire de l’API REST. - Les téléchargements de fichiers, comme les sauvegardes (
/backups), les fichiers publics (/files) et les fichiers privés (/private/files), sont traités à part pour répondre avec un fichier téléchargeable. - Les requêtes de pages web, comme
/aboutou/posts, sont traitées par le routeur du site web (website router). C’est ce que détaille cette page.
Pour aller plus loin : API REST et assets statiques.
Prétraitement de la requête
Quelques opérations ont lieu avant que les règles de routage ne s’appliquent : le prétraitement de la requête, l’initialisation de l’enregistreur (recorder) et du limiteur de débit (rate limiter).
Résolveur de chemin (Path Resolver)
Quand la requête atteint le routeur du site web depuis app.py, elle passe par le résolveur de chemin, qui effectue les opérations suivantes.
Résolution des redirections
Le résolveur cherche d’abord une éventuelle redirection pour le chemin demandé. Il récupère les règles de redirection du hook website_redirects et les redirections de routes définies dans les paramètres du site web (Website Settings).
Résolution de la route
S’il n’y a pas de redirection, le résolveur tente de déterminer le point d’arrivée (endpoint) final à partir des règles du hook website_route_rules et des routes dynamiques définies dans les documents des DocTypes dont l’option has_web_view est activée.
Sélection du moteur de rendu
Une fois le point d’arrivée obtenu, il est soumis à tous les moteurs de rendu de page (Page Renderer) disponibles pour savoir lequel peut rendre ce chemin. Le premier moteur dont la méthode can_render renvoie True est utilisé.
Moteur de rendu de page (Page Renderer)
Un moteur de rendu se charge de produire la page (ou la réponse) pour un point d’arrivée donné. Il est implémenté par une classe Python qui doit définir deux méthodes : can_render et render.
Le résolveur de chemin appelle can_render pour savoir si une instance du moteur peut rendre un chemin donné. Dès qu’un moteur renvoie True, c’est à sa classe de rendre le chemin.
Exemple de classe de moteur de rendu
from frappe.website.page_renderers.base_renderer import BaseRenderer
class PageRenderer(BaseRenderer):
def can_render(self):
return True
def render(self):
response_html = "Response"
return self.build_response(response_html)Les moteurs de rendu standard ci-dessous couvrent tous les types génériques de pages web.
StaticPage
StaticPage sert des PDF, images, etc. depuis le dossier www de n’importe quelle app installée sur le site. Tout fichier dont le type n’est pas l’un des suivants est considéré comme statique : html, md, js, xml, css, txt ou py.
Conseil
La méthode recommandée pour servir des fichiers statiques est de les placer dans le dossier public de votre app Frappe. NGINX les sert alors directement, avec compression et mise en cache, ce qui réduit aussi la latence.
TemplatePage
TemplatePage parcourt le dossier www de toutes les apps. Si le chemin correspond à un fichier HTML ou Markdown, celui-ci est renvoyé ; s’il correspond à un dossier, c’est le fichier index.html ou index.md de ce dossier qui est renvoyé.
WebformPage
WebformPage tente de rendre un Web Form si le chemin demandé correspond à la route de l’un des Web Forms existants.
DocumentPage
DocumentPage tente de rendre un template de document s’il en existe un dans le dossier /templates du DocType. Le fichier de template doit porter le même nom que le DocType. Exemple : pour ajouter un template de document au DocType User, le dossier templates du DocType User doit contenir user.html, soit l’arborescence doctype/user/templates/user.html.
ListPage
Si un DocType possède un template de liste dans son dossier /templates, ListPage le rend. Voir le dossier templates de Blog Post comme référence d’implémentation.
PrintPage
PrintPage rend la vue d’impression d’un document. Il utilise le format d’impression standard, sauf si un autre format d’impression est défini pour le DocType via default_print_format.
NotFoundPage
NotFoundPage rend la page standard « non trouvé » et répond avec le code 404.
NotPermittedPage
NotPermittedPage rend la page standard « accès refusé » et répond avec le code 403.
Ajouter un moteur de rendu personnalisé
Si vos besoins ne sont pas couverts par les moteurs standard, vous pouvez ajouter un moteur de rendu personnalisé via le hook page_renderer.
# in hooks.py of your custom app
page_renderer = "path.to.your.custom_page_renderer.CustomPage"La classe doit définir deux méthodes : can_render et render.
Le résolveur de chemin appelle can_render pour savoir si une instance peut rendre un chemin donné. Dès qu’un moteur renvoie True, c’est à sa classe de rendre le chemin.
À retenir
Les moteurs de rendu personnalisés sont prioritaires : leur méthode can_render est appelée avant celle des moteurs standard.
Exemple :
from frappe.website.utils import build_response
from frappe.website.page_renderers.base_renderer import BaseRenderer
class CustomPage(BaseRenderer):
def can_render(self):
return True
def render(self):
response_html = "Custom Response"
return self.build_response(response_html)À retenir
Vous pouvez aussi étendre les moteurs de rendu standard pour surcharger ou réutiliser certaines de leurs fonctionnalités.
