Show, don’t tell
In this section we are going to build a lightweight static version of Die Ministerratsprotokolle 1848–1918
uvx cookiecutter gh:acdh-oeaw/dse-static-cookiecutter
mrp-staticDie Ministerratsprotokolle 1848–1918 (statisch)MRP (statisch)deacdh-tool-galleryhttps://github.com/acdh-tool-gallery/mrp-statichttps://acdh-tool-gallery.github.io/mrp-static/187161ymrp-datahttps://github.com/acdh-tool-gallery/mrp-datamrp-static./fetch_data.sh to download the data from https://github.com/acdh-tool-gallery/mrp-data into the current projectant to build the website, i.e. converting TEI/XML-Documents into HTML-Fileshtml and start a webserver
cd html && python -m http.server
mrp-static same as your answer to Question 1/12mrp-static folder git init
git add --all
git commit -a -m "init commit"
git branch -M main
git remote add origin https://github.com/acdh-tool-gallery/mrp-static.git
git push -u origin main
this takes a short while because many files need to be processed/uploaded
GitHub ActionsThis section exemplifies some basic development best practices
e.g. https://acdh-tool-gallery.github.io/mrp-static/toc.html makes not much sense
<titleStmt>
<title level="s" type="desc">Digitale Edition</title>
<title level="s" type="main" n="3">Die Protokolle des cisleithanischen Ministerrates 1867–1918</title>
<title level="s" type="main" n="0"/>
<title level="a" type="desc" n="044">Nr. 44 Ministerrat (19. Februar 1867–15. Dezember 1867)</title>
<title level="m" type="main">Band I: 1867</title>
<title level="m" type="main" n="01">Band 1</title>
<title level="m" type="sub" n="0"/>
<title level="m" type="sub">19. Februar 1867–15. Dezember 1867</title>
<title level="m" type="dates" from="1867-02-19" to="1867-12-15"/>
<meeting>
<placeName>Wien</placeName>
<orgName>Ministerrat</orgName>
<date when="1867-08-16">1867-08-16</date>
</meeting>
</titleStmt>
<title level="a" type="desc" n="044">Nr. 44 Ministerrat (19. Februar 1867–15. Dezember 1867)</title> (actually created beforehand for this tool-gallery)mrp-static.xpr and open itxslt/toc.xsl<xsl:value-of select=".//tei:titleStmt/tei:title[1]/text()"/> -> <xsl:value-of select=".//tei:titleStmt/tei:title[@level='a']/text()"/>data/imprint.xml| click on the wrench symbol (or Document » Transformation » Apply | Configure Transformation Scenario) |
using a more recent Saxon processor `
<xsl:variable name="full_path">
<xsl:value-of select="document-uri(/)"/>
</xsl:variable>
with
<xsl:variable name="docId">
<xsl:value-of select="document-uri(/)"/>
</xsl:variable>
<xsl:value-of select="replace(tokenize($full_path, '/')[last()], '.xml', '.html')"/>
with
<xsl:value-of select="$docId"/>`
xslt/editions.xsl <xsl:variable name="doc_title">
<xsl:value-of select=".//tei:titleStmt/tei:title[1]/text()"/>
</xsl:variable>
with
<xsl:variable name="doc_title">
<xsl:value-of select=".//tei:titleStmt/tei:title[@level='a']/text()"/>
</xsl:variable>
data/editions/MRP-3-0-01-0-18670219-P-0001.xml and hit strg+shift+T (apply Transformation Scenario)
xslt/partials/html_footer.xsl by replacing existing `<footer></footer> with the snippet below
<footer class="footer mt-auto py-3 bg-body-tertiary">
<div class="container-fluid pt-2">
<div class="row justify-content-center">
<div class="col-lg-1 col-md-2 col-sm-2 col-xs-6 text-center">
<div>
<a href="https://www.oeaw.ac.at/acdh/">
<img src="images/logo.png" class="footer-logo" alt="ACDH Logo" title="ACDH Logo" />
</a>
</div>
</div>
<div class="col-lg-4 col-md-3 col-sm-3">
<div>
<p>
ACDH
<br />
Austrian Centre for Digital Humanities
<br />
Österreichische Akademie der Wissenschaften
</p>
<p>
Bäckerstraße 13
<br />
1010 Wien
</p>
<p>
T: +43 1 51581-2200
<br />
E: <a href="mailto:acdh-helpdesk@oeaw.ac.at">acdh-helpdesk@oeaw.ac.at</a>
</p>
</div>
</div>
<div class="col-lg-3 col-md-4 col-sm-3">
<div class="row">
<div>
<span class="fs-6">HELPDESK</span>
<br />
<p>ACDH betreibt einen Helpdesk mit Rat und Hilfestellung zu verschiedensten Fragen der Digital
Humanities.
</p>
<p>
<a href="mailto:acdh-helpdesk@oeaw.ac.at">e-Mail</a>
</p>
</div>
</div>
<div class="row">
<div class="col-lg-3 col-md-4 col-sm-3">
<div class="col-md-4">
<a id="github-logo" title="GitHub" href="{$github_url}" class="nav-link" target="_blank">
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24">
<path
d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-4.466 19.59c-.405.078-.534-.171-.534-.384v-2.195c0-.747-.262-1.233-.55-1.481 1.782-.198 3.654-.875 3.654-3.947 0-.874-.312-1.588-.823-2.147.082-.202.356-1.016-.079-2.117 0 0-.671-.215-2.198.82-.64-.18-1.324-.267-2.004-.271-.68.003-1.364.091-2.003.269-1.528-1.035-2.2-.82-2.2-.82-.434 1.102-.16 1.915-.077 2.118-.512.56-.824 1.273-.824 2.147 0 3.064 1.867 3.751 3.645 3.954-.229.2-.436.552-.508 1.07-.457.204-1.614.557-2.328-.666 0 0-.423-.768-1.227-.825 0 0-.78-.01-.055.487 0 0 .525.246.889 1.17 0 0 .463 1.428 2.688.944v1.489c0 .211-.129.459-.528.385-3.18-1.057-5.472-4.056-5.472-7.59 0-4.419 3.582-8 8-8s8 3.581 8 8c0 3.533-2.289 6.531-5.466 7.59z">
</path>
</svg>
</a>
</div>
</div>
</div>
</div>
<!-- .-->
</div>
<div class="text-center fs-6 fw-lighter">© Copyright OEAW | <a href="imprint.html">Imprint</a>
</div>
</div>
</footer>
html/css/style.css by adding
.footer-logo {
max-width: 50%;
max-height: 150px;
}
xslt/index.xsl<main> ... </main>
with
<main class="flex-shrink-0 flex-grow-1">
<div class="container col-xxl-8 pt-3">
<div class="row flex-lg-row align-items-center g-5 py-5">
<div class="col-lg-6">
<h1 class="lh-base">
<span class="display-6"><xsl:value-of select="$project_short_title"/></span>
<br/>
<span class="display-5"><xsl:value-of select="$project_title"/></span>
</h1>
<p class="text-end">Demo Applikation, erstellt für die ACDH Tool-Gallery 11.3</p>
<p class="lead"> Die Daten stammen von: Stephan Kurz. (2024). oeaw-ministerratsprotokolle/mp-edition-data: v. 1.5 including CMR calendar data 1872–1914 (v.1.5). Zenodo. <a href="https://doi.org/10.5281/zenodo.11484662">https://doi.org/10.5281/zenodo.11484662</a></p>
<div class="d-grid gap-2 d-md-flex justify-content-md-start">
<a href="search.html" type="button" class="btn btn-primary btn-lg px-4 me-md-2">Volltextsuche</a>
<a href="toc.html" type="button" class="btn btn-outline-primary btn-lg px-4">Zu den Protokollen</a>
</div>
</div>
<div class="col-10 col-sm-8 col-lg-6">
<figure class="figure">
<img src="images/title-image.jpg" class="d-block mx-lg-auto img-fluid" alt="Friedrich Ferdinand Freiherr von Beust, via Wikimedia Commons" width="400" height="600" loading="lazy"/>
<figcaption class="pt-3 figure-caption">Friedrich Ferdinand Freiherr von Beust um 1860; von Autor/-in unbekannt - <a rel="nofollow" class="external free" href="http://www.aeiou.at/aeiou.encyclop.data.image.b/b417372a.jpg">http://www.aeiou.at/aeiou.encyclop.data.image.b/b417372a.jpg</a>, Gemeinfrei, <a href="https://commons.wikimedia.org/w/index.php?curid=1326691">Link</a></figcaption>
</figure>
</div>
</div>
</div>
</main>
html/images/title-image.jpg
e.g. running
curl -L "https://upload.wikimedia.org/wikipedia/commons/thumb/1/12/Friedrich_Ferdinand_von_Beust_1860.jpg/594px-Friedrich_Ferdinand_von_Beust_1860.jpg?download" -o html/images/title-image.jpg
git add --all
git commit -a -m "feat(design): landing page"
git push origin main
Some answers from the initialisation process are stored in xslt/partials/params.xsl.
<xsl:param name="project_short_title">MRP (statisch)</xsl:param>
with
<xsl:param name="project_short_title">MRP</xsl:param>
index.htmlMRP (statisch) -> MRPExpose metadata via HTML-Meta tags for Zotero
xslt/partials/zotero.xsl
<xsl:template name="zoterMetaTags">...</xsl:template>
with
<xsl:template name="zoterMetaTags">
<xsl:param name="zoteroTitle" select="false()"></xsl:param>
<xsl:param name="pageId" select="''"></xsl:param>
<xsl:param name="customUrl" select="$base_url"></xsl:param>
<xsl:variable name="fullUrl" select="concat($customUrl, $pageId)"/>
<xsl:if test="$zoteroTitle">
<meta name="citation_title" content="{$zoteroTitle}"/>
</xsl:if>
<meta name="citation_editors" content="Franz Adlgasser; Anatol Schmied-Kowarzik"/>
<meta name="citation_publisher" content="Österreichische Akademie der Wissenschaften"/>
<meta name="citation_book_title" content="{$project_title}"/>
<meta name="citation_public_url" content="{$fullUrl}"/>
<meta name="citation_date" content="2025"/>
</xsl:template>
data/editions/MRP-3-0-01-0-18670301-P-0006.xml
<editor key="http://d-nb.info/gnd/109427793" role="editor" ref="#editor_Malfer">
<persName>
<forename>Stefan</forename>
<surname>Malfèr</surname>
</persName>
<affiliation key="http://d-nb.info/gnd/1202798799" from="2020-01-01">Österreichische Akademie der Wissenschaften, Institute for Habsburg and Balkan Studies</affiliation>
<affiliation key="http://d-nb.info/gnd/1047201437" to="2019-12-31">Österreichische Akademie der Wissenschaften, Institut für Neuzeit- und Zeitgeschichtsforschung</affiliation>
<!-- Legacy Doppelung nur bei Malfèr, weil da das Institut noch INZ hieß -->
</editor>
editions.xsl and replace
<!-- Provide the names of the authors/editors of the current unit, ideally fetched from the data via xslt or hard coded as below -->
<meta name="citation_author" content="Foo, Bar"/>
<meta name="citation_author" content="Bar, Foo"/>
with
<xsl:for-each select=".//tei:titleStmt/tei:editor/tei:persName">
<meta name="citation_author" content="{string-join(.//text())}"/>
</xsl:for-each>
data/editions/MRP-3-0-01-0-18670301-P-0006.xml with xslt/editions.xsl (ant)Stefan Malfèr / Franz Adlgasser / Anatol Schmied-Kowarzik: Nr. 1 Ministerrat (19. Februar 1867–15. Dezember 1867). In: MRP (statisch). 2025. [https://acdh-tool-gallery.github.io/mrp-static/MRP-3-0-01-0-18670219-P-0001.html]
xslt/listperson.xsldata/indices/listperson.xmldata/indices/listperson.xml
<person xml:id="mpr2049">xslt/listperson.xsl
<th scope="col" tabulator-headerFilter="input">Tätigkeit</th>
<th scope="col" tabulator-headerFilter="input">Erwähnungen</th>
<td>
<xsl:value-of select="string-join(.//tei:occupation, ', ')"/>
</td>
<td>
<xsl:value-of select="count(.//tei:noteGrp/tei:note[@type='mentions'])"/>
</td>
[!IMPORTANT]
Denormalisation! Make sure that your data provides the information needed to link from an index file to the actual mentions.
xslt/listperson.xsl change
<xsl:if test="./tei:noteGrp/tei:note[@type = 'mentions']">
<dt>Erwähnt in</dt>
<dd>
<xsl:for-each select="./tei:noteGrp/tei:note[@type = 'mentions']">
<a href="{replace(@target, '.xml', '.html')}">
<xsl:value-of select="./text()"/>
</a>
</xsl:for-each>
</dd>
</xsl:if>
to
<xsl:if test="./tei:noteGrp/tei:note[@type = 'mentions']">
<dt>Erwähnt in</dt>
<xsl:for-each select="./tei:noteGrp/tei:note[@type = 'mentions']">
<dd>
<a href="{replace(@target, '.xml', '.html')}">
<xsl:value-of select="./text()"/>
</a>
</dd>
</xsl:for-each>
</xsl:if>
<dl> by adding
dd {
margin-left: 1rem;
}
to html/css/style.css
pyscripts/make_ts_index.py if it fits your data
record["title"] = doc.any_xpath(".//tei:titleStmt/tei:title[1]")[0].text
with
record["title"] = doc.any_xpath(".//tei:titleStmt/tei:title[@level='a']")[0].text
pyproject.toml)uv run pyscripts/make_ts_index.py from mrp-static docker run -d -p 80:80 ghcr.io/bfritscher/typesense-dashboard:latest
- name: Build the app
run: ant
- name: Setup Pages
with
- name: Build the app
run: ant
- name: Create search index
run: python pyscripts/make_ts_index.py
- name: Setup Pages
TYPESENSE_API_KEY
Once the index is created, we can create a search page in our website. The search page is created using instantsearch.js and typesense-instantsearch-adapter
mrp-static
companies with mrp-static
directory_name you provided on initializationhtml/js/search.js
const apiKey = "0drlT8CHD6T9z8QxQjYXvSWT2dZ75nPv"; /* change this */
with
const apiKey = "the new key"; /* change this */
Error: 404 - Could not find a facet field named
bibl_entities.labelin the schema.Error: 404 - Could not find a facet field named
bibl_entities.labelin the schema.
html/js/search.jsbibl_entities ${hit.bibl_entities.map(
(item) =>
html`<a href="${item.id}.html" class="pe-2 custom-link"><i class="bi bi-book pe-1"></i>${item.label}</a>`
)}
<br />
...
instantsearch.widgets.panel({
collapsed: ({ state }) => {
return state.query.length === 0;
},
templates: {
header: "Literatur",
},
})(instantsearch.widgets.refinementList)({
container: "#rf-works",
attribute: "bibl_entities.label",
searchable: true,
showMore: true,
showMoreLimit: 50,
limit: 10,
searchablePlaceholder: "Suche nach Literatur",
cssClasses: DEFAULT_CSS_CLASSES,
}),
dse-static-cookiecutter tries to follow three principles static, automatic, generic so that your edition can be kept online forever.
No database, no application server needed; easy to host/maintain (just a bunch of HTML files)
All code needed to process, build, deploy should be managed by a single script/file; no more “But it runs on my machine”. This is achieved by .github/workflows/build.yml and as backup by docker/Dockerfile
cookiecutter is used to create a similar starting point for your individual application. The idea is: You know one, you know all

