ブロックのテンプレートを作詞
my-custom-blocks/srcにpick-up-articleフォルダを作成
block.json
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "my-custom-blocks/pick-up-article",
"title": "ピックアップ記事",
"description": "ピックアップ記事です",
"category": "text",
"attributes": {},
"textdomain": "my-custom-blocks",
"editorScript": "file:./index.js",
"style": "file:./style-index.css"
}
index.js
import { registerBlockType } from "@wordpress/blocks";
import Edit from "./edit.js";
import metadata from "./block.json";
registerBlockType(metadata.name, {
edit: Edit,
});
edit.js
export default function Edit() {
return <>ピックアップ記事</>;
}
index.php
<?php
function my_custom_block_pick_up_article_render_callback(){
return '<p>render_callbackで実行される関数</p>';
}
function my_custom_block_register_block_pick_up_article(){
register_block_type(
__DIR__,
array(
'render_callback'=>'my_custom_block_pick_up_article_render_callback'
)
);
}
add_action('init', 'my_custom_block_register_block_pick_up_article');
my-custom-blocks.php
function create_block_my_custom_blocks_block_init() {
register_block_type( __DIR__ . '/build/balloon' );
}
add_action( 'init', 'create_block_my_custom_blocks_block_init' );
//追記
require plugin_dir_path(__FILE__). 'build/pick-up-article/index.php';
ビルド npm run build
index.phpがビルドに含まれないので、package.jsonを編集し、–webpack-copy-phpを追加
"scripts": {
"build": "wp-scripts build --webpack-copy-php"
"start": "wp-scripts start --webpack-copy-php",
},
再ビルドし、エディターにブロックが読み込まれていることを確認する
エディターには「ピックアップ記事」と表示される。
フロントエンドには「render_callbackで実行される関数」が表示される。
エディター画面を作成
edit.js
import { useBlockProps, InspectorControls } from "@wordpress/block-editor";
import ServerSideRender from "@wordpress/server-side-render";
import { useSelect } from "@wordpress/data";
import { PanelBody, BaseControl } from "@wordpress/components";
export default function Edit(props) {
const { attributes, setAttributes } = props;
const { pickUpArticleIdLists } = attributes;
// サイドパネルに記事のIDを保存機能を追加する
// WordPressのデータから保存記事リストを取得
const post = useSelect((select) => {
return select("core").getEntityRecords("postType", "post");
}, []);
console.log("post:", post);
return (
<>
<div {...useBlockProps()}>
{/* フロント表示と合わせるため、ServerSideRenderを呼び出す */}
{/* blockには対象のブロック名をblock.jsonより転記する */}
<ServerSideRender block="my-custom-blocks/pick-up-article" />
</div>
</>
);
}
import { useBlockProps, InspectorControls } from "@wordpress/block-editor";
import ServerSideRender from "@wordpress/server-side-render";
import { useSelect } from "@wordpress/data";
import { PanelBody, BaseControl } from "@wordpress/components";
export default function Edit(props) {
const { attributes, setAttributes } = props;
const { pickUpArticleIdLists } = attributes;
// サイドパネルに記事のIDを保存機能を追加する
// WordPressのデータから保存記事リストを取得
const post = useSelect((select) => {
return select("core").getEntityRecords("postType", "post");
}, []);
console.log("post:", post);
return (
<>
<InspectorControls>
<PanelBody title="設定">
<BaseControl>
{/* postがnullの場合エラーのなるため、lengthのチェックを挟む */}
{post?.length &&
// map関数:与えられた関数を配列のすべての要素に対して呼び出し、その結果からなる新しい配列を生成
post.map((page) => (
<div key={page.id}>{page.title.rendered}</div>
))}
</BaseControl>
</PanelBody>
</InspectorControls>
サイドパネルに記事選択用のチェックボックスを作成
edit.js
import { PanelBody, BaseControl, CheckboxControl } from "@wordpress/components";
<InspectorControls>
<PanelBody title="設定">
<BaseControl>
{/* postがnullの場合エラーのなるため、lengthのチェックを挟む */}
{post?.length &&
// map関数:与えられた関数を配列のすべての要素に対して呼び出し、その結果からなる新しい配列を生成
post.map((page) => (
<div key={page.id}>
{/* {page.title.rendered} */}
<CheckboxControl
label={page.title.rendered}
checked={pickUpArticleIdLists.includes(page.id)}
onChange={() => {
const newPickUpArticleIdLists =
pickUpArticleIdLists.includes(page.id)
? pickUpArticleIdLists.filter(
(item) => item !== page.id,
)
: [...pickUpArticleIdLists, page.id];
setAttributes({
pickUpArticleIdLists: newPickUpArticleIdLists,
});
}}
/>
</div>
))}
</BaseControl>
</PanelBody>
</InspectorControls>
記事の絞り込み機能を追加
edit.js
import {
PanelBody,
BaseControl,
CheckboxControl,
SearchControl,
} from "@wordpress/components";
import { useState } from "@wordpress/element";
const [searchTerm, setSearchTerm] = useState();
// サイドパネルに記事のIDを保存機能を追加する
// WordPressのデータから保存記事リストを取得
const post = useSelect(
(select) => {
const query = {};
if (searchTerm) {
query.search = searchTerm;
}
return select("core").getEntityRecords("postType", "post", query);
},
[searchTerm],
);
<InspectorControls>
<PanelBody title="設定">
<BaseControl>
<SearchControl
onChange={(value) => setSearchTerm(value)}
value={searchTerm}
/>
検索中はローディング画面を表示する
edit.js
import { useBlockProps, InspectorControls } from "@wordpress/block-editor";
import ServerSideRender from "@wordpress/server-side-render";
import { useSelect } from "@wordpress/data";
import {
PanelBody,
BaseControl,
CheckboxControl,
SearchControl,
Spinner,
} from "@wordpress/components";
import { useState } from "@wordpress/element";
export default function Edit(props) {
const { attributes, setAttributes } = props;
const { pickUpArticleIdLists } = attributes;
const [searchTerm, setSearchTerm] = useState();
// サイドパネルに記事のIDを保存機能を追加する
// WordPressのデータから保存記事リストを取得
const { post, hasResolved } = useSelect(
(select) => {
const query = {};
if (searchTerm) {
query.search = searchTerm;
}
const selectorArgs = ["postType", "post", query];
return {
post: select("core").getEntityRecords(...selectorArgs),
hasResolved: select("core").hasFinishedResolution(
"getEntityRecords",
selectorArgs,
),
};
},
[searchTerm],
);
console.log("post:", post);
return (
<>
<InspectorControls>
<PanelBody title="設定">
<BaseControl>
<SearchControl
onChange={(value) => setSearchTerm(value)}
value={searchTerm}
/>
{!hasResolved && <Spinner />}
{hasResolved && post.length === 0 && <div>検索結果なし</div>}
{/* postがnullの場合エラーのなるため、lengthのチェックを挟む */}
{hasResolved && post?.length > 0 && (
// map関数:与えられた関数を配列のすべての要素に対して呼び出し、その結果からなる新しい配列を生成
<div
style={{
height: "100px",
overflow: "scroll",
border: '1px, solid, "eeeeee',
padding: "1opx",
}}
>
{post.map((page) => (
<div
key={page.id}
style={{
padding: "8px 10px 0",
borderBottom: "1px, solid #cccccc",
}}
>
{/* {page.title.rendered} */}
<CheckboxControl
label={page.title.rendered}
checked={pickUpArticleIdLists.includes(page.id)}
onChange={() => {
const newPickUpArticleIdLists =
pickUpArticleIdLists.includes(page.id)
? pickUpArticleIdLists.filter(
(item) => item !== page.id,
)
: [...pickUpArticleIdLists, page.id];
setAttributes({
pickUpArticleIdLists: newPickUpArticleIdLists,
});
}}
/>
</div>
))}
</div>
)}
</BaseControl>
</PanelBody>
</InspectorControls>
<div {...useBlockProps()}>
{/* フロント表示と合わせるため、ServerSideRenderを呼び出す */}
{/* blockには対象のブロック名をblock.jsonより転記する */}
<ServerSideRender block="my-custom-blocks/pick-up-article" />
</div>
</>
);
}
レンダリングコンテンツの作成
index.php
<?php
function my_custom_block_pick_up_article_render_callback($attributes){
$pick_up_articles_id_lists = isset($attributes['pickUpArticleIdLists'])? $attributes['pickUpArticleIdLists'] : array();
if(empty($pick_up_articles_id_lists)){
return null;
}
$query = new WP_Query();
$posts = $query->query(
array(
'post_type' => 'post',
'orderby'=> 'post__in',
'post__in' => $pick_up_articles_id_lists,
)
);
$pick_up_article_html = '';
foreach ($posts as $post){
$post_link = esc_url(get_permalink($post));
$title = get_the_title($post);
$featured_image = get_the_post_thumbnail($post, 'post-thumbnail');
if(!$title){
$title = 'タイトルなし';
}
$pick_up_article_html .= '<div class"my-custom-blocks-pick-up-article">';
if($featured_image) {
$pick_up_article_html .= sprintf(
'<div class="my-custom-blocks-pick-up-image"><a href="%1$s">%2$s</a></div>',
$post_link,
$featured_image
);
}
$pick_up_article_html .= sprintf(
'<h3 class="my-custom-blocks-pick-up-title"><a href="%1$s">%2$s</a></h3>',
$post_link,
$title
);
$pick_up_article_html .= '</div>';
};
wp_reset_postdata();
return $pick_up_article_html;
}
function my_custom_block_register_block_pick_up_article(){
register_block_type(
__DIR__,
array(
'render_callback'=>'my_custom_block_pick_up_article_render_callback'
)
);
}
add_action('init', 'my_custom_block_register_block_pick_up_article');
edit.js
<ServerSideRender
block="my-custom-blocks/pick-up-article"
attributes={ attributes }
/>
ブロックにラッパークラスを追加
index.php
$wrapper_attributes = get_block_wrapper_attributes();
return sprintf(
'<div $1$s>%s$s</div>',
$wrapper_attributes,
$pick_up_article_html
);
幅広、全幅をサポート
block.json
"supports": {
"align": ["wide", "full"],
"spacing": {
"padding": true,
"margin": true
}
},