php Symfony 2 中 CSS 文件中的资源路径

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9500573/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 06:58:15  来源:igfitidea点击:

Path of assets in CSS files in Symfony 2

phpcsssymfonyassetic

提问by apfelbox

Problem

问题

I have a CSSfile with some paths in it (for images, fonts, etc.. url(..)).

我有一个CSS文件,其中包含一些路径(用于图像、字体等url(..))。

My path structure is like this:

我的路径结构是这样的:

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

I want to reference my images in the stylesheet.

我想在样式表中引用我的图像。

First Solution

第一个解决方案

I changed all paths in the CSS file to absolute paths. This is no solution, as the application should (and has to!) be working in a subdirectory, too.

我将 CSS 文件中的所有路径更改为绝对路径。这不是解决方案,因为应用程序也应该(并且必须!)在子目录中工作。

Second Solution

第二种解决方案

Use Assetic with filter="cssrewrite".

将 Assetic 与filter="cssrewrite".

So I changed all my paths in my CSS file to

所以我将 CSS 文件中的所有路径更改为

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

to represent the actual path from my resources directory to the /web/imagesdirectory. This does not work, since cssrewrite produces the following code:

表示从我的资源目录到/web/images目录的实际路径。这不起作用,因为 cssrewrite 生成以下代码:

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

which is obviously the wrong path.

这显然是错误的道路。

After assetic:dumpthis path is created, which is still wrong:

之后assetic:dump这条道路被创建,它仍然是错误的:

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

The twig code of Assetic:

Assetic的树枝代码:

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

Current (Third) Solution

当前(第三)解决方案

Since all CSS files end up in /web/css/stylexyz.css, I changed all paths in the CSS file to be relative:

由于所有 CSS 文件/web/css/stylexyz.css都以 .

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

This (bad) solution works, except in the devenvironment: The CSS path is /app_dev.php/css/stylexyz.cssand therefore the image path resulting from this is /app_dev.php/images/myimage.png, which results in a NotFoundHttpException.

这个(糟糕的)解决方案有效,除了在dev环境中:CSS 路径是/app_dev.php/css/stylexyz.css,因此由此产生的图像路径是/app_dev.php/images/myimage.png,这导致NotFoundHttpException.

Is there a better and working solution?

有没有更好的和有效的解决方案?

回答by Xavi Montero

I have came across the very-very-same problem.

我遇到了非常非常相同的问题。

In short:

简而言之:

  • Willing to have original CSS in an "internal" dir (Resources/assets/css/a.css)
  • Willing to have the images in the "public" dir (Resources/public/images/devil.png)
  • Willing that twig takes that CSS, recompiles it into web/css/a.css and make it point the image in /web/bundles/mynicebundle/images/devil.png
  • 愿意在“内部”目录中拥有原始 CSS (Resources/assets/css/a.css)
  • 愿意在“公共”目录中拥有图像(Resources/public/images/devil.png)
  • 愿意那根树枝接受那个 CSS,将它重新编译成 web/css/a.css 并使它指向 /web/bundles/mynicebundle/images/devil.png 中的图像

I have made a test with ALL possible (sane) combinations of the following:

我已经对以下所有可能的(理智的)组合进行了测试:

  • @notation, relative notation
  • Parse with cssrewrite, without it
  • CSS image background vs direct <img> tag src= to the very same image than CSS
  • CSS parsed with assetic and also without parsing with assetic direct output
  • And all this multiplied by trying a "public dir" (as Resources/public/css) with the CSS and a "private" directory (as Resources/assets/css).
  • @notation,相对符号
  • 用 cssrewrite 解析,没有它
  • CSS 图像背景与直接 <img> 标签 src= 到与 CSS 完全相同的图像
  • CSS 使用资产进行解析,也没有使用资产直接输出进行解析
  • 所有这一切都通过尝试Resources/public/css使用 CSS的“公共目录”(as )和“私有”目录(as Resources/assets/css)而倍增。

This gave me a total of 14 combinations on the same twig, and this route was launched from

这给了我在同一根树枝上总共有 14 种组合,而这条路线是从

  • "/app_dev.php/"
  • "/app.php/"
  • and "/"
  • “/app_dev.php/”
  • “/app.php/”
  • 和 ”/”

thus giving 14 x 3 = 42 tests.

因此给出 14 x 3 = 42 个测试。

Additionally, all this has been tested working in a subdirectory, so there is no way to fool by giving absolute URLs because they would simply not work.

此外,所有这些都已经在子目录中进行了测试,因此无法通过提供绝对 URL 来愚弄,因为它们根本不起作用。

The tests were two unnamed images and then divs named from 'a' to 'f' for the CSS built FROM the public folder and named 'g to 'l' for the ones built from the internal path.

测试是两个未命名的图像,然后为从公共文件夹构建的 CSS 命名为从“a”到“f”的 div,对于从内部路径构建的 CSS 命名为“g”到“l”。

I observed the following:

我观察到以下情况:

Only 3 of the 14 tests were shown adequately on the three URLs. And NONE was from the "internal" folder (Resources/assets). It was a pre-requisite to have the spare CSS PUBLIC and then build with assetic FROM there.

14 个测试中只有 3 个在三个 URL 上得到了充分显示。NONE 来自“内部”文件夹(资源/资产)。先决条件是拥有备用的 CSS PUBLIC,然后从那里使用资产进行构建。

These are the results:

这些是结果:

  1. Result launched with /app_dev.php/ Result launched with /app_dev.php/

  2. Result launched with /app.php/ Result launched with /app.php/

  3. Result launched with / enter image description here

  1. 使用 /app_dev.php/ 启动的结果 使用 /app_dev.php/ 启动的结果

  2. 结果用 /app.php/ 启动 结果用 /app.php/ 启动

  3. 结果以 / 启动 在此处输入图片说明

So... ONLY - The second image - Div B - Div C are the allowed syntaxes.

所以...只有 - 第二个图像 - Div B - Div C 是允许的语法。

Here there is the TWIG code:

这里有 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>

The container.css:

容器.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;
}

And a.css, b.css, c.css, etc: all identical, just changing the color and the CSS selector.

和 a.css、b.css、c.css 等:全部相同,只是更改颜色和 CSS 选择器。

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

The "directories" structure is:

“目录”结构是:

DirectoriesDirectories

目录目录

All this came, because I did not want the individual original files exposed to the public, specially if I wanted to play with "less" filter or "sass" or similar... I did not want my "originals" published, only the compiled one.

这一切都来了,因为我不想将个别原始文件暴露给公众,特别是如果我想玩“less”过滤器或“sass”或类似...我不想发布我的“原始文件”,只有编译了一个。

But there are good news. If you don't want to have the "spare CSS" in the public directories... install them not with --symlink, but really making a copy. Once "assetic" has built the compound CSS, and you can DELETE the original CSS from the filesystem, and leave the images:

但也有好消息。如果您不想在公共目录中使用“备用 CSS”...请不要使用 安装它们--symlink,而是真正制作一个副本。一旦“assetic”构建了复合 CSS,您就可以从文件系统中删除原始 CSS,并保留图像:

Compilation processCompilation process

编译过程编译过程

Note I do this for the --env=prodenvironment.

注意我这样做是为了--env=prod环境。

Just a few final thoughts:

只是一些最后的想法:

  • This desired behaviour can be achieved by having the images in "public" directory in Gitor Mercurialand the "css" in the "assets" directory. That is, instead of having them in "public" as shown in the directories, imagine a, b, c... residing in the "assets" instead of "public", than have your installer/deployer (probably a Bashscript) to put the CSS temporarily inside the "public" dir before assets:installis executed, then assets:install, then assetic:dump, and then automating the removal of CSS from the public directory after assetic:dumphas been executed. This would achive EXACTLY the behaviour desired in the question.

  • Another (unknown if possible) solution would be to explore if "assets:install" can only take "public" as the source or could also take "assets" as a source to publish. That would help when installed with the --symlinkoption when developing.

  • Additionally, if we are going to script the removal from the "public" dir, then, the need of storing them in a separate directory ("assets") disappears. They can live inside "public" in our version-control system as there will be dropped upon deploy to the public. This allows also for the --symlinkusage.

  • 可以通过将图像放在GitMercurial 的“public”目录中并将“css”放在“assets”目录中来实现这种期望的行为。也就是说,与其将它们放在目录中所示的“公共”中,不如想象 a、b、c... 位于“资产”而不是“公共”中,而不是让您的安装程序/部署程序(可能是Bash脚本)在assets:install执行之前将 CSS 临时放在“公共”目录中,然后assets:install,然后assetic:dump,然后在执行后自动从公共目录中删除 CSS assetic:dump。这将完全实现问题中所需的行为。

  • 另一个(如果可能的话未知)解决方案是探索“assets:install”是否只能将“public”作为来源,或者也可以将“assets”作为发布来源。--symlink在开发时安装该选项会有所帮助。

  • 此外,如果我们要从“公共”目录中删除脚本,那么将它们存储在单独的目录(“资产”)中的需要就消失了。它们可以存在于我们的版本控制系统中的“公共”中,因为在向公众部署时会被删除。这也允许--symlink使用。

BUT ANYWAY, CAUTION NOW:As now the originals are not there anymore (rm -Rf), there are only two solutions, not three. The working div "B" does not work anymore as it was an asset() call assuming there was the original asset. Only "C" (the compiled one) will work.

但无论如何,现在注意:因为现在原件不再存在 ( rm -Rf),只有两种解决方案,而不是三种。工作 div "B" 不再工作,因为它是一个资产()调用,假设有原始资产。只有“C”(编译后的)会起作用。

So... there is ONLY a FINAL WINNER: Div "C" allows EXACTLY what it was asked in the topic: To be compiled, respect the path to the images and do not expose the original source to the public.

所以......只有一个最终赢家:Div“C”完全符合主题中的要求:要编译,尊重图像的路径,不要向公众公开原始来源。

The winner is C

获胜者是C

The winner is C

获胜者是C

回答by jeremymarc

The cssrewrite filter is not compatible with the @bundle notation for now. So you have two choices:

cssrewrite 过滤器目前与 @bundle 表示法不兼容。所以你有两个选择:

  • Reference the CSS files in the web folder (after: console assets:install --symlink web)

    {% stylesheets '/bundles/myCompany/css/*." filter="cssrewrite" %}
    
  • Use the cssembed filter to embed images in the CSS like this.

    {% stylesheets '@MyCompanyMyBundle/Resources/assets/css/*.css' filter="cssembed" %}
    
  • 参考在网络文件夹中的CSS文件(后:console assets:install --symlink web

    {% stylesheets '/bundles/myCompany/css/*." filter="cssrewrite" %}
    
  • 使用 cssembed 过滤器像这样在 CSS 中嵌入图像。

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

回答by ChocoDeveloper

I'll post what worked for me, thanks to @xavi-montero.

感谢@xavi-montero,我将发布对我有用的内容。

Put your CSS in your bundle's Resource/public/cssdirectory, and your images in say Resource/public/img.

将您的 CSS 放在您的包Resource/public/css目录中,并将您的图像放在 say 中Resource/public/img

Change assetic paths to the form 'bundles/mybundle/css/*.css', in your layout.

将资产路径更改为表单'bundles/mybundle/css/*.css', 在您的布局中。

In config.yml, add rule css_rewriteto assetic:

在 中config.ymlcss_rewrite向资产添加规则:

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

Now install assets and compile with assetic:

现在安装资产并使用资产编译:

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

This is good enough for the development box, and --symlinkis useful, so you don't have to reinstall your assets (for example, you add a new image) when you enter through app_dev.php.

这对于开发框来说已经足够好了,而且--symlink很有用,因此您在通过app_dev.php.

For the production server, I just removed the '--symlink' option (in my deployment script), and added this command at the end:

对于生产服务器,我刚刚删除了“--symlink”选项(在我的部署脚本中),并在最后添加了这个命令:

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

All is done. With this, you can use paths like this in your .css files: ../img/picture.jpeg

一切都完成了。有了这个,你可以在你的 .css 文件中使用这样的路径:../img/picture.jpeg

回答by Cowlby

I had the same problem and I just tried using the following as a workaround. Seems to work so far. You can even create a dummy template that just contains references to all those static assets.

我遇到了同样的问题,我只是尝试使用以下方法作为解决方法。到目前为止似乎工作。您甚至可以创建一个仅包含对所有这些静态资产的引用的虚拟模板。

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

Notice the omission of any output which means nothing shows up on the template. When I run assetic:dump the files are copied over to the desired location and the css includes work as expected.

注意任何输出的省略,这意味着模板上没有显示任何内容。当我运行 assetic:dump 时,文件被复制到所需的位置,css 按预期包含工作。

回答by user1041440

If it can help someone, we have struggled a lot with Assetic, and we are now doing the following in development mode:

如果它可以帮助某人,我们在 Assetic 上挣扎了很多,现在我们在开发模式下做以下事情:

  • Set up like in Dumping Asset Files in the dev Environmenso in config_dev.yml, we have commented:

    #assetic:
    #    use_controller: true
    

    And in routing_dev.yml

    #_assetic:
    #    resource: .
    #    type:     assetic
    
  • Specify the URL as absolute from the web root. For example, background-image: url("/bundles/core/dynatree/skins/skin/vline.gif");Note: our vhost web root is pointing on web/.

  • No usage of cssrewrite filter

  • 在成立类似的开发环境下倾资源文件所以config_dev.yml,我们说:

    #assetic:
    #    use_controller: true
    

    而在routing_dev.yml

    #_assetic:
    #    resource: .
    #    type:     assetic
    
  • 将 URL 指定为 Web 根目录中的绝对 URL。例如,background-image:url("/bundles/core/dynatree/skins/skin/vline.gif");注意:我们的 vhost web root 指向web/.

  • 不使用 cssrewrite 过滤器

回答by Jean-Luc Barat

I offen manage css/js plugin with composer which install it under vendor. I symlink those to the web/bundles directory, that's let composer update bundles as needed.

我使用 Composer 管理 css/js 插件,并将其安装在供应商下。我将它们符号链接到 web/bundles 目录,这让 Composer 根据需要更新包。

exemple:

例子:

1 - symlink once at all (use command fromweb/bundles/

1 - 一次符号链接(使用命令 fromweb/bundles/

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

2 - use asset where needed, in twig template :

2 - 在需要的地方使用资产,在树枝模板中:

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

Regards.

问候。