4. Configuration
All configuration is supplied at runtime — nothing deployment-specific is
packaged into the jar. The main file is config/application.yml; it points
to the other configuration files.
4.1. application.yml
Key |
Meaning |
|---|---|
|
PostgreSQL connection (URL, username, password). |
|
Elasticsearch connection (default |
|
Search engine: |
|
Directory of the persisted embedded index; unset = in-memory (rebuilt on every start). |
|
Language of the described material, as an IETF language tag (default
|
|
Path to |
|
Portal name, localizations and optional menu definition
( |
|
News shown on the portal home page ( |
|
Preconfigured favourite queries ( |
|
Facet — and search relevance — configuration
( |
|
Branding images served to the UI. |
|
Optional layout of the structured search results
( |
|
Optional citation forms and their scripts ( |
|
Optional directory of the images the portal serves by name: the record and field icons of the structured results, the pictures of the home page’s tiles, and thumbnails delivered by name. Several directories may be listed, separated by commas — a name is looked up in the order given, the first hit wins. Only plain file names are served, never paths. |
|
|
|
|
|
|
|
External help link shown in the default menu. |
|
Optional input-directory import — a file-based alternative to the Transfagent upload (see Operations). Unset = off. |
|
File storage of attachments and the working directory of the SOAP file transfer. |
|
Deep-zoom tile storage for large images: Transfagent generates the tile
pyramids, the portal unpacks them here on import and serves them at
|
|
Optional attribution of digital objects, shown as an overlay in the
viewer: a standing dedication line and license statements matched by the
object’s license code ( |
|
Directories the portal may serve referenced digital-object files from (files delivered as a path on a local/shared disk instead of being transferred). One directory or a comma-separated list; a referenced file outside them gets no URL and is never served. Unset (default) = local referenced files are not served at all. Externally hosted files (URL references) are unaffected — their URLs pass through to the client and the portal never touches the bytes. |
|
SOAP endpoint of the external Transform agent (file/format transformations). |
|
Optional subpath for standalone subpath deployments (see Installation). |
|
Optional separate port for the internal SOAP interfaces
( |
|
Optional network interface the |
4.2. types.yaml
The display and indexing model of description items (“item types”). For each
item type it defines the data type (STRING, ENUM, APU_REF,
INTEGER, UNITDATE, LINK, …), the Czech display label and the
indexing flags:
indexed— whether the item is written to the search index at all;fulltext— whether the item’s value participates in the general fulltext search (default: yes; see Search);nameVariant— marks the item as a variant name form of the record (the other names of an access point); its values rank just below the primary name (default: no; see Search).
Note
Values of ENUM items are not configured here and are not translated
by the portal: Transfagent delivers them as the text to display. Like record
names and descriptions they are content, so their language is the language
the source system recorded them in.
Important
types.yaml describes what the search index contains. Any change to
its indexed fields is detected at startup and triggers an automatic
rebuild and reindex (see Operations). Weight tuning does not
belong here — see the relevance section of searchConfig.yaml.
4.3. Translating configured text
Text a deployment writes into its configuration — item labels, the portal name,
facet titles — is translated in a sibling file: next to <config>.yaml
put <config>_localization.yaml. The configured file keeps one language, the
source language, which stays the fallback; further languages are added without
touching it. Every such file is optional, so a deployment that adds none behaves
exactly as before.
Sibling file |
Translates |
|---|---|
|
Labels of part types and item types ( |
|
Facet |
|
Portal name ( |
The one exception is footer links, whose labels are written inline in
pageTemplate.yaml (label: {cs: …, en: …}): a link is identified by its
URL rather than by a code, so there is no stable key a sibling file could use.
types_localization.yaml
Translations of the display labels in types.yaml.
partTypes:
en:
PT_TITLE: Title
itemTypes:
en:
TITLE_MAIN: Main title
Codes are written in the underscore form used in types.yaml. The language
keys should match the localizations declared in pageTemplate.yaml —
those are the languages clients may ask for.
searchConfig_localization.yaml
Display texts of the facets, keyed by the facet’s source code exactly as
written in searchConfig.yaml. Any of the three texts may be omitted; an
omitted one falls back to searchConfig.yaml.
facets:
en:
LANG_CODE:
title: Language
tooltip: Language of the described material
A facet without an explicit title is labelled by its item type instead, so
translating it belongs in types_localization.yaml.
pageTemplate_localization.yaml
The portal name; a single field, so no codes are involved.
name:
en: Archives online
Note
Which language a response is rendered in comes from the request’s lang
parameter (an IETF tag such as en or cs-CZ), matched against the
configured localizations; absent or unmatched, the first configured
localization applies. This is the reader’s language and affects display
text only — never which records match, nor their order, which follows
search.content-locale.
4.4. Dating vocabulary
Datings are rendered by the server, because presenting one means applying the archival grammar — granularity (century, year, month, date), estimated bounds in brackets, intervals whose sides collapse when equal — and not merely formatting a date. The dates themselves come from the JDK’s CLDR data, so month names and date order are correct in any language without configuration.
The words around them — how a century reads, the interval separator — are not
in CLDR and ship as resource bundles in the application
(cz/aron/web/v1/unitdate*.properties): Czech as the base, plus one file per
further language. Supporting a new language therefore means adding one
properties file, not writing date patterns.
Alongside the rendered string, the API also carries the dating in machine form
(dating: bounds, granularity, estimate flags) — for semantic markup and for
consumers that process datings rather than display them.
4.5. searchConfig.yaml
Two concerns, both deployment-specific:
facets:— which search filters each portal section offers, their type (FULLTEXT,ENUM,MULTI_REF,UNITDATE, …), labels, ordering and display rules;relevance:— the fulltext ranking weights (see Search).
Changes take effect after a restart; no reindex is required.
4.6. pageTemplate.yaml
Portal name, available localizations and optionally the main menu (section
codes, colors, external URLs). Without a menu: block the default menu is
used (funds, archival description, entities + help from help-url).
Clients never receive raw server configuration files — the UI reads a typed
/api/v1/ui/config endpoint.
name: Archiv online
localizations:
- cs_CZ
- en
localizations declares which languages the portal offers; the first is the
default. The portal ships UI strings for Czech and English, so those are
the languages a deployment can list today — the language switcher shows only
the ones declared here and present in the build, and a single declared
language shows no switcher at all.
Declaring a language covers the interface strings and the datings. The labels
of the description items follow only if types_localization.yaml translates
them; untranslated ones fall back to the types.yaml names.
4.7. Home page
The optional homepage: block of pageTemplate.yaml fills the portal’s
home page below the search box: groups of prepared entry points, and the
deployment’s own footer band. Without the block the home page is the search box
alone, which is a legitimate configuration.
Every value a reader sees can be written either as one string (the source language) or as a mapping of language to text.
homepage:
groups:
- label: { cs: Mohlo by vás zajímat, en: You might be interested in }
style: GRID # GRID = picture tiles, LIST = rows of links (default)
tiles:
- label: { cs: Matriky, en: Parish registers }
note: { cs: církevní i civilní, en: church and civil }
image: { name: matriky.jpg, positionY: top }
columnSpan: 2 # 1 or 2 grid cells; GRID only
rowSpan: 2
apuType: ARCH_DESC
filters:
- facet: UNIT_TYPE
values: [matrika]
- label: Porta fontium
url: https://www.portafontium.eu
footer:
columns:
- heading: { cs: Základní informace, en: About }
paragraphs:
- text:
cs: "Portál je aplikace {archiv} a zpřístupňuje popis archiválií."
en: "The portal is an application of the {archiv}."
links:
archiv:
label: { cs: Státního oblastního archivu, en: State Regional Archives }
url: https://archiv.example
- heading: { cs: Kontakt, en: Contact }
links:
- label: badatelna@archiv.example
url: "mailto:badatelna@archiv.example"
Tiles
A tile leads either out of the portal or into one section’s search, never both and never neither:
url— an absolutehttp/https/mailtoaddress. In-app destinations are the other kind; a bare path is refused.apuTypeplus optionalqueryandfilters— the section’s search with those constraints already applied. The reader sees them in the search sidebar and can remove them, so a tile is a starting point rather than a locked scope.
Filters are written with the same vocabulary as searchConfig.yaml: facet
is the description item’s code with underscores, exactly as written there. The
kind of filter is not written — the facet’s configured type decides it, so
the two files cannot disagree:
ENUM/MULTI_REFfacet —values: [...]FULLTEXTfacet —q: textUNITDATEfacet —from:and/orto:(a year, a date, or a full timestamp)
image names a file of webResources.images (see above);
positionX/positionY move the crop of a picture whose subject is not in
the middle, and take a percentage or a CSS keyword. In a GRID group the
picture fills the tile; in a LIST group it is a small mark beside the label.
A GRID tile with no picture keeps the portal’s primary colour.
The startup fails on a mistake rather than serving a tile that cannot work:
an unknown facet for that section, a filter whose shape does not fit the
facet’s type, apuType: COLLECTION (the one record type with no section of
its own), a span outside 1–2, an image that is not a readable file, an unknown
key. Filter values cannot be checked — they are data, so a tile may
legitimately find nothing in a given deployment.
4.8. Citations
A reader who wants to quote a record needs a citation: the archive, the fonds it belongs to, the reference codes the description carries. What such a citation says - which identifiers appear, in which order, with which abbreviations - is the archive’s own agreement with its archivists and differs per citation norm, so the portal does not compose one. It runs the deployment’s citation script and publishes what that produced.
citation.yaml (webResources.citation) lists the citation forms the
portal offers:
forms:
- code: DEFAULT # stable identity of the form, used by the API
label: Citace # its name; translations in the sibling file
script: citation.groovy # resolved next to this file
apuTypes: [ARCH_DESC, FUND]
apuTypes decides where a citation is offered: the portal shows the
action only for those record types, so a reader is never offered a citation
that cannot be produced. Without the webResources.citation key the portal
offers none at all.
A second citation norm is another entry in the list, with a script of its own;
the API and the UI carry several forms without any change. The old portal’s UI
shows one citation and gets the first form whose script is the file it asks
for (citation.groovy).
The shipped citation.groovy is the default Czech citation and is what most
deployments should start from - copy it and adjust the wording with your
archivists rather than writing one from scratch.
Everything the portal can check, it checks at startup: an unknown key, a
duplicate code, an unknown record type, a missing script, a script that
does not compile. A citation is reached by a reader’s click, so a mistake
found then would be found by the reader.
What a script receives
A script is Groovy and is given four variables:
Variable |
Meaning |
|---|---|
|
|
|
Read access to the records: |
|
Jackson mapper, used to write the result. |
|
The reader’s language tag, for a deployment whose citation differs per language. The shipped script ignores it: a citation is written in the language of the archive. |
The script returns JSON with either citation (the text) or error (a
diagnostic naming the piece of description that was missing):
objectMapper.writeValueAsString([citation: text])
objectMapper.writeValueAsString([error: "Fund part not exist"])
Scripts are compiled once at startup and cached, so a citation costs one run.
Note
A script may read description items marked invisible - invisible means “not displayed on the record’s page”, and a source system may prepare a value for the citation without showing it. A script only ever reads the item types it names, so nothing reaches a citation by accident. Keep genuinely non-public data out of the description instead.
Important
A record the script cannot cite answers HTTP 422 and the reason is written to the log. In the shipped script that happens when an archival description names no fonds, which is a data error: every archival description belongs to one.
Coming from the old portal
The old portal ran the same kind of script, but the endpoint read
citation.groovy from the application’s working directory and the old UI
was told where to offer the action with showCitationFor in
configuration.js. The script now belongs beside citation.yaml and the
record types come from apuTypes there, so both halves are one piece of
configuration; a script name that no form declares is refused. An existing
script keeps working: it is given the same variables and returns the same
JSON.
4.9. Structured search results
A source system can deliver, alongside a record, a pre-rendered structured
presentation of it: rows of coded fields, optionally a thumbnail. Transfagent
carries it in the APUX result element and the portal stores it with the
record. A search hit that has one is presented with it; a hit that has none is
presented by its name and description as usual.
There is no switch to turn this on. Whether a record has a structured
presentation is a property of the data, so the portal simply uses it when it is
there — a deployment whose source system delivers none never sees the feature,
and a partially reimported one stays readable. search.structured-results:
OFF exists for the opposite case: a deployment that has the data but prefers
the plain presentation.
The codes in the data (A_IB, N, J_S, …) are the source system’s own,
so the portal cannot know what they mean. resultLayout.yaml says how to
present them; without it the rows still render, only without icons, prefixes
and an emphasised heading.
fieldSeparator: " | " # between fields of one row (default " | ")
iconSize: 35 # default record-icon width in pixels
icons: # keyed by the record code
- code: A_IB
image: archival-item-book.svg
- code: A_IM
image: archival-item-matrika.svg
size: 28
fields: # keyed by the field code
- code: N
heading: true # this field's text links to the record
scale: 1.2 # font size, 1 = base text
bold: true
- code: J_IC
prefix: "Inv. č.: " # visible text before the values
image: J_IC.svg
- code: J_S
valueSeparator: ", " # between the field's own values (default a space)
color: "#666666"
label: "Signatura" # field name for screen readers, when no prefix shows
Field keys: code, heading, prefix, label, valueSeparator,
color, scale, bold, image. Icon keys: code, image,
size. An unknown key stops the startup rather than being ignored, and so
does an image reference when webResources.images is not
configured.
Notes on the individual keys:
heading marks the one field whose text becomes the link into the record. Mark exactly one. With none marked, the first field of the first row is used; if that yields no text, the record’s own name is.
label is what a screen reader announces before the values. A field with a
prefixneeds none — the prefix is already its name. A field with neither is announced as bare values, which is why giving every styled field one of the two is part of meeting the accessibility obligation (seedoc/accessibility.md).color is applied to text only, never as a background. The contrast against the card background is the deployment’s responsibility (WCAG 2.1 AA requires 4.5:1 for body text).
image is a plain file name inside
webResources.images— no subdirectories, no paths. The portal serves those files at/api/v1/ui/images/<name>(svg,png,jpeg) and builds the URLs itself, so nothing has to be hosted next to the application. When the setting lists several directories, the name is looked up in each in turn.
prefix and label are display text, so they are translated in the sibling
resultLayout_localization.yaml:
fields:
en:
J_IC:
prefix: "Inv. no.: "
J_S:
label: "Reference code"
The values are never translated: they arrive already rendered from the source system, like record names and descriptions.
Coming from the old portal
The old portal read the same information from a static app/config.json
served next to the application, switched on with useStructuredResults: true
in configuration.js. Both are gone: the layout is server configuration now
and the switch is unnecessary. The keys map as follows.
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dropped — configuring |
|
dropped — see above; the opposite case is
|
color, bold and prefix keep their names and meaning. Prefixes that
were Czech-only in config.json can now be translated in the sibling file.