最近又折腾了一下博客,把文章都用 denote 来命名管理,方便后面文章多了维护。
这里面主要有一个问题是,denote 的文件名很长,而且可能会变化,如果作为导出的 URL,那么这个 URL 就可能会经常变,如果有人引用了旧的 URL,再访问就会是 404。
在翻 org-mode export 的 info 的时候,发现一个 keyword,#+export_file_name,可以设置导出的文件名,正好解决我这个问题。
此外,还需要处理一些问题:
- denote 内部链接的导出,使用 export_file_name 作为链接名
- org-publish 基于 denote keyword 过滤文件
- org-publish 输出的 sitemap,使用 export_file_name 作为链接名
都处理完之后,目前用着还行,所以分享一下,如果你也打算用 denote 来管理博客文章的话,希望对你有帮助。
5 个赞
可以这样:
(defun my/ox-files ()
"返回一个包含'blog'标签的'denote'文件路径列表"
(denote-directory-files "_blog"))
……
(setq org-publish-project-alist
;; 处理帖文
`(("posts"
:exclude ".*"
:include ,(my/ox-files)
)))
1 个赞
Cool!学习了,thanks!
denote-directory-files 只会搜索 denote-directory 里的文件,但是我用了 silos,和 denote-directory 不是一个目录。
我需要临时改变 denote-directory 的值后再使用 denote-directory-files:
(defun spike-leung/get-file-list-from-denote-silo (silos tag)
"Return files in SILOS match TAG.
SILO is a file path from `denote-silo-directories'.
TAG is string."
(cl-letf ((denote-directory (expand-file-name silos)))
(denote-directory-files tag)))
(setq org-publish-project-alist
`(("orgfiles"
:base-directory "~/git/taxodium/posts"
:base-extension "org"
:exclude ".*"
:include ,(spike-leung/get-file-list-from-denote-silo "~/git/taxodium/posts" "_published")
;; 省略部分代码
)
;; 省略部分代码
))
比我原来用 exclude 排除直观和方便得多,非常感谢。
2 个赞
这个方法似乎有个问题,当新增了一篇文章的时候,需要重新执行 setq org-publish-project-alist,让它获取到最新的文件列表,新增的文章才会被发布。
不知道你有没碰到,如果碰到了你又是如何解决的。
谢谢你的分享!
这是我从你文章中看到的 puhlish 配置:
;; Define the publishing project
(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"
:exclude-tags '("draft" "noexport")
:exclude "draft*"
:with-author t
:with-creator t
:with-toc t
:with-email t
:html-link-home "/"
:section-numbers nil
:time-stamp-file nil)))
看起来你应该主要是通过 :exclude 和 :exclude-tags 过滤文件?
:exclude-tags 我在 org-publish 的 info 里好像没有看到。
:exclude 我尝试过,但是我目前有三种 tag: published,draft,blackhole(一些特殊的页面)
因为我所有的文章都在一个目录里,如果用 :exclude 的话,对于 published 的文章,我需要 exclude draft,blackhole,如果后面有更多的 tag,我就需要排除更多。而对于 draft 我又需要排除 published, blackhole。感觉有些麻烦,没有用 :include 来得直观。
看了你的文章我也收获了不少,例如 org-html-home/up-format 可以设置一个固定在顶部的内容。
利用 org-export-before-processing-hook 可以给每个页面添加一些内容。
你实现了 tags!我一直也想实现,我会研究一下你是怎么做的,我也想做一个 tag page。
关于 setup.org,我尝试了一下,它的内容会出现在 toc 下面。
我也看到你的配置:
#+OPTIONS: toc:nil
#+TOC: headlines 5
就是用来解决这个问题的吗?
但这是每个文件都引用的内容,有的文章只需要 headlines 1,看起来还需要写点 Elisp 判断一下?
另外,我有一些关于博客的小建议:
- 作用在 html 上的这个 filter,会影响一些插件的样式表现,看起来有点怪= =
- 代码块可以考虑添加一个 Copy 按钮?因为页面不足以显示所有的代码,我更倾向于复制下来在 Emacs 里看,我尝试了鼠标选择一直往下滚动,直到选择全部,但不知道为什么页面滚动的很慢(似乎只在那个 Full Script 的代码块中滚动比较慢)
(defun my/org-project-update (&optional ARG PRED)
"这个函数的作用是动态更新`org-publish-project-alist',以便及时匹配'denote'文件标签的变动。"
(setq org-publish-project-alist
;; 处理帖文
`(("posts"
:exclude ".*"
:include ,(my/ox-files)))))
(advice-add #'org-export-dispatch :before 'my/org-project-update)
1 个赞
把 advide 加载 org-publish 之前也可以。
(advice-add 'org-publish :before #'spike-leung/setup-org-publish-project-alist)
如果您想改变标题数量,很简单。
(defun remove-org-element (string)
"Delete the first element which contains STRING."
(save-excursion
(search-backward string nil t 2)
(goto-char (match-beginning 0))
(org-mark-element)
(delete-region (region-beginning) (region-end))))
在文档中设定一些其他的参数。
#+begin_src emacs-lisp :exports results
(remove-org-element "#+TOC:")
#+end_src
移除 #+TOC: 行,然后在该页面添加自己的 TOC。
博客贴士:
- 过滤器是用来获取光线主题的,我以前只知道CSS中的黑色主题(有点懒我承认)。
- 我会尝试添加它。虽然src块没有什么问题。
2 个赞