{
“content”: "\u003cdiv data-theme-toc="true"\u003e \u003c/div\u003e\n\n## 使用永久链接将旧论坛 URL 重定向到新的 Discourse URL\n\n如果您使用我们的导入脚本之一从其他论坛软件迁移到 Discourse,那么您可能希望所有辛苦获得的 Google 搜索结果继续指向相同的内容。Discourse 内置了一种处理此问题的方法,作为编写 nginx 规则的替代方案,它使用永久链接查找表。\n\n永久链接表允许您设置两件事:要匹配的 URL 以及该 URL 应该显示的内容。有几种选项可以定义 URL 应重定向到的位置。设置以下其中之一:\n\n* topic_id:显示一个主题\n* post_id:显示主题中的特定帖子\n* category_id:显示一个分类\n* tag_id:显示一个标签\n* user_id:显示一个用户资料\n* external_url:重定向到一个可能不属于您的 Discourse 实例的 URL\n\n例如,如果您的原始论坛的主题 URL 如下所示:http://example.com/discussion/12345,并且该主题导入后的 URL 是 http://example.com/t/we-moved/987,那么您可以这样设置映射:\n\nbash\ncd /var/discourse\n./launcher enter app\nrails c\nPermalink.create(url: '/discussion/12345', topic_id: 987)\n\n\nDiscourse 将使用 http 响应状态码 301(永久移动)执行重定向到主题 ID 12345 的正确 URL。301 应该会导致搜索引擎更新其记录并开始使用新的 URL。\n\n如果您希望某些 URL 重定向到 Discourse 外部,可以通过设置 external_url 来实现:\n\nruby\nPermalink.create(url: '/discussion/12345', external_url: 'http://archived.example.com/discussion/12345')\n\n\n### 关于主题 URL 上外部永久链接的重要行为\n\n当为Discourse 主题 URL(例如 /t/some-slug/123)创建 external_url 永久链接以重定向到外部站点时,请记住:\n\n- 原始主题应被软删除(而非硬删除)\n- 该主题应属于一个公开分类\n\n原因:如果主题仍然处于活动状态,Discourse 会正常解析它,并且不会使用永久链接查找。\n如果主题位于私人分类中,权限检查可能会返回 404,而不是应用外部永久链接重定向。\n\n这对于应用内导航(已登录用户)尤其重要,因为路由可能被请求为 JSON/XHR。\n\n## 附加信息\n\n要查找子分类的 ID,可以通过 slug 如下查找:\n\nruby\nCategory.find_by_slug('products').id\n\n\n要删除该 URL 的永久链接,请执行此操作:\n\nruby\nPermalink.find_by_url(\"/blah\").destroy\n\n\n每个 URL 只能有一个永久链接记录,因此只需按 URL 搜索即可。\n\n### 从 MyBB 到 Discourse 的主题映射创建\n\n[quote="Dan Dascalescu, post:21, topic:20930, username:dandv"]\n我刚刚使用迁移脚本自动创建了一个从 MyBB 到 Discourse 的主题映射。\n\nMyBB 设置为使用不包含 ID 的 SEO 友好型 URL。现在,例如,当我导航到 /thread-foo-bar 时,nginx 会重定向到 /t/foo-bar/12。以下是我的操作方法:\n\n1. 修补导入器以输出以创建可供 nginx 的map 模块使用的映射文件的行。对于 MyBB 导入器,我在 create_posts 中添加了以下代码:\n\nruby\nparent = topic_lookup_from_imported_post_id(m['first_post_id'])\nif parent\n puts \"\\nXXX #{m['topic_id']}: #{parent[:topic_id]},\"\nend\n\n\n之后,我使用 grep 查找以 XXX 开头的行,删除了 XXX,并将文件制作成一个 JSON 对象,我将其粘贴到此脚本中。更改 URL 以指向您的论坛,运行脚本,其输出将是一系列 nginx map 行。我将其保存为 /etc/nginx/mybb2discourse.map。\n2. 配置 nginx 以“在与 Discourse 相同的机器上运行其他网站”,同时对 nginx 配置文件 (/etc/nginx/conf.d/discourse.conf)进行以下修改,以将 nginx 指向映射文件:\n * 在文件顶部插入此内容:\n\nnginx\nmap_hash_bucket_size 128;\nmap_hash_max_size 50000; # 可能需要增加此值\n\nmap $uri $new {\n include /etc/nginx/mybb2discourse.map;\n}\n\n\n * 然后在 server 部分中,添加:\n\nnginx\nif ($new) {\n rewrite ^ $new permanent;\n}\n\n\n3. 完成上述 Configure nginx… 帖子末尾链接的 nginx 重载和容器重建步骤。\n\n如果有人更擅长 Ruby,可以将导入器打补丁以输出主题 ID 映射(或者更好的是,直接输出 nginx 映射),那将非常有帮助。\n[/quote]\n\n### Discourse 到 WordPress 重定向问题\n\nhttps://meta.discourse.org/t/discourse-to-wordpress-redirect-questions/87031\n\n### 永久链接规范化\n\n[quote="Danny Goodall, post:36, topic:20930, username:bletch"]\n我只是想回顾一下这个问题,提一下我发现的一些陷阱,也许能为未来的探险者留下一些线索——因为我发现调试这个非常困难。\n\n#### 永久链接规范化字符串中的转义\n\n永久链接规范化字符串的格式包含两个组成部分\n\n1. 正则表达式字符串\n2. 替换字符串\n\n它们按照如下方式紧挨着出现在永久链接规范化字符串中\n\ntext\n Permalink Normalization\n Regular Expression Replacement\n\u003c-------------------------\u003e\u003c-------------\u003e\n/(this)reallyis(intuitive)/\\1reallyisn't\\2\n\n\n重要的是,斜杠(和其他 regex 字符)在同一字符串的不同部分中的处理方式不同。\n\n字符串的正则表达式部分中的斜杠(和其他 regex 字符)必须进行转义,然而,替换部分中的斜杠则不需要转义,它们将被视为字面值。\n\n#### 传入 URL 字符串的格式\n\n其次,这花了我一段时间才弄清楚,您匹配的 URL 是相对于根目录的路径描述,但您不会收到开头的 / 作为字符串的第一部分。\n\n例如,如果您的旧论坛使用的 URL 如下所示……\n\nhttp://oldforum.com/chat/the-topic-title/post/d9aa09c3-19bd-4c6e-9d8d-a8f1008000a1\n\n……那么您的永久链接规范化中的正则表达式将与之匹配的 URL 如下所示……\n\nchat/topic-title/post/d9aa09c3-19bd-4c6e-9d8d-a8f1008000a1\n\n即,从根目录开始的路径描述,但不包含前导的 / 斜杠。(我猜测这取决于您重定向的 URL 结构,您的情况可能会有所不同——但我并不这么认为)。\n\n#### 示例\n\n以下是我迁移项目中
是否可以将重写规则直接存储在 discourse docker 集群中?有一个 Web 服务器负责处理 http 和 ssl,我可以在那里添加一些东西吗?
location /threads/ {
rewrite ^/threads/(.*)\.\d+/?$ /t/$1 permanent;
}
我不知道那怎么可能行得通,因为 nginx 不知道新的主题 ID。/threads ID 需要转换为 Discourse 主题 ID。
如果我调用 /threads/name.1234,它会被重写为 /t/name,然后显示正确的帖子,此时 ID 不会被使用,我刚刚测试过。
可能只有在你运气好的时候,Discourse 和你的旧论坛才会生成相同的 slug(并且 slug 不以数字开头),但这可能已经足够了。
如果你想按你建议的那样更改 NGINX,你可以查看 discourse_docker 中的 web 模板,了解如何在容器内更改 nginx 配置。这是一个例子:
非常感谢,我认为这足以分散注意力
我是否必须在每次更新时都进行此更改?
不。您将把它添加到 app.yml 中,它将在每次重建时应用。
为了节省测试时间,您可以:
cd /var/discourse
./launcher enter app
apt update
apt-get install -y vim nano
然后使用 vim 或 nano 编辑您想查看的内容(并为每次重建节省 10-20 分钟)。您可以使用 sv restart nginx 重启 nginx。
以上所有内容均未经测试,但应该接近。
谢谢你的帮助,我已经调整了nginx配置,它能按预期工作。
nginx 必须在 app.yml 的什么位置编写才能自动调整?是在自定义命令的运行区域吗?
因为如果我添加这个:
- replace:
filename: "/etc/nginx/conf.d/discourse.conf"
from: "# auth_basic_user_file /etc/nginx/htpasswd;"
to: "# auth_basic_user_file /etc/nginx/htpasswd;
location /threads/ {
rewrite ^/threads/(.*)\.\d+/?$ /t/$1 permanent;
}"
会报 (\u003cunknown\u003e): 解析带引号的标量时发现未知转义字符 错误。
请查看使用多个域名/重定向设置 Let’s Encrypt,并使用与其中添加至 nginx 配置的示例相同的方式。\n\n您可以将其放在(您将添加的)after_ssl 挂钩中,就像该示例一样。
我仍然收到相同的错误,我认为这与我的格式设置有关。