WordPressのビジュアルエディタにFont Awesomeを表示する

最終更新:2017/01/16

本記事は、前の記事の方法でFont Awesomeを導入していることを前提としています。


Font Awesomeを導入しただけでは、プレビューを含む実際のサイトの表示にしか反映されない。ビジュアル・エディタにも表示されるようにしないと、プレビューでマークアップが間違っていないか逐一確認しなければならないので執筆の能率が落ちる。Font Awesomeは便利だけど、能率が悪くなると使う動機が薄れていく。可能ならばビジュアル・エディタにもFont Awesomeを表示させたい。

本記事を書いている時点でのFont Awesomeのバージョンは4.7.0。

WP Visual Icon Fontsは更新が停滞中

Font Awesomeをサイトとビジュアル・エディタの両方に表示させるプラグインとしてはWP Visual Icon Fontsが有名だけど、更新が年単位で滞っている。Font Awesome 4.0.3の時点で止まっているので、比較的最近追加されたアイコンフォントには対応していない。最初はその方法しか見つからなかったので試してみたけど、WordPress 4.7.1でも動作はするようだ。

使えないアイコンがあるとなると少々気持ち悪い。メジャーどころのアイコンは4.0までで実装されていたので実用上はそれほど困らないだろうけど、WP Visual Icon Fontsがいつまで使えるかはわからない。なんとかプラグインに頼らない方法はないか調べることにした。

エディタのCSSにスタイルを追加する方法

当初は、Font Awesome用のCSSをeditor-style.cssに単純にインポートすればいいのではないかと考えたんだけど、どうもそれではうまくいかない。強引に全体をコピー&ペーストする方法も考えたけど、Font Awesomeがバージョンアップする度にそれをやるのでは今後のメンテナンス作業に手間がかかりすぎる。CDN(Contents Delivery Network)を使って本家からCSSを引っ張ってくる方法を紹介している記事もあったけど、せっかく自分のサーバーにFont Awesomeを導入したのにビジュアル・エディタの表示のためだけにCDNを使うのでは二度手間になる。

そこで、functions.phpに次のコードを追加する。念のため、不具合があった時にすぐに戻せるように子テーマを編集するほうが好ましい。add_editor_style関数は、WordPress 3.0で追加された比較的新しい関数で、editor-style.cssに記述されているビジュアルエディタ専用スタイルシートに更にスタイルを追加するもの。引数にはFont AwesomeのCSSを指定するわけだけど、テーマが存在しているディレクトリ(フォルダ)から見て相対パスで指定する。

function vf_add_editor_styles() {
	add_editor_style( 'font-awesome/css/font-awesome.min.css' );
}
add_action( 'admin_init', 'vf_add_editor_styles' );

functions.phpを保存してテーマのディレクトリにアップロードする。

表示の確認

新規記事を用意してテキスト・エディタでマークアップを打ち込んだ後、ビジュアル・エディタに切り替えると次のように表示される。Font Awesome 4.1~4.7で実装されたアイコンも表示されているので、WP Visual Icon Fontsを無効化し忘れたということはないことがわかる。

問題点

綺麗にまとまったように思えるけど、欠点もある。

WP Visual Icon Fontsは、TinyMCE(ビジュアル・エディタ)にアイコン挿入用のドロップダウンメニューを追加し、視覚的にアイコンを選べるようになっている。これはこれで便利で、上記の方法を使う場合は従前のようにFont Awesomeのページに行って、使いたいアイコンとそのクラス名を調べてこなければならない。

最新のアイコンは使えなくてもいいから手軽にアイコンを入力できるほうがいいか、プラグインの更新に左右されずに最新のアイコンと機能を使えるほうがいいかを選択することになる。同居させてもおそらく問題は起きないだろうけど、CSSは重複してお互いに打ち消し合う。

もっとも、WP Visual Icon Fontsのドロップダウンメニューでアイコンを選んだ場合でも、次のようなマークアップが挿入されてしまう。公式では<span>要素は文脈上必要でない限り、必須ではないとされている。

<i class="fa fa-camera-retro"><span style="color: transparent; display: none;">icon-camera-retro</span></i>

Font Awesome 4.0の頃はこれが正式な書き方だったのかもしれないけど、場合によってはテキスト・エディタに移って消して回らなければならないという問題も起こりえるため、一概にどちらが優れているとは言えないかもしれない。

関連記事

参考記事

WordPressにFont Awesomeを導入する

最終更新:2020/01/18

WordPressの基本テーマのひとつであるtwentyfifteenは、コンテント・フッターのメタ情報などの表示にGenericonsを使用していて、それに関連するファイルも内蔵して配布されている。本ブログのテーマもtwentyfifteenを親テーマとしてGenericonsを引き継いで使用している。

GenericonsはGenericons Neueへ

ところが最近(2016年後半?)、GenericonsはGenericons Neueと名前が変わった。インターネット・サービスのブランドなどに関連する一部のアイコンが削除され、従来のアイコンのデザインも変わり、装いも新たになった。しかしながら、SVGを使う方式がメインになったのか、使い方が変わってしまったようだ。WordPressをはじめとする、レンタルサーバーなどで運用されている一般のサイトに実装するためのガイドが書かれているわけでもない。

GitHubを見るとicon-fontというフォルダに旧Genericonsと似たような構成のファイルもあるようだけど、ダウンロード用パッケージが用意されているわけではないので、ちょっとハードルが高い。もともとWordPressのデフォルト・テーマを流用していただけなので旧Genericonsの使い方をちゃんと理解しているとは言い難く、旧版のコードの書き方も今となっては調べようがない。そのため、仮にバイナリを含むファイルをダウンロードできたとしても、その先どうしたらいいのか見当がつかない。プログラミング言語は世界共通語と言え、言葉は通じなくてもやりたいことが伝わることもよくあるから、説明は英語で書いてあっても、コード例が書いてあればなんとなくわかることも多いんだけども。

いずれにせよ、新アイコンを使うならファイルの差し替え程度では済まないので、Genericons Neueをちゃんと理解してテーマを改造しなければならなくなった。個人利用でも商利用でも目的に制限を受けないGPL-2.0ライセンスだったのは魅力だったんだけど、使い方を理解できないのでは仕方ない。Genericons Neueを使うために膨大な作業時間と試行錯誤を要することが予想されるのも気が進まない理由のひとつ。

そこで、旧Genericonsと似たようなフォント感覚で使用できるFont Awesomeを試してみることにした。

本記事を書いている時点でFont Awesomeのバージョンは4.7.0。

Font Awesomeのアップロード

Font AwesomeのWEBサイトからzipアーカイブのパッケージをダウンロードして作業フォルダに解凍する。zipアーカイブにはバージョン番号がついているので、削除してフォルダ名をfont-awesomeとしておくと後の作業がしやすい。

使用しているテーマが存在するディレクトリにfont-awesomeフォルダごとアップロードする。実際にはどこのパスにアップロードしてもいいんだけど、テーマ内のディレクトリのほうがわかりやすいだろう。今回はCSSを使用して導入するので、赤字以外のディレクトリとファイルは必要ないので削除するけど、あっても特に支障はない。

  • font-awesome
    • css
      • font-awesome.css
      • font-awesome.min.css
    • fonts
      • FontAwesome.otf
      • fontawesome-webfont.eot
      • fontawesome-webfont.svg
      • fontawesome-webfont.ttf
      • fontawesome-webfont.woff
      • fontawesome-webfont.woff2
    • less
    • scss
    • HELP-US-OUT.txt

なお、上のリストのフォルダアイコンやファイルアイコンはFont Awesomeで実現している。

functions.phpからFont Awesomeを組み込む

Font Awesomeは、<head>要素内の<link>要素からCSSをリンクして使用する。WordPressに正しくスタイルを取り込ませる方法として、wp_enqueue_style関数を使用する。テーマのfunctions.phpに次のコードを追加する。引数にはget_stylesheet_directory_uri関数を使用してstyle.cssのある場所を参照し、その後に続く相対パスを連結して指定する。get_stylesheet_directory_uri関数は末尾にスラッシュ(/)を返さないので、相対パスの前に必ずスラッシュを書き足しておく。

function enqueue_font_awesome_stylesheets(){
	wp_enqueue_style('font-awesome', get_stylesheet_directory_uri() . '/font-awesome/css/font-awesome.min.css');
}
add_action('wp_enqueue_scripts','enqueue_font_awesome_stylesheets');

header.phpに直接<link>要素を書き込んでも結果は同じだけど、WordPressに「style.css以外にどういったスタイルシートを組み込みたいのか」を明確に知らせることができる。twentytwelve以降はfunctions.phpからCSSを読み込む仕組みになっているはずなので、そこに追加するという意味合いになる。繰り返しになるけど、本ブログのテーマはtwentyfifteenをベースにした子テーマを使用している。

(非推奨)header.phpに直接Font Awesomeを組み込む

※この節の方法は、functions.phpからwp_enqueue_style関数でスタイルシートを組み込んでいない古いタイプのテーマでのみ使うべき。誤った作業の記録として残してある。

Font Awesomeは、<head>要素内の<link>要素からCSSをリンクして使用するようになっている。テーマのheader.phpを次のように編集し、スタイルシートを読み込ませるのが最も簡単な方法。相対パスを指定すると、各投稿ページのURLをベース・ディレクトリとしてそこからFont Awesomeを探してしまうので、長くなっても絶対パスを指定する。

<head>
	<meta charset="<?php bloginfo( 'charset' ); ?>">
	<meta name="viewport" content="width=device-width">
	<link rel="profile" href="http://gmpg.org/xfn/11">
	<link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>">
	<!--[if lt IE 9]>
	<script src="<?php echo esc_url( get_template_directory_uri() ); ?>/js/html5.js"></script>
	<![endif]-->
	<?php wp_head(); ?>
	<!-- Font-Awesome 4.7.0 stylesheet -->
		<link rel="stylesheet" href="http://example.domain.name/wp-content/themes/twentyfifteen-child/font-awesome/css/font-awesome.min.css">
</head>

表示例

 camera-retro
recycle (Ver. 4.1)
bus (Ver. 4.2)
motorcycle (Ver. 4.3)
battery-three-quarters (Ver. 4.4)
hashtag (Ver. 4.5)
question-circle (Ver. 4.6)
thermometer-three-quarters (Ver. 4.7)
snowflake (Ver. 4.7)

<i class="fa fa-fw fa-2x fa-camera-retro"></i> camera-retro
<i class="fa fa-fw fa-2x fa-recycle"></i> recycle (Ver. 4.1)
<i class="fa fa-fw fa-2x fa-bus"></i> bus (Ver. 4.2)
<i class="fa fa-fw fa-2x fa-motorcycle"></i> motorcycle (Ver. 4.3)
<i class="fa fa-fw fa-2x fa-battery-three-quarters"></i> battery-three-quarters (Ver. 4.4)
<i class="fa fa-fw fa-2x fa-hashtag"></i> hashtag (Ver. 4.5)
<i class="fa fa-fw fa-2x fa-question-circle"></i> question-circle (Ver. 4.6)
<i class="fa fa-fw fa-2x fa-thermometer-three-quarters"></i> thermometer-three-quarters (Ver. 4.7)
<i class="fa fa-fw fa-2x fa-snowflake"></i> snowflake (Ver. 4.7)

関連記事

参考記事

固定ページに構造化データを考慮してパンくずリストを追加する

最終更新:2017/01/13

WordPressの固定ページにパンくずリストを追加する。どうせ追加するなら、Googleが収集して階層構造を認識してくれる構造化データを考慮したマークアップ記述にしたい。

基本的に、構造化データの記述を支援してくれるBreadcrumb NavXTプラグインを利用する。本記事を書いている時点での最新バージョンは5.6.0

インストール方法に特別変わった手順は必要ないので省略する。

パンくずリストを追加すること自体はそれほど難しくはないけど、構造化データを考慮するとなると話が異なってくる。最初は気付かずにだいぶ古い記事を参考にしていたのでGoogleの構造化データテストツールで試行錯誤しても一向にエラーが解消されずに苦労したので、改めて書き留めておく。

Breadcrumb NavXTの設定

Breadcrumb NavXTにはデフォルトでパンくずリストの各要素のためのマークアップがあらかじめ設定されているけど、Googleのパンくずリスト(Breadcrumbs)に関するドキュメントやサンプルを見ると若干異なる。今回は、RFDa形式のマークアップを参考にした。

また、Googleのサンプルには<li>要素にパンくずリスト用のプロパティやフィールドが直接記述されているけど、Breadcrumb NavXTの設定画面でそれをやろうとすると拒否されてしまう。そのため、<span>要素をもうひとつ追加し、その中にプロパティを記述することにした。

リンクありのマークアップ

次のマークアップは固定ページ用、あるいはホームページ用の「リンクあり」のパンくずリストの要素。見やすくするために改行、インデントしてあるけど、実際の設定画面に入力する時は改行やタブを削除する。

<li>
	<span property="itemListElement" typeof="ListItem">
		<a property="item" typeof="WebPage" href="%link%" class="%type%">
			<span property="name">%htitle%</span>
		</a>
		<meta property="position" content="%position%">
	</span>
</li>

リンクなしのマークアップ

次のマークアップは固定ページあるいはホームページのもので、現在表示されているページなど、リンクする必要がないページのパンくずリスト。

<li>
	<span property="itemListElement" typeof="ListItem">
		<span property="name">%htitle%</span>
		<meta property="position" content="%position%">
	</span>
</li>

投稿などのフォーマットについて

ブログ記事などの投稿(post)にパンくずリストを表示したいケースもあるだろうし、Breadcrumb NavXTにも設定項目が備えられてはいる。ただ、投稿の場合は複数のカテゴリを設定できるために親子関係が複雑になりがちで、Breadcrumb NavXTの設定以外にも考えなければならないことが多くなる。基本的な考え方やマークアップは固定ページと同じだけど、本記事ではとりあげない。

テンプレートにパンくずリストを追加する

いつも使っているテーマのテンプレートにパンくずリストを追加する。次のコードは、twentyfifteenテーマの一般用固定ページを表示するcontent-page.phpに変更を加えた例。

	<header class="entry-header">
		<?php /* breadcrumbs */ ?>
			<ol class="breadcrumbs" typeof="BreadcrumbList" vocab="http://schema.org/">
				<?php if(function_exists('bcn_display'))
				{
					bcn_display();
				}?>
			</ol>
		<?php /* breadcrumbs */ ?>

		<?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
	</header><!-- .entry-header -->

RFDa形式の構造化データとしてリスト化したい場合は、3行目と8行目のパンくずリストを囲むタグを<ol>要素にして順序のあるリストにしておくことをGoogleは推奨している。

Googleで受け付けてくれる構造化データを意識しない場合は、Breadcrumb NavXTのインストールガイドにもあるように3行目と8行目は<div>タグでもよく、リストの各要素はデフォルト設定のような<span>要素でも構わない。特にCSSを設定しなくても簡素なテキストとして横一列にパンくずリストが並ぶ。

CSSの調整が手間だったので、パンくずリストをエントリ・ヘッダーの中に入れてしまったけど、サイトのデザインや他の構造化データの問題で都合が悪い場合は外に出してしまっても問題ない。構造化データというのは、ブラウザに表示されない<meta>要素などとは異なり、検索エンジンが識別に使用するクラス、プロパティ、フィールドが設定してありさえすれば、どういう文脈のところに入っていても識別される。つまり、検索エンジンが識別するためだけの特別なデータを別に用意する必要はなく、人間が見るための情報を検索エンジンに意味をわからせるためのデータとして兼ねてしまえるということ。

テンプレート・ファイルの変更が済んだらWordPressのサーバーにアップロードする。

構造化データのテスト

念のため、エラーが出ていないか構造化データ テストツールで固定ページ固有のURLを入力し、テストする。マークアップの改善がテストツールにすぐに反映されない場合は、ページのソースを表示させてパンくずリストの部分だけコピーしてエラーや警告が出ている部分に貼り付けたり、手入力で修正することでチェックだけはできる。

RFDa形式の場合、Googleによって解釈されたパンくずリストは次のように表示される。問題ないようならば、Googleボットがクロールに来るのを待つ。

クローラーが来て情報が収集されると、構造化データに従い、次の画像のようにパンくずリストが検索結果にも表示されるようになる。

CSSの追加

最後に、パンくずリスト用のCSSをテーマのstyle.cssに追加する。構造化した上で普通のテキストでいい場合はリストを横並びにするCSSだけでいいはず。

デザインは好みの問題が大半を占めるので、次のCSSはあくまでも例に過ぎない。特に、最近のCSSは高度化していて画像を使っていないのが不思議なくらい非常に凝った作りになっているものも多いので、CSSのコードを眺めているだけでは何を意図したプロパティなのかはわかりにくいと思われる。気になるデザインのパンくずリストを見つけたらブラウザの要素解析ツールで検証してみるといいだろう。

.breadcrumbs {
	list-style: none;
	display: table;
	margin-bottom: 2px;
	font-size: 12px;
}

.breadcrumbs li {
	display: table-cell;
	position: relative;
	left: 20px;
	padding: 0 20px 0 0;
	margin: 0;
	background-color: #c7dcef;
	line-height: 20px;
/* 	color: #fff; */
}

.breadcrumbs li > span {
	position: relative;
	padding: 0 10px;
}

.breadcrumbs li:after {
	content: "";
	position: absolute;
	top: 0;
	right: -4px;
	border: 0 solid #fff;
	border-left: 10px solid #c7dcef;
	border-top: 10px solid #c7dcef;
	border-width: 10px 10px;
	width: 0;
	height: 0;
}

.breadcrumbs li:before {
	content: "";
	position: absolute;
	top: 0;
	left: -20px;
	border: 0 solid #c7dcef;
	border-left: 10px solid transparent;
	border-top: 10px solid transparent;
	border-width: 10px 10px;
	width: 0;
	height: 0;
}

上記のCSSを使うと、次のようにパンくずリストが表示される。リストの各要素の前(:before疑似要素)と後(:after疑似要素)に斜めの切り欠きを追加している。

参考記事

WordPressの子テーマに固定ページ用テンプレートを追加する

最終更新:2017/01/13

WordPressの子テーマは親テーマのコードを直接変更することなくコードを差し替えたり追加したりできるため、各自の好みや目的に応じたカスタマイズがしやすいという特徴がある。

仮に手に負えなくなったとしても、子テーマを丸ごとサーバーから削除してしまえば元に戻せるため、初心者でも挑戦しやすい。もちろん、プログラミングの一種であることに変わりはないため、子テーマをカスタマイズしたことによって発生した事態には当方は一切責任を負えない。

テーマを構成するコードのほとんどはPHPというスクリプト言語で記述されている。一般的なHTMLの途中にPHPスクリプトをタグのような形式で挟んでいくような記述スタイルを採用しているので、HTMLさえ理解していれば比較的取っつきやすい。

一方、WEBデザインで頻繁に使われるものでも、JavaScriptはスクリプトのほうが優位で、HTMLタグはあくまでもJavaScriptから出力される文字列という扱いになるため、HTMLの階層構造がわかりやすくなるようにインデントしながら記述するのは難しいという特徴がある。できないわけではないけど、JavaScriptの構文上のネストなのかHTMLを見やすくするためのネストなのか判別しづらくなるためJavaScriptの都合に合わせるのが一般的で、スクリプト内のHTMLはキリのいいところまでひたすら1行で書くというのもそれほど珍しい話ではない。見た目にもまさにプログラムコードといった趣で、動的HTMLを実現する方法がJavaScriptくらいしかなかった時代にはオブジェクト指向言語にも通じる記述方法も相まって決して初心者向きとは言えなかった。

また、JavaScriptはウェブ・ブラウザのようなクライアント側で動作するものであるのに対し、PHPはサーバー側が適切なバージョンのライブラリを実装していないと動作しないという性質のあるものなので、一般的な環境のローカルPCでは試験できない。手直ししたコードをサーバーに逐一アップロードしなければならないため動作確認に若干時間がかかり、それなりに根気が必要になるという点は覚えておいたほうがいい。

当ブログのデザインはWordPress標準のTwenty Fifteenテーマをベースにした子テーマを使用しているけど、WordPressに実装されているテンプレート関連タグ(関数群)は共通なので、他のテーマでも作業そのものは大差ない。プログラムに詳しくなくても親テーマのコードを参考にして見よう見まねで組んでもなんとかなる。

テンプレートの追加

親テーマの固定ページ用テンプレート・ファイルpage.phpを複製し、追加テンプレート用のファイルを用意する。テンプレートは固定ページにしか使えないものなので自明ではあるんだけど、念のため「page」という単語をファイル名のどこかに入れておいたほうが後々改良を加えたくなった時にどこを変更すればいいのか思い出しやすくなる。

page.phpの記述は次のようになっている。ヘッダーと記事ループとフッターが記述されているだけのシンプルなもので、ここで悩むようなことはないだろう。24行目でcontent-page.phpというテンプレートファイルを読み込んでいる。

<?php
/**
 * The template for displaying pages
 *
 * This is the template that displays all pages by default.
 * Please note that this is the WordPress construct of pages and that
 * other "pages" on your WordPress site will use a different template.
 *
 * @package WordPress
 * @subpackage Twenty_Fifteen
 * @since Twenty Fifteen 1.0
 */

get_header(); ?>

	<div id="primary" class="content-area">
		<main id="main" class="site-main" role="main">

		<?php
		// Start the loop.
		while ( have_posts() ) : the_post();

			// Include the page content template.
			get_template_part( 'content', 'page' );

			// If comments are open or we have at least one comment, load up the comment template.
			if ( comments_open() || get_comments_number() ) :
				comments_template();
			endif;

		// End the loop.
		endwhile;
		?>

		</main><!-- .site-main -->
	</div><!-- .content-area -->

<?php get_footer(); ?>

新テンプレート用のファイル名の長さには特に制限はないけど、あまり長くてもメリットはないので、vfpage.phpとした。WordPressテーマの決まり事として、最初のコメント行にテンプレート名を必ず書いておく。WordPressはここに書いたテンプレート名を識別して編集画面に反映する仕様になっている。

<?php
/*
Template Name: VANGUARD FLIGHT
*/

get_header(); ?>

	<div id="primary" class="content-area">
		<main id="main" class="site-main" role="main">

		<?php
		// Start the loop.
		while ( have_posts() ) : the_post();

			// Include the page content template.
			get_template_part( 'content', 'vfpage' );

			// If comments are open or we have at least one comment, load up the comment template.
			if ( comments_open() || get_comments_number() ) :
				comments_template();
			endif;

		// End the loop.
		endwhile;
		?>

		</main><!-- .site-main -->
	</div><!-- .content-area -->

<?php get_footer(); ?>

16行目をget_template_part( 'content', 'vfpage' );に書き換え、content-vfpage.phpを呼び出すように変更しておく。表示させたい内容に変更がない場合は書き換えなくても問題はないだろうけど、テンプレートを分岐させておきながら、結局親テーマのテンプレートを再度呼び出すようなプログラミングは後で混乱の元になるため、内容はまったく同じでもcontent-page.phpを複製してcontent-vfpage.php作成しておく。

ここまで作成すると、固定ページ編集画面の「ページ属性」ボックスに追加したテンプレート名が追加される。

wordpress000

テンプレートを切り替えると、WordPressによって生成されたHTMLのbodyタグに「page-template-vfpage」といった、デフォルトとは異なるテンプレートを使用しているということを示すクラスが自動的に追加されるので、子テーマのstyle.cssに必要なスタイルを書き加える。

.page-template-vfpage h1,
.page-template-vfpage h2,
.page-template-vfpage h3,
.page-template-vfpage h4,
.page-template-vfpage h5,
.page-template-vfpage h6 {
	clear: none;
}

.page-template-vfpage table.infobox {
	table-layout: auto;
	float: right;
	width: 360px;
	margin: 0.5em 0 0.5em 1em;
}

Twenty Fifteenのデフォルトではレベルを問わず見出し行が来ると、CSSのfloatプロパティの左寄せ、右寄せが強制的に解除(clear: both;)されるようになっていたので、見出しが来ても右寄せ、左寄せを解除しないように変更した。また、infoboxというクラスを持つtableタグのスタイルを定義した。クラスを限定してあるので投稿フォーマットのブログ記事のスタイルにはまったく影響しない。

もちろん、新テンプレート専用のCSSファイルを別に用意してlinkタグで個別に読み込ませることもできるけど、テンプレート用のクラスをWordPressが追加してくれていることで煩雑な条件判定は既に済んでいると見なせるので、コード記述やファイル管理の手間が増える割にはメリットは少ない。

サイドバーの増設

Twenty Fifteenは片側のみ(デフォルトは左)のサイドバーしか想定していないので、親テーマのfunctions.phpには次に示すコードのように「sidebar-1」という名前のサイドバーがひとつしか登録されていない。有料テーマなど凝ったものでは複数のサイドバーがあらかじめ用意されているものもあるようだけど、WordPressが標準で用意してくれているテーマはいわば白地図のようなもので、各自のカスタマイズが前提みたいなところもあるので、あまり期待はしないほうがいい。

/**
 * Register widget area.
 *
 * @since Twenty Fifteen 1.0
 *
 * @link https://codex.wordpress.org/Function_Reference/register_sidebar
 */
function twentyfifteen_widgets_init() {
	register_sidebar( array(
		'name'          => __( 'Widget Area', 'twentyfifteen' ),
		'id'            => 'sidebar-1',
		'description'   => __( 'Add widgets here to appear in your sidebar.', 'twentyfifteen' ),
		'before_widget' => '<aside id="%1$s" class="widget %2$s">',
		'after_widget'  => '</aside>',
		'before_title'  => '<h2 class="widget-title">',
		'after_title'   => '</h2>',
	) );
}
add_action( 'widgets_init', 'twentyfifteen_widgets_init' );

サイドバーも「sidebar-vfpage.php」のようなテンプレート名を含むファイルを用意すれば、<?php get_sidebar('vfpage'); ?>といったコードでテンプレートによるデザインの切り替えも可能なんだけど、ダッシュボードの「外観」>「ウィジェット」からGUIを利用してウィジェットを編集可能なダイナミック・サイドバーを使えたほうが何かと都合が良い。

追加ダイナミック・サイドバーのために子テーマのfunctions.phpに次のようなコードを追加する。functions.phpがなく、style.cssだけでも子テーマとしては成立するし、特にエラーにもならないけど、ダッシュボードからコードを追加・編集することもできるようになるので、まったくの白紙状態でもいいからお約束としてfunctions.phpファイルは用意しておいたほうがいい。ただし、誤動作の元になるので親テーマのfunctions.phpを無闇に丸ごとコピーしてはいけない。

/* Add Extra Sidebar */
function vf_widgets_init() {
	register_sidebar( array(
		'name'          => __( 'VF用ウィジェット エリア', 'VANGUARD FLIGHT' ),
		'id'            => 'sidebar-2',
		'description'   => __( 'VF用サイドバーに表示されるウィジェットを追加できます。', 'VANGUARD FLIGHT' ),
		'before_widget' => '<aside id="%1$s" class="widget %2$s">',
		'after_widget'  => '</aside>',
		'before_title'  => '<h2 class="widget-title">',
		'after_title'   => '</h2>',
	) );
}
add_action( 'widgets_init', 'vf_widgets_init' );

ダイナミック・サイドバー(ウィジェット・エリア)を追加すると、ウィジェット編集画面に次の画像のように2つのウィジェット・エリアが表示されるようになる。

wordpress001

コンテンツでサイドバーを切り替える

Twenty Fifteenテーマはヘッダーエリアとサイドバーエリアが左側のエリアを共有していて、上下に分け合って表示される仕組みになっているので、サイドバー本体はheader.phpから呼び出されるようになっている。ヘッダーエリアが独立していてタイトルとメインメニューの表示のみに使っているテーマの場合は、記事ループが記述されているテンプレートからフッターの直前にサイドバーを呼び出すようになっているものもある。

親テーマのsidebar.phpは次のコードのようになっている。サイドバーをひとつしか使わないことを前提としたコードなので、ブログの記事を表示していても、固定ページを表示していても同じサイドバーが表示される。

		<?php if ( is_active_sidebar( 'sidebar-1' ) ) : ?>
			<div id="widget-area" class="widget-area" role="complementary">
				<?php dynamic_sidebar( 'sidebar-1' ); ?>
			</div><!-- .widget-area -->
		<?php endif; ?>

そこで、子テーマにsidebar.phpを複製して作成し、特定のテンプレートを使用している場合のみ新しく登録したダイナミック・サイドバーを表示するように条件分岐を書き加える。is_page_template関数は特定のテンプレート・ファイルを経由して表示しようとしているかどうかを判定するため、テンプレート・ファイル名を引数として指定する。

		<?php if ( is_page_template( 'vfpage.php' ) ) :
			if ( is_active_sidebar( 'sidebar-2' ) ) : ?>
				<div id="widget-area" class="widget-area" role="complementary">
					<?php dynamic_sidebar( 'sidebar-2' ); ?>
				</div><!-- .widget-area -->
			<?php endif;
		else :
			if ( is_active_sidebar( 'sidebar-1' ) ) : ?>
				<div id="widget-area" class="widget-area" role="complementary">
					<?php dynamic_sidebar( 'sidebar-1' ); ?>
				</div><!-- .widget-area -->
			<?php endif;
		endif; ?>

なお、PHPは、主にHTMLと混在している箇所で条件分岐内等のブロックコードの始まりと終わりを意味する中括弧{…}は必須ではない、というプログラミング言語としては変わった仕様を持つ。ブロックの開始はコロン(:)で置き換え可能で、終始の記号が一対一で対応している必要も、何かの記号で閉じる必要も特にない。

記事のメタ情報の書式変更

投稿(post)フォーマットのコンテント・フッターには次の画像のようにメタ情報が表示される。ここに、最終更新日の情報を追加したい。

wordpress002
改修前のコンテント・フッター

template-tags.phpに含まれる関数の移設

Twenty Fifteenテーマのコンテント・フッターは厳密にはテンプレートではなく、inc/template-tags.phpというファイルに記述された関数群で実現している。一度読み込まれると上書きを拒否するコードになっているため、他のテンプレート・ファイルと同様の感覚で子テーマにinc/template-tags.phpを追加して編集しても変更が反映されることはない。

まず、親テーマのtemplate-tags.phpの中からtwentyfifteen_entry_metaという関数を探す。

if ( ! function_exists( 'twentyfifteen_entry_meta' ) ) :
/**
 * Prints HTML with meta information for the categories, tags.
 *
 * @since Twenty Fifteen 1.0
 */
function twentyfifteen_entry_meta() {
:
:
(中略)
:
:
	}
}
endif;

template-tags.phpの代わりに、子テーマのfunctions.phpに同名の関数を追加、登録する。親テーマのtemplate-tags.phpよりも先に子テーマのfunctions.phpが実行されるため、こちらが優先される。

上のif ( ! function_exists( 'twentyfifteen_entry_meta' ) ) :endif;というコードで、一度定義された関数は重複して定義しないようになっているので、親テーマの同名の関数で上書きされたり、二重定義でエラーになったりすることはない。

15~37行が投稿日と最終更新日に関するコード。詳しくは説明しないけど、ところどころ出てくるprintf関数やsprintf関数がJavaScript式のHTML挿入方法によく似ていて、HTMLタグでは普通使わない「%1」や「$s」が出てきてプログラム初心者には少し敷居が高そうに見えるかもしれない。関数そのものはC++の祖先のC言語時代からある「初心者がまず最初に覚える関数」のひとつではあるんだけど、本来は英語であるシステム・メッセージの多言語翻訳の都合もあり、WordPressでは使い方がやや高度。

function twentyfifteen_entry_meta() {
	if ( is_sticky() && is_home() && ! is_paged() ) {
		printf( '<span class="sticky-post">%s</span>', __( 'Featured', 'twentyfifteen' ) );
	}

	$format = get_post_format();
	if ( current_theme_supports( 'post-formats', $format ) ) {
		printf( '<span class="entry-format">%1$s<a href="%2$s">%3$s</a></span>',
			sprintf( '<span class="screen-reader-text">%s </span>', _x( 'Format', 'Used before post format.', 'twentyfifteen' ) ),
			esc_url( get_post_format_link( $format ) ),
			get_post_format_string( $format )
		);
	}

	if ( in_array( get_post_type(), array( 'post', 'attachment' ) ) ) {
		$time_string = '<time class="entry-date published updated" datetime="%1$s">%2$s</time>';

		$time_string = sprintf( $time_string,
			esc_attr( get_the_date( 'c' ) ),
			get_the_date(),
			esc_attr( get_the_modified_date( 'c' ) ),
			get_the_modified_date()
		);

		printf( '<span class="posted-on"><span class="screen-reader-text">%1$s </span><a href="%2$s" rel="bookmark">%3$s</a></span>',
			_x( 'Posted on', 'Used before publish date.', 'twentyfifteen' ),
			esc_url( get_permalink() ),
			$time_string
		);

		if ( get_the_time( 'U' ) !== get_the_modified_time( 'U' ) ) {
			printf( '<span class="updated-on"><time class="updated" datetime="%1$s">%2$s</time></span>',
				esc_attr( get_the_modified_date( 'c' ) ),
				get_the_modified_date()
			);
		}
	}

	if ( 'post' == get_post_type() ) {
		if ( is_singular() || is_multi_author() ) {
			printf( '<span class="byline"><span class="author vcard"><span class="screen-reader-text">%1$s </span><a class="url fn n" href="%2$s">%3$s</a></span></span>',
				_x( 'Author', 'Used before post author name.', 'twentyfifteen' ),
				esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ),
				get_the_author()
			);
		}

		$categories_list = get_the_category_list( _x( ', ', 'Used between list items, there is a space after the comma.', 'twentyfifteen' ) );
		if ( $categories_list && twentyfifteen_categorized_blog() ) {
			printf( '<span class="cat-links"><span class="screen-reader-text">%1$s </span>%2$s</span>',
				_x( 'Categories', 'Used before category names.', 'twentyfifteen' ),
				$categories_list
			);
		}

		$tags_list = get_the_tag_list( '', _x( ', ', 'Used between list items, there is a space after the comma.', 'twentyfifteen' ) );
		if ( $tags_list ) {
			printf( '<span class="tags-links"><span class="screen-reader-text">%1$s </span>%2$s</span>',
				_x( 'Tags', 'Used before tag names.', 'twentyfifteen' ),
				$tags_list
			);
		}
	}

	if ( is_attachment() && wp_attachment_is_image() ) {
		// Retrieve attachment metadata.
		$metadata = wp_get_attachment_metadata();

		printf( '<span class="full-size-link"><span class="screen-reader-text">%1$s </span><a href="%2$s">%3$s &times; %4$s</a></span>',
			_x( 'Full size', 'Used before full size attachment link.', 'twentyfifteen' ),
			esc_url( wp_get_attachment_url() ),
			$metadata['width'],
			$metadata['height']
		);
	}

	if ( ! is_single() && ! post_password_required() && ( comments_open() || get_comments_number() ) ) {
		echo '<span class="comments-link">';
		/* translators: %s: post title */
		comments_popup_link( sprintf( __( 'Leave a comment<span class="screen-reader-text"> on %s</span>', 'twentyfifteen' ), get_the_title() ) );
		echo '</span>';
	}
}

Genericonsの新規使用指定

Twenty FifteenはGenericonsを使用している。せっかくなので見栄えも揃えたい。上で改変したtwentyfifteen_entry_meta関数では更新日の表示にupdated-onクラスを新たに使用することにしているので、当該クラスをstyle.cssのGenericonsを使用するクラスに追加する。

.social-navigation a:before,
.secondary-toggle:before,
.dropdown-toggle:after,
.bypostauthor > article .fn:after,
.comment-reply-title small a:before,
.comment-navigation .nav-next a:after,
.comment-navigation .nav-previous a:before,
.posted-on:before,
.updated-on:before,
.byline:before,
.cat-links:before,
.tags-links:before,
.jetpack_views:before,
.comments-link:before,
.entry-format:before,
.edit-link:before,
.full-size-link:before,
.pagination .prev:before,
.pagination .next:before,
.image-navigation a:before,
.image-navigation a:after,
.format-link .entry-title a:after,
.entry-content .more-link:after,
.entry-summary .more-link:after,
.author-link:after {
	-moz-osx-font-smoothing: grayscale;
	-webkit-font-smoothing: antialiased;
	display: inline-block;
	font-family: "Genericons";
	font-size: 16px;
	font-style: normal;
	font-weight: normal;
	font-variant: normal;
	line-height: 1;
	speak: none;
	text-align: center;
	text-decoration: inherit;
	text-transform: none;
	vertical-align: top;
}

使いたいアイコンをウェブサイトのサンプルから選び、アイコン・コードをstyle.cssのGenericonsの各クラス定義部分に追加する。

.format-aside .entry-format:before {
	content: "\f101";
}

.format-image .entry-format:before {
	content: "\f473";
}

.format-gallery .entry-format:before {
	content: "\f103";
}

.format-video .entry-format:before {
	content: "\f104";
}

.format-status .entry-format:before {
	content: "\f105";
}

.format-quote .entry-format:before {
	content: "\f106";
}

.format-link .entry-format:before {
	content: "\f107";
}

.format-chat .entry-format:before {
	content: "\f108";
}

.format-audio .entry-format:before {
	content: "\f109";
}

.posted-on:before {
	content: "\f307";
}

.updated-on:before {
	content: '\f420';
}

.byline:before {
	content: "\f304";
}

.cat-links:before {
	content: "\f301";
}

.tags-links:before {
	content: "\f302";
}

.comments-link:before {
	content: "\f300";
}

.full-size-link:before {
	content: "\f402";
}

.edit-link:before {
	content: "\f411";
}

改修が終わったコンテント・フッター。矢印が円形につながっている更新マーク(正確にはリフレッシュ・アイコン)の後に最終更新日が表示されている。

wordpress003
改修後のコンテント・フッター

参考記事

MediaWikiでショートURLを使う

最終更新:2016/09/06

MediaWikiを運用するようになってからかなり経つけど、記事のURLは初期設定のままで、

http://vanguardflight.xii.jp/w/index.php?title=Page_title

といったように表示されていた。編集するユーザーも管理者も一人しかいない無名のマイナーウィキだから、それでも別に困ってなくて先延ばしになってたんだけど、どうせならウィキペディア日本語版のようなショートURLにしたい。

例によって、MediaWiki公式サイトの説明はわかりにくい。大抵のWebサーバーで使われているApacheを実装していて、mod_rewriteというモジュールを利用可能であれば、MediaWikiが動いているほとんどすべてのサーバーでショートURLを利用できると書いてある。

一方で、rootの権限がどうのこうのと書いてあるので、ローカルホストにアクセスする権限がないと無理なのかと思って真面目に調べてなかった。ところが、よく読むとリモートサーバーでも利用可能と書いてあるし、更には、「そのくらいのことができないようなリモートサーバーにお金を払う価値はない」とまで書いてあってかなり強気。

さくらインターネット公式サポートサイトによると、Apacheを実装しているし、mod_rewriteも利用可能と書いてある。mod_rewriteそのものの設定を変更するにはサーバー管理者の権限がないといけないんだけど、共有サーバーを使っているユーザー側でも.htaccessで設定できる。

.htaccess

.htaccessを配置すべき場所は、MediaWikiのディレクトリが存在しているディレクトリ。つまり、home/[user-name]/www/wというディレクトリにMediaWikiをインストールしているとしたら、home/[user-name]/wwwに.htaccessを置けばいい。

.htaccessに記述すべき内容はわずか2行。

RewriteEngine On
RewriteRule ^/?wiki(/.*)?$ %{DOCUMENT_ROOT}/w/index.php [L]

1行目のRewriteEngine Onは、mod_rewriteを有効にする設定。

2行目は、URLをどのようにリライトするかというルール。正規表現で記述されているのでちょっとわかりにくい。簡単に言うと、http://example.domain.com/wiki/Page_titleというURLを受け取ったら、それを内部的にはhttp://example.domain.com/w/index.php?title=Page_titleに置き換えながら、ブラウザのアドレスバーにはhttp://example.domain.com/wiki/Page_titleが表示され続けるということ。

最後の[L]は「ここで.htaccessは終わり」という意味。

LocalSettings.php

$wgScriptPath = "/w";
$wgArticlePath = "/wiki/$1";
$wgScriptExtension = ".php";

初期設定では$wgScriptPath$wgScriptExtensionしかないんだけど、その間に$wgArticlePathという環境変数を追加する。

補足

なお、独自ドメインを使用している場合でもショートURLを利用できる。独自ドメインが/wwwディレクトリの更に下の階層に設定してあって、例えばhome/[user-name]/www/directory/wにMediaWikiをインストールしてあっても問題ない。

また、独自ドメインの直下(上の例で言うと、home/[user-name]/www/directory)にindex.htmlindex.phpで始まるような普通のウェブサイトを配置していて、そこに上記の.htaccessを設置してもそのウェブサイトは何の問題もなく表示される。同様に、独自ドメインに/wpといったディレクトリを作って本記事のブログのようなWordPressを設置してMediaWikiと並列で運用していても問題ない。

唯一ダメなのは、/wikiというディレクトリが実際に存在している場合。MediaWiki公式サイトのインストール・ガイドにも「wikiというディレクトリ名だけはやめたほうがいい」と書いてある。もし、そこにMediaWikiをインストールしてしまった場合でショートURLを使いたい場合は別のディレクトリに移動させないとならない。

参考記事

MediaWikiのキャッシュを有効にする

最終更新:2016/09/06

MediaWikiをインストールしてから結構経ったけど、キャッシュを有効にしてなかったことに今更気がついた。ページひとつ更新するにも結構待つし、ファイルをまとめて10個くらいアップロードするとなるとかなりの時間になる。

そこで、多少なりともレスポンスが速くなればいいなぁ、と思い、サーバー側のキャッシュを有効にしてみることにした。MediaWiki公式サイトの説明をざっくり読んでみてからネットを検索したらいくつか記事が見つかった。

具体的には、LocalSettings.phpの次の設定を追加又は変更する。

$wgMainCacheType = CACHE_ANYTHING; /* default: CACHE_NONE; */
$wgUseFileCache = true;
$wgCacheDirectory = "$IP/cache";
$wgShowIPinHeader = false;
$wgEnableSidebarCache = true;

この記事を書いている時点で最新バージョンのMediaWiki 1.24.2では、$wgUseFileCacheを true にすると、$wgShowIPinHeaderは自動的に false になるので設定する必要はないんだけど、念のため。

$wgCacheDirectoryは特別な理由がない限り、"$IP/cache"でいいと思う。英語用のキャッシュが約620KB、日本語用のキャッシュが約708KBくらい生成されてたけど、思ったよりは大きくはなかった。しばらく運用してみてどのくらいになるのか観察することにする。

試しに、いくつかファイルをアップロードしてみたけど、目に見えてレスポンスが良くなった。日本語版ウィキペディアの記事を更新するくらいのレスポンスにはなったように思う。ベンチマークで厳密に計って比較したわけではないけど、体感的に速くなったと感じられれば目的は達成。こんなことなら、もっと早くキャッシュを有効にしておくべきだった。

参考記事

MediaWikiにExtension:Scribuntoをインストール

最終更新:2016/09/06

さくらインターネットのレンタルサーバでMediaWikiを動作させている前提で、Extension:Scribuntoをインストールする。Scribuntoは、Luaという言語で書かれたスクリプトを実行する環境をMediaWikiに追加設定する拡張機能。シンプルに使う分にはなくても特に困らないけど、Wikipedia英語版やWikimedia Commonsからテンプレートをインポートしたい場合はかなりの確率で必要になる。

Lua 5.1.4

Extension:Scribuntoは単体では動作しないので、Luaというプログラミング言語を解釈するインタープリターが必要になる。さくらインターネットではサーバのOSにFreeBSDを使用していて、SourceForgeで提供されているWindows用やMac用のLuaバイナリではうまく動作しない。Extension:Scribuntoのアーカイブに /extensions/Scribunto/engines/LuaStandalone/binaries という思わせぶりなフォルダが事前に用意されているけど基本的に役に立たない。そこで、Lua Download areaから lua-5.1.4.tar.gz のソースコードをダウンロードし、解凍後、makeして直接サーバにインストールする。

2016年3月7日現在、Luaの最新バージョンは5.3.2になっているが、Lua 5.2.xやLua 5.3.xを使用すると「ステータス1」を返してインタープリターがエラーを起こすことがある模様。なお、Lua 5.1.xではLua 5.1.5が最終バージョン。

具体的には、SSHにログインを参考にSSHシェルにログインし、コマンドラインから次の手順で行う。あからじめ/local/src/というディレクトリをサーバに作っておく(これだけはFTPクライアントでもできる)。

cd ~/local/src/
wget http://www.lua.org/ftp/lua-5.1.4.tar.gz
tar -zxvf lua-5.*
cd lua-5.1.4
make freebsd
make local
cd bin
ln -s lua lua-5.1.4

Extension:Scribuntoの実装

Extension:Scribuntoのスナップショット(現時点で安定動作する最新版)をMediaWiki公式サイトからダウンロードし、適当なフォルダに解凍する。/extensionディレクトリに/Scribuntoディレクトリを作成し、そこへFTPクライアントでアップロードする。

LocalSettings.phpに次の6行を追加する。Luaインタープリターはユーザーが指定できるもっともルートに近いところから順にパスを指定しなければならないので注意(他の環境変数のように$IP/~では始められないということ)。

require_once "$IP/extensions/Scribunto/Scribunto.php";
$wgScribuntoDefaultEngine = 'luastandalone';
$wgScribuntoEngineConf['luastandalone']['luaPath'] = '/home/[user-name]/local/src/lua-5.1.4/bin/lua-5.1.4';
$wgScribuntoEngineConf['luastandalone']['errorFile'] = '/home/[user-name]/www/[wiki-directory]/extensions/Scribunto/errorfile.log';
$wgScribuntoUseGeSHi = true;
$wgScribuntoUseCodeEditor = true;

メインページを再読み込みすると、「モジュール」、「モジュール・トーク」という名前空間が追加され、Luaで書かれたスクリプトを実行できるようになる。

なお、4行目はLuaインタープリターのエラーログの設定で、正常に動作するようになったらコメントアウトするなどして無効にしてもOK。5行目は、各種言語の文法(マークアップ)をハイライトするExtension:SyntaxHighlight_GeSHiを、6行目は、CSSやJavaScriptの編集を補助するExtension:CodeEditorをそれぞれLua言語で書かれたスクリプトモジュールでも有効にする設定。

もし、スクリプトを保存しようとした時に、

Script error: Lua error: Internal error: The interpreter exited with status 127
Script error: Lua error: Internal error: The interpreter exited with status 126

といったエラーメッセージが出る場合は、インタープリターのmakeに失敗しているか、パスが間違っている可能性がある。上の手順でインタープリターをmakeした場合は自動的に実行可能なパーミッションが与えられているので特に問題にならないけど、手順が間違っていないのにうまくいかない場合はインタープリターのバイナリファイルのパーミッションが「755」など全ユーザーが実行可能になっていることを確認する。

インタープリターが正常に動作しているかどうかテストするには、Wikipedia英語版にあるModule:Bananasという極シンプルなスクリプトを自分のWikiにコピーして同名で保存してみる。保存時に文法エラーがないかチェックされるので、正常に動作していれば、何事もなく保存できる。

{{int:Lang}}の問題を解決

メディアウィキ・コモンズからテンプレートを移入しようとすると、必ずと言っていいほど言語間の翻訳の問題が出てくる。メディアウィキ・コモンズは、各言語ごとに英語の原文を翻訳した膨大なシステム・メッセージを持っており、閲覧者の環境(またはプリファレンス・個人設定)に合わせて置き換えたうえで出力してくれる。ところが、そういった言語自動切換え機能を備えたテンプレートをそのまま実行(トランスクルード)しようとするとModule:FallbackModule:Languagesといったモジュールでスクリプト・エラーが出る。これは、{{int:Lang}}というマークアップを使ってMediaWikiに標準で実装されていないシステム・メッセージを呼び出そうとしているから。MediaWikiは、Langというキーワードに結び付けられたシステム・メッセージを見つけられない場合は<Lang>という文字列を返してくる(詳しくはHelp:マジックワード参照)。これでは、ISO 639で定められた2文字の言語記号には当たらないのでエラーになって当然ということになる。

これを解消するには、自分のウィキにMediaWiki:Langというファイルを作り(作り方は標準記事名前空間と同じなので特に説明はしない)、「ja」(日本語)や「en」(英語)などとシンプルにISO 639で定められた2文字の言語記号を書いて保存する。

システム・メッセージの反映には少し時間がかかるので、すぐに確認したい場合は、エラーが出たテンプレートを編集モードで開いて何も変更せずにプレビュー機能を使い、スクリプト・エラーが出ないことを確認する(関係するテンプレートやモジュールを全部展開して解釈するので数十秒かかる)。遅くとも、一晩経てばシステム・メッセージは全体に反映されるようになっている。

モジュール名前空間の接頭辞変更

モジュール名前空間はデフォルトでは「モジュール」、「モジュール・トーク」となっている。私はUTF-8でのURLがわかりにくいという理由ですべての名前空間を英語に戻してしまったので、同様に英語に統一したい。そこで、/extension/Scribuntoディレクトリの直下にあるPHPファイルScribunto.namespaces.phpを次のように変更する。例は、日本語のWikiを対象とする場合。

なお、しつこいようだけど、UTF-8を編集できるエディタでないとファイルが破損するので、必ずUTF-8が編集できるエディタを使用する。

$namespaceNames['ja'] = array(
	828 => 'Module',
	829 => 'Module_talk',
);

参考記事

MediaWikiのインストール手順

最終更新:2016/09/06

現在、このWordPressのブログも含めて、さくらのレンタルサーバを使っているけど、せっかく最大容量が増えて30GBから100GBになったのに、1GBにも満たないほどしか使っていない。月額500円とは言っても少々もったいない気もする。

WordPressには数えきれないほどのプラグインやテーマがあってカスタマイズに自由度があるのが長所。ブログやCMSとしては十分なんだけど、HTMLの文法に制限されるためリンクや段落わけが気軽にできず、ひとつの題材を持った作品やデータベースを少しずつ育てていくという使い方にはあまり向いていないような気がする(あくまでも個人的な感想)。ついつい備忘録的なブログ記事を書いてしまっているのが現状。

そこで、少々敷居は高いけど、ウィキ文法が確立していて記事を編集しやすいウィキペディアで使用されているMediaWikiを導入してみることにした。MicrosoftのWebMatrix3を使用してローカルホストで実験してみた限りではそれほど難しくはなさそうだった。もちろん、ここにわざわざ備忘録を残すくらいなので、設定を半自動的にやってくれるWebMatrix3とは異なり、いくつかハードルにぶかったことは言うまでもない。

インストール要件

MediaWikiは、WordPressと同様に、ホスト側にPHPとSQLデータベースが動作する環境がなければならない。MediaWiki 1.20からPHP 5.3.2以上が必要となったため、WordPressの要件に合わせてPHP 5.2.17を使っている場合は注意が必要。さくらのサーバコントロールパネルの「PHPのバージョン選択」で簡単に変更できる。今回は、PHP 5.4.26に変更した。なお、同じサーバに同居しているWordPressには影響なかった。

データベース作成

いつも使っているウェブブラウザでさくらのサーバコントロールパネルにログインし、「データベースの設定」からデータベースを新規作成する。

既にデータベースを使用している場合は、データベース名を入力して文字コードを選択するだけで設定は終わる。まだデータベースをひとつも作っていない場合は、データベースユーザー名(普通は初期アカウント名)とデータベース接続パスワードを設定する。サーバコントロールパネルにログインするパスワードとは独立しているので、忘れないように記録しておく。文字コードは必ず「UTF-8」を選択する。MediaWikiの初期設定時に使うため、ホスト名も記録しておく。

MediaWikiソフトウェアのアップロード

MediaWikiの公式サイトからmediawiki-1.22.4.tar.gz(2014年3月26日現在)をダウンロードし、ローカルPCの適当なフォルダに解凍する。一般に普及しているFTPクライアント・ソフトウェアで/home/[user-name]/www/以下に作ったMediaWiki用のディレクトリにアップロードする。ディレクトリ名はなんでもいいけど、初期設定が済んでしまうと容易に変更できなくなるので、後で変更するつもりなら今のうちに。ここでは、ディレクトリ名を仮に[wiki-directory]とする。

ちなみに、ついつい使ってしまいそうな/wikiという名前のディレクトリはショートURLのために予約されているので、ショートURLを使うつもりであれば、使ってはいけない。なお、さくらのレンタルサーバーではショートURLを利用できる。詳しくは、MediaWikiでショートURLを使うを参照。

ここで一点だけ注意。それは、FTPクライアントの「アップロード時にファイル名をすべて小文字(大文字)にする」という設定をオフにするということ。MediaWikiのファイルには大文字・小文字を併用しているものがかなりある。MediaWikiの公式サイトのインストールガイドにも太字で Make sure the “Change file names to lowercase” option for upload is disabled. と書いてあるんだけど、リネームするのが面倒で普段は自分のWEBページを更新する時には小文字にしてアップロードするのが当たり前になっていたため、すっかり忘れていた。そのために初期設定からいきなり動かず、2700個くらいあるファイルのアップロードをやり直す羽目に。気をつけましょう。

MediaWikiの初期設定

ブラウザからhttp://[domain]/[wiki-directory]/index.phpにアクセス。インストール要件を満たしているかチェックされ、主にPHPのバージョンが要件に達していない場合は設定を見直して再度アクセスするように促される。要件を満たしていれば、次の図のように「set up the wiki」と表示されるので、それをクリックし、あとは画面の指示に従って入力する。あくまでも例示なので、設定の細部はお好みで。
MediaWiki-1.22.4

言語

あなたの言語 日本語
ウィキの言語 日本語
MediaWikiのインターフェースに使用する言語。

データベースに接続

データベースの種類 MySQL
データベースのホスト 記録しておいたデータベースのホスト名。
データベース名 記録しておいたデータベース名。
データベーステーブルの接頭辞 他のデータベースと識別するためのプリフィックス。MediaWiki専用にデータベースを作った場合は未入力でもいいけど、後で変更するのは手間なので、できればそういうものだと思って入力しておいたほうが無難。後でわかったことだけど、さくらのレンタルサーバーでは独立したデータベースを複数作ることができるので、プリフィックスを入力しなくてもまったく問題ない。
データベースのユーザー名 記録しておいたデータベースユーザー名。
データベースのパスワード 記録しておいたデータベースパスワード。

データベースの設定

ウェブアクセスのためのデータベースアカウント チェックボックスにチェック☑しておく。
ストレージエンジン InnoDB
データベースの文字セット バイナリ
データベースの文字セットをUTF-8にしたのだからUTF-8なのかと思ったら説明書きを読むとバイナリのほうが良さそう。

名前

ウィキ名 これから作成するWikiの名前($wgSitename)。
プロジェクト名前空間 標準記事名前空間と区別してプロジェクト上のメタな事柄を書くための名前空間の接頭辞($wgMetaNamespace)。ウィキペディアなら「Wikipedia:~」がそれにあたる。例えば、Wikipedia:著作権はウィキペディア上での著作権の取り扱いなどを書き、標準名前空間の著作権は「著作権とは何か」を書くための記事。
管理アカウント名前 Wikiにログインして管理するためのアカウント名。最初のユーザーでもある。
パスワード 上記アカウントのパスワード。

以上で、基本的な設定は終了。「私にもっと質問してください。」をチェックして続行すると、引き続き閲覧や編集が可能なユーザーグループを設定したり、著作権などの詳細な設定ができる(機会があれば追加する)。

初期設定が完了すると、LocalSettings.phpというPHPファイルのダウンロードが自動的に始まるので、一回ローカルPCに保存して、[wiki-directory]の直下にアップロードする。

LocalSettings.phpは、DefaultSettings.php(これは変更禁止)を元に、これまで設定した基本データを反映した設定ファイル。暗号化されていないパスワードなどがそのまま書かれているので、他のユーザーに見られてしまうと困る。FTPクライアントの属性変更コマンド(chmodコマンド)で必ず属性(パーミッション)を「700」か「600」に設定して不特定多数が閲覧できないようにしておく。

ちなみに、LocalSettings.phpはいつでも変更できるため、初期設定を変更したくなった場合はUTF-8を編集できるエディタで変更して再アップロードしてブラウザをリロードすると反映される(とは言ってもデータベース関連はいじらないほうが無難だし、いじる必要はそうそう発生しない)。

起動

LocalSettings.php[wiki-directory]に存在している状態で、再び http://[domain]/[wiki-directory]/index.phpにアクセスすると普通ならばおなじみのMediaWikiのメインページが表示されるわけだけど、私はこんなエラーメッセージに阻まれた。

Fatal exception of type MWException Error

どうやら、拡張機能で適当に追加したLocalisationUpdate.phpというファイルが悪さをしているらしい(MediaWiki:当該トラブルシュートスレッド)。そこで、何をするファイルなのかはよくわからないので、ひとまず次のようにコメントアウトして、ようやく起動した。

# Enabled Extensions. Most extensions are enabled by including the base extension file here
# but check specific extension documentation for more details
# The following extensions were automatically enabled:
require_once "$IP/extensions/Cite/Cite.php";
require_once "$IP/extensions/Gadgets/Gadgets.php";
# require_once "$IP/extensions/LocalisationUpdate/LocalisationUpdate.php";
require_once "$IP/extensions/Nuke/Nuke.php";
require_once "$IP/extensions/ParserFunctions/ParserFunctions.php";
require_once "$IP/extensions/Renameuser/Renameuser.php";
require_once "$IP/extensions/SyntaxHighlight_GeSHi/SyntaxHighlight_GeSHi.php";
require_once "$IP/extensions/WikiEditor/WikiEditor.php";

サイドバー

MediaWikiには主要なリンクやツールをまとめたサイドバーというものがある。WordPressのウィジェットとは比べるべくもない簡素な見た目のツール群だけど、これが一定の規則に基づいたキーワードを元にJavaScriptで自動的に生成されているらしく、/[wiki-directory]/skins/common/に格納されているすべてのスキンの根本のCSSであるcommonElements.cssを変更してもリンクの色が変わらない。生成されたソースを見てもよくわからない。

とても人力で解析できそうには思えなかったので、FireFoxの要素解析ツールを使って構造を調べてみた。<a>タグのエレメントに直に割り当ててあったリンク色も上書きしていて複雑なIDとクラスの構造になっていた。その結果を反映したものが次のCSS。これをMediaWikiのサイト上からMediaWiki:Common.cssに反映する。色はお好みで。

div#mw-panel
div.portal
div.body ul li a { color: #003BC8; }

div#mw-panel
div.portal
div.body ul li a:visited { color: #003BC8; }

名前空間

現在、日本語版の名前空間接頭辞はカタカナや漢字に訳されている。一般的にはこのほうがわかりやすいんだろうし、多言語に対応するために英語版の接頭辞も使えるようになっているけど、UTF-8のマルチバイト文字をURLにするとどこの名前空間なのかわかりにくいので私はあまり好きではない。そこで、システムメッセージは日本語のまま($wgLanguageCode = "ja";)にしておいて、名前空間の接頭辞だけを英語版仕様に戻すというワガママ仕様にすることにした。

具体的には、/[wiki-directory]/languages/messages/MessagesJa.phpというファイルを変更し、同じディレクトリにあるMessagesEn.phpから$namespaceNamesをコピーして移入する(システムに直接影響するので、下手に手動入力しないほうが無難)。日本語化されていた接頭辞も念のためエイリアス(別名)として残しておいた。

$namespaceNames = array(
	NS_MEDIA            => 'Media',
	NS_SPECIAL          => 'Special',
	NS_MAIN             => '',
	NS_TALK             => 'Talk',
	NS_USER             => 'User',
	NS_USER_TALK        => 'User_talk',
	# NS_PROJECT set by $wgMetaNamespace
	NS_PROJECT_TALK     => '$1_talk',
	NS_FILE             => 'File',
	NS_FILE_TALK        => 'File_talk',
	NS_MEDIAWIKI        => 'MediaWiki',
	NS_MEDIAWIKI_TALK   => 'MediaWiki_talk',
	NS_TEMPLATE         => 'Template',
	NS_TEMPLATE_TALK    => 'Template_talk',
	NS_HELP             => 'Help',
	NS_HELP_TALK        => 'Help_talk',
	NS_CATEGORY         => 'Category',
	NS_CATEGORY_TALK    => 'Category_talk',
);

$namespaceAliases = array(
	'ノート'               => NS_TALK,
	'利用者‐会話'         => NS_USER_TALK,
	'$1‐ノート'           => NS_PROJECT_TALK,
	'画像'                 => NS_FILE,
	'画像‐ノート'         => NS_FILE_TALK,
	'ファイル‐ノート'     => NS_FILE_TALK,
	'MediaWiki‐ノート'    => NS_MEDIAWIKI_TALK,
	'Template‐ノート'     => NS_TEMPLATE_TALK,
	'Help‐ノート'         => NS_HELP_TALK,
	'Category‐ノート'     => NS_CATEGORY_TALK,
	'メディア'             => NS_MEDIA,
	'特別'                 => NS_SPECIAL,
	'トーク'               => NS_TALK,
	'利用者'               => NS_USER,
	'利用者・トーク'       => NS_USER_TALK,
	'$1・トーク'           => NS_PROJECT_TALK,
	'ファイル'             => NS_FILE,
	'ファイル・トーク'     => NS_FILE_TALK,
	'MediaWiki'            => NS_MEDIAWIKI,
	'MediaWiki・トーク'    => NS_MEDIAWIKI_TALK,
	'テンプレート'         => NS_TEMPLATE,
	'テンプレート・トーク' => NS_TEMPLATE_TALK,
	'ヘルプ'               => NS_HELP,
	'ヘルプ・トーク'       => NS_HELP_TALK,
	'カテゴリ'             => NS_CATEGORY,
	'カテゴリ・トーク'     => NS_CATEGORY_TALK
);

参考記事