レ点腫瘍学ノート

pukiwikiカスタマイズ箇所/2019 の履歴ソース(No.24)

#author("2019-11-17T15:13:08+09:00;2019-11-16T20:31:44+09:00","default:tgoto","tgoto")
すでにカスタマイズを加えている[[pukiwikiカスタマイズ箇所/2018]]の項目に加えて、2019年に新たに下記の改変を加えた。

#contents

----

*Pukiwiki 1.5.2へのアップデート
これによりlibフォルダ内にあるlib/html.phpなどは再修正を強いられることになった。なお、検索などが高速化したとのことだが100ページ程度の当wikiではこれまでもサイト内検索は一瞬であったため、あまり恩恵を実感できるほどの違いはない。

ja.lng.php, lib/html.phpなどは[[pukiwikiカスタマイズ箇所/2018]]に記載したのと同様の修正を再度加えた。

* PukiWikiのSSL対応(https化)

サイト全体をSSL対応(https化)とした。コスト削減のためにレンタルサーバーで提供されている無料SSLを用いている。最近のモダンブラウザの仕様ではSSLに対応していないサイトでは「安全ではないサイトです」というような警告が表示されるものもある。またSEO的にもHTTPS対応しているか否かが評価対象となるという話もある。

10年ほど前までは個人のウェブサイトにSSLを導入するには数万円の費用を要することもあったが、最近は個人用であれば安価なSSLも利用可能となっている。

** 当サイトの具体的な実施内容

SSL化したサイトでは、サイト内リンク(画像などのページ内要素も含む)が全てSSL化されていることが必要である。ページによって https:// ではなく http:// へのリンクがのこっていると「安全ではないサイトです」の警告が表示されてしまうこともある。サイトをSSL化した場合は .htaccess でhttpへのアクセスをhttpsへ転送する設定をしておくと良い。

Google search consoleでは、ドメインごとDNSで登録しているのではなくサーバに置いた認証ファイルかmetaタグなどでサイトのプロパティを登録している場合、SSL化に伴ってhttpとは別のhttpsのサイトを登録しなおす必要があることがある。またサイトマップもSSL対応後も書き換えがなされていないと意味がないので、https対応のURLを記載すること。

* PukiWikiのSEOとは

Pukiwikiに限らない一般的な検索エンジンからの評価を向上させるためのSEOについては多数のWEBページがあるため、そちらを参照されたい。基本的にSEOには裏技はなく、サイトの内容を充実させることが王道であることは間違いない。中身の充実したPukiwikiを作れば検索エンジンからの評価も高まり、自然にアクセス数は増加する。また様々なウェブサイト、個人ブログからリンクを貼ってもらうことも有効と思われるが、これも内容が充実すれば自然と結果はついてくると思われる。

** Pukiwikiのmetaタグでのkeywordとdescription

metaタグのkeywordは最近のGoogleではほとんど参照されていないということである。したがってあえて記載する必要はないかもしれない。一方で、metaタグのdescriptionは、記載すれば検索エンジンで検索された時にページの要約として表示されるため無意味では無さそうであるが、Googleの場合は本文の丸写しであればdescriptionは書く意味がないという話もある。

PukiWikiの場合は本文の丸写しではないdescriptionを各ページごとに記載するのはシステム的に難しく、当サイトでも記載していない。ただし記載する場合はpukiwiki.skin.phpに直接記載すればよい。

pukiwiki.skin.phpのもともとの構造はかなり複雑なHTMLを吐き出すので、ページのタイトルをh1タグにする、HTML5化が済んでいるサイトなら本文を<main>や<article>などの要素タグで囲むなどの工夫をしておくなど、robotsから見て構造がわかりやすいHTML構造にするなどの配慮は必要だろう。

descriptionは当サイトでは使用していない(2019年9月現在)が、OGPで使用しているdescriptionの部分が参考になると思われる。つまり、OGPのdescriptionを記載する場面では下記のようにして本文のはじめ140文字を抜粋してdescriptionとしているのと同じ方法を取れば良いのである。

> <meta property="og:description" content="<?php echo $str = str_replace(array("\r\n", "\n"), '', mb_substr(strip_htmltag($body, $all = TRUE), 1, 140, "UTF-8")); ?>…" />

**レスポンシブ対応

サイトのレスポンシブ対応(あるいはモバイルフレンドリー化)は必須である。当サイトでも全アクセスの4割はモバイルブラウザ経由であり、さらにPukiwikiの内容によっては過半数がモバイルからのアクセスというPukiwikiもあるだろう。

Googleの検索インデックス作成においてもサイトがモバイルフレンドリーであるかどうかは重要な評価項目である。Pukiwikiのレスポンシブ対応については[[pukiwikiカスタマイズ箇所/2018]]ですでにほとんど対応を済ませているので、そちらを参照してください。

#ogpi(https://oncology.uvs.jp/?6292a4bc9d,amp)

**画像圧縮とサイト表示の高速化

[[Google Pagespeed Insight:https://developers.google.com/speed/pagespeed/insights/]]でウェブページの表示速度などを測定し軽量化の評価をすることができる。これで高得点であることはサイトの高評価につながる。なお、PukiWiki自体はwordpress などに比べるとずっと表示速度は速く、当サイトもサーバが不安定でない限りほぼ99点〜100点であることが多い。

#ref(https://oncology.uvs.jp/img/20190909.png)

サイトそのものを軽くする方法はいろいろなものがあるが、特に効果が大きいのは画像の圧縮である。PNGファイルは[[TinyPNG:https://tinypng.com/]]や[[CompressPNG:https://compresspng.com/]]などのPNG圧縮サイトで徹底的にサイズを小さくしよう。複数のPNG圧縮サイトに繰り返しPNGファイルを投入するとどんどん圧縮できる。

当サイトのロゴPNGファイルも、元ファイルは67KB程度あり、これをmacのある画像編集ソフトで画質を下げて保存してもPNGファイル容量は12KBであったが、複数のPNG圧縮サイトで繰り返し圧縮を行うことで最終的に2350バイトまで圧縮することができた。ほぼ単色の単純なロゴとは言え、この圧縮でGoogle Pagespeed Insightの評価も上がって効果的である。

ほかには複数のCSSのincludeを1つにまとめたり、javascriptを軽量化するか省略するなどするのも効果的であると思われる。当サイトはもともとほとんどjavascriptを使用していないので、これについては言及しない。

**htaccessでのキャッシュの設定

画像ファイルやwebフォントなどについてはキャッシュ設定をすることで高速化が図れる。

なお今回はjavascriptなどについてはキャッシュしていない(このサイトでほとんど使用していないので)。

**サイトマップ

標準のプラグインsitemap.inc.php(またはrss.inc.php)を使う。sitemapプラグインで出力するサイトマップでなくても、RSSもGoogleにはサイトマップとして認識させることができる。ただし標準のrss.inc.phpを使う場合はデフォルトでは最近の更新15件しか表示されないため、pukiwiki.ini.php内のRSSの表示記事数を増やしておく(rss_maxを記事数に対して十分大きな値、たとえば1000程度にしておく)。

このsitemap.inc.phpは https://oncology.uvs.jp/?cmd=sitemap で、rss.inc.phpは https://oncology.uvs.jp/?cmd=rss で表示させることができるので、これらのURLを[[Google Search Console:https://search.google.com/search-console]]でサイトマップとして登録しておくと数日以内にGooglebotがクロールに来るはずである。なお、Google Search Consoleに登録する際は http:// と https:// は別のURLとして区別されるため入力を間違えないように。

** X-Robots-Tag http ヘッダーのnoindexをコメントアウト

lib/html.php内に設定されている X-Robots-Tag http ヘッダーでnoindexを吐くようになっているが、これがどうも必要なページにまでnoindexのhttpヘッダーを送っているようで行儀が悪い。Google search consoleでみると表示されるべきページでもインデックスされていないものが多数あり、その理由を確認すると「httpヘッダーでnoindexを検出したのでインデックスの登録を外した」と表示されてしまうページが多数ある。

正規表現でnoindexをつけるページを振り分けることもできるが、ひとまずHTML内ではなくhttpヘッダーでnoindexをつける設定は下記のようにコメントアウトしておくという方法がある。しかしこれは、本来はインデックスされてほしくないPukiwikiの編集ページや添付ファイルページまでインデックスされそうになるというデメリットもある。利用は慎重に判断すること。

>	//if (!$is_read || $nofollow) {
>	//	if (!headers_sent()) {
>	//		header("X-Robots-Tag: noindex,nofollow");
>	//	}
>	//}

* PukiwikiのAMP対応の試み

2019年9月に当サイトのPukiwikiのAMP  HTML対応に向けて様々な試みをしたが、CSSで描いたページレイアウトの崩れを避けられないことと、GoogleのAMPキャッシュでは動的なモジュールが予想外の挙動を示すことなどから、一時はAMP対応を断念した。

#ogpi(https://oncology.uvs.jp/?ac495292e4,amp)

しかしその後にハンバーガーメニューの改良などを経て、再びAMP化の作業を始めてAMP対応を果たした。

#ogpi(https://oncology.uvs.jp/?249510a175,amp)

* PukiwikiスキンのOGP対応

OGP(open graph protocol)に対応すると、TwitterやFacebookなどのSNS、各種ブログ(Wordpressやはてなブログ)にPukiWikiのURLを貼り付けたときにいわゆるブログカードが表示される機能が付加される。SEOにどの程度の効果があるかは不明だが見た目が良くなることからクリック率も向上するのではないかと思われる。

OGPは基本的にHTMLの<head>内にmetaタグとして記載するので、スキンを改変すれば容易にOGPを実装することができる。今回は一般的なOGPの設定のみにとどめて、FacebookやTwitter専用のタグの記載は最小限とした(Facebook専用OGPタグなどを利用するにはFacebookのアカウントを使って登録・認証を行う必要があるなど、若干の手間が生じる)。

OGPを設定する際にはアイキャッチ画像を用いることが多いが、PukiWikiの性質上それぞれのページに個別にアイキャッチ画像を設定するのは難しいので、今回はfavicon画像へのリンク(favicon192x192.png)を用いることとした(したがってPukiWiki内の全ページで共通の画像が表示される)。<head>内に下記のタグを記載する。この og:description の"1,140"の値は4文字目から143文字目を本文として抜粋するように指示したものであるが、よりよいdescriptionが書ける場合はそちらを利用して良い。

descriptionを記載するプラグインもあるが、PukiWiki 1.5系に対応しているかどうか不明であるため今回は使用していない。contentsプラグインで頁の初めに目次を設定していると、文頭から約140文字を切り取るとちょうど目次の項目名がdescriptionに並ぶので良いかもしれない。

> <meta property="og:title" content="<?php echo $title ?> - <?php echo $page_title ?>" />
> <meta property="og:type" content="article" />
> <meta property="og:url" content="<?php echo $link['canonical_url'] ?>" />
> <meta property="og:image" content="<?php echo SKIN_DIR ?>favicon192x192.png" />
> <meta property="og:site_name" content="<?php echo $page_title ?>" />
> <meta property="og:description" content="<?php echo $str = str_replace(array("\r\n", "\n"), '', mb_substr(strip_htmltag($body, $all = TRUE), 1, 140, "UTF-8")); ?>…" />
> <meta name="twitter:card" content="summary" />

また、<head>にprefixをつけておく。prefixは不要との記事を見ることもあり、たしかにprefixなしでもブログカードは表示されるようである。

> <head prefix="og: http://ogp.me/ns#">

**OGPイメージを各ページに応じて変更できるようにする

上記のOGP対応だけではOGPイメージは全てのページでサイトのロゴを表示するようになっていてページごとには変更できないようになっている。しかし別で記載したページのURL短縮改造と組み合わせて、【ページ名】.jpgや【ページ名】.pngを画像フォルダに置いておけばこれをOGPイメージとして使用するように設定する。

PHPで画像フォルダに【ページ名】.jpgか【ページ名】.pngがあるかどうかで分岐させて、画像があればそれをOGPイメージに使用し、画像がなければサイトロゴをOGPイメージにする。

> <?php
> 	$ogpijpg = 'img/'.substr($canonical_url, -10).'.jpg' ;
> 	$ogpipng = 'img/'.substr($canonical_url, -10).'.png' ;
> if(file_exists($ogpijpg)) /* 短縮URLに連動したOGP画像が存在する場合 */ { ?>
> 	<meta property="og:image" content="<?php echo get_script_uri().$ogpijpg ?>" />
> <?php } else if(file_exists($ogpipng)) { ?>
> 	<meta property="og:image" content="<?php echo get_script_uri().$ogpipng ?>" />
> <?php } else { ?>
> 	<meta property="og:image" content="<?php echo get_script_uri() ?>skin/favicon192x192.png" />
> <?php } ?>

*URL短縮ライブラリの組み込み

URL短縮ライブラリを組み込んで、URLの短縮を試みる。lib/shroturl.phpのアップロード、lib/pukiwiki.php lib/func.php lib/make_link.phpの修正が必要である。他のプラグインの改造などに比べてこのURL短縮ライブラリははるかに構造が複雑で、現在は開発元のサイトの方がPukiWiki 1.5.2まで精力的にアップデート対応をしてくださっているが、今後このアップデートが対応できなくなった場合にはメンテナンスを独力で続けるのは難しそう。。。

#ogp(https://dajya-ranger.com/pukiwiki/embed-url-shortener/,amp)

***lib/pukiwiki.phpの45行目に挿入

> // URL短縮ライブラリロード
> require(LIB_DIR . 'shorturl.php');
> // ページ名上書きセット
> $vars['page'] = get_pagename_from_short_url($vars['page']);

***lib/func.phpの815目に挿入

> {
>     return get_base_uri($uri_type) . get_short_url_from_pagename($page); // ※ライブラリの仕様を一部変更し、2019/06/03記事公開当初の記述に戻した
> /* コメントアウト
>     global $defaultpage;
>     if ($page === $defaultpage) {
>         return get_base_uri($uri_type);
>     }
>     return get_base_uri($uri_type) . '?' . pagename_urlencode($page);
> */
> }

***lib/make_link.php の780行目を下記に変更

> $r_page  = pagename_urlencode($page); //780行 修正前
> $r_page  = get_short_url_from_pagename($page); //780行 修正後

***lib/make_link.php の802行目の ? を削除

> return $al_left . '<a ' . 'href="' . $script . '?' . $r_page . $anchor . //802行 修正前
> return $al_left . '<a ' . 'href="' . $script . $r_page . $anchor . //802行 修正後

*HTML5対応とmetaタグの変更

**DOCTYPE宣言

-<!DOCTYPE html>に変更
-<html lang="ja">に変更
-<nav> <footer> <article>などのHTML5対応の要素タグを配置

**IE9までの古いブラウザ対応

IE9までのブラウザでモダンブラウザ用のタグ(HTML5の要素タグなど)を用いるとレイアウトが崩れてしまうので、<head>に下記の記載を加えている。なお、IE9までのブラウザのシェアはかなり下がってきているためこれを記載しなくてもほとんどのユーザーには害はなさそうである。

> <!--[if lt IE 9]>
> <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
> <![endif]-->

注意点として、2016年1月からGoogle CodeのサーバーのHTML5shivへのリンクは廃止されているので他のCDNにリンクするか、ローカルサーバーにファイルを置いておく必要があることに注意が必要。

> meta http-equiv="X-UA-Compatible" content="IE=edge" //当サイトは非実装

上記のX-UA-Compatibleを使うサイトもあるが当サイトはこれは用いていない。現在は必須とは言えなさそうである。詳しくはこちらのサイトを参考に。
https://www.creativevillage.ne.jp/2819

**metaタグの記載
-<meta charset="utf-8"> 文字コードの指定
-<meta name="viewport" content="width=device-width, initial-scale=1"> viewportの指定(2018年までに対応済み)
**canonical URLとshortlinkの記載
URL短縮ライブラリの導入に伴って、同一内容で非短縮URLと短縮URLの2つのページが生じたため、SEO的にもcanonical URLを記載する必要がある。短縮URLは $link['canonical_url'] で取得できるが、非短縮URLはこのままでは $link 配列から直接取得できず、若干不格好になっている(修正の余地あり)。

> <link rel="canonical" href="https://oncology.uvs.jp/?<?php echo $r_page ?>"> //canonicalリンクの記載
> <link rel="shortlink" href="<?php echo $link['canonical_url'] ?>" /> //短縮リンクの記載

**スマホでページを見た際に数字が並んでいても電話番号としてのリンクを貼らない

iPhoneのSafariの場合であれば8〜11桁の数字は勝手に電話番号だと認識されてアンカーをふかされてTELリンクを貼られてしまう。これ自体はサイトによっては便利な機能であり、特に予約の電話などを受け付けたい小売店・飲食店ではこの機能はありがたいのだが、当サイトのような電話をかけることと直接関係しない場合はこの機能はじゃまになってしまう。むしろ文献の発行年とページ数が勝手にTELリンクになってしまい、不用意にクリックすると電話を発信しそうになるのは勘弁していただきたい。

そこで、ブラウザがTELリンクを貼ることをmetaタグで制限しておく。ただしこれをつけると本来ならTELリンクを張りたいところでもTELリンクにならないことに注意する。

> <meta name="format-detection" content="telephone=no">

*レスポンシブメニュー

別名ハンバーガーメニューとも。スマホなどのモバイルブラウザのみで表示される、クリックすると左の画面外からせり出してくるタイプのメニューである。

#ogpi(https://oncology.uvs.jp/?14f584878f,amp)

*FrontPageだけトップにロゴとサイト名を表示させる

特定ページだけで表示される機能の実装 http://design.kyusan-u.ac.jp/OpenSquareJP/?pukiwiki/Customize#q=%E4%BB%A5%E5%A4%96 で記載されている機能を使って、タイトルが「FrontPage」となっているトップページだけでページタイトルを非表示とし、一方でロゴとサイト名を表示させることにした。
具体的には

> <?php if ( $title == 'FrontPage' ) { ?> AAA <?php } else { ?> BBB <?php } ?>

としておくとページタイトルがFrontPageに合致するページのみでAAAが実行される一方でBBBは実行されない。このAAAやBBBには好みのHTMLや <?php echo $title ?> などを挿入すると、FrontPageだけで特定の画像を表示したり、逆にh1ページタイトルを非表示にしたりできる。一方で <?php if ( $title != 'FrontPage' ) { ?> とすればFrontPage''以外''でこれを実行するようにも設定できる。

これの応用で、FrontPage以外のページでモバイルブラウザから閲覧した場合のみ左上にサイトアイコンとサイト名を記載することにした。FrontPageではこの左上のサイトアイコンとサイト名を非表示にしている。このまま設置しただけでは右上のレスポンシブメニュー(ハンバーガーメニュー)の≡アイコンと高さが微妙にずれてしまい見栄えが良くないので、縦位置を揃えるために、position:relative と top:3px; などを併用して見栄えを整えている。

* その他

** 2カラムへの変更

従来は760px以下のブラウザは1カラム、960px以上のブラウザは3カラムとしてその間を2カラムとしていたが、2019年9月から760pxを境に1カラムと2カラムをレスポンシブに切り替えるデザインとした。

(2019.9.14追記)
その後に1カラムに変更しました。

** htmlinsert.inc.phpプラグインの導入
あらかじめコードしておいたHTMLをPukiwiki内で表示するためのhtmlinsert.inc.phpをインストールする。このプラグインでは、Pukiwikiを設置しているフォルダ内にhtmlinsertのフォルダを新たに置いておき、この中にHTMLを記載したtxtファイルを置いておくとPukiwiki内でincludeすることができる。サイドバーでTwitterへのリンクや検索ボックスを設置するためにこのプラグインを利用している。
''関連ページ:'' [[https://pukiwiki.osdn.jp/?自作プラグイン/htmlinsert.inc.php>https://pukiwiki.osdn.jp/?%E8%87%AA%E4%BD%9C%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3/htmlinsert.inc.php]]

**スタイルシート pukiwiki.css
h1,h2,h3などのborderの変更、行間の拡大などデザイン上の微修正。

**存在しないページへのアクセスを404にする
Pukiwikiのデフォルトでは存在しないページにアクセスされた場合はnewpageプラグインが作動してそのタイトル名の新しいページを作成する画面に遷移してしまう。これを避けるために、plugin/read.inc.phpに対して下記の工夫を行った。" } else if (is_pagename($page)) { "の下にある2行を削除し、そのあとに6行を追加する。

>$vars['cmd'] = 'edit'; //この行を削除
>return do_plugin_action('edit'); //この行を削除

以下の行を追加する。

> header('HTTP/1.0 404 Not Found');
> return array(
> 'msg'=>'NOT FOUND',
> 'body'=>str_replace('$1', "/?cmd=edit&amp;page=$page",
> str_replace('$2', "../", $_msg_notfound))
> );

これだけだとnewpageを作ろうとした時も存在しないページと判定されてしまって編集画面に入れないので、plugin/newpage.inc.phpも以下のように変更する。つまり、newpage変種画面にcmd=readではなくcmd=editで入るように設定する。

> pkwk_headers_sent();
> header('Location: ' . get_base_uri(PKWK_URI_ROOT) . '?cmd=read&page=' . $r_page . '&refer=' . $r_refer); //変更前

> pkwk_headers_sent();
> header('Location: ' . get_base_uri(PKWK_URI_ROOT) . '?cmd=edit&page=' . $r_page . '&refer=' . $r_refer); //変更後

**インデックスされたくないページにrobots.txtを設定する

Pukiwikiの内部ページはやたらと検索サイトにインデックスされるのを避けたい。Googleのbotが勝手にPukiwikiを書き換えることはないと思うが、検索された時にcmd=newpageなどプラグインページばかりが検索されるのは避けたいものである。検索インデックスを避ける方法は色々とあるが、ひとまず単純にrobots.txtに下記の事項を書いておいてGoogle  botを避けることとする。

> User-agent: *
> Disallow: /*plugin=*
> Disallow: /*cmd=diff*
> Disallow: /*cmd=newpage*
> Disallow: /*cmd=freeze*
> Disallow: /*cmd=rename*
> Disallow: /*cmd=edit*
> Disallow: /*cmd=backup*

**印刷用スタイルシート print.css
必要性が乏しくなってきたため、print.cssを廃止した。

**pukiwiki.ini.php
-nowikinameを0から1に変更(CheckMateなどのキーワードへの自動リンクを回避するため)

**recent.inc.phpの呼び出し回数
recentプラグインはサーバーへの負荷対策として、PukiWiki 1.4.6から一度に呼び出せる回数に制限が2度までとかけられている。しかし、これではレスポンシブ対応のサイトでFrontPageにrecentプラグインを使うと、本文内・サイドバー・スマホ用ハンバーガーメニューの3箇所で呼び出すことになりエラーが生じる。呼び出せる回数を3回に増やしておくことで回避できる。
''関連ページ:'' [[https://pukiwiki.osdn.jp/dev/?BugTrack/2090]]

> define('PLUGIN_RECENT_EXEC_LIMIT', 3); // ここを2から3に変更しておく

**検索ページや編集ページでもMenubarを表示する

Pukiwikiの初期設定のままではread設定されているページ(検索ページや編集ページなど)ではMenubarが表示されないので、read設定されているページでもMenubarが表示されるようにする。これを設定しておかなければレスポンシブメニューをクリックした時に白紙が表示されるだけになってしまって寂しい。pukiwiki.skin.phpに少し手を加えることで回避できる。
‘’関連ページ:’’ [[https://pukiwiki.osdn.jp/dev/?PukiWiki/1.4/ちょっと便利に/編集や検索ページでも常にMenubarを表示する>https://pukiwiki.osdn.jp/dev/?PukiWiki/1.4/%E3%81%A1%E3%82%87%E3%81%A3%E3%81%A8%E4%BE%BF%E5%88%A9%E3%81%AB/%E7%B7%A8%E9%9B%86%E3%82%84%E6%A4%9C%E7%B4%A2%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%A7%E3%82%82%E5%B8%B8%E3%81%ABMenubar%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B]]

> <?php if (arg_check('read') && exist_plugin_convert('menu')) { ?> //編集前
> <?php if (exist_plugin_convert('menu')) { ?> //編集後

** 「関連ページ」に改行を lib/func.php
308行目 return '<span class="page_passage" data-mtime="' . $date_atom . '"></span>'; の</span>の直後に<br />を挿入して「このページに関連するページ」の各項目を改行させて縦に並べるようにした。
> return '<span class="page_passage" data-mtime="' . $date_atom . '"></span><br />'; //編集後は<br />を加えている