ローカルで作成する方法
最初、手元でランダムなリストを作ってそのまま送ってしまおう、としたのがこちら。
plugins/random_posts.rb
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
require 'jekyll'
module Jekyll
class RandomPosts < Generator
safe :true
priority :low
def generate ( site )
# check if random local is required or not
if ! site . config [ 'random_local' ]
return
end
if site . config [ 'random_posts' ]
n_posts = site . config [ 'random_posts' ]
else
n_posts = 5
end
popular_posts = site . posts . shuffle
site . posts . each { | post |
post . data . merge! ( "random_posts" => popular_posts [ 0 , n_posts ] )
}
site . pages . each { | page |
page . data . merge! ( "random_posts" => popular_posts [ 0 , n_posts ] )
}
end
end
end
これをplugins/ の中に入れておけば
page.random_posts
という値が使える様になるので、
source/_includes/custom/asides/random_posts.html とかいう名前で
source/_includes/custom/asides/random_posts.html
1
2
3
4
5
6
7
8
< section >
< h1 > Random Posts</ h1 >
< ul class = "posts" >
{% for post in page.random_posts %}
{% include post_list.html %}
{% endfor %}
</ ul >
</ section >
こんな内容の物を作っておけばサイドバーで使える様になります。
post_list.html は
Google AnalyticsのView数を取ってきてランキングを作る
で作ったものと同じです。
JavaScriptで動的に変更する方法
上の方法だと新しくビルドするまで全てのページでずっと一緒なので余り面白くありません。
ということで、JavaScriptで動的にその場で作成する方法をやってみます。
今回はリスト用の簡易HTMLを用意しておいて、それをJavaScriptで読み取って
適当に選ぶ、と言う方法でやってみました。
リスト用HTMLの準備
まず、source 直下にposts.html という名前で
source/posts.html
1
2
3
4
5
6
7
8
---
layout: null
---
< div >
{% for post in site.posts %}
{% include post_list.html %}
{% endfor %}
</ div >
こんな感じのファイルを作ります。
これが
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
< div >
< li class = "post index_click_box" >
< div class = "group" >
< div class = "title-smallthumb" >
< a href = "/blog/2015/02/10/blog-octopress/" >< img src = "/images/post/20150210_popularlist.jpg" ></ a >
</ div >
< a class = "click_box_link" href = "/blog/2015/02/10/blog-octopress/" > Google AnalyticsのView数を取ってきてランキングを作る</ a >
</ div >
</ li >
< li class = "post index_click_box" >
< div class = "group" >
< div class = "title-smallthumb" >
...
</ div >
</ li >
< div >
こんな感じのHTMLになります。
ここでリストだけアレば良いのですが、一番外側のdiv
要素が無いと
あとでJavaScript(JQuery)で中身を取得するときに上手く行かないので周りに1つ要素が必要です。
(html
、body
以外で。)
XMLとかにした方が汎用性は出るかと思いますが、
取ってきた後に整形したりするのが面倒なので
今回はそのまま使える様にHTMLにしてあります1 。
サイドバー用のHTML & JavaScript
source/_includes/custom/asides/random.html
を以下のように変更し、取り敢えずJavaScriptもここへ書いておきます。
source/_includes/custom/asides/random.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
< section >
< h1 id = "random-link" > Random Posts</ h1 >
< div id = "random-posts" >< div >
< ul >
</ ul >
</ div >
< script type = "text/javascript" >
$ ( function (){
$ . ajax ({
url : '/posts.html' ,
type : 'GET' ,
dataType : 'html'
}). done ( function ( data ){
var entry_list = $ ( data ). find ( 'li' );
var nentries = entry_list . length ;
var rand = [];
var f = document . createDocumentFragment ();
while ( rand . length < { % if site . random_posts % }{{ site . random_posts }}{ % else % } 10 { % endif % } && rand . length < nentries ){
var r = Math . floor ( Math . random () * nentries );
if ( rand . indexOf ( r ) !=- 1 ) continue ;
f . appendChild ( entry_list [ r ]);
rand . push ( r );
}
var t = document . getElementById ( 'random-posts' ). getElementsByTagName ( 'ul' )[ 0 ];
t . appendChild ( f );
var random_url = $ ( entry_list [ Math . floor ( Math . random () * nentries )]). find ( '.click_box_link' )[ 0 ]. href ;
$ ( '#random-link' ). wrap ( $ ( '<a href="Random Fly!"/>' ));
$ ( '#random-link' ). click ( function (){
window . location = random_url ;
return false ;
});
});
});
</ script >
</ section >
Ajaxを使って作成される/posts.html を取得して、その中にある
li
要素を配列として取ってきています2 。
この時に先のdiv
要素が周りにないと上手くli
要素の配列が取れません。
この辺り、ブラウザによって動作が違ったりしますが、
取り敢えず上のコードだと手元のMac/WindowsでFirefox/Google Chrome/IE/Safariで動いています。
後は適当に乱数を使って必要な数だけ最初に作ったul
要素の中に加えて行くだけです。
また、タイトルのRandom Posts
の部分も別途適当なページヘのリンクになるようにもしています。
_config.yml
今回はそれ程設定する所はありませんが
_config.yml
1
2
3
# Random posts
random_posts : 5
random_local : false
とでも書いておけば動的な方だけ有効になって5つのランダムな記事が表示されます。
(少なくともコレ書いた時点では)右下にあるRandom Posts
リストはリロードするたびに変わるはずです。