使用带有Rails资产管道的字体

我有一些字体被配置在我的Scss文件如下:

@font-face {
font-family: 'Icomoon';
src: asset-url('icoMoon.eot?#iefix', font) format('embedded-opentype'),
asset-url('icoMoon.woff', font) format('woff'),
asset-url('icoMoon.ttf', font)  format('truetype'),
asset-url('icoMoon.svg#Icomoon', font) format('svg');
}

实际的字体文件存储在/app/assets/fonts/中

我已经在我的应用程序中添加了config.assets.paths << Rails.root.join("app", "assets", "fonts")。rb文件

编译CSS源代码如下:

@font-face {
font-family: 'Icomoon';
src: url(/assets/icoMoon.eot?#iefix) format("embedded-opentype"), url(/assets/icoMoon.woff) format("woff"), url(/assets/icoMoon.ttf) format("truetype"), url(/assets/icoMoon.svg#Icomoon) format("svg");
}

但当我运行应用程序的字体文件没有被发现。日志:

Started GET "/assets/icoMoon.ttf" for 127.0.0.1 at 2012-06-05 23:21:17 +0100 已服务的资产/icoMoon.ttf - 404 Not Found (13ms)

.ttf

为什么资产管道不把字体文件压缩成/assets?

大家有什么想法吗?

< p >亲切的问候, 尼尔。< / p >

额外信息:

当检查rails控制台的资产路径和assetprecompile时,我得到如下:

1.9.2p320 :001 > y Rails.application.config.assets.precompile
---
- !ruby/object:Proc {}
- !ruby/regexp /(?:\/|\\|\A)application\.(css|js)$/
- .svg
- .eot
- .woff
- .ttf
=> nil






1.9.2p320 :002 > y Rails.application.config.assets.paths
---
- /Users/neiltonge/code/neiltonge/app/assets/fonts
- /Users/neiltonge/code/neiltonge/app/assets/images
- /Users/neiltonge/code/neiltonge/app/assets/javascripts
- /Users/neiltonge/code/neiltonge/app/assets/stylesheets
- /Users/neiltonge/code/neiltonge/vendor/assets/images
- /Users/neiltonge/code/neiltonge/vendor/assets/javascripts
- /Users/neiltonge/code/neiltonge/vendor/assets/stylesheets
- /Users/neiltonge/.rvm/gems/ruby-1.9.2-p320@neiltonge/gems/jquery-rails-2.0.0/vendor/assets/javascripts
- /Users/neiltonge/.rvm/gems/ruby-1.9.2-p320@neiltonge/gems/coffee-rails-3.2.1/lib/assets/javascripts
- /Users/neiltonge/.rvm/gems/ruby-1.9.2-p320@neiltonge/gems/bourbon-1.3.0/app/assets/stylesheets
- !ruby/object:Pathname
path: /Users/neiltonge/code/neiltonge/app/assets/fonts
=> nil
186297 次浏览
  1. 如果你的Rails版本在> 3.1.0< 4之间,把你的字体放在这些文件夹中的任何一个:

    • app/assets/fonts
    • lib/assets/fonts
    • vendor/assets/fonts

    < br >

    对于Rails版本> 4,你必须将字体放在app/assets/fonts文件夹中。

    注意:要将字体放在这些指定文件夹之外,使用以下配置:

    config.assets.precompile << /\.(?:svg|eot|woff|ttf)\z/

    对于Rails版本> 4.2,将此配置添加到config/initializers/assets.rb推荐

    但是,你也可以将它添加到config/application.rbconfig/production.rb

  2. 在CSS文件中声明你的字体:

    @font-face {
    font-family: 'Icomoon';
    src:url('icomoon.eot');
    src:url('icomoon.eot?#iefix') format('embedded-opentype'),
    url('icomoon.svg#icomoon') format('svg'),
    url('icomoon.woff') format('woff'),
    url('icomoon.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
    }
    

    确保您的字体名称与声明的URL部分完全相同。大写字母和标点符号很重要。在这种情况下,字体的名称应该是icomoon.

  3. 如果你正在使用Sass或Less with Rails > 3.1.0(你的CSS文件有.scss.less扩展名),然后将字体声明中的url(...)更改为font-url(...)

    否则,CSS文件的扩展名应该是.css.erb,字体声明应该是url('<%= asset_path(...) %>')

    如果你正在使用Rails > 3.2.1,你可以使用font_path(...)而不是asset_path(...)。这个helper做的事情完全相同,但它更清楚

  4. 最后,在CSS中使用你在font-family部分中声明的字体。如果它被声明为大写,你可以这样使用它:

    font-family: 'Icomoon';
    

如果你有一个叫做scaffold。css的文件。Scss,那么就有可能覆盖您在其他文件中所做的所有自定义操作。我把那个文件注释掉了,突然之间一切都正常了。如果那个文件里没有什么重要的东西,你还不如把它删掉!

如果你不想跟踪字体的移动:

# Adding Webfonts to the Asset Pipeline
config.assets.precompile << Proc.new { |path|
if path =~ /\.(eot|svg|ttf|woff)\z/
true
end
}

这里有一个转折:

你应该把所有字体都放在app/assets/fonts/中,因为它们在登台和生产时默认会被预编译——当它们被推到heroku时,它们会被预编译。

放置在vendor/assets中的字体文件将在默认情况下在登台或生产时预编译 -它们将在heroku上失败。源!

——@plapier thoughtbot /波旁威士忌

我坚信将供应商字体放入vendor/assets/fonts 比将它们放入app/assets/fonts更有意义。与 这两行额外的配置对我来说工作得很好 Rails 4): < / p >

app.config.assets.paths << Rails.root.join('vendor', 'assets', 'fonts')
app.config.assets.precompile << /\.(?:svg|eot|woff|ttf)$/

——@jhilden thoughtbot /波旁威士忌

我还在rails 4.0.0上测试了它。实际上,最后一行足以安全地预编译vendor文件夹中的字体。花了几个小时才弄明白。希望它能帮助到某人。

你需要在@font-face块中使用font-url,而不是url

@font-face {
font-family: 'Inconsolata';
src:font-url('Inconsolata-Regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}

以及这条线在应用中。如你所述(用于app/assets/fonts中的字体

config.assets.paths << Rails.root.join("app", "assets", "fonts")

我最近将Rails 3应用程序升级到Rails 4时也遇到了类似的问题。我的字体不能正常工作,因为在Rails 4+中,我们只允许将字体保存在app/assets/fonts目录下。但是我的Rails 3应用程序有一个不同的字体组织。所以我必须配置应用程序,使它仍然与Rails 4+工作,我的字体在不同的地方,而不是app/assets/fonts。我已经尝试了几个解决方案,但在我发现non-stupid-digest-assets宝石后,它只是让它很容易。

通过在Gemfile中添加以下代码行来添加这个gem:

gem 'non-stupid-digest-assets'

然后运行:

bundle install

最后在你的配置/初始化/ non_digest_assets.rb文件中添加以下一行:

NonStupidDigestAssets.whitelist = [ /\.(?:svg|eot|woff|ttf)$/ ]

就是这样。这很好地解决了我的问题。希望这对遇到类似问题的人有所帮助。

我使用Rails 4.2,并不能得到footable图标显示。显示的是小方框,而不是我所期望的折叠行上的(+)和小排序箭头。在学习了这里的信息之后,我对代码做了一个简单的更改:删除css中的字体目录。也就是说,像这样更改所有的css条目:

src:url('fonts/footable.eot');

看起来像这样:

src:url('footable.eot');

它工作。我认为Rails 4.2已经假定了字体目录,所以在css代码中再次指定它会使字体文件找不到。希望这能有所帮助。

只需要把你的字体放在app/assets/fonts文件夹中,并在app开始使用application.rb中编写代码时设置自动加载路径

< >强config.assets。路径& lt; & lt;Rails.root。加入("app", "assets", "fonts") 和< / p >

然后在css中使用以下代码。

@font-face {

 font-family: 'icomoon';
src: asset-url('icomoon.eot');
src: asset-url('icomoon.eot') format('embedded-opentype'),
asset-url('icomoon.woff') format('woff'),
asset-url('icomoon.ttf') format('truetype'),
asset-url('icomoon.svg') format('svg');
font-weight: normal;
font-style: normal;

试一试。

谢谢

下面是我在资产管道中使用字体的方法:

1)把你所有的字体文件放在app/assets/fonts/下,实际上你不限制把它放在fonts文件夹名下。你可以放任何你喜欢的子文件夹名。例如:app/assets/abcapp/assets/anotherfonts。但我强烈建议你把它放在app/assets/fonts/文件夹结构更好。

2)从你的sass文件中,使用sass helper font-path来请求你的字体资产,就像这样

@font-face {
font-family: 'FontAwesome';
src: url(font-path('fontawesome-webfont.eot') + '?v=4.4.0');
src: url(font-path('fontawesome-webfont.eot') + '?#iefix&v=4.4.0') format('embedded-opentype'),
url(font-path('fontawesome-webfont.woff2') + '?v=4.4.0') format('woff2'),
url(font-path('fontawesome-webfont.woff') + '?v=4.4.0') format('woff'),
url(font-path('fontawesome-webfont.ttf') + '?v=4.4.0') format('truetype'),
url(font-path('fontawesome-webfont.svg') + '?v=4.4.0#fontawesomeregular') format('svg');
font-weight: normal;
font-style: normal;
}

3)在本地机器上运行bundle exec rake assets:precompile并查看application.css的结果。你应该会看到这样的东西:

@font-face {
font-family: 'FontAwesome';
src: url("/assets/fontawesome-webfont-d4f5a99224154f2a808e42a441ddc9248ffe78b7a4083684ce159270b30b912a.eot" "?v=4.4.0");
src: url("/assets/fontawesome-webfont-d4f5a99224154f2a808e42a441ddc9248ffe78b7a4083684ce159270b30b912a.eot" "?#iefix&v=4.4.0") format("embedded-opentype"), url("/assets/fontawesome-webfont-3c4a1bb7ce3234407184f0d80cc4dec075e4ad616b44dcc5778e1cfb1bc24019.woff2" "?v=4.4.0") format("woff2"), url("/assets/fontawesome-webfont-a7c7e4930090e038a280fd61d88f0dc03dad4aeaedbd8c9be3dd9aa4c3b6f8d1.woff" "?v=4.4.0") format("woff"), url("/assets/fontawesome-webfont-1b7f3de49d68b01f415574ebb82e6110a1d09cda2071ad8451bdb5124131a292.ttf" "?v=4.4.0") format("truetype"), url("/assets/fontawesome-webfont-7414288c272f6cc10304aa18e89bf24fb30f40afd644623f425c2c3d71fbe06a.svg" "?v=4.4.0#fontawesomeregular") format("svg");
font-weight: normal;
font-style: normal;
}

如果你想了解更多资产管道如何工作,你可以访问以下简单指南: https://designcode.commandrun.com/rails-asset-pipeline-simple-guide-830e2e666f6c#.6lejlayk2 < / p >

我在Rails 4.2 (ruby 2.2.3)上遇到了这个问题,不得不编辑字体很棒的_paths。删除对$fa-font-path的引用,并删除前导的正斜杠。以下是破碎的:

@font-face {
font-family: 'FontAwesome';
src: font-url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}');
src: font-url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),
font-url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'),
font-url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),
font-url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),
font-url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');
font-weight: normal;
font-style: normal;
}

以及以下工作:

@font-face {
font-family: 'FontAwesome';
src: font-url('fontawesome-webfont.eot?v=#{$fa-version}');
src: font-url('fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),
font-url('fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'),
font-url('fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),
font-url('fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),
font-url('fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');
font-weight: normal;
font-style: normal;
}

另一种方法是简单地删除插入的$fa-font-path后面的正斜杠,然后将$fa-font-path定义为一个空字符串或带正斜杠的子目录(根据需要)。

记得根据需要重新编译资产并重新启动服务器。例如,在乘客设置中:

prompt> rake assets:clean; rake assets:clobber
prompt> RAILS_ENV=production RAILS_GROUPS=assets rake assets:precompile
prompt> service passenger restart

然后重新加载浏览器。

在我的情况下,最初的问题是使用asset-url没有结果,而不是简单的url css属性。使用asset-url最终在Heroku中为我工作。加上在/assets/fonts文件夹中设置字体并调用asset-url('font.eot'),而不添加任何子文件夹或任何其他配置。

这里是一个repo演示了在Heroku上使用Rails 5.2提供自定义字体。它进一步优化了根据https://www.webpagetest.org/提供的字体,使其尽可能快

https://github.com/nzoschke/edgecors

首先,我从上面的答案中挑选了一些。对于Rails 5.2+,您不需要额外的资产管道配置。

资产管道和SCSS

  • 将字体放置在app/assets/fonts
  • @font-face声明放在一个scss文件中,并使用font-url helper

app/assets/stylesheets/welcome.scss:

@font-face {
font-family: 'Inconsolata';
src: font-url('Inconsolata-Regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}


body {
font-family: "Inconsolata";
font-weight: bold;
}

从CDN与CORS服务

我使用CloudFront,添加了Heroku Edge插件

首先在production.rb中配置CDN前缀和默认的Cache-Control头:

Rails.application.configure do
# e.g. https://d1unsc88mkka3m.cloudfront.net
config.action_controller.asset_host = ENV["EDGE_URL"]


config.public_file_server.headers = {
'Cache-Control' => 'public, max-age=31536000'
}
end

如果您尝试从herokuapp.com URL访问CDN URL的字体,您将在浏览器中得到一个CORS错误:

从来源'https://edgecors.herokuapp.com'访问'https://d1unsc88mkka3m.cloudfront.net/assets/Inconsolata-Regular.ttf'的字体已被CORS策略阻止: 被请求的资源上没有'Access-Control-Allow-Origin'标头。edgecors.herokuapp.com/ GET https://d1unsc88mkka3m.cloudfront.net/assets/Inconsolata-Regular.ttf net::ERR_FAILED

因此,配置CORS以允许从Heroku到CDN URL访问字体:

module EdgeCors
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.2


config.middleware.insert_after ActionDispatch::Static, Rack::Deflater


config.middleware.insert_before 0, Rack::Cors do
allow do
origins %w[
http://edgecors.herokuapp.com
https://edgecors.herokuapp.com
]
resource "*", headers: :any, methods: [:get, :post, :options]
end
end
end
end

服务gzip字体资产

资产管道构建了一个.ttf.gz文件,但不为它服务。这个monkey补丁将资产管道gzip白名单更改为黑名单:

require 'action_dispatch/middleware/static'


ActionDispatch::FileHandler.class_eval do
private


def gzip_file_path(path)
return false if ['image/png', 'image/jpeg', 'image/gif'].include? content_type(path)
gzip_path = "#{path}.gz"
if File.exist?(File.join(@root, ::Rack::Utils.unescape_path(gzip_path)))
gzip_path
else
false
end
end
end

最终的结果是app/assets/fonts中的自定义字体文件,该文件来自一个长期存在的CloudFront缓存。