Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fullbleed Django shared-template demo

This repository demonstrates a pattern that should feel natural to Django teams:

  • define accessible document structure once in Django templates
  • reuse that semantic structure for the normal browser page
  • send the same structure to Fullbleed for a real tagged PDF export

The example is an account summary because it mirrors a common SaaS workflow: a customer reviews information in the browser, then downloads the same information as a PDF for accounting, procurement, or compliance purposes.

What the demo shows

The app has three key routes:

  • / shows the project framing and a fixture-backed account summary
  • /accounts/northwind-analytics/ renders the user-facing browser page
  • /accounts/northwind-analytics/export/pdf/ renders a real tagged PDF using Fullbleed

This is not a mocked export route. The PDF endpoint generates a real PDF response with:

  • pdf_profile="tagged"
  • document_title and document_lang
  • a footer generated by Fullbleed
  • a seed verification pass surfaced in the response headers

Core architecture

The important implementation detail is the shared template boundary:

  • billing/templates/billing/_account_summary.html
    The semantic partial. It owns the headings, table structure, contact details, and note sections.
  • billing/templates/billing/account_summary_page.html
    The browser page layout that includes the shared partial directly.
  • billing/templates/billing/account_summary_pdf.html
    The PDF document wrapper that also includes the same shared partial.
  • billing/templates/billing/account_summary_pdf.css
    The CSS payload sent to Fullbleed alongside the PDF HTML document.
  • billing/services/fullbleed.py
    The single Fullbleed integration boundary.

The export route stays small on purpose:

document_html = render_to_string("billing/account_summary_pdf.html", context, request=request)
document_css = render_to_string("billing/account_summary_pdf.css", context, request=request)
renderer = FullbleedRenderer()
fullbleed_request = renderer.build_request(
    summary=summary,
    html=document_html,
    css=document_css,
)
pdf_bytes = renderer.render_tagged_pdf(fullbleed_request)

That is the pattern in one glance: Django owns semantics, Fullbleed owns PDF generation.

Why this matters for Django developers

Django teams already know how to build accessible HTML with semantic headings, tables, landmarks, readable order, and clear labels. The accessibility gap usually appears when the same content has to leave the browser as a PDF.

A lot of teams solve that by creating a second export-only rendering layer. That usually means:

  • duplicated structure
  • duplicated styling decisions
  • drift between web and PDF output
  • accessibility bugs that only exist in the export path

This demo argues for a cleaner split:

  • keep document semantics in Django templates, where the team already works
  • reuse those semantics for both the web UI and the export path
  • let Fullbleed turn that HTML into a tagged PDF instead of rebuilding the document in a separate PDF-only layer

That gives the team one place to review structure and accessibility.

Accessibility story

The shared account-summary partial is intentionally semantic:

  • it uses a real article with nested header and section structure
  • heading order is explicit (h1 followed by h2 sections)
  • the charge breakdown is a proper data table with a caption, column headers, row headers, and a footer total
  • contact information uses address
  • notes stay in the same reading order for both screen and export paths

When that structure is passed to Fullbleed, the PDF route preserves the same document logic instead of inventing a second one.

Real Fullbleed integration details

The service layer uses Fullbleed directly:

from fullbleed import PdfEngine

engine = PdfEngine(
    document_title=request.document_title,
    document_lang="en",
    pdf_profile="tagged",
    margin="0.5in",
    footer_each="Generated with Fullbleed — Page {page} of {pages}",
    footer_font_size=8,
    footer_color="#5d6873",
    footer_y_from_bottom="0.25in",
)

pdf_bytes = engine.render_pdf(request.html, request.css)

The demo also runs verify_pdf_ua_seed() on the generated PDF and returns the result through the X-Fullbleed-Seed-Verify response header.

Important Fullbleed implementation note

Fullbleed expects HTML and CSS as separate inputs. It does not consume embedded <style> blocks from the HTML payload. That is why this demo renders:

  • account_summary_pdf.html
  • account_summary_pdf.css

separately before calling the engine.

That detail is easy to miss and worth preserving in any real integration.

Data model and fixture

The demo uses one small model pair:

  • AccountSummary
  • ChargeLineItem

The fixture lives at billing/fixtures/demo.json and seeds a realistic account summary for Northwind Analytics.

Running the demo

python3 -m pip install -r requirements.txt
python3 manage.py migrate
python3 manage.py loaddata billing/fixtures/demo.json
python3 manage.py runserver

Then open:

  • http://127.0.0.1:8000/
  • http://127.0.0.1:8000/accounts/northwind-analytics/
  • http://127.0.0.1:8000/accounts/northwind-analytics/export/pdf/

The PDF route should download a real tagged PDF.

Tests

python3 manage.py test

The test suite checks that:

  • the overview page renders
  • the browser page renders shared content
  • the PDF route returns application/pdf
  • the response advertises X-Fullbleed-Pdf-Profile: tagged
  • the seed verification passes

Why I like this pattern

It gives Django teams a clean division of labor:

  • Django templates remain the source of truth for document structure
  • Fullbleed handles the hard PDF-specific problems
  • accessibility is reviewed once at the semantic HTML layer instead of in parallel rendering stacks

That makes the Fullbleed pitch to Django developers much clearer: use the same accessible component/template thinking for the page your users see and the PDF they download.

About

Django sample showing one semantic template powering both the browser UI and a tagged Fullbleed PDF export.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages