Göks
2021 年1 月 16 日 13:32
1
你好,
我成功地将一个自行编写的旧版论坛软件迁移到了 Discourse。
在导入了 200 万条记录并运行 24 小时后,除了永久链接(permalinks)之外,一切运行完美。
我在 Discourse 的 permalinks 数据库表中大约有 350,000 条永久链接。它们全部是小写的,例如:“forum/t140842-s1/8p-hilfe-bei-1-8-tfsi-guter-motor-oder-schlechter-motor.html”。
不幸的是,Google 链接到的是 “/forum/t140842/8P-Hilfe-bei-1-8-tfsi-guter-Motor-oder-schlechter-Motor/”,导致我收到 404 错误。
有什么建议可以在查询 permalinks 表之前将请求 URL 转换为小写,同时不破坏其他功能吗?难道这种在查找前进行的转换不应该成为标准做法吗?
感谢你们开发了如此出色的软件!
Göks
pfaffman
(Jay Pfaffman)
2021 年1 月 16 日 13:48
2
欢迎!恭喜您走到这一步!
您想创建一个规范化永久链接的规则,去掉 slug,仅使用论坛 ID 来生成永久链接,我猜是这样。
要识别正确的主题,只需要 t140842-s1 对吧?
确实有一些其他导入器也这样做,不过我不确定具体是哪些。也许是 vBulletin?但如果您对所有导入器进行规范化相关的 grep 搜索,应该能找到我的示例。
1 个赞
Göks
2021 年1 月 16 日 13:58
3
感谢您的快速回复。
在迁移之前,我并不知道查找操作是区分大小写的——否则我会提前考虑到这一点,并确保 URL 的保存方式与旧软件中一致。
不过现在迁移已经完成,站点也已正式投入使用。因此,我目前只能寻找变通方案。
我可以通过主题 ID 来识别主题,因此像“/forum/t140842”这样的路径就足够了。通过 SQL,我可以按这种方式修改 permalinks 表中的 url 字段,但这样之后是否还能正常查找并重定向?我快速测试了一下,发现不行。
Discourse 设置中有一个关于 permalinks 规范化的选项,但我不太清楚它的具体作用。
pfaffman
(Jay Pfaffman)
2021 年1 月 16 日 14:56
4
规范化永久链接会在匹配永久链接之前重写 URL,因此你可以用它来移除 slug。设置中的说明解释了这一点,但可能只有在你已经理解的情况下才能看懂。
旧的主题 ID 应位于 topicCustomField 中,因此你可以通过遍历这些 ID 来创建新的永久链接。然后只需删除旧的链接(或者在你确信能够生成所需链接后,删除所有旧链接)。
你可以在这里以及其他导入器中搜索“永久链接”和“规范化”以找到一些示例(grep -r 是一种方法)。如果你需要更多帮助且有预算,我可以在下周协助你。
1 个赞
Göks
2021 年1 月 16 日 15:02
5
好的,我有一个请求:
https://a3-freunde.de/forum/t140842/8P-Hilfe-bei-1-8-tfsi-guter-Motor-oder-schlechter-Motor
以及在配置中添加一个永久链接规范化规则,例如:
/t(\\d*)/?$forum/t\\1
这应该使上述请求的结果变为 “forum/t140842”。
但是,当我将 URL “forum/t140842” 添加到 Discourse 的永久链接表中时,似乎没有任何效果?
我的假设正确吗?我漏掉了什么?
pfaffman
(Jay Pfaffman)
2021 年1 月 16 日 15:15
6
你走对了方向。正则表达式那部分确实有点棘手。我觉得你的永久链接开头需要加上 forum/。
Göks
2021 年1 月 16 日 15:23
7
感谢付出,我很感激。
在配置中,我将我的正则表达式改为(我的意思是它应该也能匹配主题 ID):
forum/t(\\d*)/?$forum/t\\1
当我在表中添加一条新永久链接,URL 为 “forum/t140842” 并保存后……Discourse 将 URL 更改为 “f?$forum/t140842”。这要么是一个 bug,要么是我没有理解这里的概念。
Göks
2021 年1 月 16 日 19:52
8
在进一步尝试正则表达式规范化后,我仍无法弄清楚其工作原理。使用描述中的示例在添加新永久链接时,再次导致 URL 字段出现意外结果。
迁移到 Discourse 时,我移除了域名的 www 前缀。这使我现在有机会通过 Apache 配置和 .htaccess 在旧服务器上重写 URI 为小写,然后再重定向到新的 Discourse 服务器。这在一定程度上暂时解决了我的问题。
Göks
2021 年1 月 17 日 11:59
9
未按预期工作,因为迁移脚本中生成的 URL slug 部分与旧软件中的略有不同。
因此,我自行对 URL 进行了“标准化”。
添加/生成标准化 URL(Discourse 永久链接表)
从以下 URL 字段中获取:
forum/t140842-s1/8p-hilfe-bei-1-8-tfsi-guter-motor-oder-schlechter-motor.html
或
forum/t140842-s2/8p-hilfe-bei-1-8-tfsi-guter-motor-oder-schlechter-motor.html
或
forum/t140842/8p-hilfe-bei-1-8-tfsi-guter-motor-oder-schlechter-motor.html
转换为仅包含旧主题 ID 的简单 URL:
forum/t140842
这是通过一条 SQL 命令完成的,该命令使用 REGEXP_REPLACE 函数重写 URL:
INSERT INTO permalinks (created_at, updated_at, topic_id, url) SELECT NOW(), NOW(), topic_id, REGEXP_REPLACE(url,'forum/t(\\d*)(-?.*)/(.*)','forum/t\\1','') url FROM permalinks WHERE topic_id > 0 ON CONFLICT DO NOTHING;
在旧域名的 .htaccess 中重写旧请求
RewriteRule ^forum/t([0-9]*)(-?.*)/(.*)$ https://discourse-domain.com/forum/t$1 [R=301,L]
这里发生了什么?
Google 已索引并链接到 URL https://old-domain.com/forum/t140842/8p-hilfe-bei-1-8-tfsi-guter-motor-oder-schlechter-motor.html。幸运的是,由于域名不同,该请求最终到达了 Apache 服务器,因此我可以轻松使用 .htaccess 进行重写。于是,我将该请求重写到 https://discourse-domain.com/forum/t140842。我在 permalinks 表中添加了 forum/t140842 这条记录,方法是利用已添加的包含完整 slug 的永久链接,并通过正则表达式进行处理(见上文)。
希望这能作为起点帮助到其他人。
1 个赞