Assetic and template inheritance - symfony

Is this possible to use assetic with inheritance ? With the code below I get this error :
An exception has been thrown during the rendering of a template ("Unable to generate a URL for the named route "_assetic_41351d9" as such route does not exist.
My app layout :
{# app/Resources/views/layout.html.twig
{% block javascripts %}
{% javascripts
'assets/js/jquery-2.2.0.min.js'
'assets/js/main.js'
output='assets/compiled/app.js'
%}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock %}
My child layout :
{% extends "::layout.html.twig" %}
...
{% block javascripts %}
{{ parent() }}
{% javascripts
'assets/js/jquery.owl.min.js'
output='assets/compiled/page.js'
%}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock %}

Yes you can use inheritance with Twig, and there is nothing inherently wrong with what you are trying to do in your code. I would try completely clearing your cache and loading the page again, and make sure all of the assets you are trying to load properly exist.

I believe it's not working the way we wanted it, but I discovered named assets
You name all your parent template assets in the config file
assetic:
assets:
jquery_and_ui:
inputs:
- '#AppBundle/Resources/public/js/thirdparty/jquery.js'
- '#AppBundle/Resources/public/js/thirdparty/jquery.ui.js'
And then you include the jquery_and_ui name in all children, along with any other assets:
{% javascripts
'#jquery_and_ui'
'#AppBundle/Resources/public/js/*' %}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
It's obviously a hassle to do but I can't find the easy way to do this and don't understand why it doesn't generate parent template assets.
EDIT
Are you by any chance using LiipThemeBundle? This could solve the problem:
# app/config/config.yml
liip_theme:
# ...
assetic_integration: true

That should work fine. Extending block javascripts is ok for assets as well.
Actually such a message
Unable to generate a URL for the named route "_assetic_41351d9" as
such route does not exist
says about outdated cache. Did you clear it? That helped me.
php app/console cache:clear --env=dev
Hope it makes sense.

In my case it appeared that error was caused by fact that the base file extension was .html.twig, while child file had only .twig - changing extensions of both files to .html.twig solved the problem...

Related

Assetics ou Gassetics?

I just run on Gassetics, seems to be the next gen of SF assets management. So far I used Assetics.
One question though : with Assetics I used to split files in order to load only needed one, using Twig parent() method :
{% block scripts %}
{{ parent() }}
{% javascripts
'#LCHAdminBundle/Resources/public/js/jquery.specific.addition.js'
%}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock scripts %}
SO I could add on a specific page, only script needed and so was "forced" (in the noble way) to think and split my twig files accordingly.
Is it possible to do so with Gassetics? I jsut saw that you can specify back-end and front-end files, nothing more.
If I nest Twig files with Gassetic tag, will it do the trick?
EDIT : thanks to Wouter J. comment, I adjust my question :
In Assetics you explicitely specify files you want to include, giving the nesting ability. As in Gassetics you just add the tag which will be replaced during CSS/JS file generation, how do you achieve the same?
You can do all of this in the gassetic config (see section yaml example with gassetic.yml in https://github.com/romanschejbal/gassetic).
Example gassetic.yml:
js:
files:
common.js:
- assets/vendor/jquery/jquery.js
- assets/vendor/angular/angular.js
page1.js:
- assets/vendor/lchadminbundle/jquery.specific.addition.js
common.html.twig:
{% block scripts %}
<!-- prod:common.js --><!-- endbuild -->
{% endblock scripts %}
page1.html.twig
{% extends 'common.html.twig' %}
{% block scripts %}
{{ parent() }}
<!-- prod:page1.js --><!-- endbuild -->
{% endblock scripts %}
This approach is better than nesting scripts in children templates, since the commonly needed files can be cached between page requests.

Symfony2 asset managment with assetic

In one of my Symfony projects I am using assetic for asset managment.
All my twig files extend a base file called base.html.twig. I This file (base) I have:
{% stylesheets output="css/compiled/main.css" filter='cssrewrite'
'../vendor/bootstrap/css/bootstrap.css'
'css/general.css'
'css/navigation.css'
%}
<link rel="stylesheet" href="{{ asset_url }}" />
{% endstylesheets %}
{% endblock %}
In the other files that extend the base file I override the stylesheets block so that I can add other css files. This is what I do:
{% block stylesheets %}
{{ parent() }}
{% stylesheets output="css/compiled/main.css" filter='cssrewrite'
'bundles/account/css/signup.css'
%}
<link rel="stylesheet" href="{{ asset_url }}" />
{% endstylesheets %}
{% endblock %}
Now the problem is that signup.css is never added in main.css and so are all the other files that are not in the stylesheet block in the base file.
I don't know why but this started happening when I swtiched to prod environment (it was working fine in dev). I've done, as recommending on Symfony's website:
php app/console assetic:dump --env=prod --no-debug
One other thing, it seems that I can't swtich back to dev mode even when I'm using app_dev.php
Do you guys have any idea of where these errors could come from ?
Thank you in advance for you help,
kimimsc
Your have a conflict with your 'option' attribute. So in prod environnement, the second stylesheet overwrite the first.
You must use another output value for signup.css (or don't use this option)

Load one js file using assetic inside Symfony2

I am new to Symfony 2. Previously I worked a lot with Codeigniter. Now that I am exploring assetic, I am not able to understand how I can add a single file to the stack of JS files which are already being loaded.
I have a main page twig file which has something like this:
{% javascripts '#BlogBlogBundle/Resources/public/js/vendor/*' output='js/combined.js' %}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
Now this works fine if all the JS files are inside the vendor folder. But what if I have a JS file contact.js inside a folder called contact and I want that to be visible only on contact page. So, when I added such a code inside block body of contact page twig file
{% javascripts '#BlogBlogBundle/Resources/public/js/home/*' output='js/home_combined.js' %}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
the contact.js is coming before all other js files which are being loaded before the body ends.
In codeigniter, using the Carabiner library I could set up the default files which I want to load on all pages like jQuery. And if there are any specific file for a page, I can do that inside that particular controller.
Please let me know how I can do this inside Symfony also.
You can add a file to your assets like this:
{% javascripts
'#YourBundle/Resources/public/js/*'
'#AnotherBundle/Resources/public/js/some.js'
'#YourBundle/Resources/public/vendor/someother.js'
output="filename.js"
%}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
In order to have pre-defined asset collections which you can then use as for example '#js_default' you can add these in your assetic.assets configuration as suggested in my answer here.
To add the contact.js after the main file js files you can do something like this.
{% block javascripts %}
{{- parent() -}}
{% javascripts "#AcmeBundle/Resources/public/js/contact.js" %}
<script type="text/javascript" src="{{ asset_url }}" ></script>
{% endjavascripts %}
{% endblock %}

Symfony2 Production CSS/JS includes throwing 404 (may be a parent issue)

I am writing a Bundle to theme a site we are developing. The other Bundles call on a Core bundle for templating via Twig, and this Themeing bundle warps that core bundle.
I have done this by implementing the getParent() method inside the theme bundle class to return the name of the core bundle, thus causing Symfony2 to look in the theme bundle (for basically ANY file) before looking in the Core bundle.
Now, this works great in Dev mode, however, when I try in Production Mode, and my CSS/JS files are combined into one, the resulting path resolves to a 404 page, and all styling is lost.
I have cleared both dev and production cache, as well as rm -rf'd the dev and prod directories. Calling php app/console assetic:dump --env=prod --no-debug returns:
$ php app/console assetic:dump --env=prod --no-debug
Dumping all prod assets.
Debug mode is off.
10:25:40 [file+] /webapps/xxxbundle/app/../web/css/f996955.css
10:25:46 [file+] /webapps/xxxbundle/app/../web/js/f307b3f.js
10:26:05 [file+] /webapps/xxxbundle/app/../web/css/55d26a0.css
10:26:05 [file+] /webapps/xxxbundle/app/../web/js/ccfc30e.js
[RuntimeException]
The source file "/webapps/xxxclient/app/../web/bundles/xxxbundle/js/modernizer.custom.96376.js"
does not exist.
assetic:dump [--watch] [--force] [--period="..."] [write_to]
The web facing css and js dirs show:
$ ls web/css
55d26a0.css f996955.css
$ ls web/js
f307b3f.js
The missing JS file is likely due to another bundle that isn't being used. The main issue is, the template is looking for:
<link rel="stylesheet" type="text/css" media="screen" href="/css/2a6fc23.css">
<script src="/js/adf6a7a.js"></script>
Neither of which exist. Any ideas or directions?
[[ EDIT ]]
On further review, even the assetic production cache references these files, and yet they are never created... why? ....
[[ TEMPLATES ]]
(Overwritten Template)
{% extends 'FrontBundle:Frame:base.html.twig' %}
{% block title %}{{ page.title }}{% endblock %}
{% block wrapper %}
{# route: {{ route }} #}
{{ rendered | raw }}
{% endblock %}
(Overwriting Template)
{% extends 'SkinBundle::layout.html.twig' %}
{# Site Name #}
{% block site_name %}
{{ page.title }} | {{ parent() }}
{% endblock %}
Layout extends a base template which is just a shell of a site, in the process overwritting lets say CSS like:
{% extends 'FrontBundle:Frame:default.html.twig' %}
{# Stylesheets #}
{% block stylesheets %}
{# no execute {{ parent() }}#}
{% stylesheets
filter='cssrewrite'
'bundles/core/css/normalize.css'
'bundles/skin/css/main.css'
%}
<link rel="stylesheet" type="text/css" media="screen" href="{{ asset_url }}">
{% endstylesheets %}
{% endblock %}
Which is declared in the Base template as:
{# Stylesheets #}
{% block stylesheets %}
{% stylesheets
filter='cssrewrite'
'bundles/core/css/normalize.css'
'bundles/front/css/global.css'
'bundles/page/css/page.css'
%}
<link rel="stylesheet" type="text/css" media="screen" href="{{ asset_url }}">
{% endstylesheets %}
<!-- Page -->
{% endblock %}
These style-sheets are not needed, which is why I have parent() wrapped in comment tags. Removing the line entirely doesn't help.
Removing parent() did help, after a thorough clearing of the cache and rebuild.
I will be making a bug ticket here soon, as for some reason having parent() inside of a comment ({# ... #}) was breaking the generation, even though nothing inside of {# ... #} should be parsed, or indeed even considered, by the template compiler.
Tricky bug.

Twig Template Asset Resolution

I'm having problems with my child twig templates properly resolving their assets.
My assets lie in web/bundles/mlbp/images|js|css
In my parent twig template that all my other templates inherit from I have something like:
{% block javascripts %}
<script src="{{ asset('bundles/mlbp/js/jQuery.js') }}" type="text/javascript"></script>
{% endblock %}
When looking at source this resolves properly to /bundles/mlbp/js/jQuery.js
But in one of my child templates I'm doing something like this:
{% block javascripts %}
{{parent()}}
<script src="{{ asset('bundles/mlbp/js/tableSortInit.js') }}" type="text/javascript"></script>
{% endblock %}
This for some reason resolves to /js/tableSortInit.js which does not exist. I don't see why it would work in one but not the other so any help will be very appreciated
You should try checking any other templates that relate to that one, it may be coming from those especially if you do a lot of in template rendering etc.

Resources