Menggunakan font dengan pipa aset Rails

345

Saya memiliki beberapa font yang dikonfigurasi dalam file Scss saya seperti ini:

@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');
}

File font yang sebenarnya disimpan di / app / assets / fonts /

Saya telah menambahkan config.assets.paths << Rails.root.join("app", "assets", "fonts")ke file application.rb saya

dan kompilasi sumber CSS adalah sebagai berikut:

@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");
}

Tetapi ketika saya menjalankan aplikasi file font tidak ditemukan. Log:

Mulai DAPATKAN "/assets/icoMoon.ttf" untuk 127.0.0.1 di 2012-06-05 23:21:17 +0100 Aset yang dilayani /icoMoon.ttf - 404 Tidak Ditemukan (13ms)

Mengapa pipa aset tidak meratakan file font menjadi adil / aset?

Ada ide orang?

Salam, Neil

Informasi tambahan:

Saat memeriksa konsol rel untuk jalur aset dan kompilasi aset, saya mendapatkan yang berikut:

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
rctneil
sumber
3
Anda memiliki font-urlpembantu dalam SCSS di Rails.
Hauleth
Sayangnya tidak ada bedanya. Oleh karena itu pertanyaan saya masih tetap
rctneil
Saya menulis cara umum untuk mendiagnosis dan menyelesaikan masalah ini di stackoverflow.com/a/40898227/1197775 .
situs

Jawaban:

651
  1. Jika versi Rails Anda berada di antara > 3.1.0dan < 4, tempatkan font Anda di salah satu folder ini:

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


    Untuk versi Rails > 4, Anda harus meletakkan font Anda di app/assets/fontsfolder.

    Catatan: Untuk menempatkan font di luar folder yang ditunjuk ini, gunakan konfigurasi berikut:

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

    Untuk versi Rails > 4.2, disarankan untuk menambahkan konfigurasi ini config/initializers/assets.rb.

    Namun, Anda juga dapat menambahkannya ke config/application.rb, atau keconfig/production.rb

  2. Nyatakan font Anda di file CSS Anda:

    @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;
    }

    Pastikan font Anda dinamai sama persis dengan di bagian URL deklarasi. Huruf kapital dan tanda baca penting. Dalam hal ini, font harus memiliki nama icomoon.

  3. Jika Anda menggunakan Sass atau Less with Rails > 3.1.0(file CSS Anda memiliki .scssatau .lessekstensi), maka ubah url(...)deklarasi font menjadi font-url(...).

    Jika tidak, file CSS Anda harus memiliki ekstensi .css.erb, dan deklarasi font seharusnya url('<%= asset_path(...) %>').

    Jika Anda menggunakan Rails > 3.2.1, Anda dapat menggunakan font_path(...)bukan asset_path(...). Pembantu ini melakukan hal yang persis sama tetapi lebih jelas.

  4. Akhirnya, gunakan font Anda di CSS Anda seperti Anda mendeklarasikannya di font-familybagian. Jika dinyatakan sebagai huruf besar, Anda dapat menggunakannya seperti ini:

    font-family: 'Icomoon';
Ashitaka
sumber
36
Apakah Anda me-restart server Anda?
Ashitaka
9
@ NadeemYasin Terima kasih atas komentar Anda, saya punya masalah yang sama. Nama file memiliki tanda hubung di dalamnya dan ketika saya menghapus bahwa solusi yang diusulkan di sini berfungsi.
tsega
35
config.assets.precompile += %w( .svg .eot .woff .ttf )sebenarnya salah, Anda perlu menambahkan untuk mengkompilasi sesuatu yang cocok dengan nama aset lengkap. Sebuah regexp bekerja untuk saya:config.assets.precompile << /\.(?:svg|eot|woff|ttf)$/
Sunny
2
Nah, cara sekarang berfungsi untuk saya. Jadi baris kode itu tidak diperlukan sama sekali atau cara untuk mengatur konfigurasi ini tergantung pada versi Rails (atau yang lainnya). @ Jim sudah mengatakan bahwa dia harus menghapus konfigurasi pada langkah 2 jadi mungkin kita kehilangan sesuatu di sini. Man, seharusnya lebih mudah menggunakan font dengan pipeline aset.
Ashitaka
3
Langkah 2 harus dihapus. Menurut Rails Guides , config.assets.pathsadalah untuk referensi Sprocket, tidak relevan di sini. config.assets.precompilejuga tidak berguna karena "Pencocokan default untuk mengkompilasi file termasuk application.js, application.css dan semua file non-JS / CSS (ini akan mencakup semua aset gambar secara otomatis) dari folder app / aset" (lihat di sini )
Eric L.
38

Sekarang inilah twist:

Anda harus meletakkan semua font app/assets/fonts/karena mereka AKAN dikompilasi dalam pementasan dan produksi secara default-mereka akan dikompilasi ketika didorong ke heroku .

Font files ditempatkan dalam vendor/assetsakan tidak akan dikompilasi pada pementasan atau produksi secara default - mereka akan gagal pada heroku . Sumber!

- @plapier, pikirbot / bourbon

Saya sangat percaya bahwa menempatkan font vendor vendor/assets/fonts lebih masuk akal daripada menempatkannya app/assets/fonts. Dengan 2 baris konfigurasi tambahan ini, ini berhasil bagi saya (di Rails 4):

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

- @jhilden, pikirbot / bourbon

Saya juga sudah mencobanya rails 4.0.0. Sebenarnya baris terakhir sudah cukup untuk mengkompilasi font dari vendorfolder dengan aman . Butuh beberapa jam untuk mengetahuinya. Semoga ini bisa membantu seseorang.

jibiel
sumber
2
+1 edgeguides.rubyonrails.org/... menjelaskan tata letak pipa aset dan membantu memahami cara kerjanya. Tepat pada 2014-07-04
Zachary Moshansky
Apakah Anda membutuhkan keduanya? app.config.assets.paths << Rails.root.join('vendor', 'assets', 'fonts') app.config.assets.precompile << /\.(?:svg|eot|woff|ttf)$/Sebuah komentar pada jawaban lain mengatakan bahwa yang terakhir menangani keduanya.
ahnbizcad
Bahkan di Rails 4.2 + -land, saya benar-benar berpikir bahwa app/assetsinput ke sprocket dan teman diproses sebagai output public/assets, sedangkan vendor/assetsmasih dapat berguna untuk menggunakan aset tanpa modifikasi; keduanya memiliki kasus penggunaannya. Seluruh konvensi pembatalan didasarkan pada jaminan bahwa tidak akan terjadi apa-apa vendor/*. (Ya, vendor/pluginsdisalahgunakan dengan penimbunan kode, sumber mania pra-permata era tertutup dan orang-orang hanya menyalin js tidak berversi yang disisipkan ke dalam vendor/assets/javascriptsaset pre-bower / rails.)
2
Bagi mereka yang bertanya-tanya; lempar ini ke dalamconfig/initializers/assets.rb
TJ Biddle
23

Jika Anda tidak ingin melacak pemindahan font Anda:

# Adding Webfonts to the Asset Pipeline
config.assets.precompile << Proc.new { |path|
  if path =~ /\.(eot|svg|ttf|woff)\z/
    true
  end
}
Nathan Colgate
sumber
1
Saya pikir ini adalah solusi terbaik; kecuali jika Anda mengarang font yang mungkin berada di / vendor / assets / fonts - bukan / app / aset / font Pendekatan ini memecahkan keduanya, hal di atas tidak
Casey
5
@Casey: solusi ini memungkinkan Anda memasukkan font ke vendor / aset @Nathan Colgate: Ini bisa disederhanakan menjadi:config.assets.precompile << /\.(?:svg|eot|woff|ttf)$/
Sunny
@ Sunny - Saya tahu, itu sebabnya saya pikir itu lebih baik daripada jawaban yang diterima
Casey
2
Anda juga harus mengakhiri regex Anda dengan \ Z - stackoverflow.com/questions/577653/...
Casey
1
Bagaimana Anda menangani hash yang ditambahkan Rails ke file font?
James McMahon
21

Anda harus menggunakan font-urldi blok @ font-face Anda, bukanurl

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

serta baris ini di application.rb, seperti yang Anda sebutkan (untuk font di app/assets/fonts

config.assets.paths << Rails.root.join("app", "assets", "fonts")
craic.com
sumber
Anda juga perlu mengaktifkan prakompilasi untuk produksi
ahnbizcad
Pada aplikasi 4.2 baru, keduanya src: url(someFont.ttf)dan src: font-url(someFont.ttf)berfungsi ketika memiliki file app/assets/fonts. Saya memiliki .scssekstensi secara default. Saya tidak perlu menambahkan ke config.assets.paths.
Danny
9

Di sini pendekatan saya untuk menggunakan font dalam pipa aset:

1) Letakkan semua file font Anda di bawah app/assets/fonts/, sebenarnya Anda tidak dibatasi untuk meletakkannya di bawah fontsnama folder. Anda dapat memasukkan nama subfolder yang Anda suka. Misalnya app/assets/abcatau app/assets/anotherfonts. Tetapi saya sangat menyarankan Anda meletakkannya di bawah app/assets/fonts/untuk struktur folder yang lebih baik.

2) Dari file sass Anda, gunakan helper sass font-pathuntuk meminta aset font Anda seperti ini

@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) Jalankan bundle exec rake assets:precompiledari mesin lokal Anda dan lihat hasil application.css Anda. Anda harus melihat sesuatu seperti ini:

@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;
}

Jika Anda ingin tahu lebih banyak tentang cara kerja pipeline aset, Anda dapat mengunjungi panduan sederhana berikut: https://designcode.commandrun.com/rails-asset-pipeline-simple-guide-830e2e666f6c#.6lejlayk2

Tim
sumber
5

Saya mengalami masalah ini pada Rails 4.2 (dengan ruby ​​2.2.3) dan harus mengedit parsial font-awesome _paths.scss untuk menghapus referensi $fa-font-pathdan menghapus garis miring ke depan. Berikut ini rusak:

@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;
}

Dan karya-karya berikut:

@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;
}

Alternatifnya adalah dengan hanya menghapus garis miring mengikuti interpolasi $fa-font-pathdan kemudian mendefinisikan $fa-font-pathsebagai string kosong atau subdirektori dengan garis miring ke depan (sesuai kebutuhan).

Ingatlah untuk mengkompilasi ulang aset dan mulai ulang server Anda sesuai kebutuhan. Misalnya, pada pengaturan penumpang:

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

Kemudian muat ulang browser Anda.

markeissler
sumber
5

Saya menggunakan Rails 4.2, dan tidak dapat menampilkan ikon yang dapat ditampilkan. Kotak-kotak kecil ditampilkan, alih-alih (+) pada baris yang diciutkan dan panah sortir kecil yang saya harapkan. Setelah mempelajari informasi di sini, saya membuat satu perubahan sederhana pada kode saya: hapus direktori font di css. Artinya, ubah semua entri css seperti ini:

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

agar terlihat seperti ini:

src:url('footable.eot');

Itu berhasil. Saya pikir Rails 4.2 sudah mengasumsikan direktori font, jadi menetapkannya lagi dalam kode css membuat file font tidak ditemukan. Semoga ini membantu.

Brian Doherty
sumber
3

Saya memiliki masalah serupa ketika saya meningkatkan aplikasi Rails 3 saya ke Rails 4 baru-baru ini. Font saya tidak berfungsi sebagaimana mestinya di Rails 4+, kami hanya diperbolehkan menyimpan font di bawah app/assets/fontsdirektori. Tetapi aplikasi Rails 3 saya memiliki organisasi font yang berbeda. Jadi saya harus mengkonfigurasi aplikasi sehingga masih berfungsi dengan Rails 4+ memiliki font saya di tempat lain selain app/assets/fonts. Saya telah mencoba beberapa solusi tetapi setelah saya menemukan permata non-bodoh-intisari aset , itu membuatnya sangat mudah.

Tambahkan permata ini dengan menambahkan baris berikut ke Gemfile Anda:

gem 'non-stupid-digest-assets'

Lalu lari:

bundle install

Dan akhirnya tambahkan baris berikut di file config / initializers / non_digest_assets.rb Anda :

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

Itu dia. Ini memecahkan masalah saya dengan baik. Semoga ini bisa membantu seseorang yang mengalami masalah serupa seperti saya.

KM Rakibul Islam
sumber
3

Berikut adalah repo yang menunjukkan melayani font khusus dengan Rails 5.2 yang berfungsi pada Heroku. Ia melangkah lebih jauh dan mengoptimalkan penyajian font secepat mungkin menurut https://www.webpagetest.org/

https://github.com/nzoschke/edgecors

Untuk memulai, saya mengambil bagian dari jawaban di atas. Untuk Rails 5.2+ Anda tidak perlu memerlukan konfigurasi pipa aset tambahan.

Pipa Aset dan SCSS

  • Tempatkan font app/assets/fonts
  • Tempatkan @font-facedeklarasi dalam file scss dan gunakan font-urlhelper

Dari 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;
}

Sajikan dari CDN dengan CORS

Saya menggunakan CloudFront, ditambahkan dengan addon Heroku Edge .

Pertama-tama konfigurasikan awalan CDN dan Cache-Controltajuk default di 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

Jika Anda mencoba mengakses font dari URL herokuapp.com ke URL CDN, Anda akan mendapatkan kesalahan CORS di browser Anda:

Akses ke font di ' https://d1unsc88mkka3m.cloudfront.net/assets/Inconsolata-Regular.ttf ' from origin ' https://edgecors.herokuapp.com ' telah diblokir oleh kebijakan CORS: Tidak ada 'Akses-Kontrol-Izinkan Header -Origin 'hadir di sumber yang diminta. edgecors.herokuapp.com/ DAPATKAN https://d1unsc88mkka3m.cloudfront.net/assets/Inconsolata-Regular.ttf net :: ERR_FAILED

Jadi konfigurasikan CORS untuk memungkinkan akses ke font dari Heroku ke 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

Sajikan Aset Font gzip

Pipeline aset membuat .ttf.gzfile tetapi tidak menayangkannya. Patch monyet ini mengubah daftar putih gzip jalur pipa aset ke daftar hitam:

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

Hasil akhirnya adalah file font khusus yang app/assets/fontsdisajikan dari cache CloudFront yang berumur panjang.

Noah Zoschke
sumber
2

Dalam kasus saya, pertanyaan awal menggunakan asset-urltanpa hasil alih-alih urlproperti css biasa . Menggunakan asset-urlakhirnya bekerja untuk saya di Heroku. Ditambah pengaturan font di /assets/fontsfolder dan panggilan asset-url('font.eot')tanpa menambahkan subfolder atau konfigurasi lainnya.

bartoindahouse
sumber
1

Jika Anda memiliki file bernama scaffolds.css.scss, maka ada peluang yang mengesampingkan semua hal khusus yang Anda lakukan di file lain. Saya berkomentar file itu dan tiba-tiba semuanya bekerja. Jika tidak ada sesuatu yang penting dalam file itu, Anda bisa menghapusnya!

katfa
sumber
-7

cukup tempatkan font Anda di dalam folder app / assets / fonts dan atur jalur muat otomatis ketika aplikasi mulai menggunakan penulisan kode di application.rb

config.assets.paths << Rails.root.join ("app", "aset", "font") dan

kemudian gunakan kode berikut dalam 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;

}

Cobalah.

Terima kasih

Shoaib Malik
sumber
Bagaimana ini menambahkan sesuatu dari jawaban yang ada?
cimmanon