Skip to content

Instantly share code, notes, and snippets.

@JasonHoffmann
Created February 15, 2018 14:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save JasonHoffmann/31a492aaf6f3b244b9e32ce1fe8526c9 to your computer and use it in GitHub Desktop.
Save JasonHoffmann/31a492aaf6f3b244b9e32ce1fe8526c9 to your computer and use it in GitHub Desktop.
Sample filterable block
/**
* This is an example of a script that would hook into the filter or
* subscribe to some sort of data. I want to make the assumption that
* this could be non-ES6 code with no access to the spread operator, so
* something like push would be used instead.
*/
function rkvAddPython( codeList ) {
codeList.push( {
title: 'Python',
codemirror: 'python',
} );
return codeList;
}
wp.hooks.addFilter( 'blocks.syntax.addCodeMode', 'rkv/codeMode', rkvAddPython );
const { registerBlockType, BlockControls } = wp.blocks;
const { DropdownMenu, Toolbar } = wp.components;
const { __ } = wp.i18n;
import './editor.scss';
import CodeMirrorBlock from './codemirror';
window.CodeMirror = wp.CodeMirror;
let codeMap = [
{
title: 'HTML',
codemirror: 'htmlmixed',
prism: 'html',
},
{
title: 'CSS',
codemirror: 'css',
},
{
title: 'SASS',
codemirror: 'sass',
},
{
title: 'JS',
codemirror: 'javascript',
},
{
title: 'PHP',
codemirror: 'php',
},
{
title: 'JSX',
codemirror: 'jsx',
},
{
title: 'Markdown',
codemirror: 'markdown',
},
{
title: 'Bash',
codemirror: 'shell',
prism: 'bash',
},
{
title: 'YAML',
codemirror: 'yaml',
},
];
// Here, or somewhere similar, I'd like to make the above array,
// codeMap, avaliable to other plugins to add to if they want to.
// I could use `once` or wp.hooks.didFilter but I'm wondering if there
// is a way to do that with wp.data
registerBlockType( 'rkv/syntax-highlighting', {
title: __( 'Code Syntax' ),
icon: 'editor-code',
category: 'formatting',
attributes: {
content: {
type: 'string',
source: 'property',
selector: 'pre',
property: 'textContent',
},
mode: {
type: 'string',
default: 'php',
},
modeTitle: {
type: 'string',
default: 'PHP',
},
},
supports: {
html: false,
},
edit( props ) {
const { content, mode, modeTitle } = props.attributes;
// Right here I'm using wp.hook, but it runs multiple times.
codeMap = wp.hooks.applyFilters( 'blocks.syntax.addCodeMode', codeMap );
const changeMode = ( newMode ) => {
props.setAttributes( {
mode: newMode,
} );
};
const changeModeTitle = ( newModeTitle ) => {
props.setAttributes( {
modeTitle: newModeTitle,
} );
};
const codeControls = codeMap.map( obj => {
return {
title: obj.title,
onClick: () => {
changeMode( obj.codemirror );
changeModeTitle( obj.title );
},
};
} );
function onChangeContent( newContent ) {
props.setAttributes( { content: newContent } );
}
return (
<div className={ props.className }>
{
!! props.focus && (
<BlockControls key="custom-controls">
<Toolbar>
<DropdownMenu
className="components-toolbar"
label="Select a code mode"
icon="editor-code"
controls={ codeControls }
/>
<div className="toolbar-mode">
{ modeTitle }
</div>
</Toolbar>
</BlockControls>
)
}
<CodeMirrorBlock
className={ 'code-mirror' }
onChange={ onChangeContent }
value={ content }
focus={ props.focus }
onFocus={ props.setFocus }
mode={ mode }
/>
</div>
);
},
save( { attributes } ) {
const { mode, content } = attributes;
//
// The CodeMap array also needs to be filtered here.
//
codeMap = wp.hooks.applyFilters( 'blocks.syntax.addCodeMode', codeMap );
let codeMode = codeMap.find( ( obj ) => obj.codemirror === mode );
codeMode = codeMode.prism || mode || '';
return <pre><code className={ 'language-' + codeMode }>{ content }</code></pre>;
},
} );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment