Announcements
B2C Commerce Architecture
Get Started with Business Manager
Localization
B2C Commerce Release Notes
Ask the Community
Salesforce B2C Commerce is localizable, from business objects (for example, catalogs, products, and attributes) to the storefront.
To localize your B2C Commerce site:
There are some situations, however, where localization isn’t possible.
B2C Commerce supports Asian languages.
Note
B2C Commerce includes current world currency data. There’s no need to add, edit, or remove currencies through Business Manager. However, define how a currency appears for a locale if needed. For example, the decimal positive pattern is defined as #,##0.00 for the Default (default) locale.
The appropriate currency is automatically selected in the storefront based on the selected locale. The currency assigned to the default locale is the lead locale of B2C Commerce.
B2C Commerce uses the $ for United States dollar (USD). For other currencies, the $ symbol is prefixed with letters based on common convention. For example, A$ denotes the Australian dollar.
Note
B2C Commerce uses country codes for various features, such as:
B2C Commerce supports two-character country codes per ISO 3166-1-alpha-2 only. B2C Commerce doesn’t support other standards, such as 3-letter codes. Using them might result in some features no longer working correctly. For example, if you store 3-letter country codes in order addresses, the export of such orders would fail. Export files would be invalid per the B2C Commerce order.xsd schema.
See the API documentation on the following:
A locale represents a specific geographical, political, or cultural region. Salesforce B2C Commerce supports multiple locales for both the Business Manager user interface, and the underlying storefront site data.
B2C Commerce supports language-specific locales, in addition to country-specific locales, with an extended resource lookup sequence for all localized data.
If you use the United Arab Emirates Dirham (AED) currency, we recommend that you show the amount value prefixed with the abbreviation currency, for example, (AED) 250. B2C Commerce doesn’t currently handle certain UTF characters that are right-to-left. For example, gift certificates purchased under the AED currency don’t show the amount under the list view. The list view is displayed when you click App Launcher
and then select Merchant Tools > site > Online Marketing > Gift Certificates.
Note
B2C Commerce is structured as an organization containing one or more sites (storefronts). To configure locales:
If you support multiple languages across sites, you might want to use a second language for your default language. For example, you could use French for the default language for France, Switzerland, and Luxembourg, but use country-specific resources for a portion of the data. In this case, typically you have multiple sites with shared resources and want to localize most of your data based on language rather than region. While sites using the same language (such as en), but different country (such as en_US, en_CA), might use some region or country-specific resources, most of the resources are the same.
Tip
Some Business Manager elements can’t be localized.
Note
Business Manager supports multiple languages in both its user interface and in the underlying data that is created, edited, and shown within it to be used in the storefront. Configure locales separately for:
For example, a user could view English products and content using a Japanese Business Manager.
There are two ways to select the Business Manager user interface locale:
To set a locale as preselected for all Business Manager pages that include localized attributes, you define the preferred locale (language) in a user profile. This locale (language) must have been previously activated for the instance through global preferences. This sets locales for:
To edit the locale, including specifying localized formats for attributes, dates, currency, quantity, and input settings, click the Locale ID link. If you want B2C Commerce to give you default formats, click Prefill after you select the locale.
Define how linguistic search rules (stop words, category name exclusions, synonyms, hypernyms, compound words, common phrases, search suggestions, and stemming exceptions) are applied in a multi-locale site.
When you’ve configured the required locales, you must build search indexes for those locales. When customers use those locales (languages) in their search criteria, B2C Commerce is able to respond appropriately.
Salesforce B2C Commerce provides you with a locale fallback mechanism to meet your site’s multi-locale requirements. By default, the country locale (for example, en_US) inherits data from the respective language locale (en), and the language locale (en) inherits from the locale default. Configure locale inheritance as needed.
Configure a locale to skip a locale in its fallback chain, or to not have any fallback. For example, en_US falls back to en and then to default. Configure en_US to fall back directly to default, or configure en_US to not have any fallback.
The application server uses the locale fallback that you configure only when looking up localizable attributes or properties of objects of subclasses of PersistentObject, such as Product. The application server doesn’t consider the fallback locale when locating ISML templates, web forms, resource files in cartridges, or static content such as images.
Note
If a locale is configured as the fallback for another locale, you can’t delete it: an error message appears.
For example:
Disabling Locale Fallback
Disable the fallback behavior for each locale.
For example:
Most elements of the Business Manager user interface are localizable. You see the configured language throughout the application. However, there are some situations where localization isn’t possible
The following table describes situations where localization isn’t possible.
| Element | Description |
|---|---|
| Attributes used for column titles in grids | Attributes defined by a customer in the database appear as they were entered. Some column headers in an otherwise localized grid appear untranslated. |
| Attributes used for section and field labels | Attributes defined by the customer in the database that are used on many pages as field labels, appear untranslated. On a page with many such custom attributes, 90% of the page could appear untranslated. |
| Site IDs in breadcrumb and other strings | The site ID on a History tab or in breadcrumbs aren’t translated. |
| Country names used in the Store Locator | In the Store Locator, country names come from the GeoLocationPO database and aren’t translated. |
| Order status | Order status names are customer-defined and aren’t translated. |
| Tooltips text defined in the database | Text beneath the dividing line of some tooltips comes from the customer’s database and isn’t translated. |
| Permissions managed in the database | In the Roles & Permissions module, descriptions for the different permissions are defined in the customer database and aren’t translated. |
| Third-party data and proper names | Third-party data and names aren’t translated, for example, the calendar to enter the start or end date of a campaign is in English. It’s part of GWT and not accessible for localization. |
| Object types from auditing framework: | On the Customer Groups page, for example, a variable inside the description of a group isn’t translated. Such object types can’t be translated because they come from inside the auditing framework. |
| UI elements coming from the browser: | The browser controls the Browse button. This button isn’t localizable from within Business Manager. |
| Internal exceptions: | Errors caused by exceptions outside of Business Manager aren’t translated. For example, an error such as, “Start node not found (ManageCustomGMVReports) for pipeline (ViewCustomizationImpex).” is untranslated. |
Message resources support Asian character sets because property files assume a UTF-8 encoding. As a result, existing property files that are compatible with the ISO-8859-1 (Latin 1) encoding might no longer be supported in their existing form.
UTF-8 encoding supports many more languages than ISO-8859-1, including Greek, Cyrillic, Coptic, Armenian, Hebrew, Arabic, Syriac and Tana alphabets, as well as Chinese, Japanese and Korean ideographs, symbols, and punctuation.
| Location | Impact |
|---|---|
| USA | UTF-8 encoding, like ISO-8859-1, is a super-set of the US-ASCII format. This means that existing property files containing only letters, numbers and punctuation among the 128 character codes in US-ASCII are inherently compatible with this change. |
| Other Countries | Property files containing accented characters and additional punctuation, that are beyond the 128 US-ASCII codes and commonly called extended ASCII characters, aren’t compatible with this change. These files must be converted to UTF-8 format to continue to be used. |
If you use extended ASCII characters, you must convert your property files to support UTF-8.
Note
Search Query Processing
Salesforce B2C Commerce supports search query processing for Chinese and Japanese sites.
There are tasks required to translate your storefront into the required languages.
To enable translation of the source:
To enable content translation:
Localize static files such as images and CSS.
Images
Localize static files such as images to include images with localized text or locale-specific symbols. Your initial system includes the following structure:
| Location | Contains | Localized |
|---|---|---|
| cartridge/web_ch_cust_app/cartridge/static/{default} | English (or default) images (such as buttons), JavaScript (including English error messages), css files. (all are in the cod) | No |
| sites/Sites-cust-Site/1/units/Sites-cust/static/{default} | English (or default) content and category images, category images and homepage images (all are from the content library) | Yes - text overlay |
Include an images folder within the locale-specific folder, but note that the SiteGenesis application doesn’t use this capability for cartridge images.
Note
If a user calls the URL using locale es_US, the files in folder es_US are loaded first. If they aren’t found, Salesforce B2C Commerce uses the default folder as a fallback. So within a local-specific folder, you need only include files that are truly locale-specific (not background images, for example).
This logic occurs on a per file basis.
Note
CSS Files
Your file system must have unique, locale-specific folders. For example, to support both English and Spanish (es_US), create a second es_US folder within the /static folder that lets B2C Commerce overwrite the default files. The included files must have the same names as the files under default and the same folder structure.
In the following directory structure, for example, the localized files are stored in language-specific directories (French and German). Use locale-specific directories (for example, fr_FR, fr_CA, en_US) as needed.
1/Cartridge
2 /static
3 /default
4 /css - generic files
5 normalize.css
6 print.css
7 style-responsive.css
8 style.css
9 /images
10 generic images
11 /js - generic files
12 /fr
13 /css
14 normalize.css
15 print.css
16 style-responsive.css
17 style.css
18 /images
19 localized images
20 /js
21 /de
22 /css
23 normalize.css
24 print.css
25 style-responsive.css
26 style.css
27 /images
28 localized images
29 /jsWhen developing your storefront application, use one template set or a unique template set for each locale.
When you use one template set, you externalize localizable strings, and translate the strings in resource files. Salesforce recommends this approach as a best practice methodology.
The advantage of using one template set is that templates (which can hold complex logic to visualize dynamic data) don’t have to be modified as the storefront is localized. Also, the display logic exists in a single place (the non-language specific template) only. The externalized strings are stored in a simple file format that can be passed to translation service providers. The translation can be integrated back into B2C Commerce simply by copying the translated file into the cartridge, without potentially breaking the logic.
The Storefront Reference Architecture (SFRA) application provides a simple way to localize any text that appears in the storefront. It uses a single template set for all locales, stored in properties files (called template resource bundles). The template resource bundles are translated, not the templates. The templates reference the localizable text in the template resource bundles by keys. Depending on the locale that is used in the storefront, a different translation (localization) of the properties file is used.
Projects typically start from the SFRA application code, so it’s important that you use this approach consistently.
To support multiple languages, create language-specific (for example, en) or locale-specific (for example, en_US) directories within the templates/resources directory, as follows:
1/templates
2 /default
3 /account.isml
4 ...
5 /util.isml
6 /resources
7 account.properties - default files
8 ...
9 storelocator.properties
10 /fr
11 account.properties
12 ...
13 storelocator.properties
14 /de
15 account.properties
16 ...
17 storelocator.propertiesSalesforce B2C Commerce (and the SFRA application) supports a localization fall-back mechanism. If no locale-specific directory exists, the language-specific directory is used. If there’s no language-specific directory, the default directory is used.
There’s a corresponding template resource bundle for each folder in the templates directory and one for the forms definitions.
Template resource bundles hold static content for localization. They’re stored for each cartridge within the /templates/resources directory. Messages from the bundles are accessible to all templates of the corresponding cartridge via the msg()method, available in the dw.web.Resource class.
Content Warning: The content on this page necessarily engages with noninclusive language that can be emotionally and intellectually challenging.
Note
See the Salesforce B2C Commerce API documentation for more information.
Note
These properties files have already been created for you in the SiteGenesis application. They each contain a list of text that pertains to its corresponding object (template or form). They’re organized as a single properties file per top-level directory.
If a valid localeID is set by the SendMail API pipelet, the locale is also used inside an email template to resolve localized messages by the Resource.msg() function based on the given locale. If you’re using the dw.net.Mail class to send messages, the LocaleID set through Template.setLocaleId or the constructor Template(Template,LocaleID) is used to look up the template resource before the locale linked to the current request.
Tip
Account Example
For example, account.properties, which lists the text in the minicartcontent.isml template, looks like this:
1##############################################
2# ISML Directory: account/addressbook/
3##############################################
4editaddress.editaddress=Edit Address
5editaddress.addaddress=Add Address
6editaddress.defaultaddress=Default Address
7editaddress.makedefaultaddress=Make DefaultName the elements anything you want. In the SiteGenesis application, the elements are named after the files in which they’re contained, followed by a descriptive string. For example, a resource bundle referenced in the editaddress.isml template would be editaddress.discriptivestring,
Note
For any text to be included in the storefront using this methodology, you must create a line within the corresponding language-specific properties file. These language files are named to correspond to the file directory of the language snippet to be used. Each text snippet has a unique key (unique across resource bundle files).
Comments
Comments are preceded by a # character.
For example, in the account.properties file, the text list is separated by the sub directories within the top-level directories.
1##############################################
2# ISML Directory: account/
3##############################################
4accountoverview.welcome=Hello
5accountoverview.welcome2=, Welcome Back
6accountoverview.not=Are you not
7
8accountredirect.title=Redirect
9accountredirect.permanent=This account has been permanently removed. You can attempt to login with another account or create a new account by going to the
10accountredirect.accountlogin=login page.
11account.forbidden=This page has timed out. You must close the window and login to continue.
12account.createnew=Create Account
13account.editaccount=Edit Account
14
15##############################################
16# ISML Directory: account/addressbook/
17##############################################
18editaddress.editaddress=Edit Address
19editaddress.addaddress=Add Address
20editaddress.defaultaddress=Default Address
21editaddress.makedefaultaddress=Make DefaultProperties with the sub directory would be separated, as shown previously.
Form Example
The following is an example of using properties within a German version of a form (forms/default/creditcard_de.xml - forms.properties):
1##############################################
2# Template name: forms/default/creditcard_de
3##############################################
4creditcard.visa=Visa
5creditcard.mastercard=Mastercard
6creditcard.amex=Amex
7creditcard.discover=Discover
8creditcard.cvn=CVN
9creditcard.savecard=Au�er Dieser KreditkarteUse the same pattern of appending the local identifier when creating locale-specific resource bundles (.properties) files. For example:
Note
To include your language text within a template or form, reference the corresponding line from the correct file.
Content Warning: The content on this page necessarily engages with noninclusive language that can be emotionally and intellectually challenging.
Note
Cart Template Example
The following example calls resource usage in a template:
1// Reference to resource minicart.viewcart in resource file
2<a href="${URLUtils.https('Cart-Show')}"
3 title="${Resource.msg('minicart.viewcart','checkout',null)}"
4 class="mini-cart-link"></a>
5// ${ Resource.msg('minicart.viewcart','checkout',null) }
6// will grab the text = View your cartThis entry is the corresponding entry in checkout.properties:
1minicart.viewcart;Form Example
This example shows resource usage in a form:
1//Reference to resource forms.properties resource file
2<options>
3 <option optionid="Visa" value="creditcard.visa" label="creditcard.visa" />
4 <option optionid="American Express" value="creditcard.amex" label="creditcard.amex" />
5 <option optionid="Main" value="creditcard.mastercard" label="creditcard.mastercard" />
6 <option optionid="Discover" value="creditcard.discover" label="creditcard.discover" />
7</options>This is the corresponding section in forms.properties:
1creditcard.visa=Visa
2creditcard.mastercard=Mastercard
3creditcard.amex=Amex
4creditcard.discover=DiscoverUse language-specific template sets to localize, although using one template set is the preferred approach.
With the multiple template set approach, each locale of a storefront has its own set of templates. The templates are stored in uniquely named folders, with this file structure:
1templates\{locale_folder}\{template_files}By default, Salesforce B2C Commerce provides all templates within the \defaultfolder. This folder is used when no template is found for the requested locale. Directory names for locale-specific templates consist of a language and a country code, as specified in the standard ISO 639 (language) and ISO 3166 (country).
This table shows some sample folder names:
| Locale | Folder Name |
|---|---|
| English/United States | en_US |
| English/Ireland | en_IE |
| German/Austria | de_AT |
| Spanish/Argentina | es_AR |
| French/Canada | fr_CA |
For example, templates could be stored in this directory structure:
1.../cartridge/templates/default/multiple_template_files
2.../cartridge/templates/en_GB/multiple_template_files
3.../cartridge/templates/en_IE/multiple_template_files
4.../cartridge/templates/en_US/multiple_template_filesUse the following defaults to represent general languages:
| Language | Folder Name |
|---|---|
| English | en |
| German | de |
| French | fr |
| Spanish | es |
Use different templates for different locales, even though the locales share the same language. Share templates between different locales with the same language.
For example, a company set up a multi-site environment with three sites:
Select the correct locale for each site: en_US for the US, en_GB for the UK and en_IE for Ireland. All main templates are shared between these locales. Implement country-specific changes to each site, for example, show the different country icons in the top left-hand corner of the Welcome page.
To achieve this effect, use three welcome templates with three different images or logos. Store the welcome.isml template in different folders specific for each locale:
1.../cartridge/templates/en_GB/welcome.isml
2.../cartridge/templates/en_IE/welcome.isml
3.../cartridge/templates/en_US/welcome.ismlThe characters, xx_XX represent a combination of the language and the country. For example, en_US represents the English (en) language spoken in the USA (US), while en_IE represents the English language (en) spoken in Ireland (IE). Likewise, de_DE represents the German language (de) spoken in Germany (DE), while de_AT represents the German language (de) spoken in Austria (AT).
Note
In Salesforce B2C Commerce, URLs can be localized. When you create a site, the URL Rules module automatically formats your URLs according to the module configuration.
If site URLs are configured with the locale ID as the first element of the URL (for example, /en_US/mens), B2C Commerce doesn’t resolve URLs if they don’t contain the locale (for example, /mens).
Note
Standard B2C Commerce URLs aren’t enabled by default and aren’t optimized for SEO. This URL structure is important to understand if you’re generating a locale-specific URL programmatically. Standard Demandware URLs have a simple structure for storefront access in the following format:
1http://{instance}-{realm}-{customer}.brand.com/on/demandware.store/
2{organization}-{sitename}-Site/{locale}/{pipeline_name}-{startnode_name}Links to this type of address call a public pipeline-start node and can provide parameters such as category or product. Use these additional parameters:
cgid=category ID
pid= product ID (sku)
cid= content ID
Finding the locale in the URL
Find the locale used for a user session in the URL. For single-language installations, there’s always a locale named default. When using multiple locales, use {locale} instead of /default/.
Example:
| URL | Locale |
|---|---|
| http://{domain}/on/demandware.store/Sites-customer-Site/default/… Value | default |
| http://{domain}/on/demandware.store/Sites-customer-Site/en_US/… Value | en_US |
The locale is used for the lookup of resources in the file system and in the database.
Provide two links so that your users can switch from English to Spanish on the homepage. But these links can’t be hardcoded to the production instance URL. The links must also be able to access the staging and sandbox instances for testing purposes.
Access (get or set) the default locale programmatically, as shown in this example:
1<isscript>
2 var currentLocale : String = pdict.CurrentRequest.getLocale();
3</isscript>
4<span>${currentLocale}</span>
5<isloop items="${dw.system.Site.getCurrent().getAllowedLocales()}" var="locale" status="loopStatus">
6 <isscript>
7 var localeLanguage : String = new dw.util.Locale.getLocale(locale).getDisplayLanguage();
8 if (localeLanguage == '') { // if the default langauge isn't defined, assume it's English localeLanguage = 'English'; }
9 localeLanguage = localeLanguage.charAt(0).toUpperCase()+localeLanguage.substring(1);
10 </isscript>
11 <a href="${URLUtils.http(new dw.web.URLAction('Home-Show',dw.system.Site.getCurrent().getID(),locale))}"><isprint value="${localeLanguage}"></a>
12</isloop>Get the default locale from the site: dw.system.Site.getCurrent().defaultLocale (Read Only)
Note
Show product prices in multiple currencies in the storefront using the Salesforce B2C Commerce API.
Use these API methods:
ProductPriceModel.getPriceBookPrice(String priceBookID)ProductPriceModel.getPriceBookPrice(String priceBookID, Quantity quantity)If the price book currency is different from the site currency, these methods return a product price.
This feature is for display purposes on the product details page only. Use this feature to show product prices in another currency, along with the actual sales price in the site currency. This feature doesn’t support a multi-currency checkout.
Search result sorting, search refinements, price ranges, and other price-related features are limited to the site currency only.
Note