-
Notifications
You must be signed in to change notification settings - Fork 255
Mirador 3 plugins
Mirador plugins are a way for non-core code to inject components and other behavior into a Mirador application. The plugin configuration supplies information to Mirador about how to inject the plugin into the application:
const plugin = {
target: 'WorkspaceControlPanelButtons',
mode: 'wrap',
component: PluginComponent,
connectOptions: additionalOptionsToPassToReduxConnect,
mapStateToProps: mapStateToProps,
mapDispatchToProps: mapDispatchToProps,
reducers: {
pluginState: pluginStateReducer,
},
saga: saga,
value: 'Button thing', # Only available in a WindowSideBarButtons add plugin
};
This form enables a plugin to do the following:
- Target an existing Mirador component
- Either
wrap
oradd
itself to that component. Note:add
is only available on certain components - Connect to the Mirador state using
mapStateToProps
,mapDispatchToProps
, andconnectOptions
(see Redux#connect) - provide custom
reducers
and a rootsaga
for manipulating state.
The Mirador 3 plugin system is in active development. We invite the community to share their experiments and contributions in several areas:
- Add your example the Example Plugins list below
- Share your plugin at Mirador Community Call
- Share your plugin on the Mirador tech group or the IIIF Slack #mirador-dev channel
See the mirador-plugin-demos repo for additional implementation examples.
An existing plugin (see the In Progress list below for some examples) can easily be added to a Mirador instance.
First, from the command line, install the javascript package:
$ npm install mirador-image-tools --save
and then add it to the plugins
array before instantiating Mirador:
import miradorImageToolsPlugin from 'mirador-image-tools/es/plugins/miradorImageToolsPlugin.js';
const config = {
...
};
const plugins = [
...miradorImageToolsPlugin
];
Mirador.viewer(config, plugins);
Plugins with mode=add can be used to inject content into specifically designated areas within Mirador. We can discover where these areas are by looking for the PluginHook component, e.g.:
WindowTopBarPluginArea BackgroundPluginArea WorkspaceControlPanelButtons ManifestInfo
Let’s write a plugin to demonstrate this behavior. First, we need to build the component we want to render. Make a new directory at src/components
, and create a new file in that directory called custom_metadata.js
import React, { Component } from 'react';
export default function () {
return <h5>Custom metadata!</h5>;
}
In index.js, we can wire up our react component as a plugin:
import CustomMetadata from './components/custom_metadata';
const plugins = [
{
mode: 'add',
component: CustomMetadata,
target: 'CanvasInfo',
}
];
If we take a look at the info sidebar panel, we’ll see our placeholder text. We could make our component blend in with Mirador a little better by adopting some of practices and markup from upstream:
import React, { Component } from 'react';
import Typography from '@material-ui/core/Typography';
import { LabelValueMetadata } from 'mirador/dist/es/src/components/LabelValueMetadata';
export default function () {
return <>
<Typography
variant="h5"
component="h6"
>
Custom metadata
</Typography>
<LabelValueMetadata labelValuePairs={[{ label: 'Cat?', values: ['Yes!'] }]} />
</>;
}
"Wrap" plugins can be used in several ways:
- to entirely replace the content of a Mirador component
- to literally wrap a Mirador component with some additional context
- to intercept and modify the attributes of a component
Nearly all Mirador components can be wrapped, so this is a very powerful feature to inject your customizations in a very targeted way. Setting up a wrapping plugin is very similar to the add-style of plugin:
import CustomBrand from './components/custom_brand';
const plugins = [
{
mode: 'wrap',
component: CustomBrand,
target: 'Branding',
}
];
and we can use a minimal component that just erases the whole brand:
import React, { Component } from 'react';
export default function ({}) {
return <></>;
}
One of the unique things about wrapping components is they also receive the Mirador component they are wrapping, which makes it easy to surround the original component with additional context, or change the props that are used to render the component.
import React, { Component } from 'react';
export default function ({ TargetComponent, targetProps }) {
return <TargetComponent {...targetProps} />;
}
Here is an example of integrating Mirador plugins into an existing site: https://github.com/sul-dlss/sul-embed/blob/master/app/assets/javascripts/modules/m3_viewer.js#L97-L103
- mirador-dl-plugin - Mirador download plugin Demo
- mirador-share-plugin - Mirador share plugin Demo
- mirador-image-tools - Mirador image tools Demo
- mirador-plugin-demos - Demos and proof of concept work on Mirador 3 plugins
- catchpy-mirador-plugin - Mirador 3 plugin that hooks up an external annotation source (HarvardX Captchy system)
- mirador-annotot-plugin - Mirador 3 plugin that hooks up an external annotot endpoint
- mirador-annotations - Annotation creation and editing plugin for Mirador 3 Demo
- mirador-textoverlay - A Mirador 3 plugin to display a selectable text overlay based on OCR or transcriptions Demo