PRO: Update CPT with new JSON-data

This pages shows you how to update Custom Post Type-Pages by running a twig-script which is loading the JSON-data and updates Page by Page.

Create a JCI-Template with

  • URL:
  • twig-template:
    • wp_clear_taxonomy: remove all taxconomy-enties from the taxonomy defined by “taxonomyslug”
    • “{% for i in _context %}”: Loop through JSON-data
    • wp_get_cp_by_cpf_keyvalue: Check if there are existing Pages of the CPT slug (=”cptexample”), where the CPF “cpf1” matches the JSON-datafield “id”
    • If there is a Page use wp_insert_custom_field_keyvalue to insert / overwrite a CPF. And wp_insert_taxonomy to insert a taxonomy-value.
{% set slug = 'cptexample' %}
{% set taxonomyslug = 'cptaxonomyexample' %}
{% set cleartax = wp_clear_taxonomy(taxonomyslug, FALSE) %}
{% for i in _context %}
{% if %}
name: {{}}<br>
{% set cpfound = wp_get_cp_by_cpf_keyvalue(slug , 'cpf1',  %}
{% if cpfound.0 %}
{% set tz = date().format('U') %}
{% set rescpf = wp_insert_custom_field_keyvalue(cpfound.0, 'cpf2', tz ~ ' - ', FALSE) %}
{% set taxval= 'tax-'~cpfound.0 %}
{% set addtax = wp_insert_taxonomy(cpfound.0, taxonomyslug, taxval, TRUE) %}
{% endif %}
{% endif %}
{% endfor %}

In Action:

name: Love Breakfast
add taxonomy to page 10296: cptaxonomyexample / tax-10296
name: Drupal Coworking Day
add taxonomy to page 10297: cptaxonomyexample / tax-10297
name: Geeks - Februrary Edition
add taxonomy to page 10298: cptaxonomyexample / tax-10298
name: February 2019 Meetup
add taxonomy to page 10299: cptaxonomyexample / tax-10299
name: UG February Event
add taxonomy to page 10300: cptaxonomyexample / tax-10300
name: Ignite Talks & Networking
add taxonomy to page 10301: cptaxonomyexample / tax-10301
name: public Event
add taxonomy to page 10302: cptaxonomyexample / tax-10302
name: D-Meetup
add taxonomy to page 10303: cptaxonomyexample / tax-10303

twig: Generate, update or delete Custom Post Pages out of JSON

Challenge: Create Custom Post Pages out of JSON. Update the data and delete pages in case they’re not in the JSON any more.


  1. Create a Custom Post Type with slug “cptevent_2022” (e. g. with a Plugin like CPT UI).
    Add Custom Post Fields “id” and “name” (e. g. with a Plugin like Advanced Custom Fields)
  2. Create a new JCI-Template:
    Name: crescat
{% set slugCPT = "cptevent_2022" %}
{# CPF: id and name #}
{% set idArr = []  %}
{% for item in _parent  %}
    {% if %}
        {% set id= %}
        {% set idArr = idArr | merge([id]) %}
        {% set name = %}
        {% set listofcpp = wp_get_cp_by_cpf_keyvalue(slugCPT, "id", id) %}
        {% if (listofcpp | length)==0 %}
            {# create new page #}
            {% set slug = name %}
            {% set content = (item | json_encode) %}
            {% set newpageid = wp_create_new_custom_post(slugCPT, name, slug, content) %}
            {% set newcpf = wp_insert_custom_field_keyvalue(newpageid, "id", id) %}
            newpageid: {{newpageid}} (id: {{id}}, name: {{name}})<br>
        {% else %}
            {# modify existing page #}
            {% for k,v in listofcpp %}
                modify pageid {{v}}  (id: {{id}}, name: {{name}})<br>
                {% set outdate = (currenttimestamp|date("U")) %}
                {% set modf = wp_insert_custom_field_keyvalue(v, "name", outdate) %}
            {% endfor %}
        {% endif %}
    {% endif %}
{% endfor %}
{# delete pages not in the current JSON #}
{% set listofcpp = wp_get_cp_by_cpf_keyvalue(slugCPT) %}
{% for k,v in listofcpp %}
    {% set cpfvalArr = wp_get_custom_field_value(v, "id") %}
    {% set isInJSON = FALSE %}
    {% for cpfval in cpfvalArr %}
        {% if cpfval in idArr %}
            {# there is JSON-data for that page #}
            {% set isInJSON = TRUE %}
        {% endif %}
    {% endfor %}
    {% if not isInJSON %}
        delete pageid: {{v}}<br>
        {% set delcpt = wp_delete_custom_post(v, TRUE) %}
    {% endif %}
{% endfor %}

This twig-code loops through the JSON and creates (if needed) a new Custom Post Page (CPP). Or – if CPP is already there – updates the CPP.
Also it loops through the existing CPP: If there is a CPP which is not in the JSON when updating, this CPP is deleted.


[jsoncontentimporterpro nameoftemplate="crescat"]

PRO: Quote of the day

This pages demonstrates how to get JSON with a “quote of the day”, show the quote and store it in a Custom Post Page.

  1. Data-Source:
    API: and
    Local stored JSON:
  2. Create a new JCI-Template:
  • Name of template: quote-of-the day
  • URL:
  • Curloptions (otherwise you get XML):
CURLOPT_HTTPHEADER=accept:application/json##content-type: application/json


{% set  nowtime = "now"| date("U")  %}
{% set dateofquote = | date("d.m.Y") %}
{% set dateofquotetime = | date("U") %}
{% set author = %}
{% set quote= (contents.quotes.0.quote | slice(0,10)) ~ '... (we use only the first 10 chars of the quote, see more at <a href="" target="_blank"></a>)' %}
{% set id = %}
{% set cont = '<center><strong>Quote of '~dateofquote~' by '~author~':</strong><br>'~quote~'</center>' %}

{% set cont = cont ~ '<hr><a href="/pro-quote-of-the-day/">see how this page was generated out of JSON</a>' %}


{% set slug = 'cptquoteoftheday' %}
{% set taxonomyslug = 'quoteofthedayauthors' %}

is there any stored-quote of the day {{dateofquote}}?<br>
{% set cpids = wp_get_cp_by_cpf_keyvalue(slug , "date", dateofquotetime , FALSE) %}

<!--{{cpids  | dump }}-->

{% if cpids %}
yes there is already one: nothing to do

{% set  rescpf = wp_insert_custom_field_keyvalue(cpids.0, 'latestupdate', nowtime, FALSE) %}

{% else %}
create a new cpt:<br>
{% set titel = dateofquote ~': '~author ~ '- ' ~ nowtime %}
{% set pageslug=  'name-'~author %}
{% set postStatusUsed= 'publish' %}
{% set newpageid = wp_create_new_custom_post(slug, titel, pageslug, cont, dateofquote, postStatusUsed, 1, FALSE) %} 
newpageid : {{newpageid }}<br>
{% set  rescpf = wp_insert_custom_field_keyvalue(newpageid , 'date', dateofquotetime, FALSE) %}
{% set  rescpf = wp_insert_custom_field_keyvalue(newpageid , 'author', author, FALSE) %}
{% set  rescpf = wp_insert_custom_field_keyvalue(newpageid , 'quote', quote, FALSE) %}
{% set tax = wp_insert_taxonomy(newpageid, taxonomyslug, author, FALSE) %}
{% endif %}

3. Set up a Custom Post Type with custom Post Fields
You might use a Plugin like “Custom Post Type UI” for a new Custom Post Type with slug “cptexample”.
And ACF for Custom Post Fields to set CPFs with the slugs “quote”, “date” and “author”.
The slugs for the CPT and the CPFs are used in the twig-template!

4. In Action:

Quote of 30.01.2022 by Paul Brown:
When you w... (we use only the first 10 chars of the quote, see more at

see how this page was generated out of JSON
is there any stored-quote of the day 30.01.2022?
yes there is already one: nothing to do

PRO: API, Access to JSON (sending Token) and generate CPT

Get data from via it’s API


[jsoncontentimporterpro url= method=curlget method=curlget curloptions='CURLOPT_HTTPHEADER=Accept:application/json##Authorization:Token token=YOUR_API_KEY##Content-type:application/json' parser=twig332adj]
issues: {{issues|length}}
{% for i in issues %}
{{i.published_at}}: </code></code><a href="{{i.url}}" target="_blank" rel="noopener">title: {{i.title}}</a><code>
{% endfor %}
[/jsoncontentimporterpro] gives you a list of “issues”. You can generate for each issue a “WordPress-page” (aka “Custom Post Type” or “Custom Post Page”) -for that you need:

  • A JCI-template:
    There are all information on how to connect the API and what data is displayed at the generated pages.
    Name: pattern-template
    URL: method=curlget method=curlget
Accept:application/json##Authorization:Token token=YOUR_API_KEY##Content-type:application/json


summary: {{summary}}
number: {{number}}
title: {{title}}
url: {{url}}
published_at{{published_at | date("d.m.y, H:i")}}
  • A new “Custom Page Type” (CPT):
    At the JCI-Options, Tab “Custom Post Types” there is “JCI-own way: Create JCI-Custom Post Types”. With this you can create a new CPT. You’re free to do this with many other Plugiins.
    Add the following at “JCI-own way: Create JCI-Custom Post Types”, save it an reload the page. Then there should be a new menu-entry “curatedname” (change ptname if you like).
    Importaint: The “Permalink Settings” of the WordPress must be at “Post name” reloaded to register this new CPT. Check that at the general WordPress “Settings” > “Permalinks”
  • A WordPress-Page called “generating-page”: This page is in the generating-page with a special JCI-Shortcode. Every time it is called, existing pages are deleted and new pages are created.
    • “loop” is the JSON-path to the list of issues in the JSON: Other JSON, other value here!
[jsoncontentimporterpro nameoftemplate=pattern-template mode=create createoptions='{"type":"curatedtype", "loop":"issues", "title":"Issue-number: {{number}}", "slugname": "slugname{{number}}", "deleteold":"yes"}']

Preview the “generating-page”:
There should be “start looping” where the issues are used for generating pages.
The generated pages do have URLs like “…/curatedredirect/slug179/”: “curatedredirect” is the value of “ptredirect” (change as you like), “slug{{number}}” comes from the “createoptions”-JSON in the Shortcode of the generating-page. Same is with the title of the page: “Issue-number: {{number}}”

If the Clikc on a generated Page gives a “page not found”-error: The “Permalink Settings” of the WordPress must be at “Post name”. Check that at the general WordPress “Settings” > “Permalinks”