Replacing product pages
- 6 minutes to read
Sometimes you may need to change the design loaded into the editor. For example, you can provide the user with several design styles or layouts to choose from, and you want them to be able to switch between these options during editing.
The IFrame API provides two methods to change the product layout at runtime:
- setPrintAreas updates a single product page.
- updateSurfaces change a multipage product.
In this topic, we will learn how you can use these methods to implement different scenarios.
Replacing a design in a print area
A fairly common task is to replace the design not completely, but only the current page. For example, when you're editing a two-sided card, you may want the user to be able to change the layout of only the back side without affecting the front design.
In this case, you can use the setPrintAreas
method. You need to prepare a new definition of the print area in the same format as passing into loadEditor
and pass it to the setPrintArea
method as follows:
var newPrintAreas = [{ designFile: "back-side-design" }];
var options = { ... };
var product = await editor.getProduct();
await product.surfaces[1].setPrintAreas(newPrintAreas, options);
This method has an additional parameter, where you can pass options
of this operation. For the complete list of options, refer to ISetPrintAreasOptions.
For example, if you want to completely replace the design without saving your changes, pass preserveUserChanges
, replaceAll
, and updateSurfaceSize
with the following values:
var newPrintAreas = [{ designFile: "back-side-design" }];
var options = {
preserveUserChanges: false,
replaceAll: true,
updateSurfaceSize: true
};
var product = await editor.getProduct();
await product.surfaces[1].setPrintAreas(newPrintAreas, options);
If you want the design editor to transfer the user's changes to the new design, set preserveUserChanges
to true
.
var options = {
preserveUserChanges: true,
...
};
If you don't need to stick to the previous safety zone, you can set preserveSafetyLines
to false
.
var options = {
preserveSafetyLines: false,
...
};
Replacing the whole product
No matter in what format you uploaded the product into the editor, you can replace pages from a new product in the ST, IDML, or PSD formats.
By default, when the loaded and new products have a different number of pages, then the replacement is executed as follows:
- If the current product has more pages than the new one, then the new pages appear starting from the first page, while the last pages remain unchanged.
- If the current product has fewer pages than the new one, then only the first pages of the new product appear in the editor.
You can pass an optional parameter updateBehavior
to define how these cases should be handled.
The updateSurfaces
method has a mandatory parameter definition
. Let's look at how you can pass products of different formats within this parameter.
Replacement with an ST template
If the definition
is a string, it represents the name of a state file. This is how you can switch to the product in a state file.
var product = await editor.getProduct();
await product.updateSurfaces({
definition: "7a6ecf23-1286-4e90-8f18-c7c1c77e3cb0"
});
Here, we replace the pages of the loaded product with the pages of the 7a6ecf23-1286-4e90-8f18-c7c1c77e3cb0.st file.
Replacement with an IDML template
Since updateSurfaces
supports IProductDefinition, you can also specify an IDML file in the definition
.
var product = await editor.getProduct();
await product.updateSurfaces({
definition: {
surfaces: { file: "flyer" }
}
});
In this case, the pages of the loaded product will be replaced with the pages of flyer.idml.
Replacement with PSD templates
If your PSD templates are organized in a folder, then you can specify the name of this folder to replace the product as follows:
var product = await editor.getProduct();
await product.updateSurfaces({
definition: {
surfaces: { designFolder: "my-photo-book" }
}
});
As an alternative, you can list PSD files in the definition
one by one.
var product = await editor.getProduct();
await product.updateSurfaces({
definition: {
surfaces: ["my-photo-book\\cover", "my-photo-book\\first-page"]
}
});
Replacing specific design pages
Using updateSurfaces
, you can also replace not the whole product but only specific pages. To do so, pass additional parameters:
- The
surfaces
array with indexes of pages of the loaded product that will be removed. - The
newProductSurfaces
array with indexes of pages of the new product that will be inserted instead.
var product = await editor.getProduct();
await product.updateSurfaces({
definition: "7a6ecf23-1286-4e90-8f18-c7c1c77e3cb0",
surfaces: [0, 1],
newProductSurfaces: [1, 4]
});
Here, we take surfaces 1
and 4
from the specified state file and insert them instead of the surfaces 0
and 1
into the loaded product.
Maintaining design elements
When arranging design elements, updateSurfaces
changes the content of placeholders having the same layer names on the current surface and in the new layout.
By default, when this method replaces pages of the loaded product, it maintains only texts and image placeholders and moves them to new positions, but drops other design elements. To maintain other elements, you can pass true
in the replaceAll
parameter. In this case, the rest of the placeholders will take the content in a random order according to their type. If the old layout has more placeholders than the new layout, then extra placeholders will be removed.
var product = await editor.getProduct();
await product.updateSurfaces({
replaceAll: true,
definition: {
surfaces: ["invitation"]
}
});
Changing the size of surfaces
If the current and the new surfaces have different widths or heights, you can specify whether to update the surface size to match the new one by using the updateSurfaceSize
param, for example:
var product = await editor.getProduct();
await product.updateSurfaces({
updateSurfaceSize: true,
definition: "7a6ecf23-1286-4e90-8f18-c7c1c77e3cb0"
});
Adding and removing pages
You can also completely replace products when using this method. To remove all pages of the loaded product and accept the pages of the new product, pass "changeSurfaceLength"
in the updateBehavior
option.
var product = await editor.getProduct();
await product.updateSurfaces({
updateSurfaceSize: true,
updateBehavior: "changeSurfaceLength",
definition: {
surfaces: { file: "flyer" }
}
});
When updateBehavior
is set to changeSurfaceLength
, the loaded product will be removed first. Then, the resulting product will get all pages of the new product or only pages listed in the newProductSurfaces
array if defined. If there are more elements in the new product than in the current product, additional pages will be added, if fewer, the latter pages will be deleted.
If updateBehavior
is keepCurrentSurfaceLength
, then the number of pages will remain the same. If there are more elements in the new product than in the current product, then extra pages will be dropped, if fewer, only the first pages will be replaced.
Chaining updateSurfaces or setPrintAreas calls
The updateSurfaces
method replaces surfaces and returns a new product instance with the updated surfaces.
Note that each method call that changes the product returns a copy of the changed product, but the previous instance remains unchanged. This is the feature of the Customer's Canvas SDK. If you want to call such a method as updateSurfaces
several times in succession, like this:
const product = await editor.getProduct();
await product.updateSurfaces({ ... });
await product.updateSurfaces({ ... });
Then, you will not get the expected result. Instead, you need to do this:
const product1 = await editor.getProduct();
const product2 = await product1.updateSurfaces({ ... });
await product2.updateSurfaces({ ... });