MishkaCmsCore.Runtime.Compilers.ErrorCompiler (Mishka CMS Core v0.0.1)

Copy Markdown View Source

Runtime compiler for Error Page modules with dynamic content compilation.

This module provides functionality to dynamically compile error page modules at runtime from configuration data. It generates complete error handling modules with custom layouts, templates, and helper functions for different HTTP error status codes.

Features

  • Dynamic error page module generation from configuration
  • Custom error page templates for different HTTP status codes
  • Flexible layout system with root layout and per-status layouts
  • Helper function integration for custom error page logic
  • Automatic CSS and JavaScript injection for styled error pages
  • Fallback error handling for unhandled status codes
  • Site-specific error page configurations

Error Page Structure

Generated error page modules include:

  • __error_information__/0 - Returns error page metadata
  • __error_information__/1 - Returns specific metadata by key
  • render/2 - Main rendering function for each status code
  • layout/2 - Layout function for each status code
  • root_layout/1 - Root HTML layout wrapper
  • Helper functions (if defined)

Usage

params = %{
  title: "My Site Errors",
  error_module: MyApp.Errors.SiteErrors,
  site: "main",
  site_id: 1,
  error_pages: [
    %{
      status: 404,
      template: ~S(<h1>Page Not Found</h1><p>The page you're looking for doesn't exist.</p>),
      layout: %{template: ~S(<div class="error-layout"><%= @inner_content %></div>)}
    },
    %{
      status: 500,
      template: ~S(<h1>Server Error</h1><p>Something went wrong on our end.</p>)
    }
  ],
  root_layout_template: ~S(
    <!DOCTYPE html>
    <html>
      <head><title>Error <%= @status %></title></head>
      <body><%= @inner_content %></body>
    </html>
  ),
  helpers: [
    %{
      name: "format_error_message",
      args: "status, message",
      code: ~S("Error " <> Integer.to_string(status) <> ": " <> message)
    }
  ]
}

ast = ErrorCompiler.build_module(params)
MishkaCmsCore.Runtime.Compilers.ModuleCompiler.compile_module(ast)

Layout Hierarchy

The error page rendering follows this hierarchy:

  1. Root Layout - Outer HTML document structure
  2. Status Layout - Per-status layout wrapper (optional)
  3. Error Template - The actual error content

Error Page Configuration

Each error page in the :error_pages list should contain:

  • :status - HTTP status code, or :offline for the page an offline site shows (required) — see MishkaCmsCore.Runtime.ErrorStatus
  • :template - Error content template (required)
  • :layout - Optional layout wrapper with :template key

Summary

Functions

Build error page information including metadata.

Build helper functions for the error pages.

Build layout functions for error pages.

Main function to build error page modules from error page data.

Build render functions for error pages.

Create the final module AST.

The <title> of an error page whose site set no root layout, in the language of the request.

Create environment for template compilation.

Whether the compiled Error Page module holds an :offline entry, however its status was stored.

The compiled Error Page module's page for status, drawn for conn, as HTML.

Functions

build_error_information(params)

Build error page information including metadata.

Creates AST for the __error_information__ functions that provide access to error page metadata, private information, and extra data. These functions are used by the runtime system to introspect error page properties.

Parameters

  • params - Atomized error page parameters map

Returns

Returns a tuple {params, functions_ast} where functions_ast contains the AST for:

  • __error_information__/0 - Returns complete metadata map
  • __error_information__/1 - Returns metadata by atom key or key path
  • __error_information__/1 - Returns metadata by string dot-notation path

Metadata Structure

The metadata includes:

  • :error - Public error page info (title, path, error_pages, timestamp)
  • :private - Private runtime info (id, error_module, priority, site details)
  • :extra - Additional custom metadata

build_helpers(arg)

Build helper functions for the error pages.

Processes helper function definitions and creates corresponding function AST, plus generates the root layout function for the complete HTML document structure.

Parameters

  • {params, functions_ast} - Tuple containing params and accumulated AST functions

Returns

Returns updated tuple with helper functions and root layout function added to the AST.

Helper Functions

Each helper function definition should contain:

  • :name - Function name as string
  • :args - Function arguments as Elixir code string
  • :code - Function body as Elixir code string

Root Layout Function

Generates a root_layout/1 function that provides the outer HTML document structure:

Custom Root Layout

If :root_layout_template is provided, compiles it as the root layout.

Default Root Layout

If no custom template provided, generates a default HTML document with:

  • Proper DOCTYPE and HTML structure
  • Error status in page title
  • CSRF token meta tag
  • Viewport meta tag for responsive design
  • Automatic CSS injection from TailwindCompiler (if site configured)
  • Automatic JavaScript injection from JavaScriptCompiler (if site configured)
  • Body containing the inner content

Template Compilation

All templates are compiled using Phoenix.HTML.Engine for proper HTML generation and security (XSS protection, HTML escaping, etc.).

build_layout_functions(arg)

Build layout functions for error pages.

Generates layout functions for each error page status code. Layout functions provide an intermediate rendering layer between the error template and the root layout.

Parameters

  • {params, functions_ast} - Tuple containing params and accumulated AST functions

Returns

Returns updated tuple with layout functions added for each status code.

Generated Functions

For each error page, generates a layout/2 function that:

  • Takes a status code and assigns map as parameters
  • Returns the rendered layout template (if provided)
  • Falls back to returning inner_content directly if no layout template

Layout Behavior

  • With layout template: Renders the template with inner_content available
  • Without layout template: Returns the inner_content as-is for direct rendering

build_module(params)

Main function to build error page modules from error page data.

Takes error page configuration parameters and returns a complete AST for an error handling module. The function orchestrates the entire compilation process through a pipeline of transformations.

Parameters

  • params - Map containing error page configuration with keys:
    • :title - Error page title/name (required)
    • :error_module - Target module name (required)
    • :site - Site identifier (required)
    • :site_id - Site ID for database reference
    • :error_pages - List of error page definitions (required)
    • :root_layout_template - Root HTML layout template (optional)
    • :helpers - List of helper function definitions (optional)
    • :host - Host information for multi-tenant setups
    • :extra - Additional metadata

Error Page Structure

Each error page in :error_pages should contain:

  • :status - HTTP status code (integer)
  • :template - Error content template string
  • :layout - Optional layout map with :template key

Returns

Returns the complete AST for the error module that can be compiled using MishkaCmsCore.Runtime.Compilers.ModuleCompiler.compile_module/1.

Example

params = %{
  title: "Site Error Pages",
  error_module: MyApp.SiteErrors,
  site: "production",
  error_pages: [
    %{status: 404, template: "<h1>Not Found</h1>"},
    %{status: 500, template: "<h1>Server Error</h1>"}
  ]
}

ast = build_module(params)

build_render_functions(arg)

Build render functions for error pages.

Generates the main rendering functions for each error page status code and a catch-all fallback function. These functions are the primary entry points for error page rendering.

Parameters

  • {params, functions_ast} - Tuple containing params and accumulated AST functions

Returns

Returns updated tuple with render functions added for each status code plus a catch-all function.

Generated Functions

For each error page, generates a render/2 function that:

  1. Takes a connection and status code as parameters
  2. Creates assigns with conn, status, and inner_content
  3. Calls the appropriate layout function for the status
  4. Wraps the result in the root layout

Catch-All Function

Adds a fallback render/2 function that:

Rendering Flow

  1. render/2 called with conn and status
  2. Error template compiled and rendered
  3. Layout template applied (if configured)
  4. Root layout wraps the final result

create_module_ast(arg)

Create the final module AST.

Assembles all error page components into a complete error handling module AST. The generated module includes all necessary imports and uses for proper Phoenix integration.

Parameters

  • {params, functions_ast} - Tuple containing params and all accumulated function ASTs

Returns

Returns the complete module AST ready for compilation via ModuleCompiler.compile_module/1.

Generated Module Structure

The final module includes:

  • defmodule declaration with the target error module name
  • Required imports (Logger)
  • LiveView integration via the configured :web_module
  • Runtime component helper imports
  • All accumulated function definitions (info, layout, render, helpers, root layout)

The module is fully self-contained and ready for runtime compilation and loading into the Phoenix error handling system.

fallback_title(status)

@spec fallback_title(MishkaCmsCore.Runtime.ErrorStatus.t()) :: String.t()

The <title> of an error page whose site set no root layout, in the language of the request.

make_env()

Create environment for template compilation.

Builds a compilation environment with necessary imports for template processing. Ensures that Phoenix HTML, Component, and LiveView helpers are available during template compilation.

Returns

Returns a Macro.Env struct with all required imports defined for proper template compilation.

Imported Modules

Failed imports are logged but don't stop the compilation process, ensuring robustness even when some modules aren't available.

Error Handling

If any module fails to import, the error is logged as a warning and compilation continues with the remaining successfully imported modules.

offline_entry?(module)

@spec offline_entry?(module()) :: boolean()

Whether the compiled Error Page module holds an :offline entry, however its status was stored.

render_page(module, conn, status)

The compiled Error Page module's page for status, drawn for conn, as HTML.

The template is handed @status, and @conn with :page_module and :page_data assigned.