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.
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
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
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 html_navigation.zip 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
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.
Figure 2: Resetting the folio by tapping the title in the navigational controls
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”
// 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:
//ensure that the article on which you put the reset button
//is not last in this list
// set nextArticle to the number of articles in the folio minus 1
localStorage["nextArticle"] = 5;
//don't mess with the these two lines
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
The next ingredient is the reset button itself, which is included in the file resetButton.html
localStorage["resetting"] = "yes";
window.location.href = localStorage["customURL"] + "://v1/folio/" + localStorage["targetFolio"] +"/" + localStorage["article."+localStorage["nextArticle"]] + "#0";
<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>
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
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
// 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
window.location.href = localStorage["customURL"]
+ "://v1/folio/" + localStorage["targetFolio"] +"/"
+ localStorage["article."+localStorage["currentArticle"]] + "#0";
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.
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.