Reminder - Digital Publishing Suite (DPS) will End of Life on August 31st, 2019. 
Prerequisite knowledge
  • Knowledge of both InDesign and DPS Interactive Overlays, specifically Web Content overlays.
  • Familiarirty with the App Builder.
  • Acess to a DPS Pro or Enterprise account with the Application role.
  • In addition, a working knowledge of JavaScript is required to implement any solution beyond the example that is provided in this article.
User level: Intermediate
Required products
Other required products
Sample files
By downloading software from the Adobe Web site you agree to the terms of our license agreement. Please read it before downloading.
DPS users have long had a means of navigating within a DPS folio via InDesign’s native buttons actions and hyperlinks. Using the navto:// tag in an InDesign button, for instance, readers can tap to navigate to a specific page in a specific article in a folio. The navto:// tag does not work in Web Content overlays, however, so a different approach is required.
Fortunately, DPS Viewer Applications can have a Custom URL Scheme associated with them. Custom URL Schemes for iOS apps are detailed here in the section entitled “Communicating with other Apps.” Thankfully, the DPS Engineers have done all of the heavy lifting for us, so if we assign a Custom URL Scheme to our DPS Viewer App, then we can send it messages using that Scheme, without having to know any Objective C or XCode.
In this article, we will learn how to create a DPS Custom Viewer App that has a Custom URL Scheme and also how to leverage that Custom URL Scheme to enable navigation within that app from Web Content Overlays. In addition, we will use JavaScript to create navigational links programmatically.

Assigning custom URL schemes to your app

In order to leverage the Custom URL Scheme, you need to build an app that has a Custom URL Scheme associated with it. This is done in the DPS App Builder. Note that this option applies to apps that target iPad and iPhone.
Open App Builder, and then create a new iPad/iPhone app or edit an existing iPad/iPhone app. In the App Details panel, enter your usual app details. In the Optional URL Scheme field, enter your Custom URL Scheme. In the example below, I have used the Reverse DNS naming con vention common to application development. For my DPS Examples app, I used “com.jameslockman.dpsexamples,” which is the app’s Bundle ID from iTunes Connect. While not required, it is a best practice.
Figure 1: Setting the Custom URL Scheme for your app in App Builder

Figure 1: Setting the Custom URL Scheme for your app in App Builder


Having entered the Custom URL Scheme, proceed with building your app as normal. Once you have your developer .ipa (or your deployment .ipa for an Enterprise Signed App), install it on your iPad for content testing.
Note: You will need to deploy your app to an iPad/iPhone in order to test your content. You will not be able to test Custom URL Scheme navigation using the Content Viewer, unless you intend to navigate from the Content Viewer to your Custom Viewer App. For this reason, I have an app I use for testing in addition to the one I use for deployment. Each is associated with different Publication Role Adobe IDs, so that I don’t inadvertently publish test folios to my DPS Examples app. Once tested, I move the folios from the test account to the DPS Examples account and republish the folios.

Custom URL scheme navigation explained

Custom URL Schemes allow applications and web browsers to send messages to each other using a URL. The URL contains everything the app needs identify the target of the message and also for the receiving app to understand what you want it to do. Of course, the receiving app needs to understand what you’re asking it to do, so you need to be sure that you know exactly how to phrase the request. The only messages we can send to DPS Viewer Apps at this time are navigational messages.
DPS Viewer Apps understand the following Custom URL structure:
custom_url_scheme: your Custom URL Scheme
target_folio_name: the name of your folio in the Folio Builder panel. This is NOT the Publication Name that appears in the Folio Properties panel; this is the name you gave the folio when you chose “New Folio” from the Folio Builder panel.
target_article_name: the name of your article in the Folio Builder panel. This is NOT the Title that appears in the Article Properties panel; this is the name you gave the article when you chose “Add Article” from the Folio Builder panel.
#page_number: this is an optional parameter that lets you target a specific page in an article. The numbers are logical numbers, so #0 points at the first page, and #13 points at page 14.
Only the Custom URL Scheme followed by "://" is required, however, to launch your app. You can leverage the Custom URL Scheme in hyperlinks or in other navigational methods, such as "window.location.href =" that we use in JavaScript and which we will use to great effect later in this article.
As an example, you can start my DPS Examples app (if you have it installed on your iPad or iPhone) from a Web page or a Web Content Overlay with the following:
<a href= "com.jameslockman.dpsexamples://">Start the DPS Examples App on your iPad or iPhone</a>
Try it yourself in your Content Viewer (no custom app required for this). Copy and paste that line of code into a text file (or in InDesign CS6 use Object>Insert HTML…), save it into its own folder, and point to it from a Web Content overlay. You can also use the file called “links.html” in the file included at the top of the article. Now, test the page in Adobe Content Viewer on your iOS device. Be sure to have my DPS Examples app installed first, though, or nothing will happen when you tap the link in your folio.
Now, for a more specific example, the following goes to the first page of the article called “Software Demo” of the folio called “Captivate”
<a href=”com.jameslockman.dpsexamples://v1/folio/Captivate/Software%20Demo#0”>Launch the Software Demo Example</a>
Add that to your HTML file or your HTML Object and test again. However, before you do, be sure to remove the Captivate example folio if you have it already installed. The Content Viewer will recognize the request for the Captivate folio, realize that it is not installed, and automatically download it so that it can show you the section. Of course, you need to be entitled to download the folio, so you need to be careful in retail situations not to try to navigate to a folio to which the reader has no access.
With the Custom URL Scheme, you can launch an app from another app, link to content in a Custom Viewer, or navigate within a folio from a Web Content Overlay. This last use case overcomes the limitation in the navto:// tag, which does not work in Web Content Overlays. The rest of the article will focus on using JavaScript and Web Content Overlays to programmatically navigate through a folio.

The reset button conundrum

Many of my agency customers who use DPS create sales aids for their clients. These might be folios that help a pharmaceutical rep explain a benefit or risk of a new medication to a doctor, folios that help an automotive service technician explain the radiator flush procedure to a customer, or folios that helps a retailer communicate the new season’s store layout to their store managers. In all of these cases, the person who is driving the presentation needs a way to quickly reset it to its default state so that they are ready for the next presentation. The Custom Viewer has a method to do it, but it’s less than intuitive.
In order to reset a folio to its default state, tap on the folio to reveal the navigational controls and then tap repeatedly on the name of the folio at the top of the screen. It will briefly show some numbers related to the version number of the viewer application, and your folio will reset to its default state, which is page 1 of the first article. While effective, customers want a way to reset the folio with a single tap. The Custom URL Scheme is just the ticket, but we need to use JavaScript in Web Content Overlays to drive the resetting process.
Figure 2: Resetting the folio by tapping the title in the navigational controls

Figure 2: Resetting the folio by tapping the title in the navigational controls


The setup
In order to reset the folio, we need three HTML files that will auto-run when the user browses the folio. The first of these sets up the initial conditions for resetting the folio, the second is the reset button, and the third is the event listener that waits for the reset signal. We will use WebKit localStorage[] to keep a record of the folio structure and also to control the flow of the resetting process.
Below is the contents of the included file called “init.html”
<script> // Set customURL to the app's custom URL scheme localStorage["customURL"] = "com.jameslockman.dpsexamples"; // Set targetFolio to the name of the folio you want to clear localStorage["targetFolio"] = "ResetButton"; //List your articles in order, using the pattern: //localStorage["article.n"]="name_of_article_in_folio_builder" localStorage["article.0"]="Cover"; localStorage["article.1"]="Article1"; localStorage["article.2"]="Article2"; localStorage["article.3"]="Article3"; localStorage["article.4"]="Article5"; //ensure that the article on which you put the reset button //is not last in this list localStorage["article.5"]="Article4"; // set nextArticle to the number of articles in the folio minus 1 localStorage["nextArticle"] = 5; //don't mess with the these two lines localStorage["currentArticle"]=localStorage["nextArticle"]; localStorage["resetting"]="no"; </script>
Of course, you will use your Custom URL Scheme, your folio name, and your article names.
To use the script, you need to create a box with no fill or stroke on the first page of the first article in the folio, set it as a Web Content Overlay, and point it at init.html. Set the Overlay to Auto Play with 0 second delay, to have a transparent background, and to not Allow User Interaction. This will allow the initial conditions to be set when the reader opens the folio, and the Overlay will not interfere with other interactive content on the page.
Figure 3: Settings for the “init” script Web Content Overlay

Figure 3: Settings for the “init” script Web Content Overlay


The reset button
The next ingredient is the reset button itself, which is included in the file resetButton.html
<head> <script> function resetFolio() { localStorage["resetting"] = "yes"; window.location.href = localStorage["customURL"] + "://v1/folio/" + localStorage["targetFolio"] +"/" + localStorage["article."+localStorage["nextArticle"]] + "#0"; } </script> </head> <body> <button onclick="resetFolio()">Reset Folio</button></br> Here is the resolved reset button path: <script>document.write(localStorage["customURL"] + "://v1/folio/" + localStorage["targetFolio"] +"/" + localStorage["article."+localStorage["nextArticle"]] + "#0");</script> </body>
The resetFolio() function is in the head of the HTML. It sets the resetting flag and forces folio to navigate to the first page of the last article in the article list in init.html. It is important that the last article in the list is not the article on which you place the reset button. The function uses the window.location.href object and sets it to a computed URL. You can see how we use the localStorage variables to construct the URL “on the fly” from what we had previously set in init.html. I have also included a line that displays the computed URL in my example. You should remove it or comment it out of the code when you deploy your actual reset button. Also, you should probably stylize the button with CSS or use an image to make the button match your project’s design.
To use the button, draw a box on the page of the article where you would like the reset button to appear. Set it as a Web Content overlay with zero time delay, transparent background if your design requires it, and Allow User Interaction.
Figure 4: Setting up the Reset Button as a Web Content Overlay

Figure 4: Setting up the Reset Button as a Web Content Overlay


The resetting code
Now that we have set the initial conditions and have placed the reset button, we need to add the code that responds to the resetting flag. The following is the content of the file called resetHidden.html
<script> // are we resetting? if (localStorage["resetting"] == "yes") { // decrement the nextArticle and setup currentArticle localStorage["currentArticle"] = localStorage["nextArticle"]; localStorage["nextArticle"] = parseInt(localStorage["currentArticle"]) - 1; // navigate to the first page of the previous article // if we're not on the first article if (localStorage["currentArticle"]>=0) { currentArticle="article."+localStorage["currentArticle"].toString(); window.location.href = localStorage["customURL"] + "://v1/folio/" + localStorage["targetFolio"] +"/" + localStorage["article."+localStorage["currentArticle"]] + "#0"; } else { localStorage["resetting"]="no"; } } </script>
For the process to work, resetHidden.html needs to be in an invisible Web Content Overlay on the first page of each article except the first article. I found it easiest to copy the Overlay I used for init.html, paste it on the first page of the second article, point the Overlay at resetHidden.html, and then copy and paste it onto the first page of the remaining articles.
If the resetting flag is set, we decrement nextArticle and automatically navigate to the first page of the previous article. The resetting process happens in reverse order based on the article list in init.html, so once we get to the first article, init.html fires and the whole process stops with the folio in its initial condition.

Where to go from here

We’ve seen how to use the Custom URL Scheme to tell a DPS Custom Viewer to navigate to a specific page in a specific article. In addition, we’ve seen how to use JavaScript to programmatically create URLs that enable us to reset the folio after it has been viewed. This specific function is particularly valuable for sales aid applications, and it exposes a wide array of programmatic navigation use cases. For instance, you could make a folio that automatically advances through the pages for kiosk applications. You could also use it to navigate between folios in different DPS Viewer applications. Using this method, you could cross-promote magazines with links in a custom storefront that would open articles in other DPS applications. While there is no guarantee that Custom URL Scheme navigation will work forever, for now, it represents a powerful tool for designers and developers to expand how they use navigation in their DPS folios.