admin管理员组文章数量:1122832
Using an example given here: enter link description here I've successfully been able to restrict the block types available globally or by post type (eg: page). But what I really would like to do is restrict the the block types by page template.
I have tried using if ( is_page_template('page-home.php') ) {...}
but with no joy. It will be apparant from the code below, but I am using ACF custom blocks. The blocks themselves are working fine.
So currently I have the following in my functions.php file:
function my_allowed_block_types( $allowed_blocks, $post ) {
// works on all content
$allowed_blocks = array(
'core/image',
'core/paragraph',
'core/heading',
'core/list'
);
// works for all pages but too general for what I want to do
if( $post->post_type === 'page' ) {
$allowed_blocks= array(
'acf/homepage'
);
}
// Intended to restrict to just one block on my homepage template but does not
if ( is_page_template('page-home.php') ) {
$allowed_blocks= array(
'acf/homepage'
);
}
Using an example given here: enter link description here I've successfully been able to restrict the block types available globally or by post type (eg: page). But what I really would like to do is restrict the the block types by page template.
I have tried using if ( is_page_template('page-home.php') ) {...}
but with no joy. It will be apparant from the code below, but I am using ACF custom blocks. The blocks themselves are working fine.
So currently I have the following in my functions.php file:
function my_allowed_block_types( $allowed_blocks, $post ) {
// works on all content
$allowed_blocks = array(
'core/image',
'core/paragraph',
'core/heading',
'core/list'
);
// works for all pages but too general for what I want to do
if( $post->post_type === 'page' ) {
$allowed_blocks= array(
'acf/homepage'
);
}
// Intended to restrict to just one block on my homepage template but does not
if ( is_page_template('page-home.php') ) {
$allowed_blocks= array(
'acf/homepage'
);
}
Share
Improve this question
edited Feb 13, 2020 at 7:50
UntitledGraphic
asked Feb 13, 2020 at 7:11
UntitledGraphicUntitledGraphic
1831 gold badge2 silver badges9 bronze badges
3 Answers
Reset to default 1Expanding on some of the prior art here. You need to handle the template switch from the js/editor side of things. Here is a a quick snippet I used to solve this issue.
Key Idea: Check for template match, remove all blocks not in whitelist, force unregister. It is important to remove all the non-allowed blocks from the editor prior to unregistering to prevent a bunch of errors. The debounce here could be pushed even higher.
import domReady from '@wordpress/dom-ready';
import { dispatch, subscribe, select } from '@wordpress/data';
import { getBlockTypes, unregisterBlockType } from '@wordpress/blocks'
import { debounce } from 'lodash';
/**
* Template Updating.
*/
domReady(() => {
// Get current block list func.
const getBlockList = () => select('core/block-editor').getBlocks();
subscribe(
debounce(() => {
// Get Blocks.
const currentBlockList = getBlockList();
// Get Template.
const template = select('core/editor').getEditedPostAttribute(
'template',
);
// Set allowed.
const allowedBlocks = [
'core/paragraph',
];
// Check whatever template.
if (template === 'template-chapters.php') {
// Compare current blocks with allowed
if (currentBlockList.length > 0) {
// Array of allowed blocks.
const tmp = currentBlockList.filter(block => {
return -1 !== allowedBlocks.indexOf(block.name);
});
if (tmp.length !== currentBlockList.length && currentBlockList.length > 1) {
// Remove all offending blocks.
dispatch('core/block-editor').resetBlocks(tmp);
return;
}
}
// Proceed to unregister.
getBlockTypes().forEach( function ( blockType ) {
if ( allowedBlocks.indexOf( blockType.name ) === -1 ) {
unregisterBlockType( blockType.name );
}
} );
}
}, 100)
);
});
It's theoretically possible but would require reloading the page again because the page template can be changed after the content is initially loaded for editing; unlike a post-type.
(Maybe try to use UpdateSettings to do this although documentation is scarce.
Hey so it is possible to do this, I wrote an article about it. You need to do it on the javascript side using the Gutenberg's data module api.
Here's the code that'll get this up and running for you.
/** main.js **/
import BlockRestrictor from './BlockRestrictor'
/*
* Add a mapping of block names and what templates they are
* restricted to.
*/
const blockTemplateRestrictions = {
'core/code': [
'template-super-cool.php',
],
}
wp.domReady(() => {
const restrictor = new BlockRestrictor(blockTemplateRestrictions)
const templateWhitelister = new TemplateWhitelister(blockTemplateRestrictions)
restrictor.run()
templateWhitelister.run()
})
const { data } = window.wp
const { select, dispatch, subscribe } = data
const { getEditedPostAttribute } = select('core/editor')
const { isTyping } = select('core/block-editor')
const { getBlockType } = select('core/blocks')
const { addBlockTypes, removeBlockTypes } = dispatch('core/blocks')
class BlockRestrictor {
/**
* Currently selected template.
* @type {string}
*/
currentTemplate = ''
/**
* Map block names to the actual block object.
*
* @type {object}
*/
unregisteredBlocks = {}
constructor(blockTemplateRestrictions) {
this.blockTemplateRestrictions = blockTemplateRestrictions
}
/**
* Initiates listening to the redux store for when a restricted block is either
* added or removed.
*/
run() {
this.currentTemplate = getEditedPostAttribute('template') || 'default'
this.restrictBlocksToTemplate()
/**
* subscribe fires whenever the redux store in gutenberg updates
*/
subscribe(() => {
/**
* ensure we don't run our logic when the user is typing.
*/
if (isTyping() === true) {
return false
}
const newTemplate = getEditedPostAttribute('template') || 'default'
if (this.currentTemplate !== newTemplate) {
this.currentTemplate = newTemplate
this.restrictBlocksToTemplate()
}
})
}
/**
* Helps decide which blocks we actually want to add or remove from
* the store.
*/
templateBlockRegistry() {
let blocksToAdd = []
let blocksToRemove = []
Object.keys(this.blockTemplateRestrictions).forEach((blockName) => {
if (this.blockTemplateRestrictions[blockName].includes(this.currentTemplate)) {
blocksToAdd.push(blockName)
} else {
blocksToRemove.push(blockName)
}
})
return {
blocksToAdd,
blocksToRemove,
}
}
/**
* Either removes or adds blocks to the store based on what the current
* template is.
*/
restrictBlocksToTemplate() {
const { blocksToAdd, blocksToRemove } = this.templateBlockRegistry()
if (blocksToRemove.length) {
blocksToRemove.forEach((blockName) => {
const blockExists = getBlockType(blockName)
const isRegistered = typeof this.unregisteredBlocks[blockName] === 'undefined'
if (blockExists && isRegistered) {
this.unregisteredBlocks[blockName] = getBlockType(blockName)
}
})
removeBlockTypes(Object.keys(this.unregisteredBlocks))
}
if (blocksToAdd.length) {
let registeredBlocks = []
blocksToAdd.forEach(blockName => {
const blockExists = typeof getBlockType(blockName) === 'undefined'
const isUnregistered = typeof this.unregisteredBlocks[blockName] !== 'undefined'
if (blockExists && isUnregistered) {
registeredBlocks.push(this.unregisteredBlocks[blockName])
delete this.unregisteredBlocks[blockName]
}
})
addBlockTypes(registeredBlocks)
}
}
}
export default BlockRestrictor
Here's a link to the article going into detail on how to restrict blocks based on page templates. How to Restrict Blocks to Specific Page Templates in the WordPress Gutenberg Editor
本文标签: functionsHow to specify which Gutenberg blocks are available in the editor for a page template
版权声明:本文标题:functions - How to specify which Gutenberg blocks are available in the editor for a page template 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736296600a1929831.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论