記事作成のたびにスラッグ(URL末尾)を手で入力するのは地味に手間です。運用ポリシーとして「投稿のスラッグは日付(例:20250907
や 2025-09-07-133045
)」に統一したいなら、保存フックで自動付与するのが最も確実です。ここでは functions.php
だけで実装できる、衝突回避つきのサンプルを紹介します。
方針
投稿保存直前にフック(wp_insert_post_data
)で post_name
を上書きします。既にユーザーが手動入力したスラッグは尊重し、空(下書き/自動下書き)や「日本語など URL 化が望ましくない状態」のときだけ日付で置換します。最後に wp_unique_post_slug()
を通して一意性を保証します。
実装(投稿タイプ post・8桁日付:YYYYMMDD)
<?php
// functions.php
add_filter('wp_insert_post_data', function ($data, $postarr) {
// 対象を通常の投稿に限定(必要に応じて変更)
if (($data['post_type'] ?? '') !== 'post') {
return $data;
}
// 既に手動でスラッグ入力済みなら何もしない
if (!empty($postarr['post_name'])) {
return $data;
}
// 基準日時:公開日時があればそれを、なければ現在時刻
// (予約投稿でも意図した日付でスラッグ化されます)
$date_gmt = $data['post_date_gmt'] !== '0000-00-00 00:00:00'
? $data['post_date_gmt']
: current_time('mysql', true); // GMT
// WP 時刻に変換
$ts = strtotime(get_date_from_gmt($date_gmt));
// 例:20250907 形式
$slug_base = gmdate('Ymd', $ts);
// 一意なスラッグに確定
$unique = wp_unique_post_slug(
$slug_base,
$postarr['ID'] ?? 0,
$data['post_status'],
$data['post_type'],
$data['post_parent'] ?? 0
);
$data['post_name'] = $unique;
return $data;
}, 10, 2);
秒まで入れたい(YYYY-MM-DD-hhmmss)
日内で複数本公開するサイトは秒まで入れると読みやすく、重複もしにくくなります。
$slug_base = gmdate('Y-m-d-His', $ts); // 例:2025-09-07-133045
日本語タイトル由来のスラッグを上書きしたい場合
既定の挙動では、日本語タイトルだとスラッグが空になったり、パーセンテージエンコードの長い文字列になることがあります。上書き対象を「自動生成とみなせる場合」に広げるなら、下の条件に差し替えます。
// 手動入力ではない&現スラッグが空 or 非ASCIIのみなら上書き
$auto_generated = empty($postarr['post_name']) || !preg_match('/[a-z0-9\-]/i', $postarr['post_name']);
if (!$auto_generated) return $data;
カスタム投稿タイプにも適用する
ニュース(news
)など、複数の投稿タイプで同じルールにしたい場合は配列で判定します。
$targets = ['post', 'news'];
if (!in_array(($data['post_type'] ?? ''), $targets, true)) {
return $data;
}
運用メモ(はまりどころ)
予約投稿は公開日時(post_date
)を基準にすることで、その日に合わせたスラッグになります。既存記事を更新してもスラッグは変えないのが一般的(URLが変わるとSEO・共有リンクへ影響)なので、上記コードは「保存のたびに更新しない」よう条件で保護しています。パーマリンク設定は「投稿名」等どれでも動きますが、/YYYY/MM/
などの年/月フォルダを構造に含む場合でも問題ありません。
おまけ:一度だけ全投稿を日付スラッグへ一括変換
既存記事を移行する小ワンショット。バックアップ取得のうえ、実行後は必ず削除してください。
if (is_admin() && isset($_GET['once_convert_date_slug'])) {
$q = new WP_Query(['post_type' => 'post', 'posts_per_page' => -1, 'post_status' => 'any']);
while ($q->have_posts()) { $q->the_post();
$ts = strtotime(get_post_time('Y-m-d H:i:s', true));
$base = gmdate('Ymd', $ts);
$unique = wp_unique_post_slug($base, get_the_ID(), get_post_status(), 'post', 0);
wp_update_post(['ID' => get_the_ID(), 'post_name' => $unique]);
}
wp_reset_postdata();
}
まとめ
スラッグを日付で自動付与するには、wp_insert_post_data
で保存直前に post_name
を組み立て、wp_unique_post_slug()
で一意化するのが安全かつ簡潔です。手入力は尊重しつつ、未入力時のみ日付ルールを適用すれば、運用の手間を減らしつつ安定したURL設計を実現できます。