一、從零開始搭建自己的靜態部落格 -- 基礎篇
目錄
- 1. 準備環境
- 2. 新建專案
- 3. 第一篇博文
- 4. 修改配置檔案
- 5. 本地構建和訪問
- 6.
markdown
解析異常- 6.1.
Markdown
包的實現機制 - 6.2.
pelican
預設使用的Markdown
擴充套件 - 6.3. 向第三方擴充套件尋求幫助
- 6.4. 解決問題
- 6.1.
- 7. One more thing
前幾天心血來潮,想要在
GitHub Pages
上搭建一個靜態部落格;之前,我也曾基於Django
開發過自己的部落格,並買了雲主機部署,但是訪問量感人,慢慢自己也不打理了,就把雲主機退訂了(去吃噸好的~~~);雖然搭建靜態部落格很簡單,但是也想記錄一下,如果恰好能對你有所幫助或啟發,那我也覺的很開心了。
搭建靜態部落格的工具多種多樣,即有流行的WordPress,也有GitHub Pages
官方推薦的Jekyll;其實,選用哪種工具不重要,關鍵是一步步的理解它,遇到問題、解決問題的思路和過程;
因為我本人對Python
比較熟悉,所以我選用基於Python
開發的pelican,它基本滿足我的需求:
- 支援
markdown
的格式; - 提供自動化構建;
- 足夠的主題庫和外掛庫,並且支援定製化;
- ...
本文主要涉及pelican
的基本使用方法,最終在本地搭建一個簡陋的部落格網站;
1. 準備環境
選定工作目錄,並使用pipenv建立一個虛擬環境:
λ mkdir pelican-blog
λ cd pelican-blog
# 建立基於 Python 3 的虛擬環境
λ pipenv install --three
# 檢視虛擬環境中的 Python 版本
λ pipenv run python --version
Python 3.7.3
在虛擬環境中安裝必要的包:
λ pipenv install Markdown pelican # 檢視包之間的依賴關係 λ pipenv graph Markdown==3.1.1 - setuptools [required: >=36, installed: 41.6.0] pelican==4.2.0 - blinker [required: Any, installed: 1.4] - docutils [required: Any, installed: 0.15.2] - feedgenerator [required: >=1.9, installed: 1.9] - pytz [required: >=0a, installed: 2019.3] - six [required: Any, installed: 1.13.0] - jinja2 [required: >=2.7, installed: 2.10.3] - MarkupSafe [required: >=0.23, installed: 1.1.1] - pygments [required: Any, installed: 2.4.2] - python-dateutil [required: Any, installed: 2.8.1] - six [required: >=1.5, installed: 1.13.0] - pytz [required: >=0a, installed: 2019.3] - six [required: >=1.4, installed: 1.13.0] - unidecode [required: Any, installed: 1.1.1]
2. 新建專案
pelican
提供了一個命令列工具:pelican-quickstart
,能夠讓我們快速地新建一個網站專案;
它在執行的過程中,會互動式的詢問一些配置項,如果你現在還不能確定的話,那就大膽的使用預設值吧,後面還可以在配置檔案中修改;
命令執行完成後,它會在我們的專案中新建如下的目錄和檔案:
.
├── content # 目錄,存放原始博文和相關靜態檔案
├── output # 目錄,存放構建後的網站原始碼
├── Makefile
├── pelicanconf.py # 構建相關的配置檔案
├── publishconf.py # 釋出相關的配置檔案
└── tasks.py
其中,content/
目錄存放所有的markdown
格式的文字,我們還可以再新建一個content/images/
的子目錄,用於存放所有的圖片;
注意:
在自動構建的過程中,
content/images/
中的檔案會被無損地拷貝到output/images/
中,通過修改pelicanconf.py
檔案中STATIC_PATHS
的配置項(預設值為['images']
)可以改變這種行為;
3. 第一篇博文
現在我們在content/
目錄下新增第一篇markdown
格式的文章,就以本文為例;
pelican
可以很“聰明”地從文章的元資料中提取需要的資訊,所以我們以特定的格式編寫文章的開頭:
Title: 一、從零開始搭建自己的靜態部落格 -- 基礎篇
Date: 2019-11-21 14:37
Modified: 2019-11-22 11:09
Category: 工具
Tags: pelican
Author: luizyao
Slug: pelican-blog-chapter-1
Summary: 本文簡要的介紹 pelican 的基本用法
Status: published
<開始正文>
注意:
更多元資料以參考:https://docs.getpelican.com/en/stable/content.html#file-metadata;
如果你使用
VSCode
作為你的日常開發工具,那麼我建議你使用psioniq File Header外掛為不同型別的檔案自動生成頭資訊模版;
4. 修改配置檔案
在正式開始構建之前,我們需要完善一下配置檔案pelicanconf.py
:
# pelicanconf.py
# 修改時區
TIMEZONE = 'Asia/Shanghai'
# 新增一個 GitHub 的“絲帶”連結
GITHUB_URL = 'https://github.com/luizyao'
# 修改社交賬號的展示
SOCIAL = (
('GitHub', 'https://github.com/luizyao'),
)
# 修改預設的時間格式('%a %d %B %Y')
DEFAULT_DATE_FORMAT = "%Y-%m-%d %H:%M"
# 為元資料定義預設值
DEFAULT_METADATA = {
# 預設釋出的文章都是草稿,除非在文章元資料中明確指定:Status: published
'status': 'draft',
}
5. 本地構建和訪問
我們通過以下命令構建網站並自動適配檔案的修改,通過http://localhost:8000訪問:
λ pipenv run pelican --autoreload --listen content/
注意:
不要忘記把文章元資料中的
Status: draft
改成Status: published
,不然我們是看不到這篇文章的;
pelican
預設使用notmyidea
這個主題來構建網站;你可以通過pelican-themes
命令檢視已安裝的主題:λ pipenv run pelican-themes --list notmyidea simple
然後通過在
pelicanconf.py
中設定THEME = 'simple'
或者構建時傳入-t 'simple'
選項來使用主題simple
,實際上和純文字差不多了;
6. markdown
解析異常
這是一個列表:
if 1: print('這是一段python程式碼')
這個時候,如果你訪問我們的網站,你會發現上面的markdown
程式碼被展示成下面的形式,根本就不是我們想要的縮排程式碼塊的效果:
為什麼會這樣呢?我們又該如何解決這個問題?
6.1. Markdown
包的實現機制
pelican
使用Markdown包作為markdown
文字的直譯器,這個包嚴格實現了John Gruber’s Markdown語法,並提供一些擴充套件;
John Gruber
是markdown
語法的發明者,他在2004
釋出了第一個版本的markdown
語法,這一版本的語法有著明顯的特點:
- 不支援三個反引號(
'```'
)包裹程式碼的寫法; - 不支援表格;
- 定義了嚴格的巢狀縮排的格式,必須是
4
個空格; - ...
雖然自從釋出了第一版之後,就再也沒有更新過,但是現在流行的各種markdown
語法都是基於它的擴充套件和補充,例如:GitHub Markdown、PHP Markdown等;
注意:
雖然
Markdown
包嚴格實現了John Gruber’s Markdown
語法,但是具體的實現還是有一些差別的,更多細節可以參考:https://python-markdown.github.io/#differences
6.2. pelican
預設使用的Markdown
擴充套件
上一節中我們提到,Markdown
包同樣提供一些擴充套件用於解析更多型別的語法,這些擴充套件又分為官方擴充套件和第三方擴充套件;
通過查閱pelican
的原始碼(或官方文件),可以看到其預設使用了以下擴充套件:
# pelican/settings.py
'MARKDOWN': {
'extension_configs': {
'markdown.extensions.codehilite': {'css_class': 'highlight'},
'markdown.extensions.extra': {},
'markdown.extensions.meta': {},
},
'output_format': 'html5',
},
首先,我們看一下markdown.extensions.extra擴充套件:
它主要實現了大多數PHP Markdown
的語法,是其它6
個擴充套件的合集:
擴充套件 | 文件 | 描述 |
---|---|---|
Abbreviations | https://python-markdown.github.io/extensions/abbreviations/ | |
Attribute Lists | https://python-markdown.github.io/extensions/attr_list/ | |
Definition Lists | https://python-markdown.github.io/extensions/definition_lists/ | |
Fenced Code Blocks | https://python-markdown.github.io/extensions/fenced_code_blocks/ | 擴充套件了程式碼塊的寫法 |
Footnotes | https://python-markdown.github.io/extensions/footnotes/ | |
Tables | https://python-markdown.github.io/extensions/tables/ | 支援表格 |
我們重點看一下Fenced Code Blocks
,因為它支援了我常用的三個反引號包裹程式碼塊的寫法:
GitHub‘s backtick (```) syntax is also supported:
# more python code
然後,我們再看一下markdown.extensions.codehilite擴充套件:
它基於Pygments包為我們提供了程式碼的高亮顯示,我們主要看一下它的一些可配置選項:
linenums
:如果置為True
,將會為程式碼塊每行標上行號;css_class
:為<div>
標籤加上class
屬性,預設是codehilite
;在這裡,pelican
使用的是highlight
;
最後,我們看一下markdown.extensions.meta:
它主要是pelican
內部使用,還記得我們每個markdown
文字的開頭都要有特定的格式嗎?就是通過這個擴充套件讀取的;感興趣的同學可以自己去看一下,這裡我們就不多說了;
6.3. 向第三方擴充套件尋求幫助
看到現在,我們也沒有找到想要的解決方案:對列表裡縮排巢狀反引號包裹的程式碼塊,進行正確的渲染;
還好我們還有眾多的第三方擴充套件供我們使用:https://github.com/Python-Markdown/markdown/wiki/Third-Party-Extensions
我們找到一個pymdownx.extra的擴充套件貌似可以代替markdown.extensions.extra
,來一起看一下吧:
它和markdown.extensions.extra
大部分是一樣的,只是有以下不同:
- 新包含了BetterEm擴充套件:優化粗體和斜體的展示(不關心);
- 新包含了ExtraRawHTML擴充套件:增加了對原始
HTML
程式碼的處理(不關心); - 使用SuperFences擴充套件代替
Fenced Code Blocks
:加強版的markdown
語法解析(看來正式我們想要的);
其實,看到
SuperFences
文件的第一句話,我就知道妥了,嘻嘻;Allowing the nesting of fences under blockquotes, lists, or other block elements (see Limitations for more info).
文件的內容很豐富,我們就不再這裡一一解釋了,有興趣的同學可以自己去看一看,說不定有什麼意外的收穫呢!!!
6.4. 解決問題
現在,我們來實際解決這個問題:
安裝必要的包:
λ pipenv install pymdown-extensions
修改
pelicanconf.py
檔案中MARKDOWN
的預設配置:# 使用第三方擴充套件來增強對 markdown 語言的解析,但是首先要安裝 pymdown-extensions 模組 MARKDOWN = { 'extension_configs': { 'markdown.extensions.codehilite': {'css_class': 'highlight'}, 'pymdownx.extra': {}, 'markdown.extensions.meta': {}, }, 'output_format': 'html5', }
7. One more thing
我在瀏覽SuperFences
文件時,發現一個很有意思的章節:https://facelessuser.github.io/pymdown-extensions/extensions/superfences/#code-highlighting;
它推薦了pymdownx.highlight代替markdown.extensions.codehilite
,那我們就來看看這到底是個什麼鬼?
在它的文件中有一句話大概能說明兩者的關係:
The Highlight extension is inspired by CodeHilite, but differs in features. PyMdown Extensions chooses not to implement special language headers for standard Markdown code blocks like CodeHilite does; PyMdown Extensions takes the position that language headers are better suited in fenced code blocks.
更多實現上的細節,我們不再去深究,主要看看我們可以用來幹什麼?
比如,為程式碼塊每行加上行號:
咦?markdown.extensions.codehilite
也可以啊,它不是也有一個linenums
的選項嗎?置成True
不就行了;
說的對,不過醜。
一般情況下,為程式碼塊新增行號有兩種樣式:
table
:預設的樣式,建立一個表,第一列是行號;inline
:在每行程式碼的開頭,但是複製程式碼會把行號一起復制,不方便;
不過,pymdownx.highlight
提供了第三種樣式:pymdownx-inline
,它和inline
很像,只是複製時不會加上行號,因為實際上把行號元素渲染成下面這樣:
<span class="lineno" data-linenos="1 "></span>
然後,我們通過以下的CSS
樣式去“啟用”它:
[data-linenos]:before {
content: attr(data-linenos);
}
下面,我們來將它具體的應用到我們的專案中吧:
首先,修改pelicanconf.py
檔案中MARKDOWN
的預設配置:
# 使用第三方擴充套件來增強對 markdown 語言的解析,但是首先要安裝 pymdown-extensions 模組
MARKDOWN = {
'extension_configs': {
'pymdownx.highlight': {
'css_class': 'highlight',
'linenums': True,
'linenums_style': 'pymdownx-inline',
},
'pymdownx.extra': {},
'markdown.extensions.meta': {},
},
'output_format': 'html5',
}
然後,在output/theme/css/main.css
檔案的末尾加上下面這段程式碼:
[data-linenos]:before {
content: attr(data-linenos);
}
最後重啟下服務,就能看到效果了:
注意:
這裡有個問題,如果我們重新執行構建命令,
output/theme/css/main.css
檔案又會被覆蓋成原先的內容,我們這個效果就看不到了;不過這並不是我們最終的方案,所以我們也不在這裡繼續深究了。
GitHub:https://github.com/luizyao/pelican-blog/tree/chapter-1