问题 可以将Ruby哈希包含在Sass和CoffeeScript中,以便共享数据吗?


我想知道是否可以在Sass和CoffeeScript之间共享ruby哈希,并且最小化。

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

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

由于这是一个实际问题,我已经多次面对(干预预处理的前端代码,但也为后端处理提供相同的值,例如在HTML模板中生成SVG)但从未真正解决过干净的方式我会接受使用Rails的解决方案。

请注意,我对这个问题非常具体 预编译阶段 前端资产生产,即 萨斯 和 CoffeeScript的。涉及CSS,JavaScript或需要浏览器的答案不是我想要的。

额外的位

我决定添加一个示例,这里有三个与键值对相同​​的数据定义:

红宝石

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

萨斯地图

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

CoffeeScript的

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

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


12542
2018-06-16 11:52


起源

我不清楚你究竟想要什么,但以.erb结尾的文件是erb模板。 - Dave Newton
我添加了一些内容,涵盖了我知道可能的事情,但不是否可以包含ruby - 我想象一个插件可能会这样做,但我还没有找到 - Toni Leigh
@DaveNewton - 我想在coffee-script和sass之间共享ruby hash预编译,这两种语言具有类似ruby的语法 - Toni Leigh
也不会神奇地理解Ruby。如果你想要Ruby,那就让它们成为erb模板。 - Dave Newton
@DaveNewton - 看起来很有希望,怎么可能这样做 - 是的,我明白他们不会神奇地解释,因此我接受可能有一些中间阶段,但是,这样做有价值 - Toni Leigh


答案:


您可以将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

10
2018-06-21 20:52



很高兴在答案中看到一个例子,特别是看到有赏金,并且因为链接腐烂 - Toni Leigh
当然,更新的答案,希望它有所帮助。 - hedgesky
我相信咖啡脚本可以使用原始哈希,它们是相同的,不需要咖啡化? - Toni Leigh
我尝试过,但是Ruby以Ruby 1.8.7样式表示法打印哈希:{:a => 1} - hedgesky
是的,我的例子中的Ruby哈希是更新的语法 - Toni Leigh


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

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

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

gon.ruby_hash = {key: value}

现在在你的coffeescript:

gon.ruby_hash

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


-1
2018-06-16 13:26



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