I have a page template like so:
{# page.twig #}
{% import "_widgets.twig" as widgets %}
{% include '_header.twig' %}
<body>
{{ widgets.fancy_widget(record.items) }}
{# more content goes here #}
</body>
_header.twig
contains the <head>
tag and some blocks for css and javascript:
{# _header.twig #}
<!DOCTYPE html>
<head>
{% block javascripts %}
{% endblock %}
{% block stylesheets %}
{% endblock %}
</head>
_widgets.twig
contains a macro which generates some markup
{# _widgets.twig #}
{% macro fancy_widget(fanciful_items) %}
{# insert special css and js into <head> only if the macro is used #}
{% block stylesheets %}
<link rel="stylesheet" href="css/some_fancy_widget.css">
{% endblock %}
{% block javascripts %}
<script src="js/some_fancy_widget.js"></script>
{% endblock %}
{% for item in fanciful_items %}
{# output some fancy markup #}
{% endfor %}
{% endmacro %}
What I'd like to do is add the widget css/js to the blocks in _header.twig
if the macro is called. Ideally they'll only be added once, so multiple calls won't create extra <link>
and <script>
tags.
Is this possible? Or is there a better way to accomplish this?
I would say that you are not using Twig correctly.
In fact your page.twig must extends base.html.twig.
{# app/Resources/views/base.html.twig #}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>{% block title %}Welcome!{% endblock %}</title>
{% block stylesheets %}{% endblock %}
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" />
</head>
<body>
{% block body %}{% endblock %}
{% block javascripts %}{% endblock %}
</body>
</html>
Then your page.html.twig must extends this base.html.twig
You cannot define or overide blocks in macros. The simplest way will be:
In your page.html.twig:
{% extends 'base.html.twig' %}
{% import "_widgets.twig" as widgets %}
{% block stylesheets %}
{{ parent() }}
<link rel="stylesheet" href="css/some_fancy_widget.css">
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script src="js/some_fancy_widget.js"></script>
{% endblock %}
{% block body %}
{% endblock %}
and the rest (Your macro) : _widgets.twig :
{# _widgets.twig #}
{% macro fancy_widget(fanciful_items) %}
{% for item in fanciful_items %}
{# output some fancy markup #}
{% endfor %}
{% endmacro %}