给 Hexo 博客加一张足迹地图:hexo-post-map 使用指南

AI文章摘要 本文介绍 hexo-post-map 插件的主要功能、实际展示效果和完整使用步骤,包括高德地图配置、单地点与多地点标注、行程路线、足迹总览以及常见问题排查。
  1. 断桥残雪

旅行文章写得越来越多以后,我一直想给博客增加一个更直观的浏览方式:读者不仅能看到文章列表,还能从地图上知道这些故事发生在哪里,同一次旅行经过了哪些地方。

为此,我在博客中接入了 hexo-post-map。它可以给单篇文章添加地点或行程地图,也可以自动生成一张汇集全站游记的“足迹地图”。本文记录插件的主要功能、实际使用效果和完整配置步骤。

插件能做什么

hexo-post-map 是一款面向 Hexo 静态博客的地理信息插件。目前使用高德 JS API 2.0,适合游记、城市记录、徒步、骑行、音乐节等带有明确地点的内容。

它主要提供以下功能:

  1. 在文章中展示地图:地图卡片可以出现在正文前、正文后,或通过标签插入指定位置。
  2. 支持单个或多个地点:一篇文章既可以只标记一座城市,也可以展示景点、车站、餐厅等多个点位。
  3. 绘制行程示意线:按照地点顺序连接路线,并用编号显示途经地点。
  4. 生成全站足迹地图:插件会为所有带地理信息的文章生成独立地图页面,并根据缩放级别自动聚合文章。
  5. 展示文章缩略图:优先使用文章的 thumbnail,也可以从正文图片或 Live Photo 的静态图中自动选择。
  6. 适配不同设备和主题:支持移动端文章抽屉、深色模式、减少动态效果和一组可覆盖的 CSS 变量。
  7. 构建时校验配置:坐标、地点 ID、代表地点和路线引用有误时,构建过程会直接指出对应文章和字段。

实际使用效果

单篇文章地图

地图

文章设置地理信息后,正文附近会出现一张高度较小的地图卡片,不会过多挤占阅读空间。

单地点文章显示一个定位图钉;多地点文章会自动调整视野,把所有地点放入可见区域。如果设置了路线,路线中的地点会按访问顺序编号并用直线连接。点击图钉可以查看地点名称。

这里的连线用于表达“先去了哪里、再去了哪里”,不是高德导航规划出来的道路或徒步轨迹。

全站足迹地图

地图

插件会生成 /map/ 页面,并把每篇地图文章的代表地点显示在同一张地图上。缩放较小时,相邻文章会合并为聚合圆;继续放大后,会展开为带缩略图的文章标记。

点击单篇文章标记可以预览标题、日期和地点,点击聚合点则会继续放大或打开文章列表。在手机上,文章列表会显示为底部抽屉。

截至本文发布时,这个博客共有 40 篇文章,其中 26 篇已经标注地理信息,共包含 50 个地点和 11 条行程路线。原本分散在归档页面里的旅行记录,现在可以沿着地图重新浏览。

准备工作

插件当前要求:

  • Node.js 20 或更高版本
  • Hexo 7 或 Hexo 8
  • 高德开放平台的 Web 端(JS API)Key
  • GCJ-02 坐标

需要注意,高德控制台中的 Key 类型应选择 Web 端(JS API),而不是“Web 服务”。新申请的 JS API Key 还需要配合安全密钥或安全代理使用。

第一步:安装插件

进入 Hexo 博客根目录,执行:

1
npm install hexo-post-map

安装完成后,可以在 package.json 的依赖中看到 hexo-post-map。仅安装依赖不会自动启用地图,还需要继续配置站点。

第二步:申请高德地图 Key

  1. 登录高德开放平台控制台。
  2. 进入“应用管理”,创建一个应用。
  3. 在应用中添加 Key,服务平台选择“Web 端(JS API)”。
  4. 保存生成的 Key 和安全密钥 securityJsCode。
  5. 根据实际部署地址设置可使用的域名。

如果只是个人博客,可以先使用客户端安全密钥完成配置;如果对安全边界有更高要求,可以根据高德官方文档部署安全代理。

第三步:配置 Hexo

编辑博客根目录下的 _config.yml,注意不是主题目录中的配置文件。加入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
post_map:
enabled: true
provider: amap
post:
enabled: true
position: before
height: 220px
default_zoom: 11
overview:
enabled: true
path: map/
title: 足迹地图
layout: page
cluster:
grid_size: 60
max_zoom: 18
amap:
key: replace-with-your-web-key
security:
security_js_code: replace-with-your-security-js-code

上面的 Key 和安全密钥都是占位符,需要替换为自己在高德控制台申请的内容。

几个常用选项的含义如下:

  • post.position:文章地图的位置,可选 before、after 或 manual。
  • post.height:桌面端文章地图的高度。
  • overview.path:足迹地图的访问路径,默认是 /map/。
  • overview.layout:优先使用主题的页面布局;设置为 standalone 可以使用插件自带的独立页面。
  • cluster.grid_size:文章聚合的屏幕距离,单位为像素。
  • cluster.max_zoom:足迹地图允许聚合和展开的最大缩放级别。

如果博客源码是公开仓库,不建议把真实凭据提交进去。可以将 amap 保留为空对象,并在构建环境中设置变量:

1
2
3
post_map:
# 其余配置保持不变
amap: {}
1
2
3
4
export HEXO_POST_MAP_AMAP_KEY='replace-with-your-web-key'
export HEXO_POST_MAP_AMAP_SECURITY_JS_CODE='replace-with-your-security-js-code'
npx hexo clean
npx hexo generate

环境变量能避免凭据进入源码仓库,但 Web Key、客户端安全密钥和文章坐标最终仍会发送到浏览器,不能把它们当作私密数据。生产环境也可以改用 HEXO_POST_MAP_AMAP_SERVICE_HOST 配置安全代理,但客户端安全密钥和安全代理只能选择一种。

第四步:给文章添加地理信息

地图信息写在文章顶部的 YAML Front Matter 中。插件不会根据地点名称自动搜索坐标,也不会转换坐标系,因此需要填写 GCJ-02 坐标。

标记单个地点

适合城市记录、演出、展览或只涉及一个主要地点的文章:

1
2
3
4
5
6
7
8
9
10
11
---
title: 魔都
thumbnail: https://example.com/shanghai.jpg
map:
zoom: 11
points:
- id: shanghai
name: 上海
longitude: 121.4737
latitude: 31.2304
---

当文章只有一个地点时,这个地点会自动成为全站足迹地图中的代表位置。

标记多个地点

一篇文章包含多个景点,但不需要表达访问顺序时,可以只设置点位:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
---
title: 衢州一日游
map:
representative: old-city
points:
- id: old-city
name: 衢州古城
longitude: 118.8739
latitude: 28.9570
- id: museum
name: 衢州市博物馆
longitude: 118.8762
latitude: 28.9551
---

多地点文章必须使用 representative 指定一个代表地点。全站地图只使用这个代表地点定位文章,但文章详情地图会展示全部地点。

添加行程路线

如果文章需要体现旅行、徒步或骑行的先后顺序,可以增加 route:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
---
title: 武功山真的很美
map:
representative: summit
points:
- id: visitor-center
name: 武功山游客中心
longitude: 114.1501
latitude: 27.4682
- id: cableway
name: 一级索道
longitude: 114.1623
latitude: 27.4741
- id: summit
name: 武功山金顶
longitude: 114.1735
latitude: 27.4568
route:
- visitor-center
- cableway
- summit
---

route 中填写的是 points 已有的地点 ID,顺序就是地图中的编号和连线顺序。没有写进 route 的地点仍会显示,只是不会参与连线。

地点 ID 只能使用小写英文字母、数字和单个连字符,例如 west-lake。经纬度必须是数字,不能写成带引号的字符串。

第五步:控制地图出现的位置

默认的 position: before 会把地图放在正文前。设置为 after 后,地图会出现在正文末尾。

如果想自己决定具体位置,可以将配置改为:

1
2
3
post_map:
post:
position: manual

然后在文章正文中插入:

1
{% post_map %}

每篇文章最多使用一次这个标签。即使关闭文章详情地图,已经标注的文章仍然可以出现在全站足迹地图中。

第六步:添加足迹地图入口

插件会生成地图页面,但不会自动修改主题导航。需要根据主题的配置方式,把 /map/ 添加到菜单中。

如果 Hexo 配置了 root: /blog/,最终地址会是 /blog/map/,但 overview.path 仍然只写 map/,不需要重复添加站点根路径。

第七步:构建并预览

本地预览可以执行:

1
2
npx hexo clean
npx hexo server

确认文章地图和 /map/ 页面正常后,再生成用于部署的静态文件:

1
2
npx hexo clean
npx hexo generate

修改 Key、安全模式、点位或地图配置后,都需要重新构建。如果使用对象存储和 CDN,还要重新上传 public/ 并刷新相关缓存。

常见问题

地图没有出现

检查以下内容:

  • post_map.enabled 是否为布尔值 true。
  • 文章是否包含合法的 map.points。
  • 使用 manual 模式时,正文中是否插入了 {% post_map %}。
  • 当前主题是否正常渲染文章内容。

页面空白或高德地图加载失败

确认 Key 的服务平台是 Web 端(JS API),部署域名符合高德控制台限制,并且只配置了一种安全模式。修改配置后应重新构建;如果 SDK 加载超时,还需要刷新页面重试。

构建时报地点或路线错误

插件会严格校验 Front Matter。多地点文章必须设置 representative,路线只能引用本文已经声明的地点 ID,同一篇文章中的 ID 不能重复。根据错误信息中的文章路径和字段修正即可。

坐标显示偏移

插件按照 GCJ-02 使用输入坐标,不会自动转换。如果原始坐标来自 GPS 或其他地图服务,坐标系不同就可能产生偏移,应先确认并转换为 GCJ-02。

隐私位置是否适合标注

文章详情会公开全部地点坐标,足迹地图也会公开代表地点。家庭住址、临时住所等敏感位置应改用城市中心、公共地标或主动降低精度后的坐标。

总结

hexo-post-map 把传统的文章归档变成了一张可以探索的旅行足迹。对作者来说,只需要在 Front Matter 中维护结构化地点;对读者来说,则多了一种按照空间而不是时间浏览内容的方式。

单地点、多地点和路线共用同一套配置结构,后续增加新游记时可以持续复用。更完整的配置、安全说明和版本变化,可以查看 hexo-post-map 项目仓库。