Symfony Unable to Generate a URL for Route to Stylesheet - symfony

I have two CSS files in the same folder, with identical access rights. When testing in the same Twig file, one CSS file generates a URL to the file and loads perfectly and one gives an error.
Error
An exception has been thrown during the rendering of a template
("Unable to generate a URL for the named route "_assetic_a328b4c_0" as
such route does not exist.") in #GutensiteStream/Stream35163.html.twig
at line 19.
Files on Server
ls -al /var/www/core/cms/src/Templates/GutensiteAdminBundle/Resources/public/css
-rw-rw-r-- 1 chadwick developer 17K Feb 7 14:00 dashboard.css
-rw-rw-r-- 1 chadwick developer 49K Feb 6 16:00 site.css
Template with CSS that Loads
{% stylesheets '#TemplatesGutensiteAdminBundle/Resources/public/css/site.css' %}
<link rel="stylesheet" href="{{ asset_url }}">
{% endstylesheets %}
Template with CSS that does NOT Load
{% stylesheets '#TemplatesGutensiteAdminBundle/Resources/public/css/dashboard.css' %}
<link rel="stylesheet" href="{{ asset_url }}">
{% endstylesheets %}
Linking to the File Directly Works
<link rel="stylesheet" href="/gutensite/v/2/0/bundles/templatesgutensiteadmin/css/dashboard.css">
Steps Taken
I have already cleared cache multiple times, via app/console cache:clear and via rm -rf app/cache/*. I use php app/console assets:install --symlink /var/www/core/web/gutensite/v/2/0/ to symlink the public files to the bundles, and of course they are accessible (as demonstrated via the direct link).
My Config.yml
assetic:
#don't use dynamic links to assets, use full production paths
use_controller: false

When I ran into this error, the solution was quite simple:
When in doubt:
bin/console cache:clear
Assetic is looked for a cached version which doesn't exist. This could be for any number of reasons, but cache:clear seems like it should be the first stop.

It is not recommended to use the # helper and load css directly from your bundle in production.
The best practice approach is to store the css files in the app/Resources directory and using assets:install requesting them from the web root, but seing as you don't have an AppBundle, the second best thing would be to request them from the web/bundles directory:
{% stylesheets
'bundles/templategutenstideadmin/css/site.css'
'bundles/templategutenstideadmin/css/dashboard.css'
%}
<link rel="stylesheet" href="{{ asset_url }}">
{% endstylesheets %}
Make sure you run assets:install beforehand.
This way, your css files will be compressed to one file and they will be loaded with the latest changes from the assets:install command.
Loading css files directly from your bundle using # is not recommended outside of local testing. I suspect your first issue is the usage of muliple stylesheets tags in assetic (stylesheets tag is not a part of Twig), but generally using # for file linking is not a good idea for assets. Use it for things like routing and config in .yml files, but not for assets! :)

One instance where this error will occur is when you try to load such an asset in a child template, that is already being loaded in one of the parent templates.
To fix it, load the asset only once in a template chain.
(Have to post this as answer, as I can't comment, yet.)

config.yml
assetic:
bundles: [you bundle name , otherbundlename] #add this

Related

symfony composer update twbs where are the files?

I've added
"twbs/bootstrap" : "3.3.5",
"components/jquery" : "2.1.4"
to my composer.json file.
I've run composer:update with no problems.
However now it's time to use assetic to create the files and composer used symlinks to install the components and twbs folders.
In the ::base.html.twig I would write something like the following...
{% block stylesheets %}
{% stylesheets filter = 'cssrewrite'
'%kernel.root_dir%/../vendor/twbs/bootstrap/dist/css/boostrap.css'
'%kernel.root_dir%/../vendor/twbs/bootstrap/dist/css/bootsrtap-theme.css'
'#AppBundle/Resources/public/css/custom.css'
%}
<link rel="stylesheet" href="{{ asset_url }}" />
{% endstylesheets %}
however the path for the rewrite is not correct because of the symlink installed by composer...
My question: Where did the files actually go?
Or is there another syntax to get at the files in twig?
I guess I need this... '%kerner.root_dir%/path/to/the/files'
every thing that you install through composer json goes to vendor folder (outside web folder)
you should check under web/bundles/ folder if you are in a linux or osx OS, if you are under windows, i don't think you'll have symlinks (so probably it's a hard copy each time you make a composer update). anyway. i think you should never use %kernel.root_dir% on twig.
in my case one of the bundles i'm using are symlinked under web/bundles to the real folder. as example guzzle :
lrwxrwxrwx 1 odin odin 88 ago 9 13:47 guzzle -> ../../vendor/eightpoints/guzzle-bundle/EightPoints/Bundle/GuzzleBundle/Resources/public/
so probably the path you should be using is:
bundles/twbs/bootstrap/css/boostrap.css
bundles/twbs/bootstrap/css/boostrap-theme.css
bundles/yourbundle/css/custom.css
and instead of using the public folder of app, at least in the documentation recomends adding css, js, and img folder inside web (if you are using them in more than one bundle)
I think you just need to do a php app/console assetic:dump in the terminal to dump the required assets into your web folder where they'll be publicly accessible to reference in your code.

Difference between assetic:dump and assets:install

In Symfony2, what is the difference between assetic:dump and assets:install? In what scenarios should each of these commands be used, and in what order (if order is relevant)?
I actually wrote about this recently in an article about OroCRM, which is based on Symfony 2. If you want some of the context/why of the different commands, you might find it interesting.
There are two different systems for including frontend files (javascript, css, images, etc.) in a Symfony application. The assets:install command came first. This command will search all the Symfony Bundles in an application for a
Resources/public
folder. If found, the assets:install command will copy or symlink files from Resources/public to web/public/bundle/[bundle-name]. This is where links created with the twig assets function will look for these files. This
<script src="{{ asset('js/script.js') }}" type="text/javascript"></script>
Becomes this
<script src="/bundles/[bundle-name]/js/script.js" type="text/javascript"></script>
That's all the assets system does. It lets you store your frontend files with the bundle.
The assetic system is different. With assetic, you link to files like this.
{% javascripts '#AcmeFooBundle/Resources/public/js/foo.js' %}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
There's similar tags for stylesheets and images. Notice that assetic allows you to link to files in any bundle. (#AcmeFooBundle). Assetic will also let you link to multiple files in a folder with a wildcard.
{% javascripts '#AcmeFooBundle/Resources/public/js/*' %}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
Another difference with assetic is in the links generated. In the dev environment they'll look something like this.
<script type="text/javascript" src="/app_dev.php/js/foo.js"></script>
<script type="text/javascript" src="/app_dev.php/js/bar.js"></script>
That is, requests for these files will run through the PHP front controller (app_dev.php) via special routes setup in the assetic bundle. This means, when you're in dev mode, you never need to dump you assets. They're included automatically. It also allows you to apply filters to the files. For example, the following applies the cssrewrite filter to the files pulled in.
{% stylesheets 'bundles/acme_foo/css/*' filter='cssrewrite' %}
<link rel="stylesheet" href="{{ asset_url }}" />
{% endstylesheets %}
If you ever wanted to programmatically alter the output of your frontend assets — assetic lets you do that by writing custom twig filters.
However, this is performance intensive. In production, instead of linking each file individually via a the PHP front controller file, the generated HTML will look like this
<script type="text/javascript" src="/js/as5s31l.js"></script>
Where does as5s31l.js come from? That's what the assetic:dump command does. It combines all the individual javascript/css files (after applying the filters) and creates a nice, static, cacheable file for production.
What You Need to Do
Unless the project specifically tells you otherwise, you should always run assets:install and assetic:dump, because you'll never know which of your third party bundles use these commands. You only need to run assetic:dump before you deploy or view the application in prod mode. Order is irrelevant.
As for which system your bundle should use — if you've read the above and you're unsure what assetic can do for you, use assets. You'll be fine.

Symfony: Assetic not using controller with bootstrap bundle?

I'm new to Symfony (2.4) and having trouble understanding how Assetic serves assets through the app instead of off the file system for development.
In particular, I'm trying to get the BrainCrafted Bootstrap Bundle setup so that I don't have to dump my assets for it to work on development.
In my base template file, I have:
<link href="{{ asset('/css/bootstrap.css') }}" rel="stylesheet" media="screen">
When I render a page using the app_dev.php, the path does not change and still tries to load it via /css/bootstrap.css, which does not exist.
My assetic setting for "use_controller" is set to true.
However, if I include a stylesheet like this:
{% stylesheets '#MyCustomBundle/Resources/public/css/*' %}
<link rel="stylesheet" href="{{ asset_url }}" />
{% endstylesheets %}
Then the URL to the stylesheet is properly rooted with "app_dev.php".
Why doesn't the main asset twig function prepend app_dev.php?
BootstrapBundle configures Assetic using config.yml. You need to dump the assets using php app/console assetic:dump to generate the CSS files.
If you want to configure your stylesheets inside your Twig template you should use stylesheets (as mentioned by Dovydas Bartkevičius) and if you want to configure your stylesheets in your config.yml you have to generate the static CSS using php app/console assetic:dump and use assets to include the static files in your template.
BootstrapBundle configures Assetic using config.yml so you have to dump the assets. While developing you can also use php app/console assetic:dump --watch to generate the CSS every time the source changes.
{{ asset }} function just adds a path to the assets folder of the project. It seems that your assets are in the bundle's directory therefore they are not public and cannot be reached.
http://symfony.com/doc/current/book/templating.html#linking-to-assets
{% stylesheets %} and {% javascripts %} actually takes asset files from your bundles, applies filters if present (compression, etc) and serves them at request through the controller.
You can dump asset files with command line API php app/console assetic:dump.
http://symfony.com/doc/current/cookbook/assetic/asset_management.html#dumping-asset-files
If you pass an absolute path to the asset function then it will return the argument without changing it at all.

get css in the folders using assetic

I would like to know if it is possible with symfony 2 and Assetics to say that I want to load all of the css files in a specific folder even though this one has some other folders inside.
For example I have :
css/aaa.css
css/bbb.css
css/jquery/ccc.css
css/jquery/ddd.css
in assetics I would do that to load :
{% stylesheets 'bundles/my-bundle/css/*' %}
<link rel="stylesheet" href="{{ asset_url }}" media="screen" />
{% endstylesheets %}
this will only load aaa.css and bbb.css
Is there a way to say : 'take everything' in one single line (sure i could add each folder in the stylesheets tag but I want to know if I can avoid doing that)
Thank you
You can't do this thing directly with assetic as is yet but it's possible thanks to everzet and his AsseticPipeline class suite and will probably be brought in next Assetic major version.
So what to do now ?
test previous KnpRadBundle version by cloning it here
get more information about how to implement it in your project : read this discussion
Good luck.
In the app_dev environment, the files are processed for each request, and run through all the filters before they are provided by the Assetic controller. This is useful, because we will see every change directly:
In a production environment, this process is just too slow. In this case, Assetic is able to generate real files, which are static and can be delivered statically:
To generate the final assets, invoke the following script in your console:
$ php app/console assetic:dump --env=prod --no-debug
All the css will combine in the production environment.The above command will generate a css folder and a combined file into that folder.

Creating a ready-to-use symfony 2 application zip

I have created a symfomy application bundle that can be used to collect crash reports from Android applications (for those interested in Android and ACRA: https://github.com/marvinlabs/acra-server).
People who are ok with that can simply install that application as a regular Symfony 2 bundle, by getting it from GitHub and doing all the command line stuff that is needed BUT I want people to be able to install that application very simply and without:
any knowledge of symfony
requiring access to php composer
requiring to type any php command line
To do that, I have packaged a zip file containing the whole Symfony code + my bundle. Problem: it seems that the CSS and Javascripts are not properly found, I still need to run a command on the server:
php app/console assetic:dump --env=prod --no-debug
Question 1: How could I get rid of that last step?
Question 2: Overall, what would you add to my process before making the zip file?
Before making that zip file, here is what I do:
Remove all git folders
Remove my app/config/parameters.yml file (specific to my dev environment)
I also execute the following commands:
php app/console cache:clear --env=dev
php app/console cache:clear --env=prod
php app/console doctrine:schema:create --env=dev --dump-sql > create-schema.sql
php app/console doctrine:schema:update --env=dev --dump-sql > update-schema.sql
php app/console assets:install --env=prod --no-debug
php app/console assetic:dump --env=prod --no-debug
PS:
Demo is there: http://acra-server-demo.marvinlabs.com/dashboard
Zip file is there: http://www.vincentprat.info/tmp/acra-server-1.0.0.zip (17MB)
Instructions to install for those who want to try troubleshooting it:
Download http://www.vincentprat.info/tmp/acra-server-1.0.0.zip
Upload the zip content on your server
Give permissions 777 to directories app/logs and app/cache
Create file app/config/parameters.yml from sample file app/config/parameters.yml.dist
Create DB tables with help from the file create-schema.sql
Make your (sub-)domain point to the directory acra-server/web
Access the home page: http://www.example.com/dashboard
Edit 12/06/2013
Listing of files and permissions right after unzip
~/acra-server/web$ ls -l css
total 10
-rw-r--r--+ 1 vincentp users 8990 May 23 18:26 d82d504.css
~/acra-server/web$ ls -l js
total 103
-rw-r--r--+ 1 vincentp users 104721 May 23 18:26 7cb568e.js
Listing of files and permissions after the assetic dump command
:~/acra-server$ ls -l web/js
total 281
-rw-r--r--+ 1 vincentp users 205123 May 28 21:48 7cb568e.js
-rw-r--r--+ 1 vincentp users 21767 May 28 21:48 b96fe74.js
We can see that another JS file has been generated (same goes with CSS). I guess Assetic is not looking for the right files out of the unzip. Any idea on how to correct that? Maybe force assetic to use a given filename?
Dumping to a given filename
( assetic's output option )
You are able to configure your asset collection's to dump to a given filename. This can be achieved inside twig with the output option. No more auto-generated filenames like 7cb568e.js.
example:
{% stylesheets
'bundles/mlabsacraserver/stylesheets/*'
filter='cssrewrite'
output='css/stylesheets.css'
%}
<link href="{{ asset_url }}" type="text/css" rel="stylesheet" />
{% endstylesheets %}
... or javascripts ...
{% javascripts
'bundles/mlabsacraserver/js/jquery.min.js'
'bundles/mlabsacraserver/js/*'
output='js/javascripts.js'
%}
<script src="{{ asset_url }}" type="text/javascript"></script>
{% endjavascripts %}
Now assetic will dump your assets to js/javascripts.js and css/stylesheets.css using the given filters.
The base path where assetic will dump these assets can be configured in your config.yml with assetic.write_to and defaults.to the web/ folder.
pre-configured asset-collections
you can do even better and keep your code more structured.
You can define asset collections inside your config.yml ( or another imported config file ).
The configuration can be found under assetic.assets
example:
# app/config.yml
assetic:
# ...
assets:
js_main:
inputs:
- "bundles/mlabsacraserver/js/jquery.min.js"
- "bundles/mlabsacraserver/js/*"
output: js/javascripts.js
css_main:
inputs:
- "bundles/mlabsacraserver/stylesheets/*"
filters:
- cssrewrite # ...add more if you like
output: css/stylesheets.css
Now you can use these collections inside your twig templates using assetic's asset() function and the #-syntax with the corresponding collection names.
example:
<link href="{{ asset('#css_main') }}" type="text/css" rel="stylesheet" />
... and ...
<script src="{{ asset('#js_main') }}" type="text/javascript"></script>
This way you can configure where assetic shall look for your assets , change the names with a single configuration parameter and keep this logic outside of your templates, making them more readable and easier to maintain.
example resulting output:
<link href="/web/css/stylesheets.css" type="text/css" rel="stylesheet" />
<script src="/web/js/javascripts.js" type="text/javascript"></script>
You now have a single configuration point in your application where you add and remove assets using collections and then just use their reference name in your templates.
further improvements for the deployment
You can have your users enter their MySQL host, user and password and let symfony write the parameters file for you.
This is what the symfony standard-edition does using SensioDistributionBundle when you first access your application .
The class performing the actual writing of the parameters.yml is Sensio\DistributionBundle\Configurator\Configurator.
use Sensio\DistributionBundle\Configurator\Configurator;
Now use the configurator in your Installation Controller.
$configurator = new Configurator($this->get('kernel')->getRootDir());
$configurator->mergeParameters(array(
'my_parameter' = 'my_value',
'my_parameter2' = 'my_value2',
));
$configurator->write();
}
The best thing will be looking at the Configurator class itself to understand how it works.
can i haz bounty now? ;-)
If it not critical to you, its possible do not use assetic at all and not combine all assetic files into one. You lose all features like minify, combining and others. Instead you no longer need to run php app/console assetic:dump --env=prod --no-debug.
To do that - run php app/console assets:install web. It copy all your assets to web/bundles folder. Then in base.html.twig template you can include your assets manually.
{% block stylesheets %}
<link href="{{ asset('bundles/mlabsacraserverbundle/stylesheets/style.css') }}" rel="stylesheet" media="screen">
...
{% endblock %}
{% block javascripts %}
<script src="{{ asset('bundles/mlabsacraserverbundle/js/jquery.min.js')}}"></script>
...
{% endblock %}
This is simlpest way to solve your problem.
Other way is to call command from php code like described in documentation here and live example here. You can make an install page, where run this command and install assets.
What is the html saying? are your asset paths generated correctly ?
And I see a:
"php app/console assets:install --env=prod --no-debug"
so actually the css should be there.
Maybe you try the command with your web dir.
wich copies over the css from your Resources/Public folder to your web/bundlename/...
"php app/console assets:install web"
or is it just the same ?
sorry but (again I'll talk about having to execute command lines) how having to type 7 commands (downaload/wget, unzip, chmod, cp, sql, config) is simpler than making
composer create-project marvinlabs/acra-server --prefer-dist acra-server
If you add some post install scripts, you could even auto configure web server / ...
For example, the step of parametere.yml is already handled by a composer script in symfony-standard (https://github.com/Incenteev/ParameterHandler).
I would strongly suggest to not use a zip file, but if you want so, here are links to fix your problem of assetic:
use a static/fixed output name
distribute prod assets
By default, assetic always generate unique file names, so every dump is another file name.

Resources