Add a Language Switcher to a Cascade Story
A recent post on the ArcGIS blog describes how to publish a story map in multiple languages.
That post mentioned how it’s possible to customize one of Esri’s open source story map apps to add a button to let readers easily switch languages. The following article shows you one way to implement a custom language switcher button for Story Map Cascade and provides sample code so you can implement this for your own stories.
Examples
Here are a few examples of stories published in English plus a second language that implement a custom language switcher: Embattled Borderlands, Restoring Old Havana, and The Two Koreas.
The method of switching languages used by both of these stories is simply a button on the cover page (and custom link in the header that can be used anywhere in the story). Below are images of how the button and header link look on a desktop browser and when viewed on a mobile device.
How to implement the language switcher
The basic steps for creating a story with a language switcher are:
- Build two versions of your story map, one in each language.
- Download the compiled code for the latest version of the Story Map Cascade app here via the Download the ready-to-deploy app link at the bottom of the page.
- Modify the code to include the language switcher (as described in the next section).
- Host your modified version of the app on your own web server.
If you’ve never customized or hosted a story map before, this article covers the basics…
The Code
Below are the code snippets you’ll need to add the language switcher. Essentially, this code adds a button to the story cover and a link to the header, both of which can be used to switch languages.
A URL parameter is used to show the alternate language. In the sample code, the default language is English and the alternate language is Spanish.
Remember, you’ll need to have already created two versions of your story map, one for each language. You’ll also need the
appid
of each story.
Make the following modifications to index.html
, as shown in the code below (marked in bold).
- Add a variable for the URL parameter value. In the example below this is
_spanish
, but you should name this based on the alternate language used in your story. - Modify the
appid
definition inconfigOptions
as shown below using the URL parameter variable and the ids of your stories. The secondappid
should be the language specified in your URL parameter variable. - Add the
getURLParameter
function afterconfigOptions
.
You may want to first copy and paste the code exactly as it is below into your locally hosted story. That way, you can test your code and know if you have everything in the right place before you make modifications to reflect the languages or
appid
s for your stories.
var _spanish = getUrlParameter("language") === "spanish";
var configOptions = {// Enter application IDs for stories created through the Cascade builder appid: _spanish ? "c9a1396a0b4f4f2eade8b807f8235a6c" : "7d368289bba9419f93934cb530c74822",// Optionally, to secure Cascade's access if the story item is private or to use the builder, configure an ArcGIS OAuth application ID (example: 6gyOg377fLUhUk6f)
// When specified, sign-in is mandatory even if your story is public
oAuthAppId: "",
// Optionally, to use the appid URL parameter, configure authorizedOwners to reference members whose stories can be viewed by this storytelling app.
// To authorize stories owned by...
// specific members: use ["member"] or ["member1", "member2", ...]
// any ArcGIS member: use ["*"]
// any member of one or more organizations: use ["[orgID]"] or ["[orgID1]", "[orgID2]", ...] (Note the use of brackets in this case, e.g., ["[nzS0F0zdNLvs7nc8]"])
// You can get your orgID by going to My Organization and clicking Find...The most viewed items in the organization.
// Your orgID will be shown in the search box.
authorizedOwners: [""]
};
function getUrlParameter(name) {
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
var results = regex.exec(location.search.toLowerCase());
return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
}
Add this CSS to the index.html
file just under where it says /* CUSTOM CSS RULES */
. Change the language names and their abbreviations, which are used in the mobile view of the story, as needed (marked in bold).
a#languageButtonHeader {
margin-right: 10px;
cursor: pointer;
color: inherit;
}
.mobile-view a#languageButtonHeader {
margin-right: 15px;
}
a#languageButtonHeader:before {
content: "Español";
}
.storymap-spanish a#languageButtonHeader:before {
content: "English";
}
.mobile-view a#languageButtonHeader:before {
content: "ES";
}
.mobile-view.storymap-spanish a#languageButtonHeader:before {
content: "EN";
}
a#languageButtonCover {
background-color: #864726;
cursor: pointer;
color: inherit;
margin-top: 20px;
font-family: 'open_sans','Helvetica Neue','Helvetica','Arial', sans-serif;
font-size: 27px;
padding: 15px;
padding-right: 25px;
padding-left: 25px;
border-radius: 25px;
}
a#languageButtonCover:hover {
text-decoration: none;
}
.mobile-view a#languageButtonCover {
font-size: 1.2em;
padding: 5px;
padding-right: 15px;
padding-left: 15px;
border-radius: 15px;
}
a#languageButtonCover:before {
content: "En Español";
}
.storymap-spanish a#languageButtonCover:before {
content: "In English";
}
Finally, add the JavaScript below to custom-scripts.js
. This goes after the note that says Custom Javascript to be executed when the application is ready goes here
. Change the language names as needed (marked in bold).
/*
* Custom Javascript to be executed when the application is ready goes here
*/if (_spanish) {
$("html body").addClass("storymap-spanish");
} var languageButtonHeader = $("<a>")
.attr("id", "languageButtonHeader")
.addClass("link")
.attr("href", _spanish ? "?language=english" : "?language=spanish");
$("div.share").prepend(languageButtonHeader); var languageButtonCover = $("<a>")
.attr("id", "languageButtonCover")
.attr("href", _spanish ? "?language=english" : "?language=spanish");
$("div.section.section-layout-cover div.foo").append(languageButtonCover);
Code Challenge
Here are some other ideas you could try by modifying/extending the sample code:
- Style the language switcher button differently: change it’s color, shape, or hover effect, or modify how it looks on mobile devices.
- Add additional buttons on the cover if you have a story that’s available in three or more languages.
- Use the
locale
parameter to also translate the app user interface into another language. For example:
https://www.example.com/Cascade/index.html&language=spanish&locale=es
What we’ve been calling a “language switcher” in this article is really just some code that adds a button that loads a different story map (using a different appid
). You could think of this code as a generic “story switcher.”
What other creative ideas can you come up with to use this code?