I have a main layout file and extending it with another template. I have my markup and content in the {% block content %}{% endblock %} however, I'd like to add content to another "block" on the individual entry page for meta data - that would require adding another {% block content %} to my template as it would need to be output in a different area of the layout template.

Essentially, is there a way to add a second block (perhaps name it differently) or is my best bet to set all that meta data as a variable and pass it that way?

2 Answers 2


Option A: Set individual properties in the child template

If you want to set specific meta properties instead of defining a block, you can include lines like this in _layout.html:

{% if metaDescription is defined %}<meta property="description" content="{{ metaDescription }}">{% endif %}
{% if metaKeywords is defined %}<meta property="keywords" content="{{ metaKeywords }}">{% endif %}

Then, you can simply set either value from within the child template...

{% set metaDescription = entry.summaryFieldOrWhatever %}
{% set metaKeywords = entry.tagField %}

Option B: Pack an array with properties in the child template

...or as you pointed out, that could get cumbersome if you have a whole bunch of meta data. In that case, you could take a similar approach with an object instead of a block. So in _layout.html:

{% if metaProperties is defined %}
     {% for prop in metaProperties %}
     <meta property="{{ prop.name }}" content="{{ prop.value }}">
     {% endfor %}
{% endif %}

In the child template, then, you could...

{% set metaProperties = [
    { name: "description", value: entry.summaryFieldorWhatever },
    { name: "keywords", value: entry.tagField }
] %}

This way, you could set as many items as you'd like and still avoid passing markup to the parent template.

[EDIT] Typo fix

  • This is great for simple strings, but when it's 10 lines of open graph code, I thought a block was better suited.
    – Ryan Shrum
    Commented Jul 9, 2014 at 16:25
  • @RyanShrum It very well may be, but you can also pass objects too! I'll update my answer since it'd make an awful comment.
    – Matt Stein
    Commented Jul 9, 2014 at 16:28
  • Would love if someone could weigh in here on best practice with specific regard to performance. I love the idea of passing an object. Are there any performance hits using the block method?
    – Ryan Shrum
    Commented Jul 9, 2014 at 17:28
  • @Ryan I wouldn't be concerned about performance, with either method. Which method do you prefer in other respects? I'd say the Block method is easier to maintain (readability) as you have html and values side by side. Using an Object lets you call your variable values in the complete parent template, you don't need to inject your meta data html as one single block.
    – carlcs
    Commented Jul 9, 2014 at 19:47
  • @RyanShrum My guess is that the performance difference would be negligible, but my guess is about as authoritative as math tips from a houseplant.
    – Matt Stein
    Commented Jul 9, 2014 at 19:48

In my example ({% block content %}), the variable is "content" so you can create additional blocks by naming the block something different and outputting it in your layout template - reference Twig docs for more examples.

By adding a new block {% block meta %} I was able to output entry specific meta data.


Child template: group/template.html

{% extends "_layout" %}

{% block meta %}
<meta property="og:title" content="{{ entry.title }}">
<meta property="og:site_name" content="{{ siteName }}">
<meta property="og:type" content="article">
<meta property="og:locale" content="en_US"> 
<meta property="og:url" content="{{ entry.url }}">
<meta property="og:description" content="{{ entry.body|hacksaw(chars=300) }}">
<meta property="article:published_time" content="{{ entry.postDate|date('U') }}">   
{% endblock %}

{% block content %}
{% endblock %}

Parent template: _layout.html

<!DOCTYPE html>
    {% block meta %}{% endblock %}
    {% block content %}{% endblock %}
  • Also, check out the Twig parent() function: twig.sensiolabs.org/doc/functions/parent.html Commented Jul 9, 2014 at 16:46
  • Are you really using the embed tag? Not just a simple extends '_layout' with parent()?
    – carlcs
    Commented Jul 9, 2014 at 19:57
  • I updated my answer with both templates' code, in the simplest sense. I could be wrong, but I don't think parent() applies here as I'm not trying to append anything to the parent. I think using the object method mentioned in the other answer might be better. Iterating through that and only having one line of markup in the parent template (layout) sounds better to me.
    – Ryan Shrum
    Commented Jul 9, 2014 at 20:19
  • @RyanShrum I think Christian meant that you could have a {% block head %} inside the <head> element that includes the page title, stylesheet references, etc. and then easily append more meta properties (or any valid <head> markup) as needed. I've done this as well, I'm just a fan of the object syntax for whatever reason.
    – Matt Stein
    Commented Jul 9, 2014 at 21:25
  • @Ryan, sure you don't need to use parent() but it is an elegant way to leave shared meta or other head tags in _layout and include / override it dynamically.
    – carlcs
    Commented Jul 9, 2014 at 21:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.