I've got this homepage and when I execute my template, the JSON-LD script is duplicated inside my page (1 in the HEAD and 1 in the middle of the page).
I just don't understand why this script is running another time in the middle of the page...
So here is my code: The header, where I introduced the JSON-LD script and the the bodyContent block where you can find the page content.
{% block header %}
{% block head_javascript %}
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "WebSite",
"url": "",
"description": "",
"name": ""
}
</script>
{% endblock%}
{% endblock %}
{% block bodyContent %}
{# TAG | SELECTION #}
<div>
<h2> {{ 'title' }} </h2>
<p> {{ 'desc' }} </p>
</div>
<div>
<div>
<h1>{{ 'create.title' }}</h1>
<p>
{{ 'create.desc' }}
</p>
<div>
<div>
{% set texte %}{{ 'create.step.one' }}{% endset %}
{% set svg %}svg:cursor-mkp.svg.twig{% endset %}
{% set number %}1{% endset %}
{{ include(':step.html.twig') }}
</div>
<div>
{% set texte %}{{ 'create.step.two' }}{% endset %}
{% set svg %}svg:mkp.svg.twig{% endset %}
{% set number %}2{% endset %}
{{ include('idea-step.html.twig') }}
</div>
</div>
<a href="{{path('path.mkp')}}">
<button>{{ 'create.button' }}</button>
</a>
</div>
</div>
{% endblock %}
I've found this error with the Google Structured Data Testing Tool. Indeed, I've seen that there was the same structured data twice.
May this help someone :
From my controller, my header block is generating more code than I coulded see and I was not able to check this before I just move my jsonld script out of the header block.
Now it's working well and I do not have 2 times the same snippet.
{% block header %}
{% endblock %}
{% block head_javascript %}
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "WebSite",
"url": "",
"description": "",
"name": ""
}
</script>
{% endblock%}
Related
Trying to use a paginator in a view. Getting none from page = request.GET.get('page'). As is, the call to paginator limits posts on a page properly, but any call to page sequence henceforth fails. Pages will display, but there will be nothing form pagination.html displayed. For clarity, Base.html is the base template from which all others inherit. list.html is the page where I expect to see pagination.html displayed.
This code is based off of the django manual. Is there something else that needs to be setup to give the requests querydict a key of 'page' or a better way to paginate?
views.py
from django.shortcuts import render, get_object_or_404
from .models import Post
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
def post_list(request):
object_list = Post.published.all() #a list of the posts
paginator = Paginator(object_list, 4) # 4 posts in each page
page = request.GET.get('page')
try:
posts = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer deliver the first page
posts = paginator.page(1)
except EmptyPage:
# If page is out of range deliver last page of results
posts = paginator.page(paginator.num_pages)
return render(request,'blog/post/list.html',{'page': page,'posts': posts})
pagination.html
<div class="pagination">
<span class="step-links">
{% if page.has_previous %}
Previous
{% endif %}
<span class="current">
Page {{ page.number }} of {{ page.paginator.num_pages }}.
</span>
{% if page.has_next %}
Next
{% endif %}
</span>
</div>
base.html
#...
<div id="content">
{% block content %}
{% include "pagination.html" with page=posts %}
{% endblock %}
</div>
#...
list.html
{% extends "blog/base.html" %}
{% block title %}My Blog{% endblock %}
{% block content %}
<h1>My Blog</h1>
{% for post in posts %}
<h2>
<a href="{{ post.get_absolute_url }}">
{{ post.title }}
</a>
</h2>
<p class="date">
Published {{ post.publish }} by {{ post.author }}
</p>
{{ post.body|truncatewords:30|linebreaks }}
{% endfor %}
{% endblock %}
When you fill a block in a child template it replaces the super template's block's content (not literally the block named content here). If you want to keep the parent's block along with some extra content, you should use {{ block.super }}, i.e. list.html should be:
{% extends "blog/base.html" %}
{% block title %}My Blog{% endblock %}
{% block content %}
<h1>My Blog</h1>
{% for post in posts %}
<h2>
<a href="{{ post.get_absolute_url }}">
{{ post.title }}
</a>
</h2>
<p class="date">
Published {{ post.publish }} by {{ post.author }}
</p>
{{ post.body|truncatewords:30|linebreaks }}
{% endfor %}
{{ block.super }}
{% endblock %}
Apologies if this has been asked before, but I'm on my first week working with Drupal and Twig.
I have the following code:
{%
set container_classes = [
'paragraph',
'paragraph--type--' ~ paragraph.bundle|clean_class,
view_mode ? 'paragraph--view-mode--' ~ view_mode|clean_class,
not paragraph.isPublished() ? 'paragraph--unpublished',
'container'
]
%}
{% set image_classes = [
'col-12'
]
%}
{% block paragraph %}
{% block content %}
<div{{ attributes.addClass(container_classes) }}>
<div class='row'>
<div{{ attributes.addClass(image_classes) }} data-type='image'>
{{ content.field_two_column_image }}
</div>
<div class='col-12 col-lg-auto' data-type='copy'>
{{ content.field_two_column_copy }}
</div>
</div?>
</div>
{% endblock %}
{% endblock paragraph %}
My issue is the nested attributes.addClass. When I look at the HTML, I'm also seeing the container_classes classes, which is not what I'm looking for.
So how can I separate the two?
You can Create Attributes in Twig.
Something like this should work.
{# attributes for container #}
{% set container_attributes = create_attribute() %}
{%
set container_classes = [
'paragraph',
'paragraph--type--' ~ paragraph.bundle|clean_class,
view_mode ? 'paragraph--view-mode--' ~ view_mode|clean_class,
not paragraph.isPublished() ? 'paragraph--unpublished',
'container'
]
%}
{% set container_attributes = container_attributes.addClass(container_classes) %}
{# attributes for image #}
{% set image_attributes = create_attribute() %}
{% set image_classes = [
'col-12'
]
%}
{% set image_attributes = image_attributes.addClass(image_classes) %}
{% block paragraph %}
{% block content %}
<div{{ container_attributes }}>
<div class='row'>
<div{{ image_attributes }} data-type='image'>
{{ content.field_two_column_image }}
</div>
<div class='col-12 col-lg-auto' data-type='copy'>
{{ content.field_two_column_copy }}
</div>
</div?>
</div>
{% endblock %}
{% endblock paragraph %}
I have the following code that I repeat multiple times in my layout:
<div id="hi">
<div class="howAreYou">
<p class="fineTYForAsking">
<!-- additional HTML logic goes here -->
</p>
</div>
</div>
How can I put in the above html into a single Twig template, and then use that template and put in my additional specific html in the <!-- additional HTML logic goes here --> section?
You could just define blocks and embed the template where ever you want
partial.twig.html
<div id="{{ id | default('hi') }}">
<div class="howAreYou">
<p class="fineTYForAsking">
{% block content %}
{% endblock %}
</p>
</div>
</div>
template.twig.html
{% embed "partial.html.twig" with { 'id' : 'foo' } %}
{% block content %}
Lorem Ipsum
{% endblock %}
{% endembed %}
You could also use an embed in a for-loop. Variables known inside the loop, are also know in the embedded file, e.g.
item.html.twig
<div{% if item.id|default %} id="{{ item.id }}"{% endif %}>
<div class="howAreYou">
<p class="fineTYForAsking">
{% block title %}
{% if item.title is defined %}
<h1>{{ item.title }}</h1>
{% endif %}
{% endblock %}
{% block content %}
{% if item.content is defined %}
<p>{{ item.content }}</p>
{% endif %}
{% endblock %}
</p>
</div>
</div>
template.html.twig
{% for item in items %}
{% embed "item.twig" %}
{% endembed %}
{% endfor %}
demo
I'm pretty new to patternlab and am just migrating my php based project onto the node version.
I am having issues to access global data and block in a block file, which I didn't have previously.
I am using Pattern Lab Node v3.0 on Mac, with Node v13.9.0, using a Gulp Edition with Twig.
source/_data/data.json
"img": {
"landscape": {
"w_1024": {
"src": "../../images/1536x864_16x9.jpg",
"alt": "16x9 Image"
}
}
}
source/macros/ui.twig
{% macro icon( name ) %}
{% if name == "airplay" %}<img src="airplay.png"/>{% endif %}
{% endmacro %}
source/02-organisms/00-global/file-1.twig
{% import "#macros/blocks.twig" as blocks %}
{% import "#macros/ui.twig" as ui %}
<p class="icon">{{ ui.icon( "airplay" ) }}</p>
<p class="output">{{img.landscape.w_1024.src}}</p>
{{ blocks.media(item) }}
source/macros/blocks.twig
{% import "#macros/ui.twig" as ui %}
{% macro media( params ) %}
<p class="icon2">{{ ui.icon( "airplay" ) }}</p>
<p class="output2">{{img.landscape.w_1024.src}}</p>
{% endmacro %}
Expected Behavior
Generated html should look as follow :
<p class="icon"><img src="airplay.png"/></p>
<p class="output">../../images/1536x864_16x9.jpg</p>
<p class="icon2"><img src="airplay.png"/></p>
<p class="output2">../../images/1536x864_16x9.jpg</p>
Actual Behavior
Generated html looks as follow :
<p class="icon"><img src="airplay.png"/></p>
<p class="output">../../images/1536x864_16x9.jpg</p>
<p class="icon2"></p>
<p class="output2"></p>
Any help is welcome!
Macro's have their own variable scope. If you want to access any other defined variables you'd need to pass the special variable _context.
{% macro foo(bar, context) %}
{{ bar }}
{{ context['foo'] }}
{% endmacro %}
{% import _self as macros %}
{{ macros.foo(42, _context) }}
demo - demo with include
I have a symfony3/twig skeleton template
page1/skeleton.twig
{# set default values #}
{% block content %}
{% set test = {
sec1: {
title: "null",
content: 'null'
},
}
%}
{% endblock %}
<ul>
19 {% for sec in test[0:] %}
<li>
<p>{{ sec.title }}</p>
<div>
<p>{{ sec.content }}</p>
</div>
</li>
{% endfor %}
</ul>
I then create a layout template that extends the skeleton with 'real' data
page1/layout.html.twig
{% extends 'page1/skeleton.html.twig' %}
{% block content %}
{% set test = {
sec1: {
title: "title1",
content: 'content2'
},
sec2: {
title: "title2",
content: 'content2'
}
%}
{% endblock %}
But when I generate/publish the page, Symfony fires an error
Variable "test" does not exist in :page1:skeleton.html.twig at line 19
500 Internal Server Error - Twig_Error_Runtime
complaining about the skeleton itself.
That 'test' array is defined in the skeleton. Afaict from reading the docs on 'block', 'extends' & 'set', and can't figure out what exactly the problem is.
What do I need to change to eliminate this error?
blocks in twig have their own variable scope.Variables created inside a block can't be accessed outside of it.
Imo you should only test if the variable exist and otherwise create the default value :
skeleton.twig
{% if not test is defined %}
{%
set test = {
sec1: {
title: "null",
content: 'null'
},
}
%}
{% endif %}
<ul>
{% for sec in test[0:] %}
<li>
<p{{ sec.title }}</p>
<div>
<p>{{ sec.content }}</p>
</div>
</li>
{% endfor %}
</ul>
controller.php
<?php
echo $twig->render('page/page.twig', array(
'foo' => [
'title' => 'title1',
'content' => content1',
],
);
Change this in the file page1/skeleton.twig:
{% for sec in test %}
Then it will work.
I tried it. Make sure you understand why!