You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails中Redcarpet Markdown Gem:如何根据href修改target属性?

解决方案

要实现锚点链接(以#开头的href)不设置target,普通链接根据用户偏好添加带随机后缀的_blank target,需要重写Redcarpet的自定义渲染器,在处理每个链接时单独判断href属性:

1. 修改自定义渲染器OurHTML

重写渲染器的link方法,同时添加初始化参数接收用户的新窗口偏好:

class OurHTML < Redcarpet::Render::HTML
  def initialize(options = {}, open_links_in_new_window = false)
    super(options)
    @open_links_in_new_window = open_links_in_new_window
  end

  # 重写link方法,针对每个链接单独处理target
  def link(link, title, content)
    # 构建基础属性字符串
    attrs = []
    attrs << "href=\"#{link}\""
    attrs << "title=\"#{title}\"" if title.present?

    # 判断是否为锚点链接
    if link.start_with?('#')
      # 锚点链接不添加target
      "<a #{attrs.join(' ')}>#{content}</a>"
    else
      # 非锚点链接根据用户偏好添加target
      if @open_links_in_new_window
        target = "_blank#{rand(1000000)}"
        attrs << "target=\"#{target}\""
      end
      "<a #{attrs.join(' ')}>#{content}</a>"
    end
  end
end

2. 调用渲染器时传入用户偏好

在生成Markdown渲染实例前,先判断用户的新窗口设置,再传递给渲染器:

# 读取用户的新窗口偏好设置
open_in_new_window = request.cookies["open_links_in_new_window"].nil? || (request.cookies["open_links_in_new_window"] == "yes")

# 初始化渲染器并传入偏好
options = {}
extensions = { with_toc_data: true } # 保留你的目录生成选项
renderer = OurHTML.new(options, open_in_new_window)
markdown = Redcarpet::Markdown.new(renderer, extensions)
markdown.render(text).html_safe

原理说明

Redcarpet的自定义渲染器允许重写link、header等核心方法,在生成HTML元素时直接控制属性。通过重写link方法,我们能拿到每个链接的具体href值,从而区分锚点链接和普通链接,分别处理target属性,完全满足需求。

内容的提问来源于stack exchange,提问作者user3096851

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 14:25:57