Extend Solr search: content coverage, 14.0.2, news recency, result images

- Index the text columns of the market/solution Content Blocks and the
  vitec_items/vitec_faq_items collection children; story documents now
  include their body (inline tt_content children via
  tx_vitec_usecase_content, same per-element extraction as pages) -
  stories were indexed with subtitle and teaser only until now
- Upgrade EXT:solr 14.0.0-RC1 -> 14.0.2 final (the Solr image moved to a
  fresh volume because the configset changed; synonyms restored via REST)
- News decay with age by publication date: crdate is the import date, so
  news map datetime to created; boost function gated to news only
- Results carry `image`: processed 640px tile image per type,
  root-relative, null for pages and downloads
- Spec v1.21: 7.16 states the /_json prefix and lists `solution` in the
  type vocabulary; footer had been stuck at v1.19
- suggest-demo.html fetches through /_json after the URL swap
This commit is contained in:
orasche committed 2026-10-07 16:22:50 +02:00
1 parent 8e67f5db23
commit 9b1ad202a9
7 files changed
+242 -23

No files matched your search

@@ -27,7 +27,7 @@ use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
* or the FlexForm override on the plugin),
* "numFound": total hits,
* "totalPages": ceil(numFound / resultsPerPage),
* "results": [ { "title", "url", "type", "teaser" } ],
* "results": [ { "title", "url", "type", "teaser", "image" } ],
* "filter": the active type filter or null,
* "facets": { "type": [ { "value", "count", "active" } ] } -
* counts stay complete while a filter is active,
@@ -217,11 +217,20 @@ class SearchJsonRenderer
} else {
$teaser = mb_substr(trim((string)$document->getContent()), 0, self::TEASER_FALLBACK_LENGTH);
}
$image = (string)($document['image'] ?? '');
// IMG_RESOURCE yields fileadmin/... without a leading slash -
// made root-relative like every other URL in the payload
if ($image !== '' && !str_starts_with($image, '/') && !preg_match('#^https?://#', $image)) {
$image = '/' . $image;
}
$results[] = [
'title' => (string)$document->getTitle(),
'url' => (string)$document->getUrl(),
'type' => self::TYPE_LABELS[$document->getType()] ?? (string)$document->getType(),
'teaser' => $teaser,
// processed tile image (640px wide) from the index; null when the
// document type has none (pages, downloads) or no image is set
'image' => $image !== '' ? $image : null,
];
}