commit
938ee28b84
4 changed files with 122 additions and 0 deletions
@ -0,0 +1,24 @@
|
||||
# Mirador search highlight |
||||
|
||||
When someone clicks an item from the Solr search results, Mirador opens with |
||||
the search term already run against the item's IIIF content search service, |
||||
so matches are highlighted with no extra JavaScript. |
||||
|
||||
## How it works |
||||
|
||||
1. `hook_views_pre_render()` appends `?search_api_fulltext=<term>` to the |
||||
"Link this field to its item" links in the `solr_search_content` view. |
||||
2. `hook_preprocess_mirador()` reads that parameter and sets |
||||
`windows[0].defaultSearchQuery` on the viewer's Mirador config. |
||||
|
||||
The manifest must advertise a search service (`search_endpoint` in the |
||||
`iiif_manifest` view) for Mirador to run the search. |
||||
|
||||
## Configuration |
||||
|
||||
Edit the constants at the top of `mirador_search_highlight.module` to change |
||||
the query parameter or the views whose links carry the term. |
||||
|
||||
Only fields using Search API's "Link this field to its item" option get the |
||||
term. Fields linked another way (for example an image formatter linking to |
||||
content) are left alone. |
||||
@ -0,0 +1,18 @@
|
||||
{ |
||||
"name": "roblib/mirador_search_highlight", |
||||
"description": "Carries the Solr search term from search results to the item page and runs it as a IIIF content search in Mirador on load.", |
||||
"type": "drupal-custom-module", |
||||
"license": "GPL-2.0-or-later", |
||||
"keywords": [ |
||||
"drupal", |
||||
"islandora", |
||||
"mirador", |
||||
"search_api" |
||||
], |
||||
"require": { |
||||
"php": ">=8.1", |
||||
"drupal/core": "^10 || ^11", |
||||
"drupal/islandora_mirador": "*", |
||||
"drupal/search_api": "*" |
||||
} |
||||
} |
||||
@ -0,0 +1,9 @@
|
||||
name: 'Mirador search highlight' |
||||
type: module |
||||
description: 'Carries the Solr search term from search results to the item page and runs it as a IIIF content search in Mirador on load.' |
||||
package: Islandora |
||||
core_version_requirement: ^10 || ^11 |
||||
dependencies: |
||||
- islandora_mirador:islandora_mirador |
||||
- search_api:search_api |
||||
- drupal:views |
||||
@ -0,0 +1,71 @@
|
||||
<?php |
||||
|
||||
/** |
||||
* @file |
||||
* Runs a IIIF content search in Mirador on load from a passed search term. |
||||
*/ |
||||
|
||||
use Drupal\views\ViewExecutable; |
||||
|
||||
/** |
||||
* Query string parameter used to carry the search term to the item page. |
||||
* |
||||
* Matches the identifier used by the search_in_hocr view. |
||||
*/ |
||||
const MIRADOR_SEARCH_HIGHLIGHT_PARAM = 'search_api_fulltext'; |
||||
|
||||
/** |
||||
* Views whose item links should carry the search term. |
||||
*/ |
||||
const MIRADOR_SEARCH_HIGHLIGHT_VIEWS = ['solr_search_content']; |
||||
|
||||
/** |
||||
* Implements hook_views_pre_render(). |
||||
* |
||||
* Appends the search term to "Link this field to its item" links so the item |
||||
* page knows what was searched for. |
||||
*/ |
||||
function mirador_search_highlight_views_pre_render(ViewExecutable $view) { |
||||
if (!in_array($view->id(), MIRADOR_SEARCH_HIGHLIGHT_VIEWS, TRUE)) { |
||||
return; |
||||
} |
||||
if (!method_exists($view->query, 'getOriginalKeys')) { |
||||
return; |
||||
} |
||||
// Parse modes may turn the keys into an array; only the raw string is |
||||
// useful as a Mirador search query. |
||||
$keys = $view->query->getOriginalKeys(); |
||||
if (!is_string($keys) || trim($keys) === '') { |
||||
return; |
||||
} |
||||
|
||||
foreach ($view->field as $handler) { |
||||
if (!empty($handler->options['link_to_item'])) { |
||||
// Search API items are merged with $options['alter'] when rendered as |
||||
// links, and an explicit 'query' replaces the item URL's query. |
||||
// UrlHelper::buildQuery() encodes the value before Views token |
||||
// replacement, so user input is never treated as Twig. |
||||
$handler->options['alter']['query'] = [MIRADOR_SEARCH_HIGHLIGHT_PARAM => trim($keys)]; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Implements hook_preprocess_HOOK() for mirador. |
||||
* |
||||
* Runs after template_preprocess_mirador(), so mirador_view_id is already the |
||||
* unique ID used as the drupalSettings viewer key. |
||||
*/ |
||||
function mirador_search_highlight_preprocess_mirador(&$variables) { |
||||
// Vary the cached viewer by the search term, otherwise the first term |
||||
// searched would be cached and shown to everyone viewing this item. |
||||
$variables['#cache']['contexts'][] = 'url.query_args:' . MIRADOR_SEARCH_HIGHLIGHT_PARAM; |
||||
|
||||
$term = \Drupal::request()->query->get(MIRADOR_SEARCH_HIGHLIGHT_PARAM, ''); |
||||
$term = is_string($term) ? trim($term) : ''; |
||||
if ($term === '') { |
||||
return; |
||||
} |
||||
$selector = '#' . $variables['mirador_view_id']; |
||||
$variables['#attached']['drupalSettings']['mirador']['viewers'][$selector]['windows'][0]['defaultSearchQuery'] = mb_substr($term, 0, 256); |
||||
} |
||||
Loading…
Reference in new issue