Đường dẫn của nội dung trong tệp CSS trong Symfony 2


101

Vấn đề

Tôi có một tệp CSS với một số đường dẫn trong đó (cho hình ảnh, phông chữ, v.v. url(..)).

Cấu trúc đường dẫn của tôi như thế này:

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

Tôi muốn tham chiếu hình ảnh của mình trong biểu định kiểu.

Giải pháp đầu tiên

Tôi đã thay đổi tất cả các đường dẫn trong tệp CSS thành đường dẫn tuyệt đối. Đây không phải là giải pháp, vì ứng dụng cũng phải (và phải!) Hoạt động trong một thư mục con.

Giải pháp thứ hai

Sử dụng Assetic với filter="cssrewrite".

Vì vậy, tôi đã thay đổi tất cả các đường dẫn trong tệp CSS của mình thành

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

đại diện cho đường dẫn thực tế từ thư mục tài nguyên của tôi đến /web/imagesthư mục. Điều này không hoạt động, vì cssrewrite tạo ra mã sau:

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

mà rõ ràng là con đường sai lầm.

Sau khi assetic:dumpđường dẫn này được tạo, vẫn sai:

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

Mã cành cây của Assetic:

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

Giải pháp hiện tại (thứ ba)

Vì tất cả các tệp CSS đều kết thúc /web/css/stylexyz.css, tôi đã thay đổi tất cả các đường dẫn trong tệp CSS thành tương đối:

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

Giải pháp (không tốt) này hoạt động, ngoại trừ trong devmôi trường: Đường dẫn CSS là /app_dev.php/css/stylexyz.cssvà do đó đường dẫn hình ảnh tạo ra từ điều này /app_dev.php/images/myimage.png, dẫn đến a NotFoundHttpException.

Có một giải pháp tốt hơn và làm việc?


1
Tôi đã đăng giải pháp của mình ở đây: stackoverflow.com/q/9501248/1146363
Cerad

Điều này thực sự giải quyết vấn đề với các đường dẫn khi sử dụng app_dev.php?
apfelbox

Câu trả lời:


194

Tôi đã gặp phải vấn đề rất giống nhau.

Nói ngắn gọn:

  • Sẵn sàng có CSS ​​gốc trong một dir "nội bộ" (Tài nguyên / tài sản / css / a.css)
  • Sẵn sàng có hình ảnh trong dir "công khai" (Resources / public / images / devil.png)
  • Sẵn sàng rằng cành cây lấy CSS đó, biên dịch lại nó thành web / css / a.css và làm cho nó trỏ hình ảnh trong /web/bundles/mynicebundle/images/devil.png

Tôi đã thực hiện một bài kiểm tra với TẤT CẢ các kết hợp có thể (lành mạnh) của những điều sau:

  • @ chú thích, ký hiệu tương đối
  • Phân tích cú pháp bằng cssrewrite, không có nó
  • Nền hình ảnh CSS so với thẻ <img> trực tiếp src = đến cùng một hình ảnh với CSS
  • CSS được phân tích cú pháp với assetic và cũng không cần phân tích cú pháp với đầu ra trực tiếp assetic
  • Và tất cả điều này được nhân lên bằng cách thử một "public dir" (as Resources/public/css) với CSS và một thư mục "private" (as Resources/assets/css).

Điều này đã cho tôi tổng cộng 14 sự kết hợp trên cùng một nhánh và tuyến đường này được khởi chạy từ

  • "/app_dev.php/"
  • "/app.php/"
  • và "/"

do đó cho ra 14 x 3 = 42 thử nghiệm.

Ngoài ra, tất cả điều này đã được thử nghiệm hoạt động trong một thư mục con, vì vậy không có cách nào để đánh lừa bằng cách đưa ra các URL tuyệt đối bởi vì chúng chỉ đơn giản là không hoạt động.

Các bài kiểm tra là hai hình ảnh không được đặt tên và sau đó các div được đặt tên từ 'a' đến 'f' cho CSS được xây dựng từ thư mục chung và đặt tên 'g thành' l 'cho các hình ảnh được tạo từ đường dẫn nội bộ.

Tôi đã quan sát những điều sau:

Chỉ 3 trong số 14 bài kiểm tra được hiển thị đầy đủ trên ba URL. Và NONE là từ thư mục "nội bộ" (Tài nguyên / tài sản). Điều kiện tiên quyết là phải có CSS ​​PUBLIC dự phòng và sau đó xây dựng với assetic FROM đó.

Đây là những kết quả:

  1. Kết quả được khởi chạy với /app_dev.php/ Kết quả được khởi chạy với /app_dev.php/

  2. Kết quả được khởi chạy với /app.php/ Kết quả được khởi chạy với /app.php/

  3. Kết quả được đưa ra với / nhập mô tả hình ảnh ở đây

Vì vậy, ... CHỈ - Hình ảnh thứ hai - Div B - Div C là các cú pháp được phép.

Đây là mã 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>

Vùng chứa. 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;
}

Và a.css, b.css, c.css, v.v.: tất cả đều giống hệt nhau, chỉ thay đổi màu sắc và bộ chọn CSS.

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

Cấu trúc "thư mục" là:

Thư mục Thư mục

Tất cả những điều này xảy ra, bởi vì tôi không muốn các tệp gốc riêng lẻ bị lộ ra trước công chúng, đặc biệt nếu tôi muốn sử dụng bộ lọc "less" hoặc "sass" hoặc tương tự ... Tôi không muốn "bản gốc" của mình được xuất bản, chỉ biên dịch một.

Nhưng có một tin tốt . Nếu bạn không muốn có "CSS dự phòng" trong các thư mục chung ... hãy cài đặt chúng không phải bằng --symlink, mà hãy thực sự tạo một bản sao. Sau khi "assetic" đã xây dựng CSS tổng hợp và bạn có thể XÓA CSS gốc khỏi hệ thống tệp và để lại các hình ảnh:

Quy trình biên dịch Quy trình biên dịch

Lưu ý tôi làm điều này vì --env=prodmôi trường.

Chỉ là một vài suy nghĩ cuối cùng:

  • Hành vi mong muốn này có thể đạt được bằng cách có các hình ảnh trong thư mục "công khai" trong Git hoặc Mercurial và "css" trong thư mục "tài sản". Nghĩa là, thay vì đặt chúng ở "công cộng" như được hiển thị trong các thư mục, hãy tưởng tượng a, b, c ... nằm trong "tài sản" thay vì "công khai", hơn là có trình cài đặt / trình triển khai của bạn (có thể là tập lệnh Bash ) để tạm thời đặt CSS bên trong dir "công khai" trước khi assets:installđược thực thi, sau assets:installđó assetic:dump, rồi tự động xóa CSS khỏi thư mục công cộng sau khi assetic:dumpđã được thực thi. Điều này sẽ thực hiện CHÍNH XÁC hành vi mong muốn trong câu hỏi.

  • Một giải pháp khác (không xác định nếu có thể) sẽ là khám phá xem "tài sản: cài đặt" chỉ có thể lấy "công khai" làm nguồn hoặc cũng có thể lấy "tài sản" làm nguồn để xuất bản. Điều đó sẽ hữu ích khi được cài đặt với --symlinktùy chọn khi phát triển.

  • Ngoài ra, nếu chúng tôi định viết kịch bản xóa khỏi dir "công khai", thì nhu cầu lưu trữ chúng trong một thư mục riêng ("tài sản") sẽ biến mất. Chúng có thể tồn tại bên trong "công khai" trong hệ thống kiểm soát phiên bản của chúng tôi vì chúng sẽ bị loại bỏ khi triển khai cho công chúng. Điều này cũng cho phép --symlinksử dụng.

NHƯNG BẤT CỨ LÚC NÀO, THẬN TRỌNG NGAY BÂY GIỜ: Vì bây giờ bản gốc không còn ở đó nữa ( rm -Rf), chỉ có hai giải pháp, không phải ba. Div đang hoạt động "B" không hoạt động nữa vì nó là một lệnh gọi nội dung () giả sử có nội dung ban đầu. Chỉ "C" (một trong những biên dịch) sẽ hoạt động.

Vì vậy ... CHỈ CÓ MỘT NGƯỜI CHIẾN THẮNG CUỐI CÙNG: Div "C" cho phép CHÍNH XÁC những gì nó được yêu cầu trong chủ đề: Được tổng hợp, tôn trọng đường dẫn đến hình ảnh và không để lộ nguồn gốc ra công chúng.

Người chiến thắng là C

Người chiến thắng là C


3
Liên kết đến các hình ảnh cho bài đăng trước: 1) Kết quả được khởi chạy với /app_dev.php/ , 2) Kết quả được khởi chạy với liên kết /app.php/ , 3) kết quả được khởi chạy với / link , 4) Liên kết thư mục , 5) Liên kết quá trình biên dịch , 6) Ai là người chiến thắng liên kết
Xavi Montero

1
Và nếu bạn muốn thêm một hình ảnh từ bó khác, thay vì sử dụng background-image: url('../images/devil.png');sử dụng nàybackground-image: url('../../../bundles/frontendlayout/images/devil.png');
Xavi Montero

1
Cũng hoạt động kết hợp "cssrewrite" với "ít":{% stylesheets filter="cssrewrite,less" "bundles/frontendlayout/less/layout.less" %} <link href="{{ asset_url }}" rel="stylesheet" type="text/css" /> {% endstylesheets %}
Xavi Montero

1
Điều này được lưu ý trong tài liệu của symfony. Xem tại đây
Noah Duncan

17

Bộ lọc cssrewrite hiện không tương thích với ký hiệu @bundle. Vì vậy, bạn có hai lựa chọn:

  • Tham chiếu các tệp CSS trong thư mục web (sau console assets:install --symlink web:)

    {% stylesheets '/bundles/myCompany/css/*." filter="cssrewrite" %}
  • Sử dụng bộ lọc cssembed để nhúng hình ảnh vào CSS như thế này.

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

Cảm ơn bình luận của bạn. Giải pháp thứ hai nghe có vẻ khá tốt nếu bạn chỉ có những hình ảnh khá nhỏ. Tuy nhiên, tôi sẽ không cảm thấy thoải mái khi đặt một số hình ảnh hơn 100k vào tệp CSS.
apfelbox

9

Tôi sẽ đăng những gì phù hợp với tôi, cảm ơn @ xavi-montero.

Đặt CSS của bạn trong thư mục của gói Resource/public/cssvà hình ảnh của bạn nói Resource/public/img.

Thay đổi các đường dẫn giả định đối với biểu mẫu 'bundles/mybundle/css/*.css', trong bố cục của bạn.

Trong config.yml, thêm quy tắc css_rewritevào assetic:

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

Bây giờ hãy cài đặt nội dung và biên dịch với assetic:

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

Điều này đủ tốt cho hộp phát triển và --symlinkhữu ích, vì vậy bạn không phải cài đặt lại nội dung của mình (ví dụ: bạn thêm hình ảnh mới) khi nhập qua app_dev.php.

Đối với máy chủ sản xuất, tôi vừa xóa tùy chọn '--symlink' (trong tập lệnh triển khai của tôi) và thêm lệnh này vào cuối:

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

Tất cả đã xong. Với điều này, bạn có thể sử dụng các đường dẫn như thế này trong các tệp .css của mình:../img/picture.jpeg


5

Tôi đã gặp vấn đề tương tự và tôi chỉ thử sử dụng cách giải quyết sau. Có vẻ như hoạt động cho đến nay. Bạn thậm chí có thể tạo một mẫu giả chỉ chứa các tham chiếu đến tất cả các nội dung tĩnh đó.

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

Lưu ý việc bỏ sót bất kỳ đầu ra nào có nghĩa là không có gì hiển thị trên mẫu. Khi tôi chạy assetic: dump các tệp được sao chép đến vị trí mong muốn và css bao gồm hoạt động như mong đợi.


1
Bạn có thể sử dụng mục nhập cấu hình cho nội dung được đặt tên và bạn không bắt buộc phải đưa nó vào các mẫu. Nó sẽ đổ anyways symfony.com/doc/current/cookbook/assetic/...
venimus

3

Nếu nó có thể giúp ích cho ai đó, chúng tôi đã đấu tranh rất nhiều với Assetic và hiện chúng tôi đang làm những điều sau trong chế độ phát triển:

  • Thiết lập giống như trong Dumping Tệp nội dung trong Môi trường dành cho nhà phát triển config_dev.yml, chúng tôi đã nhận xét:

    #assetic:
    #    use_controller: true

    Và trong routing_dev.yml

    #_assetic:
    #    resource: .
    #    type:     assetic
  • Chỉ định URL là tuyệt đối từ gốc web. Ví dụ: background-image: url("/bundles/core/dynatree/skins/skin/vline.gif");Lưu ý: gốc web vhost của chúng tôi đang trỏ vào web/.

  • Không sử dụng bộ lọc cssrewrite


3
Đây là một giải pháp hợp lệ, nhưng chỉ khi bạn sẽ không bao giờ phục vụ các tập tin từ một thư mục con, ví dụ: http://example.org/sub/.
apfelbox

1

Tôi không quản lý plugin css / js với trình soạn nhạc cài đặt nó theo nhà cung cấp. Tôi liên kết biểu tượng những cái đó với thư mục web / bó để cho phép nhà soạn nhạc cập nhật các gói khi cần thiết.

ví dụ:

1 - liên kết biểu tượng một lần (sử dụng lệnh fromweb / Bundles /

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

2 - sử dụng nội dung khi cần thiết, trong mẫu cành cây:

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

Trân trọng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.