admin管理员组文章数量:1124811
I have a plugin that registers four different Gutenberg blocks. I build them using the build
script from the wp-scripts
package. As you all surely know, this script automatically generates an index.asset.php
file with an array with all the script dependencies for each block. For example:
<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => 'a955a4059265b7ad1ce6');
I need to add the masonry
script (included in WP) to this dependency array in just ONE (not ALL) of the blocks, like this:
<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-element', 'wp-i18n', 'wp-primitives', 'masonry'), 'version' => 'a955a4059265b7ad1ce6');
I know that I can add this dependency manually after I build the blocks, but I'm wondering if there's a way to do this automatically via the block block.json
file, a custom webpack.config.js
file or anything else.
The contents of the block.json
file is:
{
"$schema": ".json",
"apiVersion": 3,
"name": "my/masonry-block",
"title": "My Masonry Block",
"description": "Display a Masonry gallery.",
"textdomain": "my-domain",
"category": "media",
"attributes": {
"items": {
"type": "array",
"default": []
},
"columns": {
"type": "number",
"minimum": 1,
"maximum": 8,
"default": 3
},
"gap": {
"type": "string",
"default": "10px"
},
"captions": {
"type": "boolean",
"default": false
}
},
"supports": {
"spacing": {
"margin": true,
"padding": true
},
"align": [ "center" ]
},
"editorScript": [
"file:./index.js",
"imagesloaded",
"masonry"
],
"viewScript": [
"file:./view.js",
"imagesloaded",
"masonry"
],
"style": [
"file:./style-index.css",
"file:./view.css"
],
"editorStyle": "file:./index.css"
}
I'm registering the block with:
register_block_type(
__DIR__ . '/build/blocks/masonry',
array(
'render_callback' => array( $this, 'render_block_masonry' ),
)
);
This is the block edit
function (some code omitted for brevity):
const displayItems = (items) => {
return (
items.map((item, index) => {
return (
<div className="gallery-item" key={index}>
<figure>
<a data-rel="collection" href={item.url} data-sub-html={item.caption}>
<img className={`wp-image-${item.id}`} src={item.url} alt={item.alt} key={item.id} />
</a>
{captions && item.caption &&
<figcaption className="wp-element-caption">
{item.caption}
</figcaption>
}
</figure>
</div>
)
})
)
};
const containerMasonryRef = useRefEffect((element) => {
var msnry;
const { ownerDocument } = element;
const { defaultView } = ownerDocument;
if (!defaultView.imagesLoaded || !defaultView.Masonry) {
console.log('scripts not loaded');
return;
}
imagesLoaded(element, function () {
console.log('images loaded');
msnry = new defaultView.Masonry(element, {
itemSelector: '.gallery-item',
columnWidth: '.grid-sizer',
percentPosition: true,
gutter: parseInt(gap),
});
});
return () => {
msnry?.destroy();
}
}, [items, columns, gap, captions]);
const containerLightboxRef = useRefEffect((element) => {
lightGallery(element, {
selector: 'a[data-rel^=collection]',
mode: 'lg-fade',
preload: 4,
counter: false,
download: false,
youtubePlayerParams: {
autoplay: 0
},
vimeoPlayerParams: {
autoplay: 0
}
});
return () => {
window?.lgData[element?.getAttribute('lg-uid')]?.destroy(true);
}
}, []);
const mergedRefs = useMergeRefs([
containerMasonryRef,
containerLightboxRef,
]);
return (
<>
<InspectorControls>
<PanelBody
title={__('Settings')}
>
<RangeControl
label={__('Columns')}
value={columns}
onChange={setColumns}
min={1}
max={8}
/>
<UnitControl
label={__('Gap between items')}
min="0"
onChange={setGap}
value={gap}
units={units}
/>
</PanelBody>
</InspectorControls>
<BlockControls group="block">
<ToolbarButton
onClick={toggleCaptions}
icon={captionIcon}
isPressed={captions}
label={
captions
? __('Hide captions')
: __('Show captions')
}
/>
</BlockControls>
<BlockControls group="other">
{items.length > 0 && (
<ToolbarGroup>
<MediaUploadCheck>
<MediaUpload
allowedTypes={['image']}
multiple={true}
gallery={true}
value={items.map((item) => item.id)}
onSelect={setItems}
render={({ open }) => (
<ToolbarButton onClick={open}>
{__('Edit items')}
</ToolbarButton>)}
/>
</MediaUploadCheck>
</ToolbarGroup>
)}
</BlockControls>
<MediaUploadCheck>
{items.length > 0 ?
<div {...blockProps}>
<div className="gallery-items" style={{ '--gap': gap }} ref={mergedRefs}>
<div className="grid-sizer"></div>
{displayItems(items)}
</div>
</div>
:
<MediaPlaceholder
accept="image/*"
allowedTypes={['image']}
onSelect={setItems}
multiple={true}
gallery={true}
addToGallery={true}
handleUpload={true}
labels={
{ title: __('My Masonry Block') }
}
/>
}
</MediaUploadCheck>
</>
);
I have a plugin that registers four different Gutenberg blocks. I build them using the build
script from the wp-scripts
package. As you all surely know, this script automatically generates an index.asset.php
file with an array with all the script dependencies for each block. For example:
<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => 'a955a4059265b7ad1ce6');
I need to add the masonry
script (included in WP) to this dependency array in just ONE (not ALL) of the blocks, like this:
<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-element', 'wp-i18n', 'wp-primitives', 'masonry'), 'version' => 'a955a4059265b7ad1ce6');
I know that I can add this dependency manually after I build the blocks, but I'm wondering if there's a way to do this automatically via the block block.json
file, a custom webpack.config.js
file or anything else.
The contents of the block.json
file is:
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "my/masonry-block",
"title": "My Masonry Block",
"description": "Display a Masonry gallery.",
"textdomain": "my-domain",
"category": "media",
"attributes": {
"items": {
"type": "array",
"default": []
},
"columns": {
"type": "number",
"minimum": 1,
"maximum": 8,
"default": 3
},
"gap": {
"type": "string",
"default": "10px"
},
"captions": {
"type": "boolean",
"default": false
}
},
"supports": {
"spacing": {
"margin": true,
"padding": true
},
"align": [ "center" ]
},
"editorScript": [
"file:./index.js",
"imagesloaded",
"masonry"
],
"viewScript": [
"file:./view.js",
"imagesloaded",
"masonry"
],
"style": [
"file:./style-index.css",
"file:./view.css"
],
"editorStyle": "file:./index.css"
}
I'm registering the block with:
register_block_type(
__DIR__ . '/build/blocks/masonry',
array(
'render_callback' => array( $this, 'render_block_masonry' ),
)
);
This is the block edit
function (some code omitted for brevity):
const displayItems = (items) => {
return (
items.map((item, index) => {
return (
<div className="gallery-item" key={index}>
<figure>
<a data-rel="collection" href={item.url} data-sub-html={item.caption}>
<img className={`wp-image-${item.id}`} src={item.url} alt={item.alt} key={item.id} />
</a>
{captions && item.caption &&
<figcaption className="wp-element-caption">
{item.caption}
</figcaption>
}
</figure>
</div>
)
})
)
};
const containerMasonryRef = useRefEffect((element) => {
var msnry;
const { ownerDocument } = element;
const { defaultView } = ownerDocument;
if (!defaultView.imagesLoaded || !defaultView.Masonry) {
console.log('scripts not loaded');
return;
}
imagesLoaded(element, function () {
console.log('images loaded');
msnry = new defaultView.Masonry(element, {
itemSelector: '.gallery-item',
columnWidth: '.grid-sizer',
percentPosition: true,
gutter: parseInt(gap),
});
});
return () => {
msnry?.destroy();
}
}, [items, columns, gap, captions]);
const containerLightboxRef = useRefEffect((element) => {
lightGallery(element, {
selector: 'a[data-rel^=collection]',
mode: 'lg-fade',
preload: 4,
counter: false,
download: false,
youtubePlayerParams: {
autoplay: 0
},
vimeoPlayerParams: {
autoplay: 0
}
});
return () => {
window?.lgData[element?.getAttribute('lg-uid')]?.destroy(true);
}
}, []);
const mergedRefs = useMergeRefs([
containerMasonryRef,
containerLightboxRef,
]);
return (
<>
<InspectorControls>
<PanelBody
title={__('Settings')}
>
<RangeControl
label={__('Columns')}
value={columns}
onChange={setColumns}
min={1}
max={8}
/>
<UnitControl
label={__('Gap between items')}
min="0"
onChange={setGap}
value={gap}
units={units}
/>
</PanelBody>
</InspectorControls>
<BlockControls group="block">
<ToolbarButton
onClick={toggleCaptions}
icon={captionIcon}
isPressed={captions}
label={
captions
? __('Hide captions')
: __('Show captions')
}
/>
</BlockControls>
<BlockControls group="other">
{items.length > 0 && (
<ToolbarGroup>
<MediaUploadCheck>
<MediaUpload
allowedTypes={['image']}
multiple={true}
gallery={true}
value={items.map((item) => item.id)}
onSelect={setItems}
render={({ open }) => (
<ToolbarButton onClick={open}>
{__('Edit items')}
</ToolbarButton>)}
/>
</MediaUploadCheck>
</ToolbarGroup>
)}
</BlockControls>
<MediaUploadCheck>
{items.length > 0 ?
<div {...blockProps}>
<div className="gallery-items" style={{ '--gap': gap }} ref={mergedRefs}>
<div className="grid-sizer"></div>
{displayItems(items)}
</div>
</div>
:
<MediaPlaceholder
accept="image/*"
allowedTypes={['image']}
onSelect={setItems}
multiple={true}
gallery={true}
addToGallery={true}
handleUpload={true}
labels={
{ title: __('My Masonry Block') }
}
/>
}
</MediaUploadCheck>
</>
);
Share
Improve this question
edited Feb 13, 2024 at 14:52
leemon
asked Feb 12, 2024 at 20:15
leemonleemon
2,0124 gold badges22 silver badges51 bronze badges
1 Answer
Reset to default 1Actually, you do not need to worry about adding the Masonry's script handle to the dependencies
array in the asset file (index.asset.php
).
All you needed to do to make your Masonry code work properly is by using the script
property to add the masonry
(and imagesloaded
) as dependencies for your editor and view/front-end scripts.
"editorScript": "file:./index.js",
"script": [
"imagesloaded",
"masonry"
],
"viewScript": "file:./view.js",
I don't know and haven't checked further why adding the above (trick) worked well for me.masonry
to the editorScript
and viewScript
did not work, but
- Using the
script
property to add the dependency, is also the reason why the Gutenberg Test Iframed Masonry Block worked. I.e. The plugin manually registered the shared editor and front-end script, and the plugin also sets"script": "iframed-masonry-block-script"
in the block metadata.
For completeness though, I created a simple Webpack plugin which basically modifies the asset source before it is written to the asset file, but (hopefully) after the Dependency Extraction Webpack Plugin added the asset to the compilation queue.
Here's the plugin which I placed it in the root project folder.
And here's my custom Webpack config file, i.e. webpack.config.js
.
BTW, thanks for sharing about the Gutenberg Test Iframed Masonry Block.
本文标签: javascriptHow to add an additional dependency to a block indexassetphp file
版权声明:本文标题:javascript - How to add an additional dependency to a block index.asset.php file 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736643980a1946062.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论