web-dev-qa-db-ja.com

Symfony 2のCSSファイル内のアセットのパス

問題

CSS ファイルにいくつかのパスが含まれています(画像、フォントなどの場合。url(..))。

私のパス構造は次のとおりです。

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

スタイルシートで画像を参照したい。

最初の解決策

CSSファイルのすべてのパスを絶対パスに変更しました。これも解決策ではありません。アプリケーションもサブディレクトリで動作する必要があるためです(そうする必要があります!)。

第二の解決策

Asseticをfilter="cssrewrite"とともに使用します。

そのため、CSSファイルのすべてのパスを

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

リソースディレクトリから/web/imagesディレクトリへの実際のパスを表すため。 cssrewriteは次のコードを生成するため、これは機能しません。

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

これは明らかに間違った道です。

assetic:dumpの後、このパスが作成されますが、これはまだ間違っています:

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

Asseticのtwigコード:

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

現在の(3番目の)ソリューション

すべてのCSSファイルが/web/css/stylexyz.cssになるため、CSSファイルのすべてのパスを相対パスに変更しました。

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

dev環境を除き、この(悪い)ソリューションは機能します。CSSパスは/app_dev.php/css/stylexyz.cssであるため、これから生じるイメージパスは/app_dev.php/images/myimage.pngであり、NotFoundHttpExceptionになります。 。

より優れた実用的なソリューションはありますか?

99
apfelbox

私は非常に同じ問題に出くわしました。

要するに:

  • 「内部」ディレクトリ(Resources/assets/css/a.css)に元のCSSを用意します。
  • 「パブリック」ディレクトリ(Resources/public/images/devil.png)に画像を配置する意思がある
  • twigがそのCSSを受け取り、それをweb/css/a.cssに再コンパイルし、/ web/bundles/mynicebundle/images/devil.png内の画像を指すようにします。

私は、次のすべての可能な(健全な)組み合わせでテストを行いました。

  • @記法、相対記法
  • Cssrewriteを使用して解析し、それを使用しない
  • CSS画像の背景と直接の<img>タグsrc =はCSSとまったく同じ画像に
  • アセットで解析され、アセットの直接出力で解析されないCSS
  • そして、このすべてに、CSSと「プライベート」ディレクトリ(Resources/public/cssとして)を備えた「public dir」(Resources/assets/cssとして)を試してみました。

これにより、同じ小枝で合計14の組み合わせが得られ、このルートは

  • 「/app_dev.php/」
  • 「/app.php/」
  • および「/」

したがって、14 x 3 = 42のテストを行います。

さらに、これらはすべてサブディレクトリでの動作がテストされているため、絶対URLを指定してもだまされることはありません。

テストは名前のない2つの画像で、パブリックフォルダーからビルドされたCSSの「a」から「f」の名前のdivと、内部パスからビルドされたものの「g」から「l」の名前のdivでした。

私は次のことを観察しました:

3つのURLでは、14のテストのうち3つだけが適切に表示されました。そして、NONEは「内部」フォルダー(Resources/assets)からのものでした。予備のCSS PUBLICを用意し、そこから資産のあるFROMでビルドすることが前提条件でした。

結果は次のとおりです。

  1. /app_dev.php/で起動された結果 Result launched with /app_dev.php/

  2. /app.php/で起動された結果 Result launched with /app.php/

  3. /で起動した結果 enter image description here

だから... ONLY-2番目の画像-Div B-Div Cは許可された構文です。

ここにTWIGコードがあります:

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

そしてa.css、b.css、c.cssなど:すべて同一で、色とCSSセレクターを変更するだけです。

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

「ディレクトリ」構造は次のとおりです。

ディレクトリ Directories

これはすべて、個々の元のファイルを公開することを望まないためです。特に、「より少ない」フィルターまたは「sass」などで再生したい場合は...コンパイル済みの「オリジナル」のみを公開したい。

しかし、良いニュースがあります。パブリックディレクトリに「スペアCSS」を置きたくない場合は、--symlinkではなく、実際にコピーを作成してインストールします。 「アセティック」が複合CSSを構築したら、ファイルシステムから元のCSSを削除して、画像を残すことができます。

コンパイルプロセス Compilation process

注:--env=prod環境に対してこれを行います。

ほんのいくつかの最終的な考え:

  • この望ましい動作は、イメージを Git または Mercurial の「パブリック」ディレクトリに配置し、「アセット」ディレクトリに「css」を配置することで実現できます。 。つまり、ディレクトリに示されているように「パブリック」に置く代わりに、「パブリック」ではなく「アセット」にあるa、b、c ...を想像してください。インストーラー/デプロイヤー(おそらく Bash スクリプト)assets:installassets:installassetic:dumpの順に実行される前に、CSSを「パブリック」ディレクトリ内に一時的に配置し、削除を自動化するassetic:dumpが実行された後のパブリックディレクトリからのCSS。これにより、質問で必要な動作が正確に達成されます。

  • 別の(可能な場合は不明)解決策は、「assets:install」がソースとして「public」しか使用できない場合、または公開するソースとして「assets」を使用できるかどうかを調べることです。開発時に--symlinkオプションを指定してインストールすると役立ちます。

  • さらに、「パブリック」ディレクトリからの削除をスクリプト化する場合、それらを別のディレクトリ(「アセット」)に保存する必要がなくなります。それらは、バージョン管理システムの「パブリック」内に存在できます。これは、パブリックにデプロイするとドロップされるためです。これにより、--symlinkの使用も可能になります。

しかし、とにかく、今すぐ注意:現在、オリジナルはもう存在しないので(rm -Rf)、3つではなく2つのソリューションしかありません。元のアセットがあると仮定したasset()呼び出しであったため、作業div「B」はもう機能しません。 「C」(コンパイルされたもの)のみが機能します。

だから...最終的な勝者のみがいます:Div "C"は、トピックで求められたとおりにできます。コンパイルするために、画像へのパスを尊重し、元のソースを公開しないでください。

勝者はC

The winner is C

193
Xavi Montero

現在、cssrewriteフィルターは@bundle表記と互換性がありません。したがって、2つの選択肢があります。

  • Webフォルダー内のCSSファイルを参照します(後:console assets:install --symlink web

    {% stylesheets '/bundles/myCompany/css/*." filter="cssrewrite" %}
    
  • Cssembedフィルターを使用して、このようにCSSに画像を埋め込みます。

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

@ xavi-monteroに感謝します。

バンドルのResource/public/cssディレクトリにCSSを配置し、Resource/public/imgに画像を配置します。

アセットパスをレイアウトの'bundles/mybundle/css/*.css'に変更します。

config.ymlで、ルールcss_rewriteをasseticに追加します。

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

アセットをインストールして、asseticでコンパイルします。

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

これは開発ボックスにとって十分であり、--symlinkは便利なので、app_dev.phpを入力するときにアセットを再インストール(たとえば、新しいイメージを追加)する必要はありません。

実稼働サーバーの場合、(展開スクリプトの) '--symlink'オプションを削除し、最後にこのコマンドを追加しました。

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

すべて完了です。これにより、.cssファイルで次のようなパスを使用できます:../img/picture.jpeg

8
ChocoDeveloper

私は同じ問題を抱えていたので、回避策として以下を使用してみました。これまでのところ動作しているようです。これらすべての静的アセットへの参照のみを含むダミーテンプレートを作成することもできます。

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

出力が省略されていることに注意してください。つまり、テンプレートには何も表示されません。 assetic:dumpを実行すると、ファイルが目的の場所にコピーされ、cssに期待どおりの作業が含まれます。

5
Cowlby

それが誰かを助けることができるなら、私たちはAsseticと多くの苦労をしてきました。そして現在、開発モードで次のことをしています。

  • 開発環境でのアセットファイルのダンプのように設定するため、config_dev.ymlでコメントしました。

    #assetic:
    #    use_controller: true
    

    そしてrouting_dev.ymlで

    #_assetic:
    #    resource: .
    #    type:     assetic
    
  • Webルートから絶対URLを指定します。たとえば、background-image:url("/bundles/core/dynatree/skins/skin/vline.gif");注:vhost Webルートはweb/を指しています。

  • Cssrewriteフィルターの使用なし

2
user1041440

私はcss/jsプラグインをcomposerで管理し、ベンダーの下にインストールします。それらをweb/bundlesディレクトリにシンボリックリンクします。これにより、必要に応じてcomposerバンドルが更新されます。

例:

1-一度だけシンボリックリンク(web/bundles /

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

2-twigテンプレートで、必要に応じてアセットを使用します:

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

よろしく。

1
Jean-Luc Barat