Використання шрифтів з конвеєром активів Rails


345

У моєму файлі 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');
}

Фактичний файл шрифту зберігається в / застосунку / активах / шрифтах /

Я додав config.assets.paths << Rails.root.join("app", "assets", "fonts")у файл application.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");
}

Але коли я запускаю додаток, файли шрифтів не знаходять. Журнали:

Розпочато GET "/assets/icoMoon.ttf" за 127.0.0.1 в 2012-06-05 23:21:17 +0100 Обслугований актив /icoMoon.ttf - 404 не знайдено (13 мс)

Чому конвеєр активів не згладжує файли шрифтів у просто / активи?

Якісь ідеї люди?

З повагою, Ніл

Додаткова інформація:

Під час перевірки консолі рейки на шляхи активів та активу компіляції я отримую наступне:

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

3
У вас є font-urlпомічник у SCSS в Rails.
Hauleth

На жаль, це не має ніякої різниці. Тому моє питання все ще стоїть
rctneil

Я написав загальний спосіб діагностувати та вирішити цю проблему на сайті stackoverflow.com/a/40898227/1197775 .
сайти

Відповіді:


651
  1. Якщо ваша версія Rails знаходиться між > 3.1.0і < 4, розмістіть шрифти в будь-якій з цих папок:

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


    Для версій Rails > 4ви повинні розмістити свої шрифти в app/assets/fonts папці.

    Примітка. Для розміщення шрифтів за межами зазначених папок використовуйте таку конфігурацію:

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

    Для версій Rails > 4.2, то рекомендується додати цю конфігурацію config/initializers/assets.rb.

    Однак ви також можете додати його або до config/application.rb, або доconfig/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(...). Цей помічник робить саме те саме, але це більш зрозуміло.

  4. Нарешті, використовуйте свій шрифт у своєму CSS так, як ви його оголосили в font-familyчастині. Якщо він був оголошений з великої літери, ви можете використовувати його так:

    font-family: 'Icomoon';

36
Ви перезапустили сервер?
Ашитака

9
@NadeemYasin Дякую за ваш коментар, у мене була така ж проблема. Імена файлів у них були гіпетичні елементи, і коли я видалив, що запропоновані тут рішення працюють.
цега

35
config.assets.precompile += %w( .svg .eot .woff .ttf )насправді неправильно, вам потрібно додати до попереднього компіляції щось, що відповідає повній назві активу. Для мене працював регекс:config.assets.precompile << /\.(?:svg|eot|woff|ttf)$/
Сонячний

2
Добре, як зараз це працює для мене. Отже, або цей рядок коду взагалі не потрібен, або спосіб встановлення цієї конфігурації залежить від версії Rails (або чогось іншого). @Jim вже сказав, що він повинен видалити конфігурацію на кроці 2, тому, можливо, тут щось нам не вистачає. Людина, слід простіше використовувати шрифти з конвеєром активів.
Ашитака

3
Крок 2 слід усунути. За Rails Guides , config.assets.pathsце посилання на Зірочки, тут не доречне. config.assets.precompileтакож марний, тому що "Матч за замовчуванням для компіляції файлів включає application.js, application.css та всі файли, що не включають JS / CSS (сюди автоматично включатимуться всі активи зображень) з папок додатків / активів" (див. тут )
Ерік Л.

38

Тепер ось поворот:

Ви повинні помістити всі шрифти , app/assets/fonts/як вони БУДУТЬ отримати прекомпілірованние в постановці і виробництві за замовчуванням, вони будуть отримувати прекомпілірованние при натисканні на Heroku .

Файли шрифтів, розміщені в vendor/assets, НЕ будуть попередньо скомпільовані під час постановки або виготовлення за замовчуванням - вони не матимуть результатів у героїці . Джерело!

- @plapier, thinkbot / бурбон

Я твердо переконаний, що розміщувати шрифти продавців vendor/assets/fonts має набагато більше сенсу, ніж вкладати їх app/assets/fonts. За допомогою цих 2 рядків додаткової конфігурації це добре спрацювало для мене (на Rails 4):

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

- @jhilden, мислитель / бурбон

Я також тестував його rails 4.0.0. Насправді останнього рядка достатньо, щоб безпечно попередньо скласти шрифти з vendorпапки. Знадобилося пару годин, щоб це зрозуміти. Сподіваюся, це комусь допомогло.


2
+1 edgeguides.rubyonrails.org/… пояснює структуру конвеєра активів та допомагає зрозуміти, як це працює. Правильно станом на 04.07.2014
Захарій Мошанський

Вам потрібно обоє цих? app.config.assets.paths << Rails.root.join('vendor', 'assets', 'fonts') app.config.assets.precompile << /\.(?:svg|eot|woff|ttf)$/У коментарі до іншої відповіді йдеться про те, що останній піклується про обох.
ahnbizcad

Навіть у Rails 4.2 + -land я дійсно думаю, що app/assetsвведення в зірочки та друзів обробляється як вихід public/assets, тоді як vendor/assetsвсе ще може бути корисним для розгортання ресурсів без змін; обидва мають свої випадки використання. Вся конвенція про торгівлю грунтується на гарантії, що нічого не відбудеться vendor/*. (Так, vendor/pluginsпіддавались зловживанню кодом, манія із закритим джерелом до епохи дорогоцінних каменів, а люди просто копіювали вклеєні неперевершені js у vendor/assets/javascriptsпопередньо завантажувачі / рейли-активи.)

2
Для тих, хто цікавиться; киньте цеconfig/initializers/assets.rb
TJ Biddle

23

Якщо ви не хочете слідкувати за переміщенням своїх шрифтів:

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

1
Я думаю, що це найкраще рішення; якщо ви не є автором шрифтів, які вони, ймовірно, належать до / постачальника / активів / шрифтів - не / програми / активів / шрифтів. Цей підхід вирішує і те, і інше
Кейсі

5
@Casey: це рішення дозволяє розмістити шрифти всередині постачальника / активів. @Nathan Colgate: Це можна спростити до:config.assets.precompile << /\.(?:svg|eot|woff|ttf)$/
Сонячний

@ Sunny - Я знаю, тому я вважаю, що це краще, ніж прийнята відповідь
Кейсі

2
Крім того, ви повинні закінчити своє регулярне вираження \ Z - stackoverflow.com/questions/577653/…
Кейсі

1
Як ви маєте справу з хешами, які Rails додає до файлу шрифту?
Джеймс Макмахон

21

Вам потрібно використовувати font-urlв блоці @ font-face, ніurl

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

а також цей рядок у application.rb, як ви згадали (для шрифтів у app/assets/fonts

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

Вам також потрібно включити
докомпіляцію

У абсолютно новому додатку для рейок 4.2, як src: url(someFont.ttf)і src: font-url(someFont.ttf)працювали при наявності файлів app/assets/fonts. У мене .scssрозширення за замовчуванням. Мені не потрібно було додавати в config.assets.paths.
Денні

9

Ось мій підхід до використання шрифтів у конвеєрі активів:

1) Покладіть всі файли шрифту під app/assets/fonts/, фактично ви не обмежуєтесь ставити його під fontsназвою папки. Ви можете поставити будь-яке ім’я підпапки, яке вам подобається. Наприклад , app/assets/abcчи app/assets/anotherfonts. Але я дуже рекомендую вам поставити йогоapp/assets/fonts/ для кращої структури папок.

2) З вашого файлу sass, використовуючи помічник sass, 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


5

У мене була ця проблема на Rails 4.2 (з рубіном 2.2.3), і мені довелося відредагувати шрифтове дивовижне часткове _paths.scss для видалення посилань на $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

Потім перезавантажте веб-переглядач.


5

Я використовую Rails 4.2 і не зміг відобразити піктограми, що з'являються на екрані. Маленькі поля показували замість (+) на збірних рядках та маленьких стрілок для сортування, які я очікував. Вивчивши тут інформацію, я вніс одну просту зміну свого коду: видаліть каталог шрифтів у css. Тобто змінити всі записи css таким чином:

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

виглядати так:

src:url('footable.eot');

Це спрацювало. Я думаю, що Rails 4.2 вже бере на себе каталог шрифтів, тому вказуючи його знову в коді css, файли шрифтів не знаходять. Сподіваюсь, це допомагає.


3

У мене була подібна проблема, коли нещодавно я оновив додаток Rails 3 до Rails 4. Мої шрифти не працюють належним чином, як у Rails 4+, нам дозволяється лише зберігати шрифти під app/assets/fontsкаталогом. Але мій додаток Rails 3 мав іншу організацію шрифтів. Тож мені довелося налаштувати додаток так, щоб воно все ще працювало з Rails 4+, маючи мої шрифти в іншому місці, крім app/assets/fonts. Я спробував декілька рішень, але після того, як знайшов активи, що не дають перевагу дорогоцінний камінь з , це просто зробило це так просто.

Додайте цей самоцвіт, додавши наступний рядок у свій Gemfile:

gem 'non-stupid-digest-assets'

Потім запустіть:

bundle install

І, нарешті, додайте наступний рядок у свій файл config / Initiators / non_digest_assets.rb :

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

Це воно. Це прекрасно вирішило мою проблему. Сподіваюся, це допомагає тому, хто стикався з подібною проблемою, як я.


3

Ось репо-демонстрація демонструє службовий шрифт з Rails 5.2, який працює на Heroku. Це іде далі та оптимізує обслуговування шрифтів якнайшвидше відповідно до https://www.webpagetest.org/

https://github.com/nzoschke/edgecors

Для початку я вибрав фрагменти з відповідей вище. Для Rails 5.2+ і більше вам не знадобиться конфігурація конвеєра додаткових ресурсів.

Трубопровід активів та SCSS

  • Розмістити шрифти в app/assets/fonts
  • Помістіть @font-faceдекларацію у файл scss та скористайтеся font-urlпомічником

Від 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 .

Спочатку налаштуйте префікс CDN та Cache-Controlзаголовки за замовчуванням у production.rb:

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

Якщо ви спробуєте отримати доступ до шрифту з URL-адреси herokuapp.com до URL-адреси CDN, у вашому браузері з’явиться помилка CORS:

Доступ до шрифту за адресою " https://d1unsc88mkka3m.cloudfront.net/assets/Inconsolata-Regular.ttf " від походження " https://edgecors.herokuapp.com " був заблокований політикою CORS: Ні "Access-Control-Allow -Origin 'заголовок присутній на запитуваному ресурсі. edgecors.herokuapp.com/ GET https://d1unsc88mkka3m.cloudfront.net/assets/Inconsolata-Regular.ttf net :: ERR_FAILED

Тож налаштуйте CORS, щоб дозволити доступ до шрифту від Heroku до URL-адреси CDN:

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 Font Asset

Трубопровід активів створює .ttf.gzфайл, але не обслуговує його. Цей патч мавп змінює список дозволу 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, який довго жив.


2

У моєму випадку початкове запитання використовувало asset-urlбез результатів замість простого urlcss властивості. Використання в asset-urlкінцевому підсумку працювало для мене в Heroku. Плюс встановлення шрифтів у /assets/fontsпапці та виклику asset-url('font.eot')без додавання до неї жодної підпапки чи будь-якої іншої конфігурації.


1

Якщо у вас є файл під назвою scaffolds.css.scss, то є ймовірність, що це перекриє всі власні речі, які ви робите в інших файлах. Я прокоментував цей файл і раптом все спрацювало. Якщо у цьому файлі немає нічого важливого, ви можете просто видалити його!


-7

просто розмістіть свої шрифти у папці додатків / активів / шрифтів та встановіть шлях автозавантаження, коли програма починає використовувати код у програмі.rb

config.assets.paths << Rails.root.join ("додаток", "активи", "шрифти") та

потім використовуйте наступний код у 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;

}

Спробувати.

Дякую


Як це щось додає до наявних відповідей?
Кімманон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.