PRO Version: Create Custom Pages out of JSON and Custom Post Types

Usually the JSON Content Importer PRO Plugin (JCI) retrieves JSON from an API, converts the data with a template to HTML and displays this HTML. That’s it.
The PRO-Version can do more: It can create Custom Post Pages with Custom Post Fields (CPF) and Taxonomies out of a Custom Post Type.

The JSON lists several events.

Your task:
Display and store this data in wordpress. Each event should have it’s own url and “page” (aka “Custom Post” (CP) made out of a “Custom Post Type”-template (CPT)). Also these CP should have Taxonomies (like categories for event-types) and Custom Post Fields (CPF) like latitude and longitude of the venue.

See how this works with JCI and Plugins like Toolset, Pods or Advanced Custom Fields (ACF):

See how this works with the JCI without other Plugins:

  • STEP 1
    First of all you need a Custom Post Type (CPT): This is the Template / blueprint for all the Pages that will be created. You can create such a CPT in several ways:
    • Use the WordPress-Posts- or -Pages: As they already exist Step 1 is already done
    • Use Plugins like Toolset or Pods: With that you can create CPT with CPF and Taxonomies very fast and flexible.
    • If you do not need Taxonomies and want to have direct access to all settings this is an alternative, but a bit techie, way: The JSON Content Importer-Plugin comes with it’s own “JCI-CPT-Creator”. For that see the Options of the JCI-plugin, there the Tab “Custom Post Types”. See Video and code-examples here

      Define / register a “Custom Post Type” in the Options of the JCI-plugin, there the Tab “Custom Post Types”.
      Here you have to define three parameters importains for the Custom PostType:
      – type: Singluar name of the Custom Post Type. The Plugin adds automatic “jci_” as prefix to avoid trouble with other plugins
      – ptredirect: Path for the URL of the created Custom Post
      – ptname: Menuname in the WordPress-Dashboard
      – key: Unique, random string to connect all pages created by this JSON (when deleting, all pages with that key are deleted)
      The keys and values have to be separated by “=” and the pairs by “;”. If you want to define more than one Custom Post Type separate by “##”.


      When setting “deleteold=some” you can use twig-code in “key”. E. g. key=date{{“now”|date(“Ymd”)}} creates keys with the current date.
      If you enhance the twig-code for the key by if-then-else and JSON-data you can build keys for each JSON-item. If the key is empty nothing is deleted or created. When updating the CPT with new JSON you can delete some old CPT and keep some CPT.

      The WordPress-Admin-Menu should have the items “MyCreatedPosts” and “MyCreatedPost1”.


  • STEP 2
    Set Permalink “Post name”
    Click to the general Settings of WordPress, there “Permalinks” and select the “Post name”-Radiobutton and store.


  • STEP 3
    Create a new JCI-template
    Click to the Plugins template-manager and add one with some dummy text as twig-template AND the URL with the data (plus, if needed, curloptions for access, like authentication etc.).
    Save it. Then browse the list of templates and get the id of this template, let’s call it TEMPLATE_ID_FOR_CUSTOM_POST.
    This template is used for defining the access to JSON and for building each single Custom Post (we improve that template later).


  • STEP 4:
    Create a new ordinary (!) WordPress Page
    There we place all we need to create Custom Posts like the shortcode (we do create one in the next step).
    Title of this page: Something like “Create Custom Post”.
    Store that page as draft (later we publish it).


  • STEP 5:
    Set up a Shortcode in a new WordPress Page:

    [jsoncontentimporterpro debugmode=10 id=TEMPLATE_ID_FOR_CUSTOM_POST]

    – debugmode=10: display details of the plugin-action (r. g. how the JSON-API is used), delete in the end if all is ok
    – id=TEMPLATE_ID_FOR_CUSTOM_POST: see Step 3
    – Additional Parameter: Up to now we’re creating a usual get-and-display-page. So if you need more parameter just add it. E.g. method=post, payload=… etc.


  • STEP 6:
    View Creating Page
    Preview the so far created WordPress-Page which will later create the Custom Posts. You shoud see some debug-messages: Esp. the JSON-Code retrieved should be there. If not you have to check the Shortcode for missing parameter. Also the template-dummytext should be there (see Step 3).
    If this looks good publish this page.


  • STEP 7:
    Check the JSON-data
    You should be familiar with the JSON you retrieve. You can copy paste the JSON into to see the structure. As you want to create a set of Custom Posts you need a set of data for that. You must identify the path to such a set in your JSON.

    In the path is the root as the JSON is a collection (aka array) of JSON-objects.


  • STEP 8:
    Enhance Shortcode: Add information on how to create Custom Posts (CP) out of the CPT
    For creating CPs the plugin needs two Shortcode-Parameter: “mode” and “createoptions”. We now add these to the Shortcode created in Step 5.
    Example (when copypasting remove all linefeeds!):
    [jsoncontentimporterpro id=TEMPLATE_ID_FOR_CUSTOM_POST mode=create createoptions='{“key”: “randomkey274t32t3″,”type”: “mynewposttype”, “loop”:””, “title”:”cp-title: {{name}}”, “minimumcptocreate”:”2″, “postpublishtime”:”{{data_of_publishing_in_json}}”, “requiredfields”:”name”, “slugname”: “cp-slug-{{name|replace({#SQM#/#SQM#: #SQM#-#SQM#})}}”, “deleteold”:”yes”, “postdateoffset”:”Europe/Berlin”}’]

    TAKE CARE: Copypaste Code from the following box – this avoids trouble with inavlaid quotation marks

    [jsoncontentimporterpro id=TEMPLATE_ID_FOR_CUSTOM_POST mode=create createoptions='{"key": "randomkey274t32t3","type": "mynewposttype", "loop":"", "title":"cp-title: {{name}}", "minimumcptocreate":"2", "postpublishtime":"{{data_of_publishing_in_json}}", "requiredfields":"name", "slugname": "cp-slug-{{name|replace({#SQM#/#SQM#: #SQM#-#SQM#})}}", "deleteold":"yes", "postdateoffset":"Europe/Berlin"}']

    In detail:
    – mode=create: This sets an plugin-call into “create Custom Posts mode”
    – createoptions=…: JSON-coded parameter on how to build the Custom Posts
    mandatory fields:
    — “key” or “cptkey”:”randomkey274t32t3“: A random key for identifying connected CP
    — “type”:”mynewpagetype“: This is the link to the Custom Post Type defined in Step 1. If you use WordPress-Pages or -Posts use “pages” or “posts”
    — “loop”:”data”: The Plugin needs a set of data (aka array) in the JSON-data. Use “#singlepage#” if you want to create a single Custom Posts with all JSON you have. This is defined here. See also Step 7 for that
    — “loopstart”:NUMBER: Start the loop at item loopstart
    — “loopend”:NUMBER: End the loop at item loopstart+loopend
    — “deleteold”:”yes”: (mandatory): When creating new Custom Posts all previous Custom Posts are deleted (they are identified by “jci_uniquekey_createpost”, see Step 2). Either “yes”, “no” or “some” (see later)
    — “slugname”: “cp-slug-{{name|replace({#SQM#/#SQM#: #SQM#-#SQM#})}}”: twig-template for building the slug/URL of the created Custom Post. Finde something in the JSON-data for that, like “{{id}}”.
    optional fields:
    — “title”:”cp-title:{{name}}”: twig-template for building the Title of the created Custom Post. E.g. find in your JSON data for the Custom Post HTML-title. E.g. “{{name}}”
    — “minimumcptocreate” e. g. “2”: Minimum number of to be created CP. If there are less in the JSON the creation / plugin would abort
    — “postpublishtime”: Set Publishing-date and time of generated Post, e.g. from a JSON-field with this info. You can use twig-code here with #SQM# (for '), #GT# (for >), #LT# (for <)-Placeholders
    — “requiredfields” e. g. “name”: Name of required JSON-datafield. If a dataset in the loop for the CP does not have such a field it would be ignored (e. g. if the JSON does not give data but an error etc.)
    — “featuredimage”: #BRO# {“url_json_path”:”detailpage.img”, “url_default”:”×256-1.png”}#BRC# : This is to set a featured image for the CP. “detailpage.img” is an example for the path in the JSON to an URL with the CPs featured image. “url_default” defines a default image if there is nothing in the JSON- #BRO” and #BRC# stand for “Bracket open/close” as we work here with JSON, but in a shortcode no other square brackets are allowed, so we mask those here.
    — “postdateoffset”:”VALUE”: Date of generated Custom Post Types:
    set “VALUE” for the time and date of the generated Custom Post Fields.
    If not set the current PHP-Servertime is used.
    “VALUE” can be numeric: Then this number is subtracted from the current Servertime, e.g. one hour is 3600 seconds or 3600000 miliseconds.
    “VALUE” can be “wptimezone”: Then the in the WordPress-installation defined timezone is used
    “VALUE” can be a valid timezonestring


  • STEP 9:
    Create Custom Posts
    Publish the creating Post with the enhanced Shortcode and call it in the browser (you can switch off the template by adding “?show=oc”): This should create Custom Posts and show some debug-messages.
    In case of success in the WordPress-Menu a entry “ptname” (see Step 1) is created with a number of pages. Thes pages should be publshed pages with a URL “ptredirect” (see Step 1) plus “slugname” (see Step 8).

    Open one of the created CP for editing. The content of the created Custom Post should be the template-dummytext. If you used the “featured”-image this should be there too (maybe the default image).

    Check, if the URL of the created CP (aka slug) works. If not, do step 2 again.

    In this way you can update your CP later, using the plugin written for that: Get URL Cron.


  • STEP 10:
    Enhance the template
    Click to the Plugins template-manager and open the template with the dummytext. Here you can build the content which is put into the created Custom Posts. This depends on the JSON-data you have. If you need to call the API again for retrieving more, Custom Post-specific data you can do that by adding another [jsoncontentimporterpro…]-Shortcode parametrized by the data from the initial JSON-API-call.

    For the Example-JSON you can try this:

    {{name}}, {{local_date | date("d.m.Y") }}, {{local_time}}: {{}}


  • STEP 11:
    Create Custom Posts again, like in Step 9
    Now the created CP should have JSON data in the content!
    If there is twig-code you have an error in the twig-code: debug this, please!


  • STEP 12:
    Add Custom Post Fields (CPF)
    CPFs are added either via the CPT-Plugins like Toolset or Pods. Or via the Shortcode. For that add “customfields” to the Shortcode in the “createoptions” JSON.
    E. g. in the exmaple like this:
    “customfields”: #BRO# {“cpf-name1″:”cpf-value1”}, {“cpf2{{JSONfield}}”:”date{{#SQM#now#SQM#|date(#SQM#mdY#SQM#)}}”}#BRC#

    "customfields": #BRO# {"cpf1":"cpf-value1"}, {"cpf2{{local_date}}":"date{{#SQM#now#SQM#|date(#SQM#mdY#SQM#)}}"}#BRC#

    Recreate the CP with that (see Step 9): Then two CPF in each created CP should be there. One named “cpf1” always with the same value. And “cpf2019-02-04” with the current time.


  • STEP 13:
    Create CP out of the CPT created by Toolset or Pods: JSON, Custom Posts, Custom Post Fields, Taxonomies
    By Toolset or Pods you define CPT with it’s CPF and Taxonomies. By ACF you can add CPF to CPT. With the JCI-plugin you can use these CPT and create CP with CPF and Taxonomies.
    Add to the shortcode something like this:
    “cpt”: #BRO# {“keeptaxonomies”:”yes”,”key”:”keyfromtoolsetshortcode:random32142″, “slug”:”SLUGNAME_OF_TOOLSET_OR_PODS_CPT”, “taxonomiesmatches”: #BRO# {“NAME_OF_TOOLSET_OR_PODS_TAXONOMY_1″:”JSON_PATH_BY_DOTS_1”, “NAME_OF_TOOLSET_OR_PODS_TAXONOMY_1″:”JSON_PATH_BY_DOTS_2”} #BRC#, “matches”: #BRO# {“NAME_OF_TOOLSET_OR_PODS_OR_ACF_CPF_1″:”JSON_PATH_BY_DOTS_3″,”NAME_OF_TOOLSET_OR_PODS_OR_ACF_CPF_2″:”JSON_PATH_BY_DOTS_4”} #BRC# } #BRC#

    "cpt": #BRO# {"keeptaxonomies":"yes","key":"keyfromtoolsetshortcode:random32142", "slug":"SLUGNAME_OF_TOOLSET_OR_PODS_CPT", "taxonomiesmatches": #BRO# {"NAME_OF_TOOLSET_OR_PODS_TAXONOMY_1":"JSON_PATH_BY_DOTS_1", "NAME_OF_TOOLSET_OR_PODS_TAXONOMY_1":"JSON_PATH_BY_DOTS_2"} #BRC#, "matches": #BRO# {"NAME_OF_TOOLSET_OR_PODS_OR_ACF_CPF_1":"JSON_PATH_BY_DOTS_3","NAME_OF_TOOLSET_OR_PODS_OR_ACF_CPF_2":"JSON_PATH_BY_DOTS_4"} #BRC# } #BRC#

    — keeptaxonomies: “yes” or “no” : if “no” delete all previous created taxonomies, otherwise keep them (importaint, if you fill the CP in several steps)
    — keyfromtoolsetshortcode: A random key for a group of created CP
    — slug”:”SLUGNAME_OF_TOOLSET_CPT” : define the URL of the CP
    — taxonomiesmatches: #BRO# {“NAME_OF_TOOLSET_OR_PODS_TAXONOMY_1″:”JSON_PATH_BY_DOTS_1”, “NAME_OF_TOOLSET_OR_PODS_TAXONOMY_2″:”JSON_PATH_BY_DOTS_2”} #BRC# : list of taxonomies defined in a Toolset- or Pods-CPT and it’s counterpart in the JSON-data (notation of JSON-path: dots)
    — matches: #BRO# {“NAME_OF_TOOLSET_OR_PODS_OR_ACF_CPF_1″:”JSON_PATH_BY_DOTS_3″,”NAME_OF_TOOLSET_OR_PODS_OR_ACF_CPF_2″:”JSON_PATH_BY_DOTS_4”} #BRC# } #BRC# : list of CPF defined in a Toolset- / Pods- or ACF-CPT and it’s counterpart in the JSON-data (notation of JSON-path: dots)