首页 文章

Symfony 2中CSS文件中的资产路径

提问于
浏览
98

问题

我有一个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")

资产的枝条代码:

{% 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 回答

  • 8

    如果它可以帮助某人,我们在Assetic方面遇到了很多困难,我们现在正在开发模式中做以下事情:

    #assetic:
    #    use_controller: true
    

    在routing_dev.yml中

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

    • 没有使用cssrewrite过滤器

  • 5

    cssrewrite过滤器现在与@bundle表示法不兼容 . 所以你有两个选择:

    • 引用Web文件夹中的CSS文件(之后: console assets:install --symlink web
    {% stylesheets '/bundles/myCompany/css/*." filter="cssrewrite" %}
    
    • 使用cssembed过滤器将图像嵌入CSS中,如下所示 .
    {% stylesheets '@MyCompanyMyBundle/Resources/assets/css/*.css' filter="cssembed" %}
    
  • 1

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

    简而言之:

    • 愿意在"internal" dir中使用原始CSS(Resources / assets / css / a.css)

    • 愿意在"public" dir(Resources / public / images / devil.png)中拥有图像

    • 愿意twig获取CSS,将其重新编译为web / css / a.css并使其指向/web/bundles/mynicebundle/images/devil.png中的图像

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

    • @notation,相对符号

    • 用cssrewrite解析,没有它

    • CSS图像背景vs直接<img>标签src =与CSS完全相同的图像

    • CSS使用资产进行解析,也无需使用资产直接输出进行解析

    • 所有这些都乘以CSS和"private"目录(如 Resources/assets/css )尝试"public dir"(如 Resources/public/css ) .

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

    • "/app_dev.php/"

    • "/app.php/"

    • 和"/"

    因此给出了14 x 3 = 42次测试 .

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

    测试是两个未命名的图像,然后div从'a'命名为'f',用于从公共文件夹构建的CSS,并命名为'g to'l'用于从内部路径构建的 .

    我观察到以下情况:

    14个测试中只有3个在三个URL上得到了充分的显示 . NONE来自“内部”文件夹(Resources / assets) . 这是获得备用CSS PUBLIC然后使用资产FROM进行构建的先决条件 .

    结果如下:

    • 使用/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>
    

    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

    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.

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

    编译过程
    Compilation process

    注意我为 --env=prod 环境执行此操作 .

    最后几点想法:

    • 通过在GitMercurial中的"public"目录和"assets"目录中的"css"中显示图像,可以实现所需的行为 . 也就是说,不要让它们在目录中显示的"public"中,假设a,b,c ......驻留在"assets"而不是"public",而不是让你的安装程序/部署者(可能是Bash脚本)暂时将CSS放入执行 assets:install 之前的"public"目录,然后 assets:install ,然后 assetic:dump ,然后在执行 assetic:dump 后自动从公共目录中删除CSS . 这将完全解决问题中所需的行为 .

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

    • 此外,如果我们要编写从"public"目录中删除的脚本,则需要将它们存储在单独的目录中("assets")消失了 . 它们可以存在于我们的版本控制系统中"public"内部,因为在部署到公众时会丢弃它们 . 这也适用于 --symlink 用法 .

    BUT ANYWAY, CAUTION NOW: 由于现在原件不再存在( rm -Rf ),因此只有两种解决方案,而不是三种解决方案 . 工作div "B"不再起作用,因为它是一个资产()调用,假设有原始资产 . 只有"C"(已编译的)才有效 .

    所以...只有一个最终获胜者:Div“C”完全允许在主题中提出的内容:要编译,尊重图像的路径,不要将原始资源暴露给公众 .

    获胜者是C.

    The winner is C

  • 193

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

    将CSS放在捆绑包的 Resource/public/css 目录中,然后将图像放在 Resource/public/img 中 .

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

    config.yml 中,将规则 css_rewrite 添加到assetic:

    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'选项(在我的部署脚本中),并在最后添加了这个命令:

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

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

  • 16

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

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

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

  • 2

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

    为例:

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

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

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

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

    问候 .

相关问题