Adobe Robohelp

Get new posts delivered straight to your inbox.

Subscriber count: 3,220

Adobe Robohelp

Pushing content into any format with Jekyll

Mar 6, 2015 • general

In the previous post, I talked about help APIs as a way to deliver help inside applications. In this post, I'll explain how to push your help content into any format.

Pushing content into other formats using Jekyll and for loops
Pushing content into other formats using Jekyll and for loops

Let's say that you have three different channels where you want to push your help content. Channel one is an S3 bucket in Amazon Web Services (requiring HTML), channel two is a Salesforce Knowledge center (requiring CSV), and channel three is your help API (requiring JSON).

Jekyll (and probably a lot of static site generators) provide an amazing capability here. With most help authoring tools, you see a list of outputs (e.g., PDF, HTML, Eclipse Help, etc.), and you're pretty much limited to those outputs. Jekyll, however, allows you to define the templates and format that your content is pushed into.

Let's remember the three different format channels for this scenario:
- For channel 1 (S3), the content needs to be in HTML.
- For channel 2 (Salesforce), the content needs to be in CSV (for batch import into Knowledge).
- For channel 3 (API), the content needs to be in JSON.

Pushing content into HTML

Since HTML is the main publishing use case, most of Jekyll is structured around facilitating this template. You author content in a Markdown or HTML page. At the top of this page, you specify the layout you want in the frontmatter, like this:

---
layout: page
title: My Page
permalink: /mypage/
---

Jekyll will take all the content in this page and stuff it inside the

Adobe Robohelp

How to create a help API

Mar 4, 2015 • general

In my last post in this series, I talked about static site generators as a platform for help. In this post, I want to explore Help APIs, which is actually something in part enabled by static site generators.

To put things in context, the web is sort of a giant API. Each browser functions as a client that accesses various resources from servers.

You may be viewing this post on my site. In this case, you used a client (a browser such as Chrome) and entered a URL (such as http://idratherbewriting.com/2015/03/04/how-to-create-a-help-api/) to make a request, and you got back a response (all the content on the page).

This cartoon from XKCD sums it up well:
A website is just an API

Alternatively, you may be using a Feedreader, such as Inoreader. The feedreader makes a request to the server, gets a response, and shows the requested resource to you.

Changing paradigms for how we deliver help

The idea of me sending you a copy of this post as an attachment to an email is absurd -- and yet this is the same paradigm we sometimes have with help. We send developers help files to integrate into applications. We send users help files with products.

Here's an idea: we could just put help resources on our server and give developers an "endpoint" to access the site content.

Help API

Using the endpoint, developers could pull the help directly into the application. In fact, in some cases with small help files, you might not need a help site at all. You can just have a Help API that applications can call in order to get the information they need.

With larger projects, though, I doubt you can get away from having a dedicated help site. Still, there's a strong need to pull help into the user's context in an application.

The most common example: Tooltips

As probably the most common use case, let's say you want to add popovers/tooltips next to confusing fields. The developer can merely call the Help API for information related to that field. If you want to add a quick start tutorial, the developer can add a getting-started page in an application and call a Help API endpoint for the right information to populate that modal. And so on.

For a quick demo of how this might work, see the Tooltip Demo here.

Tooltip Demo

By using a Help API, you can more fully integrate the help information into the application in all the right places where it should appear -- giving the user the right information at the right time in the right place.

Users generally dislike leaving the context of their work and going to another site, browsing through the external help site to find the right information. Few people actually consult the help, and even if people do go to the help site, finding the topic may be difficult.

But even if they find the topic, by now the user is so disconnected with the actual application and context of the problem that the help feels disconnected. Sure, the help may provide some screenshots, and in some scenarios, a video. But it's not quite the same as being in the context of the application where you encountered the problem, and where you must apply the knowledge to solve the problem.

Imagine how much better help would be if help appeared right in the place where you needed it, exactly when you needed it.

How to create a help API

I put the information for creating a help API using Jekyll as a platform here: Create a Help API.

Basically, you create a JSON file that loops through your tooltip content. Then you put it into a domain with cross-origin-resource-sharing (CORS) enabled.


Get new posts delivered straight to your inbox.

Subscriber count: 3,220

About Tom Johnson

Tom Johnson

I'm a technical writer based in the California San Francisco Bay area. Topics I write about on this blog include technical writing, authoring and publishing tools, API documentation, tech comm trends, visual communication, technical writing career advice, information architecture and findability, developer documentation, and more. If you're a professional or aspiring technical writer, be sure to subscribe to email updates using the form above. You can learn more about me here.

tag in the layout you specified (page.html). Page.html also usually has a layout defined (default.html), so Jekyll takes all the content stuffed into the page.html layout and stuffs it into the
Adobe Robohelp

How to create a help API

Mar 4, 2015 • general

In my last post in this series, I talked about static site generators as a platform for help. In this post, I want to explore Help APIs, which is actually something in part enabled by static site generators.

To put things in context, the web is sort of a giant API. Each browser functions as a client that accesses various resources from servers.

You may be viewing this post on my site. In this case, you used a client (a browser such as Chrome) and entered a URL (such as http://idratherbewriting.com/2015/03/04/how-to-create-a-help-api/) to make a request, and you got back a response (all the content on the page).

This cartoon from XKCD sums it up well:
A website is just an API

Alternatively, you may be using a Feedreader, such as Inoreader. The feedreader makes a request to the server, gets a response, and shows the requested resource to you.

Changing paradigms for how we deliver help

The idea of me sending you a copy of this post as an attachment to an email is absurd -- and yet this is the same paradigm we sometimes have with help. We send developers help files to integrate into applications. We send users help files with products.

Here's an idea: we could just put help resources on our server and give developers an "endpoint" to access the site content.

Help API

Using the endpoint, developers could pull the help directly into the application. In fact, in some cases with small help files, you might not need a help site at all. You can just have a Help API that applications can call in order to get the information they need.

With larger projects, though, I doubt you can get away from having a dedicated help site. Still, there's a strong need to pull help into the user's context in an application.

The most common example: Tooltips

As probably the most common use case, let's say you want to add popovers/tooltips next to confusing fields. The developer can merely call the Help API for information related to that field. If you want to add a quick start tutorial, the developer can add a getting-started page in an application and call a Help API endpoint for the right information to populate that modal. And so on.

For a quick demo of how this might work, see the Tooltip Demo here.

Tooltip Demo

By using a Help API, you can more fully integrate the help information into the application in all the right places where it should appear -- giving the user the right information at the right time in the right place.

Users generally dislike leaving the context of their work and going to another site, browsing through the external help site to find the right information. Few people actually consult the help, and even if people do go to the help site, finding the topic may be difficult.

But even if they find the topic, by now the user is so disconnected with the actual application and context of the problem that the help feels disconnected. Sure, the help may provide some screenshots, and in some scenarios, a video. But it's not quite the same as being in the context of the application where you encountered the problem, and where you must apply the knowledge to solve the problem.

Imagine how much better help would be if help appeared right in the place where you needed it, exactly when you needed it.

How to create a help API

I put the information for creating a help API using Jekyll as a platform here: Create a Help API.

Basically, you create a JSON file that loops through your tooltip content. Then you put it into a domain with cross-origin-resource-sharing (CORS) enabled.


Get new posts delivered straight to your inbox.

Subscriber count: 3,220

About Tom Johnson

Tom Johnson

I'm a technical writer based in the California San Francisco Bay area. Topics I write about on this blog include technical writing, authoring and publishing tools, API documentation, tech comm trends, visual communication, technical writing career advice, information architecture and findability, developer documentation, and more. If you're a professional or aspiring technical writer, be sure to subscribe to email updates using the form above. You can learn more about me here.

tag on the default.html page.

(You could just specify your layout as default from the beginning, but you might have various HTML layouts, such as a layout for pages, posts, and specific content types (such as API doc), which all plug into default.html.)

Pushing content into JSON

Now let's move to the JSON use case. Rather than stuffing content into

Adobe Robohelp

How to create a help API

Mar 4, 2015 • general

In my last post in this series, I talked about static site generators as a platform for help. In this post, I want to explore Help APIs, which is actually something in part enabled by static site generators.

To put things in context, the web is sort of a giant API. Each browser functions as a client that accesses various resources from servers.

You may be viewing this post on my site. In this case, you used a client (a browser such as Chrome) and entered a URL (such as http://idratherbewriting.com/2015/03/04/how-to-create-a-help-api/) to make a request, and you got back a response (all the content on the page).

This cartoon from XKCD sums it up well:
A website is just an API

Alternatively, you may be using a Feedreader, such as Inoreader. The feedreader makes a request to the server, gets a response, and shows the requested resource to you.

Changing paradigms for how we deliver help

The idea of me sending you a copy of this post as an attachment to an email is absurd -- and yet this is the same paradigm we sometimes have with help. We send developers help files to integrate into applications. We send users help files with products.

Here's an idea: we could just put help resources on our server and give developers an "endpoint" to access the site content.

Help API

Using the endpoint, developers could pull the help directly into the application. In fact, in some cases with small help files, you might not need a help site at all. You can just have a Help API that applications can call in order to get the information they need.

With larger projects, though, I doubt you can get away from having a dedicated help site. Still, there's a strong need to pull help into the user's context in an application.

The most common example: Tooltips

As probably the most common use case, let's say you want to add popovers/tooltips next to confusing fields. The developer can merely call the Help API for information related to that field. If you want to add a quick start tutorial, the developer can add a getting-started page in an application and call a Help API endpoint for the right information to populate that modal. And so on.

For a quick demo of how this might work, see the Tooltip Demo here.

Tooltip Demo

By using a Help API, you can more fully integrate the help information into the application in all the right places where it should appear -- giving the user the right information at the right time in the right place.

Users generally dislike leaving the context of their work and going to another site, browsing through the external help site to find the right information. Few people actually consult the help, and even if people do go to the help site, finding the topic may be difficult.

But even if they find the topic, by now the user is so disconnected with the actual application and context of the problem that the help feels disconnected. Sure, the help may provide some screenshots, and in some scenarios, a video. But it's not quite the same as being in the context of the application where you encountered the problem, and where you must apply the knowledge to solve the problem.

Imagine how much better help would be if help appeared right in the place where you needed it, exactly when you needed it.

How to create a help API

I put the information for creating a help API using Jekyll as a platform here: Create a Help API.

Basically, you create a JSON file that loops through your tooltip content. Then you put it into a domain with cross-origin-resource-sharing (CORS) enabled.


Get new posts delivered straight to your inbox.

Subscriber count: 3,220

About Tom Johnson

Tom Johnson

I'm a technical writer based in the California San Francisco Bay area. Topics I write about on this blog include technical writing, authoring and publishing tools, API documentation, tech comm trends, visual communication, technical writing career advice, information architecture and findability, developer documentation, and more. If you're a professional or aspiring technical writer, be sure to subscribe to email updates using the form above. You can learn more about me here.

tags, you create a file that looks like this:
---
layout: none
search: exclude
---
{
    "entries": 
[
    
]
}

"tooltips" is the name of a collection I created inside Jekyll. This code has the basic structure of the JSON that I want, but you'll notice some placeholders. A for loop iterates through all the pages inside the tooltips collection and, with each page, the page's id gets inserted into the /2015/03/06/pushing-content-into-any-format-with-jekyll placeholder, and the page content gets inserted into the {% include series/seriesTagInnovation.html %}

In the previous post, I talked about help APIs as a way to deliver help inside applications. In this post, I'll explain how to push your help content into any format.

Pushing content into other formats using Jekyll and for loops
Pushing content into other formats using Jekyll and for loops

Let's say that you have three different channels where you want to push your help content. Channel one is an S3 bucket in Amazon Web Services (requiring HTML), channel two is a Salesforce Knowledge center (requiring CSV), and channel three is your help API (requiring JSON).

Jekyll (and probably a lot of static site generators) provide an amazing capability here. With most help authoring tools, you see a list of outputs (e.g., PDF, HTML, Eclipse Help, etc.), and you're pretty much limited to those outputs. Jekyll, however, allows you to define the templates and format that your content is pushed into.

Let's remember the three different format channels for this scenario:
- For channel 1 (S3), the content needs to be in HTML.
- For channel 2 (Salesforce), the content needs to be in CSV (for batch import into Knowledge).
- For channel 3 (API), the content needs to be in JSON.

Pushing content into HTML

Since HTML is the main publishing use case, most of Jekyll is structured around facilitating this template. You author content in a Markdown or HTML page. At the top of this page, you specify the layout you want in the frontmatter, like this:

---
layout: page
title: My Page
permalink: /mypage/
---

Jekyll will take all the content in this page and stuff it inside the {{content}} tag in the layout you specified (page.html). Page.html also usually has a layout defined (default.html), so Jekyll takes all the content stuffed into the page.html layout and stuffs it into the {{content}} tag on the default.html page.

(You could just specify your layout as default from the beginning, but you might have various HTML layouts, such as a layout for pages, posts, and specific content types (such as API doc), which all plug into default.html.)

Pushing content into JSON

Now let's move to the JSON use case. Rather than stuffing content into {{content}} tags, you create a file that looks like this:

---
layout: none
search: exclude
---
{
    "entries": 
[
    {% for page in site.tooltips %}
    {
      "id"    : "{{ page.id }}",
      "body": "{{ page.content | strip_newlines | replace: '', '' | replace: '"', '"' }}"
    } {% unless forloop.last %},{% endunless %}
  {% endfor %}
]
}

"tooltips" is the name of a collection I created inside Jekyll. This code has the basic structure of the JSON that I want, but you'll notice some placeholders. A for loop iterates through all the pages inside the tooltips collection and, with each page, the page's id gets inserted into the {{page.id}} placeholder, and the page content gets inserted into the {{page.content}} placeholder.

Assuming our pages were short descriptions of sports, here's what the result might look like:

{
"entries": [
{
"id": "baseball",
"body": "Baseball is considered America's past-time sport, though that may be more of a historical term than a current one. There's a lot more excitement about football than baseball. A baseball game is somewhat of a snooze to watch, for the most part."
},
{
"id": "basketball",
"body": "Basketball is a sport involving two teams of five players each competing to put a ball through a small circular rim 10 feet above the ground. Basketball requires players to be in top physical condition, since they spend most of the game running back and forth along a 94-foot-long floor."
},
{
"id": "football",
"body": "No doubt the most fun sport to watch, football also manages to accrue the most injuries with the players. From concussions to blown knees, football players have short sport lives."
},
{
"id": "soccer",
"body": "If there's one sport that dominates the world landscape, it's soccer. However, US soccer fans are few and far between. Apart from the popularity of soccer during the World Cup, most people don't even know the name of the professional soccer organization in their area."
}
]
}

Pushing content into CSV

CSV requires a different format from either HTML or JSON. And admittedly, here's where things get a little theoretical because I haven't actually tested this.

Here's a typical CSV format that I just pulled off the web:

policyID,statecode,county,eq_site_limit,hu_site_limit,fl_sit
e_limit,fr_site_limit,tiv_2011,tiv_2012,eq_site_deductible,hu_site_deductible,fl_site_deductible,fr_site_deductible,point_latitude,point_longitude,line,construction,point_granularity
119736,FL,CLAY COUNTY,498960,498960,498960,498960,498960,792148.9,0,9979.2,0,0,30.102261,-81.711777,Residential,Masonry,1 
448094,FL,CLAY COUNTY,1322376.3,1322376.3,1322376.3,1322376.3,1322376.3,1438163.57,0,0,0,0,30.063936,-81.707664,Residential,Masonry,3

You have a top row of comma-separated values, and then data in rows below that following the same pattern. Commas separate each value.

In Jekyll, you would first make sure your pages had all the frontmatter tags corresponding each of these CSV headers. Here's what one page might look like:

---
policyID:119736
statecode:FL
county: CLAY COUNTY
eq_site_limit: 48960
hu_site_limit: 498960
fl_sit: 498960
e_limit: 498960
fr_site_limit: 498960
tiv_2011: 498960
tiv_2012: 792148.9
eq_site_deductible: 0
hu_site_deductible: 9979.2
fl_site_deductible: 0 
fr_site_deductible:0
point_latitude: 30.102261
point_longitude: -81.707664
line: Residential
construction: Masonry
point_granularity: 3
---

You then create a file with a .csv extension, such as data.csv. In this file, you add some basic frontmatter at the top so that Jekyll processes the file as a page. And then you iterate through each of the pages using a for loop and stuff the data into your CSV template.

I'll pretend that I've created a collection here called "policies," and that each of my pages exists inside _policies.

---
layout: none
search: exclude
---
policyID,statecode,county,eq_site_limit,hu_site_limit,fl_sit
e_limit,fr_site_limit,tiv_2011,tiv_2012,eq_site_deductible,hu_site_deductible,fl_site_deductible,fr_site_deductible,point_latitude,point_longitude,line,construction,point_granularity
{% for page in site.policies %}
{{page.policyID}},{{page.statecode}},{{page.county}},{{page.eq_site_limit}},{{page.hu_site_limit}},{{page.fr_site_limit}},{{page.tiv_2011}},{{page.tiv_2012}},{{page.eq_site_deductible}},{{page.hu_site_deductible}},{{page.fl_site_deductible}},{{page.fr_site_deductible}},{{page.point_latitude}},{{page.point_longitude}},{{page.line}},{{page.construction}},{{page.point_granularity}}
{% endfor %}

See how you access content in the frontmatter using the page namespace? page.policyID gets the value for the policyID in the frontmatter, and so on. The for loop would go through each of the pages and construct a new row of comma-separated values until it reached the end of the pages in the policies collection.

When you build your Jekyll site, Jekyll will recognize the data.csv file as needing to be processed because of the frontmatter tags. You will find a fully populated data.csv file in your build folder.

Not bound by format

Because of this flexibility in constructing templates to stuff content into, you're not bound by a specific format, for the most part. You create your content, decide on the template, and then Jekyll shoves the content inside the template. The template could be HTML, JSON, CSV, or something else. This way you can author content in a way that is separate from format. (You could equally create a template that stuffs this same arcane policy information content into a JSON file, for example.)

No doubt many tools do a similar kind of thing on the backend. I just never really understood what was happening when I selected a certain output. Jekyll exposes this processing in a clear and simple way. Now your content can travel into any number of systems in a seamless way.

There is at least one limitation with the formats, though. You can't really create a DITA template and push the content into a DITA format except maybe in the most general way, with body including just HTML. This is because DITA has some very specific structures, and this simplistic template method won't really wrap lists inside task elements, convert links inside pages into xrefs, enforce element order, and so forth.

Other more sophisticated formats might have similar restrictions. However, my point is that Jekyll allows you to separate out your content from the template (presentation), and this is a huge deal when it comes to processing and displaying information.

{% include series/seriesTagInnovation_next.html %}
placeholder.

Assuming our pages were short descriptions of sports, here's what the result might look like:

{
"entries": [
{
"id": "baseball",
"body": "Baseball is considered America's past-time sport, though that may be more of a historical term than a current one. There's a lot more excitement about football than baseball. A baseball game is somewhat of a snooze to watch, for the most part."
},
{
"id": "basketball",
"body": "Basketball is a sport involving two teams of five players each competing to put a ball through a small circular rim 10 feet above the ground. Basketball requires players to be in top physical condition, since they spend most of the game running back and forth along a 94-foot-long floor."
},
{
"id": "football",
"body": "No doubt the most fun sport to watch, football also manages to accrue the most injuries with the players. From concussions to blown knees, football players have short sport lives."
},
{
"id": "soccer",
"body": "If there's one sport that dominates the world landscape, it's soccer. However, US soccer fans are few and far between. Apart from the popularity of soccer during the World Cup, most people don't even know the name of the professional soccer organization in their area."
}
]
}

Pushing content into CSV

CSV requires a different format from either HTML or JSON. And admittedly, here's where things get a little theoretical because I haven't actually tested this.

Here's a typical CSV format that I just pulled off the web:

policyID,statecode,county,eq_site_limit,hu_site_limit,fl_sit
e_limit,fr_site_limit,tiv_2011,tiv_2012,eq_site_deductible,hu_site_deductible,fl_site_deductible,fr_site_deductible,point_latitude,point_longitude,line,construction,point_granularity
119736,FL,CLAY COUNTY,498960,498960,498960,498960,498960,792148.9,0,9979.2,0,0,30.102261,-81.711777,Residential,Masonry,1 
448094,FL,CLAY COUNTY,1322376.3,1322376.3,1322376.3,1322376.3,1322376.3,1438163.57,0,0,0,0,30.063936,-81.707664,Residential,Masonry,3

You have a top row of comma-separated values, and then data in rows below that following the same pattern. Commas separate each value.

In Jekyll, you would first make sure your pages had all the frontmatter tags corresponding each of these CSV headers. Here's what one page might look like:

---
policyID:119736
statecode:FL
county: CLAY COUNTY
eq_site_limit: 48960
hu_site_limit: 498960
fl_sit: 498960
e_limit: 498960
fr_site_limit: 498960
tiv_2011: 498960
tiv_2012: 792148.9
eq_site_deductible: 0
hu_site_deductible: 9979.2
fl_site_deductible: 0 
fr_site_deductible:0
point_latitude: 30.102261
point_longitude: -81.707664
line: Residential
construction: Masonry
point_granularity: 3
---

You then create a file with a .csv extension, such as data.csv. In this file, you add some basic frontmatter at the top so that Jekyll processes the file as a page. And then you iterate through each of the pages using a for loop and stuff the data into your CSV template.

I'll pretend that I've created a collection here called "policies," and that each of my pages exists inside _policies.

---
layout: none
search: exclude
---
policyID,statecode,county,eq_site_limit,hu_site_limit,fl_sit
e_limit,fr_site_limit,tiv_2011,tiv_2012,eq_site_deductible,hu_site_deductible,fl_site_deductible,fr_site_deductible,point_latitude,point_longitude,line,construction,point_granularity

See how you access content in the frontmatter using the page namespace? page.policyID gets the value for the policyID in the frontmatter, and so on. The for loop would go through each of the pages and construct a new row of comma-separated values until it reached the end of the pages in the policies collection.

When you build your Jekyll site, Jekyll will recognize the data.csv file as needing to be processed because of the frontmatter tags. You will find a fully populated data.csv file in your build folder.

Not bound by format

Because of this flexibility in constructing templates to stuff content into, you're not bound by a specific format, for the most part. You create your content, decide on the template, and then Jekyll shoves the content inside the template. The template could be HTML, JSON, CSV, or something else. This way you can author content in a way that is separate from format. (You could equally create a template that stuffs this same arcane policy information content into a JSON file, for example.)

No doubt many tools do a similar kind of thing on the backend. I just never really understood what was happening when I selected a certain output. Jekyll exposes this processing in a clear and simple way. Now your content can travel into any number of systems in a seamless way.

There is at least one limitation with the formats, though. You can't really create a DITA template and push the content into a DITA format except maybe in the most general way, with body including just HTML. This is because DITA has some very specific structures, and this simplistic template method won't really wrap lists inside task elements, convert links inside pages into xrefs, enforce element order, and so forth.

Other more sophisticated formats might have similar restrictions. However, my point is that Jekyll allows you to separate out your content from the template (presentation), and this is a huge deal when it comes to processing and displaying information.


Get new posts delivered straight to your inbox.

Subscriber count: 3,220

About Tom Johnson

Tom Johnson

I'm a technical writer based in the California San Francisco Bay area. Topics I write about on this blog include technical writing, authoring and publishing tools, API documentation, tech comm trends, visual communication, technical writing career advice, information architecture and findability, developer documentation, and more. If you're a professional or aspiring technical writer, be sure to subscribe to email updates using the form above. You can learn more about me here.