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> </> ); } 
2
  • can you clarify what the question is? You've explained your situation but it's not clear what you want answered. Also I'm not seeing any reason for not using the built in query loop block, other than that your version hardcodes some inner templates in JS, something which could be done instead with locked patterns in combination with registering a variant of the query block. If the problem is that you want a shorter file, then you only need to remember that these are react components, don't think of them as the edit component. Create a new component in another file and import it
    – Tom J Nowell
    CommentedMar 12 at 15:43
  • I am creating a theme that works via Tailwind CSS and I need each block to correspond to an HTML block. Each block will then have a field where you can insert Tailwind CSS classes that in real time display the graphics I want. Unfortunately, many Gutenberg blocks use extra code that would not then allow the graphics I want. So I preferred to redo it to make it work with what I want.CommentedMar 13 at 15:24

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.