---
schema_version: "1"
id: 3e6accc6405dcc5a3b83bca5be2ebedc2e35ea1954c3506ce8907badea56258f
title: Export Localizable Elements for Bulk Localization for Page Designer
collection: admin
version: current
locale: en-us
portal_url: https://docs.salesforce.com/admin/current/en-us/cc/264-0-0/b2c_localize_bulk_pages.md
canonical_url: https://help.salesforce.com/s/articleView?id=cc.b2c_localize_bulk_pages.htm&release=264.0.0&type=5
source_site: help.salesforce.com
content_type: documentation
content_hash: e9e6600e7b0b7b19f5fd493907bd956ab796ea1054c13b64042a902e84960d4a
description: To speed up the B2C Commerce Page Designer localization process, configure localization export and import using two API jobs.
products:
  - Commerce
  - B2C Commerce
release: "264"
---
# Export Localizable Elements for Bulk Localization for Page Designer

To speed up the B2C Commerce Page Designer localization process, configure localization export and import using two API jobs.

To start, create a custom job step (referred to as FindPages in the following documentation) that provides a list of PageIDs to be exported. For additional information on this process, refer to [Creating Custom Job Steps](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-custom-job-steps.html).

The following code samples are supplied for reference:

`FindPages.js`

```
/**
* Sample logic for finding Page Designer pages for bulk translation
*
* @module cartridge/scripts/jobsteps/FindPages
*/

'use strict';

/**
* Find the pages main function
*
* @param {object}  parameters Job step parameters
* 
* @param {boolean} parameters.IsDisabled Mark the step as disabled - skips step execution and returns an OK status
* @param {string}  parameters.TranslationContentFolder The content folder for pages for translation
* @param {string}  parameters.OutputPageIDsFile File with list of IDs of pages found for translation, relative to the 'Impex/src' folder
* @param {boolean} parameters.OutputUnassignmentFile File with unassignments for the Page Designer pages from the translation folder, relative to the 'Impex/src' folder, not created if omitted
* @param {string}  parameters.NoDataFoundStatus No Data for translation found exit code
* 
* @param {dw.job.JobStepExecution} stepExecution Represents an execution of a step that belongs to a job
* 
*/
function DoFindPages(parameters, stepExecution) {
	var 
		Status = require("dw/system/Status"), 
		ContentMgr = require("dw/content/ContentMgr"),
		File = require("dw/io/File"),
		FileWriter = require("dw/io/FileWriter");
	
	var folder, foundContent, content, contentFolder, impexsrc, pageidsFile, pageidsWriter, unassign, unassignFile, unassignWriter;
	
	if (parameters.IsDisabled) {
	    return new Status(Status.OK, "SKIPPED", "The job step " + stepExecution.stepID + " was skipped");
	}
	
	folder = ContentMgr.getFolder(parameters.TranslationContentFolder); // get contents of translation folder
	foundContent = (folder != null) && (folder.content.length > 0);
	if (foundContent) {
		foundContent = false;
		impexsrc = new File('IMPEX/src');
		pageidsFile = new File(impexsrc, parameters.OutputPageIDsFile);
		pageidsWriter = new FileWriter(pageidsFile, "UTF-8");
		unassign = !!parameters.OutputUnassignmentFile;
		if (unassign) {
			unassignFile = new File(impexsrc, parameters.OutputUnassignmentFile);
			unassignWriter = new FileWriter(unassignFile, "UTF-8");
			unassignWriter.writeLine('<?xml version="1.0" encoding="UTF-8"?>');
			unassignWriter.writeLine('<library xmlns="http://www.demandware.com/xml/impex/library/2006-10-31" library-id="' + ContentMgr.siteLibrary.ID +'">');
		}
		for (var i=0; i<folder.content.length; i++) { // loop through the folder content
			content = folder.content[i];
			if (content.page) {
				foundContent = true;
				pageidsWriter.writeLine(content.ID); // write page ID to the result pages list file
				if (unassign) {
					unassignWriter.writeLine('  <content content-id="' + content.ID + '">'); // write content xml for unassigning the page from the translation folder
					unassignWriter.writeLine('    <folder-links>');

					for (var j=0; j<content.folders.length; j++) {
						contentFolder = content.folders[j];
						unassignWriter.write('      ');    
						if (contentFolder.ID == folder.ID) { // as it is not possible to just delete a folder assignment, all folders a listed without the translation one
							unassignWriter.write('<!-- ');   // an XML comment is used to not include the translation folder, but it is also possible to omit it in the content xml
				        }
						if (contentFolder.ID == content.classificationFolder.ID) {
							unassignWriter.write('<classification-link folder-id="'+contentFolder.ID+'"/>')
						} else {
							unassignWriter.write('<folder-link folder-id="'+contentFolder.ID+'"/>')
						}
						if (contentFolder.ID == folder.ID) {
							unassignWriter.write(' -->');
				        }
						unassignWriter.writeLine('');
					}
					unassignWriter.writeLine('    </folder-links>');
					unassignWriter.writeLine('  </content>');
				}
			}
		}
		pageidsWriter.flush();
		pageidsWriter.close();
		if (unassign) {
			unassignWriter.writeLine('</library>');
			unassignWriter.flush();
			unassignWriter.close();
		}
	}
	if (!foundContent) {
		return new Status(Status[parameters.NoDataFoundStatus], "NO_DATA_FOUND", "No pages were found for translation in folder " + parameters.TranslationContentFolder)
	}
}


/* Exports of the modules */
/**
* @see {@link module:cartridge/scripts/jobsteps/FindPages~DoFindPages} 
*/
exports.DoFindPages = DoFindPages;
```

`steptypes.json`

```
{
	"step-types": {
		"script-module-step": [{
			"@type-id": "custom.PageDesignerTranslate.FindPages",
			"@supports-site-context": "true",
			"@supports-organization-context": "false",
			"module": "bc_page_designer_translate/cartridge/scripts/jobsteps/FindPages.js",
			"description": "Find Page Designer Pages for translation",
			"function": "DoFindPages",
			"parameters": {
				"parameter": [{
						"@name": "IsDisabled",
						"description": "Mark the step as disabled - skips step execution and returns an OK status",
						"@type": "boolean",
						"@required": false,
						"@trim": true
					},
					{
						"@name": "TranslationContentFolder",
						"description": "The content folder for pages for translation",
						"@type": "string",
						"@required": "true",
						"@trim": "true",
						"default-value": "for_translation"
					},
					{
						"@name": "OutputPageIDsFile",
						"description": "File with list of IDs of pages found for translation, relative to the 'Impex/src' folder",
						"@type": "string",
						"@required": "true",
						"@trim": "true",
						"default-value": "library/page_ids.txt"
					},
					{
						"@name": "OutputUnassignmentFile",
						"description": "File with unassignments for the Page Designer pages from the translation folder, relative to the 'Impex/src' folder, not created if omitted",
						"@type": "string",
						"@required": "false",
						"@trim": "true"
					},
					{
						"@name": "NoDataFoundStatus",
						"@type": "string",
						"@required": true,
						"@trim": true,
						"enum-values": {
							"value": [
								"OK",
								"ERROR"
							]
						},
						"default-value": "OK",
						"description": "No Data for translation found exit code"
					}

				]
			},
			"status-codes": {
				"status": [{
						"@code": "ERROR",
						"description": "Used when an error occurred."
					},
					{
						"@code": "OK",
						"description": "Used when execution was successful."
					},
					{
						"@code": "NO_DATA_FOUND",
						"description": "Used when no page designer pages could be found in the source folder."
					},
					{
						"@code": "SKIPPED",
						"description": "Used when step is marked as disabled."
					}
				]
			}
		}]
	}
}
```

#### See Also

- [Localize Content in Page Designer (Video)](https://salesforce.vidyard.com/watch/rUNxBuzePGa1cN2n6T385B)