博客 / 詳情

返回

一篇文章瞭解Liquid Template Engine 模版引擎 (Jekyll模版)

學習製作Jekyll模版,其實主要是學習Liquid語法。

參考:Liquid官方文檔。

就像PHP、ASP、Python等一切網絡動態語言一樣,Liquid也相當於一種獨立的動態語言,沒什麼大差別,基本功能都有。
説白了就是動態生成HTML,可以輸出變量,操作數組,調用外部數據,設置IF ELSE判斷,FOR循環等,這些都能達到。

開始講語法前,大概説明一下運行流程:

常用變量及屬性

參考:Jekyll 語法簡單筆記

site對象

site對象是全站都能調用的變量,全部都在_config.yml文件中定義。
常用變量如下:

  • site.pages: 所有`_
  • site.posts: 所有文章
  • site.categories: 所有的 categories
  • site.tags: 所有的 tags
  • site.related_posts: 從LSI Keywords提取出來最相關最新的10篇文章
  • site.collections: 所有集合(與posts邏輯很大不同,一般用來放members等特殊數據)
  • site.documents: 所有 collections 裏面的文檔
  • site.data: _data 目錄下的數據
  • site.[abc]: 自定義的變量(手動在_config.yml中指定)

page對象

  • page.content: 頁面的內容
  • page.title: 標題 (手動在Front Matters中指定)
  • page.excerpt: 摘要
  • page.url: 鏈接
  • page.date: 時間
  • page.id: 唯一標示
  • page.categories: 分類(手動在Front Matters中指定)
  • page.tags: 標籤(手動在Front Matters中指定)
  • page.path: 源代碼位置
  • page.next: 下一篇文章
  • page.previous: 上一篇文章

categories對象

site.categories列表中循環得到的是一個一個的category,其中包括這些屬性:

  • cat[0]: 返回cat的名稱
  • cat[0].size: 返回這個分類裏的文章數量
  • cat[1]: 返回一個post_list列表,包含這個category裏所有的post對象。
  • cat[1].size: 返回這個post_list列表中的對象數量。

tag對象

site.tags列表中循環得到的是一個一個的tag,其中包括這些屬性:

  • tag[0]: 返回tag的名稱
  • tag[0].size: 返回這個tags裏的文章數量
  • tag[1]: 返回一個post_list列表,包含這個tags裏所有的post對象。
  • tag[1].size: 返回這個post_list列表中的對象數量。

paginator對象

  • paginator.per_page: 每一頁的數量
  • paginator.posts: 這一頁的數量
  • paginator.total_posts: 所有文章的數量
  • paginator.total_pages: 總的頁數
  • paginator.page: 當前頁數
  • paginator.previous_page: 上一頁的頁數
  • paginator.previous_page_path: 上一頁的路徑
  • paginator.next_page: 下一頁的頁數
  • paginator.next_page_path: 下一頁的路徑

列表讀取(各種歸檔頁面用)

循環讀取Posts

讀取全站所有的posts:

{% for post in site.posts %}
    <h2> {{ post.title }} </h2>
    <h2> {{ post.url }} </h2>
    <h2> {{ post.category }} </h2> 
    <h2> {{ post.excerpt }} </h2>  ︎ 文章摘要,自動生成的
{% endfor %}

只讀取_posts/文件夾中某個category中的posts,
例如_posts/tech文件夾中放的是一些category為tech的文章,那麼讀取方式是:

{% for post in site.categories.tech %}
    <h2> {{ post.title }} </h2>
{% endfor %}

注意,在_posts中nested文件夾裏的文章,也必須在Front matter中指定分類,要不然讀不出來。

循環讀取categories

讀取全站所有的分類:

{% for cat in site.categories %}
    <h2> {{ cat[0] }} </h2>
{% endfor %}

讀取所有分類下的所有文章:

{% for cat in site.categories %}
    {% for post in cat[1] %}
        <h2> {{ post.title }} </h2>
    {% endfor %}
{% endfor %}

讀取某個分類下所有的文章:

{% for post in site.categories.blog %}
    <h2> {{ post.title }} </h2>
{% endfor %}

循環讀取tags

讀取全站所有的tags:

{% for tag in site.tags %}
    <h1> {{ tag[0] }} </h1>
{% endfor %}

讀取所有tags下的所有文章:

{% for tag in site.tags %}
    {% for post in cat[1] %}
        <h2> {{ post.title }} </h2>
    {% endfor %}
{% endfor %}

讀取某個tag下所有的文章:

{% for post in site.tags.math %}
    <h2> {{ post.title }} </h2>
{% endfor %}

讀取某category下所有文章並按tag分組讀取

{% for post in site.categories.Tech %}   ︎ 先讀取某分類下所有的文章
     {% assign tags = tags |concat: post.tags |uniq %}   ︎ 把每篇文章的tags存到列表裏,並刪除重複項
{% endfor %}

{% for tag in tags %}
    <h2> {{ tag }} </h2>   ︎ 循環輸出這個category中的所有tags
    {% for post in site.categories.calculus %}
        {% if post.tags contains tag %}      ︎ 循環判斷如果文章屬於此tag則顯示出來
            <h4> {{ post.title }} </h4>
        {% endif %}
    {% endfor %}
{% endfor %}

Post讀取

需要在MD文檔裏指定layout才能調用。比如文檔裏指定了layout: post,那麼系統就找到_layouts/post.html這個文件;如果文檔指定了layout: blog,那麼系統就會找到_layout/blog.html這個文件。
在layout裏面讀取post數據很簡單,不需要for循環,不需要if判斷,直接用post這個對象就行。因為系統已經把文章的數據傳過來了。

假如我們在_posts/xx.md文章的頭信息中,定義了這些數據:

---
layout: post
title: I'm a post
category: 'blog'
tags: ['jekyll', 'wordpress', 'blog']
---

(注:tags列表等,在yaml中可以用- tag['tag']表示,一樣的 )

以下就是這個post.html文件讀取post數據的方式:

<h2> {{ post.title }} </h2>
<h2> {{ post.category }} </h2>

<h2> {{ post.content }} </h2>

{% for tag in post.tags %}
    <h2> {{ tag }} </h2>
{% endfor %}

group_by 分組和where_exp條件篩選

官方的group_by做到了複雜查詢的功能,比如查找某個category下的全部文章並按tag分組顯示。
相對自己寫for/if實現來説,雖然官方提供了這個功能,但是你仔細閲讀文檔就會發現,這個group_by必須配合單獨的靜態的額外的文檔才能實現。
也就是説,你必須手動寫個mygroup.doc文件,一個一個指定每篇文章的分組、分類、順序等。
那實在太麻煩了。

參考官方:Navigation

user avatar cnzhwei 頭像 ray_learn 頭像
2 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.