Interchange sports a completely flexible item ordering scheme. One practical implementation can always be seen in the latest demo catalog shipping with Interchange; the latest demo catalog is called Standard.

Just as in many other Interchange demo catalogs, order-related files are kept in the CATROOT/pages/ord/ directory. The most important file would probably be CATROOT/pages/ord/basket.html which shows order basket contents, and is displayed to the user every time an item is added to it, or the user explicitly requests it.


It is not strictly necessary to display the basket page every time an item is ordered, but most customers will be confused if you don't give them a clear visual consequence of their ordering action.

An alternative to a separate basket page could be a side-bar menu that would display cart contents in a summarized form, and be visible on all pages. However, it would still be useful to display the complete basket page to the users when they are about to stop ordering and proceed with the check-out routine.

Besides just listing electronic cart contents, the basket page usually also allows for item removal (or quantity selection in general) and total price recalculation.

In general, the body of the basket page is a HTML form. Strictly speaking, it could just be a normal list of contents (without the <form> element), but then you couldn't request any actions on the items (such as their removal from the cart).

At minimum, the basket page will contain the [item-list] tag that will loop over all items in the cart and display them. Any Interchange tags can be used on the page, and you can freely have multiple item lists (the basket page is in no way special and does not place any restrictions on content).

Placing Items in the Basket

Interchange supports a number of ways to add an item to the basket. You can order an item by using both form-based (button-clicking) and link-based (link-visiting) methods.

Link-based Ordering

Link-based ordering is implemented through the [order] tag. You should check the [order] reference page for complete documentation, but let's give a summary of its functionality here. In general, ITL code

[order code=SKU quantity=NUMBER href=URL cart=NAME ]Link text</a>

expands into an appropriately-constructed HTML link. Clicking a link places the item of specified SKU number in the cart and displays the basket page. The code parameter should be a valid product SKU (listed in one of the products tables), and is the only required parameter. href allows some page other than the default basket to be displayed once the item has been added to the cart. cart selects the shopping cart the item will be placed in (you see, the default cart is called main, but Interchange is always a step ahead).

The [order] tag supports a number of attributes (more than we've shown above), but the same effect as above can be achieved with the [page] or [area] tags as well. Here are a few lines, all equal in effect:

Order a [order TK112]Toaster</a> today!
Order a [page order TK112]Toaster</a> today!

Order a <a href="[area order TK112]">Toaster</a> today!
Order a <a href="[area href=order arg=TK112]">Toaster</a> today!

Order a <a href="[area href=order form='mv_order_item=TK112']">Toaster</a> today!

"This is all nice and well", you might say, "but how do I create the link when item data fields (such as SKU, description or price) are not known in advance?". Well, this will be the case if you're creating a flypage or displaying results based on a user search operation. The procedure is, of course, exactly the same; you could just be uncertain about where to stick in the additional ITL tags. Here's a clarifying example:

Order a [order [item-code]][item-field name]</a> today!

Form-based Ordering

Form-based ordering comes handy when you want to implement more complex ordering schemes. Consider the same ordering example as above (a toaster of product SKU TK112) implemented using forms:

<form action="[process href=order]" method="post">
  <input name="mv_order_item"     type="hidden" value="TK112"      />
  <input name="mv_order_quantity" type="text"   value="1" size="3" /> toasters 
  <input value="Order!"           type="submit"                    />

Although the readability above suffers due to HTML elements and quoting, it's easy to dissect it to components. <form> and <input> are standard HTML elements. We care to supply type="text" with text fields for clarity, but that's the default type and can be safely omitted. What's left to note is that the <input> element names are of predetermined values, and that's only reasonable — you need to set those variables that you know Interchange will look for (otherwise this would be a waste of time). In our situation this includes setting mv_order_item (item SKU number), mv_order_quantity (item quantity) and mv_todo (desired form action). For a complete list of user mv variables, see .

You might notice we added the quantity field in the example above. From its implementation, you see that making special mv variables contain user input is extremely easy. What's more, input placeholders do not have to be a text fields as in our example; it can be a list, checkbox or a complex set of HTML widgets!

Interchange supports "stacking" of variables. This allows us to order different items ("batches") at once:

<form action="[process href=order]" method="post">
  <input name="mv_order_item"     type="hidden" value="TK112"            />
  <input name="mv_order_quantity" type="text"   value="1"       size="3" /> Standard Toaster <br/>
  <input name="mv_order_item"     type="hidden" value="TK200"            />
  <input name="mv_order_quantity" type="text"   value="1"       size="3" /> Super Toaster
  <input value="Order!"           type="submit"                          />

Items that have a quantity of zero (or blank) will be skipped, and only items with a positive quantity will be placed in the basket.

Items created "on fly"

Note that "on the fly" items are those that do not exist in any of the products databases, and are literally "put together" on the fly. This is unrelated to Interchange flypage functionality.

If you setup the OnFly config directive, Interchange will be able to add items to user's basket even if they're not listed in any of the products databases.

A basic on-fly item can then be generated like this:

<a href="[area form="
  mv_order_fly=description=An on-the-fly item|price=100.01
"]">Order item 000101</a>

Or, through a proper Submit button:

<form action="[process href=order]" method="post">
  <input type="hidden" name="mv_order_item" value="000101">
  Qty: <input size="2" name="mv_order_quantity" value="1">
  <input type="hidden" name="mv_order_fly" value="description=An on-the-fly item|price=100.01">
  <input type="submit" value="Order button">

A lot of things might look weird in the above example, but it is all valid ITL code.

The form parameter mv_order_fly can contain any number of fields which define attributes for our on-fly item. Fields are separated by the pipe (|) character and contain value-parameter pairs separated by an equal (=) sign.


To show description for the on-fly item, you must use the item-description tag; [item-field description] or [item-data products description] will not work since both try referencing existing fields in products databases.

Similarly, an attempt to generate a flypage for an on-fly item will fail, resulting in display of the SpecialPage missing URL.

Multiple items can be ordered at once by stacking the variables, as we've shown already. However, if there is only one mv_order_item instance defined, then you can stack mv_order_fly variables which will result in their concatenation just as if you separated them with pipes. Here's an example, equal in effect to the previous one:

<a href="[area form="
  mv_order_fly=description=An on-the-fly item
"]">Order item 000101</a>

Order Groups

We've seen variable stacking at work above, but there's more to it. Imagine you had a master item and accompanying accessories which only make sense together with the main item. You could order them at once using ordinary stacking - no problem there, but what if you also wanted accessories or options removed at the same time the master item is removed from the cart? In the simplest form, this is achieved by ordering items as usual, while defining mv_order_group. The first item in the list is then treated as the master item, and all other are sub-items.

<form action="[process href=order]"  method="post">
  <input name="mv_order_group" type="hidden" value="1"         />
  <input name="mv_order_item"  type="hidden" value="00-0011"   />
  <input name="mv_order_item"  type="hidden" value="00-0011a"  />
  <input value="Order Mona Lisa with frame" type="submit"      />

Incredible, but you can also define multiple master items! All you need to do is define a mv_order_group for each individual item. Master item "owns" all subsequent sub-items until the next master is defined.

<form action="[process href=order]"  method="post">
  <input name="mv_order_group" type="hidden" value="1"         />
  <input name="mv_order_item"  type="hidden" value="00-0011"   />
  <input name="mv_order_group" type="hidden" value="0"         />
  <input name="mv_order_item"  type="hidden" value="00-0011a"  />
  <input name="mv_order_group" type="hidden" value="1"         />
  <input name="mv_order_item"  type="hidden" value="19-202"    />
  <input name="mv_order_group" type="hidden" value="0"         />
  <input name="mv_order_item"  type="hidden" value="99-102"    />
  <input value="Order Mona Lisa and more!"   type="submit"     />

The example shows a 4-item order form. Items 1 and 3 are master items, items 2 and 4 are sub-items. If a master item of SKU 00-0011 is deleted from the basket, 00-0011a will be deleted too. If 19-202 is deleted, then 99-102 will be deleted along.


Use of HTML checkboxes for this type of thing could be inappropriate because they do not pass a value when unchecked. The value then remains defaulting to last used value. It is preferable to use radio groups or select/drop-down widgets instead. If you use checkboxes, make sure to explicitly clear mv_order_group and mv_order_item somewhere on the form page. You can re-use the following code snippet:

[value name=mv_order_group set='']
[value name=mv_order_item  set='']

mv_mi and mv_si attributes are set to the group and sub-item status of each item. The group, contained in the attribute mv_mi, is a meaningless yet unique integer. All items in a group will have the same mv_mi value. The attribute mv_si is 0 if the item is a master item, and 1 if it is a sub-item.

Basket display

Basket pages list electronic cart contents and usually allow order contents to be adjusted; items can be removed, ordered in different quantities etc.

It is possible to have an multiple (different) basket pages, because they're in no way special. It is also possible to have multiple shopping carts, for example in cases where the same user maintains a buy and sell list. Multiple basket pages could also be used where items have many accessories and, depending on the item ordered, you send customers to different, item-specific pages to choose accessories. The possibilities are endless, it's just about evaluating your actual needs.

The name of the basket page to be displayed upon item order can be defined in a few ways:

  • You can set order value of the SpecialPage directive to the page you want displayed on item order

  • You could use the [order] tag in form of [order code=SKU page=NAME]Order it!</a> to define the basket page

  • If you already are on the order page and want to "jump" next, use the standard form, setting some of mv_orderpage, mv_nextpage, mv_successpage and mv_failpage variables.

Multiple Shopping Carts

Interchange allows you to define and maintain multiple shopping carts for each user. The default shopping cart named main is created when the user session starts. If the user orders an item of SKU M1212 through the following link:

[order code=M1212 cart=layaway]Order this item!</a>

then the item will be placed in the cart named layaway, and not main. Consequently, the use won't see the just-ordered item on the basket page because the default shopping basket displays contents of the main cart only. The easiest way to support multiple carts is to copy the default basket page (CATROOT/pages/ord/basket.html) to a new file, insert [cart layaway] code snippet at the top, and specify it as the target page for the [order] tag:

[order code=M1212 cart=layaway page=ord/layaway_basket]Order this item!</a>

Now the contents of the layaway cart would be displayed on the appropriate page. Most of the fundamental cart management ITL tags support the nickname option, allowing cart name to be chosen. Using nickname is handy, and has no permanent effect, the default cart remains set at value of main. A sticky attribute could be set to change the default cart name until further notice. This is convenient, but you must remember to use [cart main] to get back to the primary cart!

And for the sake of completeness, here's the above example using form-based ordering:

<form action="[process href=order]" method="post">
  <input name="mv_order_item"     type="checkbox" value="M1212"   /> Item M1212
  <input name="mv_order_quantity" type="text"     value="1"       /> Quantity
  <input name="mv_cartname"       type="hidden"   value="layaway" />
  <input value="order this item!" type="submit">

DocBook! Interchange!