Chemin des actifs dans les fichiers CSS dans Symfony 2

Problème

J'ai un fichier CSS avec quelques chemins (pour les images, les polices,etc.. url(..)).

Ma structure de chemin est comme ceci:

...
+-src/
| +-MyCompany/
|   +-MyBundle/
|     +-Resources/
|       +-assets/
|         +-css/
|           +-stylesheets...
+-web/
| +-images/
|   +-images...
...

Je veux référencer mes images dans la feuille de style.

Première Solution

J'ai changé tous les chemins dans le fichier CSS en chemins absolus. Ce n'est pas une solution, comme l'application devrait (et doit le faire!) travailler dans un sous-répertoire, trop.

Deuxième Solution

Utilisez Assetic avec filter="cssrewrite".

J'ai donc changé tous mes chemins dans mon fichier CSS en

url("../../../../../../web/images/myimage.png")

Pour représenter le chemin réel de mon répertoire de ressources vers le répertoire /web/images. Cela ne fonctionne pas, car cssrewrite produit le code suivant:

url("../../Resources/assets/")

Ce qui est évidemment le mauvais chemin.

Après assetic:dump, ce chemin est créé, ce qui est encore faux:

url("../../../web/images/myimage.png")

Le code de brindille D'Assetic:

{% stylesheets
    '@MyCompanyMyBundle/Resources/assets/css/*.css'
    filter="cssrewrite"
%}
<link rel="stylesheet" href="{{ asset_url }}" />
{% endstylesheets %}

Solution Actuelle (Troisième)

Puisque tous les fichiers CSS se retrouvent dans /web/css/stylexyz.css, J'ai changé tous les chemins dans le fichier CSS pour être relatif:

url("../images/myimage.png")

Cette (mauvaise) solution fonctionne, sauf dans le dev environnement: Le chemin CSS est /app_dev.php/css/stylexyz.css et donc le chemin d'image résultant de ceci est /app_dev.php/images/myimage.png, ce qui entraîne un NotFoundHttpException.

Y a-t-il une solution meilleure et efficace?

98
demandé sur apfelbox 2012-02-29 18:06:35

6 réponses

J'ai rencontré le même problème.

En bref:

  • désireux d'avoir CSS original dans un répertoire "interne" (Resources/assets/css/A. css)
  • désireux d'avoir les images dans le répertoire" public " (Resources / public / images / devil.png)
  • voulant que twig prenne ce CSS, le recompile dans web / css / A. css et le fait pointer l'image dans / web / bundles/mynicebundle / images / devil.png

J'ai fait un test avec tout le possible (sain d'esprit) combinaisons des éléments suivants:

  • @notation, par rapport notation
  • analyser avec cssrewrite, Sans
  • CSS image background vs direct tag src= à la même image que CSS
  • CSS analysé avec assetic et aussi sans analyse avec assetic de sortie directe)
  • et tout cela multiplié en essayant un "répertoire public" (comme Resources/public/css) avec le CSS et un répertoire "privé" (comme Resources/assets/css).

Cela m'a donné un total de 14 combinaisons sur le même brindille, et cette route a été lancée à partir de

  • " / app_dev.php / "
  • " / app.php / "
  • et "/"

Donnant ainsi 14 x 3 = 42 tests.

De plus, tout cela a été testé dans un sous-répertoire, il n'y a donc aucun moyen de tromper en donnant des URL absolues car elles ne fonctionneraient tout simplement pas.

Les tests étaient deux images sans nom, puis divs nommés de ' a ' à ' f 'pour le CSS construit à partir du dossier public et nommés 'g à' l ' pour ceux construits depuis le chemin de l'intérieur.

J'ai observé ce qui suit:

Seulement 3 des 14 tests ont été montrés adéquatement sur les trois URL. Et aucun ne provenait du dossier "interne" (ressources / actifs). C'était une condition préalable pour avoir le public CSS de rechange et ensuite construire avec assetic à partir de là.

Ce sont les résultats:

  1. Résultat lancé avec / app_dev.php/ Résultat lancé avec / app_dev.php/

  2. Résultat lancé avec / app.php/ Résultat lancé avec / app.php/

  3. Résultat lancé avec / entrez la description de l'image ici

Donc... SEULEMENT - La deuxième image - Div B - Div C sont les syntaxes autorisées.

Voici le code de la brindille:

<html>
    <head>
            {% stylesheets 'bundles/commondirty/css_original/container.css' filter="cssrewrite" %}
                <link href="{{ asset_url }}" rel="stylesheet" type="text/css" />
            {% endstylesheets %}

    {# First Row: ABCDEF #}

            <link href="{{ '../bundles/commondirty/css_original/a.css' }}" rel="stylesheet" type="text/css" />
            <link href="{{ asset( 'bundles/commondirty/css_original/b.css' ) }}" rel="stylesheet" type="text/css" />

            {% stylesheets 'bundles/commondirty/css_original/c.css' filter="cssrewrite" %}
                <link href="{{ asset_url }}" rel="stylesheet" type="text/css" />
            {% endstylesheets %}

            {% stylesheets 'bundles/commondirty/css_original/d.css' %}
                <link href="{{ asset_url }}" rel="stylesheet" type="text/css" />
            {% endstylesheets %}

            {% stylesheets '@CommonDirtyBundle/Resources/public/css_original/e.css' filter="cssrewrite" %}
                <link href="{{ asset_url }}" rel="stylesheet" type="text/css" />
            {% endstylesheets %}

            {% stylesheets '@CommonDirtyBundle/Resources/public/css_original/f.css' %}
                <link href="{{ asset_url }}" rel="stylesheet" type="text/css" />
            {% endstylesheets %}

    {# First Row: GHIJKL #}

            <link href="{{ '../../src/Common/DirtyBundle/Resources/assets/css/g.css' }}" rel="stylesheet" type="text/css" />
            <link href="{{ asset( '../src/Common/DirtyBundle/Resources/assets/css/h.css' ) }}" rel="stylesheet" type="text/css" />

            {% stylesheets '../src/Common/DirtyBundle/Resources/assets/css/i.css' filter="cssrewrite" %}
                <link href="{{ asset_url }}" rel="stylesheet" type="text/css" />
            {% endstylesheets %}

            {% stylesheets '../src/Common/DirtyBundle/Resources/assets/css/j.css' %}
                <link href="{{ asset_url }}" rel="stylesheet" type="text/css" />
            {% endstylesheets %}

            {% stylesheets '@CommonDirtyBundle/Resources/assets/css/k.css' filter="cssrewrite" %}
                <link href="{{ asset_url }}" rel="stylesheet" type="text/css" />
            {% endstylesheets %}

            {% stylesheets '@CommonDirtyBundle/Resources/assets/css/l.css' %}
                <link href="{{ asset_url }}" rel="stylesheet" type="text/css" />
            {% endstylesheets %}

    </head>
    <body>
        <div class="container">
            <p>
                <img alt="Devil" src="../bundles/commondirty/images/devil.png">
                <img alt="Devil" src="{{ asset('bundles/commondirty/images/devil.png') }}">
            </p>
            <p>
                <div class="a">
                    A
                </div>
                <div class="b">
                    B
                </div>
                <div class="c">
                    C
                </div>
                <div class="d">
                    D
                </div>
                <div class="e">
                    E
                </div>
                <div class="f">
                    F
                </div>
            </p>
            <p>
                <div class="g">
                    G
                </div>
                <div class="h">
                    H
                </div>
                <div class="i">
                    I
                </div>
                <div class="j">
                    J
                </div>
                <div class="k">
                    K
                </div>
                <div class="l">
                    L
                </div>
            </p>
        </div>
    </body>
</html>

Le conteneur.css:

div.container
{
    border: 1px solid red;
    padding: 0px;
}

div.container img, div.container div 
{
    border: 1px solid green;
    padding: 5px;
    margin: 5px;
    width: 64px;
    height: 64px;
    display: inline-block;
    vertical-align: top;
}

Et A. css, B. css, C. css, etc: tous identiques, il suffit de changer la couleur et le sélecteur CSS.

.a
{
    background: red url('../images/devil.png');
}

La structure "directories" est la suivante:

Répertoires Annuaire

Tout cela est venu, parce que je ne voulais pas que les fichiers originaux individuels exposés pour le public, surtout si je voulais jouer avec" moins "filtre ou" sass " ou similaire... Je ne voulais pas que mes" originaux " soient publiés, seulement ceux compilés.

Mais il y a de bonnes nouvelles . Si vous ne voulez pas avoir le "spare CSS" dans les répertoires publics... installez - les pas avec --symlink, mais en faisant vraiment une copie. Une fois que "assetic" a construit le CSS composé, et vous pouvez supprimer le CSS d'origine du système de fichiers, et laisser les images:

Compilation processus Processus de Compilation

Notez que je le fais pour l'environnement --env=prod.

Juste quelques réflexions:

  • Ce comportement désiré peut être réalisé en ayant les images dans le répertoire "public" dans Git ou Mercurial et le "css" dans les "actifs" de répertoire. C'est-à-dire, au lieu de les avoir en "public" comme indiqué dans les répertoires, imaginez a, b, C... résidant dans les "assets" au lieu de "public", que votre installateur / déployeur (probablement un Bash script) pour placer temporairement le CSS dans le répertoire "public" avant l'exécution de assets:install, puis assets:install, puis assetic:dump, puis automatiser la suppression du CSS du répertoire public après l'exécution de assetic:dump. Cela permettrait D'atteindre exactement le comportement souhaité dans la question.

  • Une autre solution (inconnue si possible) serait d'explorer si " assets: install "ne peut prendre que" public "comme source ou pourrait également prendre" assets " comme source à publier. Qui pourrait aider lorsqu'il est installé avec l'option --symlink lors du développement.

  • De plus, si nous allons Scripter la suppression du répertoire "public", alors, la nécessité de les stocker dans un répertoire séparé ("assets") disparaît. Ils peuvent vivre à l'intérieur "public" dans notre système de contrôle de version car il sera abandonné lors du déploiement au public. Cela permet également l'utilisation de --symlink.

Mais de toute façon, attention maintenant: {[96] } comme maintenant les originaux ne sont plus là (rm -Rf), il n'y a que deux solutions, pas trois. Le div " B " de travail ne fonctionne plus car il s'agissait d'un appel asset() en supposant qu'il y avait l'actif d'origine. Seul " C " (le compilé) fonctionnera.

Donc... il n'y a qu'un gagnant FINAL: Div "C" permet exactement ce qui a été demandé dans le sujet: être compilé, respecter le chemin vers les images et ne pas exposer la source originale au public.

Le gagnant est C

Le gagnant est C

193
répondu Xavi Montero 2014-08-10 18:09:28

Le filtre cssrewrite n'est pas compatible avec la notation @bundle pour l'instant. Vous avez donc deux choix:

  • Référencez les fichiers CSS dans le dossier web (après: console assets:install --symlink web)

    {% stylesheets '/bundles/myCompany/css/*." filter="cssrewrite" %}
    
  • Utilisez le filtre cssembed pour intégrer des images dans le CSS comme ceci.

    {% stylesheets '@MyCompanyMyBundle/Resources/assets/css/*.css' filter="cssembed" %}
    
16
répondu jeremymarc 2014-08-10 20:20:34

Je vais poster ce qui a fonctionné pour moi, grâce à @ xavi-montero.

Mettez votre CSS dans le répertoire Resource/public/css de votre bundle, et vos images dans say Resource/public/img.

Modifiez les chemins d'accès au formulaire 'bundles/mybundle/css/*.css', dans votre mise en page.

Dans config.yml, ajouter la règle css_rewrite à assetic:

assetic:
    filters:
        cssrewrite:
            apply_to: "\.css$"

Installez maintenant les actifs et compilez avec assetic:

$ rm -r app/cache/* # just in case
$ php app/console assets:install --symlink
$ php app/console assetic:dump --env=prod

C'est assez bon pour la boîte de développement, et --symlink est utile, donc vous n'avez pas à réinstaller vos actifs (par exemple, vous ajoutez un nouveau image) lorsque vous entrez par app_dev.php.

Pour le serveur de production, je viens de supprimer l'option' --symlink ' (dans mon script de déploiement), et j'ai ajouté cette commande à la fin:

$ rm -r web/bundles/*/css web/bundles/*/js # all this is already compiled, we don't need the originals

Tout est fait. Avec cela, vous pouvez utiliser des chemins comme celui - ci dans votre .fichiers css: ../img/picture.jpeg

8
répondu ChocoDeveloper 2014-08-10 20:23:11

J'ai eu le même problème et j'ai juste essayé d'utiliser ce qui suit comme solution de contournement. Semble fonctionner pour autant. Vous pouvez même créer un modèle factice qui ne contient que des références à tous ces actifs statiques.

{% stylesheets
    output='assets/fonts/glyphicons-halflings-regular.ttf'
    'bundles/bootstrap/fonts/glyphicons-halflings-regular.ttf'
%}{% endstylesheets %}

Notez l'omission de toute sortie qui signifie que rien n'apparaît sur le modèle. Quand je lance assetic:dump les fichiers sont copiés à l'emplacement souhaité et le css inclut le travail comme prévu.

5
répondu Cowlby 2013-10-19 22:19:17

Si cela peut aider quelqu'un, nous avons beaucoup lutté avec Assetic, et nous faisons maintenant ce qui suit en mode développement:

  • Mis en place comme dans Dumping des fichiers D'actifs dans l'environnement de développement donc, dans config_dev.yml, nous avons commenté:

    #assetic:
    #    use_controller: true
    

    Et dans routing_dev.yml

    #_assetic:
    #    resource: .
    #    type:     assetic
    
  • Spécifiez l'URL comme absolue à partir de la racine web. Par exemple, background-image: url("/bundles/core/dynatree/skins/skin/vline.gif"); Remarque: Notre racine Web vhost pointe sur web/.

  • Aucune utilisation de cssrewrite filtre

2
répondu user1041440 2014-08-10 20:28:08

Je gère le plugin CSS / JS avec composer qui l'installe sous vendor. Je les relie symboliquement au répertoire web / bundles, ce qui permet à composer de mettre à jour les bundles au besoin.

Exemple:

1-lien symbolique une fois (utilisez la commande fromweb / bundles /

ln -sf vendor/select2/select2/dist/ select2

2-utiliser l'actif si nécessaire, dans le modèle twig:

{{ asset('bundles/select2/css/fileinput.css) }}

Cordialement.

1
répondu Jean-Luc Barat 2016-06-19 12:42:51