カテゴリー分け
Octopressでは元々categories
を付けられる様になっていますが、
このブログでは加えてタグも付けられる様になっています。
Octopressでのタグの運用
基本的にカテゴリーは1つにして複数のタグを付けてる感じ。
パンくずリストを作るにあたってどういう構造にしようか考えましたが、
色々変更するのも面倒なので、
まずカテゴリーを持ってきて、次にタグの中で一番最初のものを次の層とすることにしました。
ま、取り敢えず作ってみた、ということで。
breadcrumbs.html
こんな感じのファイルを_includes/post/ に作ります。
source/_includes/post/breadcrumbs.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{% if post %}
{% assign p = post %}
{% else %}
{% assign p = page %}
{% endif %}
< ol class = "breadcrumbs" >
< li >< a href = "{{site.url}}" >< span > Top</ span ></ a ></ li >
{% if p.categories and p.categories.size > 0 %}
{% capture c %}{{p.categories|first}}{% endcapture %}
< li >< span class = "breadcrumbs_separator" > › </ span >
< a href = "{{root_url}}/{{site.category_dir}}/{{c|downcase}}/" >< span > {{c}}</ span ></ a ></ li >
{% endif %}
{% if p.tags and p.tags.size > 0 %}
{% capture t %}{{p.tags|first}}{% endcapture %}
< li >< span class = "breadcrumbs_separator" > › </ span >
< a href = "{{root_url}}/{{site.tag_dir}}/{{t|downcase}}/" >< span > {{t}}</ span ></ a >
{% if p.tags.size > 1 %}
{% for t in p.tags offset:1 %}
< span > , </ span >
< a href = "{{root_url}}/{{site.tag_dir}}/{{t|downcase}}/" >< span > {{t}}</ span ></ a >
{% endfor %}
{% endif %}
</ li >
{% endif %}
</ ol >
最初のp
の設定はアーカイブページ等で読み込まれる場合に
各ページをpost
という変数に入れて回す前提です。
(Octopressデフォルトのトップページとかだとそうなってます。)
後はただのol
のリストですが、
最初にTop
ページを表示して、
カテゴリーが無かったりタグが無かったりする場合には飛ばす様にしています。
それから、タグに関しては複数ある場合があるので、
ここでは2番目以降のものもリンクを置くようにしています。
これだけだと最初のタグと後のタグと特に区別はありませんが、
下に書くクローラ向けの設定の所でちょっと変わってきます。
取り敢えず表示させたいだけならこれだけで、後は
source/_includes/article.html とかに
1
2
3
<p class="meta">
{% include post/date.html %}{{ time }}
+ {% include post/breadcrumbs.html %}
みたいな感じで日付の近くとかに適当において上げればOK。
次に、見た目を整えるためにsass/partials/_blog.scss に
sass/partials/_blog.scss
1
2
3
4
5
6
7
8
9
10
11
12
13
14
.breadcrumbs {
margin : 0 ;
> li {
list-style : none ;
display : inline-block ;
text-decoration : none ;
a {
white-space : normal ;
}
}
.breadcrumbs_separator {
font-weight : bolder ;
}
}
と.breadcrumbs
クラスの情報を加えます。
さらにsass/partials/_archive.scss に
sass/partials/_archive.scss
1
2
3
4
5
- a.category, a.tag, time {
+ a.category, a.tag, .breadcrumbs, time {
@extend .sans;
color: $text-color-light;
}
と、#blog-archives
の中の書式で、category
やtag
と同じ
フォントや色になるように加えておきます。
これで
こんな感じのパンくずリストが付いてそれっぽくなります。
JSON-LDで書くSchema.org情報
Googleのクローラ向けにSchema.orgに従った情報を
JSON-LD形式で追加します。
これを正しく記述することで、検索結果の表示のタイトル下の所で、なにもしないと
http://rcmdnk.github.io/blog/2015/06/03/computer-firefox-pocket/
みたいに単にURLが表示されるものが、
rcmdnk.github.io > Computer > Firefox
みたいにパンくずリストが表示される様になります。
最近丁度このSchema.orgのパンくずリストをGoogleもサポートした
1 、とか言うのもあったので。
まだちょっと問題がある
2
みたいですが、取り敢えず使ってみたかっただけなのでその辺は余り気にせず。
Breadcrumbs Structured Data Google Developers
を参考にして
以下の様な情報ファイルを作ります。
source/_includes/schema.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
{% if page.categories or page.tags %}
< script type = "application/ld+json" >
{
"@context" : "http://schema.org" ,
"@type" : "BreadcrumbList" ,
"itemListElement" :
[
{ % assign pos = 1 % }
{ % if page . categories and p . categories . size > 0 % }
{ % capture c % }{{ page . categories | first }}{ % endcapture % }
{
"@type" : "ListItem" ,
"position" : {{ pos }},
"item" :
{
"@id" : "{{site.url}}/{{site.category_dir}}/{{c|downcase}}/" ,
"name" : "{{c}}"
}
}
{ % capture pos % }{{ pos | plus : 1 }}{ % endcapture % }
{ % endif % }
{ % if page . tags % }
{ % if page . tags and page . tags . size > 0 % }
{ % capture t % }{{ page . tags | first }}{ % endcapture % }
{ % if pos != '1' % },{ % endif % }
{
"@type" : "ListItem" ,
"position" : {{ pos }},
"item" :
{
"@id" : "{{site.url}}/{{site.tag_dir}}/{{t|downcase}}/" ,
"name" : "{{t}}"
}
}
{ % capture pos % }{{ pos | plus : 1 }}{ % endcapture % }
{ % endif % }
]
}
</ script >
{% endif %}
ここではタグは最初のものだけを使います。
この出力はこんな感じ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
< script type = "application/ld+json" >
{
"@context" : "http://schema.org" ,
"@type" : "BreadcrumbList" ,
"itemListElement" :
[
{
"@type" : "ListItem" ,
"position" : 1 ,
"item" :
{
"@id" : "http://rcmdnk.github.io/blog/categories/blog/" ,
"name" : "Blog"
}
},
{
"@type" : "ListItem" ,
"position" : 2 ,
"item" :
{
"@id" : "http://rcmdnk.github.io/blog/tags/octopress/" ,
"name" : "Octopress"
}
}
]
}
</ script >
最初、position 1番目の所に上で書いた表示用のところと同じように
Top
を持ってきて、その後、2番めにカテゴリー、
3番目にタグ、とやっていたのですが、これだと
検索結果ページを見た時に、
rcmdnk.github.io > Top > Blog > Octopress
となって、最初の2つが被る状態になってしまうので
Top
の部分は外しました。
これをsource/_includes/after_footer.html とかで(</body>
直前)読み込んでおきます。
これでしばらくするとGoogleが認識してくれます。
とりあえずサイトをアップデートしたら、
GoogleのStructured Data Testing Tool Google Developers
でテストしてみます(実際にGoogleのクローラが見つける前でもページのHTMLを直接見てチェックしてくれます)。
こんな感じでBreadcrumbList
が認識されてればOK。
これで2,3日経って認識してもらえると
こんな感じでパンくずリスト表示されるようになります。
MICRODATAで書くSchema.org情報
上では実際にページに表示されるものと、
クローラ用の情報を別の場所に書きましたが、
MICRODATA(またはRDFA)の書式で書けば表示場所に全て書き込むことが出来ます。
source/_includes/post/breadcrumbs_microdata.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
{% if post %}
{% assign p = post %}
{% else %}
{% assign p = page %}
{% endif %}
< ol class = "breadcrumbs" itemscope itemtype = "http://schema.org/BreadcrumbList" >
< li >< a href = "{{site.url}}" >< span > Top</ span ></ a ></ li >
{% assign pos = 1 %}
{% if p.categories and p.categories.size > 0 %}
{% capture c %}{{p.categories|first}}{% endcapture %}
< li itemprop = "itemListElement" itemscope
itemtype = "http://schema.org/ListItem" >
< span class = "breadcrumbs_separator" > > </ span >
< a itemprop = "item" href = "{{site.url}}/{{site.category_dir}}/{{c|downcase}}/" >
< span itemprop = "name" > {{c}}</ span ></ a >
< meta itemprop = "position" content = "{{pos}}" />
</ li >
{% capture pos %}{{ pos | plus:1}}{% endcapture %}
{% endif %}
{% if p.tags and p.tags.size > 0 %}
{% capture t %}{{p.tags|first}}{% endcapture %}
< li itemprop = "itemListElement" itemscope
itemtype = "http://schema.org/ListItem" >
< span class = "breadcrumbs_separator" > > </ span >
< a itemprop = "item" href = "{{site.url}}/{{site.tag_dir}}/{{t|downcase}}/" >
< span itemprop = "name" > {{t}}</ span ></ a >
< meta itemprop = "position" content = "{{pos}}" />
{% if p.tags.size > 1 %}
{% for t in p.tags offset:1 %}
< span > , </ span >
< a href = "{{root_url}}/{{site.tag_dir}}/{{t|downcase}}/" >< span > {{t}}</ span ></ a >
{% endfor %}
{% endif %}
</ li >
</ li >
{% capture pos %}{{ pos | plus:1}}{% endcapture %}
{% endif %}
</ ol >
こんな感じ。
基本、
Breadcrumbs Structured Data Google Developers
のMICRODATAのサンプルをそのまま使っただけです。
最初こっちの方が別の所に余計な事を書かなくて良いので良いかな、
と思ったのですが、
これだと同じページで2つ上と下にパンくずリストを見せたいと思うと
両方でSchema.orgの情報が見つかって邪魔臭いのと、
さらにアーカイブページとかで
パンくずリストを載せてしまうとそのページに大量にパンくずリストが見つかってしまいます。
この辺、同じページに大量にあると最初のものだけを認識したりするみたいですが、
あまりすっきりしないので分けて、
schema.html の方は一つのページで最後に一つだけ読み込むようにしました。
まとめ
カテゴリー分けやタグ分けをしてれば
Octopress(Jekyll)でも簡単にパンくずリストを表示することが出来ました。
(単に今までただ羅列してたのを整理しただけみたいなもんですが。)
さらにGoogleの検索結果にも反映させることが出来ました。
検索結果表示を自分で変更できるとちょっと楽しい。
それから上にも書いた問題点ですが、
このブログを更新した際にも
こんな感じで2番目の物がFirefox > Firefox > Firefox...
となってしまったりしました。
これは最初にMICRODATAでやってた時のものですが、
JSON-LD形式の方がちゃんとしてるのかたまたまなのか、
今はきちんとこのページの表示もFirefox一つだけになってます。
まだ一部のページは反映されずにURLがそのまま載ってたりもしますが、
取り敢えず思ったよりも簡単に出来てGoogleの検索結果とかも変えられて面白かったな、と。