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

Create JSON out of JSON: Use it for a liveticker with “Auto Refresh API Ajax”

Challenge: Display the data from

Local JSON stored at

Simply displaying data is easy – create a Plugin template with the above URL and this Twigcode (Shortcode: [jsoncontentimporterpro nameoftemplate=NAME_OF_TEMPLATE])

Location:  {{value.timeSeries.0.sourceInfo.siteName}}<br>
Date: {{value.timeSeries.0.values.0.value.0.dateTime | date("Y-m-d",   "America/New_York") }} <br>
Time: {{value.timeSeries.0.values.0.value.0.dateTime | date("H:i",  "America/New_York") }}<br>
Water Level: {{value.timeSeries.0.values.0.value.0.value}}

In Action:

Location: Shrewsbury River at Sea Bright NJ
Date: 2022-05-20
Time: 01:12
Water Level: 3.04

Display this data with the “Auto Refresh API Ajax” Plugin- Way 1:

  • Install the Plugin
  • Create a HTML-Div like <div id="araatest">load data</div>
  • Go to the “Auto Refresh AA” menu and insert this:
  • URL: See above
  • What: value.timeSeries.0.values.0.value.0.value
  • Where: div[id="araatest"]

Display this data with the “Auto Refresh API Ajax” Plugin- Way 2:

Create a new JSON-Feed with the JCI-PRO-Plugin by adding a new plugin-template:

  • Name: waterservices-json
  • URL:
  • twig-template:
{"time": "{{"now" | date("d.m.Y, H:i:s") }}", "data": "Location:  {{value.timeSeries.0.sourceInfo.siteName}}, Date: {{value.timeSeries.0.values.0.value.0.dateTime | date("Y-m-d",   "America/New_York") }}, Time: {{value.timeSeries.0.values.0.value.0.dateTime | date("H:i:s",  "America/New_York") }}, Water Level: {{value.timeSeries.0.values.0.value.0.value}}"}


[jsoncontentimporterpro nameoftemplate="waterservices-json"]

This page with this Shortcode should be something like this:
Adding “?show=oc” removes the template and gives pure JSON:

This JSON we can use in “Auto Refresh API Ajax”:

Example in Action:
load data

PRO: JCI-Template urlparam4twig

You can define a urlparam4twig-list like “one#two” via the shortcode “urlparam4twig ” or (preferrably) the JCI-plugin-template.

This gives you a flexible way to put a dynamic URL together for the API-call.

Create a template with the following settings. Save this template andput the shortcode on a page:

Click here and see the change in the following paragraph. You might change the values for the parameters.
In the back the twig code in the URL is executed and the values for “one” and “two” are used.

this is a template: <br>
time: {{ "now"|date("m.d.Y") }}<br>
urlparam "one": {{ | e}}<br>
urlparam "two": {{urlparam.two | e}}

URL:{{ "now"|date("mdY") }}&a={{}}&b={{urlparam.two}}

urlparam4twig: one#two

In Action:

this is a template:
time: 05.20.2022
urlparam "one":
urlparam "two":

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: Show Page-Properties

Challenge: Show and use WordPress-Page-Properties like User-ID, Page-ID etc.

Solution: Create a new JCI-Template with name “showpageproperties” and URL “dummyrequest” (or an URL with JSON) and this twig-Code:

{% set pageprop = wp_get_page_properties() %}
get_current_user_id: {{pageprop.get_current_user_id}}
get_post.ID: {{pageprop.get_post.ID}}
all data:
{{pageprop |json_encode | e}}

Then you can use this Shortcode to display the properties:

[jsoncontentimporterpro nameoftemplate="showpageproperties"]

In Action:

get_current_user_id: 0
get_post.ID: 9540
all data:
{"get_permalink":"","home_url":"","get_current_user_id":0,"userdata":false,"get_post":{"ID":9540,"post_author":"1","post_date":"2022-01-30 20:37:32","post_date_gmt":"2022-01-30 19:37:32","post_content":"<!-- wp:paragraph -->\n<p><strong>Challenge:</strong> Show and use Wordpress-Page-Properties like User-ID, Page-ID etc.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:separator -->\n<hr class=\"wp-block-separator\"/>\n<!-- /wp:separator -->\n\n<!-- wp:paragraph -->\n<p><strong>Solution:</strong> Create a new JCI-Template with name \"showpageproperties\" and URL \"dummyrequest\" (or an URL with JSON) and this twig-Code:</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:enlighter/codeblock -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">{% set pageprop = wp_get_page_properties() %}\nget_current_user_id: {{pageprop.get_current_user_id}}\nget_post.ID: {{pageprop.get_post.ID}}\nall data:\n{{pageprop |json_encode | e}}</pre>\n<!-- /wp:enlighter/codeblock -->\n\n<!-- wp:paragraph -->\n<p>Then you can use this Shortcode to display the properties:</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:enlighter/codeblock -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">[[ nameoftemplate=\"showpageproperties\"]]</pre>\n<!-- /wp:enlighter/codeblock -->\n\n<!-- wp:separator -->\n<hr class=\"wp-block-separator\"/>\n<!-- /wp:separator -->\n\n<!-- wp:paragraph -->\n<p><strong>In Action:</strong></p>\n<!-- /wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>[ nameoftemplate=\"showpageproperties\"]</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:separator -->\n<hr class=\"wp-block-separator\"/>\n<!-- /wp:separator -->\n\n<!-- wp:paragraph -->\n<p>Remark: In the field \"post_content\" the string \"\" is removed, as this could be cause trouble in executing there shortcodes again and again</p>\n<!-- /wp:paragraph -->","post_title":"PRO: Show Page-Properties","post_excerpt":"","post_status":"publish","comment_status":"closed","ping_status":"closed","post_password":"","post_name":"pro-show-page-properties","to_ping":"","pinged":"","post_modified":"2022-02-01 23:06:39","post_modified_gmt":"2022-02-01 22:06:39","post_content_filtered":"","post_parent":9627,"guid":"","menu_order":120,"post_type":"page","post_mime_type":"","comment_count":"0","filter":"raw"},"cpf":{"_edit_lock":["1643753200:1"],"_edit_last":["1"],"jci_pagehead":[""],"_jci_pagehead":["field_602bcf9303a35"],"jci_pagetitle":[""],"_jci_pagetitle":["field_602bcf9d03a36"]}}

Remark: In the field “post_content” the string “jsoncontentimporterpro” is removed, as this could be cause trouble in executing there shortcodes again and again

PRO: Upload Image from JSON-data to WP-Media with twig-function “mediastore”

This page demonstrates how you can upload a Image to the WordPress-Library out of a JSON-feed

Input JSON:<br>
{{_context |json_encode}}<hr>

{# upload the image to the upload-page itself #}
{% set pgprop = wp_get_page_properties() %}
{% set parentPageId = pgprop.get_post.ID %} 

{# Title of the mediafile in the WP-Medialib #}
{% set mediatitle = "this-is-mediatitle" %}

{# FALSE: Store it always
TRUE: If there is already a mediafile with title 'mediatitle' do not store it
{% set useExistingMediaFile = FALSE %}

{# only relevant if useExistingMediaFile=FALSE
TRUE: do not store but delete existing files with title 'mediatitle' #}
{% set deleteonly = FALSE %}

{# set post_excerpt / caption #}
{% set excerpt = "this is post_excerpt" %}

{# set post_content / description #}
{% set content = " this is content" %}

{# not used, set always to "" #}
{% set mime_type = "" %}

{# if '' the value of source of the mediafile is used from the JSON as is. 
If sourcetype="file" the plugin checks if such a file exists on the server:
If no such mediafile is on the server the mediastore is aborted without storing. 
This is helpful: If you have many mediafiles (1000s) in the JSON you might first download
the mediafiles with a PHP-Script without any WordPress-OVerhead (much faster). 
And then laod the images via WordPress and JCI-mediastore from the server without 
http-requests (also fast)#}
{% set sourcetype = "" %}

{# FALSE: Do not generate thumbnails - 
if you store many images this is importaint, as generating costs lots of performance / time #}
{% set generate_thumbnails = TRUE %}

{% set loadedimage = ((imageurl | mediastore(parentPageId, useExistingMediaFile, deleteonly, mediatitle, excerpt, content, mime_type, sourcetype, generate_thumbnails)) | json_decode) %}

Uploaded Images at <a href="{{loadedimage.jci.attachment_url }}" target="_blank2">{{loadedimage.jci.attachment_url }}</a><br>
<img src="{{loadedimage.jci.attachment_url }}">

Complete WordPress-Response:<br>
{{ loadedimage | json_encode }}

Example in action:

Input JSON:

Warning: checkdate() expects parameter 1 to be int, string given in /www/htdocs/w0135691/ on line 7019
Complete Wordpress-Response:

PRO: Upload and send Data to API

Your Challenge:
Offer a HTML-Form to your user for inserting some text and uploading a mediafile. The mediafile should be stored locally and displayed together with the text input. Also the text and mediafile should be sent to an API.

This is the way to achieve this:

Create two JCI-Templates.
JCI-Template 1:

  • templatename: uploadaddpic
  • URL: This must be a real API where you want to send the data (“dummyrequest” is not ok here)
  • method: CURL-POST
  • urlparam4twig: text1
  • twig-Template:
{{_context | json_encode }}

JCI-Template 2:

  • templatename: uploadmediafile
  • URL: URL to an API which gives all data you sent via this form. If not needed use “dummyrequest”.
  • method: CURL-POST
  • twig-template:
    get_data_of_uploaded_file: This JCI-twig-function returns $_FILES, a ‘superglobal’ PHP-variable where the HTTP File Upload variables are stored.
{% if urlparam.text1 %}
input text: {{urlparam.text1}}<br>
{% set picdata = get_data_of_uploaded_file('yourmediafile') %}
data of uploaded file: {{picdata | json_encode}}<hr>
{% set maxsizekb= 2*1024*1024 %}
{% if picdata.error==0 and picdata.size<maxsizekb %}
upload file is ok for saving in wp-medialib<br>
{% set jciaddkond='{"answer":"hello","urlparam":{"one":"","two":"","text1":""},"apiresponseinfo":[]}' %}
shortcode for saving file: {{jciaddkond}}<hr>
{% set execsh = jciaddkond | doshortcode %}
shortcode-execution result: {{execsh | dump }}<br>
{% set execshArr = execsh | json_decode %}
{% set uploadedImgInWPLib = execshArr.apiresponseinfo.upload.attachment_url %}
<hr>{{urlparam.text1}}<br><img src="{{uploadedImgInWPLib }}">
{% else %}
mediafile not stored:<br>
picdata.error: {{picdata.error}}<br>
maxsize:  {{(maxsizekb/1024)| round(2)}} kB<br>
Bildgröße: {{(kondpicdata.size/1024)| round(2)}} kB<br>
{% endif %}
{% endif %}
<form action=/upload/ enctype="multipart/form-data" method=POST>
<input type=text name=text1 placeholder="Your example text">
<input type="file" name="yourmediafile">
<input type=submit>
  • urlparam4twig:

Use the JCI-Templates:

Place the following sortcode on the Page /upload/ (see <from action=…>” at twig-template JCI-Template 2, change this if needed)

[jsoncontentimporterpro nameoftemplate="uploadmediafile" orderofshortcodeeval=10] 

In Action, to avoid unwanted uploads this page is password protected:

Ok, if you need a nice free plugin out of the box: Check

PRO: Set Page-Title and Head-Tags by JSON and CPF

This pages shows you, how to set the Page-Title and Head-Tags out of JSON-data together with Custom Post Fields.

  • Step 1: Add “Custom Post Fields” (CPF) to “Custom Post Type” (CPT)
    You need two Custom Post Fields named “jci_pagetitle” and “jci_pagehead”. One way is to do that with ACF.
    Connect these CPF with the CPT you want to set Title and Head, e. g. “Pages”.
  • Step 2: Custom Post Fields
    Create a new Custom Post Page (CPP) out of the Custom Post Type you connected to the new Custom Post fields (CPF). Add some dummyvalues to the CPF and preview the CPP: The title should be the dummyvalue you set in “jci_pagetitle”
  • Step 3: Create a new JCI-Template
{{ ("now"|date("H:i:s")) }} - name is {{urlparam.ename |e('html') | slice(0, 5)}} - {{}}
  • Step 4: Add shortcode with template
    Insert the following into the CPF “jci_pagetitle”:
    begin-[jsoncontentimporterpro nameoftemplate=addpagetitle]-end
    The preview of the page should have the HTML-Title <title>begin-name is Love Breakfast-end</title> out of JSON-data. And out of first 5 characters of the GET-parameter “ename”, see here.
  • Step 5: Add Head-Tags to page, created out of JSON (Step 4 and the Shortcode there is required!)
    Insert the following into the CPF “jci_pagehead”:
<meta name="event" content="{{urlparam.ename |e('html'|slice(0, 3) ) }}-{{ local_date|date("s:i;H-m/d/Y") }}: {{}}">#LF#<meta name="city" content="{{}}">

See it in action here (open HTML-Sourcecode for that in the browser, please): JSON and the first 3 characters of the GET-parameter “ename” meet in Meta-Tags.