Problem
I have a CSS file with some paths in it (for images, fonts, etc.. 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.
Second Solution
Use Assetic with filter="cssrewrite"
.
So I changed all my paths in my CSS file to
url("../../../../../../web/images/myimage.png")
to represent the actual path from my resources directory to the /web/images
directory. This does not work, since cssrewrite produces the following code:
url("../../Resources/assets/")
which is obviously the wrong path.
After assetic:dump
this path is created, which is still wrong:
url("../../../web/images/myimage.png")
The twig code of 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:
url("../images/myimage.png")
This (bad) solution works, except in the dev
environment:
The CSS path is /app_dev.php/css/stylexyz.css
and therefore the image path resulting from this is /app_dev.php/images/myimage.png
, which results in a NotFoundHttpException
.
Is there a better and working solution?
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.
exemple:
1 - symlink once at all (use command fromweb/bundles/
2 - use asset where needed, in twig template :
Regards.
I have came across the very-very-same problem.
In short:
I have made a test with ALL possible (sane) combinations of the following:
Resources/public/css
) with the CSS and a "private" directory (asResources/assets/css
).This gave me a total of 14 combinations on the same twig, and this route was launched from
thus giving 14 x 3 = 42 tests.
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.
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.
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.
These are the results:
Result launched with /app_dev.php/
Result launched with /app.php/
Result launched with /
So... ONLY - The second image - Div B - Div C are the allowed syntaxes.
Here there is the TWIG code:
The container.css:
And a.css, b.css, c.css, etc: all identical, just changing the color and the CSS selector.
The "directories" structure is:
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.
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:Compilation process
Note I do this for the
--env=prod
environment.Just a few final thoughts:
This desired behaviour can be achieved by having the images in "public" directory in Git or Mercurial and 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 Bash script) to put the CSS temporarily inside the "public" dir before
assets:install
is executed, thenassets:install
, thenassetic:dump
, and then automating the removal of CSS from the public directory afterassetic:dump
has 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
--symlink
option 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
--symlink
usage.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.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.
The winner is C
If it can help someone, we have struggled a lot with Assetic, and we are now doing the following in development mode:
Set up like in Dumping Asset Files in the dev Environmen so in
config_dev.yml
, we have commented:And in routing_dev.yml
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 onweb/
.No usage of cssrewrite filter
I'll post what worked for me, thanks to @xavi-montero.
Put your CSS in your bundle's
Resource/public/css
directory, and your images in sayResource/public/img
.Change assetic paths to the form
'bundles/mybundle/css/*.css'
, in your layout.In
config.yml
, add rulecss_rewrite
to assetic:Now install assets and compile with assetic:
This is good enough for the development box, and
--symlink
is useful, so you don't have to reinstall your assets (for example, you add a new image) when you enter throughapp_dev.php
.For the production server, I just removed the '--symlink' option (in my deployment script), and added this command at the end:
All is done. With this, you can use paths like this in your .css files:
../img/picture.jpeg
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.
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.
The cssrewrite filter is not compatible with the @bundle notation for now. So you have two choices:
Reference the CSS files in the web folder (after:
console assets:install --symlink web
)Use the cssembed filter to embed images in the CSS like this.