Ruta de los activos en archivos CSS en Symfony 2


Problema

Tengo un archivo CSS con algunas rutas (para imágenes, fuentes, etc.).. url(..)).

La estructura de mi camino es así:

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

Quiero hacer referencia a mis imágenes en la hoja de estilos.

Primera solución

Cambié todas las rutas en el archivo CSS a rutas absolutas. Esta no es una solución, ya que la aplicación debería (¡y tiene que hacerlo!) estar trabajando en un subdirectorio, también.

Segunda solución

Use Assetic con filter="cssrewrite".

Así que cambié todas mis rutas en mi archivo CSS a

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

Para representar la ruta real desde mi directorio de recursos al directorio /web/images. Esto no funciona, ya que cssrewrite produce el siguiente código:

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

Que es obviamente el camino equivocado.

Después de assetic:dump se crea este camino, que sigue siendo incorrecto:

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

El código ramita de Assetic:

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

Solución actual (Tercera)

Dado que todos los archivos CSS terminan en /web/css/stylexyz.css, Cambié todas las rutas en el archivo CSS para que fueran relativas:

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

Esta solución (mala) funciona, excepto en el entorno dev : La ruta CSS es /app_dev.php/css/stylexyz.css y por lo tanto la ruta de la imagen resultante de esto es /app_dev.php/images/myimage.png, lo que resulta en un NotFoundHttpException.

¿Hay una solución mejor y que funcione?

Author: apfelbox, 2012-02-29

6 answers

Me he encontrado con el muy-muy-mismo problema.

En resumen:

  • Dispuesto a tener CSS original en un dir "interno" (Resources/assets/css/a.css)
  • Dispuesto a tener las imágenes en el dir "público" (Resources/public/images/devil.png)
  • Willing that twig toma ese CSS, recompilándolo en web/css/a.css y haz que apunte la imagen en /web/bundles/mynicebundle/images/devil.png

He hecho una prueba con TODO lo posible (cuerdo) combinaciones de lo siguiente:

  • @ notación, notación relativa
  • Analizar con cssrewrite, sin él
  • CSS image background vs direct tag src = a la misma imagen que CSS
  • CSS analizado con assetic y también sin analizar con assetic direct output
  • Y todo esto multiplicado por intentar un "dir público" (como Resources/public/css) con el CSS y un directorio "privado" (como Resources/assets/css).

Esto me dio un total de 14 combinaciones en el mismo ramita, y esta ruta fue lanzada desde

  • " / app_dev.php/"
  • " / app.php/"
  • y "/"

Dando así 14 x 3 = 42 pruebas.

Además, todo esto ha sido probado trabajando en un subdirectorio, por lo que no hay manera de engañar dando URLs absolutas porque simplemente no funcionarían.

Las pruebas fueron dos imágenes sin nombre y luego divs nombrados de 'a 'a' f 'para el CSS construido desde la carpeta pública y nombrados de 'g a' l ' para los construidos desde el camino interno.

Observé lo siguiente: {[15]]}

Solo 3 de las 14 pruebas se mostraron adecuadamente en las tres URL. Y NINGUNO era de la carpeta "interna" (Recursos/activos). Era un requisito previo tener el CSS de repuesto PÚBLICO y luego construir con assetic DESDE allí.

Estos son los resultados:

  1. Resultado lanzado con / app_dev.php/ Resultado lanzado con / app_dev.php/

  2. Resultado lanzado con / app.php/ Resultado lanzado con / app.php/

  3. Resultado lanzado con / introduzca la descripción de la imagen aquí

So... SOLO - La segunda imagen - Div B - División C son las sintaxis permitidas.

Aquí está el código de RAMITA:

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

El envase.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;
}

Y a. css, b. css, c. css, etc: todos idénticos, simplemente cambiando el color y el selector CSS.

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

La estructura de" directorios " es:

Directorios Directory

Todo esto vino, porque no quería que los archivos originales individuales expuestos para el público, especialmente si quería jugar con filtro" less " o "sass" o similar... No quería publicar mis "originales", solo el compilado.

Pero hay buenas noticias. Si no desea tener el "CSS de repuesto" en los directorios públicos... instalarlos no con --symlink, pero realmente haciendo una copia. Una vez que "assetic" ha construido el CSS compuesto, y puede ELIMINAR el CSS original del sistema de archivos, y dejar las imágenes:

Compilación proceso Proceso de compilación

Tenga en cuenta que hago esto para el entorno --env=prod.

Solo algunos pensamientos finales:

  • Este comportamiento deseado se puede lograr teniendo las imágenes en el directorio" public "en Git o Mercurial y el" css "en el directorio" assets". Es decir, en lugar de tenerlos en "público" como se muestra en los directorios, imagine a, b, c... residiendo en los "activos" en lugar de "público", que tienen su instalador / deployer (probablemente un Bash script) para poner el CSS temporalmente dentro del directorio "public" antes de que assets:install se ejecute, luego assets:install, luego assetic:dump, y luego automatizar la eliminación de CSS del directorio público después de que assetic:dump se haya ejecutado. Esto lograría EXACTAMENTE el comportamiento deseado en la pregunta.

  • Otra solución (desconocida si es posible) sería explorar si "assets:install" solo puede tomar "public" como fuente o también podría tomar "assets" como fuente para publicar. Eso ayudaría cuando se instala con la opción --symlink al desarrollar.

  • Además, si vamos a script la eliminación del dir "public", entonces, la necesidad de almacenarlos en un directorio separado ("assets") desaparece. Pueden vivir dentro de "público" en nuestro sistema de control de versiones, ya que se eliminarán al desplegarse al público. Esto también permite el uso de --symlink.

PERO DE TODOS MODOS, PRECAUCIÓN AHORA: Como ahora los originales ya no están allí (rm -Rf), solo hay dos soluciones, no tres. El div "B" que funciona ya no funciona, ya que era una llamada a asset() asumiendo que había el asset original. Solo" C " (el compilado) funcionará.

So... solo hay un GANADOR FINAL: Div " C " permite EXACTAMENTE lo que se pidió en el tema: Para ser compilado, respetar el camino a las imágenes y no exponer la fuente original al público.

El ganador es C

El ganador es C

 193
Author: Xavi Montero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-10 18:09:28

El filtro cssrewrite no es compatible con la notación @bundle por ahora. Así que tienes dos opciones:

  • Haga referencia a los archivos CSS en la carpeta web (después: console assets:install --symlink web)

    {% stylesheets '/bundles/myCompany/css/*." filter="cssrewrite" %}
    
  • Utilice el filtro cssembed para incrustar imágenes en el CSS de esta manera.

    {% stylesheets '@MyCompanyMyBundle/Resources/assets/css/*.css' filter="cssembed" %}
    
 16
Author: jeremymarc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-10 20:20:34

Publicaré lo que funcionó para mí, gracias a @xavi-montero.

Ponga su CSS en el directorio Resource/public/css de su paquete, y sus imágenes en digamos Resource/public/img.

Cambie las rutas assetic al formulario 'bundles/mybundle/css/*.css', en su diseño.

En config.yml, agregue la regla css_rewrite a assetic:

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

Ahora instala assets y compila con assetic:

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

Esto es lo suficientemente bueno para el cuadro de desarrollo, y --symlink es útil, por lo que no tiene que reinstalar sus activos (por ejemplo, agregue un nuevo imagen) cuando entras a través de app_dev.php.

Para el servidor de producción, acabo de eliminar la opción' sym symlink ' (en mi script de implementación), y agregué este comando al final:

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

Todo está hecho. Con esto, puede utilizar rutas como esta en su .archivos css: ../img/picture.jpeg

 8
Author: ChocoDeveloper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-10 20:23:11

Tuve el mismo problema y acabo de intentar usar lo siguiente como una solución. Parece funcionar hasta ahora. Incluso puede crear una plantilla ficticia que solo contenga referencias a todos esos activos estáticos.

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

Observe la omisión de cualquier salida, lo que significa que no aparece nada en la plantilla. Cuando corro assetic: dump, los archivos se copian en la ubicación deseada y el css incluye el trabajo esperado.

 5
Author: Cowlby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-19 22:19:17

Si puede ayudar a alguien, hemos luchado mucho con Assetic, y ahora estamos haciendo lo siguiente en el modo de desarrollo:

  • Configurar como en Vertido de Archivos de Activos en el dev Environmen así que en config_dev.yml, hemos comentado:

    #assetic:
    #    use_controller: true
    

    Y en routing_dev.yml

    #_assetic:
    #    resource: .
    #    type:     assetic
    
  • Especifique la URL como absoluta desde la raíz web. Por ejemplo, background-image: url("/bundles/core/dynatree/skins/skin/vline.gif"); Nota: nuestra raíz web vhost apunta a web/.

  • Sin uso de cssrewrite filter

 2
Author: user1041440,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-10 20:28:08

Me offen administrar css/js plugin con composer que instalarlo bajo vendor. Los enlace simbólicamente al directorio web / bundles, que permite composer actualizar los paquetes según sea necesario.

Ejemplo:

1-enlace simbólico una vez (use el comando fromweb / bundles /

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

2-utilice el activo cuando sea necesario, en la plantilla twig :

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

Saludos.

 1
Author: Jean-Luc Barat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-19 12:42:51