Путь активов в файлах CSS в Symfony 2

Проблема

У меня есть файл 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:

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

Текущее (третье) решение

Поскольку все файлы CSS заканчиваются на /web/css/stylexyz.css, я изменил все пути в файле CSS относительно:

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

Это (плохое) решение работает, за исключением среды dev: Путь CSS равен /app_dev.php/css/stylexyz.css, и поэтому путь изображения, полученный из этого, равен /app_dev.php/images/myimage.png, что приводит к a NotFoundHttpException.

Есть ли лучшее и эффективное решение?

Ответ 1

Я столкнулся с очень-той же проблемой.

Короче:

  • Желание иметь оригинальный CSS во внутреннем каталоге (Resources/assets/css/a.css)
  • Желание иметь изображения в "общедоступном" каталоге (Ресурсы/общедоступные/images/devil.png)
  • Считая, что веточка берет этот CSS, перекомпилирует его в web/css/a.css и заставляет его указывать образ в /web/bundles/mynicebundle/images/devil.png

Я провел тест со всеми возможными (нормальными) комбинациями:

  • @notation, относительная нотация
  • Разбор с cssrewrite, без него
  • Фон изображения CSS vs direct <img> tag src= к тому же изображению, что и CSS
  • CSS анализируется с помощью ассемблера, а также без синтаксического анализа с асептическим прямым выходом
  • И все это умножается на попытку "public dir" (как Resources/public/css) с CSS и "private" (как Resources/assets/css).

Это дало мне в общей сложности 14 комбинаций на одной ветке, и этот маршрут был запущен из

  • "/app_dev.php/"
  • "/app.php/"
  • и "/"

давая 14 x 3 = 42 теста.

Кроме того, все это было протестировано, работая в подкаталоге, поэтому нет способа обмануть, указав абсолютные URL-адреса, потому что они просто не будут работать.

Тестирование состояло из двух неназванных изображений, а затем от имени 'a' до 'f' для CSS, созданного из общей папки, и названного 'g to' l 'для тех, которые были построены из внутреннего пути.

Я заметил следующее:

Только 3 из 14 тестов были показаны адекватно по трем URL-адресам. И NONE был из "внутренней" папки (Ресурсы/активы). Это было предпосылкой для того, чтобы иметь запасную CSS PUBLIC, а затем строить с помощью assetic FROM there.

Вот результаты:

  • Результат, запущенный с помощью /app _dev.php/ Result launched with /app_dev.php/

  • Результат, запущенный с помощью /app.php/ Result launched with /app.php/

  • Результат, запущенный с / enter image description here

Итак... ТОЛЬКО  - второе изображение  - 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>

Контейнер .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, но действительно создайте копию. После того, как "assetic" построил составной CSS, и вы можете УДАЛИТЬ оригинальный CSS из файловой системы и оставить изображения:

Процесс компиляции Compilation process

Примечание. Я делаю это для среды --env=prod.

Несколько последних мыслей:

  • Это желаемое поведение может быть достигнуто за счет наличия изображений в "общедоступном" каталоге в Git или Mercurial и "css" в каталоге "assets". То есть вместо того, чтобы иметь их в "общедоступных", как показано в каталогах, представьте, что a, b, c... находятся в "активах" вместо "public", чем у вашего установщика/развертывателя (возможно, Bash script), чтобы временно помещать CSS в "общедоступный" каталог перед assets:install, затем assets:install, затем assetic:dump, а затем автоматизация удаления CSS из общего каталога после выполнения assetic:dump. Это должно было бы ТОЧНО выполнить поведение, требуемое в вопросе.

  • Другое (неизвестное, если возможно) решение будет состоять в том, чтобы исследовать, может ли "assets: install" использовать только "public" в качестве источника или также может использовать "активы" в качестве источника для публикации. Это поможет при установке с опцией --symlink при разработке.

  • Кроме того, если мы перейдем к script удалению из "общедоступного" каталога, то необходимость сохранения их в отдельном каталоге ( "активы" ) исчезнет. Они могут жить внутри "общественности" в нашей системе контроля версий, поскольку они будут удалены при развертывании для общественности. Это также позволяет использовать --symlink.

НО ВПЕРВЫЕ, ВНИМАНИЕ СЕЙЧАС: Поскольку теперь оригиналов больше нет (rm -Rf), есть только два решения, а не три. Рабочий div "B" больше не работает, так как это был вызов asset(), предполагающий, что был исходный актив. Будет работать только "C" (скомпилированный).

Итак, есть ТОЛЬКО ОКОНЧАТЕЛЬНЫЙ ПОБЕДИТЕЛЬ: Div "C" позволяет ТОЧНО, что он задал в теме: компилировать, уважать путь к изображениям и не публиковать исходный источник для публики.

Победителем является C

The winner is C

Ответ 2

Фильтр cssrewrite не совместим с нотной привязкой @bundle. Таким образом, у вас есть два варианта:

  • Ссылка на файлы CSS в веб-папке (после: console assets:install --symlink web)

    {% stylesheets '/bundles/myCompany/css/*." filter="cssrewrite" %}
    
  • Используйте фильтр cssembed для встраивания изображений в CSS, как это.

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

Ответ 3

Я опубликую то, что сработало для меня, благодаря @xavi-montero.

Поместите свой CSS в свой каталог Resource/public/css, а ваши изображения в тексте Resource/public/img.

Измените атрибуты в форме 'bundles/mybundle/css/*.css' в вашем макете.

В config.yml добавьте правило css_rewrite в атрибут:

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" (в моем развертывании script) и добавил эту команду в конец:

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

Все сделано. При этом вы можете использовать такие пути в ваших .css файлах: ../img/picture.jpeg

Ответ 4

У меня была такая же проблема, и я просто попытался использовать следующее в качестве обходного пути. Кажется, работает до сих пор. Вы даже можете создать фиктивный шаблон, который просто содержит ссылки на все эти статические активы.

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

Обратите внимание на отсутствие какого-либо вывода, что означает, что на шаблоне ничего не отображается. Когда я запускаю assetic: дамп, файлы копируются в нужное место, а css включает работу, как ожидалось.

Ответ 5

Если это может помочь кому-то, мы много боролись с Assetic, и теперь мы делаем следующее в режиме разработки:

  • Настройте, как в Dump Asset Files в Dev Environmen, поэтому в config_dev.yml мы прокомментировали:

    #assetic:
    #    use_controller: true
    

    И в routing_dev.yml

    #_assetic:
    #    resource: .
    #    type:     assetic
    
  • Укажите URL-адрес как абсолютный из корня веб-сайта. Например, background-image: url("/bundles/core/dynatree/skins/skin/vline.gif"); Примечание: наш веб-хост vhost указывает на web/.

  • Использование фильтра cssrewrite

Ответ 6

Я использую плагин css/js с композитором, который устанавливает его под поставщиком. Я символически привязываю их к каталогу web/bundles, что позволяет собирать пакеты компоновщика по мере необходимости.

Пример:

1 - symlink раз на всех (используйте команду fromweb/bundles/

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

2 - использовать актив, если необходимо, в шаблоне ветки:

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

С уважением.

Ответ 7

Я наконец нашел решение !! Я работал над этим вопросом часами!

Вы написали: '@FooBundle/Resources/public/css/main.css' filter='cssrewrite'

НО фильтр cssrewrite не принимает синтаксис @FooBundle!

Вы должны сделать: php app/console assets:install

Symfony создаст: web/bundles/yourbundle/css/main.css

Теперь в вашем шаблоне ветки замените: '@FooBundle/Resources/public/css/main.css' filter='cssrewrite'

с помощью: 'bundles/yourbundle/css/main.css' filter='cssrewrite'

Надеюсь, это поможет кому-то еще! (написано в Symfony docs.. ^^)