Below is a list of functions currently in the tool kit. There is also example template code using each function. You can see by copying and pasting the example code that you can quickly enhance your page templates with features you thought were not possible without extensive coding or over-priced modules. For those who want more than the simple functions listed, you can build expressions and create variables using the built in mivascript functions listed in the reference manual. Use mvassign and mveval to build complex expressions. Study the examples and create your own customizations of the page templates.
Detailed List of Tool Kit Functions with Examples:

For the purpose of the string function demo, the following text is used. "This page demonstrates the use of the tool kit function library to create new variables and make changes to existing variables inside the Merchant 5.x store morph templates. The %product_name% can easily replace a token within a description field. #Alternate Description: Can have other text here, e.g. greeting"

1. Use the substring to show the first x characters in a string. In this example,
<mvt:item name="toolkit" param="substring|l.all_settings:product:descrip,1,20" />,
we display the first 20 characters in the product description.
This page demonstrat

Alternatively, if you want to save the substring to a new variable, you can use the newsubstring function. For example,
<mvt:item name="toolkit" param="newsubstring|new_desc|l.all_settings:product:descrip,1,200" />
This is used in the balloon tooltip functionality as seen here.

2. Use the gettoken to separate a string using a delimiter character. In this example,
<mvt:item name="toolkit" param="gettoken|l.all_settings:product:descrip,#,2" />
we display the text after the # in the product description.
Alternate Description: Can have other text here, e.g. greeting
A variation of this is the vgettoken which allows use of a variable in the last parameter instead of a constant. So you could change the 2 above to a variable.

If you want to save the result to a variable rather than display immediately, you can add a third parameter to the function. For example:
<mvt:item name="toolkit" param="gettoken|l.all_settings:product:descrip,#,2|newtext" />
would save the portion of the full text to a variable called newtext. An example of this feature can be used with other tool kit functions to display random products from a list of product codes. Below is example code. Note that the random function uses a number one less than the total number of codes in the list of codes. Then one is added back to it after the random number is obtained.
<br />
<mvt:item name="toolkit" param="sassign|codes|SR_00013#1S_00001#LCS00002#LC_00001#LC_00002#1S_00002#TC_00008" />
<mvt:item name="toolkit" param="sassign|one|1" />
<mvt:item name="toolkit" param="random|nrandom|6" />
<mvt:item name="toolkit" param="math_add|thisone|nrandom|one" />
<mvt:item name="toolkit" param="vgettoken|codes,#,thisone|select_product_code" />
<mvt:item name="toolkit" param="vproduct_find|productfound|select_product_code" />
<img src="&mvt:key_product:image;" border="0">
<br />
&mvt:key_product:name;
<br />
&mvt:key_product:formatted_price;


3. Use the vassign to create and name a global variable from a variable. In this example,
<mvt:item name="toolkit" param="vassign|product_name|l.all_settings:product:name" />

creates a variable named product_name from the dynamic variable l.all_settings:product:name. Then you can use the mvt to evaluate the global:product_name variable.
TOOL KIT v5

<mvt:item name="toolkit" param="vassign|ip|remote_addr" />
Your IP: &mvte:global:ip;
Displays the IP address of the customer.
<mvt:item name="toolkit" param="vassign|camefrom|http_referer" />
<mvt:if expr="NOT ISNULL g.camefrom">
You came from: &mvte:global:camefrom;
</mvt:if>
Displays the url the customer came from.

The nohtml function works just like the vassign except that it will strip html out of the variable before assigning it to the new variable. This is useful for creating a variable for use on the category page or meta tag on the product page that has no html. Then you can use the substring function to limit the number of characters displayed, e.g. a shorter description might have just the first 200 characters of the description with the html stripped out. Replace vassign with nohtml in the example above to use this function. For example, this is used in the balloon tooltip functionality as seen here.

4. Use the sassign to create and name a global variable from a string. In this example,
<mvt:item name="toolkit" param="sassign|greeting|Happy Mother\'s Day" />

creates a variable named greeting from the string "Happy Mother's Day". Note the use of the backslash to escape the apostrophe character. Then you can use the mvt to evaluate the global:greeting variable.
Happy Mother's Day

5. Use the vlength to create and name a global variable which is the length (number of characters) of another variable. In this example,
<mvt:item name="toolkit" param="vlength|name_length|l.all_settings:product:name" />

creates a variable named name_length from the length of the dynamic variable l.all_settings:product:name. Then you can use the mvt to evaluate the global:name_length variable or you can use it in other functions.
11

6. Use the vglosub to replace a string with a dynamic variable inside of another variable. For example, in the product description you can replace the %product_name% with a variable. <mvt:item name="toolkit" param="vglosub|l.all_settings:product:descrip,%product_name%,l.all_settings:product:name" />
In this example it replaces it with the l.all_settings variable.
This page demonstrates the use of the tool kit function library to create new variables and make changes to existing variables inside the Merchant 5.x store morph templates. The TOOL KIT v5 can easily replace a token within a description field. #Alternate Description: Can have other text here, e.g. greeting


7. You can use the same vglosub to replace a string with a variable that you create with the assign commands above in the page template. As example,
<mvt:item name="toolkit" param="vglosub|l.all_settings:product:descrip,greeting,g.greeting" />
use the g.greeting variable as the replacement.
This page demonstrates the use of the tool kit function library to create new variables and make changes to existing variables inside the Merchant 5.x store morph templates. The TOOL KIT v5 can easily replace a token within a description field. #Alternate Description: Can have other text here, e.g. Happy Mother's Day


8. Use the sglosub to replace a string with another string. For example,
<mvt:item name="toolkit" param="sglosub|l.all_settings:product:descrip,function,features" />
replace the word function with the word features in the product description.
This page demonstrates the use of the tool kit features library to create new variables and make changes to existing variables inside the Merchant 5.x store morph templates. The TOOL KIT v5 can easily replace a token within a description field. #Alternate Description: Can have other text here, e.g. Happy Mother's Day

For the purpose of the math demo, the product price is $2.00 and the product cost is $3.00.

9. Use the math_add to calculate the sum of two variables to a new number. For example,
<mvt:item name="toolkit" param="math_add|sum|l.all_settings:product:price|l.all_settings:product:cost" />
sum the price plus the cost to get a variable called sum.
5

10. Use the math_subtract to calculate the difference between two variables to a new number. For example,
<mvt:item name="toolkit" param="math_subtract|difference|l.all_settings:product:cost|l.all_settings:product:price" />
subtract the cost minus the price to get a variable called difference.
1
This function comes in handy if you are bench marking your page development to see how fast pages load and how new code on the page might effect load times. For example, put
<mvt:item name="toolkit" param="vassign|starttime|dyn_time_t" />
at the beginning of the page template. Then at the end of the page template, put
<mvt:item name="toolkit" param="vassign|endtime|dyn_time_t" />
<mvt:item name="toolkit" param="math_subtract|elapsed|endtime|starttime" />
Elapsed Time: &mvte:global:elapsed; seconds


11. Use the math_multiply to save the result of variable1 times variable2 to a new number. For example,
<mvt:item name="toolkit" param="math_multiply|times|l.all_settings:product:cost|l.all_settings:product:price" />
multiply the cost times the price to get a variable called times.
6

12. Use the math_divide to save the result of variable1 divided by variable2 to a new number. For example,
<mvt:item name="toolkit" param="math_divide|result|l.all_settings:product:cost|l.all_settings:product:price" />
multiply the cost times the price to get a variable called times.
1.5

13. Use the currencyformat to format a variable to a text string formatted to the store's currency. For example,
<mvt:item name="toolkit" param="currencyformat|formatted_savings|difference" />
Format the difference between the cost and price to show savings.
Savings: $1.00

14. Use the a combination of functions to show percent savings of one price off another. The mathematical operation needs to be broken down into multiple steps. For example,
<mvt:item name="toolkit" param="math_subtract|difference|l.all_settings:product:cost|l.all_settings:product:price" />
<mvt:item name="toolkit" param="math_divide|result|difference|l.all_settings:product:cost" />
<mvt:item name="toolkit" param="sassign|value2|100" />
<mvt:item name="toolkit" param="math_multiply|times|result|value2" />
<mvt:item name="toolkit" param="math_round|times|times|2" />
obtains the difference between the cost and price. Then divides the difference by the cost. Then multiplies that division result times 100. And finally math_round will round that result to 2 decimal places.
Savings: 33.33%

15. Time/date functions: These functions were used to display the current time and date of our server (offset -4).
<mvt:item name="toolkit" param="set_time_zone|our_time|-4" />
<mvt:item name="toolkit" param="time_t_year|nyear|our_time" />
<mvt:item name="toolkit" param="time_t_month|nmonth|our_time" />
<mvt:item name="toolkit" param="time_t_dayofmonth|ndayofmonth|our_time" />
<mvt:item name="toolkit" param="time_t_hour|nhour|our_time" />
<mvt:item name="toolkit" param="padl|chour|nhour|2|0" />
<mvt:item name="toolkit" param="time_t_minute|nminute|our_time" />
<mvt:item name="toolkit" param="padl|cminute|nminute|2|0" />
<mvt:item name="toolkit" param="padl|csecond|nsecond|2|0" />
<mvt:item name="toolkit" param="time_t_dayofweek|ndayofweek|our_time" />
<mvt:item name="toolkit" param="sassign|days|Sunday#Monday#Tuesday#Wednesday#Thursday#Friday#Saturday" />
<mvt:item name="toolkit" param="vgettoken|days,#,ndayofweek" />
Note: The below values are simulated as this is a 4.x store so the module is not actually installed. See the Tool Kit Demo link below to actually see the module in use.
Our time zone: -4
Current year (our time): 2006
Current month (our time): 5
Current day (our time): 26
Current date (our time): 5 / 26 / 2006
Current hour (our time): 11 (left padded: 11)
Current minute (our time): 7 (left padded: 07)
Current second (our time): 18 (left padded: 18)
Current time (our time): 11:07:18
Current day of week (our time): 6 Friday
mktime_t creates a variable which is the number of seconds since Jan 1, 1970. As example,
<mvt:item name="toolkit" param="mktime_t|utc|year|month|dayofmonth|hours|minutes|seconds|time_zone" />
creates the utc variable. Each of the parameters 3-9 must be a variable for that value; not a hardcoded number. You'll probably use sassign or newsubstring to create those variables.

16. padl creates a variable which is left padded a specific number of characters with a set character from an original variable. As example,
<mvt:item name="toolkit" param="padl|csecond|nsecond|2|0" />
creates the csecond variable from nsecond. It is padded with the 0 character to the left if the length of nsecond is less than 2.

17. padr creates a variable which is right padded a specific number of characters with a set character from an original variable. As example,
<mvt:item name="toolkit" param="padr|csecond|nsecond|2|0" />
creates the csecond variable from nsecond. It is padded with the 0 character to the right if the length of nsecond is less than 2.

18. Use the callurl to pass fields, (eg subscription list, name, email) to a remote program (mvc, php, etc) and return result. The return result can be displayed with the mvt or it can just be ignored, depending on your need for the function. For example it could display the contents of the file or web page at that location or it could do something like sign the customer up for a mailing list. For example,
<mvt:item name="toolkit" param="callurl|sample|http://www.mydomain.com/subscribe.php|POST|sublist,ship_lname,ship_email" />
You could use the mvt of the variable to display the return result, in this case "sample".

You can use vcallurl if you need to have a dynamic url to call. In this function, you would enter a variable for the full url in the 3rd parameter instead of a fixed url. This would be useful if you need to build a url at runtime.

19. Use custom to retrieve a product's custom field value (if it exists), e.g. in the basket screen. It saves the value to a variable of your choosing. For example,
<mvt:item name="toolkit" param="custom|studio|l.all_settings:item:product_id|company" />
<mvt:if expr="g.studio">
Studio: &mvte:global:studio;
</mvt:if>
will check the custom product field "company" for the current product and save the value to a variable called "studio". You can then mvte the studio variable to display it. Note: This function requires use of the Miva Corp built-in custom fields module and that you have created custom product fields.

In admin, you can search a product custom field and display the matching products in a table. If you include your email address you can have the list emailed to you as an attachement. Click the + to the left of the word Utilities and scroll down to the Emporium Plus Tool Kit. Click the link.

Beginning with Tool Kit version 5.163, you can use the product code instead of the product ID by using the function customc. Sometimes the code is available and the ID is not. That said, if the ID is available use the custom function as it is faster.


20. Use attr to retrieve a product's attribute count. It saves the value to a variable of your choosing. For example,
<mvt:item name="toolkit" param="attr|acount|l.all_settings:product:id" />
Count: &mvte:global:acount;
If you use attrc, you can use the variable for the product code in the 3rd parameter.


21. Use cxp to load a category's products into an array. The category ID number is fed into the cxp function. It saves the product count to a variable of your choosing. You can then display the contents of the sub_products array. For example,
<mvt:item name="toolkit" param="cxp|pcount|l.all_settings:subcats:id" />
<mvt:if expr="pcount GT 0">
(&mvte:global:pcount;)
<font size="-2">
<mvt:foreach iterator="sub_product" array="sub_products">
<br>
<a href="&mvt:global:secure_sessionurl;Screen=PROD&Product_Code=&mvta:sub_product:code;">
&mvt:sub_product:name;</a>
</mvt:foreach>
</font>
</mvt:if>

Alternatively, if you do not know the category ID number, you can use the category code by changing the function to cxpc, e.g.
<mvt:item name="toolkit" param="cxpc|pcount|g.Category_Code" />

22. Use parentcat to load the parent categories into an array. It saves the category count to a variable of your choosing. You can then display the contents of the parent_categories array. This function does not capture the image urls, however, if your images are named according to their category code, eg category code "mycat" uses an image called "mycat.jpg" you could easily build the dynamic img src path. Alternatively you can use the functions catimage or cattreeimage (see below) to retrieve the image urls. To display parent category names, you could use code like
<mvt:item name="toolkit" param="parentcat|pccount" />
<mvt:foreach iterator="parent_category" array="parent_categories">
&mvt:parent_category:name;
</mvt:foreach>


23. Use subcat to load a parent's subcategories into an array. It saves the subcategory count to a variable of your choosing. You can then display the contents of the sub_categories array. This function does not capture the image urls, however, if your images are named according to their category code, eg category code "mycat" uses an image called "mycat.jpg" you could easily build the dynamic img src path. Alternatively you can use the functions catimage or cattreeimage (see below) to retrieve the image urls. To display subcategory names, you could use code like
<mvt:item name="toolkit" param="subcat|ccount|g.Category_Code" />
<mvt:if expr="ccount GT 0">
<mvt:foreach iterator="sub_category" array="sub_categories">
&mvt:sub_category:name;
</mvt:foreach>
</mvt:if>

Similar functions exist for subcat2, subcat3, subcat4, subcat5, and subcat6. When used together you can display the entire (up to 7 levels deep) category tree expanded. An example tree using some of these functions should get you started. You can see the effect at the bottom of this page. You can also make the typical left column expanded category tree. Simply put the example code in a new page called OPEN. Then use the render token <mvt:item name="toolkit" param="render|OPEN" /> to place that tree on any page in the store. A variation of this template is the unordered list tree that Barrett posted in the Miva Forum.

24. Use pgroup to identify all of the price groups a customer is in. It saves the price group count to a variable of your choosing. You can then display the names of the price groups the current customer is in.
<mvt:item name="toolkit" param="pgroup|pcount" />
<mvt:if expr="g.pcount GT 0">
<mvt:foreach iterator="customer_pgroup" array="customer_pgroups">
<br>&mvt:customer_pgroup:name;
</mvt:foreach>
</mvt:if>
Combine this function with other functions. In the example below you can set order minimums for groups. This example sets an order minimum of $50.00 for customers in the Platinum price group. It has a custom message which is displayed on the standard order minimum page. Put this block of code at the very top of the OSEL page template.
<mvt:item name="toolkit" param="subtotal|basketsubtotal" />
<mvt:if expr="g.basketsubtotal LT 50">
<mvt:item name="toolkit" param="pgroup|pcount" />
<mvt:if expr="g.pcount GT 0">
<mvt:foreach iterator="customer_pgroup" array="customer_pgroups">
<mvt:if expr="l.settings:customer_pgroup:name EQ 'Platinum'">
<mvt:item name="toolkit" param="sassign|showmin|1" />
</mvt:if>
</mvt:foreach>
</mvt:if>
<mvt:if expr="g.showmin">
<mvt:item name="toolkit" param="sacreate|error_message|Your price group requires $50.00 minimum order!|," />
<mvt:item name="toolkit" param="sassign|Error_Message_Count|1" />
<mvt:item name="toolkit" param="vassign|Error_Messages|l.all_settings:error_message" />
<mvt:item name="toolkit" param="render|OMIN" />
<mvt:exit>
</mvt:if>
</mvt:if>


25. Use agroup to identify all of the availability groups a customer is in. It saves the availability group count to a variable of your choosing. You can then display the names of the availability groups the current customer is in.
<mvt:item name="toolkit" param="agroup|acount" />
<mvt:if expr="g.acount GT 0">
<mvt:foreach iterator="customer_agroup" array="customer_agroups">
<br>&mvt:customer_agroup:name;
</mvt:foreach>
</mvt:if>


26. Use pgroup-p to identify all of the price groups a product is in. It saves the price group count to a variable of your choosing. You can then display the names of the price groups the product is in.
<mvt:item name="toolkit" param="pgroup-p|prdcount|g.Product_Code" />
<mvt:if expr="g.prdcount GT 0">
<mvt:foreach iterator="product_pgroup" array="product_pgroups">
<br>&mvt:product_pgroup:name;
</mvt:foreach>
</mvt:if>


27. Use agroup-p to identify all of the availability groups a product is in. It saves the availability group count to a variable of your choosing. You can then display the names of the availability groups the product is in.
<mvt:item name="toolkit" param="agroup-p|aprdcount|g.Product_Code" />
<mvt:if expr="g.aprdcount GT 0">
<mvt:foreach iterator="product_agroup" array="product_agroups">
<br>&mvt:product_agroup:name;
</mvt:foreach>
</mvt:if>


28. Use breadcrumb to create an array of category names and codes from the current g.Category_Code up to the top level parent. You can check the number of items in the array. If there is one or more, you can display the array as a breadcrumb display. A category code must be used to start the function. In most cases it will be g.Category_Code which is available on a product page when that page is reached via a link on the category page.
<mvt:item name="toolkit" param="breadcrumb|b_count|g.Category_Code" />
<mvt:if expr="b_count GT 0">
<a href="http://www.yourdomain.com/mm5/merchant.mvc">Home</a>
<mvt:foreach iterator="breadcrumb" array="breadcrumbs">
>
<mvt:if expr="g.Category_Code EQ l.settings:breadcrumb:code">
<b> <a href="http://www.yourdomain.com/c/&mvte:breadcrumb:code;/&mvta:breadcrumb:name;.html">
&mvt:breadcrumb:name;</a></b>
<mvt:else>
<a href="http://www.yourdomain.com/c/&mvte:breadcrumb:code;/&mvta:breadcrumb:name;.html">
&mvt:breadcrumb:name;</a>
</mvt:if>
</mvt:foreach>
</mvt:if>


29. Use sexists to check for the existance of a file. Assign text to the file name. Then using either sglosub (or vglosub for variables), you can replace part of that text string and assign to a variable. Then plug that variable into the sexists function to check for the existance of the file. The result will be 1 if the file is present. The file has to be on the same domain as the merchant program and the path must be virtual, ie no http://domainname in the path. In the example, vpath will be 1 if the file exists.
<mvt:item name="toolkit" param="sassign|filename|/mm5/%prog_name%" />
<mvt:item name="toolkit" param="sglosub|filename,%prog_name%,merchant.mvc" />
<mvt:item name="toolkit" param="sexists|vpath|filename" />



30. Use vproduct_find to display basic product info (name, code, thumbnail, image, price, and cost) on any page (storefront, basket, etc) in the store. The 2nd value is true if the product is found. The 3rd parameter is a variable. The 4th parameter is optional. Normally, you only display active products. But if you put an A in the 4th parameter, it will display both active and inactive products. In the example, the thumbnail, name and formatted price are displayed.
<mvt:item name="toolkit" param="vproduct_find|productfound|Product_Code" />
<mvt:if expr="productfound GT 0">
<mvt:if expr="NOT ISNULL l.settings:key_product:thumbnail">
<img src="&mvte:key_product:thumbnail;" border="0" width="30" height="20">
</mvt:if>
&mvte:key_product:name;
&mvte:key_product:inv_short;
&mvte:key_product:formatted_price;
<mvt:if expr="l.settings:key_product:costlessadjprice GT 0">
<font color="red">
(savings: &mvte:key_product:formatted_costlessadjprice;)
</font>
</mvt:if>
</mvt:if>


Alternatively, you can use sproduct_find and insert the raw product code in the 3rd parameter instead of using a variable.


31. Use render to display the contents of any page template at any location in another page. For example, if you have a page template called MINI which has only the mini-basket as its content, you can insert that page content anywhere inside another page. Page templates are created in Merchant 5 by clicking admin > stores > pages and clicking the Add button. The page code is case sensitive. In the example, a page called MINI is pulled into another page.
<mvt:item name="toolkit" param="render|MINI" />
This same technique can be used for things like inserting a "Specials" category into your storefront screen. The technique for doing this is explained here.
You can even replace a whole page. For example, let's say you want to force customers to login before they view some or all pages in your store. Simply put the following code at the beginning of each page you want to restrict and it will display the login screen instead. No need to buy a separate module for that simple task.
<mvt:if expr="basket:cust_id EQ 0">
<mvt:item name="toolkit" param="render|LOGN" />
<mvt:exit />
</mvt:if>
Like the forced login, you can replace a page if the customer does not agree to terms, i.e. an agreement page. For example, on the OSEL page you could have
<mvt:if expr="g.TK NE 1">
<mvt:item name="toolkit" param="render|SFNT" />
<mvt:exit>
</mvt:if>
Create a new page called AGREE. On the OCST page template instead of the hidden input for screen going to OUSL, you could go to AGREE. Then in the form on the AGREE page, make sure you have a hidden input called TK and the Screen going to OSEL. You can see it working at our test store. If you are using the upsell feature in your store, you will need to adjust the screen inputs accordingly.
You can use vrender if the second parameter is a variable rather than a hard coded string.
You can also have an optional 3rd parameter in the render function. Instead of automatically displaying the page requested, it saves the page to a variable (the 3rd parameter). You can then use Tool Kit code to extract data or sections of text from that variable. An example usage of this is the search of a page called ARCHIVE to find obsolete product codes and replace them with alternate codes, then redirect to the new page.
<mvt:item name="toolkit" param="render|ARCHIVE|archive_list" />


32. Use no_apostrophe to strip apostrophe characters out of a string. For example,
<mvt:item name="toolkit" param="no_apostrophe|new_descrip2|new_descrip" />
takes the variable new_descrip and removes the apostrophe. It saves the new value to the variable new_descrip2. This is particularly useful when you need the string passed to a javascript function. This is used in the balloon tooltip functionality as seen here.


33. Use bestseller to list the best sellers in a specific category. For example,
<mvt:item name="toolkit" param="bestseller|pcount|g.Category_Code|5" />
<mvt:if expr="pcount GT 0">
Best Sellers
<mvt:foreach iterator="bestsell" array="bestseller">
<br>
<a href="&mvt:global:sessionurl;Screen=PROD&Product_Code=&mvta:bestsell:code;&Store_Code=&mvta:store:code;">
&mvte:bestsell:name;<a>
&mvte:bestsell:formatted_price;
</mvt:foreach>
</mvt:if>
shows the best sellers in the current category. The 4th parameter is the number of items to display, eg 5. Optionally you can put a 1 as the 5th parameter to hide out of stock products. Leave it blank if you want to include out of stock products.

Alternatively you can display the best sellers storewide by changing the 3rd parameter to the word ALL, ie replace g.Category_Code with ALL in the above example. You can even include the actual number sold if you want your customers to know how popular the items are by using the variable &mvte:bestsell:counter;

In admin, you can also see the top XX number of best sellers in the store. Go to admin > store and click the + to the left of utilities and then click on the link for Emporium Plus Tool Kit.


34. Use last to list the most recent products added to the store. Great for a "What's New" list. For example,
<mvt:item name="toolkit" param="last|pcount|10" />
<mvt:if expr="pcount GT 0">
<table border="0" width="200">
<th>What's New</th>
<tr><td align="center">
<font size="-1">
<mvt:foreach iterator="newproduct" array="new">
<a href="&mvt:global:sessionurl;Screen=PROD&Product_Code=&mvta:newproduct:code;&Store_Code=&mvta:store:code;">
&mvt:newproduct:name;</a>
<br>
&mvt:newproduct:formatted_price; <br><br>
</mvt:foreach>
</font>
</td></tr>
</table>
</mvt:if>
creates an array of the last 10 items added to the store. The 3rd parameter is the number of items to display, eg 10. Optionally you can put a 1 as the 4th parameter to hide out of stock products. Leave it blank if you want to include out of stock products.

A variation of this is the function lastcat. Everything is identical except use lastcat instead of last in the function. It can only be used on category pages. It displays the most recent products added to the current category.


35. Use basket to display the quantity and subtotal in the basket. For example,
<mvt:item name="toolkit" param="basket|itemcount" />
<mvt:if expr="g.itemcount GT 0">
Items in Basket: &mvte:toolkit:basketcount;
<br>Subtotal: &mvte:toolkit:baskettotalF;
<mvt:else>
Basket Empty
</mvt:if>
Other variables available with this function are basketweight, baskettotal, basketsubtotal, basketsubtotalF, basketother, basketotherF

If you want a full minibasket with products listed, you can use the tool kit to do that too. Go to pages [add] and create a new page. Give it a code of TKMINI and call it a mini basket. Insert the code from this example page. Then you can use the tool kit render function to insert that page inside any other page in the store.
<mvt:item name="toolkit" param="render|TKMINI" />


36. Use random to generate a random number. For example,
<mvt:item name="toolkit" param="random|nrandom|100" />
<br>Random number: &mvte:global:nrandom;
generates a random number between 0 and 100. This could be used in conjunction with the sassign, vglosub, and vcallurl functions to insert a random file (text) into a web page. You would need a text file for each of the numbers that could be generated, e.g. 0.htm, 1.htm, 2.htm ..... 100.txt. More than likely, you will use a much smaller number for your random generation to match text files. A missing file would generate an error, so all have to be present.
<mvt:item name="toolkit" param="sassign|randomurl|http://www.pinemporium.com/%nrandom%.txt" />
<mvt:item name="toolkit" param="vglosub|randomurl,%nrandom%,g.nrandom" />
<mvt:item name="toolkit" param="vcallurl|text_insert|randomurl|GET|" />
&mvte:global:text_insert;
If the random file contains html tags which you want to render correctly, use &mvt instead of &mvte

A variation of the random function is vrandom. For the third parameter you use a variable instead of a constant. Below is an example of displaying a random thumbnail from an array of products, e.g. on the category or product list page using several tool kit functions.
<mvt:item name="toolkit" param="sassign|one|1" />
<mvt:item name="toolkit" param="sassign|delimiter|#" />
<mvt:foreach iterator="product" array="products">
<mvt:if expr="l.settings:product:thumbnail">
<mvt:item name="toolkit" param="math_add|numberinstring|numberinstring|one" />
<mvt:item name="toolkit" param="concat|newstring|newstring|l.all_settings:product:code" />
<mvt:item name="toolkit" param="concat|newstring|newstring|delimiter" />
</mvt:if>
</mvt:foreach>
<mvt:if expr="g.numberinstring GT 0">
<mvt:item name="toolkit" param="math_subtract|result|numberinstring|one" />
<mvt:item name="toolkit" param="vrandom|nrandom|result" />
<mvt:item name="toolkit" param="math_add|thisone|nrandom|one" />
<mvt:item name="toolkit" param="vgettoken|newstring,#,thisone|select_product_code" />
<mvt:item name="toolkit" param="vproduct_find|productfound|select_product_code" />
<img src="&mvt:key_product:thumbnail;" border="0">
</mvt:if>
An example can be seen at this category.


37. Use states to generate an array of states alphabetically by name, not state code. For example,
<mvt:item name="toolkit" param="states" />
Thus, on the customer account create page template (customer fields section) replace
<mvt:item name="states" param="Customer_ShipStateSelect" />
with
<mvt:item name="toolkit" param="states" />
<select name="Customer_ShipStateSelect">
<option value="">Outside US</option>
<mvt:foreach iterator="state" array="states">
<mvt:if expr="l.settings:state:code">
<mvt:if expr="Customer_ShipStateSelect EQ l.settings:state:code">
<option value="&mvte:state:code;" selected>&mvte:state:name;</option>
<mvt:else>
<option value="&mvte:state:code;">&mvte:state:name;</option>
</mvt:if>
</mvt:if>
</mvt:foreach>
</select>
It is slightly different for the ocst page and others which have a state selector. Likewise, this is for the "ship to" section. It is slightly different for the "bill to" section.


38. Use nextprevious on the product page to navigate to the previous or next product in the category. This only works when going from the category page to the individual product page and the category code is in the url. The below code goes on the product page in whatever location you want it.
<mvt:item name="toolkit" param="nextprevious|l.all_settings:product:code" />
<mvt:if expr="l.settings:tkskip:previous">
<a href="&mvte:global:sessionurl;Screen=PROD&Product_Code=&mvte:tkskip:previous;&Category_Code=&mvte:global:Category_Code;">
Previous</a>
</mvt:if>
<mvt:if expr="l.settings:tkskip:next">
<a href="&mvte:global:sessionurl;Screen=PROD&Product_Code=&mvte:tkskip:next;&Category_Code=&mvte:global:Category_Code;">
Next</a>
</mvt:if>


39. Use concat to combine one variable with another. For example:
<mvt:item name="toolkit" param="concat|newstring|var1|var2" />
You can include a 5th parameter which would be a delimiter. If you surround with the apostrophe it is a string literal, otherwise it is a variable. If you preceed it with the minus character it is inserted between var1 and var2. If no minus is used, it is appended after the var2.
<mvt:item name="toolkit" param="concat|newstring|var1|var2|'#'" />


40. Use prompt to display the attribute and option prompts instead of the codes in the basket and invoice screens. To initialize the variables, go to the basket page template. Click the link at the top called basket contents. Insert
<mvt:item name="toolkit" param="prompt" />
on the line immediately before
<mvt:foreach iterator="option" array="item:options">
Then about 10 lines down you will see the lines of code that display the attribute and option codes. Replace &mvt:option:attr_code; with &mvt:option:attr_prompt; and &mvt:option:opt_code; with &mvt:option:opt_prompt; Do NOT replace &mvt:option:data_long; or &mvt:option:data;


41. Use quick to fill an array with product info for listed product codes. The third parameter for the quicklist is a list of product codes separated by commas. Optionally you can put a 1 as the 4th parameter to hide out of stock products. Leave it blank if you want to include out of stock products. The function tests for product existance and availability group status and works great for things like featured products. Example display:
<mvt:item name="toolkit" param="quick|pcount|1AA00100,1S_00002,PB_00001,1S_00004,LCS00002" />
<table border="0">
<mvt:foreach iterator="quicklist" array="quicklists">
<tr>
<td align="center" valign="top">
<mvt:if expr="NOT ISNULL l.settings:quicklist:thumbnail">
<img src="&mvt:quicklist:thumbnail;" border="0" width="50" height="50">
<mvt:else>
No Photo
</mvt:if>
<br>
<a href="&mvt:global:sessionurl;Screen=PROD&Product_Code=&mvta:quicklist:code;">
&mvt:quicklist:name;</a>
<br>
&mvt:quicklist:formatted_price;
<br><br>
</td>
</tr>
</mvt:foreach>
</table>
A variation of the quick is the vquick. The third parameter is a variable instead of a hard coded string of product codes. This is useful for the alsobought function using a custom product field called alsobought. See the alsobought function further down in this list.

A complex use of the vquick function and several other Tool Kit functions is a Shopping Pad (version 5.248 or newer) where a customer can enter a list of product codes and generate a page that the customer can click one button to put the whole list in the basket.

Shopping Pad with vquick and Multi-Product Add - Example CSSUI [full page code]


42. Use pgrpinsert to insert a customer into a price group. This could be used on the sfnt page to insert a customer when creating a new account. Give customers a discount incentive to create an account. It could also be used on the invc page to insert a customer based on the product purchased. This would be excellent if you sell memberships and want to automatically add them to a price group based on the membership product they purchase. An example for the sfnt page is:
<mvt:if expr="g.Action AND g.Action EQ 'ICST'">
<mvt:item name="toolkit" param="pgrpinsert|maxgrp|Chairman" />
<mvt:if expr="maxgrp">
Price Group: &mvte:global:maxgrp;
</mvt:if>
</mvt:if>
Another use might be to redeem a "group" coupon. For example, put the following on the ACED (account edit page) to enter customers into the coupon special price group if they enter coupon code SURPRISE and click the redeem button.
Enter coupon for price group membership:
<form method="post" action="&mvt:global:secure_sessionurl;">
<input type="hidden" name="Store_Code" value="&mvte:global:Store_Code;">
<input type="hidden" name="Action" value="">
<input type="hidden" name="Screen" value="ACED">
<input type="text" name="tkcoupon" value="" size="15">
<input type="submit" name="trash" value="Redeem">
</form>
<mvt:if expr="g.tkcoupon">
<mvt:if expr="g.tkcoupon EQ 'SURPRISE'">
<mvt:item name="toolkit" param="pgrpinsert|maxgrp|Coupon Special" />
<mvt:if expr="g.maxgrp">
You are now entered into the &mvte:global:maxgrp; price group.
</mvt:if>
<mvt:else>
Invalid
</mvt:if>
</mvt:if>


43. Use vacreate to create an array from a string in which the data is in a variable separated by a delimiter. An example might be a custom product field with actors' names, each separated by a comma. The 2nd parameter is the array name. The third parameter is the variable or custom field. The 4th parameter is the delimiter, usually a comma. The variable can then be displayed using the store morph operator "foreach". Here's an example to display the names on separate lines:
<mvt:item name="toolkit" param="vacreate|cast|l.all_settings:product:customfield_values:customfields:actors|," />
<mvt:if expr="NOT ISNULL l.settings:cast">
<mvt:foreach iterator="actor" array="cast">
<br> &mvte:actor;
</mvt:foreach>
</mvt:if>
Alternatively you can use sacreate to manually write a string to an array.
<mvt:item name="toolkit" param="sacreate|cast|Howard, Winkler, Williams|," />
You can also sort a single dimension array alphabetically with asort.
<mvt:item name="toolkit" param="sacreate|cast|Zanuck, Howard, Winkler, Williams|," />
<mvt:item name="toolkit" param="asort|cast2|l.all_settings:cast" />
<mvt:foreach iterator="actor" array="cast2">
<br> &mvte:actor;
</mvt:foreach>


44. Use agrpinsert to insert a customer into an availability group. This could be used on the sfnt or aced (landing) page to insert a customer when they create a new account. You can use this to force login and restrict access, ensuring a customer has to create an account and/or login before they can view products and shop in your store. It could also be used on the invc page to insert a customer based on the product purchased. An example for the aced page is:
<mvt:if expr="g.Action AND g.Action EQ 'ICST'">
<mvt:item name="toolkit" param="agrpinsert|avail|Wholesale" />
<mvt:if expr="avail">
Availability Group: &mvte:global:avail;
</mvt:if>
</mvt:if>
The function above accepts a constant for the 3rd parameter. You can use a variable, e.g. as part of a url or form post by using the function vagrpinsert.


45. Use related to list related products for a specific product code. An example to display the products in a vertical list is:
<mvt:item name="toolkit" param="related|pcount|g.Product_Code" />
<mvt:if expr="pcount GT 0">
<table border="0" width="200">
<th>
Related
</th>
<tr>
<td align="center">
<font size="-1">
<mvt:foreach iterator="relproduct" array="related">
<mvt:if expr="NOT ISNULL l.settings:relproduct:thumbnail">
<img src="&mvte:relproduct:thumbnail;" border="0"><br>
</mvt:if>
<a href="&mvt:global:sessionurl;Screen=PROD&Product_Code=&mvta:relproduct:code;&Store_Code=&mvta:store:code;">
&mvt:relproduct:name;</a>
<br>
&mvt:relproduct:formatted_price;
<br><br>
</mvt:foreach>
</font>
</td>
</tr>
</table>
</mvt:if>


46. Use catimage to retrieve the path, if any, for the category main image. An example for displaying that image is below. The path (2nd parameter) is saved to a variable of your chosing, e.g. bigimage. The 3rd parameter is the variable that contains the category code. This example variable is for a specific scenario; it could be something else, e.g. g.Category_Code or other variable.
<mvt:item name="toolkit" param="catimage|bigimage|l.all_settings:parent_category:code" />
<mvt:if expr="bigimage">
<img src="&mvte:global:bigimage;" border="0">
</mvt:if>


47. Use cattreeimage to retrieve the path, if any, for the category tree image. An example for displaying that image is below. The path (2nd parameter) is saved to a variable of your chosing, e.g. smallimage. The 3rd parameter is the variable that contains the category code. This example variable is for a specific scenario; it could be something else, e.g. g.Category_Code or other variable.
<mvt:item name="toolkit" param="cattreeimage|smallimage|l.all_settings:parent_category:code" />
<mvt:if expr="smallimage">
<img src="&mvte:global:smallimage;" border="0">
</mvt:if>


48. Use export to write variables to a flat file in the "export" directory under your store's data directory. It will not write to other directories. Delimiters can be tab or | or , or #. This function is used with our Deal of the Day feature which requires our Coupon Redemption and Tool Kit modules. The step by step how to explains the page creation and coupon generation.


49. Use import to read the contents of a flat file in the "export" directory under your store's data directory. It will not read from other directories. The content is entity encoded for security reasons, so html will be garbled. For example:
<mvt:if expr="g.customer:login EQ 'ABCD123'">
<mvt:item name="toolkit" param="import|megalist|cust.dat|crlf" />
<pre>
&mvt:global:megalist;
</pre>
</mvt:if>
This example in a page template would display the contents of cust.dat. It is wrapped inside the check for a specific customer login so that only that person would see the display. You would change the ABCD123 to your customer login for your merchant.mvc. The crlf in the function defines the end of line as a carriage return and line feed. By using the <pre> tags it displays that as a list on the page which you could copy and paste to the clipboard then insert into a file or application on your PC. You could change the crlf to <br> and leave off the <pre> tags. That option would look the same on the screen but would not have the carriage return and line feeds needed by many applications.


50. Use productmeta to display the text in the product meta tag keywords and/or description fields. The second parameter is either CODE or ID (upper case), depending on the variable you are using in the third parameter. For example:
<mvt:item name="toolkit" param="productmeta|CODE|l.all_settings:product:code" />
<br>&mvte:meta:keywords;
<br>&mvte:meta:description;


51. Use categorymeta to display the text in the category meta tag keywords and/or description fields. The second parameter is either CODE or ID (upper case), depending on the variable you are using in the third parameter. For example:
<mvt:item name="toolkit" param="categorymeta|CODE|l.all_settings:category:code" />
<br>&mvte:meta:keywords;
<br>&mvte:meta:description;


52. Use exportxml to export variables to an XML file. This export requires the use of three commands. exportxmlbegin is used to initialize the file and must be used before the first of the exportxml commands. Then after all of the exportxml commands have been run, you close the process and write the data to the file with the exportxmlend command. As example, the following lines placed in the INVC page template will write the order number and customer last name to a XML file called basket.dat.
<mvt:item name="toolkit" param="exportxmlbegin" />
<mvt:item name="toolkit" param="exportxml|ORDER_NUMBER|l.all_settings:order:id|ORDER_NUMBER" />
<mvt:item name="toolkit" param="exportxml|SHIP_LAST|l.all_settings:order:ship_lname|SHIP_LAST" />
<mvt:item name="toolkit" param="exportxmlend|basket.dat|ORDER_NUMBER|l.all_settings:order:id|ORDER_NUMBER" />
See this page for details and explanation of the three functions.


53. Use logbackin on the INVC (invoice) screen to log customers back in automatically (transparent to the customer). Normally when a customer completes an order they are automatically logged out. This function can be used on the invoice screen to log them back in without exposing their password on the invoice page. The second parameter is optional. If left blank, it will log them back in with the full time until basket timeout setting. If you put a number between 1 and the basket timeout setting, it will extend their login for only that number of minutes. For example, the line below will log them back in for 10 minutes. If they click on any link in the store during the next 10 minutes, their time will update as if they never logged out.
<mvt:item name="toolkit" param="logbackin|10" />
If you are using other 3rd party modules that keep the customer logged in, do not use this function as it is not needed and would be redundant.


54. Use childof when you want to retrieve the parent category name and code for the current category. Typically this would be used on the category page if you did not want to use the full breadcrumb function above. For example:
<mvt:item name="toolkit" param="childof|parentfound|g.Category_Code" />
<mvt:if expr="g.parentfound">
<a href="http://www.yourdomain.com/mm5/merchant.mvc?Screen=CTGY&Category_Code=&mvta:childof:code;"> &mvt:childof:name;</a>
</mvt:if>


55. Use pastorders to display a list of a customer's past orders when they are logged in. It will display all of those orders which are still in the store's admin, either batched or unbatched. You can limit the number of orders that are displayed by using the pos1 variable as you see in the first example below. Or you can limit those orders newer than a set date as you see in the second example. If you don't limit the display, you can use the variable formatted_ordersum to display the total. If you have code on your INVC page template to hide items (like the nav bar) when the variable "print" exists, you can even use this for displaying printable invoices. If you use this function on the invoice screen, you'll need to use the logbackin function above to keep the customer logged in for at least a few minutes. In addition to the variables in the examples below, the pastorder:bill_zip and pastorder:bill_email are populated.
Simple list with link to each invoice
<mvt:item name="toolkit" param="pastorders|ordersum" />
<mvt:if expr="g.ordersum GT 0">
<br>
Recent Orders
<mvt:item name="toolkit" param="currencyformat|formatted_ordersum|g.ordersum" />
&mvte:global:formatted_ordersum;
<mvt:foreach iterator="pastorder" array="pastorders">
<mvt:if expr="pos1 LT 11">
<br>
<a href="&mvte:global:secure_sessionurl;Action=NEW&SubScreen=TKINVC&order_id=&mvta:pastorder:id;&print=1">
&mvt:pastorder:id;</a>
&mvt:pastorder:orderdate;
&mvt:pastorder:formatted_total;
</mvt:if>
</mvt:foreach>
<br>
</mvt:if>
Drop down select
<mvt:item name="toolkit" param="pastorders|ordersum" />
<mvt:if expr="g.ordersum GT 0">
<br>
Recent Orders
<mvt:item name="toolkit" param="currencyformat|formatted_ordersum|g.ordersum" />
&mvte:global:formatted_ordersum;
<br>
<select size="1" name="pastorder" onchange="document.location.href=this.value">
<option selected value="&mvt:global:sessionurl;">------------ View ------------</option>
<mvt:foreach iterator="pastorder" array="pastorders">
<mvt:if expr="l.settings:pastorder:systemdate GT '20080101'">
<option value="&mvte:global:secure_sessionurl;Action=NEW&SubScreen=TKINVC&order_id=&mvta:pastorder:id;&print=1">
&mvt:pastorder:id;
&mvt:pastorder:orderdate;
&mvt:pastorder:formatted_total;</option>
</mvt:if>
</mvt:foreach>
</select>
<br>
</mvt:if>
On the INVC page you can include a link to reorder the same items. If your store has inventory variant products, you cannot use this feature as they are not supported.
<a href="&mvte:global:secure_sessionurl;Action=NEW&SubScreen=TKORDR&order_id=&mvta:order:id;&Store_Code=&mvta:global:Store_Code;">Reorder</a>
Important: If you have code on your INVC page for affiliate, tracking, analytics, etc. you need to surround that code with a conditional that makes sure it only runs if the Action variable is AUTH. That way re-displaying the invoice will not run the code.
<mvt:if expr="'AUTH' CIN g.Action">
do code that should only run when action is AUTH
</mvt:if>


56. Use weight to display the basket total weight. For example
<mvt:item name="toolkit" param="weight|totalweight" />
&mvte:global:totalweight;


57. Use subtotal to display the subtotal of the products in the basket. This yields a raw number. If you wanted it formatted as currency, use in conjunction with the currencyformat function above. For example
<mvt:item name="toolkit" param="subtotal|basketsubtotal" />
<mvt:item name="toolkit" param="currencyformat|formatted_subtotal|basketsubtotal" />
&mvte:global:formatted_subtotal;


58: Use subtotalorder to display the subtotal of the products in the order. This yields a raw number. If you wanted it formatted as currency, use in conjunction with the currencyformat function above. For example
<mvt:item name="toolkit" param="subtotalorder|ordersubtotal" />
<mvt:item name="toolkit" param="currencyformat|formatted_subtotal|ordersubtotal" />
&mvte:global:formatted_subtotal;


59. Use alsobought on the INVC page template to keep track of items bought when another product is bought. This gives you a suggested products based on prior purchase history feature. First create a custom product field in utilities with the CODE "alsobought". Then add the token
<mvt:item name="toolkit" param="alsobought|250" />
on the INVC page template at any location, e.g. near the end. The second parameter is any value between 1 and 250. This determines the number of product codes that will be saved. You need to look at the average length of your product codes. For example, if it is 10, then 250 would save about 25 product codes before it started erasing the oldest ones. Keep in mind that customers would probably only want to see 5 or 6 of these also bought product links. So if you wanted 6, then make the number 66 (10 for each product code and 1 for the delimiter between them). Then on the product page, e.g. just below the related products item, you could add the following code. Make sure the custom field alsobought is assigned to the product page in the point and click mode. The system automatically updates the codes as each order is placed. You can also manually edit the custom product field to "tweak" the results.
<mvt:if expr="NOT ISNULL l.settings:product:customfield_values:customfields:alsobought">
<mvt:item name="toolkit" param="vquick|pcount|l.all_settings:product:customfield_values:customfields:alsobought" />
<mvt:if expr="pcount GT 0">
<br>
<table border="0">
<tr>
<td align="center" colspan="3">
<mvt:item name="fonts" param="hdr_font">
Customers who bought &mvt:product:name; also bought these products
</mvt:item>
</td>
</tr>
<mvt:foreach iterator="quicklist" array="quicklists">
<tr>
<td align="left" valign="top">
<mvt:if expr="NOT ISNULL l.settings:quicklist:thumbnail">
<img src="&mvt:quicklist:thumbnail;" border="0" width="50" height="50" alt="&mvta:quicklist:name;">
<mvt:else>
<img src="/mm5/graphics/en-US/admin/blank.gif" border="0" width="50" height="50" alt="&mvta:quicklist:name;">
</mvt:if>
</td>
<td align="left" valign="top">
<mvt:item name="fonts" param="body_font">
<a href="&mvt:global:sessionurl;Screen=PROD&Product_Code=&mvta:quicklist:code;">
&mvt:quicklist:name;</a>
</mvt:item>
</td>
<td align="left" valign="top">
<mvt:item name="fonts" param="body_font">
&mvt:quicklist:formatted_price;
</mvt:item>
</td>
</tr>
</mvt:foreach>
</table>
</mvt:if>
</mvt:if>


60. Use clearall on the BASK screen to provide a link to clear the basket of all items. For example
<mvt:item name="toolkit" param="clearall" />
Alternatively, you can insert the url directly without the token, for example
<a href="&mvt:global:sessionurl;Screen=BASK&SubScreen=TKCLEAR&Action=NEW&Store_Code=&mvta:store:code;">Clear Basket</a>


61. Use basketoneclick on the BASK screen and you can replace the individual remove and update buttons with a single update button for the whole basket. An example basket contents template with the necessary changes documented is online.


62. Use agroup-c to identify all of the availability groups a category is in. It saves the availability group count to a variable of your choosing. You can then display the names of the availability groups the category is in.
<mvt:item name="toolkit" param="agroup-c|acatcount|g.Category_Code" />
<mvt:if expr="g.acatcount GT 0">
<mvt:foreach iterator="category_agroup" array="category_agroups">
<br>&mvt:category_agroup:name;
</mvt:foreach>
</mvt:if>


63. Use agroup-cats to list all categories assigned to an availability group. It saves the category count to a variable of your choosing. You can then display the category info of those that are in the availability group.
<mvt:item name="toolkit" param="agroup-cats|acatcount|l.settings:agroup:name" />
<mvt:if expr="g.acatcount GT 0">
<mvt:foreach iterator="agroup_cat" array="agroup_cats">
<br>&mvt:agroup_cat:name;
</mvt:foreach>
</mvt:if>


64. Use lasturl to log the last screen (CTGY, PLST, or SRCH) a customer was on and display a continue shopping link on the basket (BASK) screen. You will be putting tokens on four screens. Don't forget to assign the tool kit to the items list of all four of those screens. In admin, on either the CTGY, PLST, or SRCH page put the following token which will create the logging database. The location is not important.
<mvt:item name="toolkit" param="create" />
Then in merchant.mvc go to the screen you put the create token on so that it will run the token and create the database. Next, go back into admin and change that token to
<mvt:item name="toolkit" param="trim" />
This token will trim expired entries about 1 out of 100 times that this screen displays in your store. Next, on the CTGY, PLST, and SRCH screens put the following token which will capture the visit to the page.
<mvt:item name="toolkit" param="lasturl|url|http://www.yourdomain.com/mm5/merchant.mvc" />
The last url visited will be saved to the variable name in the second parameter, e.g. url in this example. The third parameter is the fallback url if there is no CTGY, PLST, or SRCH page visited. This would usually be your storefront. Next, on the BASK page template you can use the following to display a continue shopping link.
<mvt:item name="toolkit" param="lasturl|url|http://www.yourdomain.com/mm5/merchant.mvc" />
<a href="&mvte:global:url;">Continue Shopping</a>
As you can see the first line is the same as on the other three pages. Then you have a http link for the continue shopping url. You can replace the text with an image button to match your store's look and feel. You may also want to have a continue shopping button on the PROD page. It would be the same code as the BASK page. If you are going to use the footsteps/visitors functions you have to use the token on the PROD page so that product page visits will be tracked. Finally, there is a token if you decide to discontinue this feature. It removes the logging datebase. To discontinue, remove the lasturl tokens from the four pages. Then change the trim token to
<mvt:item name="toolkit" param="remove" />
Visit that page in merchant.mvc to remove the database. Then in admin, remove the token completely. If for some reason your "trim" page is not visited frequently enough, your logging database could get large and you may have to use the remove technigue to clear out the database. This should never be an issue in a MySQL store and probably won't be in a MivaSQL store, but keep it in mind. Moving the trim token to a more frequently visited page may also help.
In version 5.080 and newer you can have a 4th parameter if you are also using our Power Search module. If you are not using our Power Search module, do not use the 4th parameter setting. The lasturl token will include name, code and description field searches. If you are using Power Search but not including custom fields to be searched in Power Search then use this token on the SRCH page instead of the default above.
<mvt:item name="toolkit" param="lasturl|url|http://www.yourdomain.com/mm5/merchant.mvc|1" />
If you are including custom fields to be searched, you need to include each of those that are selectable in the SRCH screen in the 4th parameter. If they are not selectable, do not include them. For example
<mvt:item name="toolkit" param="lasturl|url|http://www.yourdomain.com/mm5/merchant.mvc|srch_circa,srch_actors,srch_company,srch_director" />
would check to see if the customer had selected to search the fields circa, actors, company, and director. If they did, the continue shopping would also select them.
In version 5.085 you can even put the continue shopping button on a static page like index.html, policies.html, shipping.html, etc. You must setup the lasturl system as above and have that working before putting the link on static pages. The url is a bit different.
<a href="http://www.yourdomain.com/mm5/merchant.mvc?Action=NEW&SubScreen=TKLAST&Store_Code=yourstorecode">Continue Shopping</a>


65. Use updatebasket to insert a value in a field in the customer's basket. This is likely to be used in conjunction with the cookie saving and reading functions in the tool kit. Here is an example of updating the basket with the "ship to" state value. This is useful if you have modules which display shipping before checkout, e.g. our mini-basket module. The customer doesn't have to fill in the data since it is already known from their saved cookie.
<mvt:item name="toolkit" param="updatebasket|ship_state|g.value" />
See this example code for setting and reading cookies.


66. Use productincategory to retrieve the categories a product is in. This can be used in conjunction with the breadcrumb function to display breadcrumbs to all of the categories a product is in. This example combines the two functions.
<mvt:item name="toolkit" param="productincategory|incatcount|g.Product_Code" />
<mvt:if expr="incatcount GT 0">
<mvt:foreach iterator="incategory" array="incategories">

<mvt:item name="toolkit" param="breadcrumb|b_count|l.all_settings:incategory:code" />
<mvt:if expr="b_count GT 0">
<br><a href="http://www.yourdomain.com/mm5/merchant.mvc">Home</a>
<mvt:foreach iterator="breadcrumb" array="breadcrumbs">
>
<mvt:if expr="g.Category_Code EQ l.settings:breadcrumb:code">
<b> <a href="http://www.yourdomain.com/c/&mvte:breadcrumb:code;/&mvta:breadcrumb:name;.html">
&mvt:breadcrumb:name;</a></b>
<mvt:else>
<a href="http://www.yourdomain.com/c/&mvte:breadcrumb:code;/&mvta:breadcrumb:name;.html">
&mvt:breadcrumb:name;</a>
</mvt:if>
</mvt:foreach>
</mvt:if>

</mvt:foreach>
</mvt:if>
You can add a 4th parameter to the token if you just want to see if the product is in a specific category. For example if the category is XYZ, put 'XYZ' in the 4th parameter. Alternatively, you could use a variable in the 4th parameter by omitting the apostrophes around the variable, for example g.Category_Code.
<mvt:item name="toolkit" param="productincategory|incatcount|g.Product_Code|'XYZ'" />


67. Use header to save the category or product header to a variable. Then display the variable. It only works on the screen = CTGY or PROD. The Category_Code or Product_Code variable needs to be present so the function knows which category or product header to lookup. The second parameter in the function is the variable name you want to save it to.
<mvt:item name="toolkit" param="header|cathead" />
&mvt:global:cathead;



68. Use footer to save the category or product footer to a variable. Then display the variable. It only works on the screen = CTGY or PROD. The Category_Code or Product_Code variable needs to be present so the function knows which category or product footer to lookup. The second parameter in the function is the variable name you want to save it to.
<mvt:item name="toolkit" param="footer|catfoot" />
&mvt:global:catfoot;



69. Use mvassign if you want to use mivascript expressions on the store morph page templates. This function works similar to the MvASSIGN in mivascript. It allows you to assign a value to a variable based on an expression. Most functions in the mivascript reference manual can be used. The second parameter in the token is the global variable you are assigning the value to. The third parameter is a mivascript function with applicable variables. After the token you can then display the value. For example:
<mvt:item name="toolkit" param="mvassign|word|substring(l.all_settings:product:descrip,1,200)" />
&mvte:global:word;
The above displays the first 200 characters in the product description on a product page template.
<mvt:if expr="l.settings:product:cost GT l.settings:product:price">
<br>MSRP: <s>$&mvt:product:cost;</s>
<mvt:item name="toolkit" param="mvassign|savings|rnd(l.all_settings:product:cost - l.all_settings:product:price,2)" />
<mvt:item name="toolkit" param="mvassign|percent|rnd((g.savings/l.all_settings:product:cost) * 100,2)" />
<br>Your Price: <b>&mvt:product:formatted_price;</b>
<br>Savings:
<font color="red">
$&mvte:global:savings; (&mvte:global:percent;%)
</font>
<mvt:else>
<br>Price: <b>&mvt:product:formatted_price;</b>
</mvt:if>
If you setup the cost as MSRP and it is higher than the price, you can show the difference and percentage savings.
<mvt:item name="toolkit" param="mvassign|imgurl|'/mm5/graphics/00000001/' $ tolower(l.all_settings:product:code) $ '.gif'" />
<mvt:item name="toolkit" param="mvassign|vpath|sexists(g.imgurl)" />
<mvt:if expr="g.vpath">
<img src="&mvte:global:imgurl;" border="0">
<mvt:else>
No Image Available
</mvt:if>
For stores whose images are named based on the product code, this function checks for the existance of an image file and displays it.


70. Use mveval if you want to display the results of an expression directly without creating a variable first. It works like mvassign and can use the dozens of mivascript functions. The difference is the global variable is omitted. Some examples:
MSRP: <mvt:item name="toolkit" param="mveval|l.all_settings:product:price * 1.1" />
This example multiplies the product price by 110%
<mvt:item name="toolkit" param="mveval|glosub(l.all_settings:product:name,asciichar(34),' ')" />
Removes the " character from the product name.
<mvt:item name="toolkit" param="mveval|gettoken(l.all_settings:product:descrip,'#',2)" />
Shows text in the product description after the # character. Great for use with multilanguage stores or for adding custom field like data directly in the description.


71. Use catpages to display category pagination. Number the category pages with configurable links to any page in the category. Make sure you have pagination turned on for the page you are putting this code on, unless you are also using the ctgyproduct_list token (further down this list) on the page. See this page for an example with pagination.
<mvt:item name="toolkit" param="catpages|l.all_settings:category:id" />
<table>
<tr>
<td colspan="2" align="right" nowrap>
<mvt:item name="fonts" param="ctgy_font">
<mvt:if expr="l.settings:cxp_total_pages GT 0">
Page &mvt:cxp_current_page; of &mvt:cxp_total_pages;
<br>
</mvt:if>
<mvt:if expr="l.settings:cxp_total_pages GT 1"> |
<mvt:foreach iterator="pages" array="cxp_offset">
<mvt:if expr="l.settings:pages:buffer GE 5 AND l.settings:pages:number NE 1 AND l.settings:pages:number NE l.settings:cxp_total_pages">
<mvt:if expr="l.settings:pages:buffer EQ 5">
<a href="&mvt:global:sessionurl;Screen=CTGY&Store_Code=&mvta:store:code;&Category_Code=&mvta:global:category_code;&offset=&mvt:pages:offset;">
<mvt:if expr="l.settings:pages:number GT l.settings:cxp_current_page">
<img src="graphics/right.gif" border="0">
</a>
<mvt:else>
<img src="graphics/left.gif" border="0">
</a>
</mvt:if>
</mvt:if>
<mvt:else>
<mvt:if expr="l.settings:cxp_current_page EQ pos1">
&mvt:pages:number; |
<mvt:else>
<a href="&mvt:global:sessionurl;Screen=CTGY&Store_Code=&mvta:store:code;&Category_Code=&mvta:global:category_code;&offset=&mvt:pages:offset;">
&mvt:pages:number;</a> |
</mvt:if>
</mvt:if>
</mvt:foreach>
<br>
</mvt:if>
Total products in &mvt:category:name;: &mvt:cxp_product_total;
</mvt:item>
</td>
</tr>
</table>
FTP the left.gif and right.gif to the mm5/graphics directory.

The example doc combines the page numbering of catpages with the sorting and page length selection of the ctgyproduct_list function.


72. Use customer to display the contents of a custom customer field when the customer is logged in. Use it to display things like membership number, sales rep, etc. The second parameter is the global variable you want to save the custom field value to. The third parameter is the custom field code.
<mvt:item name="toolkit" param="customer|member|membership" />
&mvte:global:member;



73. Use custinsert to insert a variable value into a custom customer field when the customer is logged in. Use it to capture values like tax ID, sales rep, etc. The second parameter is the custom field code (case sensitive) to save the variable value to. The third parameter is the variable name. If you want to use a string in the 3rd parameter rather than a variable, surround the word with the apostrophe character, e.g. 'NA'. If you want to completely erase a previously saved value in the custom customer field, use '' for the 3rd parameter.
<mvt:item name="toolkit" param="custinsert|taxid|g.mytax" />
You can use this function in conjunction with other functions to perform complex tasks. For example, you can assign customers to price groups based on their prior purchase history. Step one: Create a custom customer field under admin utilities called orders. Step two: Insert the following code anywhere on the INVC page template. This code will read the custom customer field called orders for the current customer and retrieve the value in that field. It will then sum the existing value with the order total. It will then insert that new value back into the orders field.
<mvt:if expr="'AUTH' CIN g.Action">
<mvt:item name="toolkit" param="customer|current_total|orders" />
<mvt:item name="toolkit" param="math_add|new_total|g.current_total|l.all_settings:order:total" />
<mvt:item name="toolkit" param="custinsert|orders|g.new_total" />
</mvt:if>
Step three: Anywhere on the ACED page template insert the following code. It will retrieve the current total from that field. In the below example there are two conditions; current total over 50 and current total over 25. If it is not over 50, it checks to see if it is over 25. If the first or second test is true, it inserts the customer into the price group listed in the function (PG50 or PG25). You can have as many conditional checks as you want with corresponding tiers. You just have to write the conditionals for it. After the customer logs in and lands on the account edit page, this code will run and insert them into the appropriate price group. If you use the pgroup function above you can even display the price groups a customer is in on the account edit page.
<mvt:item name="toolkit" param="customer|current_total|orders" />
<mvt:if expr="g.current_total GT 50">
<mvt:item name="toolkit" param="pgrpinsert|maxgrp|PG50" />
<mvt:else>
<mvt:if expr="g.current_total GT 25">
<mvt:item name="toolkit" param="pgrpinsert|maxgrp|PG25" />
</mvt:if>
</mvt:if>


74. Use sendpage to send a snapshot of any page in your store to an email address. See the bottom left form on this page as a tell a friend example. You can also use it to send responses in a contact us form to an email address. You can have unlimited contact forms for surveys, support, general inquiries, etc.
<mvt:item name="toolkit" param="sendpage" />
is inserted inside the form you put on the page. See this example page on how to use this feature.


75. Use randomcat to create a random, non-repeating array of products from a specified category. The 2nd parameter is the variable name to save the count to. The 3rd parameter is a variable representing the category code. The 4th parameter is the number of random products to load into the array. If the category does not have that many products in it, it will return the number of products in the category as the count. In this example we are loading an array of 5 random products from a category whose code is SPECIALS.
<mvt:item name="toolkit" param="sassign|cat_code|SPECIALS" />
<mvt:item name="toolkit" param="randomcat|pcount|g.cat_code|5" />
<mvt:if expr="pcount GT 0">
<table border="0" width="100%" cellpadding="3" cellspacing="3">
<tr valign="top" align="center">
<mvt:foreach iterator="sub_product" array="sub_products">
<td>
<a href="&mvt:global:secure_sessionurl;Screen=PROD&Product_Code=&mvta:sub_product:code;">
&mvt:sub_product:name;</a>
<br>
&mvt:sub_product:formatted_price;<br>
<mvt:if expr="NOT ISNULL l.settings:sub_product:thumbnail">
<img src="&mvt:sub_product:thumbnail;" border="0">
</mvt:if>
</td>
</mvt:foreach>
</tr>
</table>
</mvt:if>



76. Use randomall to create a random, non-repeating array of products from the entire store. The 2nd parameter is the variable name to save the count to. The 3rd parameter is the number of random products to load into the array. In this example we are loading an array of 5 random products from the store. Optionally you can put a 1 as the 4th parameter to hide out of stock products. Leave it blank if you want to include out of stock products. You can see an example display using the code below.
<mvt:item name="toolkit" param="randomall|pcount|5" />
<mvt:if expr="pcount GT 0">
<table border="0" width="100%" cellpadding="3" cellspacing="3">
<tr valign="top" align="center">
<mvt:foreach iterator="sub_product" array="sub_products">
<td>
<a href="&mvt:global:secure_sessionurl;Screen=PROD&Product_Code=&mvta:sub_product:code;">
&mvt:sub_product:name;</a>
<br>
&mvt:sub_product:formatted_price;<br>
<mvt:if expr="NOT ISNULL l.settings:sub_product:thumbnail">
<img src="&mvt:sub_product:thumbnail;" border="0">
</mvt:if>
</td>
</mvt:foreach>
</tr>
</table>
</mvt:if>



77. Use counter to increment a number for the items in an array. One use is to number the products on the product list page. Just before the foreach loop for products put the token to initialize the variable with an existing variable. Offset is a variable which holds the count of products from the beginning. On page 1 it is zero, but for each page that number goes up. So just before the loop, put
<mvt:item name="toolkit" param="counter|current_nbr|g.offset" />
Existing loop beginning <mvt:foreach iterator="product" array="products">
Then just before the display of the product info, put
<mvt:item name="toolkit" param="counter|current_nbr" />
&mvte:global:current_nbr;. 
If there is no need to initialize the variable you can leave that line out. When the 3rd parameter is used, it sets the starting number. When there is no 3rd parameter, then 1 is added to the counter variable (which is the 2nd parameter).


78. Use prodthumb to retrieve the url to the product thumbnail for display in locations like the basket. The second parameter is the variable to save the url to. The third parameter is the product code.
<mvt:item name="toolkit" param="prodthumb|imgurl|l.all_settings:item:code" />
<mvt:if expr="g.imgurl">
<img src="&mvte:global:imgurl;" border="0">
<mvt:else>
 
</mvt:if>



79. Use shipcalc to create a shipping calculator, i.e. an array of shipping methods which can be displayed on any screen in the store. Let your customers calculate shipping on the basket (or other) screen prior to checkout. Create a new page called SHIPCALC. The initial token on the page is
<mvt:item name="toolkit" param="shipcalc|1|1|1|cost|sortship" />
The 2nd parameter is state, required (1) or not (0). The 3rd is zip, required (1) or not (0). The 4th is country, required (1) or not (0). The 5th is the sort order. The choices are cost, name, code, and module. If left blank, the shipping options will not be sorted. The 6th parameter is used if you have either our Sort Shipping Plus Free Shipping Option (sortship) or the CBS Shipping Supermod (cbs-supshipping5) installed. This will implement the special rules, e.g. location restrictions that those modules use. Leave it blank if you do not have either of these. To create the SHIPCALC page, you will need the example source code. You may have to view source on that page if the browser tries to render the code on that page. Copy and paste the source on that page to the new SHIPCALC page template. Assign the following items to that page: states, countries, colors, fonts, and toolkit. If you have the CBS Shipping Supermod and have included its module code in the 6th parameter, you will also need to assign the minibaskship item to the page. See this knowledgebase article which has the minibaskship file attached. If a customer has something in the basket, the shipping calculator will display its button. Note: we have included the link near the end to use a button called shipping.gif in the root directory. You will need to upload a gif file to your domain root directory. You can put it in another directory; just adjust the code near the end of the template to its actual location. The template is ready to go after you upload the button and change the 6th parameter based on your store's installed modules. If you make changes to the template, it is up to you to troubleshoot your code. Now that you have created your template, a single line is used to insert it into any page in your store.
<mvt:item name="toolkit" param="render|SHIPCALC" />
To see how it works, click here, then click the calculate shipping button.


80. Use fileread to insert the contents of a file into any page template and at any location you want it. This is similar to the vcallurl function above. But there are three important differences. This function is faster than vcallurl. This function does not pass any variables (name value pairs) to the called file. This function can only read files in the same domain, whereas vcallurl can read from any domain. The fileread function will check for the existance of the file. The second parameter in this function is the variable that the file contents are saved to. The third parameter is always the word script. When displaying the contents of the file, if it contains html, use &mvt. If it does not, use &mvte.
<mvt:item name="toolkit" param="sassign|filepath|/mm5/5.00/extras/%code%.txt" />
<mvt:item name="toolkit" param="vglosub|filepath,%code%,l.all_settings:product:code" />
<mvt:item name="toolkit" param="fileread|content|script|filepath" />
&mvt:global:content;

Here's a tip for putting flash into a miva merchant page. Create a regular html page in your domain. Get the flash working on that page. Then use fileread to display that page with the flash inside a merchant page template.


81. Use affiliate to determine if the customer arrived at your store via an affiliate link and you are using the built in affiliate module in your store. If the active session contains a valid affiliate code; the id, code and name of the affiliate is available for your use in template code. You might want to use it just to display the affilate company name as in the example below. Or you might want to use it in conditional code to export affiliate data to a flat file using our export function above.
<mvt:item name="toolkit" param="affiliate|myaffil" />
<mvt:if expr="g.myaffil">
Referred by: &mvte:myaffiliate:company;
</mvt:if>



82. Use loginlookup to lookup a customer's login by entering their email address into the input. This form can be put on any page. In this example the code is put on a page template called LLU. Create a new page with the code of LLU and insert the code below. You can then call that page with a link to the Screen=LLU or make a javascript popup that shows that screen in a window. If you decide to put the form on a different page, simply change the value of the hidden input called Screen to reflect the alternate page. In this example the login will be displayed on the page AND it will be emailed to the customer's email address if it is valid. You can eliminate the emailing by deleting the hidden inputs for email_subject and email_message. You can eliminate the display by deleting the conditional code that displays the Customer_Login_Lookup variable.
<html>
<body>
<h3>
Customer Login Lookup</h3>
<mvt:if expr="g.Customer_Login_Lookup">
<mvt:if expr="',' IN g.Customer_Login_Lookup">
Your UserName Logins: &mvte:global:Customer_Login_Lookup;
<mvt:else>
Your UserName Login: &mvte:global:Customer_Login_Lookup;
</mvt:if>
</mvt:if>
<mvt:if expr="g.Error_Messages">
<font color="red">
&mvte:global:Error_Messages;
</font>
</mvt:if>
<mvt:if expr="g.email_sent">
<br>
<br>
Your login has been sent to &mvte:global:email_sent;
<br>
<br>
</mvt:if>
<form method="post" action="&mvt:global:sessionurl;">
<input type="hidden" name="Store_Code" value="&mvte:store:code;">
<input type="hidden" name="Screen" value="LLU">
<mvt:item name="toolkit" param="loginlookup" />
<input type="hidden" name="Action" value="NEW">
<input type="hidden" name="email_subject" value="Your login ID">
<input type="hidden" name="email_message" value="Your username login: %customer_login%.">
Your Email Address: <input type="text" size="40" name="Customer_Email_Lookup" value="&mvte:global:Customer_Email_Lookup;">
<br>
<input type="submit" name="trash" value="Retrieve Login">
</form>
</body>
</html>



83. Use hyphen to replace spaces and non-alphanumeric characters in a variable, e.g. product name, with a hyphen so that you can use that variable in urls. The 2nd parameter is the variable to save the converted text to. The 3rd parameter is the variable holding the text to convert. This example converts the product name on the product list page.
<mvt:item name="toolkit" param="hyphen|pname|l.all_settings:product:name" />
&mvte:global:pname;.html



84. Use hyphen2 to replace spaces in a variable, e.g. product name, with a hyphen so that you can use that variable in urls. It works like hyphen except it also strips out non-alphanumeric characters like " / (). The 2nd parameter is the variable to save the converted text to. The 3rd parameter is the variable holding the text to convert. This example converts the product name on the product list page.
<mvt:item name="toolkit" param="hyphen2|pname|l.all_settings:product:name" />
&mvte:global:pname;.html



85. Use customcategory to insert a custom category field value on the CTGY page template.
<mvt:item name="toolkit" param="customcategory|cattotal|l.all_settings:category:id|productcount" />
&mvte:global:cattotal;
This will check the custom category field "productcount" for the current category and save the value to a variable called "cattotal". You can then mvte the cattotal variable to display it. Note: This function requires use of the Miva Corp built-in custom fields module and that you have created custom category fields. This example is using the custom category field "productcount". That field is automatically created if you run the Products in Category Count under admin > utilities > Emporium Plus Tool Kit. Keep in mind, you cannot use the count feature if your store uses availability groups or your products are hidden when they go out of stock. That is because the feature is run in admin whenever you change products in categories. It remains static until you run it again. In addition to being able to display the count as above, you can assign the custom field productcount to the category tree template and display counts in the tree with:
<mvt:if expr="NOT ISNULL l.settings:cattree_category:customfield_values:customfields:productcount">
(&mvt:cattree_category:customfield_values:customfields:productcount;)
</mvt:if>
<mvt:if expr="NOT ISNULL l.settings:cattree_category:customfield_values:customfields:cathaschild">
+
</mvt:if>


Beginning with Tool Kit version 5.163, you can use the category code instead of the category ID by using the function customcategoryc. Sometimes the code is available and the ID is not. That said, if the ID is available use the customcategory function as it is faster.


86. Use country to retrieve the name of the country when the country code is known. The country name is saved to the variable in the second parameter. The country code is a variable in the third parameter. In this example it is passing the basket variable for the ship to country code in the third parameter. Note: There are many country codes which are shared between more than one country. In those cases it will retrieve the first matching record. For example TT is shared between Trinidad and Tobago.
<mvt:item name="toolkit" param="country|ccode|g.basket:ship_cntry" />
&mvte:global:ccode;



87. Use current to list the most recent products purchased. For example,
<mvt:item name="toolkit" param="current|pcount|10|0" />
<mvt:if expr="pcount GT 0">
<table border="0" width="200">
<th>Recent Purchases</th>
<tr><td align="center">
<font size="-1">
<mvt:foreach iterator="currentsale" array="currentsales">
<a href="&mvt:global:sessionurl;Screen=PROD&Product_Code=&mvta:currentsale:code;&Store_Code=&mvta:store:code;">
&mvt:currentsale:name;</a>
<br>
&mvt:currentsale:formatted_price; <br><br>
</mvt:foreach>
</font>
</td></tr>
</table>
</mvt:if>
creates an array of the last 10 items purchased. The 3rd parameter is the number of items to display, eg 10. The 4th parameter (added in version 5.203) as 1 filters the list to only the viewing customer's purchases. If 0 or blank, it is all customers.


88. Use pageinfo to capture and display the page name of the page you are on.
<mvt:item name="toolkit" param="pageinfo" />
&mvt:pageinfo:name;



89. Use headeroutput to change the output of the header. In this example putting this on the first line of a page template will change the Content-Type to application/json for use with ajax. The page will not be viewable as html but will rather pass data to a javascript file for dynamic display, e.g. with an autocomplete input.
<mvt:item name="toolkit" param="headeroutput|Content-Type|application/json" />
A variation of this is the vheaderoutput which allows you to make the 3rd parameter a variable. An example of this usage would be redirecting a visitor or search bot to another page when the old page has been moved. This can be done in our short links page (TKSL). In the below example, a new url is constructed and saved to a variable called "newurl".
<mvt:item name="toolkit" param="headeroutput|Status|301 Moved Permanently" />
<mvt:item name="toolkit" param="vheaderoutput|Location|g.newurl" />


90. Use plstpages to display product list pagination. Number the product list pages with configurable links to any page in the store's product list.
<mvt:item name="toolkit" param="plstpages" />
<table>
<tr>
<td colspan="2" align="right" nowrap>
<mvt:item name="fonts" param="ctgy_font">
<mvt:if expr="l.settings:plst_total_pages GT 0">
Page &mvt:plst_current_page; of &mvt:plst_total_pages;
<br>
</mvt:if>
<mvt:if expr="l.settings:plst_total_pages GT 1"> |
<mvt:foreach iterator="pages" array="plst_offset">
<mvt:if expr="l.settings:pages:buffer GE 10 AND l.settings:pages:number NE 1 AND l.settings:pages:number NE l.settings:plst_total_pages">
<mvt:if expr="l.settings:pages:buffer EQ 10">
<a href="&mvt:global:sessionurl;Screen=PLST&Store_Code=&mvta:store:code;&offset=&mvt:pages:offset;">
<mvt:if expr="l.settings:pages:number GT l.settings:plst_current_page">
<img src="graphics/right.gif" border="0">
</a>
<mvt:else>
<img src="graphics/left.gif" border="0">
</a>
</mvt:if>
</mvt:if>
<mvt:else>
<mvt:if expr="l.settings:plst_current_page EQ pos1">
&mvt:pages:number; |
<mvt:else>
<a href="&mvt:global:sessionurl;Screen=PLST&Store_Code=&mvta:store:code;&offset=&mvt:pages:offset;">
&mvt:pages:number;</a> |
</mvt:if>
</mvt:if>
</mvt:foreach>
<br>
</mvt:if>
Total products in &mvt:store:name;: &mvt:plst_product_total;
</mvt:item>
</td>
</tr>
</table>
FTP the left.gif and right.gif to the mm5/graphics directory.


91. Use tksl to create search engine optimized (SEO) links at the domain root level. Your link can look like http://www.yourdomain.com/ABC.html. Add a new page template with the code TKSL (upper case). Assign the toolkit item to the items list of that page. In the body of the page you will have 3 lines.
<mvt:item name="toolkit" param="tksl" />
<mvt:item name="toolkit" param="vrender|g.Screen" />
<mvt:exit>
Then modify the .htaccess file slightly from the default code that is in it when you check "Enable short links" and update under admin > global settings > domain settings > SEO settings. Retrieve the .htaccess file from the server. There should be 5 rules. Remove the rules for product and category (2nd and 3rd). Then change the product + category and the other screens (4th and 5th) to read like this. Test your store and make sure it is working. Then edit links in the category tree, CTGY, and PLST page templates. An example in the CTGY would be:
http://www.YOURDOMAIN.com/&mvta:product:code;-p-&mvta:category:code;.html?Offset=&mvta:global:offset;
In the category tree:
http://www.YOURDOMAIN.com/&mvta:cattree_category:code;.html
In the PLST:
http://mm55.emporiumplus.com/&mvta:product:code;.html
You probably will not change the links in the SRCH page template because search engines don't perform fake searches to see what products display. Besides, many of you are using our Power Search module which has a specially formatted link so that customers can return to the exact spot they were at in the search results. You also cannot have a category code the same as any product code, nor can a page code be the same as any category or product code. These links and the .htaccess example are used when you only have one store in your merchant.mvc. If you have multiple stores you will need to devise extra parameters to handle the store code.

You can modify the TKSL page even further to make it an error handler and give your store the ability to have multiple category and product page templates without having to resort to expensive modules to do it. It handles this page reassignment as fast, if not faster, than 3rd party modules written specifically to do this functionality. This is discussed in parts 2 and 3 of the tksl.txt file.


92. Use systemaction to validate inputs from a page and redisplay the page if there is a problem. You use regular store morph code to validate the inputs. Put the following inside the form on the page sending the input values, e.g. on the PROD page.
<mvt:item name="toolkit" param="systemaction|ADPR|PROD|Year of Birth must be between 1900 and 1994" />
The 2nd parameter is the "action" to check. In this example we are going to check for a year of birth between 1900-1994. If the customer does not provide a date in that range, we are going to reload the page identified with the 3rd parameter. The 4th parameter is the message. No html allowed in the message. Then we need to create a new page template to handle the validation code. The page code is the same as the original page plus "_SYSTEM". So the companion page for PROD would be PROD_SYSTEM. In this example we would then put the following on this new page.
<mvt:if expr="g.Action EQ 'ADPR'">
<mvt:if expr="g.Product_Attributes[2]:code EQ 'YOB'">
<mvt:if expr="(g.Product_Attributes[2]:value GE 1900) AND (g.Product_Attributes[2]:value LE 1994)">
<mvt:else>
<mvt:if expr="g.Product_Attributes[2]:value">
<mvt:item name="toolkit" param="sassign|quantity|0" />
<mvt:item name="toolkit" param="mvassign|tkmessage|encodeentities(g.tkmessage)" />
<mvt:item name="toolkit" param="mvassign|tkscreen|encodeentities(g.tkscreen)" />
<mvt:item name="toolkit" param="vacreate|error_message|g.tkmessage|," />
<mvt:item name="toolkit" param="sassign|Error_Message_Count|1" />
<mvt:item name="toolkit" param="vassign|Error_Messages|l.all_settings:error_message" />
<mvt:item name="toolkit" param="vassign|Screen|g.tkscreen" />
</mvt:if>
</mvt:if>
</mvt:if>
</mvt:if>
<mvt:exit>



93. Use lastupdate to display the last updated time from a custom product, category or customer field that is tied to the record you are looking at. The module updates the time for products and categories when you add or edit a record in admin. It updates the customer record when they add or update their own record in merchant. If you are importing products from a flat file, you will need to put the current unix time in the column you are going to use for lastupdate. You can easily get that unix time by updating any product record in admin. Then check its custom product field for lastupdate. Copy and paste that number into your flat file. To get you started, you can use our Template Data Feed module. When exporting, if it finds an empty lastupdate, it inserts the current unix time into the field. See its install doc for the correct token. Finally, if you do not edit individually in admin or you don't run the template data feed, you can still insert an update into the empty lastupdate records. If you include the below code on the page, when the page is next visited, the token will update those that are empty with the current unix time. It will not change that date on later visits. Only updates as above will do that. The time is unix time and it is stored in a custom field called lastupdate. Below are examples of each. The -4 in the below examples is the time zone offset.
Put the following on the product page template at any location.
<mvt:item name="fonts" param="ctgy_font">
<mvt:item name="toolkit" param="lastupdate|lastupdate|-4|PRODUCT|l.all_settings:product:id" />
<mvt:if expr="g.lastupdate">
<mvt:item name="toolkit" param="mvassign|date2|g.lastupdate:DATE:MM$'/'$g.lastupdate:DATE:DD$'/'$g.lastupdate:DATE:YYYY" />
<mvt:item name="toolkit" param="sassign|days|Sunday#Monday#Tuesday#Wednesday#Thursday#Friday#Saturday" />
<mvt:item name="toolkit" param="vgettoken|g.days,#,g.lastupdate:DATE:DOW|cday" />
Updated: &mvte:global:cday; &mvte:global:date2; &mvte:global:lastupdate:TIME:HH;:&mvte:global:lastupdate:TIME:MM;:&mvte:global:lastupdate:TIME:SS;
<mvt:item name="toolkit" param="sassign|months|Jan#Feb#Mar#Apr#May#Jun#Jul#Aug#Sep#Oct#Nov#Dec" />
<mvt:item name="toolkit" param="vgettoken|months,#,g.lastupdate:DATE:M|cmonth" />
(&mvte:global:cmonth; &mvt:global:lastupdate:DATE:D;, &mvt:global:lastupdate:DATE:YYYY;)
</mvt:if>
</mvt:item>
Put the following on the category page template at any location.
<mvt:item name="fonts" param="ctgy_font">
<mvt:item name="toolkit" param="lastupdate|lastupdate|-4|CATEGORY|l.all_settings:category:id" />
<mvt:if expr="g.lastupdate">
<mvt:item name="toolkit" param="mvassign|date2|g.lastupdate:DATE:MM$'/'$g.lastupdate:DATE:DD$'/'$g.lastupdate:DATE:YYYY" />
<mvt:item name="toolkit" param="sassign|days|Sunday#Monday#Tuesday#Wednesday#Thursday#Friday#Saturday" />
<mvt:item name="toolkit" param="vgettoken|g.days,#,g.lastupdate:DATE:DOW|cday" />
Updated: &mvte:global:cday; &mvte:global:date2; &mvte:global:lastupdate:TIME:HH;:&mvte:global:lastupdate:TIME:MM;:&mvte:global:lastupdate:TIME:SS;
<mvt:item name="toolkit" param="sassign|months|Jan#Feb#Mar#Apr#May#Jun#Jul#Aug#Sep#Oct#Nov#Dec" />
<mvt:item name="toolkit" param="vgettoken|months,#,g.lastupdate:DATE:M|cmonth" />
(&mvte:global:cmonth; &mvt:global:lastupdate:DATE:D;, &mvt:global:lastupdate:DATE:YYYY;)
</mvt:if>
</mvt:item>
Put the following on the ACED (customer edit) screen at any location.
<mvt:item name="fonts" param="ctgy_font">
<mvt:item name="toolkit" param="lastupdate|lastupdate|-4|CUSTOMER|customer:id" />
<mvt:if expr="g.lastupdate">
<mvt:item name="toolkit" param="mvassign|date2|g.lastupdate:DATE:MM$'/'$g.lastupdate:DATE:DD$'/'$g.lastupdate:DATE:YYYY" />
<mvt:item name="toolkit" param="sassign|days|Sunday#Monday#Tuesday#Wednesday#Thursday#Friday#Saturday" />
<mvt:item name="toolkit" param="vgettoken|g.days,#,g.lastupdate:DATE:DOW|cday" />
Updated: &mvte:global:cday; &mvte:global:date2; &mvte:global:lastupdate:TIME:HH;:&mvte:global:lastupdate:TIME:MM;:&mvte:global:lastupdate:TIME:SS;
<mvt:item name="toolkit" param="sassign|months|Jan#Feb#Mar#Apr#May#Jun#Jul#Aug#Sep#Oct#Nov#Dec" />
<mvt:item name="toolkit" param="vgettoken|months,#,g.lastupdate:DATE:M|cmonth" />
(&mvte:global:cmonth; &mvt:global:lastupdate:DATE:D;, &mvt:global:lastupdate:DATE:YYYY;)
</mvt:if>
</mvt:item>
Put the following on the landing page after a new customer account is created at any location.
<mvt:if expr="g.Action AND g.Action IN 'ICST'">
<mvt:item name="toolkit" param="lastupdate|lastupdate|-4|CUSTOMER|customer:id" />
</mvt:if>



94. Use custadd to add a value to a comma delimited list in a custom customer field. This is useful if you want to make a customer favorites list for logged in customers. First create a custom customer field. Name it anything you want. In this example we will call it myfav. Then on the product page put the following code. This code tests to make sure the customer is logged in. Then displays a link to add the product to the list. If the customer clicks the link, the page refreshes and the toolkit custadd item executes and adds the product to the custom field.
<mvt:if expr="g.basket:cust_id GT 0">
<a href="&mvte:global:sessionurl;Screen=PROD&Product_Code=&mvta:global:Product_Code;&Category_Code=&mvta:global:Category_Code;&Store_Code=&mvta:global:store:code;&favorite=&mvta:global:Product_Code;">
Favorites List</a>
<mvt:if expr="g.favorite">
<mvt:item name="toolkit" param="custadd|myfav|g.favorite" />
</mvt:if>
</mvt:if>



95. Use custdelete to remove a value from a comma delimited list in a custom customer field. It is usually used in tandem with the custadd function to create a favorites list. For example, you can use the vquick function above to display products in the custom customer field. As you display those products you can use the custdelete link to let customers delete items from their favorites list.
<mvt:if expr="g.favdelete">
<mvt:item name="toolkit" param="custdelete|myfav|g.favdelete" />
</mvt:if>
<mvt:item name="toolkit" param="customer|fav|myfav" />
<mvt:if expr="g.fav">
<mvt:item name="toolkit" param="vquick|pcount|g.fav" />
<mvt:if expr="pcount GT 0">
<mvt:foreach iterator="quicklist" array="quicklists">
show product info in quicklist array
<a href="&mvt:global:secure_sessionurl;Screen=ACNT&Order=0&Store_Code=&mvta:global:store_code;&favdelete=&mvta:quicklist:code;">
Remove</a>
</mvt:foreach>
</mvt:if>
</mvt:if>



96. Use pgrpdelete to delete a customer from a price group. This could be used in conjunction with automated price group membership management.
<mvt:item name="toolkit" param="pgrpdelete|maxgrp|Chairman" />
<mvt:if expr="maxgrp">
Your membership in the &mvte:global:maxgrp; price group has been terminated.
</mvt:if>


97. Use agrpdelete to delete a customer from an availability group. This could be used in conjunction with automated availability group membership management.
<mvt:item name="toolkit" param="agrpinsert|avail|Wholesale" />
<mvt:if expr="avail">
Your membership in the &mvte:global:avail; availability group has been terminated.
</mvt:if>


98. Use smtp to send an email from any page in the store. You create an email as a page template. Then using the token, e.g.
<mvt:item name="toolkit" param="smtp|VISITED" />
it will send the email. In this example I created a page template with the code VISITED and the name Page Visit. In the body of the page template I put the following code:
<mvt:if expr="g.Screen CIN 'VISITED'">
<mvt:exit>
</mvt:if>
%subject|Product page visited%
%from|g.store:email%
%to|g.store:email%
<html>
<body>
The &mvt:product:name; product page was visited.
<mvt:if expr="g.basket:cust_id GT 0">
The customer was &mvte:global:customer:bill_fname; &mvte:global:customer:bill_lname; at &mvte:global:customer:bill_email; </mvt:if>
</body>
</html>
On the first line make sure the screen name is the exact same as the code for the page template you created (case sensitive). The subject token is a string. It cannot be a variable at this time. The from and to tokens must be variables. In the example above the to token is g.store:email. It could have been g.customer:bill_email if you wanted to send something to logged in customers. Be careful on how you use this. You would not want a spammer to be able to send emails through your store to hundreds of people. As long as you control the message and the destination is your store or logged in customers, spamming would be unlikely.

You can create as many email template pages as you want. For example, you might want to use the pgrpinsert function to assign customers to a price group. Then use the smtp function to send them an email to highlight the benefits of the price group they were just assigned to. Then use a different template to send them an email if their price group membership expires and you remove them with the pgrpdelete function. All of this can be automated with the Tool Kit functions. If your version of the tool kit has the smtp function listed in its admin screen here is the how to.

Another useful email is the welcome email when new customers create an account. Here's a quick how to that should take less than 5 minutes (most of that time to change the text in the welcome email) to setup, saving you from buying a $40 module that does the same thing and takes just as long to setup. You can see how it works by creating a new account in our test store.


99. Use randomstring to generate a random string of characters. The second parameter is the variable you want to save the string to. The third parameter is the length of the random string you want to create. For example:
<mvt:item name="toolkit" param="randomstring|proceedcode|8" />
There are many things you might use this for. As example, use it in conjunction with custinsert to store a proceed code with a customer's record. If they know the code, they can proceed in the checkout. Use the smtp function to send the customer the code. This would mean the customer would have to supply a valid email address to receive the code. If they used a fake address, it is probably a fraudulent order. Hence, they would not receive the code and could not proceed. Instructions for this implementation are fairly easy to follow.


100. Use pickprompt to replace the attribute and option codes with their prompts in the picklist screen which is run under manage shipments in admin. Locate the line
<mvt:foreach iterator="option" array="item:options">
On the line immediately following that, insert the following line.
<mvt:item name="toolkit" param="pickprompt|l.all_settings:option" />
Then in the next few lines replace attr_code with attr_prompt and opt_code with opt_prompt.


101. Use promptimage to replace or add to the attribute options. This will check for the existance of an attribute/option image. If there is one it will create a variable that allows you to display the image in the basket. Just before the item:options foreach loop put this line
<mvt:item name="toolkit" param="promptimage" />
Then a few lines down where the attribute and option codes are displayed you can use this code
<mvt:if expr="l.settings:option:opt_image">
<img src="&mvt:option:opt_image;" border="0" alt="&mvt:option:opt_code;">
</mvt:if>
to display the image if it exists.


102. Use exit to abruptly end the display. Here is an example usage to allow store owners to keep the store open so they can work on it, but make it appear closed to all other visitors. The following code has a conditional in its first line. When 1 EQ 1 exists, this code is active. If you change the code to 1 EQ 2, then none of this code executes. You put your IP address where you see the Xs in the first line. When you want the store in maintenance mode to all visitors, but not yourself, you change it to 1 EQ 1. When done you change it back to 1 EQ 2. Don't forget to turn it back on. To you, your store will always appear open, so don't forget and leave it closed to others. Assign the toolkit to all pages in the store EXCEPT MNTN by going to admin:pages click items. Then find toolkit. Click edit. Click pages. Assign to all pages EXCEPT MNTN. This code below goes before any other text in the html_profile item which can be edited by clicking your store name in admin, then the HTML profile tab on the right.
<mvt:if expr="(1 EQ 1) AND (remote_addr NE 'XX.XXX.XXX.XX')">
<mvt:item name="toolkit" param="sassign|emessage|Closed for maintenance" />
<mvt:item name="toolkit" param="vacreate|error_message|g.emessage|," />
<mvt:item name="toolkit" param="sassign|Error_Message_Count|1" />
<mvt:item name="toolkit" param="vassign|Error_Messages|l.all_settings:error_message" />
<mvt:item name="toolkit" param="render|MNTN" />
<mvt:item name="toolkit" param="exit" />
</mvt:if>


103. Use basketfiller to refill the basket's customer info if they have browsed your site and then returned to checkout. When a customer goes to checkout and does NOT create an account, they enter their address info but it is not saved to the customer database. If they decide to go back and shop some more, those values will not be retained with the typical Merchant flow. Instead when they return to checkout the inputs are all blank. This function will refill those inputs with the previously entered values if it is the same session. Insert this function at the beginning of the OCST page template.
<mvt:item name="toolkit" param="basketfiller" />


104. Use custfavcount to display on the product page the number of customer favorites lists the product is in. See custadd and custdelete above for adding and deleting from the favorites list. The 2nd parameter is the variable you are saving the count to. The 3rd parameter is the custom customer field code for your favorites list. The 4th parameter is the product code variable.
<mvt:item name="toolkit" param="custfavcount|favcount|myfav|g.Product_Code" />
<mvt:if expr="g.favcount GT 0">
&mvte:global:favcount; customers have this product in their favorites list
</mvt:if>


105. Use prodinsert to insert a value into a custom product field. This is useful if you want to keep track of the number of views a product has. In this case you would use it in conjunction with the custom, math_add, and sassign functions above. Insert this example on the PROD page template.
<mvt:item name="toolkit" param="custom|lastip|l.all_settings:product:id|viewip" />
<mvt:if expr="g.lastip NE remote_addr">
<mvt:item name="toolkit" param="sassign|one|1" />
<mvt:item name="toolkit" param="custom|viewcount|l.all_settings:product:id|views" />
<mvt:item name="toolkit" param="math_add|newviews|g.viewcount|one" />
<mvt:item name="toolkit" param="prodinsert|l.all_settings:product:id|views|g.newviews" />
<mvt:item name="toolkit" param="prodinsert|l.all_settings:product:id|viewip|remote_addr" />
</mvt:if>
First create two custom fields, views and viewip. This example checks the IP address. If it is not the same as the last person to visit this page, it processes the lines that follow. The custom function gets the current value in the views field. It then adds 1 to it. Then it inserts the new count into the views custom field and the IP address into the viewip custom field.


106. Use acount to count the number of elements in an array.
<mvt:item name="toolkit" param="acount|number_actors|l.all_settings:cast" />
Count: &mvte:global:number_actors;


107. Use sibling to load a parent's subcategories into an array when starting from one of the subcategories. This gives you the sibling categories to the current category. It saves the sibling category count to a variable of your choosing. You can then display the contents of the siblings array. This function does not capture the image urls. You can use the functions catimage or cattreeimage (see above) to retrieve the image urls. To display sibling names, you could use code like
<mvt:item name="toolkit" param="sibling|scount|g.Category_Code" />
<mvt:if expr="scount GT 0">
<mvt:foreach iterator="sibling" array="siblings">
&mvt:sibling:name;
</mvt:foreach>
</mvt:if>


108. Use waitlist to determine if a product or its autogenerated variants are out of stock. This function requires Miva Merchant version PR7 or newer. Typically, this function is used on the special WAITLIST page template which is called from the product page. You would not use it on other pages. See the how to document for instructions for the other pages. The function also sends pending emails to wait listed customers automatically if the product or its variants are detected as being back in stock whenever the PROD page loads, either by a customer or search engine visiting the page. A typical scenario is a customer puts a product in their basket and it goes out of stock, but they leave the store without buying. A little while later another customer visits the page and puts their email address in the wait list queue. If you have an automatic restocking module, like our Restock Shelves, or you do daily basket deletions, the item is placed back in stock that same day. In other wait list systems, the email is only sent when store employees manually take action to send emails for back in stock products. They may do this only when new inventory arrives and they update their store. Conversely, the Tool Kit waitlist is continually checking inventory and purging the queue throughout the day. Each product page in your store is likely to be visited by multiple search engine bots throughout the day. This allows you to recapture the sale before they look elsewhere. The function also removes the wait listed customer emails from the wait list as the emails are sent. It also adds customers to the wait list if they enter their email address and submit the form. They do not have to be logged in or have an account. However, if they are logged in, they can check their entire wait list using the waitlistshow function. They can also remove items from their wait list if they change their mind. The token used on the PROD page is
<mvt:item name="toolkit" param="render|WAITLIST" />
The token used on the ACED page is
<mvt:item name="toolkit" param="waitlistshow|wcount" />
In admin, the store employees can check an individual user's wait list and remove all of their entries if they want to. They can also list all products which have someone waiting for them to come back in stock. That list can be sorted by product name or code and can be used to identify potential products to order.


109. Use ctgyproduct_list to create as many different category page templates with sorting and pagination that you want without having to buy a module other than this Tool Kit, which you already have. With this function you can create new page templates, e.g. CTGY1, CTGYLINE, CTGYCOL3, CTGYCOL4, and so on. You will probably use this function in conjunction with the catpages (pagination) token above. First let's modify your default CTGY page template. Go to the CTGY page template. Click the Category Product List Layout tab at the top. Copy that product list layout template code to the clipboard. Click back to the main CTGY page template input and locate the line <mvt:item name="product_list" /> and remove it. Paste the code you copied to the clipboard at the location where you removed the product_list item. Update the page. Click on the word "Items" at the top of the page and unassign the product_list item. Then assign the toolkit item. Then insert the following line just after the body item tag (<mvt:item name="body">) in the CTGY page template.
<mvt:item name="toolkit" param="ctgyproduct_list|10|cxp.asc|1" />

You can quickly create multiple category templates by copying and pasting the contents of the main CTGY page template which you just modified into a new page. Then edit the product list layout part of the template to the various layouts you want. If you don't know where to start on editing the product list layout part, you can go up to the Items link at the top and reassign the product_list item. Then click the link at the top for the Product List Layout. If it does not say Category Product List Layout, switch to point and click mode and the first input lets you choose the layout. Change it to Category Product List Layout and save. Design the layout you want, e.g. expanded vs line, number of columns, fields to show, etc. Save the new layout. Copy the layout and paste it into the main page, overwriting the old product list layout design. Save the changes. Click Items and unassign product_list. Using this technique, you can quickly design several different pages with different layouts.

See the TKSL function above on how to redirect to these multiple page templates and incorporate short SEO links in the format http://www.yourdomain.com/ABC123.html.

Note that the above has 4 required parameters. The 1st calls the function. The second is the number of products per page to show when the page initially loads. The customer can select to see more per page if you give them the drop down to choose alternate numbers. The third parameter is the sort order that the products are in when the page first displays. cxp.asc is the default list order; the same that you see when in your admin. You can have a drop down to let the customer sort differently, e.g. by best sellers in the category. The fourth parameter is the option to load custom product field values for each product displayed. If the customer chooses to show All products in the category and that category has 1000 products you might want to have a conditional to turn off that flag. For example
<mvt:if expr="g.ProductsPerPage GT 200">
<mvt:item name="toolkit" param="ctgyproduct_list|10|cxp.asc|0" />
<mvt:else>
<mvt:item name="toolkit" param="ctgyproduct_list|10|cxp.asc|1" />
</mvt:if>

The example doc combines the page numbering of catpages with the sorting and page length selection of the ctgyproduct_list function. If you setup a new store after May 1, 2010 you are probably using the CSSUI. Here is the CSSUI example doc if that is the case.

There may be times when you don't want a product to be found in the category pages and only available by direct link. Insert <!-- miva_nodisplay //--> anywhere in the description of the products and they will not show in the category pages. The text will also not display in the description because it is surrounded with html comment tags. You can do this with the category and product list pages, and if you are using our Power Search module, the search page.

While not part of the ctgyproduct_list function, I'll mention the ability to have multiple PROD page templates here. The procedure for creating new product pages is similar to categories but you do not have to unassign items. You also do not have to copy and paste the product layout to the main page. You can leave the items in place so the tabs for each page component will be accessible for cleaner editing. You will need to fix the product list layout tab. The default is category. On the PROD pages that needs to be related products. So click the product list layout tab at the top after you create the new page. Then on that screen, change the layout to related product list layout.


110. Use plstproduct_list to add sorting and page length selection to the product list without having to buy a module other than this Tool Kit, which you already have. You will probably use this function in conjunction with the plstpages (pagination) token above. You will modify the original PLST page template.
<mvt:item name="toolkit" param="plstproduct_list|20|prod.asc|0" />
Note that the above has 4 parameters. The 1st calls the function. The second is the number of products per page to show when the page initially loads. The customer can select to see more per page if you give them the drop down to choose alternate numbers. The third parameter is the sort order that the products are in when the page first displays. prod.asc is the default list order; the same that you see when in your admin. You can have a drop down to let the customer sort differently, e.g. by best sellers in the store. The fourth parameter is the option to load custom product field values for each product displayed. If the customer chooses to show All products in the store you might want to have a conditional to turn off that flag or not allow the "All product" option. For example
<mvt:if expr="g.ProductsPerPage GT 200">
<mvt:item name="toolkit" param="plstproduct_list|10|prod.asc|0" />
<mvt:else>
<mvt:item name="toolkit" param="plstproduct_list|10|prod.asc|1" />
</mvt:if>

Beginning with version 5.179 you can also use the variable "Initial" to limit the display to products whose name begins with the letter specified, e.g. &initial=M would list all beginning with the letter M. If you use this, be sure to include the variable in the page numbering urls and the add, next and previous forms like you did with productsperpage and sort.

The example doc combines the page numbering of plstpages with the sorting and page length selection of the plstproduct_list function. If you setup a new store after May 1, 2010 you are probably using the CSSUI. Here is the CSSUI example doc if that is the case.

There may be times when you don't want a product to be found in the product list pages and only available by direct link. Insert <!-- miva_nodisplay //--> anywhere in the description of the products and they will not show in the product list pages. The text will also not display in the description because it is surrounded with html comment tags. You can do this with the category and product list pages, and if you are using our Power Search module, the search page.


111. Use simplesearch to replace the original search or add an advanced search to your store. You can even include search capabilities to the category and product list screens. The token contains 6 parameters. The simplist form of the token is like
<mvt:item name="toolkit" param="simplesearch|20|name.asc|'name,code,descrip'|'actors,circa'|g.Category_Code" />
A slightly more advanced form of the token may look like
<mvt:item name="toolkit" param="simplesearch|20|name.asc|pfields|cfields|g.Category_Code" />
The first parameter runs the simplesearch function. The second sets the default products per page to be shown. If you include a select drop down for the ProductsPerPage variable, the customer can change the number of products to show on each page. The third sets the default sort order. The results can be sorted on regular or custom product fields, e.g. most viewed products using a custom product field that is updated with the Tool Kit. You can even sort on best sellers using the built in sale quantity tracking. The fourth uses a string (1st example above) or variable (2nd example above) for which product fields will be searched. This parameter is flexible in that the store can designate all or some fields to be searched. Then based on what the customer does, others may be added. Like the 4th parameter, the fifth parameter uses a string or variable to determine which custom product fields will be searched. Like the fourth parameter, the store can designate one or more to be searched in all cases. If the customer selects other fields, those fields are also searched. The sixth parameter is an optional filter for a specific category. The category list is built using the Tool Kit subcat functions (how to). If a category is selected, the results are filtered and the category header for that category can be displayed. You can easily put the search feature on your regular category and product list pages. The default search uses the boolean operator "and", thus it will display products that contain all of the search words the customer lists. If the customer puts quotation marks around the string of words, the search is treated as an exact phrase and the words must appear in that order in at least one of the fields being searched. There may be times when you don't want a product to be found in the search pages and only available by direct link. Insert <!-- miva_nodisplay //--> anywhere in the description of the products and they will not show in the search pages. The text will also not display in the description because it is surrounded with html comment tags. You can do this with the category, product list, and search pages.

Basic Simple Search - No frills example MMUI [full page code]
Basic Simple Search - No frills example CSSUI [full page code]
Basic Simple Search - No frills example MMUI (CSS) [full page code]
Enhanced Simple Search - Enhanced example CSSUI [full page code]
All Products (PLST - Product List) with Simple Search - Example CSSUI [full page code]
Category (CTGY) with Simple Search - Example CSSUI [full page code]
Category with Simple Search and Multi-Product Add - Example CSSUI [full page code]


112. Use prior to lookup a customer's most recent order of the product they are currently viewing, if they had ordered that product previously. You can also have a link to view that specific order status. The customer has to be logged in. Put the token and code anywhere on the PROD page template, e.g. probably at the top of the product layout.
<mvt:if expr="g.basket:cust_id">
<mvt:item name="toolkit" param="prior|g.product_code" />
<mvt:if expr="l.settings:prior:order_id GT 0">
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td bgcolor="#ffff00">
You purchased this item on
<mvt:item name="toolkit" param="time_t_year|nyear|-4|l.all_settings:prior:orderdate" />
<mvt:item name="toolkit" param="time_t_month|nmonth|-4|l.all_settings:prior:orderdate" />
<mvt:item name="toolkit" param="time_t_dayofmonth|ndayofmonth|-4|l.all_settings:prior:orderdate" />
<mvt:item name="toolkit" param="sassign|months|Jan#Feb#Mar#Apr#May#Jun#Jul#Aug#Sep#Oct#Nov#Dec" />
<mvt:item name="toolkit" param="vgettoken|months,#,nmonth" />
&mvt:global:ndayofmonth;,
&mvt:global:nyear;  
<a href="&mvt:global:secure_sessionurl;Screen=ORDS&Store_Code=&mvta:global:store:code;&Order_ID=&mvta:prior:order_id;">
View order #&mvte:prior:order_id;</a>
. </td>
</tr>
</table>
</mvt:if>
</mvt:if>


113. Use footsteps to display a customer's recent product page visits. You must have the lasturl (continue shopping) function above running in the store before you implement this feature. While lasturl is required for footsteps to work, the footsteps is not required for lasturl to work. So you can have continue shopping without the recent visit history. The 2nd parameter in the function is the total found (which can be limited by the 3rd parameter. The field that stores the product codes is limited so if your product codes are real long you may only be able to display a few. If you exceed the field length, excess will be deleted. The 3rd parameter lets you limit the number to display. If your codes are short a customer could end up having dozens in the field. You may want to limit that display to 10 or 20. Optionally you can put a 1 as the 4th parameter to hide out of stock products. Leave it blank if you want to include out of stock products. Example code is:
<mvt:item name="toolkit" param="footsteps|fcount|10" />
<mvt:if expr="g.fcount GT 0">
<table border="0" cellpadding="2" cellspacing="0" width="80%">
<mvt:foreach iterator="footstep" array="footsteps">
<tr>
<td align="left" valign="top">
<a href="&mvt:global:sessionurl;Screen=PROD&Product_Code=&mvta:footstep:code;&Store_Code=&mvta:global:Store_Code;">
&mvt:footstep:code;</a>
</td>
<td align="left" valign="top" nowrap>
&mvt:footstep:name;
</td>
<td align="left" valign="top">
<mvt:if expr="NOT ISNULL l.settings:footstep:thumbnail">
<img src="&mvt:footstep:thumbnail;" border="0" width="50" height="35">
<mvt:else>
<img src="graphics/en-US/admin/blank.gif" border="0" width="50" height="35">
</mvt:if>
</td>
<td align="right" valign="top">
&mvt:footstep:formatted_price;
</td>
</tr>
</mvt:foreach>
</table>
</mvt:if>


114. Use visitors to display page names of some of the pages that other customers are currently looking at in your store. Peak interest in customers by showing them what others are interested in. You must have the lasturl (continue shopping) function above running in the store before you implement this feature. While lasturl is required for visitors to work, the visitors is not required for lasturl to work. So you can have continue shopping without the the visitor browsing list running. You will need to make sure you have the lasturl token on the PROD, CTGY, SRCH, and PLST page. The visitors token is in the format
<mvt:item name="toolkit" param="visitors|vcount|'5'|'prod,ctgy,srch,plst'|1" />
The 2nd parameter is the variable name that the count is saved to. The 3rd parameter is the number of pages to show. On the storefront or other screen you will probably limit that to about 5. On a separate BROWSE page you might make that number 50 or more. The 4th parameter is the pages you want to display. The 4 you see above are the ones that are tracked. If you are showing this on the storefront, you may want to limit it to something like 'prod,ctgy' so that viewers are more likely to see images and products. The srch and plst are rather non-interesting to view. Note that in the above token, the 3rd and 4th parameters are surrounded with the apostrophe character, like '5'. If you want to make that parameter a variable, you simply put in a variable name without the apostrophe characters, e.g.
<mvt:item name="toolkit" param="visitors|vcount|g.numbertoshow|g.pagestoshow|1" />
Of course you have to have variables which contain the value you want to use. You'll probably use the Tool Kit sassign function to create the variable and assign a value to it, e.g. <mvt:item name="toolkit" param="sassign|numbertoshow|5" />. This would be done if you want to pass a variable based on a dynamic condition. The 5th parameter is optional. If you leave it blank there will be no affect. Put a 1 in it if you don't want repeated entries. For example, if two people visit the same product page, it will only show the most recent customer's visit time. On the storefront you are more likely to set the no repeat value to 1. On the full page list, you'll probably leave that blank.

The token above creates an array of visitor data. You then display the data based on the visitor:screen in each record. For example, the PROD screen would have a visitor:code which would be the product code. Likewise the CTGY screen would have a visitor:code which is the category code. The SRCH screen has visitor:search which is the search string used. The PLST has no code or search string. The CTGY, SRCH, and PLST screen also have a variable called visitor:fullurl which is the same url that the continue shopping button uses in the lasturl function. This is handy if you want to link directly to the specific page in a category or search where another customer had been browsing. The visitor:lastupdate variable contains the exact date/time the page was visited. So you can even display a "time since" by subtracting the current time minus the lastupdate time. See the " how to" page for setting this feature up. You can see this in use at the test store at the bottom of the page.


115. Use savebasket as an easy save of the products in the logged in customer's basket with one click for later one click easy restore. The contents are saved to a custom customer field with no expiration. You can use the Tool Kit's custom customer field search feature in admin to list/edit all customers who have saved their baskets and the contents of those baskets. You can even list customers who have a specific product in their saved baskets. Simply create a custom customer field called "basket". Insert the code below on any page in the store, e.g. the BASK page. If that page is called with the variable "save" in the url or form posting to the page with a hidden input for "save", the savebasket token will run. It will return the number of products saved to the backup basket. It does not clear the basket. Those products remain in the basket unless the customer clears them with the remove button, the clearall function above, or the basket expires.
<mvt:if expr="g.save">
<mvt:item name="toolkit" param="savebasket|bcount" />
<mvt:if expr="g.bcount">
&mvte:global:bcount; items were saved to your backup basket. You can
clear the basket below and restore it at any time.
</mvt:if>
</mvt:if>

Once saved, you can restore the basket with a single click, either from a link or form if logged in. The restore function checks inventory levels (both basic and attribute inventory) and will not add a product if there are not enough in stock. If there are failed additions, the error message for each failure is configurable with store morph. An example link would be
<mvt:item name="toolkit" param="customer|saved|basket" />
<mvt:if expr="g.saved">
<a href="&mvt:global:sessionurl;Store_Code=&mvta:store:code;&Screen=BASK&Action=NEW&SubScreen=TKRESTORE">
Restore Saved Basket</a>
</mvt:if>

The code from an example BASK page will get you started. That page is in a CSSUI store so do not copy the whole page as its css may not work with your store. The applicable code is commented for the save and restore features.


116. Use savebasketdate to retrieve the date and time the basket was saved to the custom customer field called "basket". The 2nd parameter is the variable to save the value to. It returns two values, the count and date. In the example below the number of items in the saved basket would be g.saved:count and the date/time would be g.saved:date. The date can be translated to a human readable date using the Tool Kit date functions above.
<mvt:item name="toolkit" param="savebasketdate|saved" />
If you saved the basket to a cookie using the savebasketascookie function, you can retrieve the count and date/time by adding a 3rd parameter to the savebasketdate function. The 3rd parameter is the cookie name. For example, if you choose to save the basket to a cookie called basket, the token would be
<mvt:item name="toolkit" param="savebasketdate|saved|basket" />


117. Use order to retrieve values for several order variables on the invoice page, template emails, picklist, etc. The variables are: ordercount, orderweight, ordersubtotal, ordersubtotalF, orderother, orderotherF, ordershipping, ordershippingF, ordertax, ordertaxF, ordertotal, and ordertotalF. The 2nd parameter is a variable that you want to save the item count to. The 3rd parameter is the order id passed as a variable. That variable may be different on some pages, e.g. l.order:id, order:id, l.all_settings:order:id, l.all_settings:ordershipment:order:id, or even l.order_id.
<mvt:item name="toolkit" param="order|ocount|order:id" />


118. Use brief to strip html tags and parse a block of text into sentences, each sentence as a separate array element which can be displayed using a foreach loop on the page template. This allows you to define how many sentences you want to display. The typical use of this function would be to display the first couple of sentences from the product description on the category page. The default function has 4 parameters: the function name, the variable to save the array to, the variable to pass to the function which contains the block of text, and an optional length of text to parse. The third parameter extracts the first X number of characters from the block of text. By doing this, the module does not need to remove the html tags and then parse the sentences for the whole block, thus saving processing time. The below example works on the category or search pages and only parses the first 500 characters of the description. It then displays the first two sentences from that description. If there is a 3rd sentence, it shows the word "more" as a link to the product page.
<mvt:item name="toolkit" param="brief|briefdesc|l.all_settings:product:descrip|500" />
<mvt:foreach iterator="sentence" array="global:briefdesc">
<mvt:if expr="pos2 LT 3">
&mvt:sentence;
</mvt:if>
<mvt:if expr="pos2 EQ 3">
<a href="&mvt:global:sessionurl;Screen=PROD&Product_Code=&mvta:product:code;&Store_Code=&mvta:store:code;">
more&gt;&gt;</a>
</mvt:if>
</mvt:foreach>

If you do not want to create an array which you can manipulate each sentence, you can simply save all of the sentences to a single global variable. To do this, put the number of sentences in the 5th parameter. The example below uses the Tool Kit header function to retrieve the category header. Then that variable is inserted into the brief function to save the first 2 sentences to a global variable. This code is placed in the head tag content section and would be used if you have not taken the time to create a meta tag description for each of your categories. This does it automatically from the category's header.
<mvt:if expr="'CTGY' IN g.Screen">
<mvt:item name="toolkit" param="header|cathead" />
<mvt:if expr="g.cathead">
<mvt:item name="toolkit" param="brief|briefdesc|g.cathead|250|2" />
<meta name="description" content="&mvt:global:briefdesc;" />
</mvt:if>
</mvt:if>


119. Use savebasketascookie to easily save the products in the basket whenever the token runs for later one click or individual easy restore. The contents are saved to a cookie so login is not required. The typical usage is to insert the token in the head section of the BASK page template. Each time that page runs, the contents will be saved. It is an automatic passive action so the customer does not need to click a button to save the basket. It does not clear the basket either. Those products remain in the basket unless the customer clears them with the remove button, the clearall function above, or the basket expires. The function has seven required parameters. The 2nd is a variable which records the number saved. The 3rd is the name of the cookie. The 4th is the number of hours the cookie will be valid, e.g. 720 would be 30 days. The 5th is non-secure (0) or secure (1). If the page you put this token on is always secure you should make that a 1. The cookie would then only be readable on secure pages. In most stores, that will not be the case. The cookie will be non-secure and the content will be read on non-secure pages. The 6th parameter is the maximum number of products to save in the cookie. The 7th parameter is the character length of the cookie for your domain. There is a physical limit of 4000 characters for each domain's cookie. Miva Merchant already has several small cookies, but you would not want to run out of storage for them. I would recommend 2000 or less for the 7th parameter.
<mvt:item name="toolkit" param="savebasketascookie|bcount|basket|720|0|10|2000" />

Once saved, you can restore the basket with a single click, either from a link or form. Login is not required. The restore function checks inventory levels (both basic and attribute inventory) and will not add a product if there are not enough in stock. If there are failed additions, the error message for each failure is configurable with store morph. The difference between restoring from a custom customer field and restoring from a cookie is the variable "tksaved" is included with the name of the cookie as its value. An example link would be
<mvt:item name="toolkit" param="savebasketshow|savedcount|basket" />
<mvt:if expr="g.savedcount">
<a href="&mvt:global:sessionurl;Store_Code=&mvta:store:code;&Screen=BASK&Action=NEW&SubScreen=TKRESTORE&tksaved=basket">
Add All Items</a>
</mvt:if>


120. Use savebasketshow to easily display the contents of the saved basket. The 2nd parameter returns saved:count and saved:date. The date can be translated to a human readable date using the Tool Kit date functions above. The 3rd parameter is only used if the basket is saved to a cookie. In that case, the 3rd parameter is the name of the cookie. If the basket was saved to a custom customer field using the savebasket function above, the 3rd parameter is left blank. The token creates an array of products. It includes the options so that the products can be added back to the basket without having to stop at the missing attributes screen. You can add one at a time with the typical add to basket form or add all at once as discussed in the paragraph above using TKRESTORE. For example code, see the link on the module's product page at Emporium Plus in the savebasketshow paragraph. The token is:
a) when saved to a custom customer field with savebasket
<mvt:item name="toolkit" param="savebasketshow|saved|" />
b) when saved to a cookie with savebasketascookie
<mvt:item name="toolkit" param="savebasketshow|saved|basket" />

The example display will get you started.


121. Use setcookie to save content to a cookie. The 2nd parameter is a variable which contains the content to be saved. The 3rd is the actual cookie's name, e.g. widget in the example below. The 4th is the number of hours in the future that the cookie expires, e.g. 720 would be 30 days. The 5th parameter is non-secure (0) or secure (1). Cookies set on secure pages and read on secure pages are set to 1. Cookies that are set on non-secure pages are read on non-secure pages. Non-secure cookies should not be read on secure pages.
<mvt:item name="toolkit" param="setcookie|g.somevalue|widget|720|0" />


122. Use reviewsetup to initially setup the Emporium Plus Tool Kit ratings and review system. Before you do anything, go to admin > utilities and make sure the custom fields module is assigned. Then click on the custom product fields tab and make sure you do not already have the fields "rating" and "reviews" already created. If you do, you will need to rename them to something else and change how you were using them. Once you have done this, put the following token on the PROD page template anywhere on the page.
<mvt:item name="toolkit" param="reviewsetup" />
It is only going to be there for a single page display, then you are going to immediately remove it. Assign the toolkit item to the items list of the PROD page. Then go to your merchant.mvc and display any product page in the store. Then immediately go to the PROD page template and remove the token. The token should create the two new custom product fields, "rating" and "reviews". If you have been using our Rate This module, it should import the data from that module into your new Tool Kit managed system. After the import, you can inactivate the Rate This module, if applicable. Now you need to create five page templates from the how to examples. After you create the five page templates, you can read over the other "review" functions below. Keep in mind, the "how to" examples are fully functioning pages that only need your customization if you so desire. The other functions below are already included in those examples, so they are presented below just to inform you about what each function is doing in case you want to make modifications.


123. Use ratingshow to retrieve the numerical rating from the custom product field "rating". The function can be used on any page where the product ID variable is accessible or can be retrieved. The token format is
<mvt:item name="toolkit" param="ratingshow|rating|l.all_settings:product:id" />
The function returns the global variable "rating" with two subelements, "rating:average" and "rating:count". The average is the sum of the ratings which have been approved for view divided by the number used to compute that sum. The number is rounded 2 decimal places. It can then be used to display the number of hearts, stars, or whatever image you want to use in conditional store morph code. This gives the visitor a quick visual representation of the "like factor" of the product.


124. Use reviewshow to display the narrative product reviews which customers have entered. The 2nd parameter is the variable which tells you how many reviews were returned. It is limited by the number of actual reviews and the 4th parameter which can put a hard limit on how many will be shown. For example, on the product page, you may only want to show a couple with a link to show all. The 3rd parameter is the product ID. An optional 5th parameter can be used to filter the results to only reviews that have a specific 1-5 rating for the individual ratings/reviews. The token here shows the basic token without the 5th parameter.
<mvt:item name="toolkit" param="reviewshow|rcount|l.all_settings:product:id|2" />


125. Use reviewerlist to show all the ratings/reviews that a specific customer has made. This is normally linked from the first name and uses the customer login to match the reviews across multiple products. This helps a visitor to evaluate the reliability and usefulness of certain reviewer's comments. The 2nd parameter is the number of reviews returned. The 3rd parameter is the product code. Because of the way this page is called, we pass the product code instead of product ID. As you can see, the 3rd parameter is a bit different from the tokens described above. The 4th parameter is the offset in the data for this particular reviewer. By doing it this way we do not pass the reviewer login or cookie data in the url, thereby maintaining privacy. The 5th parameter is the type of lookup. Most likely you will use "login" as it is more reliable. However, if a lot of your customers do not login, you may want to use "id". That id relates to a cookie value stored on your customers' computers that is already present with visitors who allow cookies while shopping your store. It is unlikely that your visitors are blocking cookies. However, many people delete cookies routinely so this method of relating reviews to a visitor over time is less reliable, but does work. An example token for login lookup is
<mvt:item name="toolkit" param="reviewerlist|rcount|rrcode|offset|login" />


126. Use reviewfriendshow to display an info line on how many or what percentage of reviewers responded to the question about whether they would recommend the product to their friends.
<mvt:item name="toolkit" param="reviewfriendshow|friends|l.all_settings:key_product:id" />


127. Use rrinsert to actually insert the rating and review into the database. The 2nd parameter is a variable to indicate successful insertion of the review into the reviews field. The 3rd parameter is the product ID. The 4th parameter is the approved status for the review. Most stores will probably automatically approve ratings/reviews from their logged in customers. You would do this with the number 1 in the 4th parameter. If you allow ratings/reviews from non-logged in customers, you can set the pending approval element to 0. Do not leave this parameter blank. It must be 1 or 0. The 5th parameter lets you limit the length of the review text. You may allow longer reviews by logged in customers vs your anonymous reviewers. Here is an example token for automatic approval with a limit of 500 characters of text.
<mvt:item name="toolkit" param="rrinsert|result|l.all_settings:product:id|1|500" />
When the rating/review is submitted the function will check to see if the same reviewer had posted before by using the login and cookie data. If they had, it erases the previous entry and inserts the new entry at the beginning of the list. If it is an exact duplicate (except for timestamp), it does not insert the rating and review. This cuts down on the number of emails and other processing. If you have our Power Search (version 5.105 or newer) module in your store, it also updates the mirror automatically so that the reviews become searchable by other customers on your product search page (SRCH) if you have include the custom product field "reviews" in your search criteria. If the logged in customer had previously bought the product they are reviewing, the module gives them the option to let others know they actually bought the product and might know what they are talking about. In the rrinsert function, the module verifies that they really had bought the product.


128. Use variantlistbasketinfo to lookup the inactive product variants in the basket so you can display the full code or name. This currently only works in the basket because the variant_id variable is only in the basket array. It is not in the order array. It also only works if the variants were created at the product level using the autogenerate feature. In the basket contents tab within the "items" foreach loop you can include the following code.
<mvt:item name="toolkit" param="variantlistbasketinfo|vcount|l.all_settings:item:product_id|l.all_settings:item:variant_id" />
<mvt:if expr="vcount GT 0">
<mvt:foreach iterator="part" array="basketitem:variant:parts">
<br> &mvte:part:code; &mvte:part:name;
</mvt:foreach>
</mvt:if>


129. Use reviewsnew to list the most recent reviews, e.g. on the storefront. This function produces an array, similar to the reviewerlist function. The difference is that it lists the most recent reviews by all customers for a specified period of time. If more than one recent review is made on the same product, only the latest will be shown. The 2nd parameter is the variable name which contains the count of the records found. The 3rd parameter is the rating filter. Only reviews which had a rating equal to or higher than this number will be included. If you don't want to showcase your worst products on the storefront, you would set this number to 4 or 5. The 4th parameter is the number of days the list will cover. The maximum is 10. If you put a number higher than 10, it will reset it internally back to 10.
<mvt:item name="toolkit" param="reviewsnew|newcount|4|7" />


130. Use alsobought_list_load to load a list of products using the alsobought (see alsobought function) field of all of the products in the basket or order. The 2nd parameter is the variable that you want to save the product count to. The 3rd parameter is the basket id or order id. The 4th parameter is either the word basket or order, depending on the page you put it on. The 5th parameter is the maximum number of product to show. While you may have 20 or 30 products which were also bought with those in the basket or order, you would not want to show all of them. Typically 8 or 10 is more than enough. So if you put 8 and there are 30 total, the function selects 8 random products from the list. So if you viewed the list in the BASK you may actually see a different set of products each time you refresh the basket. Optionally you can put a 1 as the 6th parameter to hide out of stock products. Leave it blank if you want to include out of stock products. Example for the BASK page.
<mvt:item name="toolkit" param="alsobought_list_load|acount|g.basket:basket_id|basket|8" />
Example for the INVC page.
<mvt:item name="toolkit" param="alsobought_list_load|acount|order:id|order|8" />
This is only the first line. It creates an array which is accessed and displayed like other arrays using the foreach command, e.g. <mvt:foreach iterator="product" array="alsobought">. Study other array examples using the foreach loop and design the layout to match the way you want the data displayed.


131. Use savebasket2email to save the products in the basket with one click for later one click restore. Login is not required. The contents are saved to a database with an expiration that you set (parameter 3 in days). Insert the code below on the BASK page. If that page is called with the variable "save" in the url or form posting to the page with a hidden input for "save", the savebasket2email token will run. It will return the number of products saved to the backup basket. The name of the variable to capture the number of products is parameter 2 in the token. It does not clear the basket. Those products remain in the basket unless the customer clears them with the remove button, the clearall function above, or the basket expires. The 4th parameter limits how many products can be saved to the backup basket.
<mvt:if expr="g.save">
<mvt:item name="toolkit" param="savebasket2email|ecount|3|10" />
<mvt:if expr="g.ecount EQ 1">
&mvte:global:ecount; item was saved to your backup basket.<br />
<mvt:else>
<mvt:if expr="g.ecount GT 1">
&mvte:global:ecount; items were saved to your backup basket.<br />
</mvt:if>
</mvt:if>
<mvt:if expr="g.Save2Email_Error">
<font color="red">
&mvte:global:Save2Email_Error; <br />
</font>
</mvt:if>
<mvt:item name="toolkit" param="smtp|SAVE2EMAIL" />
</mvt:if>

<mvt:if expr="NOT l.settings:basket:empty">
<form method="post" action="&mvt:global:sessionurl;Screen=BASK">
Email: <input type="text" name="myemail" value="" size="20">
<input type="hidden" name="save" value="1">
<input type="submit" value="Save" class="button" />
</form>
</mvt:if>

Once saved, you can restore the basket with a single click, from a form. The restore function checks inventory levels (both basic and attribute inventory) and will not add a product if there are not enough in stock. If there are failed additions, the error message for each failure is configurable with store morph. An example link would be
<form method="post" action="&mvt:global:sessionurl;Screen=BASK">
Email: <input type="text" name="myemail" value="" size="20">
<input type="hidden" name="Action" value="NEW">
<input type="hidden" name="SubScreen" value="TKRESTORE">
<input type="hidden" name="tksaved" value="email">
<input type="submit" value="Restore" class="button" />
</form>

The "how to" shows you the error messages, the save and restore forms, and the example email.


132: Use discount to apply one discount per session on any page template. You can wrap the token with just about any combination of store morph conditionals you want. Use it as a coupon. Use it for an amount (fixed or percent) off the total or just one single product. Restrict to a specific price group or no price group. Restict to a specific location. Have a different percent off based on the basket total. The conditions are limited by your imagination. The token has 5 parameters. The 5th is optional. The second parameter is the label that shows in the basket page. Beginning with version 5.244 you can use either a string literal or a variable for the 2nd parameter. If you use a string put an apostrophe around the text, for example 'Facebook Disount'. If you use a variable, leave off the apostrophes, for example g.savingsmessage. The third parameter is the amount. Surround that value with the apostrophe if it is a string. If it is a variable, leave off the ' so it might look like |l.amount|. The 4th parameter is if it is taxable or not. If you want it to reduce the tax of the order, make that a 1 instead of a zero. The fifth parameter defines what values are calculated in the display of the order total. When the token reduces the order total, it overwrites the order total that is shown in the basket. It does not change the order total in the database; that is done in the background between pages. This function makes the change on the actual page rather than between pages. Probably the only screen you would use the fifth parameter on is the OPAY page because on that page the new values for shipping and tax appear. So the displayed total has to include those values. The text to put in the fifth parameter, if used, is ST.
<mvt:item name="toolkit" param="discount|FaceBook Discount 5%|'5%'|0|" />


133: Use logout to logout from any page. Sometimes the Action=LOGO may not work. If not you can try this. On the page where you want the link put:
<a href="&mvt:global:secure_sessionurl;logout=1&Screen=SFNT&Store_Code=&mvta:global:store_code;">
Log Out</a>
Then on the landing page, e.g. SFNT, put these lines.
<mvt:if expr="g.logout EQ 1">
<mvt:item name="toolkit" param="sassign|Customer_Session_Verified|1" />
<mvt:item name="toolkit" param="logout" />
</mvt:if>


134. Use customimage to retrieve a product's custom images values (if it exists). It saves the value to a variable of your choosing. For example,
<mvt:item name="toolkit" param="customimage|big|l.all_settings:item:product_id|fullsize" />
<mvt:if expr="g.big">
<img src="&mvt:global:imageroot;&mvte:global:big;">
</mvt:if>
will check the product's custom image field "fullsize" for the current path and save the value to a variable called "big". You can then mvt the "big" variable to display it. If you leave the 4th parameter blank, the function will return the first custom image in the images array. The above example is for use in the basket. On other pages the "item" in the variable may be different as it is the iterator value in a foreach array. The product id may also be different, e.g. just id instead of product_id. Note: This function requires use of the Miva Corp built-in custom product images fields module in admin utilities and that you have created custom product image fields.

You can use the product code instead of the product ID by using the function customimagec. Sometimes the code is available and the ID is not. That said, if the ID is available use the customimage function as it is faster. Here are two examples using the product code. The first example simply displays the first image in the list when you leave the 4th parameter blank.
<mvt:item name="toolkit" param="customimagec|big|g.product_code|" />
<mvt:if expr="g.big">
<img src="&mvt:global:imageroot;&mvte:global:big;">
</mvt:if>
Beginning with version 5.234 of the Tool Kit you can also list all of the images for the product if you leave the 4th parameter blank. There are several image variables returned in the array. Below shows just the url.
<mvt:item name="toolkit" param="customimagec|big|g.product_code|" />
<mvt:if expr="g.big">
<mvt:foreach iterator="image" array="toolkitadditionalimages">
<img src="&mvt:global:imageroot;&mvte:image:image:image;">
</mvt:foreach>
</mvt:if>
Beginning with version 5.238 of the Tool Kit you can display the resized, generated images from the image machine. You will need to be using the built in image machine module and set the image dimensions in its tab so that it will automatically generate the images from the base image. Then in the 5th and 6th parameters of the token you would enter the width and height (same as from the image dimensions tab) of the image you want to display. In the event that size does not exist, you can have a fallback and display the base image if you put a 1 in the 7th parameter. Variations of tokens above might be:
<mvt:item name="toolkit" param="customimage|big|l.all_settings:sub_product:id|fullsize|274|274|1" />
<mvt:item name="toolkit" param="customimagec|big|g.product_code||42|42|" />
<mvt:item name="toolkit" param="customimagec|big|g.product_code||300|300|1" />
The 3rd example, i.e. the array, has both variables available. So you can have code like this in the foreach loop.
<mvt:if expr="NOT ISNULL l.settings:image:generated:image">
<img src="&mvt:global:imageroot;&mvte:image:generated:image;">
<mvt:else>
<img src="&mvt:global:imageroot;&mvte:image:image:image;">
</mvt:if>


135. Use asortmulti to sort a multidimensional array. The 2nd parameter is the array name. The 3rd is the column to sort on. It must be preceeded with the colon character. The 4th parameter is the direction of the sort. Use 1 for ascending and -1 for descending. Below is an example of sorting the category facet in the Power Search display.
<mvt:item name="toolkit" param="asortmulti|l.all_settings:searchcats|:name|1" />


136. Use altpagecode to determine the screen code when only the numerical page id is known. This is most likely to be used on the TKSL page to determine if an alternate page code exists for products and categories before checking the custom field screencode. In Merchant PR8 Update 4, the ability to designate an alternate page was added. This function can determine if a value exists. The 2nd parameter is the variable the alternate screen code (if it exists) is saved to. The 3rd parameter is the page id, determined with the TKSL function and saved as a variable called g.altpageid. For example, the product check would be:
<mvt:if expr="g.altpageid GT 0">
<mvt:item name="toolkit" param="altpagecode|newscreen|g.altpageid" />
<mvt:else>
<mvt:item name="toolkit" param="customc|newscreen|g.Product_Code|screencode" />
</mvt:if>
and the category check would be:
<mvt:if expr="g.altpageid GT 0">
<mvt:item name="toolkit" param="altpagecode|newscreen|g.altpageid" />
<mvt:else>
<mvt:item name="toolkit" param="customcategoryc|newscreen|g.Category_Code|screencode" />
</mvt:if>


137. Use fexists to check for the existence of a file in the data directory. Save the file name to a variable. Then plug that variable into the fexists function to check for the existence of the file. The result will be 1 if the file is present. The file has to be on the same domain as the merchant program and the path must be virtual, i.e. no http://domainname in the path. In the example, vpath will be 1 if the file exists.
<mvt:item name="toolkit" param="sassign|filename|/Merchant5/s01/export/neworders.xls" />
<mvt:item name="toolkit" param="fexists|vpath|filename" />


138. Use bestseller_recent to list the best sellers in a specific category for the past X number of days. NOTE: This function only works in MySQL stores. It does not work in MivaSQL stores. For example,
<mvt:item name="toolkit" param="bestseller_recent|pcount|g.Category_Code|5|30|1|U" />
<mvt:if expr="pcount GT 0">
Best Sellers
<mvt:foreach iterator="bestsell" array="bestseller">
<br>
<a href="&mvt:global:sessionurl;Screen=PROD&Product_Code=&mvta:bestsell:code;&Store_Code=&mvta:store:code;">
&mvte:bestsell:name;<a>
&mvte:bestsell:formatted_price;
</mvt:foreach>
</mvt:if>
shows the best sellers in the current category. The 4th parameter is the number of items to display, e.g. 5. The 5th parameter is the number of days back the count will include, e.g. 30.

Alternatively you can display the best sellers storewide by changing the 3rd parameter to the word ALL, i.e. replace g.Category_Code with ALL in the above example. You can even include the actual number sold if you want your customers to know how popular the items are by using the variable &mvte:bestsell:counter; Optionally you can put a 1 as the 6th parameter to hide out of stock products. Leave it blank if you want to include out of stock products. Optionally you can exclude one string from the product code to hide products in the 7th parameter. For example, if you want to hide catalogs, gift certificates, etc, put a unique string in their product code and they will not appear in the list.


139. Use bask_getsum to create a price sum variable in the basket. It sums the base price + the attribute prices to create a formatted_price_sum. To use this function, just before the price display in the basket contents of the BASK page, insert this line.
<mvt:item name="toolkit" param="bask_getsum" />
Then change &mvt:item:formatted_price; to &mvt:item:formatted_price_sum; and also the &mvt:item:formatted_subtotal; to &mvt:item:formatted_subtotal_sum; Then you will remove the display of attribute option prices. You can also use this feature in the checkout screens as they use the basket contents display. You will use the same token as the basket screen.

If you want this feature in the invoice screen or template emails, the process is similar, except the token is
<mvt:item name="toolkit" param="invc_getsum" />


140. Use dynamicattributebasket to include a hidden attribute which then becomes visible in the basket, checkout, invoice, and emails as a typical attribute. You can use it for just about anything, e.g. shipping estimates for various products. You could have a generic date or use a custom product field for shipping estimates. The 2nd parameter in the token is the product code. It is most often l.all_settings:product:code but might also be g.Product_Code or even something other than those two. The 3rd parameter is the attribute code. It should be somewhat descriptive as that is what will be seen in the basket. The 4th parameter is the value of the attribute. If you enclose it with single quote characters, it can be a string literal. If no quote, it has to be a variable. The token is embedded in the add to basket forms. Here are three examples based on the product types.
<mvt:if expr="('1AA' IN l.settings:product:code)">
<mvt:if expr="NOT ISNULL l.settings:product:customfield_values:customfields:baskmessage">
<mvt:item name="toolkit" param="dynamicattributebasket|l.all_settings:product:code|Design Service:|l.all_settings:product:customfield_values:customfields:baskmessage" />
<mvt:else>
<mvt:item name="toolkit" param="dynamicattributebasket|l.all_settings:product:code|Email delivery:|'Software is usually sent via email within 2 hours'" />
</mvt:if>

<mvt:else>

<mvt:item name="toolkit" param="set_time_zone|our_time|68" />
<mvt:item name="toolkit" param="time_t_hour|curhour|g.our_time" />
<mvt:item name="toolkit" param="sassign|endtime|15" />
<mvt:item name="toolkit" param="sassign|oneday|24" />
<mvt:if expr="g.curhour GT g.endtime">
<mvt:item name="toolkit" param="math_add|our_time|g.oneday|g.our_time" />
</mvt:if>
<mvt:item name="toolkit" param="time_t_dayofweek|ndow|g.our_time" />
<mvt:if expr="g.ndow EQ 7">
<mvt:item name="toolkit" param="math_add|our_time|g.oneday|g.our_time" />
<mvt:item name="toolkit" param="math_add|our_time|g.oneday|g.our_time" />
</mvt:if>
<mvt:if expr="g.ndow EQ 1">
<mvt:item name="toolkit" param="math_add|our_time|g.oneday|g.our_time" />
</mvt:if>
<mvt:item name="toolkit" param="time_t_year|nyear|g.our_time" />
<mvt:item name="toolkit" param="time_t_month|nmonth|g.our_time" />
<mvt:item name="toolkit" param="time_t_dayofmonth|ndayofmonth|g.our_time" />
<mvt:item name="toolkit" param="sassign|usdate|%month%/%day%/%year%" />
<mvt:item name="toolkit" param="vglosub|usdate,%day%,ndayofmonth" />
<mvt:item name="toolkit" param="vglosub|usdate,%month%,nmonth" />
<mvt:item name="toolkit" param="vglosub|usdate,%year%,nyear" />
<mvt:item name="toolkit" param="dynamicattributebasket|l.all_settings:product:code|Expected shipping date:|g.usdate" />
</mvt:if>
The first instance of the token is checking for a value in a custom product field called baskmessage. If it finds a value it uses that as a variable in the 4th parameter. The second instance is using a string literal since no custom field value was found for baskmessage. This would be the generic display for a certain group of product codes. After the first two groups an mvt:else separates all the other products in this example store. This example shows multiple conditions. This would be typical of giving an estimated shipping date based on the day of week and time of day. It starts by setting the time zone 3 days in the future minus 4 hours for this particular time zone, i.e. 68 hours. Then it sets an ending work time of the day that we count shipping from, in this case 15 hours, i.e. 3PM our time. So if our current time is greater than the ending work day time, it adds one day (24 hours) to the time in the future. Then it tests the day of the week. If the day of the week is Saturday (7), it adds two days. If the day is Sunday (1), it adds one day. In this example, store shipping is only M-F. We could do other conditions like testing if it was Dec 25th.


141. Use taxadjustitem to change the tax status of an item in the basket. For example, you might have an option to download a purchase rather than send a tangible item to the customer. In many jurisdictions the downloaded item could be tax exempt. Include the conditional test and the taxadjustitem token in the basket contents tab of the OCST page template. You would put it right after the beginning of the foreach loop for option:items. In this example the 2nd parameter is the line_id of the product. The 3rd parameter is 0, which means turn off the tax flag so tax is not applied. If you set it to 1, you would be turning on the tax flag.
<mvt:if expr="l.settings:option:opt_code EQ 'download'">
<mvt:item name="toolkit" param="taxadjustitem|l.all_settings:item:line_id|0 " />
</mvt:if>


142. Use upcharge to apply a surcharge or fee to an order. You can use store morph coding on the page template to conditionally apply the charge. Below is a simple example testing the basket total. If it is greater than or equal to $500, the surcharge is zeroed out. If it is less than $500, the charge is $25. The 2nd parameter in the token is the basket charge description which appears in the basket, invoice and emails. You can use a string literal as you see below by surrounding it with the apostrophe characters. Or you can use a variable without the apostrophe characters, e.g. g.addonmessage. The 3rd parameter is the amount of the surcharge. Like the 2nd parameter it can be a string literal or a variable. So if you wanted to do something like the difference between the minimum order and the current basket total, you could use the Tool Kit math_subtract function to get that difference and save it to a variable. Then use the variable in the 3rd parameter. The 4th parameter is the tax flag. Test that to see how you want it based on what your surcharge is and your state's tax status for surcharges and fees.
<mvt:if expr="l.settings:basket:total GE 500">
<mvt:item name="toolkit" param="upcharge|'Order minimum surcharge'|'0'|1" />
<mvt:else>
<mvt:item name="toolkit" param="upcharge|'Order minimum surcharge'|'25'|1" />
</mvt:if>


143. Use variantarray to create an array of variants. This is primarily used in conjunction with multiple quantity inputs on the product page, one for each radio option when the options are inventory variants. The token is in the format
<mvt:item name="toolkit" param="variantarray|vcount|g.product_code" />
An example usage of this token is in the how to insert quantity inputs next to each radio option on the product page for multiple (bulk) product additions to the basket with a single button click.


144. Use catinfo to retrieve most of the variables related to a specific category. The 2nd parameter is the global variable you want to save the value to. Then you will use either the 3rd and 4th parameters (not both) to look up the category record. If you know the category code, put that in the 3rd parameter and leave the 4th blank or not use at all. If you don't know the category code but you do know the category ID, leave the 3rd parameter blank and put the numeric ID in the 4th parameter. The examples below show both usages:
<mvt:item name="toolkit" param="catinfo|catvar|g.Category_Code" />
<mvt:item name="toolkit" param="vassign|cat_id|g.catvar:id" />

<mvt:item name="toolkit" param="catinfo|catvar||g.cat_id" />
<mvt:item name="toolkit" param="vassign|cat_name|g.catvar:name" />


145. Use basketchargedelete to delete a basket charge, e.g. a coupon or discount. You cannot use it to remove shipping or tax if your store requires them (even if they are $0.00). The 2nd parameter can be a string literal surrounded by the apostrophe as in the example below. Alternatively, you could use a variable without the surrounding apostrophe characters. A typical example is to offer a discount for using a certain payment method. You can do that with the Tool Kit "discount" function which creates a discount record with the type = TKDISCOUNT. But if they don't use that payment method, you can delete the TKDISCOUNT basket charge. The following code, placed just below the body tag on the OPAY page, would do the scenario desribed in this paragraph.
<mvt:if expr="g.PaymentMethod EQ 'poplus:poplus'">
<mvt:item name="toolkit" param="discount|'Purchase Order Discount 5%'|'5%'|0|ST" />
<mvt:else>
<mvt:item name="toolkit" param="basketchargedelete|'TKDISCOUNT'" />
</mvt:if>


146. Use basketattributepercent to make the add or subtract value of an attribute-option a percentage of the base price plus other options which are fixed value. You can apply the percentage charge to select drop down options or radio options. All you need to do is include the % character in the option prompt, e.g. Large (add 10%). Then you set the option value as a decimal, e.g. .25 would result in a 25% upcharge. Whereas, -.05 would result in a 5% discount. Place the following token in the basket contents tab of the BASK and OCST pages. It goes near the top but after the conditional test for empty basket. This token causes the module to check and reconcile attribute percent charges.
<mvt:item name="toolkit" param="basketattributepercent" />
If there is a situation where the customer does not land on the basket or checkout screens after adding an item to the basket, you can include the token elsewhere. For example, a customer adding from the "All Products" page may return them to that same page, not the basket page. If that is the case in your store, use the token below on applicable pages. I found I could use it in the category tree header and all cases were covered. It does not run every time the tree displays. Because of the conditional, it only runs if the Action is equal to "ADPR", which means add product to the basket.
<mvt:if expr="g.Action EQ 'ADPR'">
<mvt:item name="toolkit" param="basketattributepercent" />
</mvt:if>


147. Use ascii2html to obfuscate a string of characters. It converts the characters in the string into their html equivalent. A practical usage of this is to display an email address on your store pages while hiding the real characters from spam bots which harvest emails from web pages. The second parameter is the variable name you are going to save the result to. The third parameter is the string you want to hide from the bots. It can either be a variable or the actual string of characters. If you use the actual string, surround it with the ' character.
<mvt:item name="toolkit" param="ascii2html|emailstore|'sales@domain.com'" />
or
<mvt:item name="toolkit" param="ascii2html|emailstore|g.store:email" />
"mailto:&mvt:global:emailstore;"


148. Use json_encode to remove characters which would break a json data stream. This would be used for projects where your data needs to be cleaned up before it is sent back to the calling routine. In this example, the token accepts the 3rd parameter as a variable. It removes characters and saves the new text to the variable in the 2nd parameter. If you do not include the "l.all_setting:" portion of the 2nd parameter, the variable will be a global variable. In this example it is a local variable and can be used in the page template the token is in.
<mvt:item name="toolkit" param="json_encode|l.all_settings:pick:term|l.all_settings:pick:term" />
An example usage is documented in the power search autocomplete feature.


149. Use batchsummary to process data in the Template Batch Report tab to create a statistical summary of your batches. The how to contains the template code to create a new batch report for retrieving batch statistics. Here is an example from this store way back at the beginning of the millennium.


150. Use donotemail to add, remove, view customers on your store's Do Not Email registry. The 2nd parameter is a variable you can save the result to. The 3rd parameter is action value add, remove, or check. The 4th parameter is the email address to perform the action on. Add and remove will not return a result. Check will return a variable with 3 members; noemail, added, ip if the email is in the database. The check can be used to hide content on a page template from customers who do not want to receive emails. The format for the add action is
<mvt:item name="toolkit" param="donotemail|dne|add|g.email" />
how to shows you how to setup the NOEMAIL page template. See donotemail_e function below for the preferred method.


151. Use donotemail_e to add, remove, view customers on your store's Do Not Email registry. It is like the donotemail function above except that it obfuscates the email address to make it less likely that a competitor could stuff potential customer emails into your Do Not Email registry. The 2nd parameter is a variable you can save the result to. The 3rd parameter is action value add, remove, or check. The 4th parameter is the email address to perform the action on. Add and remove will not return a result. Check will return a variable with 3 members; noemail, added, ip if the email is in the database. The check can be used to hide content on a page template from customers who do not want to receive emails. The format for the add action is
<mvt:item name="toolkit" param="donotemail_e|dne|add|g.email" />
I highly recommend you use the obfuscated emails instead of the plain text emails, hence the donotemail_e is the preferred token for add and remove. You would still use donotemail for most checks. The how to shows you how to setup the NOEMAIL page template.


152. Use decrypt_email to revert an obfuscated email back to readable plain text. The 2nd parameter is a variable you can save the result to. The 3rd parameter is the email address to make readable.
<mvt:item name="toolkit" param="decrypt_email|clear_email|g.email" />
&mvte:global:clear_email;


Join Emporium Plus on Facebook and follow us on Twitter for tips, tricks, update alerts, code examples, and coupons.