Shoipfy Json data parsing error for google markup schema - json-ld

I am getting this error
"Structured data with syntax errors detected
Invalid items are not eligible for Google Search's rich results." Unparsable structured data
here is the code structured-data.liquid for How to resolve it and I also want to add FAQs schema to Shopify how to add FAQs schema to Shopify.
{%- if template contains 'index' -%}
<script type="application/ld+json">
{
"#context": "https://schema.org",
"#type": "WebSite",
"name": {{ shop.name | json }},
"url": "https://{{ shop.domain }}",
"potentialAction": {
"#type": "SearchAction",
"target": "https://{{ shop.domain }}{{ routes.search_url }}?q={query}",
"query-input": "required name=query"
}
}</script>
{% endif %}
{%- if template contains 'product' -%}
{%- if product.available == true -%}
{%- if product.selected_or_first_available_variant.inventory_policy == "continue" -%}
{%- assign availability = "PreOrder" -%}
{%- else -%}
{%- assign availability = "InStock" -%}
{%- endif -%}
{%- else -%}
{%- assign availability = "OutOfStock" -%}
{%- endif -%}
<script type="application/ld+json">
{
"#context": "https://schema.org",
"#id": {{ canonical_url | json }},
"#type": "Product",
"brand": {
"#type": "Brand",
"name": {{ product.vendor | json }}
},
"sku": {{ product.selected_or_first_available_variant.sku | json }},
"description": {{ product.description | strip_html | json }},
"url": {{ canonical_url | json }},
"name": {{ product.title | json }},
{%- if product.featured_image -%}
"image": "https:{{ product.featured_image | product_img_url: 'grande' }}",
{%- endif -%}
"offers": {
"#type": "Offer",
"priceCurrency": "{{ shop.currency }}",
"price": "{{ product.selected_or_first_available_variant.price | money_without_currency | remove: "," }}",
"availability": "http://schema.org/{{ availability }}",
"url": {{ canonical_url | json }},
"sku": {{ product.selected_or_first_available_variant.sku | json }},
"seller": {
"#type": "Organization",
"name": {{ shop.name | json }}
}
{%- if product.selected_or_first_available_variant.barcode.size == 12 -%},
,"gtin12": "{{ product.selected_or_first_available_variant.barcode }}"
{% endif %}
{%- if product.selected_or_first_available_variant.barcode.size == 13 -%},
,"gtin13": "{{ product.selected_or_first_available_variant.barcode }}"
{%- endif -%}
{%- if product.selected_or_first_available_variant.barcode.size == 14 -%},
,"gtin14": "{{ product.selected_or_first_available_variant.barcode }}"
{%- endif -%}
}
}</script>
{%- endif -%}
{%- if template contains 'article' -%}
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "Article",
"mainEntityOfPage": {{ canonical_url | json }},
"name": {{ article.title | json }},
"headline": "{{- article.title -}}",
"image": [
"{{ article | img_url: 'master' }}"
],
datePublished: "{{- article.published_at | time_tag -}}",
"dateModified": "{{- article.published_at | time_tag -}}",
"author": {
"#type": "Person",
"name": "{{- article.author -}}"
},
"publisher": {
"#type": "Organization",
"name": "{{- shop.name -}}",
"logo": {
"#type": "ImageObject",
"url": "{{- 'logo.jpg' | file_url: 'master' -}}"
}
},
"description": {{- article.excerpt_or_content | strip_html | json -}},
"articleBody": {{- article.content | strip_html | json -}}
}
</script>
{%- endif -%} }

Related

In Synfony how do I divide a list according to the statut of his creator ? Error : Key for array with keys "0" does not exist

I'd like to display two lists of events : one list with events created by organizers with organizer status and a list with events created by organizers with member status. My conditions are like this : "if some event exist" and "if the organizer who created the event is an organizer (or a regular member)". For information, "organizer" and "member" depend on the status of the organizer. Because of the second condition, I had this error :
Key "organizer" for array with keys "0" does not exist.
I don't understand why... What needs to be corrected ?
Thank you very much for your help.
My twig file :
{% extends 'base.html.twig' %}
{% block title %}Liste des activités{% endblock %}
{% block main %}
<div class="events">
<div class="vr fixed-top start-50"></div>
<div class="row">
<div class="col-12 col-md-6">
<h2 class="text-center my-4">
<img src="{{ asset('img/titres/zpeak-sorties.svg') }}" alt="Les Zpeak Sorties !">
</h2>
<ul class="list-group">
{% if events and events.organizer.status == 'organizer' %}
{% for event in events %}
<a class="list-group-item list-group-item-action">
<img src="{{ asset('img/flag_images/' ~ event.spokenlanguage.image) }}" alt="Drapeau {{ event.spokenlanguage.name }}" class="me-2"> {{ event.title }}
</a>
{% endfor %}
{% else %}
<p>Il n'y a pas de zpeak sortie organisée.</p>
{% endif %}
</ul>
</div>
<div class="col-12 col-md-6">
<h2 class="text-center my-4">
<img src="{{ asset('img/titres/zpeak-idees.svg') }}" alt="Les Zpeak Idées !">
</h2>
<ul class="list-group">
{% if events and events.organizer.status == 'member' %}
{% for event in events %}
<a class="list-group-item list-group-item-action">
<img src="{{ asset('img/flag_images/' ~ event.spokenlanguage.image) }}" alt="Drapeau {{ event.spokenlanguage.name }}" class="me-2"> {{ event.title }}
</a>
{% endfor %}
{% else %}
<p>Il n'y a pas de zpeak idée proposée.</p>
{% endif %}
</ul>
</div>
</div>
</div>
{% endblock %}
My EventsController.php file :
<?php
namespace App\Controller\Front;
use App\Form\SearchType;
use App\Repository\EventsRepository;
use App\Repository\CategoriesRepository;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class EventsController extends AbstractController
{
#[Route('/search', name: 'search')]
public function search(Request $request, SessionInterface $sessionInterface)
{
$data = $request->request->all();
$sessionSearchFormData = $sessionInterface->get('searchFormData');
$form = $this->createForm(SearchType::class, ['data' => $sessionSearchFormData]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$sessionInterface->set('searchFormData', $data);
return $this->redirectToRoute('events', [$data]);
}
return $this->renderForm('front/search.html.twig', [
'form' => $form
]);
}
#[Route('/events', name: 'events')]
public function events(
EventsRepository $eventsRepository,
CategoriesRepository $categoriesRepository
){
$events = $eventsRepository->findAll();
dd($events);
$categories = $categoriesRepository->findAll();
return $this->render("front/events.html.twig", ['events' => $events, 'categories' => $categories]);
}
}
dd($events) in EventsController.php :
EventsController.php on line 45:
array:1 [▼
0 => App\Entity\Events {#1026 ▼
-id: 1
-title: "Soirée à Belleville"
-description: "Viens boire un verre, rencontrer des natifs et pratiquer l'espagnol !"
-category: Proxies\__CG__\App\Entity\Categories {#933 ▶}
-spokenlanguage: Proxies\__CG__\App\Entity\Language {#981 ▶}
-address: Proxies\__CG__\App\Entity\Location {#744 ▶}
-date: DateTime #1665446400 {#1022 ▶}
-starttime: DateTime #72000 {#1023 ▶}
-endtime: DateTime #86340 {#1024 ▶}
-organizer: Proxies\__CG__\App\Entity\User {#996 ▼
-id: 1
-email: null
-roles: []
-password: null
-gender: null
-lastname: null
-firstname: null
-birthdate: null
-occupation: null
-photo: null
-status: null
-nationality: null
-nativelanguage: null
+__isInitialized__: false
…2
}
-participations: Doctrine\ORM\PersistentCollection {#1002 ▶}
}
]
In your case, you can have many Events, so in your twig, you need to use a for loop.
Place your for loop before the if.
Something like this :
<ul class="list-group">
{% for event in events %}
{% if event and event.organizer.status == 'organizer' %}
<a class="list-group-item list-group-item-action">
<img src="{{ asset('img/flag_images/' ~ event.spokenlanguage.image) }}" alt="Drapeau {{ event.spokenlanguage.name }}" class="me-2"> {{ event.title }}
</a>
{% else %}
<p>Il n'y a pas de zpeak sortie organisée.</p>
{% endif %}
{% endfor %}
</ul>
In case you are sure to have only one item, you can use events[0].organizer.status == 'organizer'
Regards,

CKAN - adding custom fields with ckenxt-scheming

i'm working with ckanext-scheming and trying to add a custom field similar to repeating subfields with few modifications (below are few files that define the field and it's behavior), for the most part it works correct but it doesn't get submitted to the database (although once i intercept the package create action, i can see the field data is there), any ideas are welcomed:
the scheming yaml part:
- field_name: tag_string
label: Tags
form_snippet: custom_tags.html
display_snippet: modified_repeating_subfields.html
help_text: >-
Additional keywords useful for ...
the form snippet:
{% import 'macros/form.html' as form %}
{% asset 'ckanext-dalrrdemcdcpr/facets-active-js' %}
{%
set options=[
{'value': '001', 'text': _('Discipline')}
, {'value': '002', 'text': _('Place')}
, {'value': '003', 'text': _('Stratum')}
, {'value': "004", "text":_("Temporal")}
, {'value': "005", "text":_("Theme")}
]
%}
{%- set extra_html = caller() if caller -%}
{% set classes = (classes|list) %}
{% call form.input_block(field.field_name, field.label, "", classes, extra_html=extra_html, is_required=false) %}
<div class="repeating_custom_tag_row-index-0" id="repeating_custom_tag_row-index-0" data-module="repeating_tags_handler">
<div class="metadata_tags_holder">
<div class="metadata_tags_styler">
<div class="metadata_tags_input">
<label for="custom_delete" class="input-group-text">{{ _('Input tag') }}</label>
<input class="form-control" id="repeating_custom_tag_row-index0-tag-input-index-0" type="text" name="repeating_custom_tag_row-index0-tag-input-index-0" value="" placeholder=""/>
</div>
<div class="metadata_tags_type_select">
<div><label for="tag_select" class="input-group-text">{{_('Input tag type')}}</label></div>
<select id="tag_select" name="repeating_custom_tag_row-index0-select-input-index-0" required>
{% for option in options %}
<option value="{{ option.value }}"{% if option.value == selected %} selected{% endif %}>{{ option.text or option.value }}</option>
{% endfor %}
</select>
</div>
<div class="tags_buttons_wrapper">
<div class="tags_handling_buttons">
<button class="btn btn-success add_metadata_tags_btn">Add</button>
<button class="btn btn-danger remove_metadata_tags_btn"><i class="fa fa-trash"></i>Remove</button>
</div>
</div>
</div>
</div>
</div>
{% endcall %}
the display snippet (don't think it's useful):
{% set fields = data[field.field_name] %}
{% block subfield_display %}
{% for field_data in fields %}
<div class="panel panel-default">
<div class="panel-body">
<dl class="scheming-subfield-list">
{% for subfield in field.repeating_subfields %}
<dt class="dataset-label">
{{ h.scheming_language_text(subfield.label) }}
</dt>
<dd>
{%- snippet 'scheming/snippets/display_field.html',
field=subfield,
data=field_data,
entity_type=entity_type,
object_type=object_type
-%}
</dd>
{% endfor %}
</dl>
</div>
</div>
{% endfor %}
{% endblock %}
this is how the relevant part of the form looks (the tags):
the js module controlling tags fields behavior:
ckan.module("repeating_tags_handler", function ($){
/*
control muliple interaction regarding the tags
section, handles both css and buttons behavior.
*/
return {
initialize: function(){
$.proxyAll(this,/_on/);
// set the styles before copying the section
let add_btns = $(".add_metadata_tags_btn")
add_btns.each((idx,add_btn) => {add_btn.style.marginRight="2px"})
$(document).on('click','.add_metadata_tags_btn',this._on_add_tags)
$(document).on('click','.remove_metadata_tags_btn',this._on_remove_tags)
let repeating_fields_wrapper = $(".repeating_custom_tag_row-index-0")
repeating_fields_wrapper.css({"margin-bottom":"30px"})
let tags_holder = $(".metadata_tags_holder")
tags_holder.css("width:100%")
$(".metadata_tags_styler").css({"width":"100%", "display": 'flex', 'flex-direction': 'row'})
$(".metadata_tags_input").css({"width":"40%"})
$(".metadata_tags_type_select").css({"width":"30%"})//tag_select
$("#tag_select").css({"width":"100%", "height":"34px", "margin-left":"4px"})
$(".tags_buttons_wrapper").css({"margin-left": "4px", "padding-top": "2px"})
$(".tags_handling_buttons").css({"width":"100%","padding-top":"22px", "display": "flex", "flex-direction": "row", "margin-left":"4px"})
this.section_html = tags_holder.html()
const config = { attributes: true, childList: true, subtree: true };
//const added_items_observer = new MutationObserver(this.added_items_mutation_observer);
//added_items_observer.observe(repeating_fields_wrapper.get(0), config)
},
_on_add_tags:function(e){
e.preventDefault()
//let search_parent = e.target.parentElement.parentElement.parentElement.parentElement
let search_parent = e.target.closest(".metadata_tags_styler")
let new_index = Array.from(search_parent.parentNode.children).indexOf(search_parent) +1
let new_index_text = `index-${new_index}`
this.section_html = this.section_html.replace(/index-[0-9]/g, new_index_text)
this.el.append(this.section_html)
},
_on_remove_tags:function(e){
e.preventDefault()
let removed_tag_row = e.target.closest(".metadata_tags_styler")
//let removed_tag_row = e.target.parentElement.parentElement.parentElement.parentElement
removed_tag_row.remove()
},
}
})
and finally this is a Runtime error screenshot i raised for you - dear - to see the tags data is there:
thank you!

Display START and END range of objects with Liquid in jekyll static site

I have a list of 'products'
they are structured like this:
They have a product that act as a parent: "product 1"
and then they have multiple variations of that parent "product 1-small", "product 1-medium", "product 1-large" etc.
but the number of their variations vary, one product may have 2 variations, the other may have 5.
I want to display them like this:
Product 1
small - large
product 2
small - xlarge
how should I do this in liquid on a jekyll static site?
you can view my website and the page I'm referring here:
https://kostasgogas.com/shop/art/prints/new-media-vector/abstract/
where the problem is apparent on the price, and size of each product.
this is an example of my data.yml:
- id: 'first-art'
type: variable
- id: 'first-art-small'
type: variation
position: 1
price: '10'
parent: 'first-art'
- id: 'first-art-medium'
type: variation
position: 2
price: '20'
parent: 'first-art'
- id: 'first-art-large'
type: variation
position: 3
price: '30'
parent: 'first-art'
- id: 'second-art'
type: variable
- id: 'second-art-small'
type: variation
position: 1
price: '10'
parent: 'second-art'
- id: 'second-art-medium'
type: variation
position: 2
price: '20'
parent: 'second-art'
- id: 'second-art-large'
type: variation
position: 3
price: '30'
parent: 'second-art'
- id: 'second-art-x-large'
type: variation
position: 4
price: '40'
parent: 'second-art'
The liquid is as follows (currently counting up to 3 variations because I don't know how to do it):
{%- assign printartworks = site.data.products-prints -%}
{%- for printart in printartworks -%}
{%- if printart.type == "variable" -%}
<h3>
{{ printart.id }}
</h3>
<div>
{%- for variation in site.data.products-prints -%}
{%- if variation.parent == printart.id -%}
{%- if variation.position == "1" -%}
€{{ variation.price }}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
—
{%- for variation in site.data.products-prints -%}
{%- if variation.parent == printart.id -%}
{%- if variation.position == "3" -%}
€{{ variation.price }}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</div>
{%- endif -%}
{%- endfor -%}
your problem is the variants and the parent are at the same level, you should fix that setting a variants array inside the parent, after that you can use the filters first and last.
the yaml should looks something like that
products-prints:
- id: 'first-art'
type: variable
name: 'add name and other data of the product'
variants:
- id: 'first-art-small'
name: 'small'
position: 1
price: '10'
- id: 'first-art-medium'
name: 'medium'
position: 2
price: '20'
- id: 'first-art-large'
name: 'large'
position: 3
price: '30'
- id: 'second-art'
type: variable
name: 'add name and other data of the product'
variants:
- id: 'second-art-small'
name: 'small'
position: 1
price: '10'
- id: 'second-art-medium'
name: 'medium'
position: 2
price: '20'
- id: 'second-art-large'
name: 'large'
position: 3
price: '30'
- id: 'second-art-x-large'
name: 'x-large'
position: 4
price: '40'
Now the liquid will be:
{%- assign printartworks = site.data.products-prints -%}
{%- for printart in printartworks -%}
<h3>
{{ printart.id }}
</h3>
<div>
<p>
{{ printart.variants.first.name }} - {{ printart.variants.first.price }}
</p>
<p>
{{ printart.variants.last.name }} - {{ printart.variants.last.price }}
</p>
</div>
{%- endfor -%}
now the code will read the first and the last element on your array, if the yaml is on order that should do the trick, is up to you write the file on order.
To be extra careful, you can sort the variants array before read it.
Disclaimer: THIS IS A BAD IDEA. The best solution is to refactor your data, but if you can't edit the data this will work.
Without refactoring the YAML data, your app should make more processing each time the page is visited.
{%- assign printartworks = site.data.products-prints -%}
{%- for printart in printartworks -%}
{%- if printart.type == "variable" -%}
{% assign variants = '' | split: '' %}
{%- for variation in site.data.products-prints -%}
{%- if variation.parent == printart.id -%}
{% assign variants = variants | concat: variation %}
{%- endif -%}
{%- endfor -%}
{% assign variants = variants | sort: "position" %}
<h3>
{{ printart.id }}
</h3>
<ul>
<li>
€ {{ variants.first.price }}
</li>
<li>
€ {{ variants.last.price }}
</li>
</ul>
{%- endif -%}
{%- endfor -%}

Django check array inside array and change template

i have array line this
setime = ["00:00", "00:30", "01:00", "01:30", "02:00", "02:30", "03:00", "03:30", "04:00", "04:30", "05:00", "05:30", "06:00", "06:30", "07:00", "07:30", "08:00", "08:30", "09:00", "09:30", "10:00", "10:30", "11:00", "11:30", "12:00", "12:30", "13:00", "13:30", "14:00", "14:30", "15:00", "15:30", "16:00", "16:30", "17:00", "17:30", "18:00", "18:30", "19:00", "19:30", "20:00", "20:30", "21:00", "21:30", "22:00", "22:30", "23:00", "23:30"]
and i want check
in view
myListTime= checkDateTime.objects.all().filter(Teacher_id = 1)
i tried in template
{% for i in setime %}
<ul>
{% for j in myListTime %}
{% if j.cuTime in i %}
<li class="active">{{ i }}</li>
{% else %}
<li>{{ i }}</li>
{% endif %}
{% endfor %}
</ul>
{% endfor %}
i need result like this if data matched, li have active class
enter image description here
in db
Rather than iterating over the list of times, you'd be better to use that list in your database query.
If you've got a list you can do __in to check if a list of values exists in the values for a field.
setime = ["00:00", "00:30", ..., "22:30", "23:00", "23:30"]
myListTime_with_time = checkDateTime.objects.all().filter(Teacher_id=1, cuTime__in=setime)
myListTime_without_time = checkDateTime.objects.all().filter(Teacher_id=1).exclude(cuTime__in=setime)

sort data from ansible output in jinja2

I have the following output from a ansible os_stack create task:
"outputs": [{"description": "lb", "output_key": "lb_1", "output_value": "10.1.1.11"}, {"description": "lb", "output_key": "lb_2", "output_value": "10.1.1.12"}, {"description": "web", "output_key": "web_1", "output_value": "10.1.1.13"}, {"description": "web", "output_key": "web_3", "output_value": "10.1.1.14"}, {"description": "web", "output_key": "web_2", "output_value": "10.1.1.15"}]
I need to output this data into a file.
I've tried building a jinja2 template with the following code
{%- set ip_specs = {} -%}
{% for group in outputs[0].description -%}
{%- set net_info=[] -%}
{%- set index = [ 1 ] -%}
{% for ip in outputs[0].output_value[group] -%}
{%- do net_info.append({'net_info': {'ip': ip }, 'index': index[0] }) -%}
{%- do index.append(index.pop()+1) -%}
{%- endfor %}
{% if net_info -%}
{%- do ip_specs.update({ group: net_info }) -%}
{% endif -%}
{%- endfor %}
{{ { 'vm_list': ip_specs } | to_yaml }}
I'm expecting the following format:
vm_list:
lb:
- net_info: {ip: 10.1.1.11}
index: 1
- net_info: {ip: 10.1.1.12}
index: 2
web:
- net_info: {ip: 10.1.1.13}
index: 1
- net_info: {ip: 10.1.1.14}
index: 2
- net_info: {ip: 10.1.1.15}
index: 3
but i'm getting the following error from ansible:
AnsibleUndefinedVariable: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute u'i'
There are a few logic errors in your template. Try this instead:
{%- set host_groups = {} -%}
{%- for output in outputs -%}
{%- if output["description"] not in host_groups -%}
{%- do host_groups.update({output["description"]: []}) -%}
{%- endif -%}
{%- set index = host_groups[output["description"]]|length + 1 -%}
{%- do host_groups[output["description"]].append({"net_info": {"ip": output["output_value"]}, "index": index }) -%}
{%- endfor -%}
{{ { 'vm_list': host_groups } | to_yaml }}

Resources