wordpressで夢小説を楽に書きたい

※これでもうまくいくんですが、例えば「空」という名前と「空」という単語が文中に登場したときに、「単語は変換したくない」ができないので、破綻したなと思って非公開にしてました。そういう名前が発生しない人は自由に使ってください。(2022.07.30追記)
※ちょっとスクリプト修正したけど、動作確認してないので動かなかったらごめんなさい。(2023.02.15追記)
※質問来たので追記してます。(2023.3.26追記)


サイト運営19年、ずっとホームページビルダーでやってましたが、作品本数が500本を超え、更新の度に名前変換かけてHTMLファイルを作るのも面倒になりました。
ついでにwebデザインの勉強をしようと思い立ったところだったので、サイトをwordpressに移行することにしました。
「エディタで投稿しただけで名前変換できないかなー(大の字)」
と思ったので、スクリプトを作りました。
javascriptはほぼ初コーディングなので、もっといい書き方あったら助言ください。

0.概要
記事の投稿をするだけで、名前変換される機能を作ります。
wordpressの始め方は有志の方のブログなどを参考にされたし。ただし、サブディレクトリは作らないようにしているので、レンタルサーバーのデフォルト機能で入れると動かないかも。
記事の投稿時にカスタムフィールドに変換対象を入れるようにします。

1.プラグインを3つ入れる
下記のプラグインを検索して入れてください。有効化するのを忘れない。
ACF to REST API
・Advanced Custom Fields
・Simple Custom CSS and JS

2.カスタムフィールドの作成
左メニューの一番下にカスタムフィールドの項目ができています。
適当にタイトルをつけてフィールドを作ります。
記事によって出し分けしない想定なので、たとえば連載Aでは和名、連載Bでは洋名が必要だったら和名洋名のフィールド全部作ります。
「フィールドを追加」ボタンを押して、下記のように設定します。

フィールドラベルとフィールド名は「name0」「name1」「name2」という具合でつけていきます。この形式じゃないと変換されないので注意してください。プレースホルダーは何の変換項目かわかるように名前つけてください。
あとはデフォルト値でOK。変換に必要な数作ってください。
作り終わったら公開にする。

3.カスタムフィールドの有効化
デフォルトではカスタムフィールドは投稿時に入力できないので、設定をONにします。
記事の投稿画面を開いて、以下から設定画面を開きます。

上記のトグルをONにします。
投稿画面の一番下に作成した変換項目の入力欄が出てたらOK。

4.パーマリンクの修正
小説記事のURLは「https://~~/カテゴリ/連番」にします。

左メニューの設定>パーマリンクからカスタム構造を選んでテキストボックスに「/%category%/%postname%/」を入力します。

5.スクリプトの追加
Javascriptを追加します。カスタムCSS&JSというのがメニューに追加されているので、カスタムJSの追加をします。

適当にタイトルをつけて、下のフィールドに下記をコピペして追加して公開ボタンを押します。

jQuery(function () {

    var url_string = location.pathname.split('/');
    var category = url_string[1];
    var cookie_id = category + "CokkieValue";

    /** 登録ボタンが押されたときの処理 */
    jQuery("#submit").on("click", function () {
        var now = new Date();
        now.setFullYear(now.getFullYear() + 1);
        var str = cookie_id + "=";
        jQuery('#namechange').find('input').each(function( index, element ) {
            if(index == 0){
                str = str + jQuery(this).attr('name') + ":" + jQuery(this).val();
            }else{
                str = str + "," + jQuery(this).attr('name') + ":" + jQuery(this).val();
            }
        })
        document.cookie = str + "; path=/; expires=" + now;
        location.reload();
    });

    /** 削除ボタンが押されたときの処理 */
    jQuery("#delete").on("click", function () {
        var old = new Date();
        old.setFullYear(old.getFullYear() - 1);
        document.cookie = cookie_id + "=; path=/; expires=" + old;
        location.reload();
    });

    /** フォーム内反映 */
    if (getCookies() != null) {
        var cookie = getCookies();
        for (var key in cookie) {
            jQuery("#namechange [name=" + key + "]").val(cookie[key]);
        }
    }

    /** カスタムフィールド取得 */
    jQuery(document).ready(function ($) {
        var page = location.pathname.split('/');
        if(!page[page.length - 2].match(/^top/)){
            var elements = document.querySelectorAll('[id^="post-"]');
            var id_value = elements[0].id;
            var id_string = id_value.split('-');
            var id = id_string[id_string.length - 1];
    
            //変換後取得
            var after_name = getCookies();
            var str_after = "";
            if (after_name != null) {
                //本文取得
                var content = document.getElementsByClassName('entry-content');
                var str_before = content[0].innerText;
                //変換前取得
                $.getJSON(location.protocol + "//" + location.hostname + "/wp-json/wp/v2/posts/" + id + "?_fields=acf", function (results) {
                    $.each(results, function (i, item) {
                        before_name = JSON.parse(JSON.stringify(item));
                        //変換
                        for (var key1 in before_name) {
                            if (key1.match(/^name/) != null) {
                                for (var key2 in after_name) {
                                    if(before_name[key1] && after_name[key1]){
                                        var reg = new RegExp(before_name[key1], 'g');
                                        str_before = str_before.replace(reg, after_name[key1]);
                                    }
                                }
                            }
                        }
    
                        //反映
                        str_after = str_before.replace(/\r?\n/g, "<br />\r\n");
                        content[0].innerHTML = str_after;
                    });
                });
            }
        }
    })
});

/** クッキーを連想配列として取得 */
function getCookies() {

    var url_string = location.pathname.split('/');
    var category = url_string[1];
    var cookie_id = category + "CokkieValue";

    var cookiesText = document.cookie;
    var cookieSplitted = cookiesText.split(";")
    var cookies = new Array();

    for (i = 0; i < cookieSplitted.length; i++) {
        reg = new RegExp(cookie_id)
        if (cookieSplitted[i].match(reg)) {
            var split1 = cookieSplitted[i].trim().split("=");
            var split2 = split1[1].trim().split(",");
            for (j = 0; j < split2.length; j++) {
                if (split2[j].match(/^name/) != null) {
                    var name = split2[j].split(":");
                    cookies[name[0]] = escapeText(decodeURIComponent(name[1]));
                }
            }
        }

    }
    return cookies;
}

/** サニタイズ **/
function escapeText(targetValue) {
  if (targetValue == null || targetValue == undefined) {
     return "";
  }
	return targetValue.replace(/&/g, '&').
           replace(/</g, '<').
           replace(/>/g, '>').
           replace(/"/g, '"').
           replace(/'/g, "'");
	
}

(2023.2.15追記)アドバイスもらったんでサニタイジング処理入れてみた。動作確認してないです、すまない…。動かなかったら連絡ください。
(2023.3.27追記)動かんやんけ!!直しました!!!すみません……

なんかもうちょっとどうにかできる気がするけど、力尽きたので。jQueryって全部書かんでいいやろ…わからん…。
あと、先述した通りサブディレクトリはない想定なので、「https://~/wp/」とかのURLの場合はソースちょっと修正する必要があります。「変換前取得」のところの「/wp-json/wp/v2/posts/」を「/wp/wp-json/wp/v2/posts/」とかにして、サブディレクトリ追加してください。たぶんこれで動く(試してない)
あと、パーマリンクは変更した通りじゃないと動きません。
この「/wp/」をつけるのは、たとえばwordpressを入れたトップページが「https://~/wp/」になってる場合なので、「https://~/」とかのままだったら、上記から変更しなくても大丈夫です。ちょっと詳しい話をすると、worpressの記事は全部idとして番号が振られていて、ここではそのidで記事中の変換項目を取得しているんですね。たとえば名前変換小説ページのidが123だった場合、「https://サイトURL/wp-json/wp/v2/posts/123?_fields=acf」というURLを叩くとデータが取得できると思いますが、取れなかったら前段階で何か間違っています。ACF to REST APIAdvanced Custom Fieldsが有効になっているか確認してください。上記URLを叩くとこんな感じのものが返ってくればOK↓(2023/3/26追記)

5.名前変換ページを作る
まず、カテゴリを作成します。カテゴリは私は連載名にしました。日本語だとバグるので英数字にしましょう。このカテゴリを5.と6.で使用します(2023/3/26追記)
変換項目はカテゴリトップページに作る想定です。記事名は数字オンリーだと変換機能が動いてしまうので、英数字とか英字とかにしてください。
変換項目を作りたいところに下記を追加。

<form id="namechange">
名字<input id="name0" maxlength="20" name="name0" type="text">
名前<input id="name1" maxlength="20" name="name1" type="text">
<button id="submit">更新</button> <button id="delete">削除</button>
</form>

カスタムフィールドにつけた名前と「id」「name」の名前を一致させます。なので、たとえば3と4だけ使いたいとかだったらname3、name4と作ります。
タイトルは変えなくてもいいんですけど、パーマリンクを「top_xxx」とか「top_category」とか「top」から始まるものにしてください。そうじゃないとバグります。
投稿したらページ開いてcookieの登録削除ができるか試してください。

6.本文を投稿する
いよいよ本文を投稿してみましょう。
ただ文章を打ち込むだけ。変換項目と対応するカスタムフィールドに変換する名前を入れます。

カテゴリ選択するのを忘れないでください。
変換しない項目のカスタムフィールドは入力しなくていいです。


7.確認
まず名前を変えて。

ページを確認。

できた!!!!


これで更新作業が楽になる~!と思ったのですが500本移行しなきゃならないのでげんなりしてます。

使用報告はいりませんが、何かあってもサポートはできません。
バグ・質問とかあったらコメントかTwitter @rh_akまで連絡ください。
では~。

この記事が気に入ったらサポートをしてみませんか?