概要説明
functions.php で WordPress のオリジナルのショートコードを作る方法。add_shortcode の基本の形と、AdSense の広告・投稿 ID から記事の URL やリンクを出す例を紹介。echo だと広告が本文の上に出る・下書きや非公開の題が見えてしまう、という前の書き方の問題も試した結果つきで。
~ 目次 ~
基本の書き方:関数を作って add_shortcode で登録する
ショートコードは、記事の中に [名前] と書くと、決めた内容に置きかわるしくみです。
functions.php に「中身を返す関数」を作り、add_shortcode() で名前を付けて登録します。
functions.php
/*----------------------------------------------------
ショートコード:[my_hello name="山田"] 基本の形
----------------------------------------------------*/
function my_shortcode_hello( $atts ) {
$atts = shortcode_atts( array( 'name' => 'ゲスト' ), $atts, 'my_hello' );
return 'こんにちは、' . esc_html( $atts['name'] ) . 'さん';
}
add_shortcode( 'my_hello', 'my_shortcode_hello' );
[my_hello] → こんにちは、ゲストさん [my_hello name="山田"] → こんにちは、山田さん
| 書き方 | 役目 |
|---|---|
add_shortcode( 'my_hello', '関数名' ) |
[my_hello] と書いたところで、関数を呼ぶように登録する |
| 関数の $atts | [my_hello name="山田"] の name のような、書いた値が入る |
| shortcode_atts( 決まりの値, $atts, 名前 ) | 書かれなかった値に決まりの値を入れる。3 つ目に名前を入れると、ほかのプラグインからも値を変えられる |
| return で返す | 返した文字が、[my_hello] のところに入る。echo で出すと、本文の上に出てしまう |
| esc_html()・esc_url() | 書かれた値や記事の題を出すときに、HTML として動かないようにする |
| my_ を付けた名前 | [ad] や [link] のような短い名前は、プラグインとぶつかりやすい |
例:Google AdSense の広告を記事の中に出す [my_ad]
functions.php
/*----------------------------------------------------
ショートコード:[my_ad] 記事の中に広告を出す
----------------------------------------------------*/
function my_shortcode_ad() {
static $script_done = false;
$client = 'ca-pub-0000000000000000'; // 自分のサイト運営者 ID
$slot = '0000000000'; // 広告ユニットの ID
$html = '';
if ( ! $script_done ) {
// 広告を読み込む script は、ページに 1 回だけ出す
$html .= '<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=' . esc_attr( $client ) . '" crossorigin="anonymous"></script>';
$script_done = true;
}
$html .= '<ins class="adsbygoogle" style="display:block; text-align:center;" data-ad-layout="in-article" data-ad-format="fluid"'
. ' data-ad-client="' . esc_attr( $client ) . '" data-ad-slot="' . esc_attr( $slot ) . '"></ins>'
. '<script>(adsbygoogle = window.adsbygoogle || []).push({});</script>';
return $html; // echo ではなく return で返す
}
add_shortcode( 'my_ad', 'my_shortcode_ad' );
| 書き方 | 役目 |
|---|---|
| $client・$slot | AdSense の画面でもらった、サイト運営者 ID と広告ユニットの ID を入れる |
| static $script_done | 広告を何個入れても、広告を読み込む script は 1 回だけ出す |
| esc_attr() | ID を HTML の属性に入れるときの決まりの書き方 |
| return $html | [my_ad] を書いたところに広告が入る |
[my_ad]
記事の中の、広告を出したいところに書きます。
前はこの記事で、広告のコードを echo で出していました。この書き方だと、[ad] を本文の途中に書いても、広告は本文のいちばん上に出ます。ショートコードの関数は、出したい文字を return で返します。
例:投稿 ID から記事の URL を出す [my_link]
2 つのショートコードで使う「公開中の記事だけを取り出す」関数を先に作り、それを使って URL を返します。
functions.php
/*----------------------------------------------------
公開中の記事だけを取り出す([my_link]・[my_linka] で使う)
----------------------------------------------------*/
function my_shortcode_public_post( $id ) {
$id = absint( $id );
if ( ! $id ) {
return null; // get_post( 0 ) は今の記事を返すので、0 は「なし」にする
}
$post = get_post( $id );
if ( ! $post || 'publish' !== get_post_status( $post ) || post_password_required( $post ) ) {
return null; // 下書き・非公開・パスワード付きは出さない
}
return $post;
}
/*----------------------------------------------------
ショートコード:[my_link id="123"] 記事の URL を出す
----------------------------------------------------*/
function my_shortcode_link( $atts ) {
$atts = shortcode_atts( array( 'id' => 0 ), $atts, 'my_link' );
$post = my_shortcode_public_post( $atts['id'] );
if ( ! $post ) {
return '';
}
return esc_url( get_permalink( $post ) );
}
add_shortcode( 'my_link', 'my_shortcode_link' );
| 書き方 | 役目 |
|---|---|
| absint( $id ) | 書かれた ID を 0 以上の数にする。数でないときは 0 |
| 0 は null を返す | get_post( 0 ) や get_permalink( 0 ) は「今の記事」を返すので、ID がないときに今の記事の URL が出ないようにする |
| get_post_status() が publish | 公開中の記事だけを出す |
| post_password_required() | パスワード付きの記事は出さない |
| esc_url() | URL を出すときの決まりの書き方 |
[my_link id="92"] → https://functions.fs-create.net/archives/92
例:投稿 ID から記事へのリンク(a タグ)を出す [my_linka]
functions.php
/*----------------------------------------------------
ショートコード:[my_linka id="123" text="文字"] 記事へのリンク(a タグ)を出す
----------------------------------------------------*/
function my_shortcode_linka( $atts ) {
$atts = shortcode_atts( array( 'id' => 0, 'text' => '' ), $atts, 'my_linka' );
$post = my_shortcode_public_post( $atts['id'] );
if ( ! $post ) {
return '';
}
$text = '' !== $atts['text'] ? $atts['text'] : get_the_title( $post );
return '<a href="' . esc_url( get_permalink( $post ) ) . '">' . esc_html( wp_strip_all_tags( $text ) ) . '</a>';
}
add_shortcode( 'my_linka', 'my_shortcode_linka' );
| 書き方 | 役目 |
|---|---|
| text の値 | 書いたときは、記事の題の代わりにその文字をリンクにする |
| wp_strip_all_tags() | 題に入った <br> などのタグを外す |
| esc_html() | リンクの文字を、HTML として動かないようにする |
[my_linka id="92"] → <a href="https://functions.fs-create.net/archives/92">記事の題</a> [my_linka id="92" text="こちら"] → <a href="https://functions.fs-create.net/archives/92">こちら</a>
~ 目次 ~
前の書き方との違い
| ところ | 前の書き方 | 今の書き方 |
|---|---|---|
| 広告の出し方 | echo で出していたので、本文のいちばん上に出た | return で返すので、書いたところに出る |
| 広告の script | 広告の数だけ、同じ script を読み込んだ | 1 回だけ |
| 下書き・非公開の記事の ID | だれが見ても、題と URL が出た | 何も出さない |
| id を書き忘れたとき | 今の記事の URL が出て、PHP の警告(Undefined array key "id")も出た |
何も出さない |
| ない ID のとき | 中身のない <a href=""></a> が出た |
何も出さない |
| 題の文字 | そのまま出していた | タグを外して、esc_html() で出す |
| extract() | 使っていた(どの変数ができるか見えにくく、今はすすめられていない) | 使わない |
確かめた結果
このサイトの作業環境(WordPress 7.1.3・PHP 8.3)で、試しの記事(公開・下書き・非公開)を作り、ログインしていない訪問者として表示して試しました。試しの記事は、終わったあとに消しました。
| 試したこと | 今の書き方 | 前の書き方 |
|---|---|---|
[my_hello name="山田"] |
こんにちは、山田さん | — |
| 「前の文 [広告] 後の文」 | 2 つの文のあいだに広告が入った | 広告が文より先に出た(267 文字) |
| 広告を 3 つ入れる | 広告 3 つ・script 1 つ | — |
| 公開中の記事の ID | URL・リンクが出た | URL・リンクが出た |
| 下書きの記事の ID | 何も出ない | 下書きの題と URL が出た |
| 非公開の記事の ID | 何も出ない | 「非公開: 」付きの題と URL が出た |
| id なし | 何も出ない | 今の記事の URL と警告 |
| ない ID・数でない ID | 何も出ない | 空のリンク |
| text に <script> を入れる | タグが外れて文字だけ | — |
PHP のテンプレートからショートコードを使う
テーマのテンプレート
<?php echo do_shortcode( '[my_ad]' ); ?> <?php echo do_shortcode( '[my_linka id="92"]' ); ?> <?php // 自分で作った関数なら、直接呼ぶほうが速い ?> <?php echo my_shortcode_linka( array( 'id' => 92 ) ); ?>
do_shortcode() に文字を渡すと、ショートコードを置きかえた結果が返ります。
自分で作ったショートコードなら、関数を直接呼んでも同じ結果になり、文字を調べる手間がないぶん速くなります。


