Jekyll在github博客中的应用

04 November 2015

git jekyll

我们来继续讨论jekyll的实际应用中所遇到的问题以及解决之道。 jekyll的内容有很多,你如果想学深入理解jekyll那么你来错地方了。如果你是遇到了以下问题,那么希望以下内容的对你解决问题有所帮助。

问题

    1. 输出全部文章
    1. 文章分类
    1. 文章添加标签
    1. 文章显示

jekyll 的全局变量有 4个

    site: 整个站点的信息
    page: 当前页面的所有信息
    content: 所有布局文件被渲染之后的内容(In layout files, the rendered content of the Post or Page being wrapped. )
    paginator:这个配置是要配置的,相当于自定义变量

site 的参数有很多。下面我就列举一下常用的几个。

    site.time  : 运行jekyll命令的时间
    site.pages : 所有页面,注意是页面
    site.posts :所有文章
    site.static_files : 静态文件,或者是没有被修改的文件
    site.html_pages : 所有html页面
    site.html_files : 所有静态的html页面,就是不用jekyll处理的页面
    site.collections : 列表信息
    site.data : _data目录下的信息
    site.documents : 所有页面的domcument,说白了就是html页面
    site.categories : 所有分类 的文章
    site.categories.CATEGORY : CATEGORY分类下的文章
    site.tags.TAG : 获取 TAG 标签下的所有文章

1.输出全部文章

site 是整个站点的根一样,这个变量下有很多的小的参数。可以通过 { {site.name}} 来获取信息。 比如要获取站点的全部文章就可以通过 { {site.posts}}来获取所有在 _posts目录下的所有文章。 通过for循环来遍历输出所有的文章。

    <!-- exampole -->
    { % for post in site.posts %}
    <li class="j-row j-list-i">
        { {post}}  //输出文章
    </li>
    { % endfor %}

page 是单独的对一个页面来的,它包含了以下信息

    page.content : 文章的内容部分
    page.title : 文章标题
    page.excerpt : 文章摘要
    page.url : 文章的链接   //e.g.  /2008/12/14/my-post.html
    page.date : 文章的时间  
    page.id : 符合文章的唯一路径  //e.g. /2008/12/14/my-post
    page.categories : 文章的分类     ['',''] 数组
    page.tags : 文章的标签 也是数组
    page.path : 文章的文件路径 // e.g.  _posts/2015-11-04-jekyll.md
    page.next : 下一篇文章  , 没有为nil
    page.previous : 上一篇文章  没有为 nil

通过site 和 page 可以完成对所有文章的遍历了。

    <!-- exampole -->
    <ul class="j-container">
        { % for post in site.posts %}
        <li class="j-row j-list-i">
            <h2 class="j-i-title"><a href="{ {site.baseurl}}{ {post.url}}">{ {post.title}}</a></h2>
            <p class="j-i-time">{ {post.date | date_to_string}}</p>
            <p class="j-i-tags">
                { %for tag in post.tags %}
                <span class="j-i-tag">{ {tag}}</span>
                { % endfor %}
            </p>
            <div class="j-container">
                <div class="j-row j-artclie-txt">{ {post.excerpt}}</div>
            </div>
        </li>
        { % endfor %}
    </ul>

2.文章分类

因为jekyll是没有后台的,所以不可能说像有后台的网站一样传递一个类别参数就可以返回指定的类别文章。 但是jekyll也可打到那种效果。 首先文章需要定义了categories参数。

1.每个分类写一个页面

这种方法可行,但纯属作死,有5个分类就要写5个,那100个就写100个,灵活度不够,而且难以维护。

2.通过给url带上一个参数

这种方法是可行的,我目前就是使用这种方式。

首先,不过自己需要写一段js代码去解析url获取到分类的参数

其次,可以使用 site.categories 获取所有的文章,并且通过js的JSON.parse转换成json对象。

最后,就是通过js渲染页面就可以了。

那么就牵涉到两个页面,第一分类列表页,第二分类文章输出页面。

1.分类输出

    <!-- exampole -->
    { % for category in site.categories %}
        <a href="{ {site.baseurl}}/category.html?category={ { category|first}}">{ {category | first}} <span class="j-class-i-num">({ {category | last | size}})</span></a>
    { % endfor %}

{ {site.baseurl}}/category.html?category={ { category|first}} 就是访问这个类别的url链接, 页面为根目录下的category.html , 参数 category 就是类别参数。

2.类别文章获取,渲染

category.html页面通过js获取category参数来获取到指定类别的数据

    //decodeURIComponent 是为了防止浏览器转义中文字体,然后获取不到。
    var category = decodeURIComponent(parseURL(document.location.href).params["category"]);
    var data = '{ { % for categorie in site.categories %}{ % if categorie[0] != site.categories.first[0] %},{ % endif %}"{ { categorie[0] }}":[{ % for post in categorie[1] %}{ % if post != categorie[1].first %},{ % endif %}{"url":"{ {post.url}}", "tags":{ {post.tags | jsonify }} , "content":"{ {post.excerpt | uri_escape}}" , "title":"{ {post.title}}","date":"{ {post.date | date:"%d/%m/%Y"}}"}{ % endfor %}]{ % endfor %} }';
    var arr = JSON.parse(data)[category];

可能你不明白 parseURL是什么,看词取义就是解析url链接。 这个是我自己写的一个解析url链接的函数。

    /**
     * [parseURL 解析url]
     * @param  {[String]} url [url]
     * @return {[Object]}     [返回解析好的对象]
     */
    function parseURL(url) {
        var a =  document.createElement("a");
        a.href = url;
        return {
            source: url,
            protocol: a.protocol.replace(":",""),
            host: a.hostname,
            port: a.port,
            query: a.search,
            params: (function(){
                var ret = {},
                    seg = a.search.replace(/^\?/,"").split("&"),
                    len = seg.length, i = 0, s;
                for ( ; i < len ; i++ ) {
                    if ( !seg[i] ) { continue; }
                    s = seg[i].split("=");
                    ret[s[0]] = s[1];
                }
                return ret;
            })(),
            file: (a.pathname.match(/\/([^\/?#]+)$/i) || [,""])[1],
            hash: a.hash.replace("#",""),
            path: a.pathname.replace(/^([^\/])/,"/$1"),
            relative: (a.href.match(/tps?:\/\/[^\/]+(.+)/) || [,""])[1],
            segments: a.pathname.replace(/^\//,"").split("/")
        };
    }

3.文章标签

文章标签主要的作用就是定位文章的信息点以及方向。比如有篇文章是属于前端开发,但前端有这么多内容那么就可以通过标签来细分这篇文章是主要讲哪个方面的信息。 添加标签很简单只要在每篇文章的头部添加tags标签即可,输出如下。

    { %for tag in post.tags %}
        <span class="j-i-tag">{ {tag}}</span>
    { % endfor %}

你是否会发现一个规律,凡是能用for输出的必定可以定义为数组,那就说明 categories 和 tags 参数都可以定义为数组。

4.文章输出

通过观察page变量所含的参数,就可以输出一篇文章的内容。

    <!DOCTYPE html>
    <html lang="zh-cmn-Hans">
    <head>
        { % include base.html %}
    </head>
    <body>
        { % include header.html %}
        <div class="j-container">
            <div class="j-row">
                <div class="j-col-xs-12 j-col-sm-12 j-col-md-9">
                    <div class="j-container j-content">
                        <h2 class="j-i-title"><a href="{ {site.baseurl}}{ {page.url}}">{ {page.title}}</a></h2>
                            <p class="j-i-time">{ {page.date | date_to_string}}</p>
                            <p class="j-i-tags">
                                { %for tag in page.tags %}
                                <span class="j-i-tag">{ {tag}}</span>
                                { % endfor %}
                            </p>
                            <div class="j-container">
                                <div class="j-row j-artclie-txt">{ {content}}</div>
                            </div>
                    </div>
                </div>
                { % include side.html %}
            </div>
        </div>
        { % include footer.html %}
    </body>
    </html>