Empress URL Request Handling and Page Rendering

Introduction

Welcome to this guide, where we’ll dive deep into the heart of Empress, focusing on the feature: URL Request Handling and Page Rendering. This is an essential component of a web application, as it manages the user’s interaction with different URLs such as /about, /posts, and /api/resources. Understanding this feature is crucial for developers looking to fully leverage Empress’s capabilities in creating robust and dynamic web applications.

Understanding the Request Types

In Empress, each user request is handled based on the following types:

  1. API requests - These are requests that start with /api, and they are handled by the rest API handler.
  2. File downloads - Requests for file downloads like backups (/backups), public files (/files), and private files (/private/files) are handled separately to provide the user with a downloadable file.
  3. Web page requests - These are requests like /about, /posts, which are handled by the website router.
# Example of how the request types are handled
# Note: This is a conceptual representation and not actual code

if request.startswith('/api'):
    handle_api_request(request)
elif request.startswith('/backups') or request.startswith('/files') or request.startswith('/private/files'):
    handle_file_download(request)
else:
    handle_web_page_request(request)

Request Pre-processing

Before the routing rules are triggered, several preprocessing steps occur. These steps include initialising the recorder and the rate limiter, preparing the request for handling.

Path Resolver

The path resolver is responsible for processing all requests that reach the website router from app.py. It performs several operations:

  1. Redirect Resolution - The path resolver attempts to resolve any possible redirect for an incoming request path, fetching redirect rules from the website_redirects hook and route redirects from website settings.
  2. Route Resolution - If there are no redirects for incoming requests, the path resolver tries to resolve the route to get the final endpoint based on rules from the website_routing_rules hook and dynamic route set in documents of DocType with has_web_view enabled.
  3. Renderer Selection - Once the final endpoint is obtained, it is passed through all available Page Renderers to check which page renderer can render the given path. The first page renderer to return True for the can_render request will be used to render the path.

Page Renderer

A Page Renderer is responsible for rendering or responding with a page for a given endpoint. Implemented using a Python class, a Page Renderer class needs to have two methods: can_render and render.

Here’s an example of a page renderer class:

from frappe.website.page_renderers.base_renderer import BaseRenderer

class PageRenderer(BaseRenderer):
    def can_render(self):
        return True

    def render(self):
        response_html = "<div>Response</div>"
        return self.build_response(response_html)

Adding a Custom Page Renderer

If the standard page renderers do not meet your requirements, you can add a custom page renderer via the page_renderer hook.

# in hooks.py of your custom app

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

Here’s an example of a custom page renderer:

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 = "<div>Custom Response</div>"
        return self.build_response(response_html)

Remember, custom page renderers get priority and their can_render method will be called before standard page renderers.

Conclusion

Understanding URL Request Handling and Page Rendering is critical to creating dynamic, responsive web applications with Empress. These features allow developers to control the user’s interaction with the application, manage the routing of requests, and customize the rendering of pages. Mastering these aspects of Empress can significantly enhance your development and customization of business solutions.