Loading...

はてなブログのカテゴリを階層化するカスタマイズ

f:id:nasust:20170116174356j:plain



こんにちはnasustです。
今回は、はてなブログのカテゴリを階層化するカスタマイズを紹介します。

既に雑記-社会という記述方法で階層化するJavaScriptが他のブログで紹介されていますが、自分が作成したスクリプトは、ブログのカテゴリを一切編集せずに階層化します。編集が面倒くさい人向けのスクリプトです。

その代わり、階層化のルールをJavaScript内に書かなければなりません。また階層化の為にカテゴリを編集しないので、親カテゴリを選択しても子カテゴリは含まれません。もちろん、ブログの設定で編集すれば含めることが出来ます。

またカテゴリのリンクを設定する事ができます。例えば、まとめ記事にリンクさせる事ができます。

そしてGoogleパンくずリストにも対応しています。

JQuery

このスクリプトJQueryが必要です。導入していない場合はヘッダに以下の内容を入力してください。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

JavaScript

以下のスクリプトをフッタに入力してください。

<script>
(function( config ){
    var categoriesRule = [];
    config.categories.forEach(function(configCategoryRuleRow){
        var categoriesRuleRow = [];
        
        configCategoryRuleRow.forEach(function(configCategoryRuleCol){
            var rule = {
                title : undefined,
                priority : 0,
                url  : undefined
            };
            
            if( $.isArray( configCategoryRuleCol ) ){
                rule.title = configCategoryRuleCol[0];
                
                if( configCategoryRuleCol.length >= 1 ){
                     rule.url = configCategoryRuleCol[1];
                }
                
            }else{
                rule.title = configCategoryRuleCol;
            }
            categoriesRuleRow.push(rule)
        });
        var key = categoriesRuleRow[ categoriesRuleRow.length - 1 ].title;
        
        categoriesRule[key] = categoriesRuleRow;
    });
    
    var renderCategoryTree = function( ruleRow ){
        var html = "<ul class='category-tree'>"
        if( config.top ){
            html += "<li class='category-tree-top' itemscope itemtype='http://data-vocabulary.org/Breadcrumb' ><a href='" + config.top + "' itemprop='url' ><span itemprop='title'>トップ</span></a></li>"
        }
        ruleRow.forEach( function( ruleCol , index ){
            var className = "category-tree-child"
            if( index ==  ruleRow.length - 1 ){
                className = "category-tree-last"
            }
            var href = config.categoryURLPrefix + encodeURI(ruleCol.title);
            if( ruleCol.url ){
                href = ruleCol.url;
            }
            
            html += "<li class='" + className + "' itemscope itemtype='http://data-vocabulary.org/Breadcrumb'><a href='" + href + "' itemprop='url'><span itemprop='title'>" + ruleCol.title + "</span></a></li>"
        });
        html += "</ul>"
        
        $(".entry-header").append(html);
        $(".entry-categories").remove();
    }
    
    
    $(".entry-categories").each(function(){
        var categories = $(this);
        var hitRuleList = [];
        var categorylinks = categories.children();
        
        categorylinks.each(function(){
            var categoryLink = $(this);
            var cunnretHitRule = categoriesRule[ categoryLink.text() ];
            if( cunnretHitRule ){
                var updateIndex = -1;
                hitRuleList.forEach(function(hitRule , index ){
                    if( hitRule.length < cunnretHitRule.length ){
                        var hit = true;
                        for( var i = 0 ; i < hitRule.length ; i++ ){
                            var hitRuleTitle = hitRule[i].title;
                            var cunnretHitRuleTitle = cunnretHitRule[i].title;
                            
                            if( hitRuleTitle !== cunnretHitRuleTitle ){
                                hit = false;
                            }
                        }
                        if( hit ){
                            updateIndex = index;
                        }
                    } else if ( hitRule.length > cunnretHitRule.length ){
                        var hit = true;
                        for( var i = 0 ; i < cunnretHitRule.length ; i++ ){
                            var hitRuleTitle = hitRule[i].title;
                            var cunnretHitRuleTitle = cunnretHitRule[i].title;
                            
                            if( hitRuleTitle !== cunnretHitRuleTitle ){
                                hit = false;
                            }
                        }
                        if( hit ){
                            updateIndex = -2;
                        }
                    }
                });
                
                if( updateIndex == -1 ){
                    hitRuleList.push( cunnretHitRule )
                }else if( updateIndex == -2 ){
                    //ignore
                }else{
                    hitRuleList[ updateIndex ] = cunnretHitRule;
                }
                
            }
        })
        
        if( hitRuleList.length > 0 ){
            hitRuleList.forEach( function( hitRule ){
                renderCategoryTree( hitRule );
            });
        }else{
            var categoryRuleRow = [];
            categorylinks.each(function(){
                var categoryLink = $(this);
                categoryRuleRow.push({
                    title:categoryLink.text(),
                    priority : 0,
                    url:undefined
                });
            });
            renderCategoryTree( categoryRuleRow );
        }
        
    })
})({//設定はここから下
    top: "http://nasust.hatenablog.com/archive",
    categoryURLPrefix: "http://nasust.hatenablog.com/archive/category/",
    categories:[
        [ "雑記" , "社会"],
        [ "雑記" , "IT色々"],
        [ "雑記" , "酒"],
        [ "プログラミング" ],
        [ "プログラミング" , "WEB開発"],
        [ "プログラミング" , ["Go言語 / golang" , "http://nasust.hatenablog.com/entry/golang" ] ]
    ]
})
</script>

CSS

.entry-header .category-tree{
    list-style: none;
    margin: 0px;
    margin-top: 0.7em;
}

.entry-header .category-tree li{
    display: inline-block;
    margin-right: 0.3em;
}

.entry-header .category-tree li a{
    display: inline-block;
    font-size:12px;
    font-weight: bold;
    text-decoration: none;
    white-space: nowrap;
    margin-right:0.5em;
}

.entry-header .category-tree li a,
.entry-header .category-tree li a:link,
.entry-header .category-tree li a:active,
.entry-header .category-tree li a:visited,
.entry-header .category-tree li a:hover{   
    text-decoration: none;
    font-weight: bold;
}

.entry-header .category-tree-top:after{
    display: inline-block;
    font-family: blogicon;
    content: "\f006";
    margin-left: 5px;
    margin-right: 7px;
}

.entry-header .category-tree-child:after{
    display: inline-block;
    font-family: blogicon;
    content: "\f006";
    margin-left: 5px;
    margin-right: 7px;
}

設定方法

入力例:

{//設定はここから下
    top: "http://nasust.hatenablog.com/archive",
    categoryURLPrefix: "http://nasust.hatenablog.com/archive/category/",
    categories:[
        [ "雑記" , "社会"],
        [ "雑記" , "IT色々"],
        [ "雑記" , "酒"],
        [ "プログラミング" ],
        [ "プログラミング" , "WEB開発"],
        [ "プログラミング" , ["Go言語 / golang" , "http://nasust.hatenablog.com/entry/golang" ] ]
    ]
}

JavaScriptの下部にカテゴリの階層化のルールを書きます。

top

カテゴリの一番上の"トップ"のURLを指定します。通常はブログのトップのURLで良いですが、トップページをアーカイブページにしたい場合などは、アーカイブページのURLを入力します。

categoryURLPrefix

※カテゴリのURLの指定出来なかったので追加できるようにしました

カテゴリのURLの先頭を書きます。例えばhttp://nasust.hatenablog.com/archive/category/を入力した場合で、雑記のリンクは、http://nasust.hatenablog.com/archive/category/雑記となります。

アーカイブページでは無く記事の一覧にしたい場合は、http://nasust.hatenablog.com/category/と指定すると出来ます。

最後の/を忘れないようにお願いします。

categories

配列で["雑記","社会"]など記述していきます。この配列の最後の名前が、ブログのカテゴリと一致するとトップ > 雑記 > 社会とカテゴリが階層化されて表示されます。

配列の最後の名前のカテゴリで一致させますので、自由に階層を記述する事ができます。

例えば、["雑記","社会","日本"]とルールを書き、ブログの記事のカテゴリには日本とだけ設定します。表示はトップ > 雑記 > 社会 > 日本となります。

ブログの記事のカテゴリに雑記、社会、日本と設定しても日本で一致するので同じように表示します。

そして、カテゴリのURLを指定することが出来ます。指定しない場合はカテゴリのアーカイブページになります。

[ "雑記" , ["社会" , "http://xxx.blog.com/xxxx"] , "日本"]というように、カテゴリの名前の部分に[]で囲み、名前、URLの順で入力します。

二つ以上一致する場合

[ "雑記" , "社会"][ "プログラミング" , "WEB開発"]と二つ以上一致する場合は、それぞれの階層を行ごとに表示します。

ルールに一致しない場合

ルールに一致しない場合は、記事のカテゴリを、そのまま使用して階層化します。例えば記事に雑記、音楽と設定されている場合は、そのままトップ > 雑記 > 音楽と表示されます。

記事修正

  • 2016年1月16日 23:40
    • カテゴリのリンクが指定できないようになっていたので、設定でcategoryURLPrefixを追加して指定できるようにしました。
    • CSS.entry-header .category-tree li acolor:#FFFを削除

最後に

階層化する事で記事の整理がされ、読者に現在の位置が分かりやすくなりますね。

カテゴリ階層化のJavaScriptは書くつもりは無かったんですけど、既存の物だとカテゴリの設定が必要だったので、面倒だったので、それよりはJavaScriptでサクッと書いた方が楽でした。

個人的には、まとめページを指定できるのが良い機能かなと思っています。何か必要になれば機能を追加していこうかなと思います。