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

spring.datasource.*

PostgreSQL connection (URL, username, password).

spring.elasticsearch.*

Elasticsearch connection (default localhost:9200); relevant only with the Elasticsearch engine.

search.engine

Search engine: elasticsearch (default) or lucene (embedded, no external server).

search.lucene.path

Directory of the persisted embedded index; unset = in-memory (rebuilt on every start).

search.content-locale

Language of the described material, as an IETF language tag (default cs-CZ); its alphabet orders name-sorted results for every visitor and its stop words are the ones searching ignores (see Search) — this is not the visitor’s own locale. Changing it reindexes at the next startup (see Operations); an invalid tag stops the startup.

types-config

Path to types.yaml (see below).

webResources.pageTemplate

Portal name, localizations and optional menu definition (pageTemplate.yaml).

webResources.news

News shown on the portal home page (news.yaml).

webResources.favoriteQueries

Preconfigured favourite queries (favoriteQueries.yaml).

webResources.facets

Facet — and search relevance — configuration (searchConfig.yaml, see Search).

webResources.logo / webResources.topImage

Branding images served to the UI.

webResources.resultLayout

Optional layout of the structured search results (resultLayout.yaml, see below). Unset = the built-in defaults.

webResources.citation

Optional citation forms and their scripts (citation.yaml, see below). Unset = the portal offers no citations.

webResources.images

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.

search.structured-results

AUTO (default) attaches the structured presentation to every record that has one; OFF disables the feature for the whole deployment.

system.expose-version

false (default) keeps the running version out of the footer and out of /api/v1/system/info — a reader can do nothing with it. true publishes it, which is what a test server or a support case wants.

server.error.include-message

never (Spring’s default) keeps the reason of a failed request out of the response body; the portal writes it to the log. always sends it as message — the wanted behaviour on a test server, not on a public portal (see Operations).

help-url

External help link shown in the default menu.

import.input-dir

Optional input-directory import — a file-based alternative to the Transfagent upload (see Operations). Unset = off.

files.storage, files.transfer.path

File storage of attachments and the working directory of the SOAP file transfer.

tile.folder, tile.format

Deep-zoom tile storage for large images: Transfagent generates the tile pyramids, the portal unpacks them here on import and serves them at /api/v1/daofile/{id}/tiles/…. The format must match what Transfagent delivers (jpg by default on both sides).

webResources.daoFooter

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 (default is the fallback). Sentences are written with {placeholders} over a link map, exactly like the home page’s footer band — the portal renders the anchors, configured markup never reaches a page — and every text may carry per-language variants. A license entry may name an image (a file of webResources.images) shown as its mark. Everything the file can get wrong fails the startup. Without the key no attribution is shown.

files.referenced-dirs

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.

transformation-agent-url

SOAP endpoint of the external Transform agent (file/format transformations).

server.servlet.context-path

Optional subpath for standalone subpath deployments (see Installation).

soap.port

Optional separate port for the internal SOAP interfaces (/cxf/**). Unset = they share the main server port. When set, the split is strict: /cxf/** is served only on this port and this port serves nothing else (see Installation).

soap.address

Optional network interface the soap.port listener binds to (for example an internal address). Unset = all interfaces. An unusable address stops the startup.

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

types_localization.yaml

Labels of part types and item types (types.yaml).

searchConfig_localization.yaml

Facet title, tooltip and description, and the per-option explanations of tooltips (searchConfig.yaml, see Search).

pageTemplate_localization.yaml

Portal name (pageTemplate.yaml).

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 absolute http/https/mailto address. In-app destinations are the other kind; a bare path is refused.

  • apuType plus optional query and filters — 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_REF facet — values: [...]

  • FULLTEXT facet — q: text

  • UNITDATE facet — from: and/or to: (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

id

UUID of the record to cite.

apuRepository

Read access to the records: findByUuid(uuid) returns one, which is how a script reaches the fonds and its institution.

objectMapper

Jackson mapper, used to write the result.

lang

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 prefix needs 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 (see doc/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.

config.json

resultLayout.yaml

itemProperties[].type

fields[].code

class: header

heading: true

size: N

scale — the old value was 1 + (N-1)/10 em, so size: 3 becomes scale: 1.2

separator

valueSeparator

icon

image (the file moves into webResources.images)

itemSeparator

fieldSeparator

typeIcons[].type / .icon

icons[].code / .image

typeIconSize

iconSize

typeIcon

dropped — configuring icons is what enables them

useStructuredResults

dropped — see above; the opposite case is search.structured-results: OFF

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.