Deconstructing SiteGenesis
As we discussed in the Demandware Architecture module, SiteGenesis is the reference storefront application for new client development.
The main pipelines used for generating storefront pages are:
-
Search-Show
-
Product-Show
-
Page-Show
-
Cart-Show
-
Account-Show
In the past the first 3 pipelines only used to support SEO friendly URLs :
-
Search-Show with CategoryID
-
Product-Show with ProductID
-
Page-Show for Content Assets
Since the 13.1 deployment Demandware supports customizable URL layout 可定制URL样式 . You switch it on under Site – Site Preferences – Storefront URLs.
-
Go to SiteGenesis – Site URLs – URL Rules to influence the settings for locales(语言), Catalog URLs(目录), Content URLs(内容) and Pipeline URLs
SiteGenesis Page Deconstruction Tools
You can use the Storefront Toolkit Page Information tool to help you break down the files used to generate a storefront page.
Using the Storefront Toolkit: Page Information
The Storefront Toolkit is a development tool that help a developer in troubleshooting a site and is only accessible in staging, development, and sandbox instances.
When you want to know what ISML templates are being used to generate a page, use the ‘Page Information’ tool. When using the ‘Page Information’ tool, you can quickly open up a template that is used to generate a page.
Storefront Files 前端文件
Some important files used in SiteGenesis for rendering pages to a browser are:
-
htmlhead.isml, together with htmlhead_UI.isml
and footer_UI.isml contain all of the CSS, jQuery libraries, and js files.
-
app.js – Contains the JavaScript for client-side storefront event handling
IMPORTANT NOTE
Certain ISML templates may include assets designed to support advanced UI functionality. In these cases, those specific includes should be removed and a single include to <TEMPLATE_NAME>_UI.ISML is inserted. A blank <TEMPLATE_NAME>_UI.ISML is created in Core as a blank file to ensure Core does not break. Then the <TEMPLATE_NAME>_UI.ISML file is created in Rich UI. In the Rich UI version, all of the specific element includes will be inserted.
确定ISML模板可以包含的资源目的在于支持拓展UI功能,在这些情况下,那些指定的包含可以删除,而单个的包含到<TEMPLATE_NAME>_UI.ISML. 一个空白的<TEMPLATE_NAME>_UI.ISML被创建在核心内,作为一个空白文件确保核心没有被破坏,然后<TEMPLATE_NAME>_UI.ISML文件用Rich UI创建,在Rich Ui版本中。所有指定的元素需要被包含。
An example of this clearly is in HTMLHEAD.ISML. This global include file initializes a host of variables and includes a wide range of support files. Some of these support files are JavaScript based and designed to support UI functionality – such as drop down menus. So based on the above direction, a second file HTMLHEAD_UI.ISML would be created. All of the UI includes, variable initializations, etc. are removed and a single line to Include HTMLHEAD_UI.ISML is added. A blank HTMLHEAD_UI.ISML is created in Core and in the Rich UI cartridge a matching HTMLHEAD_UI.ISML. In the Rich UI version of the file, all of the removed elements from HTMLHEAD.ISML would be inserted.
在文件HTMLHEAD.ISML中就是个很好的例子。全局包含文件初始化一个服务器的变量。然后包含许多支持文件。一些支持文件是基于JavaScript,支持UI功能,例如drop down菜单,基于以上说明,一个HTMLHEAD_UI.SIML会被创建,所以UI引入,变量初始化,等等会被删除。用单独一行的引入HTMLHEAD_UI.ISML。一个空白的HTMLHEAD_UI.ISML在核心被创建,而且在Rich UI cartridge匹配到HTMLHEAD_UI.ISML. 在Rich UI 版本的文件,所有元素从HTMLHEAD.ISML中删除的会被插入。
Product Detail Page 产品详情页
The product detail page (PDP) refers to the page that displays all the information for one specific product. It is the result of the Product-Show pipeline. It is rendered by product.isml and decorated by pt_productdetails.isml.
Product Page Templates
There are many templates that are included in a product page:
product.isml includes the decorator pt_productdetails.isml which renders all product pages. productdetail.isml decides if it’s either a Product Set, Product Bundle or a regular product.
If the product has inventory, pricing, availability and option products, it will be displayed using the respective(分别) included files inside productcontent.isml, such as recommendations.isml (推荐), productbreadcrumbs.isml (面包削for navigation), modules.isml (custom tag definitions 自定义标签定义), reviews.isml(评论) and productnav.isml (used in decorator 装饰用) are supporting the appearance on the PDP.
Bundled Product Page
When a displayed product is a bundle, the page is rendered with product.isml which includes the template producttopcontent.isml.
Product Sets
When a product is part of a product set, the page is rendered with product.isml and includes the template producttopcontentPS.isml.
Data Manipulation in Product Detail Page 数据操作
The data for product.isml comes from several places:
-
pdict provides:
-
The Product which identifies the selected product for pricing, recommendations, etc
定义选中商品的价格,推荐,等等
-
ProductSearchResult and ProductPagingModel for rendering
productnav.isml and productbreadcrumbs.isml
ProductSearchResult和 ProductPagingModel渲染
productnav.isml和 productbreadcrumbs.isml
-
CurrentHttpParameterMap.source to determine if quickview, viewed from cart, or ajax search
CurrentHttpParameterMap.source 决定是否是快速预览,从购物车预览,或者ajax搜索
-
CurrentVariationModelto build the variation swatches
CurrentVariationModel 用于创建变化色板
Shopping Cart & Checkout Processing
The process of placing an item into a shopping cart and then moving through the checkout process for an order in SiteGenesis is complex and involves six pipelines :
-
Cart
-
COCustomer
-
COShipping
-
COBilling
-
COPlaceOrder
-
COSummary
Checkout Programming Concepts 结账程序设计概念
When a user adds an item to their shopping cart we create a Basket object. Later, when the user wishes to finalize their order, we convert this Basket object into an Order object.
当用户添加商品刀购物车。我们创建一个Baslet对象,然后。当用户希望下订单,我们转换这个Basket对象为Oreder对象。
Both of these objects must contain all of our individual items that we need to charge to the user. Because we may want to send different items in the same order to different addresses, items are grouped into shipments.
所有这些对象必须包含我们需要对用户要价的分别的items. 因为我们可能想要发送不同的items在同一个订单,然后发送到不同的地址。Items必须由shipments来分组。
All of these objects inherit from the class LineItemCtr(line item container). Let’s have a look at what these objects can contain
所有这些对象继承自LineItemCtr
LineItem Class
The base class used to represent any type of item to be included in the calculation of totals is the LineItem. There are many different types of line items, but they all serve basically the same purpose. A line item can be thought of exactly like a line item of an invoice which will later be used to sum up all of our invoice (or Basket > Order) totals and subtotals. So we create line items in our basket that represent a quantity of an item on our invoice, be that a shipping cost, coupon to be redeemed or a product to be purchased:
这个基本类用于表现任何类型的item被包含在总计当中的是LineItem.有许多不同类型的line items. 但是他们都服务于同一目的。一行item可以被认为是就像是一个发票的 line item ,等下将会被用于计算总金额,(购物车>订单)总计和小计,所以我们创建line item在我们的购物车内表达一些item在我们的发票中,一些可能是运费,coupon的使用。
Now that we have had a look at how data is grouped and stored for an order, let’s have a high level look at how we enable users to interact with this data.
现在我们已经看了数据是如何分组存储在一个订单内的,让我们更新一步看看用户是如何和数据交互的。
Steps for Rendering a Checkout Page
There are three basic steps to rendering a checkout page:
-
Get the most current Basket data associated with the session from the database. This is done by calling the GetBasket pipelet. In SiteGenesis a private pipeline for this is available:
Cart-GetExistingBasket sub-pipeline
获取最新的购物车数据。调用GetBasket pipelit.
-
Initialize the forms, pre-filling them with the data retrieved in last step. This is achieved by using the pipelet UpdateFormWithObject. You may specify which dictionary object should be updated with which form group. The individual attributes are updated via mappings defined in the form metadata (bindings.) Later when a user submits data via the forms and having rendered the template, we will leverage 利用 the same mechanism with the pipelet UpdateObjectWithFormto store the submitted data in the database.
初始化表单,预填上一步获得的数据,用UpdateFormWithObject pipelet 完成。你可以指定哪个字典对象需要被更新到form组。分别的属性通过mapping定义,从metadata binding中知道。之后当一个用户提交数据通过表单。我们利用同样的机制,UpdateObjectWithForm pipelet来存储提交的数据到数据库。
-
Prepare the view. Retrieve any other data from the system that you need for this page. Examples of this could be calculating applicable shipping methods or payment methods. Other examples may be retrieving basket or user specific product recommendation or promotional data. This step needs not be performed in a pipeline, it may also be performed in the isml template, or using ajax calls which is often preferred so that this data can be refreshed in real time as the usermakes changes to relevant data on the page.
准备预览,检索任何其他数据,从系统中。举个例子可以是计算shipping method,payment method. 还有些其他粒子可以是检索购物车或者用户指定商品推荐以及促销数据。这个步骤不需要在pipeline中执行,它也可以在isml模板中执行,或者调用ajax请求(优先)刷新效果很好。
You now should be prepared to render your checkout page using an ICN
It is not required to use an ICN node in checkout but they come with many advantages, such as automatic form validation (验证原子性)and the concept of form actions (form行为的概念) which allows you to create very diverse (不同的) page flow without having a lot of public entry points for pages.(不用很多来自页面的公共进入点)
Walk through SiteGenesis and see some of these concepts in action.
For this please put a breakpoint on the following Start nodes
-
Cart - AddItem
-
Cart - Show
-
Cart - COStart
-
COCustomer - Start
-
COShipping - Start
-
COBilling - Start
-
COPlaceOrder - Start
-
COSummary - Start
-
COSummary – ShowConfirmatio
Shopping Cart
In SiteGenesis, there are two displays of a visitor’s shopping cart: a mini-cart popup,And a full-page cart display that opens when the View Cart button is pressed from the mini-cart or the cart link is clicked
When a customer puts a product into the basket, the process is typically done with an ajax call. The ajax call invokes the Cart sub-pipeline that is located in the Cart pipeline.
AddItem Sub-Pipeline
The AddItem sub-pipeline adds a product to the mini cart. The pipelet AddProductToBasket creates a ProductLineItem (product sku and quantity) in the basket and also returns this object in the pipeline dictionary.
The overall functionality of the AddItem sub-pipeline is as follows:
-
Checks whether product is coming from a product list (wish list or gift
registry) - if not it makes sure there is a ProductID
-
检查是否商品来自wish list 或者 gift registry – 如果不是。确保有一个productID.
-
Product object is retrieved
可以取得product对象
-
Checks for a basket object. If one is not present, it is instantiated.
检测baseket对象。如果不存在就初始化一个。
-
AddProductToBasket pipelet is called – adds a product to the basket
调用AddProductToBasket pipelet, 增加一个商品到baseket.
-
-
It is important to note that the pipelet creates and returns a
-
ProductLineItem, or multiple line items, by creating these object(s) in the basket, representing the desired product sku(s) and quantity.
-
Pipelet创建和返回一个ProductLineItem, 或者多个line items.
-
-
-
Once anything is changed in the basket, a cart calculation is always performed. Updates order totals to represent what buyer has done so far.
任何操作在购物车内改变,一个cart计算会被执行。更新订单总计。
-
Once the ‘Checkout’ button is pressed, the ‘Cart-COStart’ pipeline is called.
checkout按钮被选,’Cart-COStart’ pinpeline被调用。
Cart-Show Sub-Pipeline
Once the user has added the product from the product detail and is ready to check out, they will click the View Cart button in the mini cart panel to get to the full view page. The pipeline that is called is Cart-Show. Since this page is the entry point to the checkout process, we must first ensure we have created all our form objects in the pipeline dictionary. We do this by using the ClearFormElement pipelet to create our form object defined in our form meta-data under the CurrentForms key.
we will fill this form with the current data from our basket object.
After we guarantee our form objects all exist, we get the current existing basket from the database. Once we have ensured the basket object is available in the dictionary, the pipeline Cart-PrepareView first updates the form objects with the basket data, and then it retrieves any page specific data we still require. In this case, if the user is a registered user and authenticated, we fetch any wish lists that are associated with the user or create one if none is found. Finally, the page is rendered using an ICN with many continue actions. Let’s have a look at where these actions are called on the cart page.
There are many form actions that can be taken from the cart ICN. All of these actions either continue the checkout flow, or perform a business operation and return the user to the cart page. Here are some brief explanations of what these actions do:
-
deleteProduct: Executes RemoveProductLineItem pipelet for the line item, removing it from the cart.
-
editLineItem: Opens a dialog for the user to edit details (typically select a different variant) and replace the line item.
-
deleteGiftCertificate: Executes RemoveGiftCertificateLineItem pipelet for the line item, removing it from the cart.
-
addCoupon: Executes AddCouponToBasket2 pipelet for the input entered into the text field.
-
updateCart: Typically used in combination with editable quantity fields, this first checks for zero quantities (removing them) and then updates the basket with the shipments form object.
-
continueShopping: Jumps to Cart-ContinueShopping which checks for the last visited in the click stream redirecting the user to this page.
-
checkoutCart: Calls Cart-COStart which prompts the user to decide what type of checkout they would like to make (guest or registered).
-
unregistered: Jumps directly to the shipping page, the user has indicated they would like to check out as a guest.
-
register: Takes the user through the registration process, logging them in and returning them to the cart page.
-
login: The user is logged in and taken to the shipping page
Cart-COStart Sub-Pipeline
The COStart sub-pipeline within the Cart pipeline starts the checkout process. It validates that the basket total could be calculated (not N/A,) that the products represented by the line items are still available on the site and that any coupons added to the basket are valid. If successful, the pipeline jumps to the COCustomer pipeline’s Start node.
COCustomer Pipeline
The first step of the checkout process is to provide an option to the visitor to choose checkout type (returning, guest or create account)
we will assume the visitor selects to proceed with an‘unregistered user’ checkout process.
Next, the ‘COShipping-Start’ pipeline/Start node is called.
COShipping Pipeline
The COShipping-Start pipeline Start node is the starting point for single shipping scenario. 每一种shipping的开始。
After performing the steps outlined above, this pipeline displays an ICN that asks for visitor input of where they want their items to be delivered.
Once a shipping address is entered successfully, the UI makes an ajax call to the public pipeline COShipping-UpdateShippingMethodList, which calculates the applicable shipping methods for this basket.
In BM, in the Shipping Methods module, rules and costs can be defined for each shipping method which will be considered while calculating this list of methods and costs. The interface (view) is then updated with the applicable shipping methods and costs. Once the user has selected an applicable shipping method and chosen to continue checkout, the pipeline reviews the basket and makes sure that there are no empty shipments (if some basket manipulation has been done
for example). Next, if there is not already a shipping address, one is created on the shipment. Lastly, the shipping method for the shipment is updated with the selected method. All values are set based on the forms value. The pipeline then exits with a jump node to the ‘COBilling-Start’ pipeline/Start node.
COBilling Pipeline
The COBilling-Start pipeline is the starting point for billing. This pipeline implements the billing logic. It is responsible for providing the payment method selection as well as entering a billing address. Again, the same steps outlined above are taken before rendering the template.
If the visitor had selected in the shipping form to use the same address for billing, then the address will be pre-populated from relevant fields.
Payment Methods Module
Payment methods can be defined in the Payment Methods module of Business Manager. This module gives a merchant control over the payment methods the storefront will accept and under which circumstances. 决定哪些情况下用什么支付方式
As part of step 3 (prepare the view) for the billing page, we will retrieve a list of applicable payment methods and cards. 获取可用支付方式
When the user submits payment information, that payment information is validated against any rules defined in business manager for that payment method/card. If the payment information is valid, a payment instrument is created based on the data submitted in the form. There can be multiple payment instruments since an order can be paid partially with a credit card and partially with a gift card, certificate or even multiple credit cards.
Once the payment method is successfully created, the pipeline exits with a jump node to COSummary
COSummary Pipeline
The summary.isml template in the COSummary pipeline displays the totals, shipping, billing and payment panels at the right side of the checkout page. Since the user may not interact with data on this page, we only perform steps 1 and 3. Once the ‘Submit’ button is clicked by the visitor, the ‘PlaceOrder’ action for the button calls the COPlaceOrder pipeline.
COPlaceOrder Pipeline
This pipeline is responsible to create an order from the current basket.
The business process for the pipeline is as follows:
-
Gets the existing basket 获取已存在basket
-
Makes sure the shipments are in order 确保配送信息
-
Calculates the cart 计算cart
-
Validates the payment 验证支付
-
Checks inventory of product line item 检查商品库存
-
Checks coupons to make sure they are still valid 检查优惠券可用性
After these final checks are complete, inventory for the order is reserved using the CreateOrder2 pipelet and a database transaction is opened. This pipelet creates an Order based on the specified Basket. If the order could be created successfully, it will be in status CREATED. The Basket will be removed from the session and marked for removal.
Next is the process of creating an order number and processing the payment.
The processing of the payment method ends with either:
支付处理的结果
-
-
Authorize
-
End
-
Decline
-
Error
-
When the payment is authorized, the PlaceOrder sub-pipeline is called. The PlaceOrder sub-pipeline is responsible for creating the order, and setting the order confirmation status. The pipelet PlaceOrder decrements inventory for all products contained in the order. (Means the pipelet ReserveInventoryForOrder must not be subsequently called.) The pipelet redeems all coupons contained in the order.
Once the order is placed and the database transaction has successfully been committed, a confirmation email is sent to the buyer. The pipeline will then exit with a jump node to
COSummary-ShowConfirmation which displays a confirmation ICN node to the buyer that gives the buyer the option of creating an account. If the order creation has failed, the pipeline exits with a jump node back to the order summary page.