Forgot password?
 Create new account
View 94|Reply 3

Discourse 中 wiki 帖子可以被未创建原帖的用户编辑

[Copy link]

3148

Threads

8489

Posts

610K

Credits

Credits
66148
QQ

Show all posts

hbghlyj Posted at 2025-3-25 09:28:47 |Read mode
本指南解释了如何在 Discourse 中创建和编辑 Wiki 帖子,这些帖子允许社区内的协作编辑和知识共享。Wiki 帖子对于文档、常见问题解答以及其他需要社区输入和定期更新的内容非常有用。

要识别 Wiki 帖子,请寻找一个独特的图标和一个显眼的编辑按钮。您还可以使用站点搜索框中的 in:wiki 过滤器搜索 Wiki 帖子。

编辑 Wiki 帖子需要达到信任等级 1 或更高。要编辑,请导航到 Wiki 帖子并点击右下角的编辑按钮。编辑会记录在帖子的编辑历史中,并在编辑完成后向帖子作者发送通知。

Wiki 帖子的最佳实践包括将其用于需要协作编辑的内容、尊重其他贡献者的工作以及使用编辑历史跟踪更改。

请注意,不支持同时编辑,用户无法阻止其它用户编辑其 Wiki 帖子。

要查看 wiki 帖子的编辑历史,请点击右上角的编辑指示器:

编辑历史和信息与普通帖子相同:


创建或移除 wiki 帖子  
要将您自己的帖子转换为 wiki 帖子,您需要达到信任等级 3(默认)。信任等级 4、版主和管理员可以将任何帖子转换为 wiki。

主题中的任何帖子都可以转换为 wiki。通常会将第一条帖子设置为 wiki,但这不是强制要求。

如何创建 wiki 帖子:
要将普通帖子转换为 wiki,请打开帖子底部的 … 菜单,选择扳手图标,然后选择“创建 Wiki”选项。


如何移除 wiki 帖子:  
如果帖子已经是 wiki,则会显示“移除 Wiki”按钮,而不是“创建 Wiki”按钮。

将 wiki 帖子转换回普通帖子时,编辑历史将正常保留。

3148

Threads

8489

Posts

610K

Credits

Credits
66148
QQ

Show all posts

 Author| hbghlyj Posted at 2025-3-25 09:37:06
每次进行更改时,都会在数据库中创建一个单独的副本,然后将其与输出进行比较。
在那里创建了帖子的完整副本。

我们看到随着时间的推移有 14 次编辑。
在这种情况下,在数据库中的 post_revisions 表的大小是原始帖子的 14 倍

3148

Threads

8489

Posts

610K

Credits

Credits
66148
QQ

Show all posts

 Author| hbghlyj Posted at 2025-3-25 10:01:04

存储 discourse 库中的帖子修订的代码。

负责将帖子修订保存到 discourse/discourse 存储库中的 post_revisions 表中的代码位于以下位置:

Post Revisor类 (lib/post_revisor.rb):
  1. def create_revision
  2.   modifications = post_changes.merge(@topic_changes.diff)
  3.   modifications["raw"][0] = cached_original_raw || modifications["raw"][0] if modifications["raw"]
  4.   if modifications["cooked"]
  5.     modifications["cooked"][0] = cached_original_cooked || modifications["cooked"][0]
  6.   end
  7.   @post_revision = PostRevision.create!(
  8.     user_id: @post.last_editor_id,
  9.     post_id: @post.id,
  10.     number: @post.version,
  11.     modifications: modifications,
  12.     hidden: only_hidden_tags_changed?
  13.   )
  14. end
  15. def update_revision
  16.   return unless revision = PostRevision.find_by(post_id: @post.id, number: @post.version)
  17.   revision.user_id = @post.last_editor_id
  18.   modifications = post_changes.merge(@topic_changes.diff)
  19.   modifications.each_key do |field|
  20.     if revision.modifications.has_key?(field)
  21.       old_value = revision.modifications[field][0]
  22.       new_value = modifications[field][1]
  23.       if old_value.to_s != new_value.to_s
  24.         revision.modifications[field] = [old_value, new_value]
  25.       else
  26.         revision.modifications.delete(field)
  27.       end
  28.     else
  29.       revision.modifications[field] = modifications[field]
  30.     end
  31.   end
  32.   if revision.modifications.empty?
  33.     revision.destroy
  34.     @post.last_editor_id = PostRevision.where(post_id: @post.id).order(number: :desc).pick(:user_id) || @post.user_id
  35.     @post.version -= 1
  36.     @post.public_version -= 1
  37.     @post.save(validate: @validate_post)
  38.   else
  39.     revision.save
  40.   end
  41. end
Copy the Code

此文件包含创建和更新帖子修订的逻辑。具体来说,请查看 create_revision 和 update_revision 方法。

Post Revision模型 (app/models/post_revision.rb):
  1. class PostRevision < ActiveRecord::Base
  2.   belongs_to :post
  3.   belongs_to :user
  4.   serialize :modifications, type: Hash, coder: YAML
  5.   after_create :create_notification
  6.   def create_notification
  7.     PostActionNotifier.after_create_post_revision(self)
  8.   end
  9. end
Copy the Code

此模型定义 PostRevision 类并包含 after_create 回调以创建通知。

posts 控制器 (app/controllers/posts_controller.rb):
  1. def revisions
  2.   post = find_post_from_params
  3.   raise Discourse::NotFound if post.hidden && !guardian.can_view_hidden_post_revisions?
  4.   post_revision = find_post_revision_from_params
  5.   post_revision_serializer = PostRevisionSerializer.new(post_revision, scope: guardian, root: false)
  6.   render_json_dump(post_revision_serializer)
  7. end
  8. def hide_revision
  9.   post_revision = find_post_revision_from_params
  10.   guardian.ensure_can_hide_post_revision!(post_revision)
  11.   post_revision.hide!
  12.   post = find_post_from_params
  13.   post.public_version -= 1
  14.   post.save
  15.   post.publish_change_to_clients!(:revised)
  16.   render body: nil
  17. end
  18. def permanently_delete_revisions
  19.   guardian.ensure_can_permanently_delete_post_revisions!
  20.   post = find_post_from_params
  21.   raise Discourse::InvalidParameters.new(:post) if post.blank?
  22.   raise Discourse::NotFound if post.revisions.blank?
  23.   RateLimiter.new(current_user, "admin_permanently_delete_post_revisions", 20, 1.minute, apply_limit_to_staff: true).performed!
  24.   ActiveRecord::Base.transaction do
  25.     updated_at = Time.zone.now
  26.     post.revisions.destroy_all
  27.     post.update(version: 1, public_version: 1, last_version_at: updated_at)
  28.     StaffActionLogger.new(current_user).log_permanently_delete_post_revisions(post)
  29.   end
  30.   post.rebake!
  31.   render body: nil
  32. end
Copy the Code

此控制器包含与帖子修订相关的操作,例如创建、更新、显示和隐藏修订。

3148

Threads

8489

Posts

610K

Credits

Credits
66148
QQ

Show all posts

 Author| hbghlyj Posted at 2025-3-25 10:15:34

Discourse论坛的帖子查看编辑历史差异

在 Discourse 论坛帖子中,例如 meta.discourse.org/t/help-us-test-the-rewritten-composer/34679,单击铅笔按钮将显示其编辑历史记录,并且有3种查看方法可切换:内联差异、并排差异和原始代码差异

负责创建帖子修订差异视图的代码位于以下位置:

Discourse Diff 类 (lib/discourse_diff.rb):
  1. class DiscourseDiff
  2.   def inline_html
  3.     # Implementation for inline HTML diff
  4.   end
  5.   def side_by_side_html
  6.     # Implementation for side-by-side HTML diff
  7.   end
  8.   def side_by_side_markdown
  9.     # Implementation for side-by-side markdown diff
  10.   end
  11. end
Copy the Code

此文件包含用于生成内联 HTML、并排 HTML 和并排 markdown 差异的方法。

帖子修订序列化器 (app/serializers/post_revision_serializer.rb):
  1. class PostRevisionSerializer < ApplicationSerializer
  2.   def body_changes
  3.     cooked_diff = DiscourseDiff.new(previous["cooked"], current["cooked"])
  4.     raw_diff = DiscourseDiff.new(previous["raw"], current["raw"])
  5.     {
  6.       inline: cooked_diff.inline_html,
  7.       side_by_side: cooked_diff.side_by_side_html,
  8.       side_by_side_markdown: raw_diff.side_by_side_markdown,
  9.     }
  10.   end
  11. end
Copy the Code

此文件使用 DiscourseDiff 类序列化帖子修订,包括正文更改、标题更改和其他与差异相关的数据。

Post Revisor 类 (lib/post_revisor.rb):
  1. def create_revision
  2.   modifications = post_changes.merge(@topic_changes.diff)
  3.   @post_revision = PostRevision.create!(
  4.     user_id: @post.last_editor_id,
  5.     post_id: @post.id,
  6.     number: @post.version,
  7.     modifications: modifications,
  8.     hidden: only_hidden_tags_changed?,
  9.   )
  10. end
Copy the Code

此文件处理帖子修订的创建和更新,并与 DiscourseDiff 类集成以生成差异。

手机版Mobile version|Leisure Math Forum

2025-4-20 12:07 GMT+8

Powered by Discuz!

× Quick Reply To Top Return to the list