Wordpressのページ間でデータを共有する方法
はじめに
内容についてはタイトルの通りです。
個人的な備忘録のため、ベストプラクティスではないと思うので悪しからず。
仕様について
今回の機能のクライアントの希望としては、「カスタム投稿の’お知らせ’カテゴリー以外でCVのボタンを表示させ、そのリンクからお問い合わせページに来た場合に元ページの情報(今回は求人情報で、求人元の会社名など)を紐づけたい」とのことでした。
(以下Wordpressは長いのでWPと省略します。)
実装方法
最初に考えた方法
WPといえばPHP、PHPでページ遷移にデータを持たせる方法といえばGET/POST通信ということで、この方法での実装を考えました。
WPで固定ページに対してGET/POST通信を行う方法としてはこちらの記事を参考にしました。
想定した処理の流れ
流れとしては、
- カスタム投稿に対してカスタムフィールドを設定し、そこにPOSTで送信したいデータを入れる
- phpで受け取り<input type="hidden">の値に設定
- <form action="<?= homeurl('お問い合わせページのスラッグ') ?>">でページ遷移を設定
- 遷移先のページ内で、jsを使用し送られてきた内容を取得し、textareaのvalueに設定
を考えました。
結果
結論から言うとこの方法ではだめでした。
var_dump()を使用して送られたデータの内容を確認したところ、データ送信自体は正常に行われていましたが、表示されて数秒後に再読み込みが入りデータがNULLになってしまいました。
原因
調べたところ、どうやらパーマリンク設定でpretty(デフォルト以外のやつ)を使用していることが原因みたいでした。
wpのadd_rewrite_rule()関数をfunctions.phpでフィルターフックで使用することで解決できるという情報も見つけましたが、技術的に難しそうなので他の方法を考えることにしました。
次に考えた方法
GET/POST以外でデータを受け渡す方法として、Cookieとsessionの2つを思いつきました。
今回はサーバーにデータを保存するまでのものではないので、このうちCookieを使用することにしました。
また、どうせあとからjsを使用してデータを取得するので、Cookieのセットもjs側で行うほうが効率がよいと考えました。
ライブラリなしでCookieを扱うのはちょっとしんどいので、js-cookieを使用することに決めました。
実装手順
まずはパッケージのインストールから
yarn add js-cookie
次にjsの記述
import Cookies from "js-cookie";
function setCookie(e){
const corpname = e.currentTarget.parentNode.querySelector('input').value
Cookies.set('max-age', '60');
Cookies.set('corp-name', corpname)
}
function getCookie(name){
return Cookies.get(name)
}
export { setCookie, getCookie }
※setCookie関数内のデータ取得が若干複雑になってしまいました。
aタグのdata属性とかにいれてgetAttributeで取得したほうが多分楽です。
import { setCookie } from './settingCookie.js'
const access_recruit_button = document.getElementById('accessRecruit')
acess_recruit_button.addEventListener('click',setCookie)
想定外の挙動
ながく保持する必要のないデータのため、MAX-AGEに60を指定して1分ほどでcookieが削除されるように設定したつもりですが、コンソールから確認したところ削除されていないようでした。
(可能性が低いとはいえ)投稿記事ページ->お問い合わせページ(問い合わせフォーム未記入で)->その他固定ページ->ナビゲーションからお問い合わせページのフローで遷移した際にデータが残ってしまうことが確認されました。
そこで、ナビゲーションメニューのお問い合わせボタンを押したときに問答無用でCookieを削除してしまえばいいじゃん、
ということでコード追加
import Cookies from "js-cookie";
function setCookie(e){
resetCookie()
const corpname = e.currentTarget.parentNode.querySelector('input').value
Cookies.set('max-age', '60');
Cookies.set('corp-name', corpname)
}
function getCookie(name){
return Cookies.get(name)
}
function resetCookie(){
Cookies.remove('corp-name')
}
export { setCookie, getCookie, resetCookie }
import { setCookie, resetCookie } from './settingCookie.js'
const header_contact_btn = document.querySelector('.main-navigation-form-block_contact')
header_contact_btn.addEventListener('click', resetCookie)
const access_recruit_btn = document.getElementById('accessRecruit')
if(access_recruit_btn){
access_recruit_btn.addEventListener('click',setCookie)
}
終わりに
実際に使用しているコードではお問い合わせページでも条件分岐が入ってくるのでもうちょっとのこってますが、大まかな実装方法はこんな感じになってます。
もっといい方法を思いついたら更新していこうと思います。
Discussion