From de02166c750074afa62a0a26a37b07e721df7847 Mon Sep 17 00:00:00 2001 From: Peter Stadler Date: Thu, 18 Dec 2025 15:55:16 +0100 Subject: [PATCH 1/7] first shot at implementing pb-timeline --- api/v1/openapi.yaml | 6 +++ .../openapi/paths/timeline-docType-docID.yaml | 40 +++++++++++++++ api/v1/openapi/paths/timeline-docType.yaml | 31 ++++++++++++ api/v1/openapi/paths/timeline.yaml | 22 ++++++++ modules/api.xqm | 50 +++++++++++++++++++ modules/app.xqm | 30 +++++++++++ modules/search.xqm | 4 +- templates/includes/search-results.html | 8 +++ 8 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 api/v1/openapi/paths/timeline-docType-docID.yaml create mode 100644 api/v1/openapi/paths/timeline-docType.yaml create mode 100644 api/v1/openapi/paths/timeline.yaml diff --git a/api/v1/openapi.yaml b/api/v1/openapi.yaml index bb7aa0ca5..c435c06cc 100644 --- a/api/v1/openapi.yaml +++ b/api/v1/openapi.yaml @@ -47,6 +47,12 @@ paths: $ref: "./openapi/paths/application-newID.yaml" /facets/{facet}: $ref: "./openapi/paths/facets.yaml" + /timeline: + $ref: "./openapi/paths/timeline.yaml" + /timeline/{docType}: + $ref: "./openapi/paths/timeline-docType.yaml" + /timeline/{docType}/{docID}: + $ref: "./openapi/paths/timeline-docType-docID.yaml" components: schemas: Document: diff --git a/api/v1/openapi/paths/timeline-docType-docID.yaml b/api/v1/openapi/paths/timeline-docType-docID.yaml new file mode 100644 index 000000000..0556c0fa6 --- /dev/null +++ b/api/v1/openapi/paths/timeline-docType-docID.yaml @@ -0,0 +1,40 @@ +# /timeline/docType/docID path +get: + tags: + - Facets + summary: Returns timeline for a specific document type + description: | + This endpoint returns a timeline object according to + https://cdn.tei-publisher.com/@2.23.2/dist/api.html#pb-timeline.0 + for a specific WeGA document type related to the given document identifier + (i.e. the works, letters, or writings associated with the given person or organization). + parameters: + - name: docType + in: path + description: The WeGA document type + required: true + style: form + explode: false + schema: + $ref: '../schemas/docTypes.yaml' + - name: docID + in: path + description: The document identifier to search for + required: true + schema: + type: string + default: A002068 + responses: + 200: + description: A timeline object according to https://cdn.tei-publisher.com/@2.23.2/dist/api.html#pb-timeline.0 + headers: + totalrecordcount: + description: The total size of the result set + schema: + type: integer + content: + application/json: + schema: + type: object + default: + $ref: '../responses/unexpectedError.yaml' diff --git a/api/v1/openapi/paths/timeline-docType.yaml b/api/v1/openapi/paths/timeline-docType.yaml new file mode 100644 index 000000000..ace277b8b --- /dev/null +++ b/api/v1/openapi/paths/timeline-docType.yaml @@ -0,0 +1,31 @@ +# /timeline/docType path +get: + tags: + - Facets + summary: Returns timeline for a specific document type + description: | + This endpoint returns a timeline object according to + https://cdn.tei-publisher.com/@2.23.2/dist/api.html#pb-timeline.0 for a specific WeGA document type + parameters: + - name: docType + in: path + description: The WeGA document type + required: true + style: form + explode: false + schema: + $ref: '../schemas/docTypes.yaml' + responses: + 200: + description: A timeline object according to https://cdn.tei-publisher.com/@2.23.2/dist/api.html#pb-timeline.0 + headers: + totalrecordcount: + description: The total size of the result set + schema: + type: integer + content: + application/json: + schema: + type: object + default: + $ref: '../responses/unexpectedError.yaml' diff --git a/api/v1/openapi/paths/timeline.yaml b/api/v1/openapi/paths/timeline.yaml new file mode 100644 index 000000000..2f45ea685 --- /dev/null +++ b/api/v1/openapi/paths/timeline.yaml @@ -0,0 +1,22 @@ +# /timeline path +get: + tags: + - Facets + summary: Returns timeline + description: | + This endpoint returns a timeline object according to + https://cdn.tei-publisher.com/@2.23.2/dist/api.html#pb-timeline.0 + responses: + 200: + description: A timeline object according to https://cdn.tei-publisher.com/@2.23.2/dist/api.html#pb-timeline.0 + headers: + totalrecordcount: + description: The total size of the result set + schema: + type: integer + content: + application/json: + schema: + type: object + default: + $ref: '../responses/unexpectedError.yaml' diff --git a/modules/api.xqm b/modules/api.xqm index f3b8b4dfc..8a289534f 100644 --- a/modules/api.xqm +++ b/modules/api.xqm @@ -290,6 +290,38 @@ declare function api:facets($model as map(*)) as map(*) { ) }; +(:~ + : Return a timeline object for driving the TEIPublisher pb-timeline component + : see https://cdn.tei-publisher.com/@2.23.2/dist/api.html#pb-timeline.0 + :) +declare function api:timeline($model as map(*)) as map(*) { + let $docID := + if($model?docID) + then $model?docID + else 'indices' + let $documents := + for $docType in api:resolve-docTypes($model) + return search:results(, map { 'docID' : $docID }, $docType)?search-results + (:if(empty(($model?start, $model?end))) + then core:getOrCreateColl($docType, $docID, true()) + else wdt:lookup($docType, core:getOrCreateColl($docType, $docID, true()))?filter-by-date($model?start, $model?end) :) + let $dates := + map:merge( + for $doc in $documents + group by $date := query:get-normalized-date($doc) + let $key := + if(exists($date)) then $date + else '?' + return + map:entry($key, count($doc)) + ) + return + map { + 'totalRecordCount': count(map:keys($dates)), + 'results': $dates + } +}; + (:~ : Search WeGA entities (persons, places, works) by name or title respectively :) @@ -764,6 +796,24 @@ declare function api:validate-toDate($model as map(*)) as map(*)? { else error($api:INVALID_PARAMETER, 'Unsupported date format given: "' || $model('toDate') || '". Should be YYYY-MM-DD.') }; +(:~ + : Check parameter start +~:) +declare function api:validate-start($model as map(*)) as map(*)? { + if($model('start') castable as xs:date) then $model + else if($model?start ='') then () (: an empty string is simply dropped :) + else error($api:INVALID_PARAMETER, 'Unsupported date format given: "' || $model('start') || '". Should be YYYY-MM-DD.') +}; + +(:~ + : Check parameter end +~:) +declare function api:validate-end($model as map(*)) as map(*)? { + if($model('end') castable as xs:date) then $model + else if($model?end ='') then () (: an empty string is simply dropped :) + else error($api:INVALID_PARAMETER, 'Unsupported date format given: "' || $model('end') || '". Should be YYYY-MM-DD.') +}; + (:~ : Check parameter date ~:) diff --git a/modules/app.xqm b/modules/app.xqm index 5833eba5f..9f0f9d645 100644 --- a/modules/app.xqm +++ b/modules/app.xqm @@ -2110,3 +2110,33 @@ declare function app:init-custom-switch($node as node(), $model as map(*)) as el $node/* } }; + +(:~ + : Construct the pb-timeline custom element, + : i.e. update the `@start-date` and `@end-date` attributes + : as well as the `@url` attribute with the API URL. + :) +declare function app:pb-timeline($node as node(), $model as map(*)) as element(xhtml:pb-timeline) { + let $api-base := config:api-base($model?openapi) + let $docType := + if(count($model?docType) eq 1 and $model?docType = $search:wega-docTypes) + then $model?docType + else () + let $docID := + if($model?docID = 'indices') + then () + else $model?docID + let $url := $api-base || str:join-path-elements(('/timeline', $docType, $docID)) + return + element {node-name($node)} { + $node/@* except $node/@start-date except $node/@end-date except $node/@url, + attribute url {$url}, + if($model?filters?fromDate castable as xs:date) + then attribute start-date {$model?filters?fromDate} + else (), + if($model?filters?toDate castable as xs:date) + then attribute end-date {$model?filters?toDate} + else (), + $node/* + } +}; diff --git a/modules/search.xqm b/modules/search.xqm index 9bba98613..2802b41c0 100644 --- a/modules/search.xqm +++ b/modules/search.xqm @@ -44,7 +44,9 @@ declare variable $search:valid-params := ( 'undated', 'orderby', 'orderdir', - 'orgs' + 'orgs', + 'start', + 'end' ); (:~ diff --git a/templates/includes/search-results.html b/templates/includes/search-results.html index df29b42c8..da71a126c 100644 --- a/templates/includes/search-results.html +++ b/templates/includes/search-results.html @@ -1,4 +1,12 @@
+ + + + Angezeigter Zeitraum: +

124 Suchergebnisse

From 628a4457005b9435fffa13a0a79525f16d568201 Mon Sep 17 00:00:00 2001 From: Peter Stadler Date: Thu, 19 Mar 2026 21:01:13 +0100 Subject: [PATCH 2/7] remove rangeSlider from HTML --- templates/ajax/biblio.html | 6 ------ templates/ajax/correspondence.html | 5 ----- templates/ajax/diaries.html | 2 -- templates/ajax/documents.html | 2 -- templates/ajax/news.html | 3 --- templates/ajax/sources.html | 4 +--- templates/ajax/thematicCommentaries.html | 4 +--- templates/ajax/writings.html | 7 ------- 8 files changed, 2 insertions(+), 31 deletions(-) diff --git a/templates/ajax/biblio.html b/templates/ajax/biblio.html index 93bc9607f..4951bdd80 100644 --- a/templates/ajax/biblio.html +++ b/templates/ajax/biblio.html @@ -7,12 +7,6 @@

-

chronology

- -
- - -

authors

- - -
diff --git a/templates/ajax/diaries.html b/templates/ajax/diaries.html index f08627a72..f7fc24485 100644 --- a/templates/ajax/diaries.html +++ b/templates/ajax/diaries.html @@ -7,8 +7,6 @@

filter

-

chronology

-

persons_mentioned

authors

-

persons_mentioned

- +

sources-meta-cat

diff --git a/templates/ajax/writings.html b/templates/ajax/writings.html index cc95d98e4..7a4465837 100644 --- a/templates/ajax/writings.html +++ b/templates/ajax/writings.html @@ -3,13 +3,6 @@

filter

-

chronology

- - -
- - -

authors

diff --git a/templates/ajax/documents.html b/templates/ajax/documents.html index 93cb7add3..1d8073b43 100644 --- a/templates/ajax/documents.html +++ b/templates/ajax/documents.html @@ -3,6 +3,7 @@

filter

+

authors

authors