We have already talked about various aspects of how Customer's Canvas integrates with web-to-print sites in the Integration with E-commerce Overview topic. This article dwells on how Customer's Canvas handles user accounts and login sessions initiated on the host site. Technically, Customer's Canvas does not require deep integration with the authentication system of the host site, as it acts only as a web-to-print editor. All it needs is to receive product settings from the e-commerce module, display the product template in the editor, let the end user personalize it, and then, when the user is done with changes, return the personalized product details back to the website. The website is responsible for extracting product settings and passing them on to the editor. Also, the website handles output from the editor and stores the customized product details among the order attributes.
Customer's Canvas only deals with login sessions once. It needs a way to differentiate uploaded files and personalized products so that a user does not have access to content belonging to someone else. To get around this, the website has to initialize Customer's Canvas with a unique user identifier. The web-to-print editor should associate personalized products with the same user identifier to specify that they were created by the corresponding user. If the user uploads photos to the image gallery when personalizing a print product during the first session, the photos will be available to the user when they return to the website and create another order.
E-commerce platforms always identify user accounts registered in the system by a unique identifier. When integrating Customer's Canvas, you will need to find the technical documentation for your platform and look up information on how to retrieve the identifier using the platform's API.
In some scenarios, it may be more beneficial to create an identifier for yourself in the code initializing Customer's Canvas on the website, store it in a custom user attribute in the e-commerce system, and then pass it to the editor. Next time the editor signs in, the code will check if the attribute is already filled with a value and, if so, retrieve and use it as the user's identifier in Customer's Canvas.
In order to initialize the editor with a user identifier, you should pass it to the loadEditor method as a part of the editor configuration.
var configuration = { userId: "e02e4ced-b56e-caee-4e88-a2482976db73" }; CustomersCanvas.IframeApi.loadEditor(iframe, product, configuration);
When a user identifier is not specified, the default value is used. To change the default user identifier, use the DefaultUserId parameter in AppSettings.config
.
Customer's Canvas creates a separate subfolder for each user whose identifier it has ever been initialized with. The path to the folder where all these subfolders are stored is set up by using the UserDataFolder parameter in AppSettings.config. The default value is "..\userdata"
, which means that all user subfolders are stored in the userdata
folder located one level higher than the web application root. Each user subfolder contains the following:
\userdata\<someUserId>\states\
- the folder contains products created by someUserId
user.\userdata\<someUserId>\images\
- the folder contains images uploaded by someUserId
user.The default user identifier and the folder path where user data is stored are set via the DefaultUserId and UserDataFolder parameters in AppSettings.config
as follows:
<appSettings> ... <add key="DefaultUserId" value="default" /> <add key="UserDataFolder" value="..\userdata" /> ... </appSettings>
The UserDataFolder path is relative to the web application root.
Customer's Canvas offers two modes that can be used on public websites: demonstration and anonymous. Both modes allow users to customize a product without authorization. The main difference between modes is the automatic clean-up of user files. In the demonstration mode Customer's Canvas automatically cleans up user files, including saved products, while in anonymous mode no files are cleaned up automatically.
Let us discuss both modes in detail.
The anonymous mode allows users to customize products without authorization. The editor in this mode treats each session as belonging to a unique user. So, on a public website it allows keeping user files separated, preventing a user from accessing another user's images and products.
The usual workflow using the anonymous mode is as follows:
To activate the anonymous mode, set the AnonymousModeEnabled parameter to True
in AppSettings.config
.
<appSettings> ... <add key="AnonymousModeEnabled" value="True" /> ... </appSettings>
The demonstration mode allows users to play with the editor. It does not require user authorization, and it prevents your system from overfilling with user files. The editor in demo mode treats each session as belonging to a unique user. So, on a public website it allows for keeping user files separated, preventing a user from accessing another user's images and products.
To activate the demonstration mode, set the DemoModeEnabled parameter to True
in the AppSettings.config
file.
<appSettings> ... <add key="DemoModeEnabled" value="True" /> ... </appSettings>
Do not use the demonstration mode for real orders. In this mode user files, including hi-res output, saved products, proof images, etc. are cleaned up automatically after the session ends. So, if a user saved a customized product when the system was in demo mode and wants to order it later, it may be impossible: the customized product may be deleted already.
Imagine your user is customizing a series of different products requiring them to enter the same information into the fields. Filling out each product from scratch is drudgery. Fortunately, Customer's Canvas supports the pre-populating of fields with data loaded from the customer's account. For example, suppose the e-commerce system stores first and last names, phone numbers, and email addresses in user accounts. We can make Customer's Canvas pre-populate these fields in user generated products:
clientConfig.json
globally or through the IConfiguration interface for a single product.
"loadUserInfoButtonEnabled": true
After that, when the page opens or reloads, the Load my info button appears in the user interface.
clientConfig.json
globally or through the IConfiguration interface for a single product.
"autoLoadUserInfo": true
In this case, when a product is loaded into the editor, it is already populated with data; the Load my info button is not displayed in the user interface.
The data used to populate a product should be loaded from your e-commerce system and passed to the loadEditor method as a part of the editor configuration.
var productDefinition = { surfaces: [ "business-card" ] }; var configuration = { autoLoadUserInfo: true, userInfo: { "FirstName": "Jon", "LastName": "Snow", "Phone": "0123456789", "Email": "jon.snow@example.com", "Photo": "https://example.com/jon.snow.jpg", "Slogan": "<p><span style='bold:true;color:green'>Only premium printing</span></p><p>always</p>", "Barcode": { "BarcodeFormat": "QR_CODE", "BarcodeSubType": "Url", "Url": "https://example.com" } } }; CustomersCanvas.IframeApi.loadEditor(iframe, productDefinition, configuration);
The userInfo property accepts data in the JSON format, where keys are layer names (without markers) or in-string placeholder names in PSD templates. For example:
Position: [#Your_Position]
in-string placeholder, the corresponding key is "Your_Position".user:
prefix; for example, the following key-value pair "Logo": "user:myLogo.jpg"
tells the editor to fill the Logo image placeholder with the myLogo.jpg
from the user folder.public:
prefix; for example, the following key-value pair "Logo": "public:car_logos/ford.jpg"
tells the editor to fill the Logo image placeholder with the ford.jpg
logo from the \car_logos\
subfolder of the public image folder.http:
or https:
protocol name; for example, the following key-value pair "Logo": "http://example.com/company.svg"
tells the editor to fill the Logo layer with the company.svg
image by the direct URL.For populating a product with predefined data, Customer's Canvas matches layer names and in-string placeholder names against keys passed in the userInfo dictionary. If a layer or a placeholder has a match, its value is replaced with a corresponding value from the dictionary.
Note that rich formatted text elements accept data in a special format defining paragraphs through the <p> tag and text styles through <span>. In the previous example, the Slogan layer consists of two paragraphs, and the first paragraph contains the bold green text. For details about paragraph and text formatting, you can refer to the specification of the Aurigma Graphics Mill library.
The previous example illustrates how you can predefine userInfo for the entire product. Also, Customer's Canvas allows you to pass user data for a single product page by using the surfaces object. You can refer to a page through its name or index starting from 0
.
// Defining a multipage product. var productDefinition = { surfaces: { designFolder: "brochure" } }; var userInfo = { // The default content. "Name": "Jon Snow", "Phone": "18005551234", // The content for specific surfaces (pages). "surfaces": { // The content for the "surface_0" page. "surface_0": { "Name": "Christopher Bennett", "Phone": "18005551255" }, // The content for the third page. "2": { "Name": "John Wood", "Phone": "18005551011" } } };
This method is time-consuming. For optimization, you can populate a product template when it is loading into the Design Editor with autoLoadUserInfo enabled.
You may want to pass user data to a product at runtime. The Editor.loadUserInfo() method allows you to populate a product template with user data. Pass the data dictionary as its parameter to populate the template with the required values. The data dictionary has the same structure as userInfo. You can also call this method without parameters; in this case it applies the userInfo set when the Design Editor has initialized.
... // Load the web-to-print editor. CustomersCanvas.IframeApi.loadEditor(iframe, productDefinition, configuration) .then(function (e) { // Retrieve the loaded editor. editor = e; }); ... // Populate the product with user data. editor.loadUserInfo({"FirstName": "Jon", "LastName": "Snow", "Phone": "0123456789", "Email": "jon.snow@example.com"});