104 votes

Chemin des actifs dans les fichiers CSS dans Symfony 2

Problème

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

Mon chemin structure ressemble à ceci:

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

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

Première Solution

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

Deuxième Solution

Utiliser Assetic avec filter="cssrewrite".

Alors, j'ai changé tous mes chemins dans mon fichier CSS

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

pour représenter le chemin d'accès réel à partir de mon répertoire de ressources à l' /web/images répertoire. Cela ne fonctionne pas, car cssrewrite produit le code suivant:

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

ce qui est évidemment le mauvais chemin.

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

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

Le rameau code de Assetic:

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

Courant (Tiers) De La Solution

Depuis tous les fichiers CSS fin en /web/css/stylexyz.css, j'ai changé tous les chemins dans le fichier CSS à être relatif:

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

Cette (mauvaise) solution fonctionne, sauf en devenvironnement: Le CSS chemin est - /app_dev.php/css/stylexyz.css et, par conséquent, le chemin de l'image résultant de cette est - /app_dev.php/images/myimage.png, ce qui résulte en une NotFoundHttpException.

Est-il mieux de et solution de travail?

196voto

Xavi Montero Points 1791

Je suis tombé sur le très très même problème.

En bref:

  • Prêt à avoir des originaux de CSS dans un "interne" dir (Resources/assets/css/un.css)
  • Désireux d'avoir les images dans le "public" dir (Resources/public/images/diable.png)
  • Disposé à ce que brindille prend que CSS, recompile en web/css/un.css et d'en faire le point de l'image dans /web/bundles/mynicebundle/images/diable.png

J'ai fait un test avec TOUS les possibles (sane) une combinaison des options suivantes:

  • @la notation, la notation relative
  • Analyser avec cssrewrite, sans qu'il
  • CSS de l'image d'arrière-plan vs direct balise <img> src= très à la même image que les CSS
  • CSS analysé avec assetic et aussi sans analyse avec assetic sortie directe
  • Et tout cela multiplié par essayer un public "dir" ( Resources/public/css) avec le CSS et un "privé" du répertoire ( Resources/assets/css).

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

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

et donc de donner de 14 x 3 = 42 tests.

En outre, tout cela a été testé de travail dans un sous-répertoire, il n'existe aucun moyen de les tromper en donnant des Url absolues car ils seraient tout simplement pas de travail.

Les tests ont été deux sans nom, les images et les divs le nom de 'a' à 'f') pour le CSS construit à PARTIR du dossier public et nommé 'g 'l' pour ceux qui sont intégrés depuis le chemin de l'intérieur.

J'ai observé ce qui suit:

Seulement 3 des 14 essais ont montré de manière adéquate sur les trois URLs. Et AUCUN n'était de la "interne" du dossier (Ressources/actifs). C'était un pré-requis pour avoir la pièce de rechange CSS PUBLIC et ensuite construire avec assetic à PARTIR de là.

Ce sont les résultats:

  1. Résultat lancée avec /app_dev.php/ Result launched with /app_dev.php/

  2. Résultat lancée avec /app.php/ Result launched with /app.php/

  3. Résultat lancée avec / enter image description here

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

Ici, il y a le RAMEAU code:

<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 un.css, b.css, c.css, etc: tous identiques, simplement en changeant la couleur et le sélecteur CSS.

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

Les "répertoires" de la structure est:

Répertoires Directories

Tout cela est venu, parce que je ne voulais pas l'individu fichiers originaux exposés au public, spécialement si je voulais jouer avec "moins" de filtre ou de "sass" ou similaire... je ne veux pas que mon "originaux", publié, seul le compilé.

Mais il ya de bonnes nouvelles. Si vous ne voulez pas avoir de "spare CSS" dans les annuaires publics... les installer avec --symlink, mais vraiment en faire une copie. Une fois "assetic" a construit le composé CSS, et vous pouvez SUPPRIMER les originaux de CSS depuis le système de fichiers, et de laisser les images:

Processus de Compilation Compilation process

Remarque je fais cela pour l' --env=prod environnement.

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, au lieu de l'avoir dans "public", comme indiqué dans les répertoires, imaginer a, b, c... résidant dans les "actifs" au lieu de "public", que d'avoir votre installateur/deployer (probablement un Bash script) pour mettre le CSS temporairement à l'intérieur du "public" dir avant assets:install est exécuté, alors assets:install, alors assetic:dump, et puis l'automatisation de la suppression de la CSS à partir de l'annuaire public après l' assetic:dump a été exécuté. Ce serait d'arriver à EXACTEMENT le comportement désiré dans la question.

  • Un autre (inconnu, si possible), la solution serait d'examiner si des "assets:install" ne peut prendre de "public" en tant que source ou pourrait aussi prendre des "actifs" comme une source de publier. Qui allait l'aider lors de l'installation avec l' --symlink option lors de l'élaboration.

  • En outre, si nous allons créer un script de la suppression de la "public", dir, ensuite, la nécessité de les stocker dans un répertoire séparé ("actif") disparaît. Ils peuvent vivre à l'intérieur de "public" dans notre système de contrôle de version comme il sera abandonné à déployer pour le public. Cela permet aussi pour l' --symlink d'utilisation.

MAIS de toute façon, la PRUDENCE MAINTENANT: Comme maintenant, les originaux ne sont plus là (rm -Rf), il n'existe que deux solutions, et non pas trois. Le travail div "B" ne fonctionne plus comme il était un atout() appel en supposant qu'il était à l'origine de l'actif. Seul "C" (compilées) de travail.

Donc... il n'y a qu'une FINALE VAINQUEUR: Div "C" permet d'effectuer EXACTEMENT ce qu'il était demandé dans le sujet: Pour être compilé, le respect, le chemin vers les images et ne pas l'exposer à la source d'origine pour le public.

Le gagnant est C

The winner is C

17voto

jeremymarc Points 283

Le filtre de cssrewrite n’est pas compatible avec la notation @bundle pour l’instant. Si vous avez deux choix :

  • Référencer les fichiers CSS dans le dossier web (après : `` )
  • Utilisez le filtre cssembed pour incorporer des images dans les CSS comme cela.

9voto

ChocoDeveloper Points 2604

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

Mettez votre CSS dans votre bundle Resource/public/css annuaire et de vos images en dire Resource/public/img.

Changement assetic chemins de la forme 'bundles/mybundle/css/*.css', la mise en page.

En config.yml, ajouter une règle css_rewrite d'assetic:

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

Maintenant installer les actifs et les compiler 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 le développement de la zone, et --symlink est utile, de sorte que vous n'avez pas à réinstaller votre actif (par exemple, vous ajoutez une nouvelle image) lorsque vous entrez par app_dev.php.

Pour le serveur de production, j'ai juste supprimé le '--symlink' option (dans mon script de déploiement), et 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 d'accès comme cela dans votre .fichiers css: ../img/picture.jpeg

5voto

Cowlby Points 406

J’ai eu le même problème et j’ai juste essayé d’utiliser ce qui suit pour contourner le problème. Semble fonctionner jusqu'à présent. Vous pouvez même créer un modèle factice qui contient juste des références à tous ces actifs statiques.

Notez que l’omission de toute sortie, qui ne veut rien dire se présente sur le modèle. Quand je lance assetic : vidage, les fichiers sont copiés sur l’endroit désiré et le css comprend les travaux comme prévu.

3voto

user1041440 Points 146

Si cela peut aider quelqu'un, nous avons eu beaucoup de mal avec Assetic, et nous sommes en train de faire la suite, le mode de développement:

  • Mis en place comme dans Dumping Fichiers d'Actifs dans le dev Mari donc, en config_dev.yml, nous avons commenté:

    #assetic:
    #    use_controller: true
    

    Et dans routing_dev.yml

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

  • Ne pas utiliser de filtre cssrewrite

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X