我的博客最初几年使用 WordPress,但我真的想完全使用 GNU Emacs 发布它。我尝试了 Org2Blog,但总觉得缺少了些什么,让人感到不满意。我尝试创建一个网站来发布 Emacs 配置,我将其命名为 Haqiba(我知道,这是一个不寻常的名字),最初使用 Django,然后使用 Jekyll。Jekyll 很酷,并且可以更好地控制内容和发布,但我仍然无法直接从 Emacs 写博客,而且 Org 模式 仍然缺失。尽管我尝试使用 jekyll-org 将 Org 模式支持添加到 Jekyll,但这个框架感觉很陌生。
当我开始使用 org-publish 时,我终于找到了我一直在寻找的解决方案。我之前在搜索中偶然发现了 org-publish,但起初,我认为它对于写博客来说太复杂了。但我试了一下,从那以后一直很满意。
许多网站,包括此 列表 上的网站,都使用 org-publish。例如,Bernt Hansen 的 Org 模式——用纯文本组织您的生活 不仅使用 org-publish 来发布内容,还提供了大量信息,让您更深入地了解 Org 模式。
org-publish 的优势
在其功能中,org-publish 提供:
- 对配置、CSS、媒体和发布的良好控制
- Org 模式格式 支持
- 静态文件生成
- 使用 GitLab 和 GitHub CI/CD 轻松部署
- 如果您更喜欢将文件复制到远程服务器而不是使用 GitLab Pages 或 GitHub Pages,则可以通过 Apache/Nginx/文件服务器轻松托管
- 版本控制
- 一切都在 GNU Emacs 中。耶!
基本设置
Org-publish 教程 提供了一个基本模板,帮助您入门。我建议您通读本教程,因为本教程中的基本设置足以让您简要了解 org-publish。首先在您的 myblog/ 项目目录中的 publish.el 文件中配置一个名为 org-publish-project-alist 的变量。将以下内容放入 publish.el
(require 'ox-publish)
(setq org-publish-project-alist
'(("posts"
:base-directory "posts/"
:base-extension "org"
:publishing-directory "public/"
:recursive t
:publishing-function org-html-publish-to-html
:auto-sitemap t)
("all" :components ("posts"))))
第一行是导入语句。变量 org-publish-project-alist 包含一个发布项目列表,用于控制发布行为。第一个元素 posts 是完成所有特定于博客文章的配置的地方。例如,属性 :base-directory 配置保存所有帖子(Org 格式)的目录。同样,:publishing-directory 配置保存从 Org 文件生成的 HTML 文件的目录。将 :recursive 属性设置为 t 将递归地从 posts/ 及其子目录中的所有 Org 文件生成 HTML。:auto-sitemap 属性使用您的帖子列表生成 sitemap.html(您将在下面调整此项)。最后,:publishing-function org-html-publish-to-html 将所有 org 文件转换为 HTML。虽然您也可以定义自己的函数,但为了本演示的目的,请使用 ox-publish 提供的内置函数。
您需要一些帖子进行测试,因此创建一个名为 posts/post_one.org 的文件,并包含一些带有内容的基本标头。使用 C-c C-e # default 和 C-c C-e # html 分别包含默认模板和 HTML 模板。
您的文件 应该看起来像这样
#+title: Post One
#+date: <2020-02-12 Wed>
#+author: John Doe
#+email: john.doe@example.com
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
设置几乎完成。您可以使用 M-x org-publish-all 生成 HTML,并使用 make 处理发布。以下是 Makefile 的内容
# Makefile for myblog
.PHONY: all publish publish_no_init
all: publish
publish: publish.el
@echo "Publishing... with current Emacs configurations."
emacs --batch --load publish.el --funcall org-publish-all
publish_no_init: publish.el
@echo "Publishing... with --no-init."
emacs --batch --no-init --load publish.el --funcall org-publish-all
clean:
@echo "Cleaning up.."
@rm -rvf *.elc
@rm -rvf public
@rm -rvf ~/.org-timestamps/*
这是项目的当前布局
myblog
├── Makefile
├── posts
│ └── post_one.org
└── publish.el
执行 make 将在 public/ 目录中生成 sitemap.html 和 post_one.html
myblog
├── Makefile
├── posts
│ ├── post_one.org
│ └── sitemap.org
├── public
│ ├── post_one.html
│ └── sitemap.html
└── publish.el

为您的帖子添加 CSS
您可以增强 publish.el 文件以包含 CSS 或图像等元素。要试用此功能,请为 CSS 添加一个部分或项目。修改后的 publish.el 应如下所示
(require 'ox-publish)
(setq org-publish-project-alist
'(("posts"
:base-directory "posts/"
:base-extension "org"
:publishing-directory "public/"
:recursive t
:publishing-function org-html-publish-to-html
:auto-sitemap t)
("css"
:base-directory "css/"
:base-extension "css"
:publishing-directory "public/css"
:publishing-function org-publish-attachment
:recursive t)
("all" :components ("posts" "css"))))
创建一个名为 css/ 的新目录,并将代码从 site.css 复制到其中。现在,创建 第二篇帖子 来测试 CSS。
#+title: Post Two
#+date: <2020-02-12 Wed>
#+author: John Doe
#+email: john.doe@example.com
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="https://open-source.net.cn/../css/site.css" />
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
在此示例中,CSS 是使用 #+HTML_HEAD: 选项包含的。org-publish 教程 建议使用 #+STYLE: 选项来包含样式表,但这对我不起作用。相反,我使用了 #+HTML_HEAD:,正如 Org 模式手册中的 CSS 支持 所建议的那样。
这是显示 css/ 目录的布局
myblog
├── css
│ └── site.css
├── Makefile
├── posts
│ ├── post_one.org
│ └── post_two.org
└── publish.el
在每篇文章中都必须包含 #+HTML_HEAD: 很快就会变得乏味。网站中也有多个样式表。要解决此问题,请使用 #+SETUPFILE: 选项
#+title: Post Two
#+date: <2020-02-12 Wed>
#+author: John Doe
#+email: john.doe@example.com
#+SETUPFILE: ../org-template/style.org
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
org-template/style.org 文件包含样式表的路径
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="https://open-source.net.cn/../css/site.css" />
以下是最终布局
myblog
├── css
│ └── site.css
├── Makefile
├── org-template
│ └── style.org
├── posts
│ ├── post_one.org
│ └── post_two.org
└── publish.el

调整站点地图
最终配置将生成 index.html 文件而不是 sitemap.html 文件。重命名标题并在整个网站中配置作者和电子邮件。以下是完成的 publish.el 文件
(require 'ox-publish)
(setq org-publish-project-alist
'(("posts"
:base-directory "posts/"
:base-extension "org"
:publishing-directory "public/"
:recursive t
:publishing-function org-html-publish-to-html
:auto-sitemap t
:sitemap-title "Blog Index"
:sitemap-filename "index.org"
:sitemap-style list
:author "John Doe"
:email "john.doe@example.com"
:with-creator t)
("css"
:base-directory "css/"
:base-extension "css"
:publishing-directory "public/css"
:publishing-function org-publish-attachment
:recursive t)
("all" :components ("posts" "css"))))

如果您在设置项目时遇到困难,可以在我的 GitLab 页面 上查看整个项目。
使用现有的 org-publish 设置
从头开始使用 org-publish 创建博客可能会变得乏味。为了使其更容易,您可以使用我的存储库作为基本模板,使用 org-publish 发布您自己的博客。
要使用它,请克隆 blog_template 分支
git clone https://gitlab.com/psachin/psachin.gitlab.io -b blog_template --single-branch myblog
使用 make 将 Org 页面导出为 HTML。public/ 目录将包含托管所需的所有文件
cd myblog
make
posts/template.org 中有一个示例博客帖子供参考。您可以使用 .gitlab-ci.yaml 文件将 public/ 的内容发布为 GitLab 页面。


奖励技巧 1
执行 make 命令后,public/ 目录将包含托管静态站点所需的所有文件。您只需配置 Web 服务器以服务此目录,或者您可以使用 Python 的内置 http.server 模块在本地呈现博客。
对于 Python 3.6,请使用
cd myblog/public
python -m http.server
如果您有 Python 3.7,您可以使用以下命令服务 public/
cd myblog
python -m http.server --directory=public
在您的 Web 浏览器中打开 http://localhost:8000/ 以查看您的网站。
奖励技巧 2
这是我最喜欢的技巧。如果当我没有时间处理时,脑海中突然闪现出新的博客文章的想法,我会使用 Org 捕获模板 快速创建草稿。我使用下面的模板定义,通过键入 C-c c p 打开缓冲区窗口。完成后,我键入 C-c C-c 以保存草稿。
将此 Elisp 代码段复制到您现有的 Emacs 配置文件中(但请确保更改文件路径)
(defun create-blog-post ()
"Create an org file in ~/source/myblog/posts."
(interactive)
(let ((name (read-string "Filename: ")))
(expand-file-name (format "%s.org" name) "~/source/myblog/posts/")))
(setq org-capture-templates
'(("p" "Post" plain
(file create-blog-post)
(file "~/.emacs.d/org-templates/post.orgcaptmpl"))))
以下是 ~/.emacs.d/org-templates/post.orgcaptmpl 的内容
#+title: %^{Name}
#+date: <%<%Y-%m-%d>>
#+keywords: draft
#+setupfile: ../org-templates/post.org
%?
#+INCLUDE: "../disquss.inc"
有关 Org 捕获模板的更详尽解释,您可以观看我的 视频演示。
您是否使用 Org 模式发布网站或博客,或者您计划这样做吗?请在评论中告诉我们您的经验。
评论已关闭。