{"_id":"598210420f32920020f6326c","project":"55773a5ba042551900b002cb","initVersion":{"_id":"55773a5ba042551900b002ce","version":"1"},"user":{"_id":"546d17e2eb9cfd1400dd4529","username":"","name":"Gareth Davies"},"__v":0,"createdAt":"2017-08-02T17:47:46.565Z","changelog":[],"body":"Whilst the Triathlon API provides a familiar JSON output format that may be integrated directly into applications some users may be more comfortable working with the API within the confines of their existing content management systems such as [Wordpress](https://wordpress.com/). Fortunately Wordpress has a plethora of plugins to ease the process and in particular the [JSON content importer plugin](https://json-content-importer.com/) that we will focus on this article. \n\nTo demonstrate the plugin in action we will be building a simple [WTS events calendar](http://www.triathlon.org/events/all#q=&hPP=15&idx=events_reverse_sort&p=0&dFR%5Bevent_categories.cat_name%5D%5B0%5D=World%20Triathlon%20Series&dFR%5Byear%5D%5B0%5D=2017&is_v=1) and displaying the start lists for each event.\n\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"title\": \"JSON content importer is available as both a free and paid version\",\n  \"body\": \"For the purpose of the article we will use the features that are only available in the pro version of the plugin.\"\n}\n[/block]\nAssuming that Wordpress and the JSON content importer plugins have been installed, adding the following code to the template will output a list of all WTS events to be held in 2017. You will need to have a valid API key by first [registering your application](https://apps.api.triathlon.org/register) and substituting in the code below.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"[jsoncontentimporterpro url=\\\"https://api.triathlon.org/v1/events?category_id=351&start_date=2017-01-01&end_date=2017-12-31\\\" numberofdisplayeditems=\\\"10\\\"  header=\\\"apikey:your-api-key-here\\\" basenode=\\\"data\\\"]\\n\\n<strong>{event_title}</strong>\\n\\n[/jsoncontentimporterpro]\",\n      \"language\": \"html\"\n    }\n  ]\n}\n[/block]\nIn the above code we are simply requesting a list of events from the [Event Listings method](https://developers.triathlon.org/docs/event-listings) of the API `https://api.triathlon.org/v1/events?category_id=351&start_date=2017-01-01&end_date=2017-12-31` using the params of `category_id` and `start_date` and `end_date` to choose the corresponding 2017 World Triathlon Series events.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/3d057ab-Events_WTS__user_s_Blog_.png\",\n        \"Events_WTS_–_user_s_Blog_.png\",\n        477,\n        462,\n        \"#272326\"\n      ],\n      \"caption\": \"List of all WTS events in 2017\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"title\": \"Plugin Settings\"\n}\n[/block]\nWhilst we have achieved a very basic integration of the API into Wordpress in order to access more functionality and improve performance a few settings changes are required.\n\nFirstly, the cache should be enabled to prevent Wordpress from requesting data on every page load. Clearly, for the majority of cases data will not be changing rapidly and a longer cache time is preferred to ensure fast page load times. In the example below a cache time of 60 minutes has been enabled.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/74691d5-Options__user_s_Blog___WordPress.png\",\n        \"Options_‹_user_s_Blog__—_WordPress.png\",\n        1191,\n        234,\n        \"#f1f1f1\"\n      ]\n    }\n  ]\n}\n[/block]\nNext, in order to generate content dynamically on the site i.e. so we can switch between events to get event specific information based on the URL we need to allow the `pathparam` setting which may be found under the \"Shortcode-Attributes\" section of the settings (you may leave all other settings as their default). \n[block:callout]\n{\n  \"type\": \"success\",\n  \"title\": \"Ensure the setting for \\\"pathparam\\\", \\\"fileext\\\" are on to continue\"\n}\n[/block]\n\n[block:api-header]\n{\n  \"title\": \"Creating the Program Listings Page\"\n}\n[/block]\nWe have the event listings and now we wish to view all programs happening at the event such that we view the start lists for each. For this the [Program Listings](https://developers.triathlon.org/docs/program-listings) method is required but we need the `event_id` from the event listing to acquire this information. Therefore we will update the previous template to pass the `event_id` as a path parameter to a program listings template. We also need to provide a `path` parameter to be explained in the next section.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"[jsoncontentimporterpro url=\\\"https://api.triathlon.org/v1/events?category_id=351&start_date=2017-01-01&end_date=2017-12-31\\\" numberofdisplayeditems=\\\"10\\\"  header=\\\"apikey:your-api-key-here\\\" basenode=\\\"data\\\"]\\n\\n<a href=\\\"/program-listings?event_id={event_id}&path=programs\\\">{event_title}</a>\\n\\n[/jsoncontentimporterpro]\",\n      \"language\": \"html\"\n    }\n  ]\n}\n[/block]\nNow in the template for the page program-listings we can access the `event_id` parameter and pass it to the [Programs Listings](https://developers.triathlon.org/docs/program-listings) method to output all programs happening at the event. One of the drawbacks of the plugin is that we cannot dynamically set all parts of the URL hence we must pass in additional URL parameters to construct the URL we require (in this case `path` which is set to programs).\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<strong>Programs</strong>\\n\\n[jsoncontentimporterpro url=\\\"https://api.triathlon.org/v1/events\\\" numberofdisplayeditems=\\\"100\\\"  header=\\\"apikey:your-api-key-here\\\" basenode=\\\"data\\\" pathparam=\\\"event_id#path\\\" oneofthesewordsmustnotbein=\\\"Officials,Medicals,Coaches\\\" oneofthesewordsmustnotbeindepth=\\\"2\\\"]\\n\\n<a href=\\\"/start-list/?event_id={event_id}&path=programs&prog_id={prog_id}&method=entries\\\">{prog_name}</a>\\n\\n[/jsoncontentimporterpro]\",\n      \"language\": \"html\"\n    }\n  ]\n}\n[/block]\n\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/30b9060-Program_Listings__user_s_Blog_.png\",\n        \"Program_Listings_–_user_s_Blog_.png\",\n        483,\n        141,\n        \"#382e35\"\n      ],\n      \"caption\": \"List of all programs at the event\"\n    }\n  ]\n}\n[/block]\nThis code will output all programs for a specific `event_id` and links to a page called start-lists which we will implement below in order to output the start lists for each program at an event. In the above code we have also used a feature of the plugin to exclude certain results from the output called `oneofthesewordsmustnotbein`. As the output of the [Program Listings](https://developers.triathlon.org/docs/program-listings) method also includes some administrative programs we want to hide those from the final output and only display the programs that we are interested in. By contrast we could also use the `oneofthesewordsmustbein` if we wanted to specifically only include certain programs.\n\nIn order to generate the start lists we will use the [Program Entries method](https://developers.triathlon.org/docs/program-entries) which requires the `event_id` and `prog_id` and hence we construct our URL on the program-listings template to pass this information in the query string.\n[block:api-header]\n{\n  \"title\": \"Outputting the start lists\"\n}\n[/block]\nOur final template outputs the start list for a single program at an event indicating the athlete name, country and start number. The result format of this API call is available [here](https://developers.triathlon.org/docs/program-entries) and contains additional information that is not being included in the basic output below.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"[jsoncontentimporterpro url=\\\"https://api.triathlon.org/v1/events\\\" numberofdisplayeditems=\\\"100\\\"  header=\\\"apikey:your-api-key-here\\\" basenode=\\\"data\\\" pathparam=\\\"event_id#path#prog_id#method\\\"]\\n\\n<strong>{subloop:event:1}{event_title}{/subloop:event}</strong>\\n\\n<strong>{prog_name} Start List</strong>\\n\\n{subloop-array:entries:100} \\n    \\n<strong>{start_num}</strong>. {athlete_title}, {athlete_noc} <img src=\\\"{athlete_flag}\\\" alt=\\\"{athlete_title]\\\" />\\n\\n{/subloop-array:entries} \\n\\n[/jsoncontentimporterpro]\",\n      \"language\": \"html\"\n    }\n  ]\n}\n[/block]\nWhich outputs the following for the Elite Women at the 2017 Edmonton event.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/ddc42a4-Start_Lists__user_s_Blog_.png\",\n        \"Start_Lists_–_user_s_Blog_.png\",\n        376,\n        490,\n        \"#343a4d\"\n      ],\n      \"caption\": \"Complete start lists from the event\"\n    }\n  ]\n}\n[/block]\nHere we are using a couple of extra tags from the plugin notably the `subloop` and `subloop-array` tags to loop though all entries in the start list and nested event information. It should be noted that the `event_title` property is contained within an `event` object and hence is accessed via the `{subloop:event:1}{event_title}{/subloop:event}` tag whereas each athlete entry is contained within an `entries` array hence the tag `{subloop-array:entries:100}` which loops through each entry to output each tag and limits the number of total number of entries displayed to 100.\n[block:api-header]\n{\n  \"title\": \"Extending the example\"\n}\n[/block]\nDuring this example we have used three of the available endpoints of the Triathlon API (Event Listings, Program Listings and Program Entries). There are [many more endpoints to explore](https://developers.triathlon.org/docs/triathlon-api-overview) which could be used for example:\n\n* [Output the results for each event](https://developers.triathlon.org/docs/program-results)\n* [Display an individual athlete profile](https://developers.triathlon.org/docs/retrieve-athlete-information)\n* [Produce a multimedia gallery of latest published videos](https://developers.triathlon.org/docs/video-listings)\n* [Display detailed compiled statistics from events and athletes](https://developers.triathlon.org/docs/statistics-api-overview) \n[block:callout]\n{\n  \"type\": \"success\",\n  \"title\": \"Join us on Slack\",\n  \"body\": \"Join us on the [triathlon-developers Slack channel](http://slack.developers.triathlon.org/) to get real time support, guidance or to demonstrate your application.\"\n}\n[/block]","slug":"integrating-the-triathlon-api-with-wordpress","title":"Integrating the Triathlon API with Wordpress"}

Integrating the Triathlon API with Wordpress


Whilst the Triathlon API provides a familiar JSON output format that may be integrated directly into applications some users may be more comfortable working with the API within the confines of their existing content management systems such as [Wordpress](https://wordpress.com/). Fortunately Wordpress has a plethora of plugins to ease the process and in particular the [JSON content importer plugin](https://json-content-importer.com/) that we will focus on this article. To demonstrate the plugin in action we will be building a simple [WTS events calendar](http://www.triathlon.org/events/all#q=&hPP=15&idx=events_reverse_sort&p=0&dFR%5Bevent_categories.cat_name%5D%5B0%5D=World%20Triathlon%20Series&dFR%5Byear%5D%5B0%5D=2017&is_v=1) and displaying the start lists for each event. [block:callout] { "type": "warning", "title": "JSON content importer is available as both a free and paid version", "body": "For the purpose of the article we will use the features that are only available in the pro version of the plugin." } [/block] Assuming that Wordpress and the JSON content importer plugins have been installed, adding the following code to the template will output a list of all WTS events to be held in 2017. You will need to have a valid API key by first [registering your application](https://apps.api.triathlon.org/register) and substituting in the code below. [block:code] { "codes": [ { "code": "[jsoncontentimporterpro url=\"https://api.triathlon.org/v1/events?category_id=351&start_date=2017-01-01&end_date=2017-12-31\" numberofdisplayeditems=\"10\" header=\"apikey:your-api-key-here\" basenode=\"data\"]\n\n<strong>{event_title}</strong>\n\n[/jsoncontentimporterpro]", "language": "html" } ] } [/block] In the above code we are simply requesting a list of events from the [Event Listings method](https://developers.triathlon.org/docs/event-listings) of the API `https://api.triathlon.org/v1/events?category_id=351&start_date=2017-01-01&end_date=2017-12-31` using the params of `category_id` and `start_date` and `end_date` to choose the corresponding 2017 World Triathlon Series events. [block:image] { "images": [ { "image": [ "https://files.readme.io/3d057ab-Events_WTS__user_s_Blog_.png", "Events_WTS_–_user_s_Blog_.png", 477, 462, "#272326" ], "caption": "List of all WTS events in 2017" } ] } [/block] [block:api-header] { "title": "Plugin Settings" } [/block] Whilst we have achieved a very basic integration of the API into Wordpress in order to access more functionality and improve performance a few settings changes are required. Firstly, the cache should be enabled to prevent Wordpress from requesting data on every page load. Clearly, for the majority of cases data will not be changing rapidly and a longer cache time is preferred to ensure fast page load times. In the example below a cache time of 60 minutes has been enabled. [block:image] { "images": [ { "image": [ "https://files.readme.io/74691d5-Options__user_s_Blog___WordPress.png", "Options_‹_user_s_Blog__—_WordPress.png", 1191, 234, "#f1f1f1" ] } ] } [/block] Next, in order to generate content dynamically on the site i.e. so we can switch between events to get event specific information based on the URL we need to allow the `pathparam` setting which may be found under the "Shortcode-Attributes" section of the settings (you may leave all other settings as their default). [block:callout] { "type": "success", "title": "Ensure the setting for \"pathparam\", \"fileext\" are on to continue" } [/block] [block:api-header] { "title": "Creating the Program Listings Page" } [/block] We have the event listings and now we wish to view all programs happening at the event such that we view the start lists for each. For this the [Program Listings](https://developers.triathlon.org/docs/program-listings) method is required but we need the `event_id` from the event listing to acquire this information. Therefore we will update the previous template to pass the `event_id` as a path parameter to a program listings template. We also need to provide a `path` parameter to be explained in the next section. [block:code] { "codes": [ { "code": "[jsoncontentimporterpro url=\"https://api.triathlon.org/v1/events?category_id=351&start_date=2017-01-01&end_date=2017-12-31\" numberofdisplayeditems=\"10\" header=\"apikey:your-api-key-here\" basenode=\"data\"]\n\n<a href=\"/program-listings?event_id={event_id}&path=programs\">{event_title}</a>\n\n[/jsoncontentimporterpro]", "language": "html" } ] } [/block] Now in the template for the page program-listings we can access the `event_id` parameter and pass it to the [Programs Listings](https://developers.triathlon.org/docs/program-listings) method to output all programs happening at the event. One of the drawbacks of the plugin is that we cannot dynamically set all parts of the URL hence we must pass in additional URL parameters to construct the URL we require (in this case `path` which is set to programs). [block:code] { "codes": [ { "code": "<strong>Programs</strong>\n\n[jsoncontentimporterpro url=\"https://api.triathlon.org/v1/events\" numberofdisplayeditems=\"100\" header=\"apikey:your-api-key-here\" basenode=\"data\" pathparam=\"event_id#path\" oneofthesewordsmustnotbein=\"Officials,Medicals,Coaches\" oneofthesewordsmustnotbeindepth=\"2\"]\n\n<a href=\"/start-list/?event_id={event_id}&path=programs&prog_id={prog_id}&method=entries\">{prog_name}</a>\n\n[/jsoncontentimporterpro]", "language": "html" } ] } [/block] [block:image] { "images": [ { "image": [ "https://files.readme.io/30b9060-Program_Listings__user_s_Blog_.png", "Program_Listings_–_user_s_Blog_.png", 483, 141, "#382e35" ], "caption": "List of all programs at the event" } ] } [/block] This code will output all programs for a specific `event_id` and links to a page called start-lists which we will implement below in order to output the start lists for each program at an event. In the above code we have also used a feature of the plugin to exclude certain results from the output called `oneofthesewordsmustnotbein`. As the output of the [Program Listings](https://developers.triathlon.org/docs/program-listings) method also includes some administrative programs we want to hide those from the final output and only display the programs that we are interested in. By contrast we could also use the `oneofthesewordsmustbein` if we wanted to specifically only include certain programs. In order to generate the start lists we will use the [Program Entries method](https://developers.triathlon.org/docs/program-entries) which requires the `event_id` and `prog_id` and hence we construct our URL on the program-listings template to pass this information in the query string. [block:api-header] { "title": "Outputting the start lists" } [/block] Our final template outputs the start list for a single program at an event indicating the athlete name, country and start number. The result format of this API call is available [here](https://developers.triathlon.org/docs/program-entries) and contains additional information that is not being included in the basic output below. [block:code] { "codes": [ { "code": "[jsoncontentimporterpro url=\"https://api.triathlon.org/v1/events\" numberofdisplayeditems=\"100\" header=\"apikey:your-api-key-here\" basenode=\"data\" pathparam=\"event_id#path#prog_id#method\"]\n\n<strong>{subloop:event:1}{event_title}{/subloop:event}</strong>\n\n<strong>{prog_name} Start List</strong>\n\n{subloop-array:entries:100} \n \n<strong>{start_num}</strong>. {athlete_title}, {athlete_noc} <img src=\"{athlete_flag}\" alt=\"{athlete_title]\" />\n\n{/subloop-array:entries} \n\n[/jsoncontentimporterpro]", "language": "html" } ] } [/block] Which outputs the following for the Elite Women at the 2017 Edmonton event. [block:image] { "images": [ { "image": [ "https://files.readme.io/ddc42a4-Start_Lists__user_s_Blog_.png", "Start_Lists_–_user_s_Blog_.png", 376, 490, "#343a4d" ], "caption": "Complete start lists from the event" } ] } [/block] Here we are using a couple of extra tags from the plugin notably the `subloop` and `subloop-array` tags to loop though all entries in the start list and nested event information. It should be noted that the `event_title` property is contained within an `event` object and hence is accessed via the `{subloop:event:1}{event_title}{/subloop:event}` tag whereas each athlete entry is contained within an `entries` array hence the tag `{subloop-array:entries:100}` which loops through each entry to output each tag and limits the number of total number of entries displayed to 100. [block:api-header] { "title": "Extending the example" } [/block] During this example we have used three of the available endpoints of the Triathlon API (Event Listings, Program Listings and Program Entries). There are [many more endpoints to explore](https://developers.triathlon.org/docs/triathlon-api-overview) which could be used for example: * [Output the results for each event](https://developers.triathlon.org/docs/program-results) * [Display an individual athlete profile](https://developers.triathlon.org/docs/retrieve-athlete-information) * [Produce a multimedia gallery of latest published videos](https://developers.triathlon.org/docs/video-listings) * [Display detailed compiled statistics from events and athletes](https://developers.triathlon.org/docs/statistics-api-overview) [block:callout] { "type": "success", "title": "Join us on Slack", "body": "Join us on the [triathlon-developers Slack channel](http://slack.developers.triathlon.org/) to get real time support, guidance or to demonstrate your application." } [/block]