學習製作Jekyll模版,其實主要是學習Liquid語法。
參考:Liquid官方文檔。
就像PHP、ASP、Python等一切網絡動態語言一樣,Liquid也相當於一種獨立的動態語言,沒什麼大差別,基本功能都有。
説白了就是動態生成HTML,可以輸出變量,操作數組,調用外部數據,設置IF ELSE判斷,FOR循環等,這些都能達到。
開始講語法前,大概説明一下運行流程:
常用變量及屬性
參考:Jekyll 語法簡單筆記
site對象
site對象是全站都能調用的變量,全部都在_config.yml文件中定義。
常用變量如下:
site.pages: 所有`_site.posts: 所有文章site.categories: 所有的 categoriessite.tags: 所有的 tagssite.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