如何在前端 UI 中从自定义 WordPress 块正确渲染表单?

问题描述 投票:0回答:1

我为古腾堡的自定义表单块编写了一个插件,它应该将提交保存到自定义帖子类型。目的是让作者填写一份表格,其中包含姓名、电子邮件、书籍/手稿标题、类型下拉选择、一些文本框摘要和文件上传字段。

主要问题是:

  1. 该块在编辑器中正确呈现,但取决于 UI 关于正在使用的主题。例如,GoDaddy 的 Go 主题并不 正确呈现选择框,因为它不显示默认值 “选择类型”。

  2. 下拉选择也不会保留所选选项 编辑器或 UI 给出脚本中的错误日志消息: “form-block.js?元数据或所选类型未加载”

  3. 并且,当自定义帖子类型已创建并可在 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
        );
    }
});

wordpress wordpress-gutenberg
1个回答
0
投票

我建议使用

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'
消息。

© www.soinside.com 2019 - 2024. All rights reserved.