source: main/trunk/greenstone3/web/interfaces/default/transform/pages/document-iiif-manifest.xsl@ 37090

Last change on this file since 37090 was 37090, checked in by davidb, 16 months ago

Adding in a sub-action to will generate IIIF-Manifest JSON based on a GS document. The XSLT can operate from within a standard install of Greenstone. To be fully functional, however, it expects the iiif-sevlet GS3 extension to be installed. This is because some of the 'id' fields generated in the produced JSON are URL links to serve up images via a IIIF-Image compliant server

File size: 11.0 KB
Line 
1<?xml version="1.0" encoding="UTF-8"?>
2<xsl:stylesheet version="1.0"
3 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
4 xmlns:java="http://xml.apache.org/xslt/java"
5 xmlns:util="xalan://org.greenstone.gsdl3.util.XSLTUtil"
6 xmlns:gslib="http://www.greenstone.org/skinning"
7 xmlns:gsf="http://www.greenstone.org/greenstone3/schema/ConfigFormat"
8 extension-element-prefixes="java util"
9 exclude-result-prefixes="java util gsf">
10
11 <!--
12 Key goal: generate a IIIF v2 compliant manifest file in JSON format based on the document
13 -->
14
15 <!-- Similar in spirit to document.xsl (catering for 'simple' and complex document structures such as 'pages'),
16 but considerably tailored down to produce the raw IIIF-manifest JSON format:
17 (i) focus on just the (potientailly hierachically nested) pages
18 (ii) so a bit like ed=1, but implied rather than needing to be set
19 -->
20
21 <!-- **** this only defines xsl-variables => change filename? -->
22 <xsl:include href="layouts/header-core.xsl"/>
23
24 <xsl:include href="pages/document-shared.xsl" />
25 <!-- **** this only defines xsl-variables => change filename? -->
26 <xsl:include href="pages/document-core.xsl" />
27
28
29 <xsl:output method="html" version="1.0" encoding="utf-8"/>
30
31 <!--
32 <xsl:output method="text" version="1.0" encoding="utf-8" omit-xml-declaration="yes"/>
33 <xsl:strip-space elements="*"/>
34 -->
35
36
37 <xsl:variable name="iiifPresentationRootIdentifier">http-greenstone://<xsl:value-of select="$site_name"/>/<xsl:value-of select="$collNameChecked"/>/<xsl:value-of select="$docID"/></xsl:variable>
38
39 <xsl:template match="/">
40 <html>
41 <body>
42 <pre>
43 <xsl:apply-templates select="/page/pageResponse/document" />
44 </pre>
45 </body>
46 </html>
47
48 </xsl:template>
49
50 <xsl:template match="/page/pageResponse/document">
51 <!-- display the document -->
52 <xsl:choose>
53 <xsl:when test="@docType='simple'">
54 <xsl:call-template name="documentContent"/>
55 </xsl:when>
56 <xsl:otherwise> <!-- kick off the recursive call for a more complex structured document-->
57 <xsl:call-template name="wrappedDocumentTopLevel"/>
58 </xsl:otherwise>
59 </xsl:choose>
60 </xsl:template>
61
62
63 <xsl:template name="wrappedDocumentTopLevel">
64
65 <!-- <xsl:call-template name="documentPre"/> -->
66 <xsl:call-template name="wrappedDocument"/> <!-- without ed=1, this template misses the binds in of documentPre and documentPost -->
67 <!-- <xsl:call-template name="documentPost"/> -->
68
69 </xsl:template>
70
71
72 <xsl:template name="wrappedDocument">
73
74 <xsl:call-template name="documentPre"/>
75 <xsl:for-each select="documentNode">
76 <xsl:call-template name="wrapDocumentNodes"/>
77 </xsl:for-each>
78 <xsl:call-template name="documentPost"/>
79
80 </xsl:template>
81
82
83 <xsl:template name="iiif-other-content">
84 <xsl:param name="optSection"/>
85
86 <xsl:variable name="baseURL">https:<xsl:value-of select="/page/pageRequest/@baseURL"/></xsl:variable> <!-- **** had to hardwire https: -->
87 <!-- **** test for a gsf-option before include !!!! -->
88 "otherContent": [{
89 "@id": "<xsl:value-of select="$baseURL"/><xsl:value-of select="$library_name"/>/sites/<xsl:value-of select="$site_name"/>/collect/<xsl:value-of select="$collNameChecked"/>/index/assoc/<gsf:metadata name="assocfilepath" select="root"/>/openannotation-list<xsl:value-of select="$optSection"/>.json",
90 "@type": "sc:AnnotationList"
91 }],
92 </xsl:template>
93
94
95 <xsl:template name="iiif-canvas-image">
96 <xsl:param name="identifier"/>
97 <xsl:param name="docType"/>
98
99 <xsl:variable name="iiifImageRootIdentifier">
100 <xsl:text>/gs-cantaloupe/iiif/2/</xsl:text><xsl:value-of select="$site_name"/>:<xsl:value-of select="$collNameChecked"/>:<xsl:value-of select="$identifier"/>
101 </xsl:variable>
102
103 <!-- page/pageRequest[@baseURL]="//intermuse.sowemustthink.space/greenstone3/ -->
104 <!-- page/pageRequest[@fullURL]="//intermuse.sowemustthink.space/greenstone3/library?a=d.... -->
105
106 <!-- ***** need to work out domain name to use from raw XML message, say processing something from the above -->
107
108 <xsl:variable name="document-location-origin">https://intermuse.sowemustthink.space</xsl:variable>
109
110 <xsl:variable name="section"><xsl:value-of select="position()" /></xsl:variable>
111 <xsl:variable name="optSection">
112 <xsl:choose>
113 <xsl:when test="$docType = 'simple'"></xsl:when><!-- i.e. empty -->
114 <xsl:otherwise><xsl:value-of select="position()" /></xsl:otherwise>
115 </xsl:choose>
116 </xsl:variable>
117
118
119 <xsl:variable name="chosenTitle">
120 <xsl:choose>
121 <xsl:when test="$docType = 'simple'">
122 <xsl:call-template name="choose-title"/>
123 </xsl:when>
124 <xsl:otherwise>page <xsl:value-of select="$section"/></xsl:otherwise>
125 </xsl:choose>
126 </xsl:variable>
127
128 <!-- The following is useful for debugging, nested in 'pre' tags -->
129 <!--
130 docType = <xsl:value-of select="$docType"/>
131 docID = <xsl:value-of select="$docID"/>
132 position = <xsl:value-of select="position()" />
133
134 identifer = <xsl:value-of select="$identifier"/>
135 section = <xsl:value-of select="$section"/>
136 optSection = <xsl:value-of select="$optSection"/>
137
138 iiifPresRootIdentifier = <xsl:value-of select="$iiifPresentationRootIdentifier" />
139 iiifImageRootIdentifier = <xsl:value-of select="$iiifImageRootIdentifier" />
140 -->
141 <!-- an array entry in 'canvases': { @content, @id, @type, label, width, height, images[{}], thumbnail {@id,@type} } -->
142 <!-- add a comma first, if it is not the first canvas element in the array -->
143 <xsl:if test="$section &gt; 1">
144 ,
145 </xsl:if>
146 {
147 "@context": "http://iiif.io/api/presentation/2/context.json",
148 "@id": "<xsl:value-of select="$iiifPresentationRootIdentifier" />/canvas/<xsl:value-of select="$section"/>",
149 "@type": "sc:Canvas",
150 "label": "<xsl:value-of select="$chosenTitle"/>",
151 <xsl:call-template name="iiif-other-content">
152 <xsl:with-param name="optSection"><xsl:value-of select="$optSection"/></xsl:with-param>
153 </xsl:call-template>
154 &quot;width&quot;: <gsf:metadata name="ImageWidth"/>,
155 &quot;height&quot;: <gsf:metadata name="ImageHeight"/>,
156
157 "images": [{
158 "image": {
159 "@context": "http://iiif.io/api/image/2/context.json",
160 "@type": "oa:Annotation",
161 "motivation": "sc:painting",
162 "on": "<xsl:value-of select="$iiifPresentationRootIdentifier" />/annotation/<xsl:value-of select="$section"/>",
163
164 "resource": {
165 "@id": "<xsl:value-of select="$document-location-origin" /><xsl:value-of select="$iiifImageRootIdentifier" />/full/full/0/default.jpg",
166 "@type": "dctypes:Image",
167 "format": "image/jpeg",
168 "width": <gsf:metadata name="ImageWidth"/>,
169 "hieght": <gsf:metadata name="ImageHeight"/>,
170 "service": {
171 "@context": "http://iiif.io/api/image/2/context.json",
172 "@id": "<xsl:value-of select="$document-location-origin" /><xsl:value-of select="$iiifImageRootIdentifier" />",
173 "profile": "https://iiif.io/api/image/2/profiles/level2.json"
174 }
175 }
176 }
177 }],
178 "thumbnail": {
179 "@id": "<xsl:value-of select="$document-location-origin" /><xsl:value-of select="$iiifImageRootIdentifier" />/full/,150/0/default.jpg",
180 "@type": "dctypes:Image"
181 }
182 }
183 <!-- Another field to consider in the above JSON is: -->
184 <!-- "format": mime_type, // ???? or is it OK to always have this as image/jpeg and rely on IIIF Image Server coverting as/when needed??? -->
185 </xsl:template>
186
187
188 <xsl:template name="wrappedSectionPost">
189
190 <!-- add in IIIF Server link for section image -->
191 <xsl:variable name="nodeID" select="@nodeID"/>
192 <xsl:call-template name="iiif-canvas-image">
193 <xsl:with-param name="identifier" select="$nodeID" />
194 <xsl:with-param name="docType" select="@docType" />
195 </xsl:call-template>
196 </xsl:template>
197
198 <xsl:template name="sectionImage">
199 <!-- don't need this template to generate anything in the IIIF-Manifest JSON case -->
200 </xsl:template>
201
202 <xsl:template name="sectionContent">
203 <xsl:call-template name="wrappedSectionPost"/>
204 </xsl:template>
205
206
207 <xsl:template name="documentPre">
208 <xsl:variable name="httpCollection">library/sites/<xsl:value-of select="$site_name"/>/collect/<xsl:value-of select="/page/pageResponse/collection/@name"/></xsl:variable>
209
210 <xsl:variable name="chosenTitle">
211 <xsl:choose>
212 <xsl:when test="@docType='simple'">
213 <xsl:call-template name="choose-title"/>
214 </xsl:when>
215 <xsl:otherwise>
216 <xsl:value-of disable-output-escaping="yes" select="/page/pageResponse/document/documentNode/metadataList/metadata[@name='Title']" />
217 </xsl:otherwise>
218 </xsl:choose>
219 </xsl:variable>
220
221 <!-- start of iiif_manifest: -->
222 {
223 "@context": "http://iiif.io/api/presentation/2/context.json",
224 "@type": "sc:Manifest",
225 "@id": "<xsl:value-of select="$iiifPresentationRootIdentifier"/>/manifest",
226 "label": "<xsl:value-of select="$chosenTitle"/>",
227 "attribution": "The Internet of Musical Events (InterMusE): Digital Scholarship, Community, and the Archiving of Performance",
228 "license": "https://**** To Be Determined ****",
229 "logo": "https://intermuse.datatodata.org/wp-content/uploads/sites/4/2021/03/cropped-cropped-cropped-1.png",
230 "metadata": [
231 { "label": "creator", "value": ["aaa1","aaa2"] },
232 { "label": "title", "value": ["chosen-title"] }
233 ],
234 <!-- trival IIIF sequences => has one IIIF canvas in it -->
235 "sequences": [{
236 "@context": "http://iiif.io/api/image/2/context.json",
237 "@id": "<xsl:value-of select="$iiifPresentationRootIdentifier"/>/sequence/normal",
238 "@type": "sc:Sequence",
239 "canvases": [
240
241 </xsl:template>
242
243
244 <xsl:template name="documentContentSimpleIIIFImage">
245 <xsl:call-template name="iiif-canvas-image">
246 <xsl:with-param name="identifier" select="$docID" />
247 <xsl:with-param name="docType" select="@docType" />
248 </xsl:call-template>
249 </xsl:template>
250
251 <xsl:template name="documentContent">
252 <!-- The way document.xsl templates are structured, only get to here is if @docType = 'simple' -->
253 <!-- A 'paged' (or 'hierarical') document goes throgh 'wrappedContent' -->
254 <xsl:call-template name="documentPre"/>
255 <xsl:call-template name="documentContentSimpleIIIFImage"/>
256 <xsl:call-template name="documentPost"/>
257 </xsl:template>
258
259
260 <xsl:template name="wrapDocumentNodes">
261
262 <xsl:call-template name="sectionContent"/>
263
264 <xsl:if test="documentNode">
265 <xsl:for-each select="documentNode">
266 <xsl:call-template name="wrapDocumentNodes"/>
267 </xsl:for-each>
268 </xsl:if>
269 </xsl:template>
270
271 <xsl:template name="wrappedSectionImage">
272 <!-- don't need this template to generate anything in the IIIF-Manifest JSON case -->
273 </xsl:template>
274
275
276
277 <xsl:template name="documentPost">
278 <!-- end of iiif_manifest: -->
279 <!-- close of canvases, then close higher level blocks to complete the JSON file -->
280 ]
281 }]
282 }
283
284 </xsl:template>
285
286
287</xsl:stylesheet>
Note: See TracBrowser for help on using the repository browser.