Symfony 2'de CSS dosyalarındaki varlıkların yolu


101

Sorun

İçinde bazı yollar olan bir CSS dosyam var (resimler, yazı tipleri, vb. İçin url(..)).

Yol yapım şöyle:

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

Resimlerime stil sayfasında referans vermek istiyorum.

İlk Çözüm

CSS dosyasındaki tüm yolları mutlak yollarla değiştirdim. Uygulamanın da bir alt dizinde çalışması gerektiği (ve olması gerektiği!) İçin bu bir çözüm değildir.

İkinci Çözüm

Assetic'i filter="cssrewrite".

Bu yüzden CSS dosyamdaki tüm yollarımı olarak değiştirdim

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

kaynaklar dizinimden dizine gerçek yolu temsil etmek için /web/images. Bu çalışmaz, çünkü cssrewrite aşağıdaki kodu üretir:

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

ki bu kesinlikle yanlış yoldur.

assetic:dumpBu yol oluşturulduktan sonra hala yanlış olan:

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

Assetic'in dal kodu:

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

Mevcut (Üçüncü) Çözüm

Tüm CSS dosyaları sona erdiğinden /web/css/stylexyz.css, CSS dosyasındaki tüm yolları göreceli olacak şekilde değiştirdim:

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

Bu (kötü) çözüm, devortam dışında çalışır : CSS yolu /app_dev.php/css/stylexyz.cssve bu nedenle bundan kaynaklanan görüntü yolu /app_dev.php/images/myimage.png, bir NotFoundHttpException.

Daha iyi ve çalışan bir çözüm var mı?


1
Çözümümü burada yayınladım: stackoverflow.com/q/9501248/1146363
Cerad

Bu, kullanırken yollarla ilgili sorunu gerçekten çözüyor app_dev.phpmu?
apfelbox 01

Yanıtlar:


194

Ben de aynı problemle karşılaştım.

Kısacası:

  • "Dahili" bir dizinde orijinal CSS'ye sahip olmaya istekli (Kaynaklar / varlıklar / css / a.css)
  • Resimleri "genel" dizinde bulundurmaya istekli (Kaynaklar / public / images / devil.png)
  • Bu dalın bu CSS'yi alıp web / css / a.css'ye yeniden derlemesini ve /web/bundles/mynicebundle/images/devil.png içindeki görüntüyü göstermesini istemek

Aşağıdakilerin TÜM olası (mantıklı) kombinasyonları ile bir test yaptım:

  • @ gösterim, göreli gösterim
  • Onsuz cssrewrite ile ayrıştırın
  • CSS resim arka planı - doğrudan <img> etiketi src = CSS ile tamamen aynı resme
  • CSS, asetik ile ve ayrıca asetik doğrudan çıktıyla ayrıştırmadan ayrıştırıldı
  • Ve tüm bunlar Resources/public/cssCSS ile bir "genel dir" (as ) ve "özel" bir dizin (as Resources/assets/css) deneyerek çarpılır .

Bu bana aynı dal üzerinde toplam 14 kombinasyon verdi ve bu rota,

  • "/app_dev.php/"
  • "/app.php/"
  • ve "/"

böylece 14 x 3 = 42 test verir.

Ek olarak, tüm bunlar bir alt dizinde çalışarak test edilmiştir, bu nedenle mutlak URL'ler vererek kandırmanın bir yolu yoktur, çünkü bunlar işe yaramayacaktır.

Testler, iki adsız görüntü ve ardından ortak klasörden oluşturulan CSS için "a" ile "f" arasında ve dahili yoldan oluşturulanlar için "g -" l "arasında adlandırılmış div'lerdi.

Aşağıdakileri gözlemledim:

14 testin sadece 3'ü üç URL'de yeterli şekilde gösterildi. Ve HİÇBİRİ "dahili" klasördendi (Kaynaklar / varlıklar). Yedek CSS PUBLIC'e sahip olmak ve ardından oradan asetic ile inşa etmek bir ön şarttı.

Sonuçlar şunlardır:

  1. Sonuç /app_dev.php/ ile başlatıldı Sonuç /app_dev.php/ ile başlatıldı

  2. Sonuç /app.php/ ile başlatıldı Sonuç /app.php/ ile başlatıldı

  3. Sonuç / ile başlatıldı görüntü açıklamasını buraya girin

Yani ... YALNIZCA - İkinci görüntü - Div B - Div C izin verilen sözdizimleridir.

İşte TWIG kodu var:

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

Container.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;
}

Ve a.css, b.css, c.css, vb: hepsi aynı, sadece rengi ve CSS seçiciyi değiştirerek.

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

"Dizinler" yapısı şu şekildedir:

Dizinler Dizinler

Bütün bunlar geldi, çünkü tek tek orijinal dosyaların halka açık olmasını istemiyordum, özellikle "daha az" filtre veya "sass" veya benzeri bir şekilde oynamak istersem ... "Orijinallerimin" yayınlanmasını istemedim, sadece bir tane derledi.

Ama iyi haberler var . Herkese açık dizinlerde "yedek CSS" nin olmasını istemiyorsanız ... bunları ile değil --symlink, gerçekten bir kopya oluşturarak kurun . "Assetic" bileşik CSS'yi oluşturduktan sonra, orijinal CSS'yi dosya sisteminden SİLİN ve görüntüleri bırakabilirsiniz:

Derleme süreci Derleme süreci

Not Bunu --env=prodçevre için yapıyorum .

Sadece son birkaç düşünce:

  • Bu istenen davranış, görüntülerin Git veya Mercurial'de "genel" dizininde ve "varlıklar" dizininde "css" de bulundurulmasıyla gerçekleştirilebilir. Yani, dizinlerde gösterildiği gibi "genel" olarak yer almaları yerine, a, b, c ... nin yükleyiciniz / dağıtıcınız (muhtemelen bir Bash betiği) yerine "genel" yerine "varlıklar" içinde bulunduğunu hayal edin. CSS'yi geçici olarak "public" dizininin içine koymak assets:install, çalıştırılmadan önce , ardından assets:installve ardından assetic:dump, çalıştırıldıktan sonra CSS'nin genel dizinden kaldırılmasını otomatikleştirmek assetic:dump. Bu tam olarak soruda istenen davranışı sağlayacaktır.

  • Başka bir (mümkünse bilinmeyen) çözüm, "assets: install" öğesinin yalnızca kaynak olarak "genel" olup olmadığını veya yayınlamak için "varlıkları" kaynak olarak alıp alamayacağını araştırmak olacaktır. Bu --symlink, geliştirme sırasında seçenekle birlikte kurulduğunda yardımcı olur .

  • Ek olarak, kaldırmayı "genel" dizininden yapacaksak, bunları ayrı bir dizinde ("varlıklar") saklama ihtiyacı ortadan kalkar. Sürüm kontrol sistemimizde "kamuya açık" içinde yaşayabilirler çünkü halka dağıtıldıktan sonra bırakılacaktır. Bu aynı zamanda --symlinkkullanıma da izin verir .

ANCAK HER ZAMAN ŞİMDİ DİKKAT : Artık orijinaller artık orada olmadığından ( rm -Rf), üç değil, yalnızca iki çözüm var. Çalışan div "B", orijinal varlığın olduğu varsayılarak bir varlık () çağrısı olduğu için artık çalışmıyor. Yalnızca "C" (derlenmiş olan) çalışacaktır.

Öyleyse ... SADECE SON BİR KAZANAN vardır: Div "C" tam olarak konuyla ilgili sorulan şeye izin verir: Derlenmek için görüntülere giden yola saygı gösterin ve orijinal kaynağı kamuya açıklamayın.

Kazanan C

Kazanan C


3
Önceki gönderi için resimlere bağlantılar: 1) Sonuç /app_dev.php/ ile başlatıldı , 2) Sonuç /app.php/ link ile başlatıldı , 3) sonuç / link ile başlatıldı , 4) Dizinler bağlantısı , 5) Derleme işlemi bağlantısı , 6) Kazanan bağlantı
Xavi Montero

1
Ve background-image: url('../images/devil.png');kullanmak yerine başka bir paketten bir resim eklemek istiyorsanız, bunu kullanınbackground-image: url('../../../bundles/frontendlayout/images/devil.png');
Xavi Montero

1
Ayrıca "cssrewrite" ile "daha az" ı birleştirerek çalışır:{% stylesheets filter="cssrewrite,less" "bundles/frontendlayout/less/layout.less" %} <link href="{{ asset_url }}" rel="stylesheet" type="text/css" /> {% endstylesheets %}
Xavi Montero

1
Bu, symfony belgelerinde belirtilmiştir. Buraya
Noah Duncan

17

Cssrewrite filtresi şimdilik @bundle gösterimi ile uyumlu değil. Yani iki seçeneğiniz var:

  • Web klasöründe CSS dosyaları referans (sonra: console assets:install --symlink web)

    {% stylesheets '/bundles/myCompany/css/*." filter="cssrewrite" %}
  • Görselleri CSS'ye bu şekilde gömmek için cssembed filtresini kullanın.

    {% stylesheets '@MyCompanyMyBundle/Resources/assets/css/*.css' filter="cssembed" %}

Yorumun için teşekkür ederim. Yalnızca oldukça küçük resimleriniz varsa, ikinci çözüm kulağa oldukça iyi geliyor. Yine de CSS dosyasına 100.000'den fazla resim koymak kendimi rahat hissetmezdim.
apfelbox

9

@ Xavi-montero sayesinde benim için neyin işe yaradığını yayınlayacağım.

CSS'nizi paketinizin Resource/public/cssdizinine koyun ve resimlerinizi söyleyin Resource/public/img.

Mizanpajınızda forma giden asetik yolları değiştirin 'bundles/mybundle/css/*.css'.

İçinde config.yml, css_rewriteassetic'e kural ekleyin :

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

Şimdi varlıkları kurun ve assetic ile derleyin:

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

Bu, geliştirme kutusu için yeterince iyidir ve --symlinkkullanışlıdır, bu nedenle girdiğinizde varlıklarınızı yeniden yüklemeniz gerekmez (örneğin, yeni bir görüntü eklersiniz) app_dev.php.

Üretim sunucusu için, '--symlink' seçeneğini kaldırdım (dağıtım betiğimde) ve sonuna şu komutu ekledim:

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

Her şey tamam. Bununla, .css dosyalarınızda bunun gibi yolları kullanabilirsiniz:../img/picture.jpeg


5

Aynı sorunu yaşadım ve aşağıdakileri bir geçici çözüm olarak kullanmayı denedim. Şimdiye kadar işe yarıyor gibi görünüyor. Hatta tüm bu statik varlıklara referanslar içeren sahte bir şablon bile oluşturabilirsiniz.

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

Şablonda hiçbir şeyin görünmediği anlamına gelen herhangi bir çıktının atlandığına dikkat edin. Assetic: dump'ı çalıştırdığımda, dosyalar istenen konuma kopyalanır ve css beklendiği gibi çalışmayı içerir.


1
Adlandırılmış varlık için bir yapılandırma girişi kullanabilirsiniz ve bunu şablonlara dahil etmeniz gerekmez. Yine de symfony.com/doc/current/cookbook/assetic/…
venimus

3

Birine yardım edebilecekse, Assetic ile çok uğraştık ve şimdi geliştirme modunda şunları yapıyoruz:

  • Dev Environmen'deki Varlık Dosyalarını Damping'de olduğu gibi ayarlayın config_dev.yml, bu yüzden yorum yaptık:

    #assetic:
    #    use_controller: true

    Ve routing_dev.yml içinde

    #_assetic:
    #    resource: .
    #    type:     assetic
  • URL'yi web kökünden mutlak olarak belirtin. Örneğin, background-image: url("/bundles/core/dynatree/skins/skin/vline.gif");Not: vhost web kökümüz işaret ediyor web/.

  • Cssrewrite filtresi kullanımı yok


3
Bu, geçerli bir çözümdür, ancak örneğin bir alt dizin, dosya asla yayınlanmaz yalnızca: http://example.org/sub/.
apfelbox

1

Css / js eklentisini, satıcıya kuran composer ile yönetiyorum. Bunları web / bundles dizinine sembolik olarak bağlarım, böylece composer gerektiğinde paketleri güncellemesine izin verir.

örnek:

1 - bir kez sembolik bağlantı (web / bundles / komutunu kullanın.

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

2 - dal şablonunda gerektiğinde varlığı kullanın:

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

Saygılarımızla.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.