Ruby 哈希是不是可以包含在 Sass 和 CoffeeScript 中,从而允许共享数据?

Posted

技术标签:

【中文标题】Ruby 哈希是不是可以包含在 Sass 和 CoffeeScript 中,从而允许共享数据?【英文标题】:Can Ruby hashes be included in Sass and CoffeeScript, allowing data to be shared?Ruby 哈希是否可以包含在 Sass 和 CoffeeScript 中,从而允许共享数据? 【发布时间】:2015-09-01 05:24:07 【问题描述】:

我想知道是否可以在 Sass 和 CoffeeScript 之间轻松共享 ruby​​ 哈希。

我四处寻找答案,但没有找到任何结论。来源,例如documentation for Sass,谈论如何链接相同类型的文件以及如何在语言内操作数据结构,但不涉及是否可以从其他地方导入数据,或者是否可以使用 ruby代码可以以某种方式解释 - 我能想到的唯一类似的事情是指南针使用 .rb 文件进行配置。

我的直觉认为这是(或应该)可能的,两种语言都类似于 Ruby 并且能够解释哈希。

由于这是我多次遇到的实际问题(干燥预处理的前端代码,但也为后端处理提供相同的值,例如在 html 模板中生成 SVG)但从未解决以一种非常干净的方式,我会接受涉及使用 Rails 的解决方案。

请注意,我对前端资产生产的预编译阶段非常具体,即SassCoffeeScript .涉及 CSS、javascript 或需要浏览器的答案不是我想要的。

额外的位

我决定添加一个例子,这里有三个定义相同的数据作为键值对:

Ruby

colours =  brandBackground: '#f00', brandForeground: '#00f', brandText: '#0f0' 
colours[:brandBackground]

Sass Map

$colours: ( brandBackground: '#f00', brandForeground: '#00f', brandText: '#0f0' )
map-get($colours, brandBackground)

CoffeeScript

colours =  brandBackground: '#f00', brandForeground: '#00f', brandText: '#0f0' 
colours.brandBackground

Coffeescript 和 Ruby 哈希定义是相同的,Sass 非常接近……如果这可行,那么颜色(或任何其他变量)可以在一个地方定义,然后由任何代码在前端和后端使用。

【问题讨论】:

我不清楚你到底想要什么,但以 .erb 结尾的文件是 erb 模板。 我添加了一些资源,这些资源涵盖了我知道可能的事情,但不包括是否可以包含 ruby​​ - 我在想象一个插件可能会这样做,但我还没有找到那 @DaveNewton - 我想在 coffee-script 和 sass 这两种具有类似 ruby​​ 语法的语言之间共享一个 ruby​​ 哈希预编译 两者都不会神奇地理解 Ruby。如果您想要 Ruby,请将它们制作成 erb 模板。 @DaveNewton - 听起来很有希望,如何做到这一点 - 是的,我知道他们不会神奇地解释,因此我接受可能存在一些中间阶段,但是,这样做是有价值的 【参考方案1】:

您可以将您的 CoffeeScript 和 SASS 转换为将被预处理的 ERB 模板(因此您可以在其中使用所有出色的 Ruby 可能性)。有一个小帖子描述了这一点:https://robots.thoughtbot.com/dont-repeat-your-ruby-constants-in-javascript。

更新

将此代码添加到lib/shared_assets_data.rb

module SharedAssetsData
  def self.colors_hash
     brandBackground: '#f00', brandForeground: '#00f', brandText: '#0f0' 
  end

  def self.sassify(hash)
    hash.map do |key, value|
      "#key: '#value'"
    end.join(', ').prepend('( ').concat(' )')
  end

  def self.coffefy(hash)
    hash.map do |key, value|
      "#key: '#value'"
    end.join(', ').prepend(' ').concat(' ')
  end
end

然后启用自动加载lib 目录添加这一行到config/application.rb:

config.autoload_paths += %W(#Rails.root/lib)

之后,您可以执行以下操作:

# screen.sass.erb
$colours: <%= SharedAssetsData.sassify(SharedAssetsData.colors_hash) %>
body
  background: map-get($colours, brandBackground)

# screen.coffee.erb
colours = <%= SharedAssetsData.coffefy(SharedAssetsData.colors_hash) %>
console.log colours.brandBackground

【讨论】:

很高兴在答案中看到一个例子,特别是看到有赏金,因为链接腐烂 我相信咖啡脚本可以使用原始哈希,它们是相同的,不需要咖啡化? 我试过了,但是 Ruby 以 Ruby 1.8.7 样式表示法打印散列::a=>1 是的,我的示例中的 Ruby 哈希是较新的语法 目前sassify 方法使用哈希作为参数。因为资产中的这段代码看起来有点笨拙(常量是重复的)。如果您计划在该类中存储所有共享哈希,则可以改进该类以提供更多可读性。如果你愿意,我可以做到。【参考方案2】:

我认为你最好的选择是使用gon。 Gon 是一个允许您将 ruby​​ 变量传递给 javascript/coffeescript 的 gem。从那里您可以内联使用 ruby​​ 哈希的样式。

Sass/CSS 实际上只与样式有关,虽然 Sass 可以有变量并进行数学运算,但您不应该将其用作更复杂数据结构的存储,这将使您的代码难以维护。数据存储和传输并不是 Sass 的工作。

所以,至于 gon。在你的控制器中尝试这样的事情:

gon.ruby_hash = key: value

现在在你的咖啡脚本中:

gon.ruby_hash

您可以通过调用 gon.ruby_variable_name 来访问哈希。

【讨论】:

我不打算将数据存储在 sass 中,而是使用存储在其他地方的数据,以便将数据定义在其他预编译资产可重用的地方 在这种情况下,您需要在 Sass 中定义一个变量,并从您的咖啡脚本中访问它。澄清一下:数据存储在哪里?它是干什么用的?它会改变吗? 数据将与预编译文件一起存储(尽管我想它可以在任何地方);它将存储可以在编译的前端资产之间共享的值,例如断点;是的,它可能会改变,部分原因是更容易以稳健的方式改变共享值; 另外,我希望它独立于任何 Ruby MVC 结构,因此不会有控制器存储任何东西 在这种情况下,编写一个在编译之前运行的脚本,生成一个 variables.scss 文件。在您的 application.scss 中需要该文件。您可以使用 sass 映射 sass-lang.com/documentation/file.SASS_REFERENCE.html#maps,但我必须强调,这不是 sass 的用途。您真的应该考虑其他选项,例如 YAML,或其他一些将数据推送到咖啡/sass/前端的普通 ruby​​ 方法。

以上是关于Ruby 哈希是不是可以包含在 Sass 和 CoffeeScript 中,从而允许共享数据?的主要内容,如果未能解决你的问题,请参考以下文章

gulp-ruby-sass 在 Windows 中不是公认的命令

如何在Ruby中使用来自哈希的查询参数构造URI

gulp-ruby-sass - 'sass' 不是内部或外部命令、可运行程序或批处理文件

如果值递归包含字符串,Ruby 返回***哈希键

如何将 JSON 转换为 Ruby 哈希

ruby 哈希包含另一个哈希,深度检查