タイトルを入力するだけで装飾するブロックを追加する
A:角丸の罫線
B:カプセル形
C:幅いっぱいの下線
D:地色の角丸

WordPress に、中タイトルを入力するだけで装飾するブロックを追加する方法。装飾は CSS で決まるので、好みのデザインにできる。

上のデモは装飾のサンプル(A〜D)。

WordPress に最初からある「見出し」ブロックでも、「高度な設定」→「追加 CSS クラス」に class を入力すれば装飾できる。ただ、毎回 class を入力する必要があり、入力し忘れると装飾されない。ブロックを追加すると、「+」から選んで中タイトルを入力するだけになる。

追加するもの ブロック;「タイトルボックス」。「+」から選んで、ブロックの中に中タイトルを入力する ショートコード;段落に [title_box]中タイトル[/title_box] を入力する

どちらも <h2 class="title-box">中タイトル</h2> を表示する。

jQuery・Font Awesome は不要。編集画面のブロックは JavaScript で作るが、WordPress に入っている部品だけを使うので、ビルド(npm)なしで動く。テーマに CSS・JavaScript・PHP の3か所を追加する。

CSS

テーマの css/title-box.css として格納。中タイトルの大きさと余白だけの CSS。装飾は「装飾のサンプル」から1つ選んで、この CSS の下に追記する。ほかデザインがあればそれを追記する。

/* ===== ここから CSS(タイトルボックス) ===== */
/* 中タイトル:<h2 class="title-box">中タイトル</h2>
   ・ここは大きさと余白だけ。装飾は「装飾のサンプル」から1つ選んで、この下に追記する */
.title-box {
  display: block;
  width: fit-content;         /* 文字の幅にする(装飾が文字の幅で囲まれる) */
  max-width: 100%;            /* 長い中タイトルは記事の幅で折り返す */
  box-sizing: border-box;
  margin: 30px 0 10px;        /* ★ 上:前の段落との間隔/下:次の要素との間隔 */
  padding: .25em .8em;        /* ★ 装飾と文字の間(上下 左右) */
  font-size: 1.1em;           /* ★ 文字の大きさ(本文の 1.1倍) */
  font-weight: normal;
  line-height: 1.5;
}
/* ===== ここまで CSS(タイトルボックス) ===== */

width: fit-content で文字の幅にしている。display: inline-block でも文字の幅になるが、上下の余白が次の段落の余白と足し算になり、次が段落のときと表・画像のときで間隔が変わってしまうため。
上下の余白は h2 に指定している。段落の上にもともと余白がある場合も、h2 の下の余白と重なって大きいほうだけになるので、次が段落でも表でも画像でも同じ間隔になる。

公開ページと編集画面の両方で読み込むので、編集画面のブロックも公開ページと同じデザインで表示される。
※ css フォルダがテーマにない場合は作成。

JavaScript

/* =====================================================================
   ブロック「タイトルボックス」(編集画面)
   - ブロックの中に文字を入力するだけ。ショートコード [title_box] と同じ表示
   - 実際の HTML は PHP(functions.php の title_box_render())で作るので、ここは入力画面だけ
   - 編集画面のデザインも css/title-box.css で決まる
   - ビルドなしで動くように、WordPress に入っている部品を使う
   ===================================================================== */
( function ( wp ) {
	'use strict';

	var el                = wp.element.createElement;
	var registerBlockType = wp.blocks.registerBlockType;
	var useBlockProps     = wp.blockEditor.useBlockProps;
	var RichText          = wp.blockEditor.RichText;

	registerBlockType( 'title-box/title', {
		apiVersion: 3,
		title: 'タイトルボックス',
		description: '記事の中タイトルを入れる(文字を入力するだけで装飾される)',
		category: 'text',
		icon: 'heading',
		keywords: [ '中タイトル', '見出し', 'title', 'h2' ],
		attributes: {
			text: { type: 'string', default: '' }
		},

		edit: function ( props ) {
			// 公開ページと同じ <h2 class="title-box"> の形にして、同じ CSS で表示する
			return el( RichText, useBlockProps( {
				tagName: 'h2',
				className: 'title-box',
				value: props.attributes.text,
				allowedFormats: [ 'core/bold', 'core/italic', 'core/link' ],
				placeholder: '中タイトルを入力',
				onChange: function ( v ) { props.setAttributes( { text: v } ); },
				// Enter を押したら、次に段落ブロックを追加してそこへ移る
				__unstableOnSplitAtEnd: function () {
					props.insertBlocksAfter( wp.blocks.createBlock( 'core/paragraph' ) );
				}
			} ) );
		},

		// 保存しない(表示は毎回 PHP で作る)
		save: function () { return null; }
	} );
} )( window.wp );

ブロックが保存するのは中タイトルの文字だけ。HTML は表示のたびに PHP で作る。
※ js フォルダがテーマにない場合は作成。

PHP(functions.php)

テーマの functions.php の最後に追記。ブロックとショートコードを登録し、CSS と JavaScript を読み込む。

/* =====================================================================
   タイトルボックス:記事の中タイトルを角丸の枠で囲む
   ・使い方:
       ブロック「タイトルボックス」 … 「+」から選んで、ブロックの中に文字を入力する
       ショートコード [title_box]中タイトル[/title_box] … 段落に入力する
   ・出力(どちらも同じ):<h2 class="title-box">中タイトル</h2>
   ・書式は css/title-box.css、編集画面のブロックは js/title-box-block.js
   ===================================================================== */

/**
 * 中タイトルの HTML を作る(ブロックとショートコードで共通)
 *
 * @param string $text 中タイトルの文字。太字・リンクなどは本文と同じ範囲だけ許可する。
 * @return string 文字が空のときは何も表示しない。
 */
function title_box_render( $text ) {
	$text = trim( (string) $text );
	if ( '' === $text ) {
		return '';
	}
	return '<h2 class="title-box">' . wp_kses_post( $text ) . '</h2>';
}

/**
 * ショートコード [title_box]中タイトル[/title_box]
 *
 * @param array       $atts    属性(使わない)。
 * @param string|null $content [title_box] と [/title_box] の間の文字。
 * @return string
 */
function title_box_shortcode( $atts, $content = null ) {
	return title_box_render( $content );
}
add_shortcode( 'title_box', 'title_box_shortcode' );

/**
 * 段落ブロックに [title_box] だけを入力したときは、外側の <p> を外す
 * ・<p> を外さないと <p><h2>…</h2></p> になり、ブラウザが <p> を途中で閉じて前後に空の段落ができるため
 * ・render_block はショートコードの変換より先に動くので、ここでは <p> を外すだけ
 *
 * @param string $block_content 段落ブロックの HTML。
 * @return string
 */
function title_box_unwrap_paragraph( $block_content ) {
	if ( false === strpos( $block_content, '[title_box]' ) ) {
		return $block_content;
	}
	if ( preg_match( '#^\s*<p[^>]*>\s*(\[title_box\].*?\[/title_box\])\s*</p>\s*$#s', $block_content, $m ) ) {
		return $m[1];
	}
	return $block_content;
}
add_filter( 'render_block_core/paragraph', 'title_box_unwrap_paragraph' );

/**
 * css/title-box.css を、公開ページと編集画面の両方で読み込む
 * ・enqueue_block_assets:公開ページと、ブロックエディタの中の両方で動く
 */
function title_box_enqueue_assets() {
	wp_enqueue_style(
		'title-box',
		get_theme_file_uri( 'css/title-box.css' ),
		array(),
		filemtime( get_theme_file_path( 'css/title-box.css' ) ) // CSS を更新したら、ブラウザが読み直す
	);
}
add_action( 'enqueue_block_assets', 'title_box_enqueue_assets' );

/**
 * ブロック「タイトルボックス」を登録
 * ・保存するのは文字だけ。HTML は表示のたびに title_box_render() で作る
 */
function title_box_register_block() {
	wp_register_script(
		'title-box-block',
		get_theme_file_uri( 'js/title-box-block.js' ),
		array( 'wp-blocks', 'wp-element', 'wp-block-editor' ),
		filemtime( get_theme_file_path( 'js/title-box-block.js' ) ),
		true
	);

	register_block_type(
		'title-box/title',
		array(
			'api_version'     => 3,
			'editor_script'   => 'title-box-block',
			'attributes'      => array(
				'text' => array(
					'type'    => 'string',
					'default' => '',
				),
			),
			'render_callback' => function ( $attributes ) {
				return title_box_render( isset( $attributes['text'] ) ? $attributes['text'] : '' );
			},
		)
	);
}
add_action( 'init', 'title_box_register_block' );

HTML を表示のたびに PHP で作るのは、HTML の形を変えたくなったときに title_box_render() を直せば、過去の記事の中タイトルもすべて変わるため。

※ functions.php の最後に ?> がある場合は、?> の手前に追記する。
※ functions.php は書き間違えるとサイトが表示されなくなるので、変更する前にバックアップを保存しておくこと。
※ ファイル名を変える場合は、PHP の中のファイル名も同じ名前に変える。ファイルがないと、ブロックが表示されない。
※ 段落には [title_box] だけを入力する。文の途中に入力すると、段落が中タイトルの前後で分かれる。
※ 段落に [title_box] だけを入力したときは、外側の <p> を外している。<p> を外さないと <p> の中に <h2> が入る形になり、前後に空の段落ができて間隔がずれるため。
※ ブロックとショートコードはテーマに追加しているので、テーマを変えるとブロックは表示されなくなり、ショートコードは文字のまま表示される。

装飾のサンプル

サンプルA〜Dのコードをcss/title-box.css の最後に追記。共通の CSS の指定を上書きするものもあるので、必ず共通の CSS の下に配置。

A:角丸の罫線

/* A:角丸の罫線 */
.title-box {
  border: 1px solid #b5b9c6;  /* ★ 罫線の太さ・色 */
  border-radius: 4px;         /* ★ 角の丸み */
}

B:カプセル形

/* B:カプセル形 */
.title-box {
  padding: .25em 1.1em;       /* 両端が丸くなる分、左右を広げる */
  border: 1px solid #b5b9c6;  /* ★ 罫線の太さ・色 */
  border-radius: 1em;         /* 1行の高さの半分。999px にすると、2行になったとき楕円のように丸くなりすぎる */
}

※ 角の丸みは 1行の高さの半分(1em)にしている。999px のように大きくすると、中タイトルが2行になったとき楕円のように丸くなりすぎるため。

C:幅いっぱいの下線

/* C:幅いっぱいの下線 */
.title-box {
  width: auto;                /* 記事の幅いっぱいにする */
  padding: 0 0 .2em;          /* ★ 文字と下線の間 */
  border-bottom: 1px solid #b5b9c6;  /* ★ 下線の太さ・色 */
}

※ 共通の CSS で文字の幅にしているので、width: auto で記事の幅いっぱいに戻している。

D:地色の角丸

/* D:地色の角丸 */
.title-box {
  background: #eef1f4;        /* ★ 地色 */
  border-radius: 4px;         /* ★ 角の丸み */
}

変更する場合

変えたい項目変更箇所
文字の大きさ共通の CSS の font-size
前後の間隔共通の CSS の margin(上 左右 下)
装飾と文字の間共通の CSS の padding(上下 左右)。C は C の CSS の padding
罫線・下線の太さと色装飾のサンプルの border(C は border-bottom)
角の丸み装飾のサンプルの border-radius
地色装飾のサンプルの background

既存の設定がある場合

テーマの CSS に、もともと h2 の下線・左の線・アイコンなどの指定がある場合は、.title-box にも当たることがある。先に削除するかコメントアウトすること。

アイコンを ::before ::after で表示している場合は、content: none; を追記しても消えないことがある。同じ強さの指定が後に書かれていると、後の指定が優先されるため。元の指定をコメントアウトするのが確実。

/* 元の指定をコメントアウトする例
h2::before {
  content: "\f053";
}
*/

使い方

ブロックで入力する場合

  1. 記事の編集画面で「+」を押して、「タイトルボックス」を選ぶ
  2. ブロックの中に中タイトルを入力する

※ 中タイトルを入力して Enter を押すと、次に段落ブロックが追加される。

ショートコードで入力する場合

  1. 記事の編集画面で段落ブロックを追加する
  2. 段落ブロックに [title_box]中タイトル[/title_box] だけを入力する

表示環境によって動きの見え方が異なる場合があるため、本番に反映する前に確認してね。

NOTICES

  • 記事内容は実装させたものがほとんどですが自己責任で参考にしてください。