我为古腾堡的自定义表单块编写了一个插件,它应该将提交保存到自定义帖子类型。目的是让作者填写一份表格,其中包含姓名、电子邮件、书籍/手稿标题、类型下拉选择、一些文本框摘要和文件上传字段。
主要问题是:
该块在编辑器中正确呈现,但取决于 UI 关于正在使用的主题。例如,GoDaddy 的 Go 主题并不 正确呈现选择框,因为它不显示默认值 “选择类型”。
下拉选择也不会保留所选选项 编辑器或 UI 给出脚本中的错误日志消息: “form-block.js?元数据或所选类型未加载”
并且,当自定义帖子类型已创建并可在 WP 中访问时 管理员,在加载前端时,浏览器控制台错误日志“发布 类型尚未加载”
一切似乎都在 php 中正确排队,但我无法确定为什么脚本没有看到自定义帖子类型,或者是什么阻止下拉列表保留所选值。
任何指导将不胜感激。
// Import necessary WordPress packages
const { registerBlockType } = wp.blocks;
const { useState, useEffect } = wp.element;
const { TextControl, SelectControl, TextareaControl, Button, FormFileUpload } = wp.components;
const { useSelect, useDispatch } = wp.data;
const FormComponent = () => {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [email, setEmail] = useState('');
const [title, setTitle] = useState('');
const [summary, setSummary] = useState('');
const [marketing, setMarketing] = useState('');
const [file, setFile] = useState(null);
const [isPostTypeLoaded, setIsPostTypeLoaded] = useState(false);
const { editPost } = useDispatch('core/editor');
//const isPostTypeReadyRef = useRef(false); // Initialize ref outside useEffect
useEffect(() => {
const checkPostType = () => {
const manuscriptConfig = wp.data.select('core').getEntityConfig('postType', 'manuscript');
if (manuscriptConfig) {
setIsPostTypeLoaded(true);
} else {
console.error('Post type not loaded yet');
}
};
checkPostType();
}, []);
const handleGenreChange = (value) => {
if (!isPostTypeLoadedRef.current) {
console.error('Post type not loaded yet');
return;
}
editPost({ meta: { _selectedGenre: value } })
.then(() => console.log('Genre updated successfully'))
.catch((error) => console.error('Error updating genre:', error));
};
const genre = useSelect((select) => {
const editedPost = select('core/editor').getEditedPostAttribute('meta');
if (editedPost && '_selectedGenre' in editedPost) {
return editedPost._selectedGenre;
}
console.warn("Meta data or selected genre not loaded.");
return ''; // Fallback if genre is not available
}, []);
return wp.element.createElement(
'div',
{ className: 'manuscript-submission-form' },
wp.element.createElement('h2', {}, 'Submit Your Manuscript'),
wp.element.createElement(TextControl, {
key: 'firstName',
label: 'First Name',
value: firstName,
onChange: (value) => setFirstName(value),
required: true,
}),
wp.element.createElement(TextControl, {
key: 'lastName',
label: 'Last Name',
value: lastName,
onChange: (value) => setLastName(value),
required: true,
}),
wp.element.createElement(TextControl, {
key: 'email',
label: 'Email Address',
type: 'email',
value: email,
onChange: (value) => setEmail(value),
required: true,
}),
wp.element.createElement(TextControl, {
key: 'title',
label: 'Manuscript Title',
value: title,
onChange: (value) => setTitle(value),
required: true,
}),
wp.element.createElement(SelectControl, {
key: 'genre',
label: 'Genre',
value: genre,
options: [
{ label: 'Select Genre', value: '' },
{ label: 'Fiction', value: 'fiction' },
{ label: 'Non-fiction', value: 'non-fiction' },
{ label: 'Science Fiction', value: 'sci-fi' },
{ label: 'Fantasy', value: 'fantasy' },
],
onChange: handleGenreChange,
}),
wp.element.createElement(TextareaControl, {
key: 'summary',
label: 'Manuscript Summary',
value: summary,
onChange: (value) => setSummary(value),
required: true,
}),
wp.element.createElement(TextareaControl, {
key: 'marketing',
label: 'Marketing Suggestions',
value: marketing,
onChange: (value) => setMarketing(value),
}),
wp.element.createElement(FormFileUpload, {
key: 'fileUpload',
accept: "image/jpeg, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.oasis.opendocument.text",
onChange: (event) => setFile(event.target.files[0]),
multiple: false,
children: 'Upload Manuscript',
}),
file ? wp.element.createElement('p', {}, `Selected file: ${file.name}`) : null,
wp.element.createElement(
'div',
{ style: { textAlign: 'right', marginTop: '20px' } },
wp.element.createElement(Button, {
isPrimary: true,
onClick: () => console.log({ firstName, lastName, email, title, genre, summary, marketing, file }), // Add submission logic
}, 'Submit')
)
);
};
// Register the block
registerBlockType('authors-form/manuscript-submission-form', {
title: 'Manuscript Submission Form',
icon: 'smiley',
category: 'common',
edit: () => {
return wp.element.createElement(FormComponent);
},
save: () => null // Dynamic block; rendered by PHP callback
});
// Front-end mounting
document.addEventListener('DOMContentLoaded', () => {
const formContainer = document.getElementById('manuscript-submission-form');
if (formContainer) {
wp.element.render(
wp.element.createElement(FormComponent),
formContainer
);
}
});
useEntityProp
钩子从当前帖子中获取和设置元值。下面的示例显示您将进行设置。
import { SelectControl } from '@wordpress/components';
import { useEntityProp } from '@wordpress/core-data';
const FormComponent = () => {
const [meta, setMeta] = useEntityProp('postType', 'manuscript', 'meta');
const handleGenreChange = (value) => {
setMeta({
...meta,
_selectedGenre: value
});
}
return (
<div className='manuscript-submission-form'>
<SelectControl
key='genre'
label='Genre'
value={meta?._selectedGenre}
onChange={handleGenreChange}
required={true}
/>
</div>
)
};
在您的
handleGenreChange
中,您检查 current
的 isPostTypeLoaded
属性,因为它是一个引用值,但实际上它是具有布尔值的状态。因此,它将始终评估为 false
并显示 'Post type not loaded yet'
消息。