元々、このブログ以前のブログはレンタルサーバーで動かしていました。
あまり更新しなかったため、必要性はないと感じ、新たにWordPressをローカルへ導入し、静的化した後、GitHub Pagesで運用することを考えました。
この2日間かけて、ようやく少し使えるような形になりました。
今回は、WordPressプラグインである、Simply Staticを使って静的化したいと思います。
Cocoonテーマを利用しているので少し変わるかもしれません。
私はWordPressに関しては完全に素人なので申し訳ないです。
手順
簡単にまとめておきます。
- Simply Staticを導入する
- 適当にSimply Static用のフォルダをつくる (つくったフォルダをsimplystatic/とします)
- WPの管理メニューのSimply Staticのページから静的ファイルを生成する
- simplystatic/をGitリポジトリにする (simplystatic下で以下のコマンドを実行)
git init git add * git commit -m "first" git remote add origin https://github.com/(ユーザー名)/(リポジトリ名).git git push origin main
- conv_for_simply.rbという日本語フォルダを変換してくれるGemをsimplystatic/につくる
- WordPressのルートにbatファイル(push.bat)をつくる
cd ./simplystatic/ ruby conv_for_simply.rb git add * git commit -m "update" git push
- batファイルを実行する
- GitHub Pagesの設定をする
Simply Staticの導入
※インストール後、必ず有効化しておきましょう。
こちらのプラグインは静的化するためのプラグインです。
静的化とは静的ファイルであるHTML、JS、CSS、画像など簡単に言えばアクセスしてもソースが変化しないクライアントサイドのファイルに変換することを指します。
つまり、PHPが生成したソースをHTMLファイルとして保存します。
適当にSimply Static用のフォルダをつくります。つくったフォルダをsimplystatic/とします。
正しく導入できれば、WordPressの管理メニューのサイドバーにSimply Staticという項目が追加されていると思います。
まず、設定を選びましょう。
配送方法はローカルディレクトリに設定してあげましょう。
ローカルディレクトリの入力欄にはつくったフォルダであるsimplystatic/(任意)のパスを指定します。
生成を選択し、静的ファイルを生成するをクリックしましょう。
待機すると生成されると思います。
クソ長いですよね、、、一分もかかりました…(笑)
GitHub の設定
GitHubのリポジトリでSettingsを開き、Pagesの項目に移動してください。
Sourceのブランチをmainで選択してSaveをクリックしましょう。
これで完了なのですが、Custom domainも私は設定しました。
おまけ
検索を機能させる
※こちらの検索機能に関しては完全に機能しているわけではありませんのでご了承ください
静的化したら検索機能が動作しないんですよ。まあ当たり前なことです。
検索機能はPHPでつくられており、サーバーサイドで動的に処理するものなのです。
つまり、クライアント側で処理できるようにインデックス化されたものも静的化しないとなりません。
WordPressにはRest APIがあります。
APIで生成されたjsonを静的化してしまえばよいという考えになりました。
めちゃくちゃなことしてますが、私はこうするしかないと思いました。
そのためのPHPスクリプトをここにおいておきます。
名前は適当ですが、なんでもいいです。
- push.php
<?php define('URL', dirname((empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']) . "/"); define('DIR', "simplystatic/"); function save_url2static($path, $ext = 'json') { $src = file_get_contents(URL . $path); if (!file_exists(DIR . $path)) mkdir(DIR . $path, 0777, true); $src = str_replace(str_replace('/', '\/', URL), '/', $src); file_put_contents(DIR . $path . "/index." . $ext, $src); } save_url2static("wp-json/wp/v2/posts"); save_url2static("wp-json/wp/v2/pages"); save_url2static("wp-json/wp/v2/media"); save_url2static("wp-json/wp/v2/comments"); save_url2static("wp-json/wp/v2/taxonomies"); save_url2static("wp-json/wp/v2/taxonomies"); save_url2static("static-json/categories"); if (!file_exists(DIR . 'conv_for_simply.rb')) copy('conv_for_simply.rb', DIR . 'conv_for_simply.rb'); copy('client.js', DIR . 'client.js'); echo exec('push.bat') . '<br />'; echo "pushed!<br />"; exit;
- client.js
var $client_lang = { search_result: "“$1” の検索結果", search_in_site: "サイト内を検索", posts_not_found: "投稿が見つかりませんでした。" }; var $url = new URL(window.location.href); var $params = $url.searchParams; var $htmlSetted = false; function apprStr($str) { $str = $str.toLowerCase(); $str = $str.replace(/(<([^>]+)>)/gi, ''); $str = $str.replace(/[A-Za-z0-9]/g, function($m) { return String.fromCharCode($m.charCodeAt(0) - 0xFEE0); }); $str = $str.replace(/[ァ-ヶ]/g, function($m) { return String.fromCharCode($m.charCodeAt(0) - 0x60); }); return $str; } function getMeta($metaProperty) { var $metas = document.getElementsByTagName('meta'); for (let $j = 0; $j < $metas.length; $j++) { if ($metas[$j].getAttribute('property') === $metaProperty) { return $metas[$j].getAttribute('content'); } } } if ($params.has('s') ) { var $s = $params.get('s'); var $isFound = false; var $html = ` <h1 id="archive-title" class="archive-title"><span class="fa fa-search" aria-hidden="true"></span>"${$s}"</h1> <form class="search-box input-box" method="get" action="/"> <input type="text" placeholder="${$client_lang['search_in_site']}" name="s" class="search-edit" aria-label="input" value="${$s}"> <button type="submit" class="search-submit" aria-label="button"><span class="fa fa-search" aria-hidden="true"></span></button> </form> <div id="list" class="list ect-entry-card front-page-type-index"> `; document.title = $client_lang['search_result'].replace('$1', $s) + " | " + getMeta("og:site_name"); var $categories_name = new Array(); fetch('./static-json/categories/index.json') // /index.json .then(($response) => $response.json()) .then(($data) => { if ($data !== undefined) Object.keys($data).forEach($key => { var $item = $data[$key]; $categories_name[$item.term_id] = $item.name; }); fetch('./wp-json/wp/v2/posts/index.json') .then(($response) => $response.json()) .then(($data) => { if ($data !== undefined) $data.forEach($item => { if (apprStr($item.title.rendered).indexOf(apprStr($s)) != -1 || apprStr($item.content.rendered).indexOf(apprStr($s)) != -1) { $isFound = true; var $categories_html; $item.categories.forEach($id => { $categories_html += '<span class="entry-category">' + $categories_name[$id] + '</span>'; }); var $post_date = $item.date.replace('-', '.'); $post_date = $post_date.substr(0, $post_date.indexOf('T')); $html += ` <a href="${$item.link}" class="entry-card-wrap a-wrap border-element cf" title="${$item.title.rendered}"> <article> <figure class="entry-card-thumb card-thumb e-card-thumb"> <img data-src="/wp-content/themes/cocoon-master/images/no-image-320.png" alt="" class="no-image entry-card-thumb-image list-no-image lozad lozad-img" loading="lazy" width="320" height="180" /><noscript><img src="/wp-content/themes/cocoon-master/images/no-image-320.png" alt="" class="no-image entry-card-thumb-image list-no-image" width="320" height="180" /></noscript> <span class="cat-label cat-label-13">Minecraft</span> </figure><!-- /.entry-card-thumb --> <div class="entry-card-content card-content e-card-content"> <h2 class="entry-card-title card-title e-card-title" itemprop="headline">${$item.title.rendered}</h2> <div class="entry-card-snippet card-snippet e-card-snippet"> ${$item.excerpt.rendered} </div> <div class="entry-card-meta card-meta e-card-meta"> <div class="entry-card-info e-card-info"> <span class="post-date"><span class="fa fa-clock-o" aria-hidden="true"></span> ${$post_date}</span> </div> <div class="entry-card-categorys">${$categories_html}</div> </div> </div><!-- /.entry-card-content --> </article> </a> `; } }); if ($isFound === false) { $html += ` <div class="posts-not-found"> <h2>NOT FOUND</h2> <p>${$client_lang['posts_not_found']}</p> </div> `; } $html += `</div><!-- .list -->`; document.addEventListener("DOMContentLoaded", function() { if ($htmlSetted === false) { document.getElementById("main").innerHTML = $html; $htmlSetted = true; } }); window.addEventListener("load", function() { if ($htmlSetted === false) { document.getElementById("main").innerHTML = $html; $htmlSetted = true; } }); }); }); }
テーマのheader.phpの</head>前に以下のコードを加える
<script src="./client.js" type="text/javascript" charset="utf-8"></script>
コメントを機能させる
Utterancesというものを使い、GitHubのIssueをサイトに埋め込み、コメント欄として利用します。
https://utteranc.es/
テーマのcomments.phpを書き換えます。
<?php //コメントエリア
/**
* Cocoon WordPress Theme
* @author: yhira
* @link: https://wp-cocoon.com/
* @license: http://www.gnu.org/licenses/gpl-2.0.html GPL v2 or later
*/
if ( !defined( 'ABSPATH' ) ) exit;
if ( is_comment_allow() || have_comments() ): ?>
<div id="utteranc_comment">
<!-- comment area -->
ここにコード
</div>
<?php endif ?>
生成したコードを「ここにコード」に貼り付けましょう。