できる限りカスタムブロックは作らずに、コアブロックで対応するのがベストだと思います
あくまでも ・・・・・
WordPress5.8のリリースから、ブロックタイプを登録する標準の方法として、block.json メタデータファイルの使用が推奨されています
wordpress.org
らしいのでw 、備忘録としてまとめようと思います
- スクリプトにブロックの登録は書かなくてよい
- ブロック用ファイルの読み込みがほぼ自動(@wordpress/scripts パッケージを利用した場合)
- 目次
「ブロック」の仕組みをざっくりと
「ブロックエディタ」の「ブロック」は「Block API規定のプロパティ集合をもったJSONオブジェクト」です
「JSONオブジェクト」として格納された「ブロックタイプ」を処理することで「PHPとJavaScript」でコードの共有が可能になります
なんとなくのイメージ図💦
const block = { clientId, // ユニークな文字列識別子。 type, // ブロックタイプ (paragraph, image...) attributes, // (キー, 値) 現行ブロックの直接のプロパティやコンテンツを表す属性の集合 innerBlocks // 子ブロックやインナーブロックの集合 }
開発環境の準備
「カスタムブロック」は「プラグイン」として作成してサイトに追加します
最低限必要なファイルは
- PHPファイル(プラグインヘッダとブロック用のスクリプトやスタイルの読み込み用)
- JavaScriptファイル(ブロックの実装用)
- block.jsonファイル(ブロックタイプを登録用のメタデータファイル)
「ブロックエディタ(Gutenberg)」は「React」で開発されていて、JSX構文をつかうならコンパイルが必要です
通常は「webpackのようなモジュールバンドラー」を使って開発します
「@wordpress/create-block」というブロック開発用のパッケージが用意されています
ビルド環境はnpx @wordpress/create-block ファイルの保管場所
を実行すればすぐに準備できます
*通常はプラグインディレクトリ wp-content/pluginsに移動して実行します
phpファイル
プラグインヘッダとブロック用のファイル(js css)依存関係を解決して読み込む設定です
init(プラグインの初期化)のタイミングで「register_block_type関数」を実行
*@wordpress/scriptsパッケージを利用するとシンプルになります
これだけて登録完了!!
<?php
/*
Plugin Name: test
*/
// *直接ファイルにアクセスされた場合exitするように追記
if ( !defined( 'ABSPATH' ) ) {
exit;
}
//@wordpress/scriptsパッケージをつかうとシンプルになります
function create_block_test_block_init() {
register_block_type( __DIR__ );
}
add_action( 'init', 'create_block_test_block_init' );
register_block_type関数
第1引数は「 block.jsonファイル」のあるフォルダへのパス(名前が異なるときはフルパス)
第2引数は配列でブロックをレンダーする際に使用されるコールバック
ちなみに、register_block_type関数の第1引数の__DIR__
(ファイルがあるフォルダへのパス)で「 block.jsonファイル」が同じ階層にある前提でブロックタイプを登録しています
block.jsonファイル
*例としてドキュメントからコピーしてきたもの
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "my-plugin/notice",
"title": "Notice",
"category": "text",
"parent": [ "core/group" ],
"icon": "star",
"description": "Shows warning, error or success notices…",
"keywords": [ "alert", "message" ],
"version": "1.0.3",
"textdomain": "my-plugin",
"attributes": {
"message": {
"type": "string",
"source": "html",
"selector": ".message"
}
},
"providesContext": {
"my-plugin/message": "message"
},
"usesContext": [ "groupId" ],
"supports": {
"align": true
},
"styles": [
{ "name": "default", "label": "Default", "isDefault": true },
{ "name": "other", "label": "Other" }
],
"example": {
"attributes": {
"message": "This is a notice!"
}
},
"editorScript": "file:./build/index.js",
"script": "file:./build/script.js",
"viewScript": "file:./build/view.js",
"editorStyle": "file:./build/index.css",
"style": "file:./build/style.css"
}
「editorScript・script・viewScript・editorStyle・style」は、「wp_register_script」 と 「wp_register_style 」でスクリプトとスタイルを登録するときに必要なパラメータです
「block.jsonファイル」からの相対パス(接頭辞 file:をつける)を書くと、ビルド時にbuild/index.asset.phpが作成され依存関係が定義されます
*stringのサブタイプ(WPDefinedAsset)で指定するそうですw
要するに
こんな感じで「register_block_typeの第二引数のキー」で「wp_register_script」の識別名を指定し「wp_register_script」で依存関係のあるJSファイルを登録していたけど「wp_register_script」や「wp_register_style」が不要ってこと
*(注意)@wordpress/scripts パッケージを利用した場合は不要です
function hoge_init() {
wp_register_script(
'hogehoge',
plugins_url( 'index.js', __FILE__ ),
array( 'wp-blocks', 'wp-element' )
);
register_block_type(
'namespace/block-name,
array(
'editor_script' => 'hogehoge',
)
);
}
add_action( 'init', 'hoge_init' );
おもなブロックオブジェクトのプロパティ
*「block.json」のキーとして書いています
「block.json」のキー | 意味 | 型 |
apiVersion | ブロックが使用するBlockAPIのバージョン(WordPress 5.6からバージョンは2) *デフォルトは1 | number |
name | (必須) namespace/block-name で、namespaceはプレフィックス(プラグインやテーマの名前) | string |
title | (必須)ブロックの表示タイトル | string |
category | コアのカテゴリ text media design widgets theme embed *追加可能です | string |
icon | ブロックのアイコン | string |
description | ブロックの簡潔な説明 | string |
keywords | ブロックを検索するときのキーワード | string[] |
version | 現在のバージョン | string |
textdomain | 翻訳するときは必要 | string |
supports | エディターで使用される機能を宣言します"html": true にするとHTML編集を確認できます | object |
styles | ブロックのラッパーにクラス名を追加 | array |
parent | 親のブロックがあるとき(ネストされた場合)のみ利用 | string[] |
example | プレビュー用 | object |
attributes | ブロックによって保存されるデータについての情報 | object |
editorScript | エディタ内でのみエンキューされるスクリプトの定義 | *string |
script | エディタ内と閲覧ページが表示される際の両方でエンキューされるスクリプトの定義 | *string |
viewScript | 閲覧ページが表示されるときのみエンキューされるスクリプトの定義 | *string |
editorStyle | エディター内でのみエンキューされるスタイルの定義 | *string |
style | エディタ内と閲覧ページが表示される際の両方でエンキューされるスタイルの定義 | *string |
「attributesプロパティ」について
パースやシリアライズは「attributesプロパティ」のデータをもとに処理されます
「attributesプロパティ」は「属性名をキー」「属性定義を値」にもつオブジェクトです
属性定義には最低「 typeまたはenum」が必要です
デフォルト値(default)をキーにできます
属性定義 | 説明 |
type | データの種類で下記のいずれか null boolean object array string integer number (integer と同じ) |
enum | 固定された値のセット 例 size: enum: [ ‘large’, ‘small’, ‘tiny’ ] |
selector | HTMLタグ・classやid 属性など(querySelectorに指定できるもの) |
source | どのように属性値を取り出すか(通常はselectorと組み合わせて使用し、selector が指定されていないときはブロックのルートノードに対して実行されます)なし :こんな感じで<!– wp:paragraph {“key”: “value”} –>コメントに保存attribute :HTML要素の属性に保存text :HTMLのテキスに保存。html : HTMLに保存(この典型的な使用例は RichText)query :オブジェクトの配列に保存meta :投稿メタに保存(非推奨) |
JavaScriptファイル
ブロックの実装です
registerBlockType関数でブロックの登録が不要になりました
registerBlockType('create-block/test', {
//ここが不要
title: 'test',
icon: '',
category: 'design',
attributes: {
content: {
type: 'array',
source: 'children',
selector: 'p',
},
//
},
} );
「registerBlockType関数」の第1引数はブロック名です
*サーバーでブロックを登録したときはクライアントでも同じブロック名( block.jsonの”name”の値)で登録します
第2引数はオブジェクトです(通常「editとsave」を含みます)
「edit」と「save」でブロックがどのように「レンダー・操作・保存」されるかのインターフェイスが提供されます
editの戻り値は、エディタ側でのレンダリング結果
saveの戻り値は、閲覧側での見え方で、データベース(post_contentフィールド)に挿入するブロックの形(wp.elementのインスタンス)です
import { registerBlockType } from '@wordpress/blocks';
//または const { registerBlockType } = wp.blocks;
registerBlockType( 'create-block/test', {
edit: function () {
return "";
},
save: function () {
return "";
}
} );
「WordPress環境 (Block API)」でのグローバルオブジェクトは「wp」です
パッケージは WordPress内で「wp.」でアクセスできます
クライアントサイドだけでブロックを登録するときは「block.jsonファイル」からデータを読み込んで登録します
import { registerBlockType } from '@wordpress/blocks';
//「block.jsonファイル」からデータを読み込んで登録
import metadata from './block.json';
registerBlockType( metadata, {
} );
最初のカスタムブロック
こちらを試してみます
npx @wordpress/create-block test を実行(かなり時間がかかる〜w)
WordPress管理画面で「testプラグイン」を有効化
「edit.jsとsave.js」は削除して「index.js」にすべて書きますw
block.jsonに追加
"attributes": {
"message": {
"type": "string",
"source": "text",
"selector": "div",
"default": ""
}
},
試しに、「index.jsファイル」でpropsを確認してみます
import { _ } from ‘@wordpress/i18n’;は翻訳に必要なので、今回は不要です しかしコピーしたコードに{ _( ‘テキスト’, ‘textdomain’ ) }がつかわれているとエラーになるので、念のため「index.jsファイル」に追加しました
「index.jsファイル」を編集し、npm startします
import { __ } from '@wordpress/i18n';
import { registerBlockType } from '@wordpress/blocks';
registerBlockType('create-block/test', {
edit( props ) {
console.log(props)
}
} );
これだけで、アイコンが表示されます
*「edit.jsとsave.js」を削除しているのでエラーになりますがw
デベロッパーコンソールで確認
コンテンツは props .attributes.messageで参照されます
「edit」の引数には通常は「setAttributes関数とattributes」を分割代入でわたします(これで、例えばコンテンツはattributes.messageで参照されます)
「attributesは各属性の値」「setAttributesは属性を更新する関数」です
その他に「isSelected(ブロックが現在選択されているか)」などがあります
{ isSelected && (trueの処理) }
registerBlockType('create-block/test', {
edit: function ({ attributes, setAttributes }) {
},
} );
「TextControlコンポーネント(input)」をつかいます
属性
label:ラベル
type : デフォルトはtext
value : 入力の現在の値
onChange : 入力の値を受け取る関数(「setAttributes」をつかい messageの値を更新)
「useBlockProps」で「Reactフック」がつかえます
import { __ } from '@wordpress/i18n';
import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps } from '@wordpress/block-editor';
import { TextControl } from '@wordpress/components';
registerBlockType('create-block/test', {
//edit: function()は省略記法にしました
edit({ attributes, setAttributes }) {
const blockProps = useBlockProps();
return (
<div { ...blockProps }>
<TextControl
label={ 'メッセージ' }
value={ attributes.message }
onChange={ ( val ) => setAttributes( { message: val } ) }
/>
</div>
);
},
} );
「edit」での「useBlockProps」について
*APIのVersion2から「useBlockProps」が必要だそうです
ブロックのラッパー要素に「className」を展開します(ブロックラッパー要素に 「useBlockPropsから取得したprops」を適用します)<div { …useBlockProps() }>
という感じ
*「className」を追加したいときは「useBlockProps」の引数にわたします useBlockProps( { className: 'hoge'} );
「’create-block/test’で登録したブロック」のクラス名は「wp-block-create-block-test」です
「style.scssファイル」は閲覧側とエディタ内両方に反映するスタイル
「editor.scssファイル」はエディタ内でのみ反映するスタイル
「save」はブロックのオブジェクトをシリアライズしてデータベース( post_contentフィールド) に保存します
引数には、基本的に「attributes」を分割代入でわたします
import { __ } from '@wordpress/i18n';
import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps } from '@wordpress/block-editor';
import { TextControl } from '@wordpress/components';
import './style.scss';
import './editor.scss';
registerBlockType('create-block/test', {
edit( { attributes, setAttributes } ) {
const blockProps = useBlockProps();
return (
<div { ...blockProps }>
<TextControl
label={ 'メッセージ' }
value={ attributes.message }
onChange={ ( val ) => setAttributes( { message: val } ) }
/>
</div>
);
},
//ここから
save( { attributes } ) {
const blockProps = useBlockProps.save();
return <div { ...blockProps }>{ attributes.message }</div>;
}
//ここまで
} );
「save」での「useBlockProps」について
静的ブロックをレンダーするときは、ブロックのラッパー要素に useBlockProps.save()
から返されるpropsを適用します
*これでHTML属性やブロックのクラス名が正しくレンダーされます
反映しないときはnpm start
をやり直します
ブラウザのキャッシュをクリア
buildディレクトを削除する
サーバー側のキャッシュ設定を確認する
バージョンをあげてみるなど…w
パソコンのスペックの問題なのか😂 エラーなのか反映していないのかわからないことがしばしば💦
(@wordpress/create-blockはかなりの重さです)
ブロックツールバーとサイドバー
ブロックエディタで使えるさまざまな「Reactのコンポーネント」があります
ブロックツールバー
サイドバー
- @wordpress/block-editorパッケージ(
wp.editor
) - 「ブロックの値の読み込みと保存のメカニズム」を投稿とそのコンテンツに関連付けます
投稿オブジェクトの操作に関連するさまざまなコンポーネント(投稿タイトル入力コンポーネントなど)を提供 - RichText・BlockControlsなど、おもにブロックツールバーでつかうコンポーネントが含まれています
- @wordpress/componentsパッケージ (
wp.components
) - 汎用的なコンポーネント(画面間で共有される共通のUI要素とWordPressダッシュボードの機能を作成するために使用される)
スタイルを追加するためのCSSが含まれてるときはCSSを追加します - おもにサイドバーでつかいます
RichText
リッチテキストは、任意のブロックレベル要素(div・h2・p など)に編集可能なコンテナを設定でき、style.cssだけでフロントエンドとエディタにスタイルが適用できます(editor.css が不要)
「block.jsonファイルのattributes」を変更しています
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "create-block/test",
"version": "0.1.0",
"title": "Test",
"category": "widgets",
"icon": "smiley",
"description": "test",
"attributes": {
"content": {
"type": "string",
"source": "html",
"selector": "p"
}
},
"supports": {
"html": true
},
"textdomain": "test",
"editorScript": "file:./build/index.js",
"editorStyle": "file:./build/index.css",
"style": "file:./build/style-index.css"
}
リファレンスの例をほぼそのままコピーしてindex.jsに
onChange={ ( content ) => setAttributes( { content } ) }
*{ content : content }なら{ content }に省略できるので、あわせるようにしますw
import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps, RichText } from '@wordpress/block-editor';
import './style.scss';
import './editor.scss';
registerBlockType( 'create-block/test', {
edit( { attributes, setAttributes } ) {
const blockProps = useBlockProps();
return (
<RichText
{ ...blockProps }
tagName="p"
value={ attributes.content }
//コンテンツは太字、斜体、リンクはできるが、他のフォーマットオプションは許可されない
allowedFormats={ [ 'core/bold', 'core/italic', 'core/link' ] }
onChange={ ( content ) => setAttributes( { content } ) }
placeholder= '...'
/>
);
},
save( { attributes } ) {
const blockProps = useBlockProps.save();
return <RichText.Content { ...blockProps }
tagName="p"
value={ attributes.content } />;
}
} );
BlockControls
editの戻り値にBlockControlsを加えるとツールバーにそのcontrolsが表示されます
*「controls」はボックスシャドウをつける際につかいます(最後)
<BlockControls //controlsでオリジナルを追加できます controls={[ { icon: "...", title: "・・・", onClick: 関数 isActive: Boolean } ]} >
「BlockControlsとAlignmentToolbar」のつかい方
「block.jsonファイルのattributes」に「alignment」を追加します
"attributes": {
"content": {
"type": "string",
"source": "html",
"selector": "p"
},
"alignment": {
"type": "string"
}
},
「index.js」ファイルを編集します
AlignmentToolbarは選択したアイコンで値として「right・center・left」が取得できます
import { __ } from '@wordpress/i18n';
import { registerBlockType } from '@wordpress/blocks';
//AlignmentToolbar, BlockControlsを追加
import { useBlockProps, RichText, AlignmentToolbar, BlockControls } from '@wordpress/block-editor';
import './style.scss';
import './editor.scss';
registerBlockType('create-block/test', {
edit( { attributes, setAttributes } ) {
//attributesのキーは分割代入
const { alignment, content, } = attributes;
//値を更新する関数
const onChangeAlignment = ( newAlignment ) => {
setAttributes( {alignment: newAlignment === undefined ? 'none' : newAlignment, } );
};
return (
<>
{/* //AlignmentToolbar, BlockControlsコンポーネントを追加 */}
<BlockControls>
<AlignmentToolbar
value={ alignment }
onChange={ onChangeAlignment }
/>
</BlockControls>
<RichText { ...useBlockProps() }
allowedFormats={ [ 'core/bold', 'core/italic', 'core/link' ] }
tagName="p"
onChange={ ( content ) => setAttributes( { content } ) }
value={content}
//style属性を追加します
style={{textAlign: alignment}}
/>
</>
);
},
save( {attributes} ){
//attributesのキーは分割代入
const { alignment, content, } = attributes;
return (
<>
<RichText.Content { ...useBlockProps.save() }
tagName="p"
value={content}
//style属性を追加します
style={{textAlign: alignment}}
/>
</>
);
},
} );
InspectorControls
サイドバーに「InspectorControlsとPanelColorSettings」をつかいカラーパレットを追加します
「block.jsonファイルのattributes」に「textColorとbackgroundColor」を追加します
"attributes": {
"content": {
"type": "string",
"source": "html",
"selector": "p"
},
"alignment": {
"type": "string"
},
"textColor": {
"type": "string"
},
"backgroundColor": {
"type": "string"
}
},
「InspectorControls」はサイドバーのコンポーネントです
その中に「PanelColorSettings」をセットします
import { __ } from '@wordpress/i18n';
import { registerBlockType } from '@wordpress/blocks';
//InspectorControls,PanelColorSettings,ContrastCheckerを追加
import {
useBlockProps,
RichText,
AlignmentToolbar,
BlockControls,
InspectorControls,
PanelColorSettings,
ContrastChecker
} from '@wordpress/block-editor';
import './style.scss';
import './editor.scss';
registerBlockType('create-block/test', {
edit( { attributes, setAttributes } ) {
//attributesのキーは分割代入
const { alignment, content, backgroundColor, textColor} = attributes;
const onChangeAlignment = ( newAlignment ) => {
setAttributes( {
alignment: newAlignment === undefined ? 'none' : newAlignment,
} );
};
return (
<>
{/* //InspectorControls,PanelColorSettings,ContrastCheckerを追加 */}
<InspectorControls>
<PanelColorSettings
title={"color"}
colorSettings={[
{
value: backgroundColor,
onChange: (backgroundColor)=>{setAttributes( { backgroundColor } )},
label: "BackgorundColor"
},
{
value: textColor,
onChange: (textColor)=>{setAttributes( {textColor } )},
label: "TextColor"
}
]}
>
{/* //ContrastCheckerは色の組み合わせをチェックをします */}
<ContrastChecker
textColor={textColor}
backgroundColor={backgroundColor}
/>
</PanelColorSettings>
</InspectorControls>
<BlockControls>
<AlignmentToolbar
value={ alignment }
onChange={ onChangeAlignment }
/>
</BlockControls>
<RichText {...useBlockProps()}
allowedFormats={ [ 'core/bold', 'core/italic', 'core/link' ] }
tagName="p"
onChange={ ( content ) => setAttributes( { content } ) }
value={content}
//スタイルを追加
style={{textAlign: alignment, backgroundColor: backgroundColor ,color: textColor}}
/>
</>
);
},
save({ attributes }) {
//attributesのキーは分割代入
const { alignment, content, backgroundColor, textColor} = attributes;
return (
<>
<RichText.Content { ...useBlockProps.save() }
tagName="p"
value={content}
//スタイルを追加
style={{textAlign: alignment, backgroundColor: backgroundColor ,color: textColor}}
/>
</>
);
},
} );
PanelBodyとRangeControl
「PanelBodyとRangeControl」をつかいボックスにシャドウをつけます
「block.jsonファイルのattributes」に「shadowとshadowOpactiy」を追加します
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "create-block/test",
"version": "0.1.0",
"title": "Test",
"category": "widgets",
"icon": "smiley",
"description": "test",
"attributes": {
"content": {
"type": "string",
"source": "html",
"selector": "p"
},
"alignment": {
"type": "string"
},
"shadow":{
"type": "boolean",
"default": false
},
"shadowOpactiy": {
"type": "number",
"default": 0.3
},
"textColor": {
"type": "string"
},
"backgroundColor": {
"type": "string"
}
},
"supports": {
"html": true
},
"textdomain": "test",
"editorScript": "file:./build/index.js",
"editorStyle": "file:./build/index.css",
"style": "file:./build/style-index.css"
}
1:「BlockControlsのcontrols」でシャドウの「ON・OFF」を切り替えます
2:サイドバーは「PanelBody」でtitleを指定すると折りたたみできます
シャドウがオンのときだけ「RangeControl」を表示、値を調整します
3:今までインラインスタイルで対応していましたが💦 classを追加してスタイルをかきます
「useBlockPropsで展開しているclassName」に「classnames」をつかって追加しますconst blockProps = useBlockProps( {
className: someClassName,
style: { color: 'blue' },
} );
*インラインスタイルもこのようにつかうようですw
import { __ } from '@wordpress/i18n';
import { registerBlockType } from '@wordpress/blocks';
import {
useBlockProps,
RichText,
AlignmentToolbar,
BlockControls,
InspectorControls,
PanelColorSettings,
ContrastChecker
} from '@wordpress/block-editor';
//Classnamesをつかって複数のクラスを指定します
import classnames from "classnames";
// RangeControl, PanelBodyを追加
import { RangeControl, PanelBody } from "@wordpress/components";
import './style.scss';
import './editor.scss';
registerBlockType('create-block/test', {
edit( { attributes, setAttributes } ) {
//attributesのキーは分割代入
const { alignment, content, backgroundColor, textColor, shadow, shadowOpacity} = attributes;
const onChangeAlignment = ( newAlignment ) => {
setAttributes( {
alignment: newAlignment === undefined ? 'none' : newAlignment,
} );
};
//useBlockPropsにclassnamesをわたします
//has-shadowクラスはshadowがtureのとき
//shadow-opacity-[数値✖️100]クラスはRangeControlの数値により変化
const blockProps = useBlockProps( {
className: classnames( {
"has-shadow": shadow,
[`shadow-opacity-${shadowOpacity * 100}`]: shadowOpacity
} )
});
return (
<>
{/* //InspectorControls,PanelColorSettings,ContrastCheckerを追加 */}
<InspectorControls>
{/* //PanelBodyにRangeControlを追加0.1~0,4の値で0.1刻み */}
<PanelBody title={"Setting"}>
{/* //shadowがtrueのときにRangeControlを表示 */}
{shadow && (
<RangeControl
label={"Shadow Opacity"}
value={shadowOpacity}
onChange={( shadowOpacity ) => setAttributes( {shadowOpacity } )}
min={0.1}
max={0.4}
step={0.1}
/>
)}
</PanelBody>
<PanelColorSettings
title={"color"}
colorSettings={[
{
value: backgroundColor,
onChange: (backgroundColor)=>{setAttributes( { backgroundColor } )},
label: "BackgorundColor"
},
{
value: textColor,
onChange: (textColor)=>{setAttributes( {textColor } )},
label: "TextColor"
}
]}
>
{/* //ContrastCheckerは色の組み合わせをチェックをします */}
<ContrastChecker
textColor={textColor}
backgroundColor={backgroundColor}
/>
</PanelColorSettings>
</InspectorControls>
{/* //シャドウの「ON・OFF」を切り替え*/}
<BlockControls
controls={[
{
icon: "chart-bar",
title: "Shadow",
onClick: () => {setAttributes({shadow: !shadow})},
isActive: shadow
}
]}
>
<AlignmentToolbar
value={ alignment }
onChange={ onChangeAlignment }
/>
</BlockControls>
{/* blockPropsを展開 */}
<RichText {...blockProps}
allowedFormats={ [ 'core/bold', 'core/italic', 'core/link' ] }
tagName="p"
onChange={ ( content ) => setAttributes( { content } ) }
value={content}
style={{textAlign: alignment, backgroundColor: backgroundColor ,color: textColor}}
/>
</>
);
},
save({ attributes }) {
//attributesのキーは分割代入
const { alignment, content, backgroundColor, textColor, shadow, shadowOpacity} = attributes;
//useBlockProps.saveにclassnamesをわたします
const blockProps = useBlockProps.save( {
className: classnames( {
"has-shadow": shadow,
[`shadow-opacity-${shadowOpacity * 100}`]: shadowOpacity
} )
} );
return (
<>
{/* blockPropsを展開 */}
<RichText.Content { ...blockProps }
tagName="p"
value={content}
style={{textAlign: alignment, backgroundColor: backgroundColor ,color: textColor}}
/>
</>
);
},
} );
style.scssの例です
.wp-block-create-block-test {
padding: 1rem;
&.has-shadow{
box-shadow: 5px 5px 10px rgba(0,0,0,0.2);
&.shadow-opacity-10 {
box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.1);
}
&.shadow-opacity-20 {
box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.2);
}
&.shadow-opacity-30 {
box-shadow:5px 5px 10px rgba(0, 0, 0, 0.3);
}
&.shadow-opacity-40 {
box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.4);
}
}
}
editor.scssの例
.wp-block-create-block-test{
border: solid 1px #eee;
}
スタイルの追加について
ラッパー要素にクラスを追加するのは簡単で「block.jsonファイル」に「styles」を追加します
*”isDefault”: trueはスタイルを初期値にするとき
"styles": [
{
"name": "rounded",
"label": "Rounded",
"isDefault": true
},
{
"name": "outline",
"label": "Outline"
},
{
"name": "squared",
"label": "Squared"
}
],
選択したクラスが追加されます(p class="wp-block-create-block-test is-style-rounded"
)
is-style-[選択したname]クラスが追加されるので「style.scssファイルに」それぞれのスタイルを追加します
*反映しないときはキャッシュクリア・npm startなどw
ちなみに、カスタムブロックと関係ありませんが
register_block_styleでコアブロックにスタイルを適応できます
下記コードで「Pブロック」に「is-style-rounded」を追加して、インラインスタイル適応しています
register_block_style(
//ブロックの名前
'core/paragraph',
array(
'name' => 'rounded',
'label' => 'Rounded',
//インラインスタイルまたは
//エンキューしているスタイルシートのハンドルを追加
'inline_style' => '.is-style-rounded {
border-radius: 6px;
}',
)
);
ブラウザのコンソールでwp.blocks.getBlockTypes()
と入力するとブロック名の完全なリストが表示されます
余談複数のブロックを同じ環境で作れないかとググったものの・・・わからないことが多すぎw
深みにハマりそうなので諦めます💦