为了让 Google 更好地发现和索引我的网站,我会使用 Google Search Console 提交 Sitemap。Sitemap 本质上是一个 XML 文件,描述网站包含的网页信息,帮助 Google 了解网站上都有哪些网页,以及这些网页的重要程度和更新频率。(Google 会参考这些信息,但我们不能通过 Sitemap 直接控制 Google 爬虫或排名。)我上一版的个人网站就包含了 Sitemap,所以重新新版本时也会把 Sitemap 加上。
上一个版本的 Sitemap 是我手工维护的 XML 文件,既然新版本的网站使用 Harp 进行编译,我希望 Sitemap 的 XML 文件也是编译时自动生成的。Harp 要使用模板生成 XML 文件很简单,把文件的后缀写成 .jade.xml
就可以了,Harp 从文件名可以推断出这个文件需要使用 Jade 模板来编译,结果保存为 XML 文件。我希望这个文件尽可能不需要手工维护,最好自己根据语言和页面的组合生成所有有效页面的链接。
每一个有效页面背后都有一个同路径的 .jade
文件,例如说 /en/resume
背后存在对应的 /en/resume.jade
,这个文件会生成 /en/resume.html
,然后 Netlify 会美化 URL 删掉不必要的 .html
后缀。如果我需要找出所有的有效页面,其中一个方法就是遍历项目目录,找出所有这些 .jade
文件,然后把它们的路径映射过去。因为遍历所有目录需要用到递归,我就写了一个 mixin 来做这个事情,原因是 Jade 里面的 mixin 类似于函数,可以自己调用自己从而实现递归。
mixin tree(current, path)
for value, key in current
if key === '_contents'
for file in value
if /\.html$/.test(file) && !/^\d{3}\.html$/.test(file)
url
loc
| https://catchen.me#{path}#{file.replace(/(index)?\.html$/, '')}
changefreq
| hourly
priority
if path === '/' && file === 'index.html'
| 1.0
else
| #{public._data[file.replace(/\.html$/, '')].priority}
else if !/^[._]/.test(key)
mixin tree(value, path + key + '/')
这个 mixin 接收两个参数,第一个是代表当前目录的对象,第二个是当前目录所在路径。在递归的入口,我会调用 mixin tree(public, '/')
,把代表根目录的 public
对象和对应的路径字符串 '/'
传进去,然后这个 mixin 就会遍历所有子目录把所有编译后的 .html
文件找出来。它找到的每一个 .html
文件都会被添加到 Sitemap 里面。
这个 mixin 在把 .html
文件映射为 URL 时,它还做了以下的特殊处理:
- 删除
.html
后缀,因为 Netlify 在美化 URL 时也会进行这个操作。如果我们在浏览器中打开https://catchen.me/zh/resume.html
,Netlify 会返回 301 重定向到https://catchen.me/zh/resume
,保证用户看到的是不包含.html
的路径。 - 删除
index
默认文件名,因为https://catchen.me/zh/index.html
和https://catchen.me/zh/
等价,同样会被 URL 美化删除。 - 过滤掉
404.html
等状态码特殊页面,因为这个页面是专门给 Netlify 返回对应状态码时使用的,不应该被索引。
最终的 sitemap.jade.xml
其实并不复杂,记得加上 doctype xml
和 urlset(xmlns="http://www.sitemaps.org/schemas/sitemap/0.9")
这类必要的元素就行了。编译后立即可以发布到 Netlify,然后在 Google Search Console 进行手工添加 Sitemap。数天后 Google Search Console 就会显示这个 Sitemap 已经被抓取了,然后还能看到 Sitemap 中页面的抓取情况。
这有可能是这个系列的最后一篇文章了,将来如果我对我的个人网站继续有更新,我会继续写这个系列。如果你对我的博客感兴趣的话,欢迎通过邮件或 RSS/Atom 进行订阅。如果你对这个话题有什么问题或者观点的话,欢迎对本文发表评论。
没有评论:
发表评论