请求生命周期

Web 应用的用户可以访问不同的 URL,例如 /about/posts/api/resources。每个请求都根据以下请求类型进行处理。

  1. /api 开头的 API 请求由 REST API 处理器处理。
  2. 文件下载,如备份文件 (/backups)、公共文件 (/files) 和私有文件 (/private/files),会单独处理,以响应可下载的文件。
  3. 网页请求,如 /about/posts,由网站路由器处理。本页将进一步说明。

详细了解 API 请求和静态文件。

请求预处理

在触发路由规则之前,会发生一些操作。这些操作包括预处理请求、初始化记录器和速率限制器。

路径解析器

一旦请求从 app.py 到达网站路由器,它就会通过路径解析器进行处理。

路径解析器执行以下操作:

重定向解析

路径解析器尝试为传入的请求路径解析任何可能的重定向。路径解析器从 website_redirects 钩子获取重定向规则,并从网站设置中获取路由重定向。

路由解析

如果传入的请求路径没有重定向,路径解析器会尝试解析路由,以根据 website_routing_rules 钩子的规则以及启用了 has_web_view 的 DocType 文档中设置的动态路由来获取最终端点。

渲染器选择

一旦获得最终端点,它会传递给所有可用的页面渲染器,以检查哪个页面渲染器可以渲染给定的路径。第一个对 can_render 请求返回 True 的页面渲染器将用于渲染该路径。

页面渲染器

页面渲染器负责为给定的端点渲染页面或响应页面。页面渲染器使用 Python 类实现。一个页面渲染器类需要有两个方法,即 can_renderrender

路径解析器调用 can_render 来检查某个渲染器实例是否可以渲染特定路径。
一旦某个渲染器从 can_render 返回 True,该渲染器类就负责渲染该路径。

页面渲染器类示例

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)

以下是处理所有通用类型网页的标准页面渲染器。

StaticPage

使用 StaticPage,您可以从站点上安装的任何应用的 www 文件夹中提供 PDF、图片等文件。任何是以下类型 htmlmdjsxmlcsstxtpy 的文件都被视为静态文件。
提供静态文件的首选方式是将它们添加到您的 frappe 应用的 public 文件夹中。这样,它们将由 NGINX 直接提供,利用压缩和缓存,同时减少延迟。

TemplatePage

TemplatePage 在所有应用中查找 www 文件夹,如果它是 HTML 或 Markdown 文件,则返回该文件;如果它是一个文件夹,则返回该文件夹中的 index.htmlindex.md 文件。

WebformPage

如果请求路径与任何可用的 Web 表单路由匹配,WebformPage 会尝试在 Web 表单列表中渲染 Web 表单。

DocumentPage

如果 DocType 的 /templates 文件夹中有可用的文档模板,DocumentPage 会尝试渲染该模板。模板文件名应与 DocType 名称相同。例如:如果您想为 User 文档类型添加文档模板,则 User DocType 的 templates 文件夹中应有 user.html。文件夹结构将类似于 doctype/user/templates/user.html

ListPage

如果 DocType 的 /templates 文件夹中有列表模板,ListPage 将渲染它。请查看 Blog Post 模板文件夹以获取实现参考。

PrintPage

PrintPage 渲染文档的打印视图。它使用标准打印格式,除非通过 default_print_format 为 DocType 设置了不同的打印格式。

NotFoundPage

NotFoundPage 渲染标准的未找到页面,并响应 404 状态码。

NotPermittedPage

NotPermittedPage 渲染标准的权限拒绝页面,并带有 403 状态码。

添加自定义页面渲染器

如果您有其他标准页面渲染器未处理的需求,可以通过 page_renderer [钩子] 添加自定义页面渲染器。

# in hooks.py of your custom app

page_renderer = "path.to.your.custom_page_renderer.CustomPage"

页面渲染器类需要有两个方法,即 can_renderrender

路径解析器调用 can_render 来检查某个渲染器实例是否可以渲染特定路径。
一旦某个渲染器从 can_render 返回 True,该渲染器类就负责渲染该路径。

注意: 自定义页面渲染器具有优先权,其 can_render 方法将在标准页面渲染器之前被调用。

示例:


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)

注意:您还可以扩展标准页面渲染器,以覆盖或使用某些标准功能。