HTMLにきれいな数式を書けるMathJaxは、専用のJavaScriptを<script>タグでHTMLに挿入するだけで使えます。しかしWordPressでは、<head>に入れてしまうと使ってないページにもJavaScriptが挿入される無意味な状態が起きる。
これを解消する方法です。チェックを付けるだけで挿入する/しないを制御します。
MathJaxって何?
MathJaxは、数式をHTMLできれいに表示するJavaScriptプラグインです。こんなことができます。
\[ 12 + 23 = 35 \]
\[ 12 -23 = -11 \]
\[ 12 \times 3 = 36 \]
\[ 12 \div 3 = 4 \]
\begin{array}{r}
25 \\[-3pt]
\underline{\times\phantom{0}52} \\[-3pt]
50 \\[-3pt]
\underline{\phantom{0}125\phantom{0}} \\[-3pt]
1300
\end{array}
\begin{array}{r}
30\phantom{.} \\[-3pt]
7\enclose{longdiv}{210} \\[-3pt]
\underline{21\phantom{..}} \\[-3pt]
0\phantom{0.} \\[-3pt]
\end{array}
\begin{eqnarray}
\tan \theta
= \frac{ \sin \theta }{ \cos \theta }
\end{eqnarray}
これ以外にも行列や微分・積分など大方の数式はできます。
WordPressの編集画面のオプションで付ける
MathJaxの一番かんたんな使い方は、表示するページのHTMLにJavaScriptを<style>タグで挿入すること。
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
2021年5月22日現在、polyfillのjsファイルの縮小版(.min)はありません。
リンク先では "/* Disable minification (remove .min
from URL path) for more info */" が表示されます。
メッセージの通り ".min" を外します。するとこんなものに変わる。
/* Polyfill service v3.104.0
- For detailed credits and licence information see https://github.com/financial-times/polyfill-service.
- Features requested: es6
- */
/* No polyfills needed for current settings and browser */
ここではブラウザがポリフィルが不要と判定されましたが、必要ならポリフィルのJSコードが入っている。
WordPressではおなじみの、header.phpテンプレートやwp_enqueue_scriptsフックで追加すると、MathJaxを使わないページでもJavaScriptのローディングをしてしまいます。
使わないJSはGoogleのサイト評価にも影響する。(Googleは無駄が大嫌い)
そこで今回は、投稿や固定ページの編集画面の設定でチェックボックスを用意し、チェックをしたページだけに上記のJavaScriptをHTMLに挿入する機能を追加します。
サンプルコード
さっそくコーディングを始めます。最初に全コードをお見せします。
<?php
add_action('save_post', function ( $post_id ) {
if( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ){
return;
}
$meta_key = '_post_mathjax';
$request_post = json_encode( $_POST[ $meta_key ] );
if ( isset( $request_post ) ) update_post_meta( $post_id, $meta_key, $request_post );
});
add_action('add_meta_boxes', function() {
add_meta_box('mathjax', __( 'MathJax設定', 'theme_name' ), 'post_mathjax', ['post', 'page'], 'side', 'high');
});
function post_mathjax() {
global $post;
$post_id = $post->ID;
$meta_key = '_post_mathjax';
$meta_value = get_post_meta( $post_id, $meta_key, true );
$meta_array = [];
if ( $meta_value ) $meta_array = json_decode( $meta_value, true );
$name = $meta_key . '[enabled]';
$checked = ( !empty( $meta_array ) && $meta_array['enabled'] === '1' ) ? 'checked' : '';
?>
<div>
<input type="hidden" name="<?php echo $name; ?>" value="">
<label for="meta_mathjax_enabled"><input type="checkbox" name="<?php echo $name; ?>" id="meta_mathjax_enabled" value="1" <?php echo $checked; ?> /> <?php _e('MathJaxを使う', 'theme_name'); ?></label>
</div>
<?php
}
add_action( 'wp_enqueue_scripts', function(){
global $post;
$post_id = $post->ID;
$meta_key = '_post_mathjax';
$meta_value = get_post_meta( $post_id, $meta_key, true );
$meta_array = [];
if ( $meta_value ) $meta_array = json_decode( $meta_value, true );
if ( empty( $meta_array ) ) return;
if ( empty( $meta_array['enabled'] ) ) return;
//$src= 'https://polyfill.io/v3/polyfill.min.js?features=es6';
$src= 'https://polyfill.io/v3/polyfill.js?features=es6';
wp_enqueue_script( 'MathJax-script-polyfill', $src, [], false, true );
$src = 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js';
wp_enqueue_script( 'MathJax-script', $src, ['MathJax-script-polyfill'], false, true );
} );
add_action( 'script_loader_tag', function( $tag, $handle, $src ) {
$targets = [
'MathJax-script',
];
if ( in_array( $handle, $targets, true ) ) {
$tag = str_replace( '<script src=', '<script async src=', $tag );
}
return $tag;
}, 10, 3 );
処理の内容
メタデータ登録処理
編集画面の下書き保存・公開・更新ボタンを押したときにデータベース登録・更新。
MathJaxを使う/使わないの判定を投稿メタ情報に登録する。(**_postmetaテーブル)
メタボックスの追加
投稿・固定編集ページのサイドメニューに表示する。
メタボックスのHTML作成
データベースから該当postのメタデータを取得し、HTMLのチェックボックスの初期値を設定。
JavaScript挿入処理
メタデータを取得しMathJaxを使うpostのページだけをエンキューでJavaScript挿入。
JavaScriptにasync挿入
エンキュー処理では<script>にasync属性を付けられないので、置換で追記。
これで、編集画面の設定オプションにチェックするだけでMathJaxのJavaScriptを挿入する/しないが決められる機能が追加されます。
PHPプログラムでするのはそろそろ辞めよう!
本当はここで、コードの詳細な説明するつもりでしたが、やめました。理由はWordPress開発コミュニティはphpでのメタボックス機能の追加を推奨していないから。
くわしくは割愛しますが、WordPressはバージョン5になってからGutenbergを採用し、JavaScriptでコーディングします。管理画面のエディタの機能はJavaScriptがメイン。
phpはWP5.7の今でも下位互換のために動作しますが先はどうなるか分からない。上記コードも暫定だと思ってください。
(と言っても5年後でも大丈夫な気がする。)
JSコードも書こうと思いましたが、慣れてないと10分そこらでサクッとできそうにないので、WordPress.orgのブロックエディターハンドブックの紹介に留めておきます。
(JS版を作る予定。ただしケツは決めていない。)