我试图通过Gutenberg组件将图像的URL和ID存储在帖子的元字段中,但我很难弄清楚如何将这些多个值存储在一个数组中。
我可以毫无问题地将单个值存储为元值。我甚至可以毫无问题地将单个值存储在数组的第一个位置。但我似乎无法找到合适的语法来利用Wordpress将数组存储为元值的能力。
总体目标是覆盖在社交媒体上分享帖子时使用的图像。问题是,我需要将URL和ID都传输到PHP挂钩,以便它能够与插件(SEO框架)正常工作。不幸的是,我不能只存储ID,因为我需要URL来在Gutenberg组件中呈现图像。
完整组件代码:
const OGImage = compose(
withDispatch( function( dispatch, props ) {
return {
setMetaValue: function( metaValue ) {
dispatch( \'core/editor\' ).editPost(
{ meta: { [ props.metaKey ]: metaValue } }
);
}
}
} ),
withSelect( function( select, props ) {
return {
metaValue: select( \'core/editor\' ).getEditedPostAttribute( \'meta\' )[ props.metaKey ]
}
} ) )( function( props ) {
const fallbackInstructions = <p>{ __( \'To edit the OG image, you need permission to upload media.\', \'atlantis\') }</p>;
const onUpdateImage = img => { props.setMetaValue( img.url ); };
const onRemoveImage = () => { props.setMetaValue( null ); };
return (
<div className="og-image__wrapper">
<MediaUploadCheck fallback={ fallbackInstructions }>
<MediaUpload
title={ OG_IMAGE_LABEL }
onSelect={ onUpdateImage }
allowedTypes={ ALLOWED_MEDIA_TYPES }
render={ ( { open } ) => (
<Button
className={ ! props.metaValue ? \'og-image__toggle\' : \'og-image__preview\' }
onClick={ open }
aria-label={ ! props.metaValue ? null : EDIT_OR_UPDATE_OG_IMAGE_LABEL }>
{ !! props.metaValue &&
<img className=\'og-image__button\' src={ props.metaValue } alt="" />
}
{ ! props.metaValue && SET_OG_IMAGE_LABEL }
</Button>
) }
/>
</MediaUploadCheck>
{ !! props.metaValue &&
<MediaUploadCheck>
<MediaUpload
title={ OG_IMAGE_LABEL }
onSelect={ onUpdateImage }
allowedTypes={ ALLOWED_MEDIA_TYPES }
render={ ( { open } ) => (
<Button onClick={ open } isDefault isLarge>
{ REPLACE_OG_IMAGE_LABEL }
</Button>
) }
/>
</MediaUploadCheck>
}
{ !! props.metaValue &&
<MediaUploadCheck>
<Button onClick={ onRemoveImage } isLink isDestructive>
{ REMOVE_OG_IMAGE_LABEL }
</Button>
</MediaUploadCheck>
}
</div>
);
}
);
export default OGImage;
重要的位:
const OGImage = compose(
withDispatch( function( dispatch, props ) {
return {
setMetaValue: function( metaValue ) {
dispatch( \'core/editor\' ).editPost(
{ meta: { [ props.metaKey ]: metaValue } }
);
}
}
} ),
withSelect( function( select, props ) {
return {
metaValue: select( \'core/editor\' ).getEditedPostAttribute( \'meta\' )[ props.metaKey ]
}
} ) )( function( props ) {
const onUpdateImage = img => { props.setMetaValue( img.url ); };
return (
<img className=\'og-image__button\' src={ props.metaValue } alt="" />
);
}
);
export default OGImage;
我的最佳解决方案是这样做,但这只存储指定的第一个值(因此在本例中,[img.url]):
const onUpdateImage = img => { props.setMetaValue( img.url, img.id ); };
...
<img className=\'og-image__button\' src={ props.metaValue[0] } alt="" />
甚至:
const onUpdateImage = img => { props.setMetaValue( [img.url, img.id] ); };
...
<img className=\'og-image__button\' src={ props.metaValue[0] } alt="" />
我将元值声明为:
register_meta(
\'post\',
\'_og_image\',
[
\'show_in_rest\' => true,
\'single\' => false,
\'type\' => \'string\'
]
);
作为最后的努力,我正在考虑将图像URL和ID组合成一个字符串,并在两端对其进行解析。这个解决方案让我觉得很粗糙,我更愿意将这两个值独立存储为一个数组。
这是一个crosspost.
Tom附录。这曾经奏效过——我想是出于某种奇怪的侥幸——但我无法复制它。图像url正在更改,但图像id拒绝保存在元值中。
PHP
function set_og_image() {
register_meta(
\'post\',
\'og_image_url\',
[
\'show_in_rest\' => true,
\'single\' => true,
\'type\' => \'string\'
]
);
register_meta(
\'post\',
\'og_image_id\',
[
\'show_in_rest\' => true,
\'single\' => true,
\'type\' => \'string\' // Solution (thank you to Tom): This needs to be an integer type.
]
);
}
JS公司
const OGImage = compose(
withDispatch( function( dispatch, props ) {
return {
setMetaValue: function( metaKey, metaValue ) {
dispatch( \'core/editor\' ).editPost(
{ meta: { [ metaKey ]: metaValue } }
);
}
}
} ),
withSelect( function( select, props ) {
return {
metaValueURL: select( \'core/editor\' ).getEditedPostAttribute( \'meta\' )[ \'og_image_url\' ],
metaValueID: select( \'core/editor\' ).getEditedPostAttribute( \'meta\' )[ \'og_image_id\' ]
}
} ) )( function( props ) {
const onUpdateImage = img => {
props.setMetaValue( \'og_image_url\', img.url );
props.setMetaValue( \'og_image_id\', img.id );
};
const onRemoveImage = () => {
props.setMetaValue( props.metaKeyURL, null );
props.setMetaValue( props.metaKeyID, null );
};
return (
...
);
}
);
父组件:
const { __ } = wp.i18n;
const { Fragment } = wp.element;
const { PanelBody, PanelRow } = wp.components;
const { registerPlugin } = wp.plugins;
const { PluginSidebar, PluginSidebarMoreMenuItem } = wp.editPost;
import OGImage from \'./components/og-image\';
const GenericSidebar = props => {
return (
<Fragment>
<PluginSidebarMoreMenuItem target="generic-sidebar">
{__("Generic Sidebar", "atlantis")}
</PluginSidebarMoreMenuItem>
<PluginSidebar
name="generic-sidebar"
title={__("Generic Sidebar", "atlantis")}
>
<PanelBody title={__("OG Image", "atlantis")} >
<PanelRow>
<OGImage
metaKeyURL = { \'og_image_url\' }
metaKeyID = { \'og_image_id\' }
/>
</PanelRow>
</PanelBody>
</PluginSidebar>
</Fragment>
);
};
registerPlugin("generic-sidebar", {
icon: "visibility",
render: GenericSidebar
});