最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to make a drop down panel in the editor that writes to the post's custom fields without updating the post(wp 5.8)

programmeradmin6浏览0评论

I want a sidebar panel in the post editor where a user can pick an assignee and an editor for a post. The post will be populated by a list of every user on the site. When the page loads, I want the current value to be highlighted.

So far I have this as my component (not pictured is the functions.php file where I register the custom fields):

/**
 * React.
 */
import React, { useState, useEffect } from 'react';

/**
 * WordPress dependencies.
 */
import { useSelect, useDispatch } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
import { store as editorStore } from '@wordpress/editor';
import { PluginDocumentSettingPanel } from '@wordpress/edit-post';
import { SelectControl, PanelRow, Button, Notice, Spinner } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

/**
 * Assignee and Editor Settings Panel.
 */
export default function AssigneeAndEditorSettingsPanel(): JSX.Element {
    // Get post type, post ID, and meta fields.
    const { postType, postId, meta } = useSelect((select) => {
        return {
            postType: select(editorStore).getCurrentPostType(),
            postId: select(editorStore).getCurrentPostId(),
            meta: select(editorStore).getEditedPostAttribute('meta'),
        };
    }, []);

    // Local state for selected users.


    const [selectedAssignee, setSelectedAssignee] = useState(meta?.assignee || '');
    const [selectedEditor, setSelectedEditor] = useState(meta?.editor || '');
    const [loading, setLoading] = useState(false);
    const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null);

    // Update state when meta values change.
    useEffect(() => {
        setSelectedAssignee(meta?.assignee || '');
        setSelectedEditor(meta?.editor || '');
    }, [meta]);

    // Get all users for dropdown.
    const users = useSelect((select) => {
        return select(coreStore).getEntityRecords('root', 'user', { per_page: -1 }) || [];
    }, []);

    const { editEntityRecord, saveEntityRecord } = useDispatch(coreStore);

    const saveAssigneeAndEditor = async () => {
        setLoading(true);
        setMessage(null);

        try {
            console.log('Saving post meta for post ID:', postId);
            console.log('Post type:', postType);
            console.log('New meta:', { assignee: selectedAssignee, editor: selectedEditor });

            // Update entity record
            editEntityRecord('postType', postType, postId, {
                meta: {
                    assignee: selectedAssignee || '',
                    editor: selectedEditor || '',
                },
            });

            // Save and check response
            const response = await saveEntityRecord('postType', postType, postId);

            console.log('Save response:', response);

            if (response) {
                setMessage({ type: 'success', text: __('Changes saved.', 'text-domain') });
            } else {
                throw new Error('No response returned.');
            }
        } catch (error) {
            console.error('Save Error:', error);
            setMessage({ type: 'error', text: __('Failed to save changes.', 'text-domain') });
        } finally {
            setLoading(false);
        }
    };
    return (
        <PluginDocumentSettingPanel
            name="assignee-and-editor-settings-panel"
            title={__('Assignee & Editor', 'text-domain')}
            className="assignee-and-editor-settings-panel"
        >
            <PanelRow>
                <SelectControl
                    label={__('Assignee', 'text-domain')}
                    value={selectedAssignee}
                    options={[
                        { label: __('Select an Assignee', 'text-domain'), value: '' },
                        ...users.map((user) => ({ label: user.name, value: user.id })),
                    ]}
                    onChange={setSelectedAssignee} // Only updates local state
                />
            </PanelRow>
            <PanelRow>
                <SelectControl
                    label={__('Editor', 'text-domain')}
                    value={selectedEditor}
                    options={[
                        { label: __('Select an Editor', 'text-domain'), value: '' },
                        ...users.map((user) => ({ label: user.name, value: user.id })),
                    ]}
                    onChange={setSelectedEditor} // Only updates local state
                />
            </PanelRow>

            {/* Save Button */}
            <PanelRow>
                <Button isPrimary onClick={saveAssigneeAndEditor} disabled={loading}>
                    {loading ? <Spinner /> : __('Save Changes', 'text-domain')}
                </Button>
            </PanelRow>

            {/* Success/Error Notice */}
            {message && (
                <Notice status={message.type} onRemove={() => setMessage(null)}>
                    {message.text}
                </Notice>
            )}
        </PluginDocumentSettingPanel>
    );
}

The issue is that I need to hit the "update" button on top to write these to the db. Is there a way to make them write to custom fields when I hit the button?

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论