WordPressのバージョンが6.9になって数式を入力できるブロックが追加されたのだが、使い勝手が悪く、それ以前から使っていたMathJaxを利用することにしている。ただ、MathJaxを利用するには記事のページにJavaScriptを記入しなければいけない。最初は「カスタムHTML」ブロックに記入していた。その後、記事の編集ページに「カスタムJavaScript」という項目があることに気づき、そこに記入することにしていた。ただ、記入するコードのコピー&ペーストが面倒に感じていた。PCの「付箋」にでも記入しておいて、そこからコピーすれば良いのかもしれないが、別の方法はないか考えて、WordPressのショートコード機能が使えないかと試すことにした。
ちなみに、「カスタムHTML」は私が利用しているテーマ Cocoon の独自ブロックであることは知っていたが、「カスタムJavaScript」も Cocoon の独自機能であることは、今日、知った。
まず、私が「カスタムHTML」ブロックに記入していたコードは次のとおりである。
<script>
window.MathJax = {
loader: {load: ['[tex]/empheq']},
tex: {packages: {'[+]': ['empheq']}, tags: 'ams', inlineMath: [['$', '$'],['\\(', '\\)']]}
};
</script>
<script id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@4/tex-chtml.js">
</script>
「カスタムHTML」を使う方法の欠点は、WordPressのページが複数ある場合に、このブロックが存在するページしか数式表示ができないことである。それに対して「カスタムJavaScript」を使う方法だと、一つの記入で全てのページで数式が使えるようになる。ただ、この「カスタムJavaScript」の仕様には気になることがあって、JavaScriptのコードのみを記入し、scriptタグは不要だということである。すると、上記のコードのようにscriptタグにsrcを指定する場合はどうしたら良いのか? 駄目元で上記のコードを入力したら機能したのだが、今日、改めて確認したら次のように最初と最後のscriptタグが消えていた。
window.MathJax = {
loader: {load: ['[tex]/empheq']},
tex: {packages: {'[+]': ['empheq']}, tags: 'ams', inlineMath: [['$', '$'],['\\(', '\\)']]}
};
</script>
<script id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@4/tex-chtml.js">
ただ、公開したページのHTMLコードを見たら、bodyタグの最後の方に次のようにscriptタグで囲まれていた。
<!-- cocoon Custom JS -->
<script>window.MathJax = {
loader: {load: ['[tex]/empheq']},
tex: {packages: {'[+]': ['empheq']}, tags: 'ams', inlineMath: [['$', '$'],['\\(', '\\)']]}
};
</script>
<script id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@4/tex-chtml.js"></script>
「カスタムHTML」も「カスタムJavaScript」もbodyタグの中にJavaScriptのコードを記入しているのだが、Geminiによると「WordPressの処理の論理的な順序とパフォーマンスに反する」という理由で推奨されず、次のように注意された。
wp_enqueue_scriptsの目的: WordPressでは、wp_enqueue_scriptsアクションフックを使ってスクリプトをエンキュー(登録)し、最終的にHTMLの**<head>内**にまとめて出力するのが標準的な手順です。
そんなGeminiに、ショートコードを記事内に記入するだけでMathJaxを使った数式が表示されるようにするために、テーマファイルエディターの functions.php に記入するコードを教えてもらった。
// 数式を表示するショートコード [mathjax_load] の登録
// MathJaxのロードが必要かを示すフラグを定義
$GLOBALS['mathjax_needed'] = false;
// 1. ショートコードの登録(コンテンツ自体には何も出力しない)
function mathjax_shortcode_handler( $atts, $content = null ) {
return '';
}
add_shortcode( 'mathjax_load', 'mathjax_shortcode_handler' );
// 2. MathJaxロードが必要か、最も適切なタイミング(wp_enqueue_scriptsの直前)でチェックする
/**
* MathJaxロードが必要か、テンプレートリダイレクト前にチェックする
* これが最も確実かつパフォーマンスに優しいチェック方法です。
*/
function mathjax_check_on_template_redirect() {
global $post;
// 現在が投稿または固定ページであり、公開されている場合のみチェック
if ( is_singular() && isset($post) ) {
// ページのコンテンツ全体を取得し、ショートコードの有無を確認
if ( has_shortcode( $post->post_content, 'mathjax_load' ) ) {
$GLOBALS['mathjax_needed'] = true;
}
}
}
// wp_enqueue_scriptsよりも早く実行される template_redirect にフック
add_action( 'template_redirect', 'mathjax_check_on_template_redirect' );
// 3. MathJaxスクリプトを条件付きでエンキューする関数
function conditionally_enqueue_mathjax_scripts() {
// フラグが立っているかチェック
if ( $GLOBALS['mathjax_needed'] ) {
// --- MathJaxの設定(ロードより先に実行する必要がある) ---
$mathjax_config = "
window.MathJax = {
loader: {load: ['[tex]/empheq']},
tex: {packages: {'[+]': ['empheq']}, tags: 'ams', inlineMath: [['$', '$'],['\\(', '\\)']]}
};
";
// 設定を登録し、インラインで追加
wp_register_script( 'mathjax-config', '', [], null );
wp_add_inline_script( 'mathjax-config', $mathjax_config, 'before' );
wp_enqueue_script( 'mathjax-config' );
// --- MathJaxメインスクリプトのロード ---
// 設定が読み込まれた後にロードされるように依存関係を設定
wp_enqueue_script( 'mathjax-main', 'https://cdn.jsdelivr.net/npm/mathjax@4/tex-chtml.js', [ 'mathjax-config' ], '4.0', array( 'in_footer' => false, 'async' => true ) );
}
}
// スクリプトのエンキュー処理をフック
add_action( 'wp_enqueue_scripts', 'conditionally_enqueue_mathjax_scripts' );
記事内に次のように記入するだけでMathJaxが使える。
[mathjax_load]
このコードで、headタグ内に次のようなコードが生成された。
<script id="mathjax-config-js-before">
/* <![CDATA[ */
window.MathJax = {
loader: {load: ['[tex]/empheq']},
tex: {packages: {'[+]': ['empheq']}, tags: 'ams', inlineMath: [['$', '$'],['\(', '\)']]}
};
//# sourceURL=mathjax-config-js-before
/* ]]> */
</script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@4/tex-chtml.js?ver=4.0" id="mathjax-main-js"></script>
このコードで機能するのだが、 functions.php に記入するにはコードが複雑すぎる。このコードに至るまで、Geminiは別のコードも作ったのだが、それは機能しなかった。何度か作り直した後に示されたのが上記のコードである。このような複雑なコードになったのは、前述のような「scriptはheadタグ内に作る」というGeminiの拘りがあるからで、ショートコードの位置に前述の「カスタムHTML」内のコードと同じコードを生成する functions.php のコードをGeminiに作ってもらったら、次のようなシンプルなコードになった。
/**
* MathJax設定とロードスクリプトをショートコードの位置に出力する
*/
function mathjax_inline_shortcode_output( $atts, $content = null ) {
$output = '
<script>
window.MathJax = {
loader: {load: [\'[tex]/empheq\']},
tex: {packages: {\'[+]\': [\'empheq\']}, tags: \'ams\', inlineMath: [[\'$\', \'$\'],[\'(\', \')\']]}
};
</script>
<script id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@4/tex-chtml.js">
</script>
';
// 改行やタブを削除してHTMLエラーを防ぐ(任意)
return trim($output);
}
// ショートコードを登録
add_shortcode( 'mathjax_load', 'mathjax_inline_shortcode_output' );
これで問題なく機能した。「カスタムHTML」に記入する方法で機能したのだから当たり前かもしれない。これも記事に次のコードを記入することでMathJaxが使えるようになる。
[mathjax_load]
実は、ショートコードの位置にコードを記入する方法は、functions.php を使わなくても、Cocoonの独自機能である定型文登録機能で実現できる。
定型文の編集はビジュアルエディタでもコードエディタでも記入できるが、私はコードエディタで記入した。その際に、scriptタグだけを記入して保存したら、自動的にpタグで囲まれてしまったので、次のようにdivタグで囲んで記入した。この場合はpタグで囲まれることはなかった。
<div><script>
window.MathJax = {
loader: {load: ['[tex]/empheq']},
tex: {packages: {'[+]': ['empheq']}, tags: 'ams', inlineMath: [['$', '$'],['(', ')']]}
};
</script><script id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@4/tex-chtml.js">
</script></div>
注意として、タグの間に改行があると、保存後に自動的に<br />が追加されてしまうので、改行しない方が良い。
後は、記事の編集中に「テンプレート」リストから選択すれば良い。ただ、記事の編集画面に表示されるのは、例えば次のようなショートコードで数式表示用だと分かりにくい。
[temp id=1]
functions.php にコードを記入する方法も同じだが、Cocoonの機能で定型文を用意して編集画面にショートコードだけを記入する方法は、MathJaxのコードを変えると、古い記事にも自動的に適用されるメリットがある。「カスタムHTML」や「カスタムJavaScript」を使う方法では、古い記事では古いコードのままである。もしかしたら古いコードのままの方が良い場合もあるかもしれないが…。



コメント