{"category":{"version":"58810495d172b61b00d73859","project":"542fe92a5eceb608003fddc8","_id":"58810495d172b61b00d7385f","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-11-04T19:48:37.185Z","from_sync":false,"order":5,"slug":"cookbook","title":"Cookbook"},"parentDoc":null,"project":"542fe92a5eceb608003fddc8","user":"542c5cfcddd3190e00228849","version":{"__v":1,"_id":"58810495d172b61b00d73859","project":"542fe92a5eceb608003fddc8","createdAt":"2017-01-19T18:25:25.206Z","releaseDate":"2017-01-19T18:25:25.206Z","categories":["58810495d172b61b00d7385a","58810495d172b61b00d7385b","58810495d172b61b00d7385c","58810495d172b61b00d7385d","58810495d172b61b00d7385e","58810495d172b61b00d7385f"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"0.11.4","version":"0.11.4"},"_id":"58810495d172b61b00d7386d","__v":0,"updates":[],"next":{"pages":[],"description":""},"createdAt":"2015-11-04T19:50:08.801Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":55,"body":"[block:callout]\n{\n  \"type\": \"warning\",\n  \"title\": \"Beta Feature\",\n  \"body\": \"This recipe uses the `ghost.url.api()` JavaScript utility, which is currently a Beta feature and should be not be used in production. For more information on what Beta means, see http://support.ghost.org/public-api-beta\\n\\nTo enable this feature, visit `yourblog.com/ghost/settings/labs/` and tick the 'Public API' checkbox.\"\n}\n[/block]\nIt is now possible to query the public Ghost API to fetch collections of **posts**, **users** or **tags** that match certain criteria. The  [API documentation](http://api.ghost.org/), covers the full range of what is possible with the Ghost JSON API. \n\nThis recipe shows you step by step how to get started using the API via AJAX to fetch and display all of the tags for your blog, using the new `ghost.url.api()` utility, which makes it possible to build URLs for making API requests.\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"1. Check the requirements\"\n}\n[/block]\nFirstly, you must have the [{{ghost_head}} helper](doc:ghost_head) in your theme, otherwise you will not get access to the `ghost.url.api()` utility. The best place to do this is in the `default.hbs` file.\n\nExample snippet from default Casper theme:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<!DOCTYPE html>\\n<html>\\n<head>\\n    {{! Document Settings }}\\n    <meta charset=\\\"utf-8\\\" />\\n    <meta http-equiv=\\\"X-UA-Compatible\\\" content=\\\"IE=edge\\\" />\\n\\n    {{! Page Meta }}\\n    <title>{{meta_title}}</title>\\n...\\n    {{! Ghost outputs important style and meta data with this tag }}\\n    {{ghost_head}}\\n</head>\",\n      \"language\": \"handlebars\"\n    }\n  ]\n}\n[/block]\nSecondly, you must have enabled the 'Public API' setting in your admin panel. To do this, choose 'labs' from the left hand menu, scroll down, and hit the 'Public API' checkbox.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/dH6WgFvmTWGB9mcct7Uz_Screen+Shot+2015-11-27+at+17.35.57.png\",\n        \"Screen+Shot+2015-11-27+at+17.35.57.png\",\n        \"1086\",\n        \"230\",\n        \"#963a19\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"2. Get your theme ready\"\n}\n[/block]\nNext, you'll need to figure out where you want the data from your ajax request to be output and have some way to reference this location. There are far more elegant ways, but for this example we'll use an empty element with an ID.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<aside>\\n  <h3>Tag list</h3>\\n  <ol id=\\\"tag-list\\\"></ol>\\n</aside> \",\n      \"language\": \"html\"\n    }\n  ]\n}\n[/block]\nThe final setup task is ensuring you have jQuery available in your theme. If you don't have jQuery included via the `{{ghost_foot}}` box in the code injection screen in your admin panel, then you'll need to add it to your `default.hbs` so that the bottom of the file looks a bit like this:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"...\\n  <script type=\\\"text/javascript\\\" src=\\\"https://code.jquery.com/jquery-1.11.3.min.js\\\"></script>\\n  {{ghost_foot}}\\n...\\n</body>\\n</html>\",\n      \"language\": \"html\",\n      \"name\": \"default.hbs\"\n    }\n  ]\n}\n[/block]\nNow that all of these pieces are in place, you can make an ajax request using ghost.url.api along with your query.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"3. Adding your Ajax script\"\n}\n[/block]\nBack in `default.hbs`, add a script tag, beneath your `{{ghost_foot}}` helper and any other scripts you need (like jQuery).\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{{ghost_foot}}\\n<script type=\\\"text/javascript\\\">\\n // your script goes here...\\n</script>\",\n      \"language\": \"html\",\n      \"name\": \"default.hbs\"\n    }\n  ]\n}\n[/block]\nNext, lets build our query URL. We want to fetch all tags, including how many posts there are that has that tag. We also want to order the results so that the tag with the most posts comes first.\n\nSo, we want a URL that queries the **tags** endpoint and that sets the **limit** to 'all'. Then we want to tell it to **include** the field `count.posts`, and finally to **order** the query by `count.posts DESC`. \n\nPutting all this together using the [ghost.url.api()](doc:ghost-url-api) utility, we end up with URL building code that looks like this:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"ghost.url.api('tags', {\\n  limit: 'all', \\n  include: 'count.posts', \\n  order: 'count.posts DESC'\\n});\",\n      \"language\": \"javascript\"\n    },\n    {\n      \"code\": \"<protocol>://<host>/ghost/api/<version>/tags/?limit=all&include=count.posts&order=count.posts%20DESC&client_id=<client_id>&client_secret=<client_secret>\",\n      \"language\": \"text\",\n      \"name\": \"URL\"\n    }\n  ]\n}\n[/block]\nAll of these query parameters are explained in the [API documentation](http://api.ghost.org/docs/parameters).\n\nIf you click the 'URL' tab above the previous code example, you'll see that the output from `ghost.url.api` is the URL we need to query. Using jQuery, performing a 'GET' HTTP request via Ajax is super simple using the `$.get()` convenience method. We just have to pass our URL to `$.get()` and tell it what we want to do with the data when we're done:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"$.get(\\n  ghost.url.api('tags', {\\n    limit: 'all', \\n    include: 'count.posts', \\n    order: 'count.posts DESC'\\n  }).done(function (data) {\\n    console.log('Success!', data);\\n  });\\n);\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nHowever, to get this to work correctly, we'll need to wrap this function in jQuery's `document.ready` function:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"jQuery(document).ready(function () {\\n  $.get(\\n    ghost.url.api('tags', {\\n      limit: 'all', \\n      include: 'count.posts', \\n      order: 'count.posts DESC'\\n    })\\n  ).done(function (data) {\\n    console.log('Success!', data);\\n  });\\n});\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nAdding this to your `default.hbs` should now result in a working query, which outputs 'Success!' and the data that has been fetched into the browser's console.\n\nNow let's do something more useful with the data...\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"4. Processing the data\"\n}\n[/block]\nFirst of all, rather than handling our data inline, let's quickly create a separate named function to make this easier to read:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"function onSuccess(data) {\\n  console.log('Success!', data);\\n}  \\n\\njQuery(document).ready(function () {\\n  $.get(\\n    ghost.url.api('tags', {\\n      limit: 'all', \\n      include: 'count.posts', \\n      order: 'count.posts DESC'\\n    })\\n  ).done(onSuccess);\\n});\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nNow, all we have to do is update our `onSuccess` method so that it does something useful. To start with, lets grab our empty element that we setup earlier with `var $result = $('#tag-list');`\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"function onSuccess(data) {\\n  var $result = $('#tag-list');\\n}  \",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nThe data we get back from the [API](http://api.ghost.org/docs/tags) is a JSON object with a key which matches the resource we requested. So in our case, we need to iterate over `data.tags`.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"function onSuccess(data) {\\n  var $result = $('#tag-list');\\n  $.each(data.tags, function (i, tag) {\\n    // do something with each tag\\n  });\\n}  \",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nFinally, we're going to append the HTML for a list item and an anchor which points to the tag page for this particular tag.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"function onSuccess(data) {\\n  var $result = $('#tag-list');\\n  $.each(data.tags, function (i, tag) {\\n    $result.append(\\n      '<li><a href=\\\"/tag/' + tag.slug + '/\\\">' + tag.name + '</a></li>'\\n    );\\n  });\\n}  \",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nYou can find out more about the data you have available to you in the [API docs for tags](http://api.ghost.org/docs/tags).\n\n**Note:** For the time being, you need to manually construct the urls for blog pages like the tag or author page. Posts get their URL returned with them. The intention is to extend `ghost.url` to also allow for building other URLs in the near future.","excerpt":"Making ajax requests to the Ghost API inside your theme","slug":"ghost-api-ajax","type":"basic","title":"Ghost API via Ajax: Fetching tags"}

Ghost API via Ajax: Fetching tags

Making ajax requests to the Ghost API inside your theme

[block:callout] { "type": "warning", "title": "Beta Feature", "body": "This recipe uses the `ghost.url.api()` JavaScript utility, which is currently a Beta feature and should be not be used in production. For more information on what Beta means, see http://support.ghost.org/public-api-beta\n\nTo enable this feature, visit `yourblog.com/ghost/settings/labs/` and tick the 'Public API' checkbox." } [/block] It is now possible to query the public Ghost API to fetch collections of **posts**, **users** or **tags** that match certain criteria. The [API documentation](http://api.ghost.org/), covers the full range of what is possible with the Ghost JSON API. This recipe shows you step by step how to get started using the API via AJAX to fetch and display all of the tags for your blog, using the new `ghost.url.api()` utility, which makes it possible to build URLs for making API requests. [block:api-header] { "type": "basic", "title": "1. Check the requirements" } [/block] Firstly, you must have the [{{ghost_head}} helper](doc:ghost_head) in your theme, otherwise you will not get access to the `ghost.url.api()` utility. The best place to do this is in the `default.hbs` file. Example snippet from default Casper theme: [block:code] { "codes": [ { "code": "<!DOCTYPE html>\n<html>\n<head>\n {{! Document Settings }}\n <meta charset=\"utf-8\" />\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n\n {{! Page Meta }}\n <title>{{meta_title}}</title>\n...\n {{! Ghost outputs important style and meta data with this tag }}\n {{ghost_head}}\n</head>", "language": "handlebars" } ] } [/block] Secondly, you must have enabled the 'Public API' setting in your admin panel. To do this, choose 'labs' from the left hand menu, scroll down, and hit the 'Public API' checkbox. [block:image] { "images": [ { "image": [ "https://files.readme.io/dH6WgFvmTWGB9mcct7Uz_Screen+Shot+2015-11-27+at+17.35.57.png", "Screen+Shot+2015-11-27+at+17.35.57.png", "1086", "230", "#963a19", "" ] } ] } [/block] [block:api-header] { "type": "basic", "title": "2. Get your theme ready" } [/block] Next, you'll need to figure out where you want the data from your ajax request to be output and have some way to reference this location. There are far more elegant ways, but for this example we'll use an empty element with an ID. [block:code] { "codes": [ { "code": "<aside>\n <h3>Tag list</h3>\n <ol id=\"tag-list\"></ol>\n</aside> ", "language": "html" } ] } [/block] The final setup task is ensuring you have jQuery available in your theme. If you don't have jQuery included via the `{{ghost_foot}}` box in the code injection screen in your admin panel, then you'll need to add it to your `default.hbs` so that the bottom of the file looks a bit like this: [block:code] { "codes": [ { "code": "...\n <script type=\"text/javascript\" src=\"https://code.jquery.com/jquery-1.11.3.min.js\"></script>\n {{ghost_foot}}\n...\n</body>\n</html>", "language": "html", "name": "default.hbs" } ] } [/block] Now that all of these pieces are in place, you can make an ajax request using ghost.url.api along with your query. [block:api-header] { "type": "basic", "title": "3. Adding your Ajax script" } [/block] Back in `default.hbs`, add a script tag, beneath your `{{ghost_foot}}` helper and any other scripts you need (like jQuery). [block:code] { "codes": [ { "code": "{{ghost_foot}}\n<script type=\"text/javascript\">\n // your script goes here...\n</script>", "language": "html", "name": "default.hbs" } ] } [/block] Next, lets build our query URL. We want to fetch all tags, including how many posts there are that has that tag. We also want to order the results so that the tag with the most posts comes first. So, we want a URL that queries the **tags** endpoint and that sets the **limit** to 'all'. Then we want to tell it to **include** the field `count.posts`, and finally to **order** the query by `count.posts DESC`. Putting all this together using the [ghost.url.api()](doc:ghost-url-api) utility, we end up with URL building code that looks like this: [block:code] { "codes": [ { "code": "ghost.url.api('tags', {\n limit: 'all', \n include: 'count.posts', \n order: 'count.posts DESC'\n});", "language": "javascript" }, { "code": "<protocol>://<host>/ghost/api/<version>/tags/?limit=all&include=count.posts&order=count.posts%20DESC&client_id=<client_id>&client_secret=<client_secret>", "language": "text", "name": "URL" } ] } [/block] All of these query parameters are explained in the [API documentation](http://api.ghost.org/docs/parameters). If you click the 'URL' tab above the previous code example, you'll see that the output from `ghost.url.api` is the URL we need to query. Using jQuery, performing a 'GET' HTTP request via Ajax is super simple using the `$.get()` convenience method. We just have to pass our URL to `$.get()` and tell it what we want to do with the data when we're done: [block:code] { "codes": [ { "code": "$.get(\n ghost.url.api('tags', {\n limit: 'all', \n include: 'count.posts', \n order: 'count.posts DESC'\n }).done(function (data) {\n console.log('Success!', data);\n });\n);", "language": "javascript" } ] } [/block] However, to get this to work correctly, we'll need to wrap this function in jQuery's `document.ready` function: [block:code] { "codes": [ { "code": "jQuery(document).ready(function () {\n $.get(\n ghost.url.api('tags', {\n limit: 'all', \n include: 'count.posts', \n order: 'count.posts DESC'\n })\n ).done(function (data) {\n console.log('Success!', data);\n });\n});", "language": "javascript" } ] } [/block] Adding this to your `default.hbs` should now result in a working query, which outputs 'Success!' and the data that has been fetched into the browser's console. Now let's do something more useful with the data... [block:api-header] { "type": "basic", "title": "4. Processing the data" } [/block] First of all, rather than handling our data inline, let's quickly create a separate named function to make this easier to read: [block:code] { "codes": [ { "code": "function onSuccess(data) {\n console.log('Success!', data);\n} \n\njQuery(document).ready(function () {\n $.get(\n ghost.url.api('tags', {\n limit: 'all', \n include: 'count.posts', \n order: 'count.posts DESC'\n })\n ).done(onSuccess);\n});", "language": "javascript" } ] } [/block] Now, all we have to do is update our `onSuccess` method so that it does something useful. To start with, lets grab our empty element that we setup earlier with `var $result = $('#tag-list');` [block:code] { "codes": [ { "code": "function onSuccess(data) {\n var $result = $('#tag-list');\n} ", "language": "javascript" } ] } [/block] The data we get back from the [API](http://api.ghost.org/docs/tags) is a JSON object with a key which matches the resource we requested. So in our case, we need to iterate over `data.tags`. [block:code] { "codes": [ { "code": "function onSuccess(data) {\n var $result = $('#tag-list');\n $.each(data.tags, function (i, tag) {\n // do something with each tag\n });\n} ", "language": "javascript" } ] } [/block] Finally, we're going to append the HTML for a list item and an anchor which points to the tag page for this particular tag. [block:code] { "codes": [ { "code": "function onSuccess(data) {\n var $result = $('#tag-list');\n $.each(data.tags, function (i, tag) {\n $result.append(\n '<li><a href=\"/tag/' + tag.slug + '/\">' + tag.name + '</a></li>'\n );\n });\n} ", "language": "javascript" } ] } [/block] You can find out more about the data you have available to you in the [API docs for tags](http://api.ghost.org/docs/tags). **Note:** For the time being, you need to manually construct the urls for blog pages like the tag or author page. Posts get their URL returned with them. The intention is to extend `ghost.url` to also allow for building other URLs in the near future.