Путь ресурсов в файлах CSS в Symfony 2 - PullRequest
98 голосов
/ 29 февраля 2012

Задача

У меня есть 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, что приводит к NotFoundHttpException.

Есть ли лучшее и рабочее решение?

Ответы [ 6 ]

193 голосов
/ 24 апреля 2012

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

Вкратце:

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

Я провел тест со ВСЕМИ возможными (вменяемыми) комбинациями из следующих:

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

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

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

, что дает 14 x 3 = 42 теста.

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

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

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

Только 3 из 14 тестов были адекватно показаны на трех URL.И 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

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

Все это пришло, потому что я не хотел, чтобы отдельные исходные файлы были доступны общественности,особенно, если я хотел поиграть с фильтром "less", "sass" или аналогичным ... Я не хотел публиковать свои "оригиналы", только скомпилированный.

Но есть хорошие новости .Если вы не хотите иметь «запасной CSS» в общедоступных каталогах ... установите их не с --symlink, а просто сделайте копию.Как только «сборка» создала составной CSS, и вы можете УДАЛИТЬ исходный CSS из файловой системы и оставить изображения:

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

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

Несколько заключительных мыслей:

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

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

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

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

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

Победитель C

The winner is C

16 голосов
/ 26 марта 2012

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

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

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

    {% stylesheets '@MyCompanyMyBundle/Resources/assets/css/*.css' filter="cssembed" %}
    
8 голосов
/ 22 августа 2012

Я выложу, что сработало для меня, благодаря @ xavi-montero.

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

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

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

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

Теперь установите ресурсы и скомпилируйте с ассемблером:

$ 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

5 голосов
/ 20 октября 2013

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

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

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

2 голосов
/ 23 августа 2012

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

  • Настроить как в Дамп файлов активов в 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

1 голос
/ 19 июня 2016

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

пример:

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

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

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

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

Привет.

...