Browse Source

first commit

main
Paul Pound 1 week ago
commit
938ee28b84
  1. 24
      README.md
  2. 18
      composer.json
  3. 9
      mirador_search_highlight.info.yml
  4. 71
      mirador_search_highlight.module

24
README.md

@ -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.

18
composer.json

@ -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": "*"
}
}

9
mirador_search_highlight.info.yml

@ -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

71
mirador_search_highlight.module

@ -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…
Cancel
Save