在 ERB 块中的字符串内包含 ERB 分隔符

2023-11-22

我正在编写一个显示代码以及输出的样式指南。目前它的结构使得代码只需要描述一次,并以原始版本和解释版本显示,如下所示:

<% code = <<PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
<div>
  #{ image_tag 'image.png' }
</div>  
PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
%>

<%= raw code %>
<%= content_tag :pre, code, class: "prettyprint linenums" %>

这很棒,而且相当容易维护。问题出在 Rails 助手上,比如image_tag在上面的例子中。视图示例正确显示 div 中的图像,代码示例显示相关 HTML。在这种情况下,相关的 HTML 包含一个锚标记 - 的结果image_tag方法,而不是调用本身。

我更喜欢代码示例来显示辅助方法,而不是它们的结果。我可以通过在文件中指定示例代码并渲染或读取文件来完成这项工作。我更愿意通过在变量中指定代码来完成这项工作,如上所述,但我似乎无法让 ERB 分隔符在 erb 块内的字符串内部工作。即使是最简单的情况<% foo = '<%= bar %>' %>根本不起作用。我尝试过使用语法(<%% %%> and % %例如),使用来自官方文档,但没有取得太大成功。

我能找到的关于此事的唯一信息是here, using <%= "<" + "%=" %> link_to <%= image.css_tag.humanize %> <%= "%" + ">" %> %>,这在此用例中不起作用(如果有的话)。

那么,有没有办法指定包含 ERB 结束分隔符的字符串(%>) 在 ERB 字符串中,或​​者我是否一直使用稍微笨拙的文件读取方法?谢谢!

Edit:

我最终想要的是一个工作版本:

<%# Idealized code - does not work %>
<% code = <<PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
<div>
  <% image_tag 'image.png' %>
</div>  
PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
%>

So that <%= raw code %>将(继续)输出:

<div>
  <img src="/images/image.png" alt="Image" />
</div>

And <%= content_tag :pre, code, class: "prettyprint linenums" %>会输出:

<pre class="prettyprint linenums">
  <div>
    <% image_tag 'image.png' %>
  </div>  
</pre>

而不是它当前使用变量时所做的事情,即:

<pre class="prettyprint linenums">
  <div>
    <img src="/images/image.png" alt="Image" />
  </div>
</pre>

我希望用户能够复制代码示例并将其粘贴到新视图中,而无需将 HTML 翻译回生成它们的帮助程序。我认为我基本上需要的是一个替代的 ERB 分隔符,就像' and "(甚至%q{}) 因字符串而异。看起来,即使最终的 ERB 分隔符出现在字符串内部,它实际上也是作为块的末尾进行处理的。最简单的情况是<% foo = '<%= bar %>' %>在某种程度上展示了我想要实现的目标。在生成器中,您可以使用<% foo = '<%%= bar %>' %>(或类似的东西),告诉它不要当场作为 ERB 进行处理。从文件读取时,甚至在纯 rb 文件(如助手)中读取时,这一切都可以正常工作,但在这种情况下,将其放入视图中是最有意义的,因为它的目的是让我们可以轻松操作设计师。


如果我理解正确,那么您真正的问题是,就插值而言,heredocs 的行为类似于双引号。因此,您所需要的只是一个行为类似于单引号的引用机制。 Ruby 有很多字符串引用机制,特别是我们有%q{...}:

<% code = %q{
<div>
  #{ image_tag 'image.png' }
</div>  
} %>

如果您愿意,可以使用其他分隔符:%q|...|, %q(...)当然还是有变化,但至少你不用担心插值问题。

如果你确实想使用heredoc,你可以指定带引号的定界符终止符并且相应的引用样式将应用于内容:

<% code = <<'PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR'
<div>
  #{ image_tag 'image.png' }
</div>  
PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
%>

中的单引号<<'PLACE...'指定单引号规则(即无插值)适用于此处文档的内容。


当然,这些东西都不适用于嵌入式 ERB,如下所示:

<% code = %q{
<div>
  <% ... %>
</div>  
} %>

因为 ERB 解析器会看到第一个%>作为外部的结束分隔符<% code...部分。不用担心,我想我有一个计划,可以在不涉及严重黑客攻击或太多工作的情况下发挥作用。

一些预备知识:

  • 导轨用途Erubis用于 ERB 处理。
  • Erubis 让您能够更改分隔符:pattern option到它的构造函数。
  • 导轨用途Tilt and 链轮处理模板处理管道,这些允许您做出正确的事情pancakes.js.coffee.erb以正确的顺序。

使用上面的内容,您可以添加自己的模板格式,即具有不同分隔符的 ERB,并且您可以让 Rails 使用这种新格式来处理您的“特殊”部分,然后正常的 ERB 处理会造成混乱。

首先你需要连接Tilt。如果你看一下lib/tilt/erb.rb在你的 Tilt 安装中,你会看到 Erubis 的东西Tilt::ErubisTemplate在底部。你应该能够子类化Tilt::ErubisTemplate并提供一个prepare覆盖添加,比如说,:pattern => '<!--% %-->'选项和弃踢到超类。然后在 Rails 初始化程序中使用 Tilt 和 Sprockets 注册它,如下所示:

Tilt.register(Your::Template::Subclass, 'klerb') # "kl" for "kludge" :)
Rails.application.assets.register_engine('.klerb', Your::Template::Subclass)

现在您的应用程序应该能够处理.klerb文件与<!--% ... %-->作为模板分隔符。您还可以使用以下名称将您的 klerb 与 erb 链接起来pancakes.html.erb.klerb文件将在 ERB 之前经过 klerb;这意味着像这样的模板(在一个名为whatever.html.erb.klerb):

<!--% code = <<PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
<div>
  <% image_tag 'image.png' %>
</div>  
PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
%-->
<!--%= "code = escape_the_erb_as_needed(%q{#{code}})" %-->
<% do_normal_erb_stuff %>

会做正确的事。

你需要一个帮助者来实现escape_the_erb_as_needed当然是功能性;一些小实验应该可以帮助你弄清楚什么需要逃避以及以什么方式逃避。

所有这些可能看起来有点复杂,但实际上非常简单。我使用 Tilt 和 Sprockets 添加了自定义模板处理步骤,最终结果非常简单;弄清楚要做哪些简单的事情需要一些工作,但我已经为您完成了这项工作:

  1. Tilt::Template子类,你可以通过小猪支持来得到这个Tilt::ErubisTemplate.
  2. 通过拨打电话注册 TiltTilt.register.
  3. 通过致电注册 SprocketsRails.application.assets.register_engine.
  4. ...
  5. Profit.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 ERB 块中的字符串内包含 ERB 分隔符 的相关文章

  • Rails 急切加载计数?

    使用 include 属性可以很好地进行预加载 Post find all include gt author 我想知道您是否也可以急切加载计数 例如我是否想获取每个帖子的评论数量 而不加载所有评论本身 也许像 Post find all
  • 使用 mysql2 gem 获取最后插入的 id

    我有这样的代码 require mysql2 db query insert into clients Name values client 我可以通过 1 个查询返回最后插入的 ID 吗 您可以使用last id客户端实例的方法 clie
  • 该块如何用于整数倍方法?

    我不明白如何n times该行在下面给出的 ruby 代码中工作 特别是逗号的含义以及如何new变量已更新 def fib n raise fib not defined for negative numbers if n lt 0 new
  • ruby 1.9.1 的 gem install mongrel 失败

    昨天我开始了 Rails 开发 我安装了 ruby 1 9 1 rubygems 和 Rails 跑步gem install mongrel工作得很好 表面上也安装了杂种 我有点困惑 因为 script server 默认启动 webric
  • 在 Rails ActiveAdmin 视图中添加指向 Flash 通知的链接

    我正在尝试在活动管理控制器成功创建操作的闪存消息中添加链接 但是该链接的 HTML 被转义并在视图上显示为纯文本 Rails 5 2 1 ruby 2 5 3p105 2018 10 18 修订版 65156 x86 64 linux 例如
  • 我可以从安装 Rails 引擎的真实应用程序运行它的规格吗?

    我有一个 Rails 引擎 旨在为我们的一个更大的项目提供一些模型和控制器 引擎有一套相当不错的规格 在引擎的虚拟应用程序中使用了一堆模拟和一些全尺寸模型和控制器 以确保引擎正在做它应该做的事情并与更大的应用程序一起工作 然而 即使所有测试
  • 对 Rails 3.1 中的特定路由强制使用 SSL

    我需要强制启用 SSL所有路线在我的申请中除了landing index In config application rb 我有 config force ssl true Then in landing controller rb 我有
  • 使用 Devise 和 Rails 从 Twitter Oauth 获取电子邮件

    我已经设置了一个基本的 Rails 应用程序来使用 twitter oauth gem 和设计 并且已经能够登录用户 但是 我的问题是我现在已将我的应用程序列入白名单 并且我想在响应中收到用户的电子邮件 我已遵循 Twitter 端的所有必
  • simple_fields_for 没有出现 [rails 4]

    我正在尝试创建两个隐藏字段 其中一个显示没有问题 但来自嵌套表单的另一个则没有 产品 rb class Product lt ActiveRecord Base has many product options dependent dest
  • 无法在 IE 上运行 Selenium 脚本

    我必须在 IE 10 浏览器上运行 Selenium 测试 为了运行以下脚本 我执行了以下操作 下载IEDriverServer 64位 因为我的机器是64位 here http code google com p selenium dow
  • Flash观看后不清晰

    这是我的创建动作 它创建一个新的 Message 实例 并通过模型验证进行检查 然后有一个简单的 if else 循环 如果模型验证已完成 则发送消息 如果要发送另一个视图 则渲染 新 视图 如果模型验证未得到满足 它只会再次呈现 新 视图
  • Rails 中的 plusDomains.circles.addPeople 的 Google API 产生 403 Forbidden

    Using Google API Ruby 客户端 https github com google google api ruby client class GooglePlus def self follow contact contac
  • Heroku 上的 Google Vision API 身份验证

    在 Heroku 上验证 Vision API 的最佳 简单方法是什么 在开发中我只使用 vision Google Cloud Vision new project instacult keyfile path to keyfile js
  • Ruby on Rails 从视图路由到控制器中的自定义方法

    我有一个控制器名称帖子 在我的 config routes rb 我用过这个 resources posts app controllers posts controller rb class PostsController lt Appl
  • 如何生成devise gem的注册控制器

    我已经设置了 Devise 我已经在 user rb 文件中设置了以下代码 def self create auto password generated password Devise friendly token first 8 sel
  • 这个结果背后的逻辑是什么?

    def foo override end p foo bye bye p foo hello world Output override hello 我可以理解如果结果是 override world or even bye bye hel
  • Rails escape_javascript 通过转义单引号创建无效的 JSON

    ActionView中的escape javascript方法转义撇号 作为反斜杠撇号 解析为 JSON 时会出错 例如 消息 我在这里 在打印时是有效的 JSON message I m here But 输出 I m here 导致无效
  • 如何在Windows 7上运行Ruby程序?

    有谁知道如何在 Windows 7 上运行 编译 Ruby 程序 例如 你可以在 Eclipse 中编译 Java 但我似乎找不到 Ruby 的编译器 http rubyinstaller org http rubyinstaller or
  • 如何使用 rspec 测试条件 ActiveRecord after_update 回调?

    我有一个触发作业的条件回调 如果经理发生变化 则应调用该方法 class Employee lt ActiveRecord Base after update employee manager on change if employee i
  • Rails 7 缺失部分

    我正在升级到 Rails 7 1 并在使用 JS 部分的视图中遇到奇怪的错误 缺少部分 account stripe js erb application stripe js erb 与 locale gt fr formats gt ht

随机推荐

  • 如何在 jQuery 中制作实时自定义事件

    jQuery 有一个非常方便的事件绑定器 称为 live 它将动态添加事件到 DOM 元素 甚至对于稍后将添加到 DOM 的元素 问题是它只适用于特定事件 在文档中列出 我真的很想举办现场活动来聚焦 模糊和改变 但目前现场不支持 此外 如果
  • WP Rest API + AngularJS:如何抓取特色图像以显示在页面上?

    我正在通过 HTTP REST API 插件访问 WordPress 数据 此 WordPress 插件 http v2 wp api org 我知道如何获取我的帖子标题 但如何使用此插件显示与该帖子相关的特色图像 我的测试显示了帖子标题和
  • 将 (0/1) 字符串加载到位数组中

    将 10101011101010 这样的字符串直接加载到新的字符串中最聪明的方法是什么位数组 不是字节数组 这些位的顺序应与列表中的顺序相同 您可以使用 LINQ 来做到这一点 var res new BitArray str Select
  • 在缩略图悬停时显示更大的图像

    对于图像列表 我有方形缩略图的网址http example com img1 thumb jpg以及原始尺寸 任何比例 http example com img1 jpg 我在网格中显示缩略图 当用户将鼠标放在网格中的图像上时 我想显示原始
  • 如何使用学说在单个查询中获取整个树?

    此片段来自官方网站按预期工作 treeObject Doctrine getTable Category gt getTree rootColumnName treeObject gt getAttribute rootColumnName
  • 将变量从 shell 脚本传递到 applescript

    我有一个 shell 脚本 我称之为使用osascript 然后osascript调用 shell 脚本并传入我在原始 shell 脚本中设置的变量 我不知道如何将该变量从 applescript 传递到 shell 脚本 如何将变量从 s
  • 如何将 ExifInterface 与流或 URI 结合使用

    我正在编写一个应用程序 可以从 Android 中的 共享方式 菜单发送照片 URI 您获得的 URI 类型是content media external images media 556然而ExifInterface想要一个标准的文件名
  • git rebase 删除提交

    我的 git 存储库中有以下更改历史记录 X Y Z A B C 我从代码 Z 的基础开始工作 并进行了 A B 和 C 三个更改 这些更改中的每一个都已作为单独的评论上传到 Gerrit 上 并且每个更改都取决于之前的更改 经过审查后 我
  • 视频元素在 IE8 中不显示?

    我想在所有浏览器中嵌入视频元素 但它在除 IE8 之外的所有浏览器中都可以正常工作 这里 我使用 mediaelement js 库来实现 首先 需要尝试以下几件事 确保 IE8 上安装了 Flash 这是旧版浏览器中 Mediaeleme
  • 无法在 Android Studio 中打开密钥库 - “找到冗余长度字节”

    我无法在 Android Studio 中打开现有的密钥库文件或使用jarsigner从命令行 在这两种情况下 错误消息都是 java security cert CertificateException 无法初始化 java io IOE
  • 如何让 AngularJS BLOB 下载 PDF?

    大家好 我对使用 AngularJS 进行开发非常陌生 我正在尝试弄清楚如何使用 BLOB 将 PDF 下载到本地计算机 我已经让它可以使用 JSON 现在我需要一个 PDF 我写了一些代码 但它似乎不起作用 html
  • 如何知道opencv中SSE2是否激活

    我有一个版本的 OpenCV 2 4 10 库 它是为 Windows 上的 Intel X64 构建的 我如何知道 CV SSE2 是否处于活动状态 我没有代码 我只有库 DLL 和标头 Thanks 您可以使用该功能检查SSE2是否启用
  • 如何在文档的 部分创建 Angular 指令?

    我是新来的angular js 我正在尝试创建一个指令来添加一些标题和元标记html 文档的一部分 但我遇到了一些麻烦 My index html文件如下
  • Rails 3 - Amazon S3 Paperclip EU 问题

    我在用着 Paperclip 2 3 16 Rails 3 0 9 Ruby 1 9 2 AWS S3 0 6 2 我正在尝试使用回形针上传到基于欧盟 爱尔兰 的存储桶 我的模型中有以下内容 has attached file image
  • 在其他项目中重用 Cucumber-JVM 步骤定义

    如何在其他项目中重用 Cucumber JVM 步骤定义来测试一些典型的 Web 操作 重点是 我创建了一些 java 项目 仅使用典型场景操作的步骤定义实现 例如 When I follow the link some link Then
  • Razor HTML 条件输出

    我有一个要作为主内容输出的项目列表 下面不包括主内容 每个项目都有 3 个属性 部分名称 标签和值 每个项目都包含在 a 中 每次部分名称更改时 我都必须打开 a 并关闭前一个 如果有的话 我正在使用带有以下代码的 Razor 视图 for
  • 保存为表单中的文件

    使用 Canvas 方法 toDataURL 我希望能够将图像保存在服务器端 使用 Rails 有了 toDataURL 字符串 如何在 HTML 表单中可以将其视为文件附件的表单中使用它 使用 jQuery Paperclip dataf
  • Intl.DateTimeFormat 返回超过 24 小时

    我有以下 Unix 时间戳 1611328500000 Fri Jan 22 2021 10 15 00 GMT 0500 Eastern Standard Time 我需要以韩国标准时间显示它 为此 我正在使用Intl DateTimeF
  • 在 Chrome 中拦截对 console.log 的调用

    我有一个无法更改的脚本 它会产生很多console log来电 我想添加另一层并在调用包含某些字符串时进行响应 这在 Firefox 中有效 但会抛出 Illegal invocation Chrome 中第 4 行出现错误 var old
  • 在 ERB 块中的字符串内包含 ERB 分隔符

    我正在编写一个显示代码以及输出的样式指南 目前它的结构使得代码只需要描述一次 并以原始版本和解释版本显示 如下所示