Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Miva - Category Page Multi-Add Example

Miva - Multi-Add Category Page Example

Note: Attribute Machine currently does not work with Multi-Add


The only thing that is required for the Multi-Add is the input name changes within the Example Category Product List and Example Product Attribute files. Everything else is just to show a completed category page.


Setup Example:

Create a new Multi-Add category page within Miva.

Create a copy of your CTGY page. You could call it, "CTGY_MULTI". Assign all of items that CTGY has to CTGY_MULTI, and transfer all of the page template code from CTGY to CTGY_MULTI as well.

Here are some example items, templates, and settings I ended up migrating:

Items

Code Module
affiliatelink CSSUI Affiliate Sign-in Link
breadcrumbs CSSUI Smart Breadcrumbs
buttons CSSUI Buttons
category Standard Category Fields
category_listing CSSUI Product List
category_listing_imagemachine Image Machine
category_title CSSUI Category Title
category_tree CSSUI Category Tree
cssui_links CSSUI Links
customerlink CSSUI Customer Sign-in Link
ga_jsencode Google Analytics
ga_tracking Google Analytics
global_minibasket Mini-Basket
hdft CSSUI Headers & Footers
head CSSUI HEAD Tag Content/CSS
html_profile CSSUI HTML Profile
navbar CSSUI Navigation Bar
prodctgy_meta Product/Category META-Tag Settings
product Standard Product Fields
product_attributes CSSUI Product Attributes
prod_ctgy_hdft CSSUI Product/Category Header & Footer
readytheme ReadyTheme
store Standard Store Fields
tokenlist Token List

Example Page Template

Category Image Machine

Category Image Machine Settings

Example Category Product List

Example Product Attribute

Notes

ADPM Products Structure

Products[]:code                          Required
Products[]:quantity                      Required if you want to add the product
Products[]:attributes[]:code             Required if the product has attributes
Products[]:attributes[]:template_code    Required if the attribute is from an attribute-template
Products[]:attributes[]:value            Required if the attribute is required
Products[]:subterm_id                    Required if the product can only be purchased with subscriptions

Example HTML Form

<input type="hidden" name="Products[1]:code"                        value="prod-abc">
<input type="hidden" name="Products[1]:quantity"                    value="1">
<input type="hidden" name="Products[1]:attributes[1]:code"          value="size">
<input type="hidden" name="Products[1]:attributes[1]:template_code" value="size-template">
<input type="hidden" name="Products[1]:attributes[1]:value"         value="small">
<input type="hidden" name="Products[1]:attributes[2]:code"          value="color">
<input type="hidden" name="Products[1]:attributes[2]:template_code" value="color-template">
<input type="hidden" name="Products[1]:attributes[2]:value"         value="red">
<input type="hidden" name="Products[1]:subterm_id"                  value="123">

Example Template Code

<form action="&mvte:urls:BASK:auto;">
	<input type="hidden" name="Action" value="ADPM">
	<mvt:foreach iterator="product" array="category_listing:products">
		<input type="hidden" name="Products[<mvt:eval expr="l.pos1"/>]:code" value="&mvte:product:code;">
		<input type="number" name="Products[<mvt:eval expr="l.pos1"/>]:quantity" value="1">

		<mvt:comment><!-- Attributes --></mvt:comment>
		<mvt:foreach iterator="attribute" array="product:attributes">
			<div>
				<input type="hidden" name="Products[<mvt:eval expr="l.pos1"/>]:attributes[<mvt:eval expr="l.pos2"/>]:code" value="&mvte:attribute:code;" />
				<mvt:if expr="l.settings:attribute:template_code NE 0">
					<input type="hidden" name="Products[<mvt:eval expr="l.pos1"/>]:attributes[<mvt:eval expr="l.pos2"/>]:template_code" value="&mvte:attribute:template_code;" />
				</mvt:if>
				&mvt:attribute:prompt;
				<mvt:if expr="l.settings:attribute:type EQ 'text'">
					<input type="text" name="Products[<mvt:eval expr="l.pos1"/>]:attributes[<mvt:eval expr="l.pos2"/>]:value" value="&mvte:attribute:value;" class="textfield" />
				<mvt:elseif expr="l.settings:attribute:type EQ 'memo'">
					<textarea name="Products[<mvt:eval expr="l.pos1"/>]:attributes[<mvt:eval expr="l.pos2"/>]:value">&mvte:attribute:value;</textarea>
				<mvt:elseif expr="l.settings:attribute:type EQ 'radio'">
					<mvt:foreach iterator="option" array="attribute:options">
						<label>
							<input type="radio" name="Products[<mvt:eval expr="l.pos1"/>]:attributes[<mvt:eval expr="l.pos2"/>]:value" value="&mvte:option:code;" />
							&mvte:option:prompt;
						</label>
					</mvt:foreach>
				<mvt:elseif expr="( l.settings:attribute:type EQ 'select' ) OR ( l.settings:attribute:type EQ 'swatch-select' )">
					<select name="Products[<mvt:eval expr="l.pos1"/>]:attributes[<mvt:eval expr="l.pos2"/>]:value">
						<mvt:foreach iterator="option" array="attribute:options">
							<option value="&mvte:option:code;">&mvte:option:prompt;</option>
						</mvt:foreach>
					</select>
				<mvt:elseif expr="l.settings:attribute:type EQ 'checkbox'">
					<label>
						<input type="checkbox" name="Products[<mvt:eval expr="l.pos1"/>]:attributes[<mvt:eval expr="l.pos2"/>]:value" />
						&mvt:attribute:prompt;
					</label>
				</mvt:if>
			</div>
		</mvt:foreach>

		<mvt:comment><!-- Subscriptions --></mvt:comment>
		<mvt:if expr="l.settings:subscription:enabled AND l.settings:subscription:term_count">
			<label>Select Subscription</label>
			<select name="Products[<mvt:eval expr="l.pos1"/>]:subterm_id">
				<option value="0">One Time Purchase</option>
				<mvt:foreach iterator="term" array="subscription:terms">
					<option value="&mvte:term:id;">&mvte:term:descrip;</option>
				</mvt:foreach>
			</select>
		</mvt:if>
	</mvt:foreach>
	<button>Add to Basket</button>
</form>
<div class="expanded"><div id="filter-items-container"><mvt:if expr="l.settings:category_listing:products_on_page_count GT 1">
<div class="sorting">
<form method="get" action="&mvte:global:sessionurl;">
<input type="hidden" name="Screen" value="&mvte:global:Screen;" />
<input type="hidden" name="Store_Code" value="&mvte:global:Store_Code;" />
<input type="hidden" name="Category_Code" value="&mvte:global:Category_Code;" />
<input type="hidden" name="Product_Code" value="&mvte:global:Product_Code;" />
<input type="hidden" name="Search" value="&mvte:global:Search;" />
<input type="hidden" name="Per_Page" value="&mvte:global:Per_Page;" />
<label for="Sort_By">Sort By:</label>
<select name="Sort_By" id="Sort_By" onchange="this.form.submit();">
<mvt:if expr="ISNULL g.Sort_By">
<option value="disp_order" selected="selected">Default</option>
<mvt:else>
<option value="disp_order">Default</option>
</mvt:if>
<mvt:if expr="g.Sort_By EQ 'name_asc'">
<option value="name_asc" selected="selected">Name Ascending</option>
<mvt:else>
<option value="name_asc">Name Ascending</option>
</mvt:if>
<mvt:if expr="g.Sort_By EQ 'name_desc'">
<option value="name_desc" selected="selected">Name Descending</option>
<mvt:else>
<option value="name_desc">Name Descending</option>
</mvt:if>
<mvt:if expr="g.Sort_By EQ 'code_asc'">
<option value="code_asc" selected="selected">Code Ascending</option>
<mvt:else>
<option value="code_asc">Code Ascending</option>
</mvt:if>
<mvt:if expr="g.Sort_By EQ 'code_desc'">
<option value="code_desc" selected="selected">Code Descending</option>
<mvt:else>
<option value="code_desc">Code Descending</option>
</mvt:if>
<mvt:if expr="g.Sort_By EQ 'bestsellers'">
<option value="bestsellers" selected="selected">Best Selling</option>
<mvt:else>
<option value="bestsellers">Best Selling</option>
</mvt:if>
<mvt:if expr="g.Sort_By EQ 'price_asc'">
<option value="price_asc" selected="selected">Lowest Price</option>
<mvt:else>
<option value="price_asc">Lowest Price</option>
</mvt:if>
<mvt:if expr="g.Sort_By EQ 'price_desc'">
<option value="price_desc" selected="selected">Highest Price</option>
<mvt:else>
<option value="price_desc">Highest Price</option>
</mvt:if>
<mvt:if expr="g.Sort_By EQ 'newest'">
<option value="newest" selected="selected">Newest Items</option>
<mvt:else>
<option value="newest">Newest Items</option>
</mvt:if>
</select>
<noscript><input type="submit" value="go"></noscript>
</form>
</div></mvt:if><mvt:if expr="l.settings:category_listing:products_on_page_count GT 1">
<div class="per-page">
<form method="get" action="&mvte:global:sessionurl;">
<input type="hidden" name="Screen" value="&mvte:global:Screen;" />
<input type="hidden" name="Store_Code" value="&mvte:global:Store_Code;" />
<input type="hidden" name="Category_Code" value="&mvte:global:Category_Code;" />
<input type="hidden" name="Product_Code" value="&mvte:global:Product_Code;" />
<input type="hidden" name="Search" value="&mvte:global:Search;" />
<input type="hidden" name="Sort_By" value="&mvte:global:Sort_By;" />
<label for="Per_Page">View:</label>
<select name="Per_Page" id="Per_Page" onchange="this.form.submit();">
<mvt:if expr="g.Per_Page EQ 10">
<option value="10" selected="selected">10</option>
<mvt:else>
<option value="10">10</option>
</mvt:if>
<mvt:if expr="g.Per_Page EQ 20">
<option value="20" selected="selected">20</option>
<mvt:else>
<option value="20">20</option>
</mvt:if>
<mvt:if expr="g.Per_Page EQ 40">
<option value="40" selected="selected">40</option>
<mvt:else>
<option value="40">40</option>
</mvt:if>
<mvt:if expr="g.Per_Page EQ -1">
<option value="-1" selected="selected">All</option>
<mvt:else>
<option value="-1">All</option>
</mvt:if>
</select>
<noscript><input type="submit" value="go"></noscript>
</form>
</div></mvt:if>
<mvt:if expr="l.settings:category_listing:page_links:last_page GT 1">
<div class="page-links">
<span class="page-links-title">Page(s):</span>
<span class="page-links-container">
<mvt:if expr="l.settings:category_listing:page_links:current_page NE 1">
<a href="&mvte:category_listing:page_links:prev_link;" class="page-links-previous">&lt;</a>
<mvt:else>
<span class="page-links-previous page-links-deactivated">&lt;</span>
</mvt:if>
<mvt:if expr="l.settings:category_listing:page_links:current_page NE l.settings:category_listing:page_links:last_page">
<a href="&mvte:category_listing:page_links:next_link;" class="page-links-next">&gt;</a>
<mvt:else>
<span class="page-links-next page-links-deactivated">&gt;</span>
</mvt:if>
<span class="page-disp">
<mvt:if expr="NOT l.settings:category_listing:page_links:contains_first">
<a href="&mvte:category_listing:page_links:first_link;" class="page-links-inactive">1</a>...
</mvt:if>
<mvt:foreach iterator="pages" array="category_listing:page_links:pages">
<mvt:if expr="l.settings:category_listing:page_links:current_page EQ l.settings:pages:page_num">
<span class="page-links-active">&mvte:pages:page_num;</span>
<mvt:else>
<a href="&mvte:pages:link;" class="page-links-inactive">&mvte:pages:page_num;</a>
</mvt:if>
</mvt:foreach>
<mvt:if expr="NOT l.settings:category_listing:page_links:contains_last">
...<a href="&mvte:category_listing:page_links:last_link;" class="page-links-inactive">&mvte:category_listing:page_links:last_page;</a>
</mvt:if>
</span>
</span>
</div>
</mvt:if>
</div>
<div class="clear"></div>
<form method="post" action="&mvte:global:sessionurl;Screen=BASK">
<input type="hidden" name="Action" value="ADPM">
<input type="hidden" name="Attributes" value="Yes">
<input type="hidden" name="Store_Code" value="&mvte:store:code;">
<mvt:item name="buttons" param="AddToBasketE" />
<hr>
<div class="clear"></div>
<mvt:foreach iterator="product" array="category_listing:products">
<div class="product-item" style="width:50%">
<div class="padding">
<div class="product-details">
<div class="product-image">
<mvt:if expr="NOT ISNULL l.settings:product:imagetypes:main">
<a href="&mvte:product:link;">
<img src="&mvte:product:imagetypes:main;" alt="&mvte:product:name;" id="main_image_&mvte:product:id;" />
</a>
<mvt:else>
<a class="image-not-available" href="&mvte:product:link;" title="&mvte:product:name;">
<img id="main_image_&mvte:product:id;" src="graphics/en-US/cssui/blank.gif" alt="&mvte:product:name;" />
</a>
</mvt:if>
</div>
<ul id="thumbnails_&mvte:product:id;" class="thumbnails"></ul>
<div id="closeup_div_&mvte:product:id;" class="closeup">
<img id="closeup_image_&mvte:product:id;" src="graphics/en-US/cssui/blank.gif" alt="&mvte:product:name;">
<div>
<a id="closeup_close_&mvte:product:id;">close</a>
</div>
</div>
<div class="product-name"><a href="&mvte:product:link;">&mvt:product:name;</a></div>
<div class="product-code">Code: <span class="bold">&mvt:product:code;</span></div>
<div class="product-code">SKU: <span class="bold">&mvt:product:sku;</span></div>
<div class="product-price">
Price:
<span style="text-decoration: line-through" id="price-value-additional_&mvte:product:id;">
<mvt:if expr="l.settings:product:base_price GT l.settings:product:price">
&mvt:product:formatted_base_price;
</mvt:if>
</span>
<span class="bold" id="price-value_&mvte:product:id;">&mvt:product:formatted_price;</span>
<div id="product-discounts_&mvte:product:id;">
<mvt:foreach iterator="discount" array="product:discounts">
<div class="product-discount">&mvt:discount:descrip;: &mvt:discount:formatted_discount;</div>
</mvt:foreach>
</div>
</div>
<mvt:if expr="l.settings:product:weight NE 0">
<div class="product-weight">Weight: <span class="bold">&mvt:product:weight;</span></div>
</mvt:if>
<div id="inventory-message_&mvte:product:id;"><mvt:if expr="l.settings:product:inv_active">&mvt:product:inv_long;<br></mvt:if></div>
<div class="product-quantity">
Quantity in Basket:
<mvt:if expr="l.settings:product:quantity EQ 0">
<span class="italic">none</span>
<mvt:else>
<span class="italic">&mvt:product:quantity;</span>
</mvt:if>
</div>
</div>
<mvt:if expr="l.settings:product:inv_level NE 'out'">
<div class="purchase-buttons">
<ul id="swatches_&mvte:product:id;" class="swatches"></ul>
<input type="hidden" name="Products[ &mvt:product:id; ]:code" value="&mvte:product:code;" />
<mvt:item name="product_attributes" param="product:id" />
</div>
<b>Quantity:</b> <input type="text" name="Products[ &mvt:product:id; ]:quantity" value="1" size="2" />
</mvt:if>
<mvt:item name="category_listing_imagemachine" param="body:product:id" />
</div>
</div>
</mvt:foreach>
<div class="clear"></div>
<hr>
<mvt:item name="buttons" param="AddToBasketE" />
</form>
<mvt:if expr="NOT l.settings:category_listing:page_disp_count GT 0">
<mvt:if expr="g.CatListingOffset OR g.CatListingNextOffset">
<div class="next-previous">
<mvt:if expr="g.CatListingOffset GT 0">
<div class="previous-button">
<form method="post" action="&mvte:global:sessionurl;">
<input type="hidden" name="Screen" value="&mvte:global:Screen;" />
<input type="hidden" name="Store_Code" value="&mvte:global:Store_Code;" />
<input type="hidden" name="Category_Code" value="&mvte:global:Category_Code;" />
<input type="hidden" name="Product_Code" value="&mvte:global:Product_Code;" />
<input type="hidden" name="Search" value="&mvte:global:Search;" />
<input type="hidden" name="Per_Page" value="&mvte:global:Per_Page;" />
<input type="hidden" name="Sort_By" value="&mvte:global:Sort_By;" />
<input type="hidden" name="Offset" value = "&mvte:global:CatListingPrevOffset;" />
<input type="hidden" name="AllOffset" value = "&mvte:global:AllOffset;" />
<input type="hidden" name="CatListingOffset" value = "&mvte:global:CatListingPrevOffset;" />
<input type="hidden" name="RelatedOffset" value = "&mvte:global:RelatedOffset;" />
<input type="hidden" name="SearchOffset" value = "&mvte:global:SearchOffset;" />
<mvt:item name="buttons" param="Previous" />
</form>
</div>
</mvt:if>
<mvt:if expr="g.CatListingNextOffset GT 0">
<div class="next-button">
<form method="post" action="&mvte:global:sessionurl;">
<input type="hidden" name="Screen" value="&mvte:global:Screen;" />
<input type="hidden" name="Store_Code" value="&mvte:global:Store_Code;" />
<input type="hidden" name="Category_Code" value="&mvte:global:Category_Code;" />
<input type="hidden" name="Product_Code" value="&mvte:global:Product_Code;" />
<input type="hidden" name="Search" value="&mvte:global:Search;" />
<input type="hidden" name="Per_Page" value="&mvte:global:Per_Page;" />
<input type="hidden" name="Sort_By" value="&mvte:global:Sort_By;" />
<input type="hidden" name="Offset" value = "&mvte:global:CatListingNextOffset;" />
<input type="hidden" name="AllOffset" value = "&mvte:global:AllOffset;" />
<input type="hidden" name="CatListingOffset" value = "&mvte:global:CatListingNextOffset;" />
<input type="hidden" name="RelatedOffset" value = "&mvte:global:RelatedOffset;" />
<input type="hidden" name="SearchOffset" value = "&mvte:global:SearchOffset;" />
<mvt:item name="buttons" param="Next" />
</form>
</div>
</mvt:if>
</div>
</mvt:if>
</mvt:if>
</div>
<mvt:item name="html_profile" />
<head>
<title>&mvt:store:name;: &mvt:category:name;</title>
<base href="&mvt:global:basehref;" />
<mvt:item name="prodctgy_meta" param="ctgy" />
<mvt:item name="head" param="css_list" />
<mvt:item name="head" param="head_tag" />
<mvt:item name="category_listing_imagemachine" param="head" />
</head>
<body class="CTGY">
<div id="site-container">
<div id="global-header"><mvt:item name="hdft" param="global_header" /></div>
<div id="navigation-bar"><mvt:item name="navbar" /></div>
<table id="content-container">
<tr>
<td id="left-navigation"><mvt:item name="category_tree" /></td>
<td id="main-content">
<div id="page-header"><mvt:item name="hdft" param="header" /></div>
<div id="breadcrumbs"><mvt:item name="breadcrumbs" /></div>
<div id="category-header"><mvt:item name="prod_ctgy_hdft" param="ctgy_header" /></div>
<mvt:if expr="NOT ISNULL l.settings:category_title:image">
<img src="&mvte:category_title:image;" alt="&mvte:category:name;" />
<mvt:else>
<h1>&mvte:category:name;</h1>
</mvt:if>
<div id="category-listing"><mvt:item name="category_listing" /></div>
<div id="category-footer"><mvt:item name="prod_ctgy_hdft" param="ctgy_footer" /></div>
<div id="page-footer"><mvt:item name="hdft" param="footer" /></div>
</td>
</tr>
</table>
<div id="bottom-wrap"></div>
<div id="global-footer"><mvt:item name="hdft" param="global_footer" /></div>
</div>
</body>
</html>
<table>
<mvt:foreach iterator="attribute" array="attributes">
<tr>
<td class="prompt">
<input type="hidden" name="Products[ &mvt:product:id; ]:attributes[ &mvt:attribute:index; ]:code" value="&mvte:attribute:code;" />
<mvt:if expr="l.settings:attribute:template_code NE 0">
<input type="hidden" name="Products[ &mvt:product:id; ]:attributes[ &mvt:attribute:index; ]:template_code" value="&mvte:attribute:template_code;" />
</mvt:if>
<mvt:if expr="l.settings:attribute:type NE 'checkbox'">
<mvt:if expr="l.settings:attribute:image">
<img src="&mvte:attribute:image;" alt="&mvte:attribute:raw_prompt;" />
<mvt:else>
<mvt:if expr="l.settings:attribute:required">
<span class="required">
<mvt:else>
<span>
</mvt:if>
&mvt:attribute:prompt;
</span>
</mvt:if>
<mvt:else>
&nbsp;
</mvt:if>
</td>
<td class="field">
<mvt:if expr="l.settings:attribute:type EQ 'text'">
<input type="text" name="Products[ &mvt:product:id; ]:attributes[ &mvt:attribute:index; ]:value" value="&mvte:attribute:value;" class="textfield" />
<mvt:elseif expr="l.settings:attribute:type EQ 'memo'">
<textarea name="Products[ &mvt:product:id; ]:attributes[ &mvt:attribute:index; ]:value">&mvte:attribute:value;</textarea>
<mvt:elseif expr="l.settings:attribute:type EQ 'radio'">
<mvt:foreach iterator="option" array="attribute:options">
<div>
<mvt:if expr="( ( g.Products[l.settings:product:id]:attributes[l.settings:attribute:index]:value EQ 0 ) AND
( l.settings:option:id EQ l.settings:attribute:default_id ) ) OR
( g.Products[l.settings:product:id]:attributes[l.settings:attribute:index]:value EQ l.settings:option:code )">
<input type="radio" name="Products[ &mvt:product:id; ]:attributes[ &mvt:attribute:index; ]:value" value="&mvte:option:code;" checked />
<mvt:else>
<input type="radio" name="Products[ &mvt:product:id; ]:attributes[ &mvt:attribute:index; ]:value" value="&mvte:option:code;" />
</mvt:if>
<mvt:if expr="l.settings:option:image">
<img src="&mvte:option:image;" alt="&mvte:option:prompt;" />
<mvt:else>
&mvte:option:prompt;
</mvt:if>
</div>
</mvt:foreach>
<mvt:elseif expr="( l.settings:attribute:type EQ 'select' ) OR ( l.settings:attribute:type EQ 'swatch-select' )">
<select name="Products[ &mvt:product:id; ]:attributes[ &mvt:attribute:index; ]:value">
<mvt:foreach iterator="option" array="attribute:options">
<mvt:if expr="( ( g.Products[l.settings:product:id]:attributes[l.settings:attribute:index]:value EQ 0 ) AND ( l.settings:option:id EQ l.settings:attribute:default_id ) ) OR
( g.Products[l.settings:product:id]:attributes[l.settings:attribute:index]:value EQ l.settings:option:code )">
<option value="&mvte:option:code;" selected>&mvte:option:prompt;</option>
<mvt:else>
<option value="&mvte:option:code;">&mvte:option:prompt;</option>
</mvt:if>
</mvt:foreach>
</select>
<mvt:elseif expr="l.settings:attribute:type EQ 'checkbox'">
<mvt:if expr="g.Products[l.settings:product:id]:attributes[l.settings:attribute:index]:value">
<input type="checkbox" name="Products[ &mvt:product:id; ]:attributes[ &mvt:attribute:index; ]:value" value="Yes" checked />
<mvt:else>
<input type="checkbox" name="Products[ &mvt:product:id; ]:attributes[ &mvt:attribute:index; ]:value" />
</mvt:if>
<mvt:if expr="l.settings:attribute:image">
<img src="&mvte:attribute:image;" alt="&mvte:attribute:raw_prompt;" />
<mvt:else>
<mvt:if expr="l.settings:attribute:required">
<span class="required">
<mvt:else>
<span>
</mvt:if>
&mvt:attribute:prompt;
</span>
</mvt:if>
</mvt:if>
</td>
</tr>
</mvt:foreach>
</table>
<mvt:if expr="l.settings:subscription:enabled AND l.settings:subscription:term_count">
<label>Select Subscription</label>
<select name="Products[<mvt:eval expr="l.pos1"/>]:subterm_id">
<option value="0">One Time Purchase</option>
<mvt:foreach iterator="term" array="subscription:terms">
<option value="&mvte:term:id;">&mvte:term:descrip;</option>
</mvt:foreach>
</select>
</mvt:if>
<div class="clear"></div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.