用 Org Mode 建立你的网站

介绍

Org 模式的发布系统是其最有用的功能之一。它允许您将 Org 文件转换为许多其他格式,包括HTML、PDF、LaTeX 等。

在这个视频中,我将向您展示如何利用 Org 模式的HTML发布功能生成一个简单但外观漂亮的网站!

如果你觉得这个指南有帮助, 请考虑通过链接 帮助 页 支持系统工匠!

开始入门

要开始,我们需要一个地方放置我们将用于生成网站的所有代码以及将提供网站内容的 .org 文件。

我们将创建一个名为 my-org-site 的文件夹,其中包含一个名为 content 的子文件夹,其中包含一个名为 index.org 的文件。这将创建一个名为 index.html 的文件,它将是我们网站的主页!

您在其中放置的 .org 文件可以非常简单,就像我将向您展示的那个。现在暂时不要在其中放置任何代码块,我们将在本视频的稍后部分介绍这一点。

我们在本集中要做的大部分工作只需要 Emacs 版本24.5或更高版本,其中内置了 Org 模式包。

创建文件夹结构:

my-org-site/ └── content/ └── index.org

创建构建脚本

现在我们将创建一个 Emacs Lisp 脚本,通过运行单个 shell 命令来生成您的 Org 文档的HTML文件。

我们将称之为 build-site.el :

;; 加载发布系统
(require 'ox-publish)

(message "构建完成!")

我们还需要一个可以运行我们的 Emacs Lisp 脚本的 shell 脚本。我们将称之为 build.sh:

#!/bin/sh
emacs -Q --script build-site.el

不要忘记使用 chmod +x build.sh 使脚本可执行!

my-org-site ├── build.sh ├── build-site.el └── content └── index.org

*注意:*如果您使用 Windows,可以创建一个 build.cmd 文件以相同的方式调用 Emacs。

-Q 参数可防止 Emacs 加载您自己的 Emacs 配置,这将有助于确保一旦我们准备开始发布此站点,此相同的脚本可以在其他机器上干净地执行。

设置发布项目

现在我们有了基本的脚本,我们可以为我们的网站设置 Org 发布配置。

我们将以下代码片段添加到 build-site.el 文件中:

;; 定义发布项目
(setq org-publish-project-alist
      (list
       (list "my-org-site"
             :recursive t
             :base-directory "./content"
             :publishing-directory "./public"
             :publishing-function 'org-html-publish-to-html)))

;; 生成站点输出
(org-publish-all t)

此配置将 org-publish-project-alist 变量定义为我们网站的发布项目。使用 M-x describe-variable 阅读此变量的文档以获取更多信息!

我们使用名称 my-org-site,但您可以把项目命名为任何您想要的名称!

  • :base-directory 告诉 Org 我们要发布为HTML的文件文件夹
  • :publishing-directory 配置所有发布文件输出的文件夹
  • :recursive 告诉 Org 在 :base-directory 的所有子文件夹中发布 .org 文件
  • :publishing-function 告诉 Org 我们要将文件发布为HTML

最后的 org-publish-all 函数告诉 Org 发布 org-publish-project-alist 中配置的每个项目! t 参数告诉它无论何时生成,都要重新生成所有文件。

我们现在可以通过运行 build.sh 来生成我们网站的输出!运行它后,请查看 public/ 文件夹。

预览生成的站点

我们来看看刚刚生成的基本网站。有一个叫做 simple-httpd 的 Emacs 包可以在本地机器上托管您的文件作为网站,这样您就可以在浏览器中打开它。

您可以从 MELPA 使用 M-x package-install 或将以下代码片段 放入 Emacs 配置中 安装 simple-httpd,如果您安装了 use-package 并将MELPA配置为软件包源:

(use-package simple-httpd
  :ensure t)

现在您可以运行 M-x httpd-serve-directory 。它会提示您选择 Emacs 内部的目录来提供服务。

选择 public/ 目录的路径,然后打开浏览器转到http://localhost:8080来预览您的网站!如果需要,可以设置 httpd-port 来更改默认端口。

每次重新生成网站文件时,您只需重新加载页面即可查看所做更改的结果!

这是一个非常方便的方法来实时预览您的 Org 网站,而无需部署到网页服务器。您可以在 Emacs 中做出更改,保存文件,然后简单地在浏览器中重新加载以查看结果。这使得构建和测试 Org 网站变得非常简单和流畅。

改进HTML输出

我们刚看到的页面有几件事我想改变一下,使输出看起来更清晰:

  • 节号
  • 作者姓名
  • 发布时间戳
  • 验证链接

幸运的是,发布系统非常可定制,所以我将向您展示如何在项目配置中禁用一些内容以获得更好的结果。

;; 定义发布项目
(setq org-publish-project-alist
      (list
       (list "org-site:main"
             :recursive t
             :base-directory "./content"
             :publishing-function 'org-html-publish-to-html
             :publishing-directory "./public"
             :with-author nil          ;; 不包括作者姓名
             :with-creator t           ;; 在页脚中包括Emacs和Org版本
             :with-toc t               ;; 包括目录
             :section-numbers nil      ;; 不包括节号
             :time-stamp-file nil)))   ;; 不包括文件中的时间戳

我们需要设置其他变量来除去底部的验证链接:

(setq org-html-validation-link nil)

通过这些更改,我们的HTML输出现在应该没有:

  • 节号(例如=1.2=)
  • 作者的名称和联系信息
  • 文件上次更新的时间戳
  • 底部的W3C验证链接

其他可自定义的项目设置

这是您可能想要定制的更多项目设置列表,直接从 org-publish-project-alist 文档中提取:

Publish setting key Emacs Lisp variable
------------------------ ----------------------------------
:author user-full-name
:email user-mail-address
:creator org-export-creator-string
:exclude-tags org-export-exclude-tags
:headline-levels org-export-headline-levels
:language org-export-default-language
:preserve-breaks org-export-preserve-breaks
:section-numbers org-export-with-section-numbers
:select-tags org-export-select-tags
:time-stamp-file org-export-time-stamp-file
:with-archived-trees org-export-with-archived-trees
:with-author org-export-with-author
:with-creator org-export-with-creator
:with-date org-export-with-date
:with-drawers org-export-with-drawers
:with-email org-export-with-email
:with-emphasize org-export-with-emphasize
:with-entities org-export-with-entities
:with-fixed-width org-export-with-fixed-width
:with-footnotes org-export-with-footnotes
:with-inlinetasks org-export-with-inlinetasks
:with-latex org-export-with-latex
:with-planning org-export-with-planning
:with-priority org-export-with-priority
:with-properties org-export-with-properties
:with-smart-quotes org-export-with-smart-quotes
:with-special-strings org-export-with-special-strings
:with-statistics-cookies org-export-with-statistics-cookies
:with-sub-superscript org-export-with-sub-superscripts
:with-toc org-export-with-toc
:with-tables org-export-with-tables
:with-tags org-export-with-tags
:with-tasks org-export-with-tasks
:with-timestamps org-export-with-timestamps
:with-title org-export-with-title
:with-todo-keywords org-export-with-todo-keywords

改进页面样式

在这一点上,我们为网站生成了一套基本的输出,但是如果我们想让它看起来更漂亮一些怎么办?

通过设置更多变量,我们可以使用一个很好的样式表来使我们的网站看起来更加精致:

;; 定制HTML输出
(setq org-html-validation-link nil           ;; 不显示验证链接
      org-html-head-include-scripts nil      ;; 使用我们自己的脚本
      org-html-head-include-default-style nil;; 使用我们自己的样式
      org-html-head "<link rel=\"stylesheet\" href=\"https://cdn.simplecss.org/simple.min.css\" />")

这将删除默认插入到HTML输出中的默认 JavaScript 和CSS代码,并将其替换为指向一个名为 Simple.css 的很好的样式表的链接(或您自己的CSS文件!)。

让我们重新生成网站和看一看! 通过将样式表链接添加到 org-html-head,我们现在应该有一个更加精致的网站输出,带有更好的字体,颜色,间距等。=Simple.css= 是一个很好的开源样式表,可以改善网站的外观并使其看起来更专业。

除了 org-html-head ,还有其他变量可以用于进一步定制网站的样式和外观:

  • org-html-head-extra:可以添加其他 <head> 内容,例如自定义CSS或JS文件
  • org-html-style-default:默认的内联样式
  • org-html-htmlize-output-type:控制如何格式化链接和着重缩进的输出。设置为 css 可与外部CSS配合使用。

通过结合这些选项,您可以完全控制网站的样式和外观。您可以使用自定义CSS,内联样式,外部样式表或这三者的组合。

生成含代码块的页面

到目前为止,我们一直在查看一个非常简单的示例页面,上面几乎没有太多内容。当我们尝试生成一个包含代码块的更详细的 Org 文件时会怎么样?

让我们试试另一个文件,我的文学 Emacs 配置的版本称为 Emacs.org!

如果您正在生成一个特色代码块的网站,如编码博客或文学 Emacs 配置,在生成网站时您可能会遇到这样的错误:

Cannot fontify source block (htmlize.el >= 1.34 required)

要解决此问题,您需要从MELPA安装 htmlize 包。我们可以通过将以下代码片段添加到我们的 build-site.el 文件中来自动安装此包:

;; 设置软件包安装目录,以便软件包不存储在~/.emacs.d/elpa路径中。
(require 'package)
(setq package-user-dir (expand-file-name "./.packages"))
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
                         ("elpa" . "https://elpa.gnu.org/packages/")))

;; 初始化包系统
(package-initialize)
(unless package-archive-contents
  (package-refresh-contents))

;; 安装依赖项
(package-install 'htmlize)

在此代码片段中,我们加载 Emacs 的软件包管理器,并将 package-user-dir 设置为项目文件夹的子目录。这允许您为脚本安装软件包,而不会与个人 Emacs 配置的软件包混淆!

下一步我们做的是将MELPA添加到软件包存档列表并刷新软件包存档,以便可以找到 htmlize 。最后,我们调用 package-install 来安装它!

在未来的视频中,我将向您展示如何将 Emacs 配色方案转换为CSS文件,您可以使用该文件为源代码块着色,颜色与主题使用的颜色完全相同!

通过添加此安装过程,现在您应该可以成功生成包含源代码块的 Org 文件,而不会遇到字体错误! htmlize 将处理将源代码转换为带有语法高亮的HTML。

这是一个非常有用的技巧,可以轻松将含有源代码的 Org 文件转换为具有语法高亮效果的HTML网站。特别是如果您正在构建一个技术博客或文学配置,这会非常有帮助。

页面之间的链接

最后一件事我想向您展示的是如何在网站上的页面之间创建链接。让我们打开 index.org 并创建指向 Emacs.org 文件的链接。

index.org 中,我们可以按 C-c C-l (org-insert-link),输入我们要链接到的 Org 文件的路径(./Emacs.org),按 Enter 键,然后输入链接的文本(“My Emacs configuration”)。

当您再次生成网站时,您应该能够在页面之间进行链接,因为 Org 的发布系统会将链接转换为适当的输出扩展名。

当找不到链接的文件时,它也会发出警告!

Debugger entered--Lisp error: (user-error "Unable to resolve link: \"Emacs2.org\"")

这是一个很好的提示,提醒您检查链接是否指向存在的文件,以避免在网站上出现坏链接。

通过在 Org 文件之间创建链接,您可以轻松构建一个组织良好的网站,将相关页面连接在一起。读者可以简单地单击链接在各个页面之间导航。

要创建链接,只需将光标放在您要链接的文本上,然后按 C-c C-l 并输入链接目标的路径即可。Org 模式会自动为您处理输出格式 - 您只需专注于网站的内容和结构。

链接也可以指向:

  • 网站上的其他文件(相对路径)
  • 网站外部的URL(绝对路径)
  • 特定的标题/节(使用#符号)
  • 邮箱地址(mailto:链接)

这使您可以在网站内外创建丰富的链接网络。我希望这个快速入门指南对您有所帮助,可以开始构建自己的 Org 网站!

最后的构建脚本

我已经将您在此视频中看到的所有代码提交到以下 GitHub 存储库:

https://github.com/SystemCrafters/org-website-example/ (see the commit for this episode)

在下一集中,我将向您展示如何自动将基于 Org 的网站发布到 GitHub Pages 和 Sourcehut Pages 等 Git 托管服务!

这里是我们 build-site.el 脚本的最终形式:

;; 设置包安装目录,这样包不会存储在~/.emacs.d/elpa路径下。
(require 'package)
(setq package-user-dir (expand-file-name "./.packages"))
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
                         ("elpa" . "https://elpa.gnu.org/packages/")))

;; 初始化包系统
(package-initialize)
(unless package-archive-contents
  (package-refresh-contents))

;; 安装依赖项
(package-install 'htmlize)

;; 加载发布系统
(require 'ox-publish)

;; 自定义HTML输出
(setq org-html-validation-link nil            ;; 不显示验证链接
      org-html-head-include-scripts nil       ;; 使用我们自己的脚本
      org-html-head-include-default-style nil ;; 使用我们自己的样式
      org-html-head "<link rel=\"stylesheet\" href=\"https://cdn.simplecss.org/simple.min.css\" />")

;; 定义发布项目
(setq org-publish-project-alist
      (list
       (list "org-site:main"
             :recursive t
             :base-directory "./content"
             :publishing-function 'org-html-publish-to-html
             :publishing-directory "./public"
             :with-author nil           ;; 不包含作者姓名
             :with-creator t            ;; 包括Emacs和Org版本在页脚
             :with-toc t                ;; 包括目录
             :section-numbers nil       ;; 不包含章节号
             :time-stamp-file nil)))    ;; 不包含时间戳

;; 生成网站输出
(org-publish-all t)

(message "构建完成!")
订阅系统工匠通讯!
与最新的系统工匠新闻和更新保持同步! 阅读 Newsletter 浏览更多信息。
名称 (optional)
邮箱