一篇文章瞭解Liquid Template Engine 模版引擎 (Jekyll模版)
學習製作Jekyll模版,其實主要是學習Liquid語法。
參考:Liquid官方文件。
就像PHP、ASP、Python等一切網路動態語言一樣,Liquid
也相當於一種獨立的動態語言,沒什麼大差別,基本功能都有。
說白了就是動態生成HTML,可以輸出變數,運算元組,呼叫外部資料,設定IF ELSE判斷,FOR迴圈等,這些都能達到。
開始講語法前,大概說明一下執行流程:
常用變數及屬性
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 page.excerpt page.url page.date page.id page.categories page.tags 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
檔案,一個一個指定每篇文章的分組、分類、順序等。
那實在太麻煩了。