Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
9a83fa5
Updated link
leontpng Aug 21, 2025
9ecf57f
Added recipe to index.
leontpng Sep 4, 2025
bd73b91
Added recipe 27
leontpng Sep 4, 2025
a806ffb
Update all sections
leontpng Sep 5, 2025
3e1d602
Merge pull request #632 from leontpng/master
leontpng Sep 9, 2025
49684ac
Merge branch 'master' into 0027-alternative-page-order
glenrobson Sep 15, 2025
577a9dd
Update manifest
leontpng Sep 16, 2025
8560805
Change title order to sequences
giacomomarchioro Sep 18, 2025
c5c54c7
Merge pull request #639 from giacomomarchioro/patch-1
giacomomarchioro Sep 18, 2025
f75bea2
Pos editors edit
giacomomarchioro Sep 18, 2025
a0638ce
Merge pull request #640 from giacomomarchioro/patch-2
glenrobson Sep 18, 2025
6b288ee
Merge branch 'master' into 0027-alternative-page-order
glenrobson Sep 18, 2025
5857c86
Updated Example
leontpng Oct 10, 2025
8142e8b
Updated manifest images
leontpng Oct 10, 2025
448a12e
Fixed manifest
leontpng Oct 10, 2025
b7ae3e3
Updated index
leontpng Oct 10, 2025
bb79130
Updated index
leontpng Oct 14, 2025
08d9201
Updated manifest
leontpng Oct 14, 2025
966dc22
Renamed recipe
leontpng Oct 15, 2025
5460d65
Renamed recipe
leontpng Oct 15, 2025
76a7c7f
Renamed recipe 27
leontpng Oct 15, 2025
9367c1d
Renamed recipe 27
leontpng Oct 15, 2025
4ebd91e
Update index.md
leontpng Nov 13, 2025
260646f
Update manifest.json
leontpng Nov 13, 2025
861dc34
Update index.md
leontpng Nov 14, 2025
37a52d0
Update manifest.json
leontpng Nov 14, 2025
3f166a0
Merge pull request #650 from leontpng/0027-alternative-page-order
leontpng Nov 16, 2025
66b40ce
Merge branch 'master' into 0027-alternative-page-order
glenrobson Nov 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions _includes/links.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
[0035]: {{site.baseurl}}/recipe/0035-foldouts/ "Foldouts, Flaps, and Maps"
[0036]: {{site.baseurl}}/recipe/0036-composition-from-multiple-images/ "Composition from Multiple Images"
[0026]: {{ site.cookbook_url | absolute_url }}/recipe/0026-toc-opera/ "Table of Contents for A/V Content"
[0027]: {{ site.cookbook_url | absolute_url }}/recipe/0027-alternative-page-order/ "Alternative Page Sequence"
[0029]: {{ site.cookbook_url | absolute_url }}/recipe/0029-metadata-anywhere/ "Metadata on any Resource"
[0030]: {{ site.cookbook_url | absolute_url }}/recipe/0030-multi-volume/ "Multi-volume Work with Individually-bound Volumes"
[0031]: {{ site.cookbook_url | absolute_url }}/recipe/0031-bound-multivolume/ "Multiple Volumes in a Single Bound Volume"
Expand Down
2 changes: 1 addition & 1 deletion index.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ _(leading on to segmentation examples later)_
* table of contents (ranges) - articles in a newspaper
* [Table of contents for A/V content][0026] (26)
* [Adding Thumbnail Navigation and `no-nav` to a Video Resource][0229]
* Alternative Sequence (via `sequence` Range) (20,22,23)
* [Alternative Page Sequence][0027]
* `sequence` Range with partial canvases

## Higher-level structure
Expand Down
51 changes: 51 additions & 0 deletions recipe/0027-alternative-page-order/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
title: Alternative Page Order
id: 27
layout: recipe
tags: [book, presentation]
summary: "Using Ranges to offer alternative orderings of book pages."
viewers:
topic:
- structure
---

## Use Case

A book may contain pages in the incorrect order; for example, a codex which was rebound at some point in history may have certain folios or quires accidentally misplaced. You want to digitally represent the book object in its current order while offering users the option to browse its contents in the intended order.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you mention representing the book in its current order, then having intended order as the secondary option, but the example shows the reverse - should the example match the use case as described?


## Implementation Notes

In Presentation API 3.0, setting a Range's `behavior` value to `sequence` allows you to define a specific viewing order for Canvases that differs from the default order in the Manifest’s `items` property.
There may be more than one Range, each representing an alternative sequence of items (for example, alternative orderings of book pages). The `items` of each Range are an array of referenced Canvases. The first Range should act as the default ordering, and any additional Ranges should be available for the user to select.
For an IIIF viewer to display the selectable Ranges, each Range should have a `label`. Additionally, for the viewer to be able to use the provided Ranges for ordering purposes, they must have the `behavior` value `sequence`.

When `behavior` is set to `sequence`, "user interfaces that interact with this order should use the order within the selected Range, rather than the default order of items" ([Presentation API 3.0](https://iiif.io/api/presentation/3.0/#54-range)).
Furthermore, the behavior property can be assigned to a list containing, besides `sequence`, other valid behaviors listed on the [behaviors section of the Presentation API](https://iiif.io/api/presentation/3.0/#behavior). These behaviors will work in combination with any behaviors inherited from the parent Manifest.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The suggestion for other behavior properties was specifically about using paged or individuals to show that one can override the manifests behavior if resequencing affects the layout for some reason. As a general note about behavior being an array, I would probably remove it. Or, combine it with the paragraph below about viewingDirection and simply say that one can add the viewingDirection property and/or other behavior values to overwrite manifest values. As it is now, this bit it somewhat confusing.


Other properties of the Range, such as `viewingDirection`, can be set to control the intended visualization of the Range.

## Restrictions

Ranges with `behavior` set to `sequence` indicate that they define an alternative reading order. Therefore, they:
- "must be directly within the `structures` property of the Manifest, and must not be embedded or referenced within other Ranges" (see [Range section](https://iiif.io/api/presentation/3.0/#54-range)). This ensures that clients can easily locate all available sequences without traversing or resolving nested structures.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would put this up in the implementation section - this is just how it works, not a restriction.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good morning, and thank you for the feedback!
We included this in the Restrictions section because using Ranges for ordering purposes limits their use for other functionalities, such as a Table of Contents, which is also a common use case for book objects. We should probably make this more explicit.

- cannot have `thumbnail-nav` or `no-nav` behaviors.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this - it's not a restriction per se, just that if someone were to use no-nav the items wouldn't display. I'm not sure it needs to be mentioned as a restriction?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For clarity, we can move this to Implementation. We considered this a 'formal' restriction of the specification since sequence is disjoint with no-nav or thumbnail-nav and must not be used together.


## Example

These manuscript folios are an excerpt from the original draft of the 1895 novel _Piccolo mondo antico_ by novelist and Nobel Prize Nominee for Literature, Antonio Fogazzaro. The original autograph numbering in pen (384, 385, [386], 387) is incorrect, so archivists noted the correct reading order in pencil: 171r (387), 171v (384), 172r (385), 172v ([386]).

Two ranges are provided within the `structures` to represent this case study. From the two Ranges with the `behavior` value `sequence`, the first Range should be used as the navigation default, and the other should be selectable.

Images provided by permission of [Biblioteca Civica Bertoliana](https://www.bibliotecabertoliana.it/).

{% include manifest_links.html viewers="" manifest="manifest.json" %}

{% include jsonviewer.html src="manifest.json" config='data-line="200-261"' %}

## Related Recipes

* [Simple Manifest - Book][0009] shows an example where the order of the pages follows the order in the `items` property.
* [Table of Contents for Book Chapters][0024] shows how to use Ranges to create a table of contents rather than to represent alternative orders.

{% include acronyms.md %}
{% include links.md %}
262 changes: 262 additions & 0 deletions recipe/0027-alternative-page-order/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
{
"@context": "http://iiif.io/api/presentation/3/context.json",
"id": "{{ id.url }}",
"type": "Manifest",
"label": {
"en": [
"Alternative Page Order"
]
},
"provider": [
{
"id": "https://www.bibliotecabertoliana.it/",
"type": "Agent",
"label": {
"en": [
"Biblioteca Civica Bertoliana"
]
},
"homepage": [
{
"id": "https://www.bibliotecabertoliana.it/",
"type": "Text",
"label": {
"en": [
"Biblioteca Civica Bertoliana Homepage"
]
},
"format": "text/html"
}
],
"logo": [
{
"id": "https://www.bibliotecabertoliana.it/img/logo-bertoliana.png",
"type": "Image",
"format": "image/png",
"height": 346,
"width": 89
}
]
}
],
"items": [
{
"id": "{{ id.path }}/canvas/p1",
"type": "Canvas",
"label": {
"en": [
"171r (387)"
]
},
"height": 3184,
"width": 2156,
"items": [
{
"id": "{{ id.path }}/page/p1/1",
"type": "AnnotationPage",
"items": [
{
"id": "{{ id.path }}/annotation/p0001-image",
"type": "Annotation",
"motivation": "painting",
"body": {
"id": "https://iiif.io/api/image/3.0/example/reference/3ec31f43ce55cfcc076804c88c06aa43-CF-f0186r_aVISNK_387/full/max/0/default.jpg",
"type": "Image",
"format": "image/jpeg",
"height": 3184,
"width": 2156,
"service": [
{
"id": "https://iiif.io/api/image/3.0/example/reference/3ec31f43ce55cfcc076804c88c06aa43-CF-f0186r_aVISNK_387",
"type": "ImageService3",
"profile": "level1"
}
]
},
"target": "{{ id.path }}/canvas/p1"
}
]
}
]
},
{
"id": "{{ id.path }}/canvas/p2",
"type": "Canvas",
"label": {
"en": [
"171v (384)"
]
},
"height": 3184,
"width": 2156,
"items": [
{
"id": "{{ id.path }}/page/p2/1",
"type": "AnnotationPage",
"items": [
{
"id": "{{ id.path }}/annotation/p0002-image",
"type": "Annotation",
"motivation": "painting",
"body": {
"id": "https://iiif.io/api/image/3.0/example/reference/3ec31f43ce55cfcc076804c88c06aa43-CF-f0186v_aVISNK_384/full/max/0/default.jpg",
"type": "Image",
"format": "image/jpeg",
"height": 3184,
"width": 2156,
"service": [
{
"id": "https://iiif.io/api/image/3.0/example/reference/3ec31f43ce55cfcc076804c88c06aa43-CF-f0186v_aVISNK_384",
"type": "ImageService3",
"profile": "level1"
}
]
},
"target": "{{ id.path }}/canvas/p2"
}
]
}
]
},
{
"id": "{{ id.path }}/canvas/p3",
"type": "Canvas",
"label": {
"en": [
"172r (385)"
]
},
"height": 3184,
"width": 2156,
"items": [
{
"id": "{{ id.path }}/page/p3/1",
"type": "AnnotationPage",
"items": [
{
"id": "{{ id.path }}/annotation/p0003-image",
"type": "Annotation",
"motivation": "painting",
"body": {
"id": "https://iiif.io/api/image/3.0/example/reference/3ec31f43ce55cfcc076804c88c06aa43-CF-f0187r_aVISNK_385/full/max/0/default.jpg",
"type": "Image",
"format": "image/jpeg",
"height": 3184,
"width": 2156,
"service": [
{
"id": "https://iiif.io/api/image/3.0/example/reference/3ec31f43ce55cfcc076804c88c06aa43-CF-f0187r_aVISNK_385",
"type": "ImageService3",
"profile": "level1"
}
]
},
"target": "{{ id.path }}/canvas/p3"
}
]
}
]
},
{
"id": "{{ id.path }}/canvas/p4",
"type": "Canvas",
"label": {
"en": [
"172v ([386])"
]
},
"height": 3184,
"width": 2156,
"items": [
{
"id": "{{ id.path }}/page/p4/1",
"type": "AnnotationPage",
"items": [
{
"id": "{{ id.path }}/annotation/p0004-image",
"type": "Annotation",
"motivation": "painting",
"body": {
"id": "https://iiif.io/api/image/3.0/example/reference/3ec31f43ce55cfcc076804c88c06aa43-CF-f0187v_aVISNK_386/full/max/0/default.jpg",
"type": "Image",
"format": "image/jpeg",
"height": 3184,
"width": 2156,
"service": [
{
"id": "https://iiif.io/api/image/3.0/example/reference/3ec31f43ce55cfcc076804c88c06aa43-CF-f0187v_aVISNK_386",
"type": "ImageService3",
"profile": "level1"
}
]
},
"target": "{{ id.path }}/canvas/p4"
}
]
}
]
}
],
"structures": [
{
"id": "{{ id.path }}/range/r1",
"type": "Range",
"behavior": [
"sequence"
],
"label": {
"en": [
"Corrected Page Order"
]
},
"items": [
{
"id": "{{ id.path }}/canvas/p1",
"type": "Canvas"
},
{
"id": "{{ id.path }}/canvas/p2",
"type": "Canvas"
},
{
"id": "{{ id.path }}/canvas/p3",
"type": "Canvas"
},
{
"id": "{{ id.path }}/canvas/p4",
"type": "Canvas"
}
]
},
{
"id": "{{ id.path }}/range/r2",
"type": "Range",
"behavior": [
"sequence"
],
"label": {
"en": [
"Original Page Order"
]
},
"items": [
{
"id": "{{ id.path }}/canvas/p2",
"type": "Canvas"
},
{
"id": "{{ id.path }}/canvas/p3",
"type": "Canvas"
},
{
"id": "{{ id.path }}/canvas/p4",
"type": "Canvas"
},
{
"id": "{{ id.path }}/canvas/p1",
"type": "Canvas"
}
]
}
]
}
Loading