読者です 読者をやめる 読者になる 読者になる

【JavaScript】Tumblrの最新記事を取得する

JavaScriptは人生で5回ぐらいしか書いたことがなくて、jQueryを使ったのはそのうち2回ぐらいです。

しかしまぁ、いい加減覚えてみるのもいいかなと思って(と言うか仕事で必要になるので)とりあえず練習してみようかなと。

今までつけていた最新記事取得の問題点

今はもう変えてしまったんですが、前までついていた最新記事取得のスクリプトTumblrAPIのverが低く、しかも同期処理で取りに行っていたので、たまーにそこが原因でページの表示が遅くなることがありました。なので、ちゃんと非同期で取りに行くよう変更しました。

また、リンクだけがずらーっと並んでいたんですが、日付も欲しくなったのでつけました。

コード

Visual Studioで作ってみました。インテリセンスはそこまで上手く効いてくれませんでしたが(jQueryはめっちゃ楽だったけど)、デバッグは死ぬほど楽でした。やっぱIDEがあると違いますね。

function recent(displayCount) {

    var domain = "outofmem.tumblr.com";
    var apiKey = "";
    var limit = displayCount >= 20 ? 20 : displayCount;
    var baseUri = "http://api.tumblr.com/v2/blog/" + domain + "/posts/?api_key=" + apiKey + "&limit=" + limit;
    var $div = jQuery("#recent");

    $.ajax({
        type: "GET",
        url: baseUri,
        dataType: "jsonp",
        success: function (data) {
            

            // ステータスコードを見て判断
            if (data.meta.status != 200) {
                $div.append($("<p/>").text("Error:" + data.meta.msg));
                return;
            }

            // postsがなければ終了
            var json = data.response.posts;
            if (json == null || json.length <= 0) {
                $div.append("<p>Empty</p>");
                return;
            }

            //日付変換Function
            var convertDate = function (date) {
                var dateArray = date.split(" ");

                var y, m, d;

                if (dateArray[0].match(/(\d+)-(\d+)-(\d+)/)) {
                    y = RegExp.$1;
                    m = RegExp.$2;
                    d = RegExp.$3;
                }

                //UTCで15時以降の時間なら日付を1増やす
                if (dateArray[1].match(/(\d+):\d+:\d+/)) {
                    var h = RegExp.$1;
                    if (h >= 15) {
                        d = 1 + (+d);
                        if (d < 10) d = "0" + d;
                    }
                }

                return y + "/" + m + "/" + d;
            }

            var postDataArray = new Array();

            json.map(function (x) {
                return { "date": x.date, "url": x.post_url, "title": x.title };
            }).forEach(function (ref) {
                //記事の日付を取得
                var date = convertDate(ref.date);

                if (!postDataArray.some(function (x) { return date == x.date; })) {
                    //キーがなければ新たに作成
                    postDataArray.push({ "date": date, "li": [{ "url": ref.url, "title": ref.title}] });
                } else {
                    //キーがある場合はli配列にデータを追加
                    postDataArray.filter(function (x) { return date == x.date; })
                                 .forEach(function (x) { x.li.push({ "url": ref.url, "title": ref.title }); });
                }
            });

            var $ul = jQuery("<ul/>");
            var $innerUl = jQuery("<ul/>");
            postDataArray.forEach(function (postData) {

                // 日付にネストするulを作る
                postData.li.forEach(function (li) {
                    $innerUl.append(
                        jQuery("<li/>").append(
                            jQuery("<a/>").attr({ href: li.url })
                                          .text(li.title)
                        )
                    );
                });

                // 日付のliの中に$innerUlを入れる
                $ul.append(
                    jQuery("<li/>").append(
                            // 日付は日付でリンクを作成する
                            jQuery("<a/>").attr({ href: "http://" + domain + "/day/" + postData.date })
                                          .text(postData.date)
                        )
                    , $innerUl);

                $innerUl = jQuery("<ul/>");
            });

            $div.append($ul);
        }
    });
}

元々配布しようとかそんな考えはなく、JavaScriptド素人なこともあるのでマズいとこがいっぱいあるかもしれません。ってか日付変換は絶対もっと上手くやれそう。

また、Arrayの処理の関係上JavaScript1.6以降じゃないと動かないので、IE 8以下だと動きませんが、これは私からのファックサインです。ご確認ください。

まとめ

やっぱりこう、型推論の効かない言語は、肌に合わないです。

っつーかCSS書かなきゃですね…。