在 GitHub 上写博客
GitHub 有一个“内置”的简单内容管理系统,称为 Jekyll。它很不起眼;您可以将普通 HTML 文件放入您的网络空间,它们将按原样提供服务,或者您可以创建 Jekyll 文件,这些文件是文本文件,以 Jekyll 文档称为“front
GitHub 有一个“内置”的简单内容管理系统,称为 Jekyll。它很不起眼;您可以将普通 HTML 文件放入您的网络空间,它们将按原样提供服务,或者您可以创建 Jekyll 文件,这些文件是文本文件,以 Jekyll 文档称为“front matter”(文档中使用的短语,好像每个人都知道它的意思一样)的标题块开头。除其他外,Jekyll 允许您使用 Markdown 编写网页和博客文章。而且,由于它是 GitHub,因此您不会惊讶地得知您的网络空间由 Git 进行版本控制,这意味着您可以通过普通的 Git push 更新您的网站。
<style> .sidebox { border: 1px dotted rgb(127, 127, 127); padding: 4px 3px 4px 6px; // top right bottom left min-width: 100px ! important; float: right ! important; font-size: 90%; margin-top: 1px; margin-bottom: 1px; margin-left: 6px; visibility: visible; max-width: 50%; width: 35%; } </style>
GitHub 组织其网络空间的方式很不寻常;它基于项目相同存储库中的“孤立分支”,基本上是您已有的存储库的相同宇宙中的“平行宇宙”。这意味着您通常需要在同一台 PC 上两次克隆您的存储库,一次用于代码,一次用于您的网站,但您存储了这两个“部分”完整历史记录的两个副本。对我来说,这很奇怪。(理论上,您只需要克隆一次您的存储库,但那样的话,当您想编辑您的网站时,git 将不得不删除您整个源代码树。令人不安,不是吗?我为什么不能只在主分支的子文件夹中放置网站,比如 /www
呢?)
他们建议在您的本地计算机上安装Jekyll,以便能够预览您的网站,但在Windows上安装 Jekyll 是一件非常麻烦的事情。Jekyll gem 通常安装失败;您必须先安装名为 Ruby Installer DevKit 的东西。这里有一个提示,因为我花了一段时间才找到这个东西的下载链接。事实证明,DevKit 下载链接位于此页面上,在 Ruby Installer for Windows 的下载链接下方,标题为“Development Kit”。后来,我找到了在 Windows 上安装 Jekyll 的说明。但后来我在两台不同的 PC 上遇到了“yajl”和“wdm”的问题(参见边栏),其中一台 PC 仍然无法运行 GitHub 的(旧版)Jekyll。
rem If github still uses jekyll 1.5.1, the yajl version is v1.1.0
gem uninstall yajl-ruby
gem install yajl-ruby -v 1.1.0 --platform=ruby
在这种情况下,bundler 可能会与 Ruby-2.0.0 产生问题,所以如有疑问,请不要使用 bundler 启动 jekyll。最后,如果 jekyll 无法启动并显示“无法加载此文件 -- wdm”,请运行gem install wdm.在我终于让 Jekyll 完全正常工作并渲染了这个网站之后,我将其推送到 GitHub。GitHub 发来一封电子邮件,说我的网站“包含 markdown 错误”。什么错误?谁知道呢,他们没有告诉你!但当然,对我来说一切正常,那到底出了什么问题呢?于是我开始在新机器上安装 Jekyll,这次我小心翼翼地安装了 GitHub 的 Jekyll 版本(1.5.1),而不是最新版本,通过安装github-pagesgem 而不是普通的 jekyll gem。
在新机器上,我不得不解决几个启动 GitHub 版本 Jekyll 的错误——yajl 的错误,wdm 的错误——然后终于我被告知“转换 '_posts/2014-06-29-blogging-on-github.md' 时出错。”(即,这篇帖子)。这让我说到了 Jekyll 最糟糕的一点:糟糕的错误处理。一个页面的错误通常会使整个网站崩溃(尽管在这种情况下没有),如果连文件名都拿不到,你就很幸运了。那么是什么导致了这个新错误消息呢?代码块。每个代码块都会在我的机器上导致“转换错误”。什么类型的错误?哈哈,好像 Jekyll 会告诉你你一样。
于是,我绝望地在另一台机器上安装了 github-pages,并在调用 jekyll 时,通过运行以下命令强制使用版本 1.5.1jekyll _1.5.1_而不是jekyll。在再次遇到有关 `yajl` 和 `wdm` 的错误并修复它们之后,错误堆栈跟踪变成了涉及pygments/mentos.rb, line 303, in start.
通过逐节删除我的帖子中的文本,我终于找到了问题:我写了~~~none来禁用语法高亮,而我应该使用~~~text.
一切正常后,Jekyll 仍然被证明是不稳定的。有时它在启动时会吐出几个错误,最后一个是jekyll 2.1.0 | Error: no implicit conversion of true into String.
解决方案:只需再次运行 Jekyll,然后希望它这次能正常工作。
总之,请参阅GitHub 的官方安装说明。
Jekyll 的文档是颠倒的。介绍性页面首先给出了所有次要细节;关键信息稍后出现。例如,直到第八部分,他们才最终告诉您如何添加博客文章。但这还不够,您还需要知道如何为您的博客创建一个“主页”和一个“历史记录页”,而他们一开始只提供了一个不完整的历史记录页模板。此外,任何好的网站都应该在每个页面上都有分类链接(例如,主页、博客、文档、代码),但直到文档的深处,他们才给您任何关于设置这些的线索。关于样式和主题呢?在文档中,我还没有看到任何关于这方面的内容。
相反,似乎一个更好的开始使用 Jekyll 的方法是使用Jekyll Bootstrap。快速入门页面准确地告诉您如何设置它,并且它比 Jekyll 文档更好地解释了 Jekyll 是什么以及它是如何工作的。然后,“使用主题”告诉您如何设置主题(因为默认主题是……嗯,它有大红色的标题!不是我的风格),一旦您解决了这两件事,您就可以在您网站的 _posts
文件夹中开始写博客了。
主题的另一个来源是这个网站。尽管这些其他主题不是为在 Jekyll Bootstrap 框架内工作而设计的,但如果您熟悉 Web 的构建块(HTML/CSS)和 Jekyll(基本上是一堆放在带有“front matter”的文件夹中的代码片段),您应该能够弄清楚如何安装其中一个主题。
但是,还有一个用于主题化 Jekyll 的框架叫做Poole,两个可用的主题不仅看起来不错,而且对各种浏览器尺寸的缩放效果也很好。移动端?是的。我通过 Joshua Lande 的一篇有用的博文了解到 Poole。
所以,一旦您弄清楚如何安装 Jekyll 和一个主题,并且您已经写了一篇虚拟博客文章和/或网页,您就会想要预览它,这意味着运行 Jekyll。我的 Jekyll 网站在我 PC 的 Loyc-web 文件夹中,我希望将预览网站输出到 Loyc-preview 文件夹中。所以我制作了一个批处理文件(shell 脚本),它位于 Loyc-web 文件夹旁边,其中包含此命令
jekyll serve --drafts --watch --source Loyc-web --destination Loyc-preview
注意:此帖子中的代码块被 CodeProject 弄乱了。请参阅原始文章以获取正确的代码。
serve
(而不是 build
)会导致它在 https://:4000
上提供预览,--drafts
要求 Jekyll 将未发布的草稿渲染为已发布的内容,而 --watch
会导致预览根据更改自动更新(这在我的其中一台 PC 上有效,但在另一台 PC 上无效,我不知道为什么)。默认的 --destination
是源文件夹内的 _site
。并且不要将您的批处理文件命名为 jekyll.bat
,像我一样。您不会喜欢结果的……
一旦我对我的网站满意,我就会推送到 GitHub,然后我就可以上线了!
语法高亮失败
在 Windows 上,您需要进行一堆额外的安装步骤来安装“pygments”,以便支持最广泛的语言的语法高亮,但使用“Rouge” invece 更容易。我发现,如果您既没有安装 Pygments 也没有安装 Rouge,那么当 Jekyll 遇到请求语法高亮的页面时,它会崩溃并显示一条奇怪的消息
Liquid Exception: cannot load such file -- yajl/2.0/yajl in _posts/2014-01-01-example.md
C:/Dev/Ruby200/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require':
cannot load such file -- yajl/2.0/yajl (LoadError)
不,Jekyll 在错误消息方面做得不好。要快速解决这个问题,
- 安装 Rouge:
gem install rouge
- 如果存在,请从您的
_config.yml
中删除pigments
选项 - 添加此选项:
highlighter: rouge
- 如果适用,在更改
_config.yml
时重新启动jekyll serve
要创建代码块,Jekyll 建议使用 {%...%}
块,如下所示
{% highlight cpp %}
// Code
{% endhighlight %}
但这当然不是标准的 Markdown 代码。我想用 Markdown 语言写帖子,而不是 Jekyll;我应该能够使用标准的“围栏”
~~~cpp
// Code
~~~
但默认情况下,围栏不支持语法高亮。要启用此功能,请通过在 _config.yml 中设置 markdown
选项,将您的 Markdown 解析器从“kramdown”更改为“redcarpet”
markdown: redcarpet
用于围栏的名称通常比文件扩展名长。例如,~~~cs
不会被识别为 C#,您必须使用 ~~~csharp
,而 ~~~yml
不会被识别为 .yml
,您必须使用 ~~~yaml
。使用 ~~~text
来确保不发生语言自动检测(尽管 GitHub 的旧版 Jekyll 不会这样做)。
不幸的是,redcarpet 和 kramdown 具有不同的高级功能集。Kramdown 对我来说似乎更灵活,但 redcarpet 似乎是标准 GitHub Flavored Markdown。
更新:自 8 月 1 日起,提交使用 rouge
的 _config.yml
会导致 GitHub 上出现“页面构建失败”,并显示误导性的错误消息,例如“文件 _posts/2014-08-01-blah.md
包含语法错误。” 在提交和推送之前,您必须在 _config.yml
中设置 highlighter: pygments
,即使您不想在本地安装 pygments。
专业提示:Jekyll 不会让您轻易编写文字字符组合 {%
或 {{
,即使在代码块内也是如此。您可以分别编写 {{"{%"}}
或 {{ "{{" }}
,但如果您不打算使用 Liquid(Jekyll 的模板结束符),一个更好的选择是在 front-matter 之后将整个页面包装在 {% raw %} ... {% endraw %}
中,就像我在本帖中所做的那样。不过,有一个问题:您不能使用Jekyll 内部链接。
我如何设置这个网站
我决定使用基于 Poole 的“Hyde”主题,所以我从 GitHub 下载了hyde-master.zip
。提供的使用说明有点令人困惑且不完整,所以我写了这个,希望有所帮助。我在仅适用于 Poole 或 Hyde 的问题前面加上了“(Hyde)”前缀。
-
早些时候,我使用 GitHub 的“自动页面生成器”生成了我的 index.html。这个东西不仅生成
index.html
,还生成了一堆 css 文件、图像和 javascript 文件,以及根目录下的一个名为params.json
的文件,其中包含您为index.html
提供的内容的描述,包括页面文本。由于“Hyde”使用的文件夹结构与“自动页面生成器”不同,并且不共享任何相同的 CSS,所以我想如果我同时保留两者会让我感到困惑……所以我删除了 GitHub 生成的所有内容,例如css
文件夹、images
文件夹、params.json
(其内容与我的 README 相同)、_includes/header.html
、_includes/footer.html
以及index.html
本身。 -
(Hyde) 解压
hyde-master.zip
后,我将大部分内容复制到我的gh-pages
工作副本中,不包括 .gitignore、_config.yml、README.md、CNAME、README.md、LICENSE.md(以免与我的网站内容的许可证混淆)以及 _posts 文件夹。 -
(Hyde) Hyde 要求
_config.yml
中存在以下选项title: "Project Name" # shown in large text description: "Blah blah blah" # shown under the title tagline: "Blah blah blah" # shown in title bar beside the title version: "1.2.3" # "Currently v1.2.3" url: "http://loyc.net" # Used by the Atom feed baseurl: "" # URL of site relative to domain github: repo: https://github.com/user/Proj # "GitHub project" link on sidebar
其他主题也使用
title
、description
、baseurl
以及可能的其他选项。以下是一些 Jekyll 本身识别的设置,您可能也需要# Jekyll settings: markdown: redcarpet encoding: UTF-8 highlighter: pygments # rouge now causes Page Build Failure on GitHub paginate: 10 # blog posts per page paginate_path: "blog/page:num" # optional, see below safe: true lsi: false
-
(Hyde) 如果您想让
baseurl
指向域的根目录,那么baseurl
选项会带来问题。Jekyll
文档暗示在这种情况下您应该使用 "",并提供了与 "/" 不兼容的示例代码;例如,这段代码在 Jekyll 站点模板中(Ruby200\lib\ruby\gems\2.0.0\gems\jekyll-2.1.0\lib\site_template
)<ul class="posts"> {% for post in site.posts %} <li> <span class="post-date">{{ post.date | date: "%b %-d, %Y" }}</span> <a class="post-link" href="{{ post.url | prepend: site.baseurl }}">{{ post.title }}</a> </li> {% endfor %} </ul>
出于某种原因,如果 baseurl 是 "/",这会产生错误的链接。但是 Hyde 会在
/_includes/head.html
中使用原始连接而中断,如果 baseurl 为 "/"。<link rel="stylesheet" href="{{ site.baseurl }}public/css/poole.css"> <link rel="stylesheet" href="{{ site.baseurl }}public/css/syntax.css"> <link rel="stylesheet" href="{{ site.baseurl }}public/css/hyde.css">
请注意,在“
public
”前面需要一个斜杠。为了解决这个问题,我将 Hyde 的所有 HTML 文件中{{ site.baseurl }}
的所有实例更改为{{ site.baseurl }}/
(确保替换所有实例!)。也许如果您不在域的根目录,也会出现同样的问题;也就是说,如果您的网络空间位于
username.github.io/projectname
。在这种情况下,Jekyll 希望baseurl
是projectname,而 Hyde 期望是projectname/。 -
默认情况下,主页(
index.html
)仅按时间顺序显示您的博客文章。我不想让博客成为主页,所以我将index.html
重命名为blog.html
(为其设置 front-matterlayout: page
和title: Blog
),但这导致所有博客文章消失!Jekyll 在此有一个奇怪的限制:您只允许在一个页面上显示您的博客,并且该页面必须命名为index.html
。但是,如果您在_config.yml
中添加一行paginate_path: "blog/page:num"
,则可以使用/blog/index.html
。 -
(Hyde) 默认情况下,侧边栏列出了所有在其 front-matter 中使用
layout: page
选项的页面(在_includes/sidebar.html
中可以看到执行此操作的 for 循环),并且title: ...
选项用作链接文本。之后有一个“下载”链接、“GitHub 项目”链接和一个版本号。我不想显示“下载”链接、版本号或“保留所有权利”,所以我从_includes/sidebar.html
中删除了这些部分。当然,如果您不喜欢链接的自动生成方式,您可以更改代码以适应您。 -
我创建了
index.md
并写入了一些内容--- layout: default title: Home --- # Welcome! This is the home page!
-
我将我的
.sidebox
类添加到sidebar.html
(参见下面的使用自定义 CSS) -
(Hyde) 我通过将
/_layouts/default.html
中的<body>
更改为<body class="theme-base-0d">
来切换到不同的预设颜色方案。 -
(Hyde) 我编辑了
/public/css/hyde.css
以根据我的喜好调整主题。特别是,我减小了各种margin-left
和margin-right
值,稍微缩小了字体,并调整了侧边栏的颜色。由于这个博客包含代码(哪个 GitHub 博客不包含代码?),宽边距会导致每个代码片段出现滚动条或换行,我们不希望那样。 -
在博客顶部,我制作了一个“所有帖子列表”链接,指向
blog-list.html
--- layout: default title: Blog index --- <h1>Blog index</h1> <div class="home"> <ul class="posts"> {% for post in site.posts %} <li> <span>{{ post.date | date: "%b %-d, %Y" }}</span>: <a class="post-link" href="{{ post.url | prepend: site.baseurl }}">{{ post.title }}</a> </li> {% endfor %} </ul> <p class="rss-subscribe">subscribe <a href="{{ "atom.xml" | prepend: site.baseurl }}">via Atom</a></p> </div>
-
(Hyde) 如果您有足够多的博客文章导致分页,Hyde 会多次显示“博客”链接,每个页面一个!事实证明这有点难修复;过了一会儿,我意识到 Jekyll,或者更具体地说Liquid,不支持 Ruby 表达式。事实上,它几乎不支持任何表达式!看看:Liquid 总共只有 9 个运算符。甚至没有
not
运算符,也没有正则表达式匹配(或者如果有,它实现的方式不是运算符)。总之,不需要的页面仍然可以过滤掉,尽管精度不如我习惯的。在_includes/sidebar.html
中,我更改了这段代码{% assign pages_list = site.pages %} {% for node in pages_list %} {% if node.title != null %} {% if node.layout == "page" %} <a class="sidebar-nav-item{% if page.url == node.url %} active {% endif %}" href="{{ node.url }}">{{ node.title }}</a> {% endif %} {% endif %} {% endfor %}
通过添加一个
unless
语句{% assign pages_list = site.pages %} {% for node in pages_list %} {% if node.title != null and node.layout == "page" %} {% unless node.url contains '/page' %} <a class="sidebar-nav-item{% if page.url == node.url %} active {% endif %}" href="{{ node.url }}">{{ node.title }}</a> {% endunless %} {% endif %} {% endfor %}
-
(Hyde) Older 和 Newer 按钮的链接断了,因为它们假设博客是主页。而且,您知道,我做了很多小的修改和修复,我不会一一列出。我只想说,您可以克隆我的存储库并将其据为己有,如果您愿意的话。
写博客文章
在 Jekyll 中写博客文章很容易。只需在 /_posts
文件夹(如果您使用的是 GitHub,则在您的 gh-pages
分支中)创建一个文本文件,并给它一个类似 2014-12-31-file-name.md
的名称,当然要加上正确的日期。在文件内,添加 front matter
---
title: Title of your blog post
layout: post
---
The content of the post goes here.
Jekyll 将输出的 HTML 放在 2014/12/31/file-name.html
中,或者如果您的网站在 _config.yml
中使用了 permalink: pretty
选项,则放在 2014/12/31/file-name/index.html
中。
如果您想通过省略日期的一部分来获得更短的 URL,请在 _config.yml
中更改 permalink
选项。例如,我使用这个
permalink: /:categories/:year/:title.html
或者在此处查看(为什么称之为“permalink”,而您可以在任何时候更改 URL 模式?)
注释
虽然 Jekyll 支持博客,但它作为博客引擎并不完整,因为它严格设计用于提供静态内容,而评论不是。而且在 GitHub Pages 中没有办法直接添加评论,因为 GitHub 不提供存储评论的地方。但是,仍然可以使用第三方提供的评论服务,例如 Disqus。Disqus 会添加广告来赚钱,不过。烦人的广告。带图片的。
Jekyll Bootstrap 目前支持四种评论引擎,包括 Disqus,但我不确定我是否信任这些商业实体来管理我的评论……尽管,呃,这个博客上很少有人留下评论。
希望 GitHub 本身将来会提供一个评论引擎,因为 GitHub 网站显然对评论的支持非常好。不过好消息!可以将 GitHub 问题跟踪器用于管理博客评论!技术在此处进行了描述,我决定使用它!评论也不必仅限于博客文章,我可以将它们放在我想要的任何页面上,尽管这需要一些额外的努力。
如何设置
-
将配置添加到
/_config.yml
github: user: qwertie project: loyc
-
在
_layouts/default.html
中,在内容下方包含comments.html
... {{ content }} {% include comments.html %} </div> </body>
-
将我复制的
comments.html
未经更改地添加到您的/_includes
文件夹中,并将comments.css
未经更改地添加到/res/css
(哦,您没有/res/css
文件夹?要么创建该文件夹,要么将comments.css
放在您喜欢放置 css 文件的任何地方,然后更改comments.html
以指向新位置。) -
要在页面上添加评论,请在您的 github 项目中创建一个问题(使用您想要的任何名称和描述),然后将博客文章 front matter 中的
commentIssueId
行设置为匹配该问题--- layout: post title: "Blogging on GitHub" commentIssueId: 42 ---
-
Ivan 说您还必须注册一个“OAuth 应用程序”,所以我为
loyc.net
注册了,但当我查看localhost:4000
上的 Jekyll 预览时,评论仍然有效。
在 Markdown 中使用自定义 CSS
有时我喜欢在我的帖子中放置侧边栏,我称之为 CSS 中的“.sidebox”,因为有些网站已经有一个“.sidebar”类来描述主侧边栏
<style>
.sidebox {
border: 1px dotted rgb(127, 127, 127);
padding: 4px 3px 4px 6px; /* top right bottom left */
min-width: 100px ! important;
float: right ! important;
font-size: 90%;
margin-top: 1px;
margin-bottom: 1px;
margin-left: 6px;
visibility: visible;
max-width: 50%;
width: 35%;
}
</style>
嘿,看这里!
这是一个侧边栏。Markdown 支持 HTML,所以您可以将一个样式块添加到 .md
文件顶部或共享的 _includes\head.html
文件中,然后像这样使用它
<div class="sidebox">This is a <i>sidebar</i>.</div>
请注意,<div>
标签内的所有文本都被视为 HTML,而不是 Markdown。在 kramdown 中,您也可以在段落后面使用“块属性” {: .sidebox}
来创建侧边栏,或者使用“refdef”,它允许侧边栏包含多个段落。这两种方法都更好,因为您可以在侧边栏中使用 Markdown 语法……但也很糟糕,因为只有 kramdown 会理解您的代码。
访问者数据
我正在使用Google Analytics 来跟踪页面浏览量。注册后,您将获得一个 JavaScript 代码段,用于放在您的网页中;我将其插入到 /layouts/default.html
的 </body>
之前。
目录生成
Kramdown 有一个用于自动生成目录的功能,适用于像本文这样长的帖子。可惜我没有使用 Kramdown,所以我无法使用它。JavaScript 解决方案更通用,但当我搜索解决方案时,我没有立即找到满意的。所以我自己制作了JavaScript 目录生成器。
处处皆 Markdown
顺便说一句,无论您是否使用 GitHub 或 Jekyll,现在都没有必要用 HTML 编写网站了。无论您的网络托管服务提供商有多差劲,无论您是否允许运行脚本,您仍然可以编写 Markdown 页面,这要归功于一个名为mdwiki的巧妙库。这个东西使用 JavaScript 将 markdown 转换为 HTML,100% 在客户端完成,所以您不必担心您的网络主机可能支持什么或不支持什么。在 GitHub 上,您不妨使用 Jekyll,但我必须承认,mdwiki 看起来拥有出色的功能集,可能比我用 Jekyll 获得的更好。但重要的是,我不再需要编写 HTML 了。再见!
您甚至可以在没有 Web 服务器的情况下使用 MDWiki,如果您在 Firefox 中查看 mdwiki.html
(它在 Google Chrome 中无效),这意味着您可以将其用于离线 Markdown 预览(这很棒,因为,至少在 Windows 上,编辑 Markdown 的工具通常非常有限。)
发布于