大家好,
我正在使用 Discourse 集成来托管位于子域名的博客评论,但现在希望将博客迁移到顶级域名的子路径下。
例如:目前博客位于
但我希望将其迁移到
我该如何更新现有的 Discourse 评论主题,使其指向新的博客位置?
我猜可以手动更新帖子内容,但访问新的博客站点时,由于 URL 已更改,是否会创建新的主题?
(该博客是 Ghost 博客,如有影响请告知)
任何帮助都将不胜感激。
Brad
大家好,
我正在使用 Discourse 集成来托管位于子域名的博客评论,但现在希望将博客迁移到顶级域名的子路径下。
例如:目前博客位于
但我希望将其迁移到
我该如何更新现有的 Discourse 评论主题,使其指向新的博客位置?
我猜可以手动更新帖子内容,但访问新的博客站点时,由于 URL 已更改,是否会创建新的主题?
(该博客是 Ghost 博客,如有影响请告知)
任何帮助都将不胜感激。
Brad
我最近处理过类似的情况。当时,该网站已经更改了博客的域名。这样做导致的结果是,对于任何已经生成 Discourse 主题的博客文章,Discourse 上都会创建重复的主题。
解决方案是从网站的 Rails 控制台运行一个脚本,查找所有 embed_url 指向旧域名的 TopicEmbed 条目。在删除重复主题对应的 TopicEmbed 条目后,将这些 embed_url 值更新为正确的域名。随后,删除新生成的重复主题。
这似乎是一种解决该问题的复杂方法。我可以发布我所用脚本的详细信息,但也非常希望听到其他人是否有更好的处理思路。随着嵌入主题的普及,这类问题迟早会再次出现。
嗨,Simon,
谢谢。
那太棒了(任何关于如何运行该脚本的信息都会有帮助)。
我想我需要手动更新那些链接回原始文章的帖子内容。(例如,帖子文本中写着“这是原始条目……的配套讨论主题”的部分。)
我同意——虽然这种情况很少需要处理,但一旦需要,似乎非常棘手。
Brad
我将在此分享脚本。请注意,我不确定这是否是解决该问题的最佳方案。该脚本需要在域名更改导致重复主题开始创建之后运行。由于直到用户开始访问新域名下的博客文章时才会创建这些主题,因此您可能需要多次运行该脚本以捕获所有主题。请务必将脚本第一行中的 old.domain.com 替换为您博客原来的实际域名。
# 首先运行此部分:
original_embeds = TopicEmbed.where("embed_url LIKE ?", "%old.domain.com%")
# 然后运行:
original_embeds.each do |original_embed|
original_topic = Topic.find(original_embed.topic_id)
if (original_topic && original_topic.title)
possible_dups = Topic.where(title: original_topic.title).order(:created_at)
if possible_dups.length === 2
new_embed = TopicEmbed.find_by(topic_id: possible_dups.last.id)
new_embed_url = new_embed.embed_url
puts "正在销毁 TopicEmbed: #{new_embed.id} 主题: #{new_embed.topic_id}"
new_embed.destroy
puts "正在更新 TopicEmbed: #{original_embed.id} 新 embed_url: #{new_embed_url}"
original_embed.update(embed_url: new_embed_url)
end
end
end
要运行脚本,请进入您网站的 Rails 控制台,然后将脚本的第一行复制进去并执行。这会将 original_embeds 变量设置为 TopicEmbed 记录的数组。完成后,您可以将脚本的其余部分复制到控制台中并运行。
为了安全起见,在运行脚本之前,您应该备份网站的数据库。此外,最好先进行一次不执行任何更改的试运行。以下代码可实现此目的:
original_embeds.each do |original_embed|
original_topic = Topic.find(original_embed.topic_id)
if (original_topic && original_topic.title)
possible_dups = Topic.where(title: original_topic.title).order(:created_at)
if possible_dups.length === 2
new_embed = TopicEmbed.find_by(topic_id: possible_dups.last.id)
new_embed_url = new_embed.embed_url
puts "(试运行) 正在销毁 TopicEmbed: #{new_embed.id} 主题: #{new_embed.topic_id}"
#new_embed.destroy
puts "(试运行) 正在更新 TopicEmbed: #{original_embed.id} 新 embed_url: #{new_embed_url}"
#original_embed.update(embed_url: new_embed_url)
end
end
end
在取消注释那些会对数据库进行实际更改的行之前,请确保输出看起来合理。
脚本执行的操作如下:
original_embeds 变量被设置为所有匹配您博客旧域名的 TopicEmbed 记录。
对于每个 original_embeds,它会尝试查找具有重复标题的主题(即新的重复嵌入)。
如果找到重复主题,并且为该重复主题找到了 TopicEmbed 记录,则该 TopicEmbed 记录将被删除,其 embed_url 属性的值将被转移到旧的 TopicEmbed 记录中。
我强烈建议在执行实际更改的脚本之前先进行试运行(使用本文中的第二个脚本)。如果试运行返回任何错误,您需要查明原因。查看代码后,我发现了一个潜在问题:如果您的 Discourse 网站上存在一个主题,其标题与某个嵌入主题的标题重复,但该主题没有关联的 TopicEmbed,则可能会发生这种情况。如果是这种情况,是可以处理的。
嗨,Simon,
这真的很有帮助,谢谢。
就我的情况而言,我觉得事情更简单,因为博客站点尚未迁移,而且我没有任何重复内容。我想我只需要更新现有的嵌入条目,使用新的 URL 即可。
我从未使用过 Ruby,但根据你的示例,我拼凑出了下面的脚本。除了更新主题嵌入外,我还扩展了它,以同时更新相关帖子中的文本和链接。
能否请你快速过目一下,确认我是否走在正确的轨道上?我已经在注释掉更新操作的情况下运行了它,看起来它显示的内容是正确的。
(顺便问一下:运行这些脚本的常规方式是什么?我一直在文本编辑器中编辑,然后粘贴到控制台中执行。)
Brad
original_embeds = TopicEmbed.where("embed_url LIKE ?", "https://blog.cantabilesoftware.com%")
old_url_prefix = "https://blog.cantabilesoftware.com/"
new_url_prefix = "https://www.cantabilesoftware.com/blog/"
original_embeds.each do |original_embed|
new_embed_url = original_embed.embed_url
new_embed_url.sub!(old_url_prefix, new_url_prefix)
puts "Updating TopicEmbed: #{original_embed.id} with new url: #{new_embed_url}"
#original_embed.update(embed_url: new_embed_url)
post = Post.find_by(id: original_embed.post_id)
new_raw = post.raw
new_raw.gsub!(old_url_prefix, new_url_prefix)
new_cooked = post.cooked
new_cooked.gsub!(old_url_prefix, new_url_prefix)
puts "Updating raw with #{new_raw}"
puts "Updating cooked with #{new_cooked}"
#post.update(raw: new_raw, cooked: new_cooked)
end
为记录在案,上述操作运行顺利。以下是我遵循的完整流程:
非常感谢 @simon 在此过程中提供的帮助。![]()