WordPress テーマを作っていると、「記事一覧から各記事へリンクを張りたい」「特定のページの URL を取り出したい」という場面が必ず出てきます。そこで使うのが get_permalink() と the_permalink() です。この記事では、2つの関数の違い、引数で別の投稿の URL を取得する方法、固定ページやアーカイブの URL を取る関連関数まで、テーマ開発でそのまま使えるコード付きで解説します。WordPress テーマを自作している初心者〜中級者の方が対象です。
目次
パーマリンクとは
パーマリンク(permalink)は「permanent link(永続的なリンク)」の略で、各投稿や固定ページに割り当てられた個別の URL のことです。https://example.com/hello-world/ のようなアドレスがそれにあたります。WordPress では URL の形を管理画面の「設定 → パーマリンク」で変えられるため、テーマ内に URL を直接書かず、必ず関数で取得するのが正しい作法です。
その取得に使うのが get_permalink() と the_permalink() です。どちらも投稿の URL を返しますが、「値を返すか」「その場で表示するか」が異なります。
get_permalink と the_permalink の違い
2つの違いはシンプルで、URL を文字列で返すか、その場で出力するかです。WordPress には get_ が付く「取得する関数」と、the_ が付く「表示する関数」のペアが多くありますが、これもその一つです。
| 関数 | 動作 | 主な使いどころ |
|---|---|---|
get_permalink() | URL を文字列で返す(表示はしない) | 属性に埋め込む・変数に入れて加工する |
the_permalink() | URL をその場で出力する | そのまま画面に表示したいとき |
属性値として安全に出力するため、the_permalink() は内部でエスケープ済みの URL を出力します。get_permalink() で取得した値を href に入れるときは、自分で esc_url() を通すのが安全です。
基本の使い方(記事一覧でリンクを張る)
もっともよく使うのが、ループの中で各記事へのリンクを作る場面です。href に URL を入れる必要があるので、ここでは get_permalink() を esc_url() でエスケープして使います。タイトルの表示には the_title() を組み合わせます。
<?php if ( have_posts() ) : ?>
<ul>
<?php while ( have_posts() ) : the_post(); ?>
<li>
<a href="<?php echo esc_url( get_permalink() ); ?>">
<?php the_title(); ?>
</a>
</li>
<?php endwhile; ?>
</ul>
<?php endif; ?>
ループ内では引数なしで呼ぶと、「今まわっている投稿」の URL が自動で取得されます。the_post() によって現在の投稿がセットされているため、どの記事の URL かを明示しなくても正しく動きます。
同じことを the_permalink() で書くと、echo や esc_url() を書かずに済みます。表示するだけなら、こちらのほうが短く書けます。
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
引数で別の投稿の URL を取得する
get_permalink() は引数に投稿 ID(または投稿オブジェクト)を渡すと、ループの外でも特定の投稿の URL を取得できます。たとえば「お問い合わせページ(ID: 42)へのボタン」を、どのテンプレートからでも作れます。
<?php
// 投稿ID 42 のページのURLを取得する
$contact_url = get_permalink( 42 );
?>
<a href="<?php echo esc_url( $contact_url ); ?>" class="btn">
お問い合わせはこちら
</a>
固定ページの場合は、ID を直接書く代わりに get_page_by_path() でスラッグから取得したり、後述の関数を使ったりすると、ID 変更に強い作りにできます。なお get_the_permalink() という別名(エイリアス)も用意されており、動作は get_permalink() と同じです。読みやすさの好みで選んで構いません。
URL を取得する関連関数
投稿以外の URL を取りたいときは、用途別の関数を使い分けます。よく使うものを表にまとめます。
| 関数 | 取得できる URL |
|---|---|
get_permalink( $id ) | 投稿・固定ページ・カスタム投稿の URL |
get_post_type_archive_link( $type ) | カスタム投稿タイプのアーカイブページ URL |
get_category_link( $id ) | カテゴリーアーカイブの URL |
get_term_link( $term ) | タクソノミーのターム(カテゴリー・タグ等)の URL |
home_url( $path ) | サイトのトップページを基準にした URL |
「個別記事なら get_permalink()、一覧・アーカイブなら専用関数、サイト内の任意パスなら home_url()」と整理しておくと、目的の URL に最短でたどり着けます。
URL が取得できない・空になるとき
ループの外で引数なしに呼んでいる
get_permalink() を引数なしで呼ぶと、「現在の投稿」を基準に URL を返します。ループの外(ヘッダーやサイドバーなど、現在の投稿が定まらない場所)で引数なしに呼ぶと、意図しない URL になったり空になったりします。ループ外で使うときは、必ず投稿 ID を引数で渡しましょう。
カスタムクエリの後にリセットしていない
WP_Query で独自のループを回したあとは、wp_reset_postdata() を呼んで現在の投稿を元に戻す必要があります。これを忘れると、その後の get_permalink() がサブループの投稿を指したままになり、URL がずれます。サブループの直後にリセットする習慣をつけておくと安全です。
下書きや非公開の投稿を指している
公開前の下書き(draft)の投稿に対しては、最終的な URL が確定していないため、プレビュー用のクエリ付き URL が返ることがあります。リンクが ?p=123 のような形になる場合は、対象の投稿が公開済みかを確認してください。
まとめ
get_permalink() と the_permalink() は、テーマで投稿の URL を扱うときの基本関数です。要点を振り返ります。
get_permalink()は URL を文字列で返し、the_permalink()はその場で出力するhrefに入れるときはesc_url( get_permalink() )でエスケープする- 引数に投稿 ID を渡せば、ループの外でも特定の投稿の URL を取得できる
- アーカイブやカテゴリーの URL は
get_post_type_archive_link()などの専用関数を使う
まずは記事一覧のリンクを get_permalink() で作るところから始め、ボタンやアーカイブリンクへと応用していくと、URL の扱いに迷わなくなります。