在上一篇文章 Pages CMS:一个勉强够用的HUGO博客后台 中,我提到可以用 Pages CMS 作为 Hugo 的文章后台管理面板。但有个问题不是很好解决,即 Hugo 默认目录结构很难与 Pages CMS 进行适配。这也不单单是 Pages CMS 独有问题,其他任何 CMS 可能都会在适配 Hugo 时遇到这个问题。但在 Hugo 社区的强大支持下,我最终解决了这一问题。
问题表现形式
Hugo 需要什么样的图片目录结构
Hugo 目录一般是下边这种形式,index.md
文件 与图片文件都保存在同一文件夹内。在 index.md
中引用图片,只需要输入 ![a](a.jpg)
即可,不需要输入图片的目录结构。除非一种情况,在下边代码类似 article-1
内有子目录,这时才需要在图片引用子目录路径。
|
|
CMS 能提供什么样的图片目录结构
CMS 的图片目录结构一般是下边这种形式,通常只有一个图片入口和出口,用于图片集中管理。在 CMS 中,上传或插入图片,默认的链接(按照下方代码设置)是 content/post/article-1/a.jpg
。在使用 markdown 语法后,会变成 ![a](content/post/article-1/a.jpg)
,一旦手动设置图片链接为 ![a](a.jpg)
就会产生错误。但 ![a](content/post/article-1/a.jpg)
这种链接格式,在 Hugo 中会被认为图片是保存在 index.md
所在目录的下级,即 content/post/article-1/content/post/article-1/a.jpg
,这当然是一个错误的路径。冲突由此而产生。
|
|
原因分析
诚然,这看起来似乎是一个很小的问题。但想要解决这个问题却并不容易。在 CMS 中,如果要让程序将 ![a](a.jpg)
这种链接结构能够直接关联到index.md
所在目录的图片,需要下很大功夫。因为绝大多数人使用 CMS 都是使用统一图片文件夹管理,需要用到图片绝对地址,很难为了适配 Hugo 单独去做一套方案来适配,而且会产生其他冲突。例如,index.md
所在目录的下级还有图片文件夹的情况。
于是,压力给到 Hugo 这边。
在本地测试中发现,![a](content/post/article-1/a.jpg)
被 Hugo 转换为了 https://localhost/content/post/article-1/a.jpg
其中,/content/post/
来自 CMS 的图片输出设置,/article-1/
为 index.md
所在文件夹名称。
而 ![a](a.jpg)
在 Hugo 中被转换为 https://localhost/article/slug/a.jpg
其中 /article/
是由 Hugo.yaml
中的 permalinks: { post: /article/:slug/ }
输出,/slug/
内容是在 front-matter
中手动设置。
到了这里,问题解决方法就逐渐明晰起来。
初步解决办法
在 CMS 图片输出路径中删掉
/content/
部分,这样 CMS 输出图片路径变成了![a](post/article-1/a.jpg)
在
Hugo.yaml
中将permalinks: { post: /article/:slug/ }
删除,同时删除测试index.md
中手动设置的 slug,这样固定链接将默认使用文件夹名称。
如此,CMS 中的 ![a](content/post/article-1/a.jpg)
在 Hugo 中被转换为了 https://localhost/post/article-1/a.jpg
,同样,手动输入的 ![a](a.jpg)
也在 Hugo 中被转换为了 https://localhost/post/article-1/a.jpg
。问题基本得到解决。
进阶解决办法
由于 CMS 中图片路径就是 Hugo 生成静态站点后的绝对地址,等于 CMS 在 Hugo 渲染中打了提前量,预测到这个地址最后就会有个文件存在,所以在网页中不会出现错误。
但是这种方法对于很多复杂的 Hugo 主题模板而言,还是差点意思。因为 Hugo 没有对这个地址上的图片文件作任何处理,主题模板也不会对这个地址上的图片文件作 CSS 预设。因为在整个过程而言,这实际上就相当于一个第三方图片。
由此,接下来需要解决的实际问题是:如何将 ![a](content/post/article-1/a.jpg)
导入到 Hugo 的图片渲染程序中。由于我在 Hugo 官方论坛提出前一个目录结构问题,当时技术大佬就指出我可以使用 Hugo 的图片钩子来保证这个路径上的图片得到渲染。
但这个设置并不简单。
我尝试了很多种方法去定义图片钩子。例如,判断 ![a](content/post/article-1/a.jpg)
图片 Markdown 语法中是否包含 /
斜杠符号,是否属于绝对地址,或者更改 Resources.GetMatch
函数等方式。但这些都没成功。
最终,我选择了一个最老土的办法,直接将 ![a](content/post/article-1/a.jpg)
中的图片文件名单独提取出来,无视 content/post/article-1
路径部分,只要匹配到 a.jpg
即导入 Hugo 渲染。但这样做有一个代价,就是前边说的,图片不能再放置于 article-1
内的子目录,必须直接放置在 article-1
中。
至此,我想上一篇博客的文章标题可以修改了,Pages CMS 不再是一个勉强可以使用的 Hugo 博客后台,而是一个具有完全能力的后台,一个设计非常优秀的CMS 软件。
示例:Hugo-theme-stack 主题中的图片钩子设置
|
|
备注:需要批量将index.md
所在文件夹内所有 images
文件夹中的图片文件上提一级使其与index.md
并列
|
|