Contents Menu Expand Light mode Dark mode Auto light/dark, in light mode Auto light/dark, in dark mode Skip to content
djiiif 1.1
djiiif 1.1

Getting started

  • Installation
  • Quickstart

Guides

  • Profiles
  • Info and manifest documents
  • Serving IIIF documents from Django
  • Share links (Content State)
  • Richer manifests & collections
  • Harvestable streams (Change Discovery)
  • Annotations & search
  • Authorization (Auth Flow 2.0)
  • Django REST Framework

Reference

  • Settings reference
  • API reference
  • Changelog
Back to top
View this page

Annotations & search¶

These two paired features turn djiiif from “expose my images” into “expose my annotated corpus”: serve W3C Web Annotations (transcriptions, OCR, commentary) and let viewers search within an object. They share one annotation type, and configuring annotations gives you search for free.

djiiif ships no annotation model — storage stays yours (a Django model, an OCR sidecar, an external annotation server). You provide a backend callable; djiiif owns the spec-compliant HTTP surface.

Transcriptions & annotations¶

Manifests can reference W3C Web Annotations that viewers like Mirador overlay on the image. Point IIIF_ANNOTATIONS_BACKEND at a callable (identifier, request) yielding one annotation per item:

settings.py¶
IIIF_ANNOTATIONS_BACKEND = "myapp.iiif.annotations"
myapp/iiif.py¶
from urllib.parse import unquote

def annotations(identifier, request):
    name = unquote(identifier)
    for t in Transcription.objects.filter(photo__image=name):
        yield {"text": t.text, "xywh": t.region, "language": t.lang}

Each entry is a plain dict (or the Annotation dataclass) with text (a string, or a preformed body dict), and optional motivation (default "supplementing"), xywh, language, format, and id.

With the URLconf mounted, the page is served at /iiif/<identifier>/annotations/1, and the generated manifest’s canvas gains an annotations reference to it. Unset backend ⇒ 404.

Search inside your objects¶

When a manifest advertises a Content Search 2.0 service, viewers can search within the object and highlight matching regions. Point IIIF_SEARCH_BACKEND at a callable (identifier, q, request) yielding hits — each an annotation plus optional snippet context:

settings.py¶
IIIF_SEARCH_BACKEND = "myapp.iiif.search_ocr"
myapp/iiif.py¶
from urllib.parse import unquote

def search_ocr(identifier, q, request):
    name = unquote(identifier)
    for word in OcrWord.objects.filter(page__image=name, text__search=q):
        yield {
            "text": word.text,
            "canvas_id": f"{request.build_absolute_uri('/iiif/')}{identifier}/canvas/1",
            "xywh": f"{word.x},{word.y},{word.w},{word.h}",
            "exact": word.text, "before": word.prefix, "after": word.suffix,  # optional snippet
        }

The endpoint is /iiif/<identifier>/search?q=..., and serve_manifest advertises the SearchService2 automatically. A missing or empty q returns a valid empty page (never the whole corpus); unrecognized spec parameters (motivation/date/user) are echoed in the response’s ignored list.

Free search from your annotations¶

If you set IIIF_ANNOTATIONS_BACKEND but no IIIF_SEARCH_BACKEND, serve_search falls back to a case-insensitive substring match over your annotations — so serving transcriptions gives you working search with no extra code:

IIIF_ANNOTATIONS_BACKEND set, IIIF_SEARCH_BACKEND unset
        └── /iiif/<id>/search?q=…  →  substring match over annotations

A dedicated IIIF_SEARCH_BACKEND (e.g. Postgres full-text search) overrides the fallback. With neither set, the search URL 404s.

Note

Response shapes are pinned against the Content Search 2.0 spec, but viewer tolerance is the real conformance test — a quick Mirador smoke test is recommended before you rely on search in production.

Next
Authorization (Auth Flow 2.0)
Previous
Harvestable streams (Change Discovery)
Copyright © 2017–2026, Roger Howard
Made with Sphinx and @pradyunsg's Furo
On this page
  • Annotations & search
    • Transcriptions & annotations
    • Search inside your objects
    • Free search from your annotations