Skip to content

Instantly share code, notes, and snippets.

@mattheu
Last active February 23, 2023 13:00
Show Gist options
  • Save mattheu/65b46c3ac34faf90029ff9b05934511f to your computer and use it in GitHub Desktop.
Save mattheu/65b46c3ac34faf90029ff9b05934511f to your computer and use it in GitHub Desktop.
Example of how to add annotations to Gutenberg
// Make sure you specify the script "wp-annotations" as a dependency of your code that uses the WP annotations API.
const { select, dispatch } = wp.data;
const ANNOTATION_NS = 'core/annotations';
const ANNOTATION_SOURCE = 'testing-annotations';
// Default attributes for blockTypes.
// richTextIdentifier - this is the ID of the richTextField we want to add the annotation to.
const blockTypes = {
'core/paragraph': {
content: {
id: 'content',
},
},
'core/quote': {
value: {
id: 'value',
},
citation: {
id: 'citation',
},
},
}
/**
* Add an annotation.
*
* @param {string} id - id A unique block ID.
* @param {int} blockIndex - Index of the block.
* @param {string} attr - Attribute to target.
* @param {int} start - Annotation start position
* @param {int} end - Annotation end position.
* @param {string} variant - a bit of a hacky way to set different class names for different styles.
*/
function addAnnotation( id, blockIndex, attr, start, end, variant = '' ) {
const block = select( 'core/editor' ).getBlocks()[ blockIndex ];
// If current block type is not supported, return.
if ( ! block || ! blockTypes[ block.name ] || ! blockTypes[ block.name ][ attr ] ) {
console.log( 'Block not found or not supported', block );
return;
}
dispatch( ANNOTATION_NS ).__experimentalAddAnnotation( {
id,
blockClientId: block.clientId,
source: variant ? `${ANNOTATION_SOURCE}-${variant}` : ANNOTATION_SOURCE,
richTextIdentifier: blockTypes[ block.name ][ attr ].id,
range: {
start,
end,
},
} );
}
function removeAnnotation( id ) {
dispatch( ANNOTATION_NS ).__experimentalRemoveAnnotation( id );
}
// Disable the core spellcheck.
document.querySelector( 'body' ).setAttribute( 'spellcheck', 'false' );
// Short delay for this demo to ensure the editor is all set up.
window.setTimeout( () => {
// Listen for clicks on the annotations.
// A bit hacky... not sure of a better workaround for this.
const el = document.querySelector( '.editor-block-list__layout' );
el.addEventListener( 'click', e => {
if ( e.target.classList.contains( `annotation-text-${ANNOTATION_SOURCE}` ) ) {
const id = e.target.id.replace( /^annotation-text-/g, '' );
alert( `Clicked active: ${id}` );
}
} );
// Adds some annotations to the first 2 blocks, both are paragraphs.
addAnnotation( '05b61881-de51-453d-bdd5-e38d9fc48010', 0, 'content', 6, 12 );
addAnnotation( '34060482-5aeb-4d13-9ee5-11f5f45b9a6b', 1, 'content', 0, 30 );
// 4th block is a quote. Adds an annotation to 2 different attributes.
addAnnotation( 'f337b310-99fc-41ed-9db6-c791e3c5a765', 2, 'value', 3, 8, );
addAnnotation( '59b88977-bbeb-42b8-8555-96d45b1c8441', 2, 'citation', 5, 20, );
// After 2.5 seconds, remove one of the annotations.
// Note that you have to move an annotation before changing it.
window.setTimeout( () => {
removeAnnotation( 'f337b310-99fc-41ed-9db6-c791e3c5a765' )
}, 2500 );
// After 5 seconds, add back with a new class.
window.setTimeout( () => {
addAnnotation( 'f337b310-99fc-41ed-9db6-c791e3c5a765', 2, 'value', 11, 19, 'active' );
}, 5000 );
}, 2500 );
<!-- wp:paragraph -->
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quodsi ipsam honestatem undique pertectam atque absolutam. Nemo igitur esse beatus potest. Esse enim, nisi eris, non potes. Uterque enim summo bono fruitur, id est voluptate. Maximas vero virtutes iacere omnis necesse est voluptate dominante. Duo Reges: constructio interrete. Quae quidem vel cum periculo est quaerenda vobis; Et ille ridens: Video, inquit, quid agas; </p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>Vestri haec verecundius, illi fortasse constantius. Apud imperitos tum illa dicta sunt, aliquid etiam coronae datum; Haec et tu ita posuisti, et verba vestra sunt. Sin laboramus, quis est, qui alienae modum statuat industriae? </p>
<!-- /wp:paragraph -->
<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Ut optime, secundum naturam affectum esse possit. </p><cite>Ubi ut eam caperet aut quando? </cite></blockquote>
<!-- /wp:quote -->
@Soean
Copy link

Soean commented Feb 23, 2023

Thanks!

In WordPress 6.1 is a warning for line 37:
wp.data.select( 'core/editor' ).getBlocks is deprecated since version 5.3 and will be removed in version 6.2. Please use wp.data.select( 'core/block-editor' ).getBlocks instead`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment