Rails 6:ActionText编码URL、Trix过滤HTML如何禁用?
我之前也碰到过这个一模一样的问题,折腾了好一阵子才搞定,给你拆解两个核心问题的解决方案:
1. 阻止ActionText编码URL中的Liquid变量/自定义标签
ActionText默认会对URL里的特殊字符(比如{{}})进行URI编码,我们需要自定义它的URL sanitizer来绕过这个行为。具体步骤如下:
- 创建自定义的Sanitizer类
在app/lib/custom_action_text_sanitizer.rb中添加:
class CustomActionTextSanitizer < ActionText::Sanitizer private def sanitize_url(url) # 先把Liquid变量临时替换成占位符,避免被编码 liquid_vars = {} url = url.gsub(/{{\s*[\w.]+\s*}}/) do |match| key = "LIQUID_VAR_#{liquid_vars.size}" liquid_vars[key] = match key end # 对剩余部分执行默认的URL sanitize逻辑 sanitized_url = super(url) # 把占位符换回原来的Liquid变量 liquid_vars.each do |key, value| sanitized_url = sanitized_url.gsub(key, value) end sanitized_url end end
- 配置ActionText使用这个自定义Sanitizer
在config/initializers/action_text.rb里添加:
Rails.application.config.action_text.sanitizer = CustomActionTextSanitizer.new
如果你的自定义标签是类似[domain_name]这种,只需要把上面正则表达式改成/\[\w+\]/就行,灵活调整匹配规则即可。
2. 让Trix保留表格、Div及Data属性
Trix和ActionText默认会过滤掉非白名单内的HTML标签和属性,我们需要扩展白名单并配置Trix编辑器:
步骤1:扩展ActionText的Sanitizer白名单
同样在config/initializers/action_text.rb中添加:
# 允许表格相关标签和div ActionText::ContentHelper.ALLOWED_TAGS.add('table', 'thead', 'tbody', 'tr', 'th', 'td', 'div') # 允许所有data-开头的属性 ActionText::ContentHelper.ALLOWED_ATTRIBUTES.add(/data-.+/)
步骤2:配置Trix编辑器支持这些元素
根据你的Rails版本,选择对应的配置方式:
如果你用的是Rails 7+(Importmap方式)
创建app/javascript/initializers/trix_config.js:
import Trix from "trix" // 初始化Trix时注册允许的块级元素 document.addEventListener('trix-initialize', (event) => { const editor = event.target.editor // 注册div作为块级元素 editor.registerBlockType('div', { tagName: 'div', terminal: true, breakOnReturn: true, group: 'block' }) // 允许所有data-属性 editor.enableAttribute('data-*') }) // 处理粘贴HTML时不被Trix自动转换 document.addEventListener('trix-paste', (event) => { const html = event.clipboardData.getData('text/html') if (html) { event.preventDefault() event.target.editor.insertHTML(html) } })
然后在app/javascript/application.js中导入这个初始化文件:
import "@hotwired/turbo-rails" import "controllers" import "./initializers/trix_config" // 添加这一行 import "trix" import "@rails/actiontext"
如果你用的是Rails 6及以下(Sprockets方式)
创建app/assets/javascripts/initializers/trix_config.js:
document.addEventListener('trix-initialize', function(event) { const editor = event.target.editor editor.registerBlockType('div', { tagName: 'div', terminal: true, breakOnReturn: true, group: 'block' }) editor.enableAttribute('data-*') }) document.addEventListener('trix-paste', function(event) { const html = event.clipboardData.getData('text/html') if (html) { event.preventDefault() event.target.editor.insertHTML(html) } })
然后在app/assets/javascripts/application.js中引入:
//= require trix //= require_tree ./initializers //= require rails/actiontext
最后提醒
修改完这些配置后,一定要重启你的Rails服务器,否则初始化文件的修改不会生效。测试的时候直接输入或粘贴你的目标HTML,就能看到它完全保留原样,同时Trix的基础编辑功能(加粗、下划线、段落等)也能正常使用。
内容的提问来源于stack exchange,提问作者Nick M




