Last active
August 26, 2024 11:42
-
-
Save jasperf/53aff6872549caf992010f5f7011b868 to your computer and use it in GitHub Desktop.
Bud style WordPress block Filter (unfinished)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Import necessary functions from @wordpress/hooks | |
import { addFilter } from '@wordpress/hooks'; | |
import { createHigherOrderComponent } from '@wordpress/compose'; | |
import { InspectorControls } from '@wordpress/block-editor'; | |
import { PanelBody, ToggleControl, TextControl } from '@wordpress/components'; | |
import { Fragment } from '@wordpress/element'; | |
import React from 'react'; // Ensure React is imported for JSX and cloneElement | |
/** | |
* @see {@link https://developer.wordpress.org/block-editor/reference-guides/filters/block-filters/#blocks-registerblocktype} | |
*/ | |
export const hook = 'blocks.registerBlockType'; | |
/** | |
* Filter handle | |
*/ | |
export const name = 'sage/cover'; | |
/** | |
* Filter callback | |
* | |
* @param {Object} settings Block settings. | |
* @param {string} name | |
* @returns modified settings | |
*/ | |
export function callback(settings, name) { | |
if (name !== 'core/cover') return settings; | |
return { | |
...settings, | |
attributes: { | |
...settings.attributes, | |
loopVideo: { | |
type: 'boolean', | |
default: false, | |
}, | |
autoplayVideo: { | |
type: 'boolean', | |
default: false, | |
}, | |
showPlayButton: { | |
type: 'boolean', | |
default: true, | |
}, | |
coverImage: { | |
type: 'string', | |
default: '', | |
}, | |
}, | |
}; | |
} | |
/** | |
* Additional cover block modifications | |
*/ | |
export const editHook = 'editor.BlockEdit'; | |
export const editCallback = createHigherOrderComponent((BlockEdit) => { | |
return (props) => { | |
const { attributes, setAttributes, name } = props; | |
if (name !== 'core/cover') { | |
return <BlockEdit {...props} />; | |
} | |
const { loopVideo, autoplayVideo, showPlayButton, coverImage } = attributes; | |
return ( | |
<Fragment> | |
<BlockEdit {...props} /> | |
<InspectorControls> | |
<PanelBody title="Video Options" initialOpen={true}> | |
<ToggleControl | |
label="Loop Video" | |
checked={loopVideo} | |
onChange={(value) => setAttributes({ loopVideo: value })} | |
/> | |
<ToggleControl | |
label="Autoplay Video" | |
checked={autoplayVideo} | |
onChange={(value) => setAttributes({ autoplayVideo: value })} | |
/> | |
<ToggleControl | |
label="Show Play Button" | |
checked={showPlayButton} | |
onChange={(value) => setAttributes({ showPlayButton: value })} | |
/> | |
<TextControl | |
label="Cover Image URL" | |
value={coverImage} | |
onChange={(value) => setAttributes({ coverImage: value })} | |
help="This image will be used as the cover image for the video." | |
/> | |
</PanelBody> | |
</InspectorControls> | |
</Fragment> | |
); | |
}; | |
}, 'withCoverControls'); | |
/** | |
* Save element modification for the cover block | |
*/ | |
export const saveHook = 'blocks.getSaveElement'; | |
export const saveCallback = (element, blockType, attributes) => { | |
if (blockType.name !== 'core/cover') return element; | |
const { loopVideo, autoplayVideo, showPlayButton, coverImage } = attributes; | |
const children = Array.isArray(element.props.children) ? element.props.children.filter(Boolean) : []; | |
console.log('Filtered Children:', children); | |
const modifiedChildren = children.map((child) => { | |
console.log('Processing Child:', child); | |
if (child && child.type === 'video') { | |
return React.cloneElement(child, { | |
loop: loopVideo, | |
autoPlay: autoplayVideo, | |
poster: coverImage || child.props.poster, | |
}); | |
} | |
return child; | |
}); | |
console.log('Modified Children:', modifiedChildren); | |
return ( | |
<div {...element.props}> | |
{modifiedChildren} | |
{showPlayButton && ( | |
<div className="wp-block-cover__play-button-overlay" style={{ position: 'absolute', zIndex: 10 }}> | |
<button className="wp-block-cover__play-button" aria-label="Play Video" /> | |
</div> | |
)} | |
</div> | |
); | |
}; | |
// Register the filters | |
addFilter(hook, name, callback); // Adds custom attributes to the block | |
addFilter(editHook, name, editCallback); // Adds the inspector controls in the editor | |
addFilter(saveHook, name, saveCallback); // Modifies the save element |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @path wp-content/themes/cafejp/resources/scripts/filters/cover.filter.js | |
* @see {@link https://developer.wordpress.org/block-editor/reference-guides/filters/block-filters/#blocks-registerblocktype} | |
*/ | |
import { createHigherOrderComponent } from '@wordpress/compose'; | |
import { addFilter } from '@wordpress/hooks'; | |
import { InspectorControls } from '@wordpress/block-editor'; | |
import { PanelBody, ToggleControl, TextControl } from '@wordpress/components'; | |
import { Fragment } from '@wordpress/element'; | |
import React from 'react'; // Ensure React is imported for JSX and cloneElement | |
// Hook name for registering the block type modification | |
export const hook = 'blocks.registerBlockType'; | |
// Unique name for the filter namespace | |
export const name = 'sage/cover'; | |
/** | |
* Add custom attributes to the core/cover block. | |
* | |
* @param {Object} settings Block settings. | |
* @returns {Object} Modified block settings. | |
*/ | |
export function addCoverAttributes(settings) { | |
if (settings.name !== 'core/cover') return settings; | |
return { | |
...settings, | |
attributes: { | |
...settings.attributes, | |
loopVideo: { | |
type: 'boolean', | |
default: false, | |
}, | |
autoplayVideo: { | |
type: 'boolean', | |
default: false, | |
}, | |
showPlayButton: { | |
type: 'boolean', | |
default: true, | |
}, | |
coverImage: { | |
type: 'string', | |
default: '', | |
}, | |
}, | |
}; | |
} | |
/** | |
* Extend the BlockEdit component to add custom controls in the Inspector. | |
* This component adds additional settings to the 'core/cover' block in the editor. | |
*/ | |
export const withCoverControls = createHigherOrderComponent((BlockEdit) => { | |
return (props) => { | |
const { attributes, setAttributes, name } = props; | |
if (name !== 'core/cover') { | |
return <BlockEdit {...props} />; | |
} | |
const { loopVideo, autoplayVideo, showPlayButton, coverImage } = attributes; | |
return ( | |
<Fragment> | |
<BlockEdit {...props} /> | |
<InspectorControls> | |
<PanelBody title="Video Options" initialOpen={true}> | |
<ToggleControl | |
label="Loop Video" | |
checked={loopVideo} | |
onChange={(value) => setAttributes({ loopVideo: value })} | |
/> | |
<ToggleControl | |
label="Autoplay Video" | |
checked={autoplayVideo} | |
onChange={(value) => setAttributes({ autoplayVideo: value })} | |
/> | |
<ToggleControl | |
label="Show Play Button" | |
checked={showPlayButton} | |
onChange={(value) => setAttributes({ showPlayButton: value })} | |
/> | |
<TextControl | |
label="Cover Image URL" | |
value={coverImage} | |
onChange={(value) => setAttributes({ coverImage: value })} | |
help="This image will be used as the cover image for the video." | |
/> | |
</PanelBody> | |
</InspectorControls> | |
</Fragment> | |
); | |
}; | |
}, 'withCoverControls'); | |
/** | |
* Modify the save element for the cover block to add the new video attributes and play button. | |
* | |
* @param {Object} element The original save element. | |
* @param {Object} blockType The block type object. | |
* @param {Object} attributes The block attributes. | |
* @returns {Object} The modified save element. | |
*/ | |
export function modifyCoverSaveElement(element, blockType, attributes) { | |
if (blockType.name !== 'core/cover') return element; | |
const { loopVideo, autoplayVideo, showPlayButton, coverImage } = attributes; | |
// Ensure the original structure is preserved | |
const children = Array.isArray(element.props.children) ? element.props.children : [element.props.children]; | |
// Clone the video element with modifications | |
const modifiedChildren = children.map((child) => { | |
if (child && child.type === 'video') { | |
return React.cloneElement(child, { | |
loop: loopVideo, | |
autoPlay: autoplayVideo, | |
poster: coverImage || child.props.poster, | |
}); | |
} | |
return child; | |
}); | |
// Create a wrapper element, ensuring that the structure is consistent | |
return ( | |
<div {...element.props}> | |
{modifiedChildren} | |
{showPlayButton && ( | |
<div className="wp-block-cover__play-button-overlay" style={{ position: 'absolute', zIndex: 10 }}> | |
<button className="wp-block-cover__play-button" aria-label="Play Video" /> | |
</div> | |
)} | |
</div> | |
); | |
} | |
// Add filters to the block editor with correct callback functions | |
addFilter(hook, name, addCoverAttributes); // Filter to add custom attributes to the block | |
addFilter('editor.BlockEdit', name, withCoverControls); // Filter to extend the BlockEdit component | |
addFilter('blocks.getSaveElement', name, modifyCoverSaveElement); // Filter to modify the save element |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment