load css in child of a twig - css

I have a super class twig which has the following block:
{% stylesheets filter='css_url_rewrite,?yui_css'
'#MainBundle/Resources/public/css/bootstrap.css'
'#MainBundle/Resources/public/css/vendor/*.css'
'#MainBundle/Resources/public/css/_normalize.css'
'#MainBundle/Resources/public/css/main.css'
'#MainBundle/Resources/public/css/fonts.css'
'#MainBundle/Resources/public/css/include/*.css'
'#MainBundle/Resources/public/css/footer.css'
%}
I have another twig that extends from the twig above, but I wanted to add an additional css on this page, so I did:
{% block stylesheets %}
{{ parent() }}
{% stylesheets filter='css_url_rewrite,?yui_css'
'#ShopiousMainBundle/Resources/public/css/shippingconfirm/*.css'
%}
{% endstylesheets %}
{% endblock %}
however this doesn't import the css that I have inside shippingconfirm,
Any idea on how to fix this?

You need to set the link element again in your stylesheets block. So it should work with the following:
{% block stylesheets %}
{{ parent() }}
{% stylesheets filter='css_url_rewrite,?yui_css'
'#ShopiousMainBundle/Resources/public/css/shippingconfirm/*.css' %}
<link rel="stylesheet" href="{{ asset_url }}" />
{% endstylesheets %}
{% endblock %}
But your additional stylesheets in the shippingconfirm folder will be in an extra file. Assetic won't put all stylesheets (css from parent and css from the current template) into one file.
A similar question was posted here: Combining Assetic Resources across inherited templates
There you can find some approaches to fix your problem.

Related

Reuseable blocks inside of custom form themes in symfony

I want to call a custom block inside an overwritten theme-block:
{% block file_widget %}
{% if image is not null %}
{{ block('imagePreview') }}
{% endif %}
{{ block('form_widget') }}
{% endblock %}
{% block imagePreview %}
<img src="{{ image.getFullPath | imagine_filter('medium_square') }}"
alt="{{ image.filename }}"/>
{% endblock %}
The imagePreview is not shown.
But it is working when I don't use a block.
And it is also working when I dont use a FormTypeExtension and create an ImageType instead.
So I guess the file_widgetblock still has the scope of the parent form_div_layout.html.twig and there in fact no imagePreview block exists.
So how can I solve this.
I mean now I solved it by removing the block.
But I just want to know if someone has a solution to this.
Maybe there is a way for using reuseable blocks inside of custom form themes in symfony?
Finally I found the solution:
I just did not 'use' the base template explicit.
The form theme worked without this - because symfony falls back the the base form theme when it does not find a block inside the new theme file.
But it seems then you also can not use custom blocks inside this new theme file.
So this works now:
{% use 'form_div_layout.html.twig' %}
{% block file_widget %}
{% if image is not null %}
{{ block('imagePreview') }}
{% endif %}
{{ block('form_widget') }}
{% endblock %}
{% block imagePreview %}
<img src="{{ image.getFullPath | imagine_filter('medium_square') }}"
alt="{{ image.filename }}"/>
{% endblock %}

Can't override extended twig template block to empty

I'm using MopaBootstrapBundle in Symfony 2.1.3 with Twig templates.
This bundle has base.html.twig template which contains scripts block:
{% block foot_script %}
{# To only use a subset or add more js overwrite and copy paste this block
To speed up page loads save a copy of jQuery in your project and override this block to include the correct path
Otherwise the regeneration is done on every load in dev more with use_controller: true
#}
{% javascripts
'http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'
'#MopaBootstrapBundle/Resources/bootstrap/js/bootstrap-transition.js'
'#MopaBootstrapBundle/Resources/bootstrap/js/bootstrap-modal.js'
'#MopaBootstrapBundle/Resources/bootstrap/js/bootstrap-dropdown.js'
'#MopaBootstrapBundle/Resources/bootstrap/js/bootstrap-scrollspy.js'
'#MopaBootstrapBundle/Resources/bootstrap/js/bootstrap-tab.js'
'#MopaBootstrapBundle/Resources/bootstrap/js/bootstrap-tooltip.js'
'#MopaBootstrapBundle/Resources/bootstrap/js/bootstrap-popover.js'
'#MopaBootstrapBundle/Resources/bootstrap/js/bootstrap-alert.js'
'#MopaBootstrapBundle/Resources/bootstrap/js/bootstrap-button.js'
'#MopaBootstrapBundle/Resources/bootstrap/js/bootstrap-collapse.js'
'#MopaBootstrapBundle/Resources/bootstrap/js/bootstrap-carousel.js'
'#MopaBootstrapBundle/Resources/bootstrap/js/bootstrap-typeahead.js'
'#MopaBootstrapBundle/Resources/public/js/mopabootstrap-collection.js'
'#MopaBootstrapBundle/Resources/public/js/mopabootstrap-subnav.js'
%}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock foot_script %}
I'm extending it in my template using:
{% extends 'MopaBootstrapBundle::base.html.twig' %}
{% block foot_script %}{% endblock foot_script %}
But it still tries to load Bundle's base.html.twig template and I get:
An exception has been thrown during the compilation of a template
("Unable to find file
"#MopaBootstrapBundle/Resources/bootstrap/js/bootstrap-transition.js".")
in "MopaBootstrapBundle::base.html.twig".
What I've found out is, that if you extend it like this:
{% extends 'MopaBootstrapBundle::base.html.twig' %}
{% block foot_script %}
{% javascripts
'#MopaBootstrapBundle/Resources/bootstrap/js/bootstrap-typeahead.js'
'#MopaBootstrapBundle/Resources/public/js/mopabootstrap-collection.js'
'#MopaBootstrapBundle/Resources/public/js/mopabootstrap-subnav.js'
%}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock foot_script %}
Note the typeahead.js
I get:
An exception has been thrown during the compilation of a template
("Unable to find file
"#MopaBootstrapBundle/Resources/bootstrap/js/bootstrap-typeahead.js".")
in "MopaBootstrapBundle::base.html.twig".
If I remove just one line:
{% extends 'MopaBootstrapBundle::base.html.twig' %}
{% block foot_script %}
{% javascripts
'#MopaBootstrapBundle/Resources/public/js/mopabootstrap-collection.js'
'#MopaBootstrapBundle/Resources/public/js/mopabootstrap-subnav.js'
%}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock foot_script %}
I get:
An exception has been thrown during the compilation of a template
("Unable to find file
"#MopaBootstrapBundle/Resources/bootstrap/js/bootstrap-transition.js".")
in "MopaBootstrapBundle::base.html.twig".
It still tries to load all the scripst from base template.
Any suggestions how to override *foot_script* block to make it empty and not to load these JS files?
What you want is to embed the MopaBootstrapBundle::base.html.twig instead of extending it. You should use Twig's embed tag:
{% embed 'MopaBootstrapBundle::base.html.twig' %}
{% block foot_script %}{% endblock foot_script %}
{% endembed %}
From Twig's documentation:
The embed tag combines the behaviour of include and extends. It allows you to include another template's contents, just like include does. But it also allows you to override any block defined inside the included template, like when extending a template.

Adding JS and CSS cleanly from included Twig templates

I'm looking to find out if there's a clean way to add JS and CSS from included templates.
So, for example, if layout.html.twig has:
{% include 'GenericBundle:Generic:page.html.twig' with {'data': data} %}
...
{% block javascript %}
{% javascripts
'#GenericBundle/Resources/public/js/app/jquery/jquery.min.js'
'#GenericBundle/Resources/public/js/lib/bootstrap/bootstrap.min.js'
%}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock %}
And in the generic bundle page I'd like to include some more Javascript but add it to the established Javascript block to keep to HTML and JS best practices.
Is there a clean way to do this? I'm using Symfony2, and could probably cludge together a solution using Singletons and such, but I'd rather a cleaner method if there's one available.
I know I'm a little late to the party, but with Twig 1.2, you can utilize the use tag and the block function:
GenericBundle:Generic:page.html.twig
{% block javascripts %}
<script src="..."></script>
{% endblock %}
{% block included_content %}
Bar
{% endblock %}
layout.html.twig
{% use 'GenericBundle:Generic:page.html.twig' with javascripts as page_javascripts %}
{% block javascript %}
{% javascripts
'#GenericBundle/Resources/public/js/app/jquery/jquery.min.js'
'#GenericBundle/Resources/public/js/lib/bootstrap/bootstrap.min.js'
%}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
{{ block('page_javascript') }} // Don't forget the 'braces'
{% endblock %}
...
{{ block('included_content') }} // Don't forget the 'braces'

Twig Assetic Stylesheets Among Several Templates

I'm trying to add stylesheets to an array so that as twig templates extend through a second and third levels the aggregated styles will carry through.
This topic is related to Combining Assetic Resources across inherited templates
From config.yml, I made a global array mystyles so that we can add to the list of necessary styles as we "bubble up" through the rendering process.
twig:
debug: %kernel.debug%
strict_variables: %kernel.debug%
globals:
mystyles: []
The first template called from my action is from CommunicatorBundle/Resources/views/Admin/Workspace.html.twig and I've set the specific style for this page called admin.workspace.css.
{% extends "DJCommunicatorBundle::base.html.twig" %}
{% set mystyles = ["#DJCommunicatorBundle/Resources/public/css/admin.workspace.css"]|merge(mystyles) %}
It extends CommunicatorBundle/Resources/views/base.html.twig which has it's own requirement data-table.css.
{% extends "DJSharedBundle::base.html.twig" %}
{% set mystyles = ["#DJCommunicatorBundle/Resources/public/css/data-table.css" ]|merge(mystyles) %}
Finally, we load the outermost template, SharedBundle/Resources/views/base.html.twig, which has it's own styles to add before all others.
<head>
{% set mystyles = ['#DJSharedBundle/Resources/public/css/global.css', '#DJSharedBundle/Resources/public/css/grid.990.9-col.css']|merge(mystyles) %}
{% stylesheets {{ mystyles }} %}
<link rel="stylesheet" href="{{ asset_url }}" type="text/css" />
{% endstylesheets %}
</head>
However, it breaks at this line
{% stylesheets {{ mystyles }} %}
inspite of this type of test that prints the array that I expect in the proper order
{{ mystyles|join(', ') }}
It seems that the {% stylesheets %} tag wants something like the following snippit to work (which is understandably not an array object, but a whitespace separated list of delimited strings).
{% stylesheets
'#DJSharedBundle/Resources/public/css/global.css'
'#DJSharedBundle/Resources/public/css/grid.990.9-col.css'
'#DJCommunicatorBundle/Resources/public/css/data-table.css'
'#DJCommunicatorBundle/Resources/public/css/admin.workspace.css'
%}
<link rel="stylesheet" href="{{ asset_url }}" type="text/css" />
{% endstylesheets %}
Even then, I tried setting a string to such a long value and printing it, but this doesn't work either:
{%
set str = "#DJSharedBundle/Resources/public/css/global.css
#DJSharedBundle/Resources/public/css/grid.990.9-col.css
#DJCommunicatorBundle/Resources/public/css/data-table.css
#DJCommunicatorBundle/Resources/public/css/admin.workspace.css"
%}
{% stylesheets {{ str }} %}
I feel like the global should be a viable solution, though not currently working. Hopefully I'm close. What might fix this?
This is not possible right now because Assetic statically analyzes your templates to find any assets you've defined there. Supporting these dynamic cases is on the roadmap.

Symfony2 Assetic + Twig Template JavaScript Inheritance

My problem:
I have 3 templates:
main.html.twig (main layout file)
layout.html.twig (a bundle specific layout override which contains some bundle specific JS tags)
create.html.twig (a page specific template file which also contains some page specific JS tags)
I am defining a block called 'javascript' in my base layout (main.html.twig), then overriding it (but calling {{ parent() }} in layout.html.twig. This works fine, and the JS tags from the main template file are still included above those in the layout.html.twig template.
I then do the same in the create.html.twig file, overriding the block as follows:
{% block javascripts %}
{{ parent() }}
{% javascripts '#BundleName/Resources/public/js/application.album.uploader.js'
'#BundleName/Resources/public/js/jquery.uploadify.js'
'#BundleName/Resources/public/js/swfuploadify.js' filter='?yui_js' %}
<script src='{{ asset_url }}' type='text/javascript'></script>
{% endjavascripts %}
{% endblock %}
At this point, instead of just overriding the javascript block in the parent (layout.html.twig) and including all the scripts defined in the templates above it, it does the following:
Dumps the <script> tags in the middle of the output (which causes an error, because in my main.html.twig file I am only including the jQuery library at the end of the HTML markup
Then it also dumps the scripts out along with the rest of the others (as I would expect it to)
I am not sure what is causing the scripts to be dumped in the middle of the create.html.twig template, and I'm also confused as to why they're being dumped to the screen twice (once in the middle of the create and then once at the bottom along with all the rest of my scripts from main.html.twig and layout.html.twig.
Has anyone got any ideas? Let me know if anything is unclear or if I can provide some more information.
EDIT:
File contents are below...
main.html.twig: https://gist.github.com/7f29353eaca0947528ce
layout.html.twig: https://gist.github.com/734947e9118b7765715e
create.html.twig: https://gist.github.com/c60c8d5c61e00ff86912
EDIT 2:
I've been having another look at the issue this morning and it looks as though its doing the same thing for stylesheets. I tried to define a new block called pagescripts in my layout.html.twig and then use the block in my create.html.twig but this had the same outcome, it just seems to dump the scripts and stylesheets wherever I use the
{% block pagescripts %}
(scripts here)
{% endblock}
I found the issue. In create.html.twig I was defining my {% block javascripts %} content inside inside my {% block content %}, so I assume Twig was rendering the output of the javascripts block inside the content block.
Moving the {% block javascripts %} content outside of the {% block content %} block fixed the issue.
Here is an example of main.html.twig:
<body>
{% block stylesheets %}
{% endblock %}
{% block jsscript %}
{% endblock %}
{% block content %}
{% endblock %}
</body>
into your create.html.twig
{% extends '::base.html.twig' %}
{% block jsscript %}
my javascript files...
{% endblock %}
{% block content %}
<h1>Create</h1>
<form action="{{ path('entity_create') }}" method="post" {{ form_enctype(form) }}>
{{ form_widget(form) }}
<p>
<button type="submit">Create</button>
</p>
</form>
{% endblock %}
If you still have issue, you can add a document ready function :
$(document).ready(function() {
// put all your jQuery goodness in here.
});

Resources