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

javascript - Create a Query Loop block

programmeradmin7浏览0评论

I am creating a Query Loop block that retrieves post type, similar to Gutenberg's, but for various reasons I need to create one.

Currently the code I am using is as follows and it works, but I would prefer the various internal blocks to use their own edit.js file.

Currently they use what is given in this file instead.

edit.js

/**
 * WordPress dependencies
 */
import { __ } from "@wordpress/i18n";
import {
    useBlockProps,
    useInnerBlocksProps,
    store as blockEditorStore,
} from "@wordpress/block-editor";
import { useSelect } from "@wordpress/data";
import { store as coreStore } from "@wordpress/core-data";
import QueryInspectorControls from "./inspector-controls";
import React from "react";

/**
 * Edit component
 *
 * @param {Object} props
 * @param {Object} props.attributes
 * @param {Object} props.setAttributes
 * @param {string} props.clientId
 */
export default function Edit({ attributes, setAttributes, clientId }) {
    const { query } = attributes;
    const blockProps = useBlockProps();

    // Get Posts
    const { posts, isResolving, templateBlock } = useSelect(
        (select) => {
            const { getEntityRecords, isResolving } = select(coreStore);
            const { getBlocks } = select(blockEditorStore);

            // Find block
            const innerBlocks = getBlocks(clientId);
            const template = innerBlocks.find(
                (block) => block.name === "prismatic/post-type-template",
            );

            return {
                posts: getEntityRecords("postType", query.postType, {
                    per_page: query.perPage,
                    offset: query.offset,
                    orderby: query.orderBy,
                    order: query.order,
                    _embed: true,
                    ...(query.authors?.length && {
                        author: query.authors.join(","),
                    }),
                    ...(query.search?.length && {
                        search: query.search.join(" "),
                    }),
                    ...(query.postType === "page" &&
                        query.parents?.length && {
                            parent: query.parents[0],
                        }),
                    ...(query.taxQuery && {
                        tax_query: Object.entries(query.taxQuery)
                            .filter(([key]) => !key.includes("_relation"))
                            .map(([taxonomy, terms]) => ({
                                taxonomy,
                                terms,
                                operator:
                                    query.taxQuery[`${taxonomy}_relation`] === "AND"
                                        ? "AND"
                                        : "IN",
                            })),
                    }),
                }),
                isResolving: isResolving("getEntityRecords", [
                    "postType",
                    query.postType,
                ]),
                templateBlock: template,
            };
        },
        [query, clientId],
    );

    // Template
    const innerBlocksProps = useInnerBlocksProps(
        {
            style: { display: "none" },
        },
        {
            template: [["prismatic/post-type-template"]],
            allowedBlocks: ["prismatic/post-type-template"],
        },
    );

    // Item rendering
    function QueryPostTypeItem({ post, templateBlock }) {
        if (!templateBlock || !post) return null;

        return (
            <div
                className={templateBlock.attributes.className || ""}
                data-id={post.id}
            >
                {templateBlock.innerBlocks.map((block) => {
                    if (block.name === "prismatic/post-type-featured-image") {
                        const imageUrl =
                            post._embedded?.["wp:featuredmedia"]?.[0]?.source_url;
                        const imageAlt =
                            post._embedded?.["wp:featuredmedia"]?.[0]?.alt_text || "";

                        if (!imageUrl) return null;

                        return (
                            <img
                                key={block.clientId}
                                src={imageUrl}
                                alt={imageAlt}
                                className={block.attributes.className || ""}
                            />
                        );
                    }

                    if (block.name === "prismatic/post-type-title") {
                        const TagName = block.attributes.tagName || "p";
                        return (
                            <TagName
                                key={block.clientId}
                                className={block.attributes.className || ""}
                            >
                                {post.title.rendered}
                            </TagName>
                        );
                    }

                    if (block.name === "prismatic/post-type-excerpt") {
                        const excerpt = post.excerpt?.rendered || "";
                        const words = block.attributes.words || 25;
                        const strippedExcerpt = excerpt.replace(/<\/?[^>]+(>|$)/g, "");
                        const trimmedExcerpt =
                            strippedExcerpt.split(" ").slice(0, words).join(" ") + "...";

                        return (
                            <p
                                key={block.clientId}
                                className={block.attributes.className || ""}
                                dangerouslySetInnerHTML={{ __html: trimmedExcerpt }}
                            />
                        );
                    }

                    if (block.name === "prismatic/post-type-button") {
                        const text =
                            block.attributes.text || __("Leggi tutto", "prismatic");
                        return (
                            <a
                                key={block.clientId}
                                className={block.attributes.className || ""}
                                href={post.link}
                            >
                                {text}
                            </a>
                        );
                    }

                    return null;
                })}
            </div>
        );
    }

    // Loop
    function QueryPostTypeLoop({ posts, templateBlock }) {
        if (!posts) return null;

        return (
            <>
                {posts.map((post) => (
                    <QueryPostTypeItem
                        key={post.id}
                        post={post}
                        templateBlock={templateBlock}
                    />
                ))}
            </>
        );
    }

    return (
        <>
            <QueryInspectorControls
                attributes={attributes}
                setAttributes={setAttributes}
            />

            <div {...blockProps}>
                {isResolving ? (
                    <p>{__("Loading...", "prismatic")}</p>
                ) : !posts?.length ? (
                    <p>{__("No content.", "prismatic")}</p>
                ) : (
                    <>
                        <div {...innerBlocksProps} />

                        <QueryPostTypeLoop posts={posts} templateBlock={templateBlock} />
                    </>
                )}
            </div>
        </>
    );
}
发布评论

评论列表(0)

  1. 暂无评论