Lieberman's Framing API
The Lieberman's Framing API can be used to quickly develop and deploy a framing application on your website that matches your website design and provides your customers with all of the framing options that Lieberman's offers. This API consists of a set of web services that run on Lieberman's web servers and are available to Lieberman's clients only. This page will discuss the technical aspects of working with the Lieberman's Framing API.
Sample Frameshop
To better understand what can be achieved using the Framing API, we have set up a sample frameshop that is built entirely on top of the Framing API web services. You can view the sample frameshop by clicking here:
View Sample Frameshop In Action (ASP version)
We currently have sample frameshop code available for download for both the ASP and ASP.NET (c#) platforms (please note that the downloads will only work for Lieberman's customers with a valid WebServiceCredential). Download the source code to the sample frameshops here:
Download ASP source code
Download ASP.NET source code
Overview
When selling custom framed artwork online, it is important that your customers have easy access to a wide selection of mouldings and mats. As they are making their selections, they also must be shown a framed image that accurately represents what the finished product will look like, along with the price for their custom product. The Lieberman's Framing API simplifies this process by exposing a simple set of web services that can be used to retrieve information about framing components (mouldings, mats, and glazings), pricing, and framed images. The web services can be called via standard SOAP messaging and are also available as REST web services.
The latest version of the SOAP WSDL can be found at:
https://services.liebermans.net/api/v2/FrameshopService.asmx
When calling the SOAP web services, a WebServiceCredential must be supplied for each call. Since these are SOAP web services, consuming them through Java or .NET platforms should be a relatively simple procedure.
The latest version of the REST web services can be accessed through the following URLs:
https://services.liebermans.net/api/v2/rest/frameshop/image/[PID]
https://services.liebermans.net/api/v2/rest/frameshop/mouldings
https://services.liebermans.net/api/v2/rest/frameshop/mats
https://services.liebermans.net/api/v2/rest/frameshop/glazings
https://services.liebermans.net/api/v2/rest/frameshop/price/[PID]
The REST web service interface provides a secondary means of working with the Framing API, and is preferable to the SOAP web services in some cases (i.e. AJAX Frameshop implementations). The REST web services require that an AuthenticationKey be passed in on the query string for each call using the auth tag (i.e. ?auth=MyAuthKey). The REST web services by default will output XML, but can also be made to output JSON by adding output=json to the query string.
It is important to note that framed images can only be accessed by calling the /frameshop/image REST web service.
Recommendations
When using the Framing API to create a custom frameshop, please consider the following recommendations:
-
Download the moulding, mat, and glazing information, and cache the results of each call.
This data does not change often, so it makes sense to only update this data for your frameshop once every 6 or 12 hours.
-
Hide your AuthenticationKey when displaying framed images by creating a web page on your server that will serve as a proxy for the /frameshop/image web service.
-
Consider caching some or all of the framed images on your server that are retrieved from the /frameshop/image web service. While in most cases it would not be necessary to cache every generated image, it is probably useful to cache the images generated with the default configuration for each print to increase the performance of your frameshop. These images could then be deleted from your local cache every 7 or 14 days and regenerated through the Framing API.
Sample Implementation - Frameshop Demo (ASP Version)
The easiest way to illustrate how to use the Framing API is to provide a walk through of the Frameshop Demo (ASP Version). The ASP Demo Frameshop is a very simple implementation of a Frameshop, using an unfiltered moulding selector and drop down lists for the mat and glazing selections. The user interface for this demo is intentionally overly simplistic, in order to highlight more clearly the interactions between the Frameshop and the Framing API.
Note: For the rest of this section, the term "Frameshop" will be used to refer to the Frameshop Demo (ASP Version) that would run on your servers, and "API" will be used to refer to the Framing API Web Services that run on Lieberman's servers. If you want to follow along in code, please download the Frameshop Demo (ASP Version).
Frameshop Files
The table below lists all of the relevant project files and provides a brief description of how they are used.
Path |
Description |
/index.html |
Start page for the demo, includes links to view items in the Frameshop. |
/frameshop-config.asp |
Stores web service settings. |
/frameshop-data.asp |
Used to interact on the server side with the API REST Web Services. |
/frameshop-image.asp |
Used to download and display a framed image from the API REST Web Services. |
/frameshop.asp |
The main Frameshop page. |
/main.css |
Main CSS file. |
/prototype-1.6.0.3.js |
Prototype JavaScript library used for AJAX calls and HTML updates. |
/xsl/mouldings.xslt |
XSLT file used to transform Mouldings XML returned from API to display HTML. |
/xsl/mats.xslt |
XSLT file used to transform Mats XML returned from API to display HTML. |
/xsl/glazings.xslt |
XSLT file used to transform Glazings XML returned from API to display HTML. |
Configuration String
The API REST Web Services make use of a string value to define how an item should be framed called the Configuration String.
The Configuration String is of the format:
c:[0|1]-m:[Moulding ID]-tn:[# Mats]-tw:[Top Mat Width (in.)]-tt:[Top Mat ID]
-tm:[Mid Mat ID]-tb:[Bot Mat ID]-g:[Glazing ID]
Some example Configuration Strings are listed below:
c:1-m:222-tn:0-tw:0-tt:0-tm:0-tb:0-g:1 - Crop Image, Moulding #222, Glazing #1
c:0-m:8-tn:1-tw:2.5-tt:101-tm:0-tb:0-g:2 - No Cropping, Moulding #008, 1 Mat, 2.5" Mat Width, Top Mat #101, Glazing #2
You can also use the Configuration String to get pricing for Canvas items. The format for Canvas items is:
mode:2-cm:{0}-cb:{1}-cs:{2}-cp:{3}
cm = Moulding ID (Use 0 for unframed canvas)
cb = Bar Type (None = 1, Regular = 2, Deep = 3)
cs = Stretch Type (None = 10, MuseumStaplesOnSide = 11, MuseumStaplesOnBack = 12, Gallery = 13)
cp = Painted Side Color Type (None = 0, Black = 1)
For example:
mode:2-cm:0-cb:2-cs:13-cp:0 - Unframed Canvas, Regular Bars, Gallery Wrap
mode:2-cm:222-cb:2-cs:12-cp:0 - Framed Canvas, Moulding #222, Regular Bars, Museum Wrap
User Supplied Images
These configuration strings can also be used to get pricing for products where the image is not one that is provided by Liebermans. In that case, the image width and image height should be supplied on the querystring, and the product ID of 16000 should be used. For example, if the image being supplied was 8.5" x 11", the REST url would have the following format:
https://services.liebermans.net/api/v2/rest/frameshop/price/16000?w=8.5&h=11&auth=[AuthenticationKey]&cfg=[Configuration String]
Please note that when framing, cropping should always be set to 0 for these items (c:0), as Liebermans will expect the image you are providing to be cropped appropriately.
Implementation Walkthrough
The steps below will outline the main concepts used in the Frameshop. Please bear in mind that the Frameshop makes extensive use of AJAX and JavaScript to provide a UI that updates without having to reload the entire page.
Step 1: Determine which print to view in the Frameshop (index.html)
The index.html page is used to display a list of images that can be loaded into the Frameshop. The links into frameshop.asp are set up in the format: frameshop.asp?pid=[PID]&cfg=[CFG]. The PID value can be either the PID or the publisher code/item number of the piece (i.e., 34000 or MCGK758). The cfg value is optional, and if it is not supplied the default configuration is used, as defined at the beginning of the frameshop.asp page in the defaultCfg variable. Both the cfg query string value and the defaultCfg variable use the Configuration String format described earlier.
Step 2: Generate HTML for available Mouldings, Mats, and Glazings (frameshop.asp)
On the server side, frameshop.asp will render the HTML for the selectors that are used to pick the Moulding, Mats and Glazing. The HTML for these selectors is generated by calling the WriteHtml() method defined in frameshop-data.asp. WriteHtml() will use the supplied parameter value to determine which type of data to download from the API in XML format, and will then use an XSLT file to transform this XML into the HTML that will be displayed on the page.
In the demo, the results of the calls to WriteHtml() are cached using Application variables, as defined in the GetHtmlFromCache() and CacheHtml() methods. Caching the results of these calls cuts down on processing time and network traffic, and as such will help to improve the performance of the Frameshop. This cached data should be refreshed on a daily basis (i.e., periodically purge the data from the Application variables and reload).
Step 3: Display the Frameshop and Apply Initial Configuration (frameshop.asp)
The Frameshop will be initially rendered without displaying the framed image or any of the default selections. However, we will use JavaScript to quickly apply the initial configuration once the page is loaded in the browser. We will repeat this process every time a selection is changed, so using JavaScript to apply the initial configuration (as opposed to handling this action on the server side) allows us to use the same code for the initial configuration and the selection changes.
In frameshop.asp, all of the AJAX functionality is contained within the FrameshopForm class. This class contains references to all of the updatable HTML elements along with methods to access data from the API REST Web Services. After the page is loaded by the browser, the FrameshopForm is initialized and the initial configuration is displayed by calling the loadInitial() method. The loadInitial() method parses the default Configuration String that is supplied and then calls the update() method, which in turn executes code to call the API and update the HTML elements of the form based on the API response.
The process for communicating with the API to update the form with the piece price and the framed image is as follows:
- Build a Configuration String from the form selections.
- Call the /frameshop/price web service validate the selected configuration.
- Update the form so only valid options are displayed and change any selections that are invalid.
- If values were changed due to an invalid configuration, start over at step 1.
- If no values were changed, update the price data and download the framed image.
The Frameshop implements this process via calls to the FrameshopForm methods
update(),
getCfg(),
updatePriceAndOptions(), and
applyAvailableOptions(). The AJAX calls take place in the
updatePriceAndOptions() method, which queries the
/frameshop/price web service to get pricing and option information in JSON format (since JSON is easy to work with in JavaScript). To better understand the data that is returned, an XML representation of the return value of a call to
/frameshop/price is shown below:
<?xml version="1.0" encoding="utf-8"?>
<Price xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://services.liebermans.net/V2/"
>
<IsNotEligibleForFraming>false</IsNotEligibleForFraming>
<IsValidConfiguration>true</IsValidConfiguration>
<SKU>R56273-AEAAAAGADM</SKU>
<PrintPriceUSD>40.0000</PrintPriceUSD>
<ServicePriceUSD>115.20</ServicePriceUSD>
<TotalPriceUSD>155.2000</TotalPriceUSD>
<WidthInches>29.75</WidthInches>
<HeightInches>29.75</HeightInches>
<ShippingBoxID>4</ShippingBoxID>
<ServicePriceComponents>
<FrameshopPriceComponent>
<Description>Flat Front Petite Black moulding</Description>
<PriceUSD>46.14</PriceUSD>
</FrameshopPriceComponent>
<FrameshopPriceComponent>
<Description>Clear Plexiglass glazing</Description>
<PriceUSD>47.64</PriceUSD>
</FrameshopPriceComponent>
<FrameshopPriceComponent>
<Description>Fitting/assembly</Description>
<PriceUSD>21.42</PriceUSD>
</FrameshopPriceComponent>
</ServicePriceComponents>
<MustBeCropped>false</MustBeCropped>
<AvailableMouldingIDs>
<int>4</int>
<int>7</int>
...
<int>264</int>
</AvailableMouldingIDs>
<MaxNumberOfMats>0</MaxNumberOfMats>
<AvailableMatWidthsInches />
<AvailableGlazingIDs>
<int>1</int>
<int>2</int>
</AvailableGlazingIDs>
</Price>
The elements MustBeCropped, AvailableMouldingIDs, MaxNumberOfMats, AvailableMatWidthsInches and AvailableGlazingIDs are all used to indicate how the piece in question can be framed. It is important to take the data in those elements and apply it to the Frameshop, which takes place in the applyAvailableOptions() method. This step is necessary because changes to the selections can sometimes cause other options to become unavailable. For example, a piece may be able to be matted with a thin moulding, but may not be able to be matted if a thicker moulding is selected. Since it is possible to pass invalid configurations to the API, the applyAvailableOptions() method will return a value that indicates if any of the values on the form needed to be changed from their initial selections. If a change had to be made, the update() method will be called once again (with a check to prevent a runaway loop).
After a valid configuration is returned, the price of the item is updated and the framed image is displayed. The framed image is downloaded by calling frameshop-image.asp, which in turn calls the /frameshop/image API. The frameshop-image.asp page is used to hide the AuthenticationKey from the end user, and can also be used to implement a caching solution (not implemented in the demo).
Step 4: Update the Framed Image and Price
The last step is to wire up all of the selectors so that when they are changed, the form is updated. To do this, we simply use the same update() method on the FrameshopForm, and call it from the onchange or onclick events for each control.
Questions
If you have any questions regarding the Framing API that are not covered in this document, please email them to developersupport@liebermans.net.