Шлях активів у файлах CSS в Symfony 2


101

Проблема

У мене є 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
Я відправив своє рішення тут: stackoverflow.com/q/9501248/1146363
Cerad

Чи реально це вирішує проблему з шляхами при використанні app_dev.php?
apfelbox

Відповіді:


194

Я зіткнувся з дуже-дуже такою ж проблемою.

Коротко:

  • Готовність мати оригінальний CSS у "внутрішньому" режимі (Ресурси / активи / css / a.css)
  • Готові мати зображення у "public" dir (Resources / public / images / devil.png)
  • Хоча ця гілка забирає цей CSS, перекомпілює його у web / css / a.css і змушує вказати зображення в /web/bundles/mynicebundle/images/devil.png

Я зробив тест із ВСІМ можливими (розумними) комбінаціями з наступного:

  • @ примітка, відносна нотація
  • Розбір з cssrewrite, без нього
  • Фон зображення CSS та безпосередньо <img> тег src = до того самого зображення, що й CSS
  • CSS розбирається з активними, а також без аналізу з прямим результатом активів
  • І все це помножено на спробу "public dir" (as Resources/public/css) з CSS та "private" каталогом (as Resources/assets/css).

Це дало мені в цілому 14 комбінацій на одній гілочці, і цей маршрут був запущений з

  • "/app_dev.php/"
  • "/app.php/"
  • і "/"

таким чином даючи 14 х 3 = 42 тести.

Крім того, все це було перевірено, працюючи у підкаталозі, тому немає можливості обдурити, надаючи абсолютні URL-адреси, оскільки вони просто не працюватимуть.

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

Я спостерігав таке:

Лише 3 з 14 тестів були адекватно показані за трьома URL-адресами. І НІКОЛИ не був із "внутрішньої" папки (Ресурси / активи). Було необхідною умовою мати запасний CSS PUBLIC, а потім будувати з активними ВІД.

Ось такі результати:

  1. Результат запущений за допомогою /app_dev.php/ Результат запущений за допомогою /app_dev.php/

  2. Результат запущений за допомогою /app.php/ Результат запущений за допомогою /app.php/

  3. Результат запущений за допомогою / введіть тут опис зображення

Отже ... ТОЛЬКО - Другий образ - 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');
}

Структура "каталогів":

Довідники Довідники

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

Але є хороші новини . Якщо ви не хочете мати "запасний CSS" у загальнодоступних каталогах ... встановлюйте їх не разом --symlink, а справді роблячи копію. Після того, як "Активік" створив складений CSS, ви можете вилучити оригінальний CSS з файлової системи та залишити зображення:

Процес компіляції Процес компіляції

Примітка. Це я роблю для --env=prodнавколишнього середовища.

Лише кілька заключних думок:

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

  • Іншим (невідомим, якщо можливо) рішенням буде дослідження, чи "активи: установка" можуть брати лише "загальнодоступні" як джерело або також можуть брати "активи" як джерело для публікації. Це допоможе при встановленні з --symlinkопцією при розробці.

  • Крім того, якщо ми збираємося скриптувати видалення з "загальнодоступного" режиму, то необхідність їх зберігання в окремому каталозі ("активи") зникає. Вони можуть жити всередині "громадськості" в нашій системі контролю версій, оскільки їх буде розміщено після розгортання для загального користування. Це дозволяє також --symlinkвикористовувати.

АЛЕ ВСЕ, ОБЕРЕЖНО ЗАРАЗ: Оскільки оригіналів уже немає ( rm -Rf), є лише два рішення, а не три. Діючий div "B" більше не працює, оскільки це був виклик активу (), якщо припустити, що він був оригінальним. Працюватиме лише "C" (складений).

Отже ... Є ТОЛЬКО ЗАКОННИЙ ПЕРЕМОЖНИК: Div "C" дозволяє ТОЧНО те, про що було задано в темі: Складати, поважати шлях до зображень і не піддавати оригіналу джерела публіці.

Переможець - C

Переможець - C


3
Посилання на зображення для попереднього допису: 1) Результат запущений за допомогою /app_dev.php/ , 2) Результат запущений за допомогою /app.php/ посилання , 3) результат запущений за допомогою / link , 4) Посилання каталогів , 5) Посилання процесу компіляції , 6) Хто є посиланням
Хаві Монтеро

1
І якщо ви хочете додати зображення з іншого пакету, замість цього background-image: url('../images/devil.png');скористайтеся цимbackground-image: url('../../../bundles/frontendlayout/images/devil.png');
Xavi Montero

1
Також працює поєднання "cssrewrite" з "менше":{% stylesheets filter="cssrewrite,less" "bundles/frontendlayout/less/layout.less" %} <link href="{{ asset_url }}" rel="stylesheet" type="text/css" /> {% endstylesheets %}
Xavi Montero

1
Це зазначається в документації на Symfony. Дивіться тут
Ной Дункан

17

Фільтр cssrewrite наразі не сумісний із нотацією @bundle. Отже, у вас є два варіанти:

  • Посилання на файли CSS у веб-папці (після console assets:install --symlink web:)

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

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

Дякую за Ваш коментар Друге рішення звучить досить добре, якщо у вас є лише невеликі зображення. Мені б не комфортно помістити якісь 100k + зображень у CSS-файл.
apfelbox

9

Я опублікую те, що працювало для мене, завдяки @ xavi-montero.

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

Змініть активні шляхи до форми 'bundles/mybundle/css/*.css'у своєму макеті.

В config.yml, додати правило css_rewriteдо assetic:

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

У мене була така ж проблема, і я просто спробував використати наступне як вирішення. Здається, працює поки що. Ви навіть можете створити фіктивний шаблон, який просто містить посилання на всі ці статичні активи.

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

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


1
Ви можете використовувати конфігураційний запис для названого ресурсу, і вам не потрібно включати його в шаблони. Він все одно
скине

3

Якщо це може комусь допомогти, ми багато боролися з Assetic, і зараз ми робимо наступне в режимі розробки:

  • Налаштування, як у демпінгових файлах активів у середовищі розробників, так config_dev.yml, ми прокоментували:

    #assetic:
    #    use_controller: true

    І в routing_dev.yml

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

  • Немає використання фільтра cssrewrite


3
Це вірне рішення, але тільки якщо ви ніколи не будете служити файли з підкаталогу, наприклад: http://example.org/sub/.
apfelbox

1

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

приклад:

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

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

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

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

З повагою

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.