かえでBlogは2012年から続いているブログであり、Wordpressで運営しています。
記事投稿の際、パーマリンクを「/%year%/%monthnum%/%day%%hour%%minute%%second%.html」と設定していたのですが、wordpress5.4.1より「%post_id%」または「%post_name%」が必須になりました。
そのため、今回発生した事象を契機にパーマリンクを変更することにしました。
といっても
見た目(URL上)は
「/%year%/%monthnum%/%day%%hour%%minute%%second%」に変更しただけですが。
WordPress 5.4.1に変更後記事が表示されない
WordPressのバージョンアップが届き、5.4.0 ⇒ 5.4.1に変更したら個別記事(simple.php)の表示がおかしくなりました。
記事投稿時のプレビューまでは問題なし
WordPress5.4.1に変更した後、記事投稿を行っていたのですが、記事編集画面ではもちろん、プレビュー画面でも問題ありませんでした。
なので、個別記事の表示がおかしくなっていると気づくのに少し時間がかかっていました。
記事投稿後、表示画面がおかしくなる
記事作成後、公開するボタンを押下した途端、今まで正常に表示されていたプレビュー画面が一転全てが表示されなくなりました。
その時はカスタムHTMLを使っている記事だったり、Twitter投稿文を載せていたりしたのでHTML変換がうまくいかなかったのかな程度にとらえていました。
しかし、簡単な文章を記載した記事をテストで投稿しても同様の現象でした。
そこで、記事の問題ではなくWordpressの問題だと認識を改めることに。
しかし、パーマリンクが問題だとまでは思っていなく、アップグレートしたことによるテンプレートの設定が問題なのかなとあれこれ試行錯誤していました。
しかし、色々修正したところで直らず、別のテーマを適用しても同じ現象が発生したのでWordpress自体に何か問題が抱えているのかと考えることに。
パーマリンクの設定が変更されていた
WordPress5.4.1の情報を収集していると「wordpress 5.4.1 からの障害について」にたどり着きました。
Changeset 47641を見ると個別記事判定で「%day%%hour%%minute%%second%」で終わらせるとダメで、最後に「%post_id %」または「%postname%」で終わらせないといけないみたいです。
セキュリティ上の問題で廃止された
「Why class-wp-query.php was changed in WordPress 5.4.1?」や「Unpacking The 7 Vulnerabilities Fixed in Today’s WordPress 5.4.1 Security Update」より
・時、分、秒だけ設定されている場合、同じ時間に複数の投稿を行うとどの記事を表示したらよいのか判断できなくなる問題が生じるため、今回のアップデートで表示しないように設定したようです。
例えば、同じ時間に公開・非公開の記事を投稿した場合、URLは秒までしかないため、間違って非公開の記事が公開されてしまう等情報漏洩等があるみたいです。
個人ブログ的に同じ時間で投稿することはほぼないので、そこまで気にしなくてもいいかもしれないですが、複数の編集者とかいる場合では起こりうりますよね。
そのため、時間指定していたパーマリンクは個別記事に遷移しないようにし、アーカイブ記事に遷移されるようなったみたいです。
WordPressの公式HPにも記載されている
パーマリンクの使い方にも「構造は必ず %post_id% あるいは %postname% で終了し、各パーマリンクが個々の投稿を指すようにしてください 」とちゃんと記事表示がユニークになるよう指示されています。
なので、時間だけのパーマリンクは邪道ということですね。
結構やっている人が多いと思いますが・・・
パーマリンクの設定とリダイレクト処理
WordPressのバージョンを上げるには、パーマリンクの設定変更が必須となります。
そのため、現在設定しているURLを変更しないといけないです。
私のサイトは公開済み記事で400記事くらいあるので全て修正するの骨が折れそうです。
・・・と思ったのですが、現状のURLを維持が目的ならば
post_nameの値を現在のURL名と同じに設定することで実現できるので、そちらでやることにしました。
下準備
URLの抽出
まずは、現在割当たっているURL情報を抽出します。
DBからの直接抽出も可能ですが、「Export All URLs」プラグインを使って簡単に抽出したいと思います。
インストール後「Export All URLs」を開き、下記を抽出
「Select a Post Type to Extract Data:」をPostsに選択
「Additional Data:」をPost IDs、Titles、URLsにチェック
「Post Status:」をPublishedに選択
「Export Type:」をCSVに選択
選択後Export nowを設定
設定後、抽出完了ダイアログが表示されるので、「Click here」をクリックしてダウンロードします。
ダウンロードしたCSVを見るとPOST IDとTitle、URLsが取得できます。
post_nameの抽出
URL情報は抽出できたが、実際にURL変更した際の値をあらかじめ知りたかったので一括で抽出できるように直接DBで取得しました。
select ID,post_name from wp_posts where post_status = 'publish' and post_type ='post' order by ID desc;
そして、さっき抽出したURL情報と突き合わせ。ID順に並べ替えたらそんな大した一致すると思います。
スラッグ登録してこなかったのでURLエンコードされた日本語が並んでますね。。。
post_nameの更新
タイトル名がそのままURLエンコードされるのですが、400記事一つ一つに今から英語名を付けていくのも骨が折れる。
なので、URLがhttps://kaede.jp/2020/05/02014155.htmlの場合、
POST-NAMEを「02014155.html」になるよう一括置換することにしました。
Excelで記事名の抽出
CSVでPostIDとURLを取得したので、URLから/より右側の値を抽出します。
下記の関数で「/」以降のデータを抽出できます。
「=MID(C2,FIND("●",SUBSTITUTE(C2,"/","●",LEN(C2)-LEN(SUBSTITUTE(C2,"/",""))))+1,LEN(C2))」
※C2セルをURL置き換え対象セルに変更してください。
もし、修正後のpost_nameで同じ名前が存在した場合、年月と比較して問題ないか確認してください。(400記事しかない自分の記事でも1件だけ重複がヒットしました。)
後に記載していますがpost_name(URLスラッグ)は「.(ドット)」は許容してくれず、「-(ハイフン)」になります。
そのため、URLスラッグで許容できない文字がある場合はこの時点で編集しておくことをお勧めします。
updateクエリ文を記事分作ります。
例)
update wp_posts set post_name = '02014155' where ID = '7874' and post_status = 'publish' and post_type ='post';
↓はExcelで一括で作成した場合
="update wp_posts set post_name = '"&F2&"' where ID = '"&A2&"' and post_status = 'publish' and post_type ='post';"
DBをあらかじめバックアップを取得し、先ほど作成したupdate分でDBを一括置き換えします。
パーマリンクの設定
WordPressのパーマリンクを下記に設定します。
/%year%/%monthnum%/%day%%hour%%minute%%second%.html
↓
/%year%/%monthnum%/%postname%/
あとは設定ボタンを押下するだけ。
これでいつもと同じURLで表示・・・できない
「.(ドット)」は許容されていない
実際に画面を開いてみる
と404表示に・・・実際に記事のページにいくと
「.(ドット)」を入力しても自動的に「-(ハイフン)」に置き換わります。
記事画面で「.(ドット)」⇒「-(ハイフン)」で保存する際、Redirection側で変換処理してくれるみたいだが、400回も記事を開いて保存はしたくないので「.html」を削除して設定することにしました。
Redirectionの設定
Redirectionのインストール
URLのリダイレクト処理ができるプラグイン「Redirection」をインストールします。
Redirection設定
本来はRedirectionの設定いらずで終了する予定でしたが、一部文字が使えなかったのでRedirectionの正規表現で「***.html」に来たURLは「***」に遷移するように設定します。
ソースURLは「^/([0-9]{4})/([0-9]{2})/([0-9]{8}).html」で正規表現にチェック
マッチしたとき「URLへ転送」にし、HTTPコードは「301(恒久的な移動)」
ターゲットURLは「/$1/$2/$3」
で設定しました。
HTTPリダイレクト処理は301設定すれば、賢いクローラは遷移先のURLに更新してくれますので、Google検索とかは自動的に切り替わってくれる(はず)
最後に
一部DBを直接弄ることになりますが、URLスラッグを全て設定+リダイレクト処理作成するよりかかなり楽になるかと思います。(実際に数時間程度でできます)
今回の作業は一般公開されている記事のみの設定なのですが、非公開記事は変更されたい場合はwp_postsテーブル参照の上、変更すればOKです。
また、「.(ドット)」などURLスラッグで使えない文字を使っていない人はpost_nameの置き換えとパーマリンクの設定が必要になりますが、正規表現で対応できるのでそこまで苦労しないかなと思います。
SEO的にはURLにもタイトル名を持たせたほうがいいんでしょうが、
今まで数字のみでやってきたので、急ピッチで作業せずとも後でゆっくりやっていけばいいんではと思います。