カスタムフィールドに複数行のテキスト(箇条書きにしたい項目など)を入力しておき、テンプレート側で1行ずつ <li> で囲んでリスト表示する方法を解説します。ポイントは改行コードの扱い(\r\n対応)と空行・空値の処理です。
この記事でわかること
get_post_meta()で複数行の値を取得するpreg_split()で改行分割する(explodeではダメな理由)- 空行の除去と、フィールドが空のときのガード
esc_html()で安全にリスト出力する
カスタムフィールドの値を取得する
まず get_post_meta() で現在の投稿のカスタムフィールド値を取得します。
PHP:カスタムフィールドの値を取得
$post_id = get_the_ID(); $custom_field_value = get_post_meta($post_id, 'custom_field_name', true);
get_post_meta() の詳しい使い方はカスタムフィールドのテキストを表示する方法(get_post_meta完全ガイド)を参照してください。
改行で分割する(explodeではなくpreg_split)
explode(“\n”) では \r が残る
テキストエリアの改行コードは環境によって
テキストエリアの改行コードは環境によって
\n だけでなく\r\n(Windows系)のことがあります。explode("\n", $value) で分割すると各行末に \r が残り、文字列比較や空行判定が誤動作する原因になります。preg_split() で3種類の改行にまとめて対応しましょう。PHP:改行コードの違いに対応して分割
// \r\n(Windows)・\r(旧Mac)・\n(Unix)のどれでも分割できる
$lines = preg_split('/\r\n|\r|\n/', $custom_field_value);
空行を除いて各行をliタグで囲む
値の末尾の改行や途中の空行をそのまま処理すると、空の <li></li> ができてしまいます。trim() + array_filter() で空行を除いてから、esc_html() でエスケープして <li> で囲みます。
PHP:空行除去+エスケープしてli化
// 各行をtrimして空行を除去
$lines = array_filter(array_map('trim', $lines), function ($line) {
return $line !== '';
});
// 各行をエスケープして <li> で囲む
$li_elements = array_map(function ($line) {
return '<li>' . esc_html($line) . '</li>';
}, $lines);
エスケープは esc_html() で
WordPress開発では
WordPress開発では
htmlspecialchars() よりも、WP標準の esc_html() を使うのが慣例です。入力値にHTMLタグが含まれていても文字として表示され、安全に出力できます。ulリストとして出力する
implode() で結合し、<ul> で囲んで出力します。リストが空のときは <ul> 自体を出さないようにガードします。
PHP:空でないときだけリストを出力
if (!empty($li_elements)) {
echo '<ul>' . implode('', $li_elements) . '</ul>';
}
完全なコード例(コピペ用)
取得から出力まで、空値・空行のガードを含めた完全版です。テンプレート(single.php など)のループ内に設置してください。
PHP:完全版(\r\n対応・空行除去・空値ガード付き)
<?php
$custom_field_value = get_post_meta(get_the_ID(), 'custom_field_name', true);
// フィールドが空なら何も出力しない
if ($custom_field_value) {
// 改行コード(\r\n / \r / \n)に対応して分割
$lines = preg_split('/\r\n|\r|\n/', $custom_field_value);
// trimして空行を除去
$lines = array_filter(array_map('trim', $lines), function ($line) {
return $line !== '';
});
// エスケープして <li> で囲む
$li_elements = array_map(function ($line) {
return '<li>' . esc_html($line) . '</li>';
}, $lines);
// 空でなければ <ul> で出力
if (!empty($li_elements)) {
echo '<ul class="meta-list">' . implode('', $li_elements) . '</ul>';
}
}
?>
「フィールドに値があるときだけ見出しごと表示したい」といった出し分けはカスタムフィールドの入力有無に応じて表示を切り替える方法が参考になります。
よくある質問(FAQ)
Qカスタムフィールドが配列で保存されている場合は?
A
get_post_meta($id, 'list_field', false) のように第3引数を false にすると同じキーの値を配列で取得できます。あとは foreach で echo '<li>' . esc_html($item) . '</li>'; と回すだけです。取得の基本は投稿のカスタムフィールドを取得する方法を参照してください。QACFのリピーターフィールドをリスト表示するには?
AACFでは
have_rows() / the_row() でループします。if (have_rows('repeater')) { echo '<ul>'; while (have_rows('repeater')) { the_row(); echo '<li>' . esc_html(get_sub_field('item')) . '</li>'; } echo '</ul>'; } のように書きます。Q値が未入力のときにデフォルトのリストを出すには?
A
$value = get_post_meta(get_the_ID(), 'field', true) ?: "デフォルト値"; のように空のときの代替値を設定できます。ただし「空なら何も表示しない」のが自然な場面が多いため、この記事の完全版のように if ($value) でガードする形を基本にしてください。まとめ
- 分割:
preg_split('/\r\n|\r|\n/', $value)(explodeだと\rが残る) - 空行除去:
array_filter(array_map('trim', $lines), ...) - エスケープ:各行を
esc_html()してから<li>で囲む - ガード:フィールドが空なら
<ul>自体を出力しない
改行コードと空行・空値のケアまで入れておけば、どの環境で入力された値でも崩れないリスト表示になります。
