admin管理员组

文章数量:1122832

I'm trying to create a block that displays post meta data for each post displayed by the Query Loop Block, specifically a link with a different URL for each post.

The issue I've ran into, is that it seems impossible to retrieve the postIDs of the looped posts. Is there a way to retrieve or pass the ids of the posts being queried to a nested block? How do blocks like the Post Title or Post Excerpt block handle this?

Here is an excerpt of my edit.js:

const Edit = ({context}) => {
const blockProps = useBlockProps();

const metaValue = useSelect((select) => {
    const { getEntityRecord } = select('core'); 
    const { getCurrentPostId } = select('core/editor');
    const currentPostId = getCurrentPostId();

    if (!currentPostId) {
        return null;
    }

    // Get the meta for the post with the current post ID
    const post = getEntityRecord('postType', 'portfolio', currentPostId);
    return post && post.meta ? post.meta['custom_link_text'] : null;
}, []);

// Show spinner while meta is loading
if (metaValue === undefined) {
    return (
        <div { ...blockProps }>
            <Spinner />
        </div>
    );
}

// If no meta is set, show placeholder text
if (!metaValue) {
    return (
        <div { ...blockProps }>
            <Placeholder 
                icon="admin-post" 
                label={__('No meta data available', 'linkplugin')}
                instructions={__('Display meta value here.', 'linkplugin')}
            />
        </div>
    );
}

// Render the post meta value
return (
    <div { ...blockProps }>
        <p>{__('Meta Value:', 'linkplugin')} {metaValue}</p>
    </div>
);

};

I'm trying to create a block that displays post meta data for each post displayed by the Query Loop Block, specifically a link with a different URL for each post.

The issue I've ran into, is that it seems impossible to retrieve the postIDs of the looped posts. Is there a way to retrieve or pass the ids of the posts being queried to a nested block? How do blocks like the Post Title or Post Excerpt block handle this?

Here is an excerpt of my edit.js:

const Edit = ({context}) => {
const blockProps = useBlockProps();

const metaValue = useSelect((select) => {
    const { getEntityRecord } = select('core'); 
    const { getCurrentPostId } = select('core/editor');
    const currentPostId = getCurrentPostId();

    if (!currentPostId) {
        return null;
    }

    // Get the meta for the post with the current post ID
    const post = getEntityRecord('postType', 'portfolio', currentPostId);
    return post && post.meta ? post.meta['custom_link_text'] : null;
}, []);

// Show spinner while meta is loading
if (metaValue === undefined) {
    return (
        <div { ...blockProps }>
            <Spinner />
        </div>
    );
}

// If no meta is set, show placeholder text
if (!metaValue) {
    return (
        <div { ...blockProps }>
            <Placeholder 
                icon="admin-post" 
                label={__('No meta data available', 'linkplugin')}
                instructions={__('Display meta value here.', 'linkplugin')}
            />
        </div>
    );
}

// Render the post meta value
return (
    <div { ...blockProps }>
        <p>{__('Meta Value:', 'linkplugin')} {metaValue}</p>
    </div>
);

};

Share Improve this question asked Oct 12, 2024 at 5:22 kathkath 6212 gold badges8 silver badges21 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 3

You don't want to use getCurrentPostId() from the core/editor store. This gets the current post ID from the post being edited, not the post in the query loop.

To get that, ensure your block accepts postId (and possibly postType) as block context values via the usesContext key in the block type metadata. This can be added in the block.json:

{
    "$schema": "https://schemas.wp.org/wp/6.6/block.json",
    "apiVersion": 3,
    "name": "vendor/block-name",
    …
    "usesContext": [
        "postId",
        "postType"
    ]
}

These values will then be available in the context prop that the edit component is given:

const Edit = ( { context } ) => {
    const blockProps = useBlockProps();

    const metaValue = useSelect( ( select ) => {
        const { getEntityRecord } = select( 'core' ); 
        
        if ( ! context.postId ) {
            return null;
        }

        // Get the meta for the post with the current post ID
        const post = getEntityRecord( 'postType', context.postType, context.postId );
        return post && post.meta ? post.meta['custom_link_text'] : null;
    }, [ context.postId, context.postType ] );

Presumably, this is a dynamic block with PHP-generated mark-up. If so, you may wish to consider using the same context values server-side for consistency:

<?php
// In `render.php` or similar.

$post_id = $block->context['postId'];

本文标签: Block that displays post meta as nested block of Query Loop