web-dev-qa-db-fra.com

Utilisation de polices avec le pipeline Rails

J'ai des polices configurées dans mon fichier Scss comme ceci:

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

Le fichier de police actuel est stocké dans/app/assets/fonts /

J'ai ajouté config.assets.paths << Rails.root.join("app", "assets", "fonts") à mon fichier application.rb

et la source CSS compilée est la suivante:

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

Mais lorsque je lance l'application, les fichiers de polices ne sont pas trouvés. Les journaux:

Ouverture de GET "/assets/icoMoon.ttf" pour 127.0.0.1 le 2012-06-05 23:21:17 +0100 Actif servi /icoMoon.ttf - 404 Introuvable (13ms)

Pourquoi le pipeline d’actifs ne réduit-il pas les fichiers de polices en un/actif?

Des idées des gens?

Cordialement, Neil

Info supplémentaire:

Lors de la vérification de la console Rails pour les chemins d'actifs et la compilation de ressources, j'obtiens les éléments suivants:

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
334
rctneil
  1. Si votre version Rails est comprise entre > 3.1.0 et < 4, placez vos polices dans l'un des dossiers suivants:

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


    Pour Rails versions > 4, vous devez placer vos polices dans le dossier app/assets/fonts.

    Remarque: Pour placer des polices en dehors de ces dossiers désignés, utilisez la configuration suivante:

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

    Pour Rails versions > 4.2, il est recommandé d'ajouter cette configuration à config/initializers/assets.rb.

    Cependant, vous pouvez également l'ajouter à config/application.rb ou à config/production.rb

  2. Déclarez votre police dans votre fichier 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;
    }
    

    Assurez-vous que le nom de votre police est identique à celui indiqué dans la partie URL de la déclaration. Les majuscules et les signes de ponctuation importent. Dans ce cas, la police devrait avoir le nom icomoon.

  3. Si vous utilisez Sass ou Less avec Rails > 3.1.0 (votre fichier CSS a l'extension .scss ou .less), remplacez url(...) dans la déclaration de police par font-url(...).

    Sinon, votre fichier CSS devrait avoir l'extension .css.erb, et la déclaration de police devrait être url('<%= asset_path(...) %>').

    Si vous utilisez Rails > 3.2.1, vous pouvez utiliser font_path(...) au lieu de asset_path(...). Cet assistant fait exactement la même chose mais c'est plus clair.

  4. Enfin, utilisez votre police dans votre CSS comme vous l'avez déclaré dans la partie font-family. S'il a été déclaré en majuscule, vous pouvez l'utiliser comme ceci:

    font-family: 'Icomoon';
    
639
Ashitaka

Maintenant, voici une torsion:

Vous devez placer toutes les polices dans app/assets/fonts/ car elles SERONT précompilées dans la mise en scène et la production par défaut. Elles seront précompilées une fois poussées vers heroku .

Les fichiers de police placés dans vendor/assets _ seront PAS lors de la mise en attente ou de la production par défaut - ils échoueront heroku . Source!

- @ plapier, thinkbot/bourbon

Je crois fermement que le fait de placer les polices du fournisseur dans vendor/assets/fonts est beaucoup plus logique que de les placer dans app/assets/fonts. Avec ces 2 lignes de configuration supplémentaires, cela a bien fonctionné pour moi (sur Rails 4):

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

- @ jhilden, thinkbot/bourbon

Je l'ai également testé sur Rails 4.0.0. En fait, la dernière ligne suffit à précompiler en toute sécurité les polices du dossier vendor. Il a fallu quelques heures pour le comprendre. J'espère que ça a aidé quelqu'un.

37
jibiel

Si vous ne souhaitez pas suivre le déplacement de vos polices:

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

Vous devez utiliser font-url dans votre bloc @ font-face, et non url

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

ainsi que cette ligne dans application.rb, comme vous l'avez mentionné (pour les polices dans app/assets/fonts

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

Voici mon approche pour l’utilisation de polices dans le portefeuille d’actifs:

1) Mettez tout votre fichier de police sous app/assets/fonts/, vous n'êtes en fait pas obligé de le placer sous le nom de dossier fonts. Vous pouvez mettre n'importe quel nom de sous-dossier que vous aimez. Par exemple. app/assets/abc ou app/assets/anotherfonts. Mais je vous recommande fortement de le placer sous app/assets/fonts/ pour une meilleure structure de dossiers.

2) À partir de votre fichier sass, utilisez l’assistant sass font-path pour demander vos ressources de police de ce type.

@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) Lancez bundle exec rake assets:precompile à partir de votre ordinateur local et consultez le résultat de votre application.css. Vous devriez voir quelque chose comme ça:

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

Si vous souhaitez en savoir plus sur le fonctionnement du pipeline d’actifs, vous pouvez consulter le guide simple suivant: https://designcode.commandrun.com/Rails-asset-pipeline-simple-guide-830e2e666f6c#.6lejlayk2

9
Tim

J'avais ce problème sur Rails 4.2 (avec Ruby 2.2.3) et je devais modifier le partiel font-awesome _paths.scss pour supprimer les références à $fa-font-path et supprimer une barre oblique avant. Le suivant était cassé:

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

Et les oeuvres suivantes:

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

Une alternative serait simplement de supprimer la barre oblique suivant le $fa-font-path interpolé, puis de définir $fa-font-path comme une chaîne ou un sous-répertoire vide avec une barre oblique de fin (si nécessaire).

N'oubliez pas de recompiler les ressources et de redémarrer votre serveur au besoin. Par exemple, sur une configuration de passager:

Prompt> rake assets:clean; rake assets:clobber
Prompt> Rails_ENV=production Rails_GROUPS=assets rake assets:precompile
Prompt> service passenger restart

Rechargez ensuite votre navigateur.

5
markeissler

J'utilise Rails 4.2, et je ne pouvais pas afficher les icônes pouvant être remplies de pieds. Des petites boîtes montraient, au lieu du (+) sur les lignes réduites et les petites flèches de tri que j'attendais. Après avoir étudié les informations ici, j'ai apporté une simple modification à mon code: supprimez le répertoire des polices dans css. Autrement dit, changez toutes les entrées css comme ceci:

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

ressembler à ceci:

src:url('footable.eot');

Ça a marché. Je pense que Rails 4.2 assume déjà le répertoire de polices. Par conséquent, si vous le spécifiez à nouveau dans le code CSS, les fichiers de polices ne seront pas trouvés. J'espère que cela t'aides.

5
Brian Doherty

J'ai eu un problème similaire lorsque j'ai mis à niveau mon application Rails 3 à Rails 4 récemment. Mes polices ne fonctionnaient pas correctement comme dans Rails 4+, nous ne sommes autorisés à conserver les polices que dans le répertoire app/assets/fonts. Mais mon application Rails 3 avait une organisation de police différente. J'ai donc dû configurer l'application de sorte qu'elle fonctionne toujours avec Rails 4+, mes polices étant situées dans un endroit différent de app/assets/fonts. J'ai essayé plusieurs solutions mais après avoir trouvé bijou non-stupide-digéré-actif , cela a rendu les choses tellement simples.

Ajoutez cette gemme en ajoutant la ligne suivante à votre Gemfile:

gem 'non-stupid-digest-assets'

Puis lancez:

bundle install

Et enfin, ajoutez la ligne suivante dans votre fichier config/initializers/non_digest_assets.rb :

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

C'est ça. Cela a bien résolu mon problème. J'espère que cela aide quelqu'un qui a rencontré le même problème que moi.

3
K M Rakibul Islam

Voici un dépôt qui montre les démonstrations d'une police personnalisée avec Rails 5.2 fonctionnant sur Heroku. Il va plus loin et optimise l'utilisation des polices pour qu'elles soient aussi rapides que possible selon https://www.webpagetest.org/

https://github.com/nzoschke/edgecors

Pour commencer, j'ai choisi des éléments des réponses ci-dessus. Pour Rails 5.2+, vous ne devriez pas avoir besoin d'une configuration de pipeline d'actifs supplémentaire.

Asset Pipeline et SCSS

  • Placez les polices dans app/assets/fonts
  • Placez la déclaration @font-face dans un fichier scss et utilisez l’aide font-url.

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

Servir à partir de CDN avec CORS

J'utilise CloudFront, ajouté avec le addon Heroku Edge .

Commencez par configurer un préfixe CDN et des en-têtes par défaut Cache-Control dans 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

Si vous essayez d'accéder à la police de l'URL herokuapp.com à l'URL du CDN, vous obtiendrez une erreur CORS dans votre navigateur:

Accès à la police sur ' https://d1unsc88mkka3m.cloudfront.net/assets/Inconsolata-Regular.ttf ' à partir de l'origine ' https://edgecors.herokuapp.com ' a été bloqué par la politique CORS: Aucun en-tête 'Access-Control-Allow-Origin' n'est présent sur la ressource demandée. edgecors.herokuapp.com/ GET https://d1unsc88mkka3m.cloudfront.net/assets/Inconsolata-Regular.ttf net :: ERR_FAILED

Configurez donc CORS pour autoriser l’accès à la police de Heroku vers l’URL du 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

Servir gzip Font Asset

Le pipeline d'actifs crée un fichier .ttf.gz mais ne le sert pas. Ce patch de singe modifie la liste blanche gzip du pipeline d’actifs en liste noire:

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

Le résultat final est un fichier de police personnalisé dans app/assets/fonts servi à partir d'un cache CloudFront de longue durée.

2
Noah Zoschke

Dans mon cas, la question initiale consistait à utiliser asset-url sans résultats à la place de la propriété plain url css. Utiliser asset-url a fini par travailler pour moi à Heroku. De plus, définir les polices dans le dossier /assets/fonts et appeler asset-url('font.eot') sans y ajouter de sous-dossier ou de configuration.

2
bartoindahouse

Si vous avez un fichier appelé scaffolds.css.scss, il est possible que vous remplaciez toutes les tâches personnalisées que vous effectuez dans les autres fichiers. J'ai commenté ce fichier et tout a fonctionné. S'il n'y a rien d'important dans ce fichier, vous pouvez aussi simplement le supprimer!

1
katfa