headのタイトルにページ番号とカテゴリー名を追加する

2014年1月22日にA8.netのファンブログはSeesaa Blogのシステムをベースにして生まれ変わりました。よってファンブログ関連の記事は今では当てはまらない可能性があります。新しいファンブログのカスタマイズは別ブログ「ファンブログ テック」で詳しく書いていますので、そちらをご覧ください。

先日の記事「ブログ移転で rel=”canonical” は有効か?」で、このブログではヘッダのタイトルに「ページ番号」や「カテゴリー名」を追加していると書きました。よく考えたら、その方法を知りたい方がいるかもしれないと思いますので、この記事にまとめます。

先日の記事に書いた通り、このスクリプトを適用したら、ほんの数日でGoogleの検索結果に反映されるようになりました。この記事は、このブログを書いているファンブログを例にしていますが、他のブログでも充分応用が効く内容だと思います。

現在、このブログのスキンは下の構成になっています。(2013年3月16日時点)

このスキンは独自仕様なので、ファンブログの物とは違います

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="Shift_JIS" />
<meta name="description" content="{$BlogDescription$}" />
<meta name="keywords" content="HTML,css,JavaScript,スタイルシート" />
<meta name="author" content="Tom" />
<meta name="copyright" content="Copyright {$BlogName$}" />
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<link rel="start" href="{$BlogUrl$}" title="{$BlogName$}" />
<link rel="stylesheet" type="text/css" href="{$BlogUrl$}style.css" charset="Shift_JIS" media="all" />
<link rel="alternate" type="application/rss+xml" title="RSS" href="{$BlogUrl$}index1_0.rdf" />
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico" />
<title>{$BlogEntryTitle$} | {$BlogName$}</title>
<!--[if lte IE 8]>
<link rel="stylesheet" type="text/css" href="" media="all" />
<script type="text/javascript" src=""></script>
<![endif]-->
<script type="text/javascript" src=""></script>
</head>
<body>
(省略)
</body>
</html>

この中のtitleタグの中身{$BlogEntryTitle$} | {$BlogName$}です。

{$BlogEntryTitle$}は、記事のタイトルに、
{$BlogName$}ブログのタイトルに自動で変換されて表示されます。

ファンブログのスキンの初期状態

ただし、ファンブログのスキンの初期設定は
{$BlogName$} だけが書き込まれていて、{$BlogEntryTitle$}はありません。このままだと「ブログ名」だけが表示され、「記事のタイトル」は表示されません。これは検索結果にも同じように反映されます。

たとえば次のキーワードで検索してみます。

キーワード

その結果、今現在このブログの記事が1位に表示されています(2013年3月17日時点)。下のどちらかが実際の表示結果、もう片方は画像を加工した物ですが、この2つを比べてみてクリックされやすいと思うタイトルはどちらでしょう?

実際の検索結果表示画面
ブログタイトルのみの場合

左が実際の表示。右がファンブログのスキンのままだと表示される状態を再現したものです。検索した人の入力した2つのキーワード。これがタイトルに含まれる方がクリックされやすいと思います。ブログ名だけで、キーワードのない右は、せっかく1位にあってもそのままスルーされそうな気はしませんか?

ファンブログのスキンに「記事のタイトル」を追加する方法

ボタン

まず、ファンブログの管理画面左の「スタイルの編集」をクリック。
画面が変わったら「フリースキンの編集」と言う項目から「1記事」を選択。
「フリースキンの編集」は画面左にあり、次の一覧になっています。

  • スタイルシート
  • メイン
  • ポータル
  • アーカイブ
  • 1記事
  • プロフィール

この中の「1記事」をクリックします。「1記事」の画面になったら画面右のタイトルが「1記事テンプレートの編集」になります。この右側の枠の中を編集します。

1記事テンプレートの編集で一番上から見ていくと、途中で下のように書かれた行があります。

<title>{$BlogName$}</title>

これを、次のように変更します。

<title>{$BlogEntryTitle$} | {$BlogName$}</title>

これで保存すれば、「記事のタイトル | ブログの名前」という風に表示されます。

タイトルに「ページ番号」を追加するスクリプト

ようやくここからが、今回の本題です。今回やるのは「ページ番号」の追加と、「カテゴリー名」の追加です。「ページ番号」を追加するスクリプトは「メイン」スキンに書き加えます。まず、上の要領で「フリースキンの編集」から「メイン」を選択して開きます。ちなみに、このブログのメインスキンはtitleタグを下のように書き直してあります。

<title>{$BlogName$} | ブログ インデックス</title>

メインスキンのheadに、次のコードを書き加えます。ソースの中の「ayzfqir5」はこのブログの場合です。各自、自分のブログのURLに変更してください。

自分のブログのURLから、赤字の部分を抜き出して、下のコードの「ayzfqir5」を書きかえます。
http://fanblogs.jp/ayzfqir5/
<script type="text/javascript"><!--
url=window.location.href.match(/^https?:\/\/fanblogs\.jp\/ayzfqir5(\/(([0-9]+)\/?)?)?$/);

if(url){
	var number=url[3]?url[3]:1;

	if(document.title){
		document.title+=' page'+number;
	}else{
		document.querySelector('title').innerHTML+=' page'+number;
	}
}
//-->
</script>

“headのタイトルにページ番号とカテゴリー名を追加する” の続きを読む

HTMLを指定文字数で切り詰めて表示する

前の記事「記事の先頭にアイコンを挿入する方法」の最後で、記事の文字数を切り詰める方法を簡単に書きました。この記事では、その部分だけ詳しく説明します。

普通に、文章を指定文字数で切り詰めるなら次のようにすれば実現できます。

function hoge(str,len){
	return str.length>len?str.slice(0,len)+'…':str;
}

第1引数strには文字列、第2引数lenに切り詰めたい長さを指定します。lenより長ければ、len文字で切り詰め、その後に「…」を加えます。ただしマルチバイト文字列の場合、どの文章も同じ文字数で切られない可能性があります。その場合は文字数ではなく、バイト数で切られていると思います。

文章と、文字数を入れて実行ボタンを押してください。

文章:

文字数:

HTMLの文章切り詰め

HTMLの場合はタグを消去しないと表示が崩れる可能性があります。文字列を切り詰めた結果、終了タグがなくなってしまったり、タグの途中で切れてしまったりするからです。

<p>こんにちは。</p>
  -> <p>こんに… &nbsp終了タグがなくなってしまった!

<p>こんにちは。<span style=”color:#0000ff;”>今日はいい天気ですね!</span></p>
  -> <p>こんにちは。<span style=”col…  タグの途中で切れてしまった!

そこで、文字を切り詰める前にHTMLタグを正規表現で消去します。

str.replace(/\<script.*?\>.*?(\<\/script\>)|\<style.*?\>.*?(\<\/style\>)|\<.+?\>/g,'');

<と>のエスケープは正規表現自体には必要ないかもしれませんが、JavaScriptをHTML内に書いた場合にトラブらないようにエスケープしておきました。たとえば、よくdocument.write(‘<scr’+’ipt’というような記述をしますが、これはdocument.write(‘\<script’でも大丈夫です。

HTMLに対応した修正版

function hoge(str,len){
	str=str.replace(/\<script.*?\>.*?(\<\/script\>)|\<style.*?\>.*?(\<\/style\>)|\<.+?\>/g,'');
	return str.length>len?str.slice(0,len)+'…':str;
}

記事の先頭にアイコンを挿入する方法

2014年1月22日にA8.netのファンブログはSeesaa Blogのシステムをベースにして生まれ変わりました。よってファンブログ関連の記事は今では当てはまらない可能性があります。新しいファンブログのカスタマイズは別ブログ「ファンブログ テック」で詳しく書いていますので、そちらをご覧ください。

このブログでは、下のキャプチャのように記事のカテゴリーごとに違うアイコンを表示しています。その実現方法です。このブログはファンブログというサービスに書いているので、ファンブログを例にとりますが、他のブログでも応用できます。

記事ごとにアイコンを配置したindexページ

アイコンを入手する

先に結論を書くと、このブログで使っているアイコンはFree Icon set – Icon Edenからダウンロードした無料アイコンセット「iCandies」です。

インターネットを探すと、無料で使えるアイコンは沢山見つかります。今回、自分はGIGAZINEの記事「フリーでハイクオリティな「IconEden」による商用利用可能な無料アイコンセットいろいろ」で、このアイコンを見つけました。GIGAZINEを見ると関連記事で、まだまだたくさん色々なアイコンを紹介してくれています。

他にもPhotoshop VIPの「RESOURCE/Icon まとめ記事/アイコンまとめ」など、アイコンを画像付で紹介してくれているサイトは沢山見つかるので、そういうところで探すと、お気に入りのものが見つかると思います。

アイコン画像をサーバーにアップロードする

自分の使うアイコンを入手できたら、それをサーバーにアップロードします。ファンブログの場合、記事の中にアップロードするしかないのですが、ひとつの記事にアップロードできる画像は5個までです。何十個もアップロードする場合は、とても大変な作業になります。

なので、私は自分の契約している別サーバーにFTPでアップロードしました。私は使ったことがないので、わかりませんが無料で使えるファイルサーバーはいくつかあるようです。

カテゴリーとアイコンを紐付ける

今回は、カテゴリーごとに違うアイコンを表示させるため、まずその設定をします。つまり、どのカテゴリーでどのアイコンを表示させるかの設定です。具体的にはJavaScriptのオブジェクトを使って連想配列で処理します。このブログの場合は次のようになります。

var categories={
	"category_5":"37_64x64.png",
	"category_28":"43_64x64.png",
	"category_6":"41_64x64.png",
	"category_7":"51_64x64.png",
	"category_27":"50_64x64.png",
	"category_30":"45_64x64.png",
	"category_34":"40_64x64.png",
	"category_35":"36_64x64.png",
	"category_33":"44_64x64.png",
	"category_20":"42_64x64.png",
	"category_13":"2_64x64.png",
	"category_32":"55_64x64.png",
	"category_24":"34_64x64.png",
	"category_18":"25_64x64.png",
	"category_15":"26_64x64.png",
	"category_26":"9_64x64.png",
	"category_16":"56_64x64.png",
	"category_19":"48_64x64.png",
	"category_25":"54_64x64.png",
	"category_29":"5_64x64.png",
	"category_31":"19_64x64.png"
};

左側の “category_xx” がキーで、右の “xx_64x64.png” が、呼び出すファイル名です。

キーは、カテゴリーごとのURL「http://fanblogs.jp/ユーザー名/category_xx/」の最後「category_xx」を記入します。たとえば、カテゴリー「超初心者HTML入門」のURLは「http://fanblogs.jp/ayzfqir5/category_28/」なので「category_28」になります。

私はアイコンを、すべて同じディレクトリにアップロードしたので右側はファイル名だけですが、ファンブログにアップロードした場合は、ファイル5個ごとにディレクトリ構成が違うので、フルパスで記入する必要があります。

挿入スクリプトの本体

今、このブログのスキンは完全自作でファンブログのものとは違う構成なのですが、ファンブログのスキンなら下のようになっていると思います。

<BlogEntries>
<div class="entry">
<div class="entryDate">{$BlogEntryDateformat="%Y年%m月%d日" language="jp"$}</div>
<h2 class="entryTitle"><a href="{$BlogEntryPermalinkUrl$}">{$BlogEntryTitle$}</a></h2>

<div class="entryBody clr">{$BlogEntryBody$}</div>
<BlogEntryIfExtended>
	<div class="entryContinue"><a href="{$BlogEntryPermalinkUrl$}#BlogEntryExtend">続きを読む...</a></div>
</BlogEntryIfExtended>
<div class="entryInfo">
	投稿者:<a href="{$BlogEntryWriterUrl$}" target="_blank">{$BlogEntryWriterName$}</a>|{$BlogEntryDate format="%H:%M"$}
	<BlogEntryIfCategory>|<a href="{$BlogEntryCategoryLink$}">{$BlogEntryCategory$}</a></BlogEntryIfCategory>
	<BlogEntryIfAllowComments>|<a href="{$BlogEntryPermalinkUrl$}#comments">コメント({$BlogEntryCommentCount$})</a></BlogEntryIfAllowComments>
	<BlogEntryIfAllowPings>|<a href="{$BlogEntryPermalinkUrl$}#Trackback">トラックバック({$BlogEntryTrackbackCount$})</a>	 </BlogEntryIfAllowPings>
 </div>
</div><!-- entry -->
</BlogEntries>

この最後の「</BlogEntries>」の直後に次のコードを追加します。それがスクリプトの本体です。書き換えるスキンは「メイン」「アーカイブ」「1記事」の3つです。

<script type="text/javascript"><!--
(function(){
	var categories={
		"category_5":"37_64x64.png",
		"category_28":"43_64x64.png",
		"category_6":"41_64x64.png",
		"category_7":"51_64x64.png",
		"category_27":"50_64x64.png",
		"category_30":"45_64x64.png",
		"category_34":"40_64x64.png",
		"category_35":"36_64x64.png",
		"category_33":"44_64x64.png",
		"category_20":"42_64x64.png",
		"category_13":"2_64x64.png",
		"category_32":"55_64x64.png",
		"category_24":"34_64x64.png",
		"category_18":"25_64x64.png",
		"category_15":"26_64x64.png",
		"category_26":"9_64x64.png",
		"category_16":"56_64x64.png",
		"category_19":"48_64x64.png",
		"category_25":"54_64x64.png",
		"category_29":"5_64x64.png",
		"category_31":"19_64x64.png"
	};

	var icon_url='ここにアイコンのディレクトリへのPATHを記入';
	var entries=document.querySelectorAll('div#entries div.entry');

	for(var i=0;i<entries.length;i++){
		var a=entries[i].querySelectorAll('div.entryInfo a');
		var icon=categories[a[1].href.replace(/^.+?\/(category_[0-9]+).*$/,'$1')];
		var img='string'==typeof icon?'<img src="'+icon_url+icon+'" alt="" class="category_icon" />':'';
		var body=entries[i].querySelector('div.entryBody');

		body.innerHTML=img+body.innerHTML;
	}
})();//-->
</script>

var categories の中身は自分のブログに合わせてください。

「ここにアイコンのディレクトリへのPATHを記入」と書いてある場所には、アイコンセットをアップロードしたサーバーのディレクトリへのPATHを記入します。ファンブログにアップロードしている場合は、アイコンのファイル名にPATHも含まれているので、空文字列にします。

a[1]の部分は、スキンがデフォルトの場合です。スキンを改造している場合は、添字の1を適切なものに訂正してください。

表示されるアイコンには、すべて「category_icon」というクラス名がつけられています。間隔などの調整はスタイルシートで行なってください。

本文を指定文字数で切り詰める

ここまでで、スキンは完成しています。ただ、うちのブログの様に、本文を切り詰めて、最後に「この記事を読む」と付ける場合は、上のスクリプトを一部変更します。

この行を削除して、下のソースに差し替えます。

body.innerHTML=img+body.innerHTML;

差し替えるソース

var str=body.innerHTML.replace(/\<script.*?\>.*?(\<\/script\>)|\<style.*?>.*?(\<\/style\>)|\<.+?\>/g,'');
body.innerHTML=img+(str.length>150?str.slice(0,149)+'…':str)+'<p class="read_more"><a href="{$BlogEntryPermalinkUrl$}">この記事を読む</a></p>';

上は、文字数を150字にする場合です。150字より長ければ、149文字で切って、150文字目に「…」を入れます。文字数は自分の都合に合うように調整してください。

もちろん、この最後の処理は「1記事」には適用しません。1記事の場合、アイコンを先頭に挿入することで、表示のバランスが狂うことがあります。それはレイアウト的な問題ですので、各自で修正してください。このブログでは「1記事」のみ、アイコンを記事本文でない場所に配置して解決しました。

appendChildやinsertBeforeでノードを移動させる

DOMのappendChildは子ノードの追加、insertBeforeはノードの挿入のためのメソッドですが、これを使ってノードの場所を変更できます。

appendChildで移動する

たとえば、次のようなHTMLがあったとします。

<div id="outer">
<p id="morning">おはよう</p>
<p>こんにちは</p>
<p id="night">こんばんは</p>
</div>

ここで、下のコードを実行すると「おはよう」が「こんばんは」の後に移動します。

document.querySelector('#outer').appendChild(document.querySelector('#morning'));

実行例

おはよう

こんにちは

こんばんは

実行すると「おはよう」が「idがouterであるdiv」に追加されます。その結果、元の位置から最後にずれます。「おはよう」の位置がずれたので、「こんにちは」が先頭になります。

insertBeforeで移動する

上の例のHTMLに今度は次のスクリプトを適用してみます。すると最後の「こんばんは」が先頭にある「おはよう」の前に移動します。

var outer=document.querySelector('#outer');
var night=outer.querySelector('#night');
var morning=outer.querySelector('#morning');

outer.insertBefore(night,morning);

実行例

おはよう

こんにちは

こんばんは

これを知っていると、すごく便利だと思います。このブログのコメント欄の改造はこのメソッドを多用して実現しました。

ファンブログでの404ページ表示法

2014年1月22日にA8.netのファンブログはSeesaa Blogのシステムをベースにして生まれ変わりました。よってファンブログ関連の記事は今では当てはまらない可能性があります。新しいファンブログのカスタマイズは別ブログ「ファンブログ テック」で詳しく書いていますので、そちらをご覧ください。

この記事はファンブログ専用情報です。2013年3月10日、記事を大幅に書き換えました。

今ご覧いただいている、このブログで実際に使っている方法は下のやり方とは違います。このブログではappendChildという方法で「404の時だけ文章を追加」しています。下の説明は、元々書き込まれている文章の「表示・非表示の切替え」をしています。SEO的には、不要な文章がない方が望ましいですが、説明が難しくなるので簡単な方法を書いています。

今回は、ファンブログ純正のスキンを使っているブログ「八百屋勘太のおもしろ体験談」のキャプチャを使わせていただきました。
ページがある時

ファンブログのページはarchive/1から始まるので、archive/0というページは存在しません。

 <- このページは存在しない。

ファンブログだと、何も設定しない場合、存在しないページは次のように表示されます。

記事がないページ

記事がないので、その下の「HOMEへ行くナビ」や、「トラックバック」「コメント」が上に上がって表示されています。これだと、記事がないのがわかりづらいので、「記事が見つからない」というメッセージを表示するように変更します。

設定方法

まず、サイドバーに1項目追加して、次のソースをそのまま貼り付けてください。サイドバーに項目を追加する方法がわからなければ、別記事「モジュールの設置方法」を参照してください。

<div id="message404" style="display:none;">
<h2 class="entryTitle">ご指定のページが見つかりません</h2>
<div class="entryBody">
ここに好きなメッセージを書いてください
</div>
</div>

<script type="text/javascript"><!--
if(-1==window.location.href.indexOf('profile')&&
	-1==window.location.href.indexOf('portal')&&
	!document.querySelector('.entryTitle a').innerHTML.length){

	var message=document.querySelector('#message404');
	var entries=document.querySelector('#entries');

	entries.parentNode.insertBefore(message,entries);
	entries.parentNode.removeChild(entries);

	message.id='entries';
	message.style.display='block';
}//-->
</script>

このソースの赤字と青字を好きな文章に書き換えてください。赤字がタイトル、青字が説明文です。今回はタイトルは変更せず、説明文のところで画像を使って説明しました。

完成したのは下のソースです。青字部分の場所だけ書き換えています。

<div id="message404" style="display:none;">
<h2 class="entryTitle">ご指定のページが見つかりません</h2>
<div class="entryBody">
<p style="text-align:center;">
<img alt="ページが存在しません" src="画像のURL" width="400" height="126" />
</p>
</div>
</div>

<script type="text/javascript"><!--
if(-1==window.location.href.indexOf('profile')&&
	-1==window.location.href.indexOf('portal')&&
	!document.querySelector('.entryTitle a').innerHTML.length){

	var message=document.querySelector('#message404');
	var entries=document.querySelector('#entries');

	entries.parentNode.insertBefore(message,entries);
	entries.parentNode.removeChild(entries);

	message.id='entries';
	message.style.display='block';
}
//-->
</script>

これを保存すれば、記事がないURLを指定された時に下のように表示されます。

ページがない時の表示

スクリプトの説明

初期状態では、追加したメッセージは非表示になっています。

<div id="message404" style="display:none;">
<h2 class="entryTitle">ご指定のページが見つかりません</h2>
<div class="entryBody">
<p style="text-align:center;">
<img alt="ページが存在しません" src="画像のURL" width="400" height="126" />
</p>
</div>
</div>

<script type="text/javascript"><!--

//開いているページがプロフィールでもポータルでもない場合、
//タイトルをクラス名entryTitleで探し、a タグの中身があるかを調べる
//なければ記事はない。その場合は括弧の中を実行
if(-1==window.location.href.indexOf('profile')&&
	-1==window.location.href.indexOf('portal')&&
	!document.querySelector('.entryTitle a').innerHTML.length){

	//非表示になっているメッセージを探す
	var message=document.querySelector('#message404');

	//記事の表示場所を探す
	var entries=document.querySelector('#entries');


	//本来記事が表示される場所の直前にメッセージを移動
	entries.parentNode.insertBefore(message,entries);

	//記事表示領域を削除(トラックバックやコメント欄も削除される)
	entries.parentNode.removeChild(entries);

	//メッセージのidをentriesに変更(スタイルシートを適用するため)
	message.id='entries';

	//メッセージを表示
	message.style.display='block';

}
//-->
</script>

このスクリプトを使うのは1記事ページだけなので、サイドバーではなく、1記事のスキンに書き込んでもかまいません。その場合は、スキンの最後に書いてください。entryTitleやentriesの前に書くと、それを見つけられないので正しく動きません。

今回のinsertBeforeの使い方は、少し特殊ですが、それに関しては別記事「appendChildやinsertBeforeでノードを移動させる」で詳しく説明しています。

余談ですが本来ペーがないときにはステータス404を返すのが決まりです。しかしファンブログは404ではなく200を返してきます。200というのは問題なしOKのコードです。確かに、記事がない空のページですが、ページそのものは表示されています。しかし、この場合200でいいのでしょうか?私は別のスクリプトで404が返って来れば、それ用の処理、200なら通常の処理という内容のものを書いたのですが、どうしてもうまく行かないので調べた結果404が返っていないことに気がつきました。