PRO Version: Create Custom Pages with a Shortcode
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.
Either via Shortcode (see below) or via twig functions.
JSON-Example:
The JSON http://api.json-content-importer.com/extra/json/meetup/1.json lists several events.
Your task:
Display and store this data in WordPress. Each event should have its 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 the latitude and the 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 its own “JCI-CPT-Creator”. For that see the Options of the JCI-plugin, there is the Tab “Custom Post Types”.
Define/register a “Custom Post Type” in the Options of the JCI-plugin, there is the Tab “Custom Post Types”.
Here you have to define three parameters important for the Custom PostType:
– type: Singular name of the Custom Post Type. The Plugin adds automatic “jci_” as a 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 “##”.
Example:
type=mynewposttype;ptredirect=herewego;ptname=MyCreatedPost;key=34tdssg54##type=mynewposttype1;petredirect=herewego1;ptname=MyCreatedPost1;key=skjfh4312
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 on the general Settings of WordPress, there “Permalinks” and select the “Post name”-Radiobutton and store.
STEP 3
Create a new JCI template
Click on the Plugins template-manager and add one template with
- the default text as twig-template
- the URL with the data, Example: http://api.json-content-importer.com/extra/json/meetup/1.json
- set the name of the template (e.g. “mytemplate1”)
- plus, if needed, curloptions for access, like authentication, etc..
Save it. This template is used for defining the access to JSON and for building each single Custom Post (we will 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 a draft (later we publish it).
STEP 5:
Set up a Shortcode and add it to the WordPress Page created in Step 4:
Example:
[jsoncontentimporterpro debugmode=10 nameoftemplate=mytemplate1]
- debugmode=10: display details of the plugin action (r. g. how the JSON-API is used), delete in the end if all is ok
- nameoftemplate: name of the JCI-template
- Additional Parameter: Up to now we’re creating a usual get-and-display page. If you need more parameter just add it.
STEP 6:
View Creating Page
Preview the so far created WordPress-Page which will later create the Custom Posts. You should see some debug messages: Esp. the JSON-Code retrieved should be there. If not you have to check the Shortcode for missing parameters. Also, the template-default-text 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 and paste the JSON into http://www.jsoneditoronline.org 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 example http://api.json-content-importer.com/extra/json/meetup/1.json 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 nameoftemplate=mytemplate1 mode=create createoptions='{“key”: “randomkey274t32t3″,”type”: “mynewposttype”, “loop”:””, “title”:”cp-title: {{name}}”, “excerpt”:”excerpt for {{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 invalid quotation marks
[jsoncontentimporterpro nameoftemplate=mytemaplte1 mode=create createoptions='{"key": "randomkey274t32t3","type": "mynewposttype", "loop":"", "title":"cp-title: {{name}}", "excerpt":"excerpt for {{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 “page” or “post”
- “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
- “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}}”
- “slugname”: “cp-slug-{{name|replace({#SQM#/#SQM#: #SQM#-#SQM#})}}”: twig-template for building the slug/URL of the created Custom Post. Find something in the JSON-data for that, like “{{id}}”
- “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)
- optional fields:
- “excerpt”: Excerpt field in the CPT
- “loopstart”:NUMBER: Start the loop at item loopstart, count from 1 on (if 0 no loopstart/loopend functionality)
- “loopend”:NUMBER: End the loop at item loopstart+loopend
- “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 the 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-data field. 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”:”http://api.json-content-importer.com/wp-content/uploads/2020/01/icon-256×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.
- “postauthorid” is the NUMBER of the user who should be the author of the created pages
- “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 Server time, e.g. one hour is 3600 seconds or 3600000 milliseconds.
“VALUE” can be “wptimezone”: Then the in the WordPress-installation defined timezone is used
“VALUE” can be a valid timezonestring
Extended Example:
[jsoncontentimporterpro nameoftemplate=mytemplate1 mode=create createoptions='{"key": "hellomyfriend242","type": "test01", "loop":"", "title":"cp-title: {{name}}", "loopstart":1,"loopend":4, "minimumcptocreate":"2", "postpublishtime":"{{data_of_publishing_in_json}}", "postdateoffset":3600, "postauthorid":1, "requiredfields":"name", "slugname": "cp-slug-{{name|replace({#SQM#/#SQM#: #SQM#-#SQM#})}}", "deleteold":"yes", "featuredimage": #BRO# {"url_json_path":"detailpage.img", "url_default":"http://api.json-content-importer.com/wp-content/uploads/2020/01/icon-256x256-1.png"}#BRC#, "postdateoffset":"Europe/Berlin"}']
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 entry “ptname” (see Step 1) is created with a number of pages. These pages should be published pages with a URL “ptredirect” (see Step 1) plus “slugname” (see Step 8).
- Open one of the created CPs for editing. The content of the created Custom Post should be the executed template-default-text with JSON data. 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: With that, you can call the URL or insert the whole Shortcode.
STEP 10:
Improve the content in the generated Custom Pages: edit JCI template
- Click on the Plugins template manager and open the template used for generating the shortcode. Edit the default text which is put into the content area of the created Custom Posts together with the JSON-data
- If you want to have a Shortcode on a generated Custom Page: E. g. having another [jsoncontentimporterpro…]-Shortcode parametrized by the data from the initial JSON-API-call you must mask the Square-Brackets like this:
#BRO#jsoncontentimporterpro nameoftemplate=inside#BRC#.
Otherwise, WordPress gets confused.
For the Example-JSON http://api.json-content-importer.com/extra/json/meetup/1.json you can try this:
{{name}}, {{local_date | date("d.m.Y") }}, {{local_time}}: {{venue.name}}#BRO#jsoncontentimporterpro nameoftemplate=inside#BRC#<br>end of page
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 with Advanced Custom Fields (ACF). Or via the Shortcode. This step is about creating and filling CPF with the plugin only. How to do it with the mentioned plugins see Step 13.
For that add “customfields” to the Shortcode in the “createoptions” JSON. E. g. in the example 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 CPFs in each created CP should be there. One named “cpf1” always with the same value. And “cpf2019-02-04” with the current time.
Complete Shortcode:
[jsoncontentimporterpro nameoftemplate=mytemplate1 mode=create createoptions='{"key": "hellomyfriend242","type": "test01", "loop":"", "title":"cp-title: {{name}}", "loopstart":1,"loopend":4, "minimumcptocreate":"2", "postpublishtime":"{{data_of_publishing_in_json}}", "postdateoffset":3600, "requiredfields":"name", "slugname": "cp-slug-{{name|replace({#SQM#/#SQM#: #SQM#-#SQM#})}}", "deleteold":"yes", "featuredimage": #BRO# {"url_json_path":"detailpage.img", "url_default":"http://api.json-content-importer.com/wp-content/uploads/2020/01/icon-256x256-1.png"}#BRC#, "customfields": #BRO# {"cpf1":"cpf-value1"}, {"cpf2{{local_date}}":"date{{#SQM#now#SQM#|date(#SQM#mdY#SQM#)}}"}#BRC#, "postdateoffset":"Europe/Berlin"}']
STEP 13:
Create CP out of the CPT created by ACF, Toolset or Pods: JSON, Custom Posts, Custom Post Fields, Taxonomies
By Toolset or Pods, you define CPT with its 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.
- ACF:
Add a field group with some fields. E. g. field groupt “acfgroup1” with fields “acf1” and “acf2”. Connect this to your Custom Post Type. When creating a new CPT manually you should see these two CPFs.
Add this to the shortcode:
"cpt": #BRO# {"slug":"test01", "keeptaxonomies":"yes", "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# {"acf1":"aa{{local_date}}","acf2":"bb{{local_date}}"} #BRC# } #BRC#,
Full examples, incl. Taxonomies:
[jsoncontentimporterpro nameoftemplate=mytemplate1 mode=create createoptions='{"key": "hellomyfriend242","type_NOT_NEEDED_ANY_MORE_SEE_slug_in_cpt": "test01", "loop":"", "title":"cp-title: {{name}}", "cpt": #BRO# {"slug":"test01", "keeptaxonomies":"yes", "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# {"acf1":"aa{{local_date}}","acf2":"bb{{local_date}}"} #BRC# } #BRC#, "loopstart":1,"loopend":4, "minimumcptocreate":"2", "postpublishtime":"{{data_of_publishing_in_json}}", "postdateoffset":3600, "requiredfields":"name", "slugname": "cp-slug-{{name|replace({#SQM#/#SQM#: #SQM#-#SQM#})}}", "deleteold":"yes", "featuredimage": #BRO# {"url_json_path":"detailpage.img", "url_default":"http://api.json-content-importer.com/wp-content/uploads/2020/01/icon-256x256-1.png"}#BRC#, "customfields": #BRO# {"cpf1":"cpf-value1"}, {"cpf2{{local_date}}":"date{{#SQM#now#SQM#|date(#SQM#mdY#SQM#)}}"}#BRC#, "postdateoffset":"Europe/Berlin"}']
In detail:
“cpt”: #BRO# {
“slug”:”SLUGNAME_OF_TOOLSET_OR_PODS_CPT: what we used before for type”,
“keeptaxonomies”:”yes”, “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#
- see each Parameter:
- “slug”:”‘SLUGNAME_OF_TOOLSET_CPT” : this is the slug (Toolset, CustomPost) or type (page, post, JCI-name for CP) of the Custom Post. Use here what was used before at field “type” (which is not used when using “cpt”)
- keeptaxonomies: “yes” or “no” : if “no” delete all previously created taxonomies, otherwise keep them (important, if you fill the CP in several steps)
- 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)
- With the free Pods-Plugin you can create a Custom Post Type with Custom Post Fields and Taxonomies.
In the following Shortcode the Pod with slug (=name) “cppods1” has two CPF “podsf1” and “podsf2” plus a Taxonomy “podstax1”. Mind the masking for twig like #SQM# etc:
[jsoncontentimporterpro nameoftemplate=mytemplate1 mode=create createoptions='{"key": "hellomyfriend242", "loop":"", "title":"pods-cp-title: {{name}}", "cpt": #BRO# {"slug":"cppods1", "keeptaxonomies":"no", "taxonomiesmatches": #BRO# {"podstax1":"tax{{local_date | date(#SQM#Ydm#SQM#) }}"} #BRC#, "matches": #BRO# {"podsf1":"aa{{local_date | date(#SQM#mdY#SQM#)}}","podsf2":"bb{{local_date}}"} #BRC# } #BRC#, "slugname": "cp-slug-{{name|replace({#SQM#/#SQM#: #SQM#-#SQM#})}}", "deleteold":"yes"}']
- With the Toolset Types-Plugin you can create a Custom Post Type with Custom Post Fields and Taxonomies as well.
In the following Shortcode the Toolset-CPT with slug (=name) “toolsetcpt” has two CPF “name” and “performances” plus a Taxonomy named “tstax”. Mind the masking for twig like #SQM# etc:
[jsoncontentimporterpro nameoftemplate=mytemplate1 mode=create createoptions='{"key": "hellots1", "loop":"", "title":"ts-cp-title: {{name}}", "cpt": #BRO# {"slug":"toolsetcpt", "keeptaxonomies":"no", "taxonomiesmatches": #BRO# {"tstax":"tstax{{start_date| date(#SQM#Ydm#SQM#) }}"} #BRC#, "matches": #BRO# {"name":"ts-aa{{start_date| date(#SQM#mdY#SQM#)}}","performances": {"path":"performances", "valuefield":"twig-{{1000+id}}"}} #BRC# } #BRC#, "slugname": "ts-slug-{{name|replace({#SQM#/#SQM#: #SQM#-#SQM#})}}", "deleteold":"yes"}']
It looks quite similar, but not at “matches” -> “performances”: If you want to fill a “multiple CPF” (one CPF which has many different values) this can be done in the following way.
See example-JSON at node “performances” of each item.
- In detail:
- The “simple” way is just dumping all JSON data of “performances” into the CPF by
{{performances | json_encode}}
Storing multiple values in one CPF: Then go to the Toolset-setup of the CPF and check the box “Allow multiple instances of this field” to define this CPF as “multi”.
First, define the CPF as “multi”: Go to the Toolset-setup of the CPF and check the box “Allow multiple instances of this field” to define this CPF as “multi”.
2nd: The JSON gives us the values either in an array or a node where a field is the needed value. So we have to define the JSON path to the data as closely as possible. E.g. a path like “performances” (put together a path separated by “.”). And then, if it’s not an array, define which JSON field should be used. In the example let’s use field “id”. With the following JSON in the shortcode, we tell the plugin to use the values for “path” and “valuefield” for the CPF (twig code is executed in the “valuefield”):
"performances": {"path":"performances", "valuefield":"twig-{{1000+id}}"}
- Another toolset hint: Toolset stores dates in the Unix-time-format. So you have to have this format in the Shortcode. For example if you want to have a random date in da toolset-date-cpf:
"eventdate": "{{ random(+#SQM#now#SQM#|date(#SQM#U#SQM#)) }}",
There “U” is the formatting part, see here for more.