Octopressをアップデート したらカテゴリが全部小文字になって困った話。
問題となる変更点
Octopressの最新版では jekyll-2.1.0を使う様になったこと。 以前は(このサイト様に使ってたものは)jekyll-0.12.1でした。
JekyllのHistory を見ると
の様に、1.0.0 / 2013-05-06 から全てCategoryがDowncaseになるようにしてある様です。
Ensure all categories are downcase. Fix for #842. · 73ca35e · jekyll/jekyll
これは、2つのポストで同じカテゴリー名を大文字小文字バラバラ (1つにCategory, もう一つにcategory、みたいな) で付けると起こる問題に対する対処です。
ビルドしてる最中は別々なものとして扱われて、
サイドバーのカテゴリーリストなんかにも2つとも表示されるのですが、
最終的に、カテゴリーページが設置されるディレクトリが.../category/index.html
的な
小文字のディレクトリに収まる様に設定されてるので
1、
最終的にその2つのカテゴリーは同じところを指し示す事になります。
この時に、先に入ってたものが消される(逆かも)ので
Categoryと付けられた物か、categoryと付けられたもの、
どちらかだけが.../category/index.html
内にリンクを貼られます。
この問題を解決するため、予めカテゴリーは全て小文字にしてしまおう、 というのが上の変更です。
ただ、以前のOctopressは区別される状態だったので、 全部統一するように注意して大文字を使ってきました。
全部小文字でも別にそれ程悪くは無いのですが ちょっと気持ち悪いので以前みたくしてみます。
チェック
(上で既にどこが悪いか書いてますが、ここではまだ分かってないとして。。。)
Octopressをアップデートしたらカテゴリーがすべて小文字に表記される様になって しまったので どこで小文字になってるか探してみました。
まず、source/_layouts/post.html がhtmlに変換される時にページの大元になるのでその先頭に
1 2 3 4 5 6 7 8 9 |
|
こんなかんじでcategories
を書き出させてみせます。
すると、Categoryの記事にもcategoryの記事にも
1 2 3 4 5 6 |
|
という記述が有り、
OctopressのプラグインとかではなくJekyllがyml設定からcategories
(category
)
を引っ張ってっくる時に既に小文字にしている様子。
で、どうしたもんかと探していたらウェブで上のJekyllのHistoryページを見つけた、と。 (意味なし。。。)
対処
原因はJekyllの中の
/lib/jekyll/post.rb: https://github.com/jekyll/jekyll/blob/master/lib/jekyll/post.rb
の変更です。
(システムのrubyに直接インストールしてるなら、
Macなら/Library/Ruby/Gems/2.0.0/gems/jekyll-2.1.0/lib/jekyll/post.rb
とか、
rvmでRubyをインストールしてるなら~/.rvm/gems/ruby-1.9.3/gems/jekyll-2.1.0/lib/jekyll/post.rb
、とかにあります。)
こいつを、以前 Octopress Tips の見出しの追加 でやってみたいに直接弄っても良いのですが、 そうもそうしなくても良さそうだったので下の様な方法で 2。
やりかたは、上のファイルをplugins
にコピーしてきて変更するだけ。
関数とかの定義が順番に読みこまれて、最終的にplugins
に同じものがあればそれが
上書きしてくれるみたいです(この辺よくわかってない。。。)。
しかも、クラス全体とかでなくて、一部の関数だけ、とかでも良いみたいなので、
1 2 3 4 5 6 7 8 9 10 |
|
と、必要な関数だけかけばOK。
populate_categories
で、downcase
となってる箇所をcapitalize
に変えただけです。
これで、どんな単語が来ても、先頭の文字だけ大文字の文字列に全て変換されます。
この辺は好みですが、もし、iPhone
的なのを入れたかったりする場合には、
1 2 3 |
|
な感じで何も変形せずに与える様にして(昔の振る舞いと同じ)、 カテゴリを定義する時に、必ず大文字小文字の違うものを作らないように注意すれば良いと思います。
post.rb
の中を見ると、上の方でもう一箇所downcase
を使ってる箇所がありますが、
そこではディレクトリ名からカテゴリーを取って来るんですが、
このブログでは関係ない上に、上の関数の所でもう一度まとめて変換してるので
特に気にしなくてOK
3。
これだけで十分ですが、もし、全部コピーしておいたほうが気分が良いという場合にも、 上の方にある、
MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)(\.[^.]+)$/
等の定数の定義は消しておかないと、
$ rake generate
## Generating Site with Jekyll
identical source/stylesheets/screen.css
Configuration file: /octopress/_config.yml
/octopress/plugins/post.rb:7: warning: already initialized constant Jekyll::Post::MATCHER
/Library/Ruby/Gems/2.0.0/gems/jekyll-2.1.0/lib/jekyll/post.rb:7: warning: previous definition of MATCHER was here
/octopress/plugins/post.rb:9: warning: already initialized constant Jekyll::Post::EXCERPT_ATTRIBUTES_FOR_LIQUID
/Library/Ruby/Gems/2.0.0/gems/jekyll-2.1.0/lib/jekyll/post.rb:9: warning: previous definition of EXCERPT_ATTRIBUTES_FOR_LIQUID was here
/octopress/plugins/post.rb:23: warning: already initialized constant Jekyll::Post::ATTRIBUTES_FOR_LIQUID
/Library/Ruby/Gems/2.0.0/gems/jekyll-2.1.0/lib/jekyll/post.rb:23: warning: previous definition of ATTRIBUTES_FOR_LIQUID was here
...
みたいなWARNINGが毎回出てうざいことになります。(buildは出来ますが)
実際、どのファイルの関数が呼ばれてるかチェックするために、
/Library/Ruby/Gems/2.0.0/gems/jekyll-2.1.0/lib/jekyll/post.rb
に
1 2 3 4 5 6 7 8 |
|
な感じで出力を加えて手元のpost.rb
にも
1 2 3 4 5 6 7 8 9 10 11 |
|
とputs
を入れてみると、
$ rake generate
(in /octopress)
## Generating Site with Jekyll
identical source/stylesheets/screen.css
Configuration file: /octopress/_config.yml
Source: source
Destination: public
Generating...
initialize in common
populate_tags in plugin!
initialize in common
populate_tags in plugin!
...
の様になって、initialize
は通常のディレクトリの物が呼ばれていて
populate_categories
はplugins/post.rb
の物が呼ばれてる事が分かります。
出来たページも確かにCapitalizeなものになっています。 各ページのカテゴリの大文字小文字を変更してチェックしてみてもすべて 統一されて全部きちんとリンクされる様になったので前より便利。
tagの方
post.rb
をみると、tagsも
populate_tags
の中で追加しているので、
1 2 3 |
|
みたいにして、plugins/post.rbに加えてあげればTagも全て大文字から始まる文字列になります。
ただ、こちらにはiPhone
とかもあるしそのまま使おうかな、ということで今回は変更せず
(デフォルトでもtags
はそのまま使うようになっています。)
-
システムによっては大文字小文字がディレクトリやファイル名で区別されないための対処?
この見出しの話はKramdownにしたので今は問題ないんですが、 rdiscountとか使ってて問題ある場合は、下に書くように直接 インストールしたファイルを変更しなくてもOctopress内で変更できます。 ↩
もし、上に書いたように大文字小文字を入力のまま使いたくて、かつディレクトリをカテゴリに使ってる場合には上の方にある
downcase
の部分も1 2
-self.categories = dir.downcase.split('/').reject { |x| x.empty? } +self.categories = dir.split('/').reject { |x| x.empty? }
な感じで消しておかないといけません。 ↩