Skip to content| Skip to navigation

Miva Merchant Quick Tip: Matching Multiple Variables in a Conditional

May 27th, 2009 by Tiny Queen

This morning I was working on a small project to modify the layout of the attributes on a product page template, and it occurred to me that others might find this little trick about writing conditionals where you need to match a multitude of variables useful.

In this particular project, I needed conditionals for two purposes: one in one location of the template to check to see if the attribute template code was either the word “Length” or the word “Width” and the second in a separate location to check to see if the template code was either “LengthFraction” or “WidthFraction.”

Since I was trying to match the code against a list of variables, I could have written my conditional like so:

<mvt:if expr="l.settings:attribute:template_code IN 'LengthFraction, WidthFraction'">

Anyone else see a problem with this though? The above conditional, which checks to see if the content of the template code variable exists in either the words LengthFraction or WidthFraction will return true not only if the template code is actually LengthFraction or WidthFraction, but also if the template code is merely Length or Width.

So, we need to be a little more specific. Since I was only trying to match one of two different variables, I could have written my conditional like this instead:

<mvt:if expr="((l.settings:attribute:template_code EQ 'LengthFraction') OR (l.settings:attribute:template_code EQ 'WidthFraction'))">

That’s fine when you only have a couple of variables to test against, but if you have several codes you want to match up, there’s a much cleaner and easier way. By making use of Store Morph Technology’s (SMT) concatenating feature, you can use the IN expression to check against a list of several codes, without the risk of inexact matches.

Here’s the code:

<mvt:if expr="'|'$l.settings:attribute:template:code$'|' IN '|Length|Width|'">

And here’s how it works.

The very first element in the conditional is a string (enclosed by single quotes) consisting of a pipe character, aka | . Next to the string is a $ sign. In many scripting languages the $ sign is used to indicate a variable, but in SMT, the $ sign is a concatenator. That is, it takes whatever string or variable is in front of it, and joins it to whatever string or variable is after it.

The next element in our conditional is the SMT variable we are wanting to test, in this case, the attribute template code. It’s followed by another $ sign and another string consisting of a pipe character. The result is that the first part of our conditional expression consists of the template code surrounded by pipes:
|Length|
|LengthFraction|
|Width|
|WidthFraction| etc.

The second element in the conditional is a string, consisting of a list of the codes we want to match. The list begins and ends with a pipe character, and the codes in the list are also separated with pipe characters.

What this means is that if the conditional tries to match |Length| to |LengthFraction| it will now return false, since there isn’t an exact character to character match — although the |Length part of the first element is found in |LengthFraction| the pipe at the end of |Length| does not appear in that same position in |LengthFraction| and so the conditional will return false.

So there you have it. A complex conditional made short and sweet.

  • Twitter
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • Yahoo! Bookmarks
  • Technorati

My "Can't Live Without 'Em" List of Web Design Tools

March 21st, 2009 by Tiny Queen


I know, I know, pretty much every web designer out there has published a list of helpful tools they just couldn’t live without. And there are some great lists out there — I can easily waste an entire day just browsing from list to list and looking at all the nifty applications that can help make a web designer’s job just that little bit easier.

But I have a few handy little apps of my own that I’d like to add to the lists out there…because after all, you just can’t have too much of a good thing. Some are free, some are not, some are probably found on every other designer’s list, but all of them are well worth checking out.

HTML and CSS Tools

TopStyle – I own several html editors, and I admit I use them all for certain things, but my html/css/php editor of choice is this compact, easy to configure application. It has some terrific tools that make troubleshooting coding errors a snap (the tag matching feature is a must-have) and even has handy helpers for choosing color palettes, cleaning up your css, and overall site management. And best of all, with its intuitive menus and great built-in help files, you can set it up and learn to use its features in no time.

Firebug – This Firefox add-on is a must-have for troubleshooting layout issues, tweaking designs, and getting things downright pixel-perfect. One of my favorite ways to use it (aside from troubleshooting) is for trying out different design versions without having to create multiple mockups of a page. You can swap out colors, images, borders, change placement of elements, etc with just a few clicks, and see the results instantly on the screen.

Image Editing and Color Tools

Irfanview – Handy little photo editor that allows you to quickly resize, crop and do basic touchups on your photos.

Pixie – I’ve tried several color selection tools, but this tiny application is a fave. Need to match the colors in a logo to the colors in a site? Just launch this little helper, mouse over the color area on the screen, and you’re done. Simple and brilliant. I often use Pixie in combination with this Color Palette Creator to get a range of shades of a given color for use on a site.

Fireshot – This is another add-on for Firefox. With Fireshot, you can create quick screenshots of your browser window, or the entire web page. Add notes, text, drawings, shapes, crop, edit and save, email or simply copy the result to your clipboard. Great for quick tutorials on using a web application’s admin features, pointing out a section of the layout that needs tweaking, etc. And I have to admit…I’m a sucker for the camera shutter sound effect.

File Management Tools

Bulk Rename Utility – I recently worked on a project where an ecommerce site owner discovered he would have to rename in excess of 400 alternate product view images in order to get them to work with a custom script. He was not a happy camper until I shared this free utility with him. With just a few clicks, we were able to rename all of the photos in a matter of minutes. The flexibility of this utility is simply outstanding — with a little creative thought, it can handle pretty much any renaming needs you might have.

Dust Me Selectors – Over time, any large web site accumulates css styles that become obsolete, but are still cluttering up the stylesheet. Dust Me Selectors is a Firefox add-on that creates a list of selectors that aren’t being used. Great for cleaning up an overgrown site.

HTML Link Validator – We’ve all done it. You play with different versions of a page, and in the process wind up uploading index-test.html, index2.html, index-new.html to the server. Or, you’re updating a file, and want to preserve the original version as a rollback option if needed. So you end up with file.php, file.php.orig, file.php.bak, file.php.032009 and so on. Or, if you run an ecommerce site, you may have products that have been inactivated, but the images are still on your server. If you’re careful, you remember to clean up those files, but all too often, they get left behind on the server as orphans. Over time, the number of orphans on even a well-maintained site can get overwhelming. This handy tool will browse your server and find those orphaned files so that you can delete them.

  • Twitter
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • Yahoo! Bookmarks
  • Technorati

Miva Merchant: Customer Account Creation on INVC Page

February 26th, 2009 by Tiny Queen

Recently there’s been lots of buzz on the Miva Merchant User Support Forum about moving the account creation process to the end of the checkout. There are a number of good reasons for doing this. First, you eliminate one of the checkout screens, and streamline the checkout process. Second, and more importantly, you eliminate a decision from the checkout process.

There’s a great usability book out there by a fellow named Steve Krug, called “Don’t Make Me Think” That book title couldn’t be more apt for the checkout process in a shopping cart. When your shoppers commit enough to hit the checkout button, don’t present them with a new decision to have to make before they can get started.

As one person put it, your shoppers aren’t looking to develop a relationship with you. You have something they want, and they want to give you their money so you can send it to them. Since you want to get their money and send them things, it seems you have a common goal. So why not make it easier to achieve that goal? Get the sale, and then offer them the opportunity to create an account if they think they’d like to come back and shop again. But don’t clutter the checkout process with an unnecessary decision.

So, to the meat of the matter. How does one go about creating an account for a customer using the information available on the INVC page? Since they’ve already provided their shipping and billing information, there are only two additional bits you need from them: a user name, and a password. The rest you can feed to the form from what they’ve already told you.

In your INVC page template, decide where you want to present the account creation option, and add the following code. The hidden input for PrevPage isn’t required, but it gives you a global variable to test against if you want to customize the ACED page to display a “Thank you for creating your account” message instead of the account edit form.

You’ll have to do your own form styling, but this should give you the bare bones you need to get started.

<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="ICST">
<input type="hidden" name="Screen" value="ACED">
<input type="hidden" name="PrevPage" value="INVC">
<label for="login">User Name</label>
<input type="text" id="login" name="Customer_Login" value="&mvte:global:Customer_Login;">
<label for="pass">Password</label>
<input type="password" id="pass" name="Customer_Password" size="25" value="&mvte:global:Customer_Password;">
<label for="verifypass">Confirm Password</label>
<input type="password" id="verifypass" name="Customer_VerifyPassword" size="25" value="&mvte:global:Customer_VerifyPassword;">
<input type="hidden" name="Customer_PasswordEmail" value="&mvte:order:bill_email;">
<input type="hidden" name="Customer_ShipFirstName" value="&mvte:order:ship_fname;">
<input type="hidden" name="Customer_ShipLastName" value="&mvte:order:ship_lname;">
<input type="hidden" name="Customer_ShipEmail" value="&mvte:order:ship_email;">
<input type="hidden" name="Customer_ShipPhone" value="&mvte:order:ship_phone;">
<input type="hidden" name="Customer_ShipFax" value="&mvte:order:ship_fax;">
<input type="hidden" name="Customer_ShipAddress" value="&mvte:order:bill_addr;">
<input type="hidden" name="Customer_ShipCompany" value="&mvte:order:ship_comp;">
<input type="hidden" name="Customer_ShipCity" value="&mvte:order:ship_city;">
<input type="hidden" name="Customer_ShipState" value="&mvte:order:ship_state;">
<input type="hidden" name="Customer_ShipZip" value="&mvte:order:ship_zip;">
<input type="hidden" name="Customer_ShipCountry" value="&mvte:order:ship_cntry;">
<input type="hidden" name="Customer_BillFirstName" value="&mvte:order:bill_fname;">
<input type="hidden" name="Customer_BillLastName" value="&mvte:order:bill_lname;">
<input type="hidden" name="Customer_BillEmail" value="&mvte:order:bill_email;">
<input type="hidden" name="Customer_BillPhone" value="&mvte:order:bill_phone;">
<input type="hidden" name="Customer_BillFax" value="&mvte:order:bill_fax;">
<input type="hidden" name="Customer_BillAddress" value="&mvte:order:bill_addr;">
<input type="hidden" name="Customer_BillCompany" value="&mvte:order:bill_comp;">
<input type="hidden" name="Customer_BillCity" value="&mvte:order:bill_city;">
<input type="hidden" name="Customer_BillState" value="&mvte:order:bill_state;">
<input type="hidden" name="Customer_BillZip" value="&mvte:order:bill_zip;">
<input type="hidden" name="Customer_BillCountry" value="&mvte:order:bill_cntry;">
<mvt:item name="buttons" param="Save" />
</form>
  • Twitter
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • Yahoo! Bookmarks
  • Technorati

Sometimes it's ok to fudge it

November 23rd, 2008 by Tiny Queen

I stumbled across a laundry list of “Popular Web Design Links” over the weekend, and I’ve been having quite a spiffin’ time poking around other peoples’ blogs and forums, and reading posts and their related comments. I came across some interesting tidbits, had a few “aha” moments, and a little bit of just good old-fashioned validation of my own best practices when it comes to web design.

I have to admit, though, that I was a little bit put off by the number of posts I came across featuring people who are dead set on “doing it right.” Don’t get me wrong. I truly believe that coding to standards is always something to strive for, and I do try to stick to my principles as far as the whole “presentation” vs. “content” issue goes.

The fact is, though, that sometimes rules are meant to be bent. I admit it. I routinely set up styles called “left” and “right” and use them to float elements…you guessed it…to the left or to the right. Yes, I know that’s evil as far as the coding gods are concerned. But it’s also practical. When I’m typing my code, I can remember “left” and “right.” I don’t have to endlessly search for some sort of false semantic meaning for an image or a paragraph or even a table cell that I want to align to the right. I can just slap a label on the element and move on.

Yes, I know that someday that “right” might become “left.” I guess that’s a risk I’m willing to take. Sometimes it’s better to be simple and straightforward than to be…well…”right.”

  • Twitter
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • Yahoo! Bookmarks
  • Technorati

Miva Merchant: A Store Morph Technology Mini-Primer

November 9th, 2008 by Tiny Queen

Store Morph Technology
When Miva Merchant released MM5, they revolutionized the way the software worked “out of the box” and opened a whole new world of customization to ecommerce store owners. Using Store Morph Technology (SMT), store owners could completely and…well, I was going to say easily customize their stores to suit their needs, but the truth is that at first glance, SMT isn’t in fact all that easy.

One of the common complaints from new developers of MM sites, is the lack of documentation about SMT and how it works. The new owners of Miva Merchant are working hard to remedy the documentation void, but in the meantime, here’s a mini primer on SMT and some examples of the things you can do with it.

You’ll see SMT in MM’s page templates in a variety of different forms.

Variables

There are two types of variables in SMT: local variables, specific to the page you’re on, and global variables, which are available sitewide. The best way to find out what variables are available on a given page is to download the free Store Helper Module from Latu.net.

Variables are displayed on MM pages in a variety of ways. Note that variables always begin with an ampersand (&) and end with a semicolon (;).

&mvt:product:code;
&mvte:product:code;
&mvta:product:code;

Variables that begin with &mvte are “entity encoded.” This means that any characters they contain will be displayed on the page in their exact form — they will not be interpreted by the browser.

Variables that begin with &mvta are “attribute encoded.” This means that any characters they contain will be converted to the correct format for use in a link.

Tags

SMT tags look similar to XHTML tags in that they are surrounded by < >, they include name / value pairs, with the values surrounded by double quotes, and all SMT tags must be closed, either by using a trailing slash, or with a separate closing tag.

Items

SMT tags may call in specific page items. These tags start with mvt:item, and use name=”xyz” to identify which page item is being called. They may also include parameters that more specifically identify the content to be called in. They are frequently self closing, but may have a separate closing tag depending on their form.

<mvt:item name="html_profile" />

<mvt:item name="fonts" param="body_font" />
Some content here
</mvt:item>

Loops and arrays

SMT tags may be used to loop through an array, and display specific data associated with that array. Common uses for these tags include such things as displaying the products in a category or search result, listing all of the products in the basket, or listing available shipping methods. All loops must be closed with a separate closing tag after you’ve worked with the content you’re pulling from the array.

<mvt:foreach iterator="product" array="products">
Some stuff about each of the items in this array
</mvt:foreach>

Conditionals

Finally, SMT tags may be used to create conditionals. This is far and away one of the most useful aspects of SMT, and is the building block of the store owner’s ability to customize his or her store (at least in my opinion!). Writing conditionals is probably worthy of a post all its own, but here are some basics.

All conditionals start with mvt:if and contain an expression to test for. A very basic conditional might look like this. This conditional checks to see if the product code is equal to the string 12345, and if it is, displays some text. Note that the string is enclosed in single quotes.

<mvt:if expr="l.settings:product:code EQ '12345'">
Display some text.
</mvt:if>

Conditionals can also be set up to do one thing if the condition is true, and another thing if it is false.

<mvt:if expr="l.settings:product:code EQ '12345'">
Display some text.
<mvt:else>
Display some other text.
</mvt:if>

Or even…

<mvt:if expr="l.settings:product:code EQ '12345'">
Display some text.
<mvt:elseif expr="l.settings:product:code EQ '45678'">
Display some other text.
<mvt:else>
Display yet some other text.
</mvt:if>

Expressions can be combined to create extremely specific situations to test against. For instance, if you want to display some text only if the product code is 12345 and the customer is logged in, you would write your conditional something like this:

<mvt:if expr="((l.settings:product:code EQ '12345') AND (g.Basket:Cust_id))">
Display some text
</mvt:if>

You can also easily test for a match in a single string or a series of strings, by using CIN or IN. CIN is case insensitive; IN is case sensitive. The strings to test against are enclosed in single quotes, and if there is more than one, they are separated by commas or some other delimiter such as a pipe. The conditional below will return true if the product code is 12345 or 45678 or 67890.

<mvt:if expr="l.settings:product:code IN '12345,45678,67890'">
Display some text.
</mvt:if>

Note that the conditional above will also return true if the product code is 1234567, 012345, or 98712356789. It checks merely to see if the content of the first variable is included in the second. If you need to look for an exact match, you would be better to use a conditional like the following.

<mvt:if expr="((l.settings:product:code EQ '12345') OR (l.settings:product:code EQ '45678') OR (l.settings:product:code EQ '67890'))">
Display some text.
</mvt:if>

Once you get the hang of them, you’ll wonder how you ever did without the power of conditionals to control your shopper’s experience on your site. Below are some of the most common conditional operators, along with what they do.

Operator Function
NOT Returns true if the condition does not match the variable
ISNULL Returns true if the variable is empty
AND Returns true if both conditions are true
OR Returns true if any of the conditions is true
EQ Returns true if the variable matches the string
NE Returns true if the variable does not match the string
GT Returns true if the variable is greater than the string
LT Returns true if the variable is less than the string
GE Returns true if the variable is greater than or equal to the string
LE Returns true if the variable is less than or equal to the string
IN Returns the first position of string_a in string_b. Case sensitive
CIN Returns the first position of string_a in string_b. Case insensitive

Comments

Finally, one of the most useful, and underused in my opinion, features of SMT is the comment feature. By carefully commenting your work, you make it so much easier on yourself or another developer when it comes time to try to make updates or changes to existing customizations. SMT comments take the following form. They are not parsed by the server, and won’t appear in your html source code.

<mvt:comment>
Here is an explanation of what this section of code is going to do.
</mvt:comment>
  • Twitter
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • Yahoo! Bookmarks
  • Technorati

Miva Merchant Custom Product Field Conundrums

October 29th, 2008 by Tiny Queen

One of the handiest features of Miva Merchant 5+ is the inclusion of built in custom product fields. These fields can be used for an enormous variety of purposes, from adding product specific data (author, manufacturer, dimensions, materials, etc) to acting as a boolean-style test variable for setting up conditional displays of information.

Unfortunately, custom product fields are not quite as intuitive as they are handy. So here are some tips for working with them.

First, how to set them up?

  1. In the Miva Merchant admin, in the left hand menu, click Utilities (the word, not the plus sign). Check the box beside Custom Fields and click Update.
  2. You will now see some new tabs across the top of the configuration settings. Click Custom Product Fields.
  3. Click Add. Enter a Code (see Tips & Tricks below) and a Name and click Update.

Second, you have custom product fields, now what?

To add custom field data to your products, there are two methods you can use.

Method 1:

  1. In Quick Find, select Products. In the search box, type a search term for your product and click Go.
  2. In the row for your chosen product, click Edit.
  3. In the tabs above the input boxes, you’ll see Custom Fields. Click that tab, and you’ll see your new custom field displayed, with a text box beside it.
  4. Enter your text (see Tips & Tricks below) and click Update.

Method 2:

If you have a lot of products for which you need to add custom fields, the above method isn’t very practical. Instead, you may wish to use the built in import functionality. The easiest way to do this is to start by setting up a single product with some content for your custom fields.

  1. Start by following the steps above for a single product.
  2. Then, expand Utilities (this time click on the plus sign).
  3. Expand Export Data and click Export Products to Flat File.
  4. In the custom field sections, check the box(es) beside your new custom field(s).
  5. Select your other settings, and click Export.
  6. Your export file will be in your mivadata directory, typically above the root on your server. Contact your host if you are not certain how to locate this file.
  7. Import the file into Excel or another suitable program, and enter the data for your custom field(s).
  8. Save the file as tab delimited (this has its own issues, which I’ll address in another blog post) and import to Miva Merchant.

Third, you’ve got data…now how to get it to show up on the site?

So, you have your content saved in your new custom product fields, and now you’d like to display it somewhere on a product page. Here’s where the tricky part comes in.

Custom product fields are available by default on the PROD (Product), CTGY (Category), SRCH (Search) and PLST (Product List) pages. Other pages may require the Tool Kit from Emporium Plus to access custom fields.

In order to display a custom product field on your product page, you must enable it.

  1. To start, go to Pages> PROD and click Edit.
  2. Click the Tab for Product Display Layout.
  3. If you are in Advanced Mode, you will need to switch to Point and Click mode. Look for the link near the bottom of the screen.
  4. In Point and Click mode, you will see a section for Custom Fields, with your new custom field, and a checkbox to activate it.
  5. Check the box, and click Update.

Important: If you’ve made any modifications to your template, activating the custom fields will reset the template back to its original state.

  1. In order to both recall your changes and insert your new custom fields, you will need to switch to Advanced Mode by clicking the link at the bottom of the screen.
  2. From the version history, select your most recent version prior to this update, and click recall. Then click update.
  3. Now to insert your custom product field, you will need to paste the code below into your template where you would like it to appear. You may of course modify the code as needed to suit your purposes, and do be sure to replace YourCode with your actual custom field code.
<mvt:if expr="NOT ISNULL l.settings:product:customfield_values:customfields:YourCode">
&mvt:customfield_names:customfields:YourCode;:
<b>&mvt:product:customfield_values:customfields:YourCode;</b><br>
</mvt:if>

Finally, the Promised Tips and Tricks

There are some sneaky things about custom product fields that I’ve found out the hard way. If you’ve followed the steps above, and the custom fields still aren’t showing as intended, here are some things to check.

  1. Make sure the custom product field has data. Check that the product on the page you’re looking at actually has some content in its custom field.
  2. Make sure you enabled the custom field properly in the relevant template using the steps above (I know…but humor me and double check anyway).
  3. If you edited the page template to restore your customizations, make sure you correctly entered your custom field code in the store morph tokens.
  4. Check the length of the custom field code. It has been my experience (completely unverified and anecdotal though it may be) that custom field codes that are longer than 10 or so characters do not work as expected. The code seems to get truncated, which means that the store morph token doesn’t match it, and therefore it doesn’t display.
  5. Check for hyphens in your custom field code. Sometimes they work ok, but other times they create problems. If at all possible, keep your custom field codes short, and use alpha and numerical characters only.

One final word on custom fields. They have a character limit, set in the database, of 254 characters. If you’re using MySQL, you can edit the s01_CFM_ProdValues table and set the type for the Value field to tinytext or tinyblob depending on your needs. If you’re not experienced in working with MySQL, ask your host for help, or hire a professional to do this for you.

  • Twitter
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • Yahoo! Bookmarks
  • Technorati

Taking Care of Business – Calendaring Important Web Events

October 13th, 2008 by Tiny Queen

On Friday, I got the sort of email every web developer dreads. The subject line…”BIG Problem”…said it all. The fact that I had spent that morning doing some updates on the site didn’t help my sinking feeling. My first thought, naturally, was that I had overlooked some major layout issue, and the site had gone haywire. In this case, though, it was something far more serious.

It turned out that the site’s security certificate had expired the day before. For this very busy ecommerce site, doing in excess of $1 million per year in online sales, an expired certificate, even for only a short period of time, meant significant revenue loss. I jumped in and tracked down the security certificate’s renewal information, helped the site owner generate and collect the information needed for the renewal process, and had the host set up a temporary shared certificate so that the site wouldn’t continue to lose sales while the security certificate company’s validation process was being completed.

Fortunately, we were able to minimize the damage that this administrative lapse might have caused, but it’s an important reminder to us all. Don’t rely on renewal emails for important details related to your website. You never know when they might go astray. Take the time to calendar your important web events:

  1. Domain registration renewal
  2. Security certificate expiration
  3. Web hosting contract renewal
  4. Software license renewals

This simple step can save you big headaches, and big bucks. Take control of your site. Take control of your business. You’ll be glad you did.

  • Twitter
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • Yahoo! Bookmarks
  • Technorati

Nobody told me there was going to be math…

September 13th, 2008 by Tiny Queen

I’ve been working on a project for a new franchising opportunity. It’s a rather graphics-heavy design, and anyone who knows me will tell you how I feel about working with graphics — it usually involves more than one four-letter word.

In this particular instance, the site owner wanted a horizontal navigation system, with an extended tab on the currently active page. Easy enough to do, except that the navigation items were also divided by a small graphic image (in this case a paw print). In order for the drop-down tab not to bisect the paw prints, the tab needed to be wider than the menu item. To further complicate things, the site is built using the content management system Joomla!, which means that simply styling each page differently wasn’t an easy option. I’d have to come up with something that could be controlled by the Joomla! template.

I first tried styling the navigation bar with different background images assigned to the various elements. But I quickly ran into problems with the width of the list items. I just couldn’t add the dropdown tab without messing up the pawprints.

What to do?

This morning I finally had a brainwave. I decided to create six different background images, with the tab spanning the pawprints. So, I fired up my image editor and set about lining things up. Or at least trying to. Let’s see, the nav bar was 868 pixels wide, and there were 7 paw prints to add, evenly spaced out, and I needed to indent the paw prints on the ends a little, and take into account the width of the paw prints … oy! Out came the calculator, and several not so successful attempts…until I got the idea to add different colored bars above the image to represent each of the navigation items. Once I did that, it became much easier to see where my calculations were off, and in short order I had my six background images.

Navigation Bar

The next task was to code the Joomla! template to assign the appropriate background image to each page. I named my images navbg-1.jpg, navbg-2.jpg, etc, where the number represents the matching page id in Joomla!

In the Joomla! template, I started by adding the following code to the top of the page (above the DOCTYPE):

$page_itemid = JRequest::getVar(‘Itemid’, ”);

Then the head tag section, I added a css styling as follows:

<?php if($page_itemid < '7') : ?>
<style type="text/css">
div.moduletable_menu {
  background:url(../images/navbg-<?php echo $page_itemid ?>.jpg) top left no-repeat
}
</style>
<?php endif; ?>

And the final result?
Navigation sample 1

Navigation sample 2

Navigation Sample 3

Navigation Sample 4

Navigation Sample 5
Navigation Sample 6

The only remaining detail was to add a css image preload to the bottom of the pages so that the background images would load quickly as the user navigates from page to page. I did this by creating a div at the bottom of the template that contains all of the navigation images, and setting its style to display:none.

It’s not a perfect solution, obviously, but it’s at least workable for now, and heaps better than the mess I had created before. If anyone has a better recommendation, I’d love to hear it.

  • Twitter
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • Yahoo! Bookmarks
  • Technorati

Restrict Access to a Product Page in Miva Merchant

July 22nd, 2008 by Tiny Queen

I have received numerous requests for some code I wrote to password protect a product page in Miva Merchant 5 (or 5.5), so I thought I’d share it here. This code was originally written for a site that wanted to implement custom product pricing using the Emporium Plus External Product Purchase module, but wanted to ensure that only staff members could access the page.

Note: This code requires the Tool Kit from Emporium Plus. If you have a Miva Merchant 5 (or 5.5) store, the Tool Kit is an immensely valuable module that allows developers and store owners enormous flexibility in customizing their stores. It is beyond worth the money (and no, I don’t get anything for saying so except the satisfaction of spreading the word about an extremely useful tool).

To use the code below:

  1. Set up an availability group, and assign authorized customers to this group.
  2. Substitute your desired product code where indicated by the text YOUR_PRODUCT_CODE_HERE (2 places).
  3. Substitute your availability group name (not code!) for the AVAILABILITY_GROUP_NAME in the code below.

This code is designed to work on the main screen of the regular PROD page. If you’re using a template manager, you can remove the conditional that tests for the product code.

If you’re using Miva 5 (instead of 5.5), you’ll want to replace <mvt:item name=”html_profile” /> with <html> and <mvt:item name=”head” param=”head_tag” /> with <mvt:item name=”head” />

<mvt:item name="html_profile" />
<head>
<title>&mvt:store:name;: &mvt:product:name;</title>
<base href="&mvt:global:basehref;">
<mvt:item name="head" param="head_tag" />
</head>

<mvt:item name="body">
<mvt:item name="hdft" param="global_header" />

<tr><td align="left" valign="bottom">
   <mvt:item name="hdft" param="header" />
</td></tr>
<tr><td align="left" valign="top" bgcolor="&mvt:colors:ctgy_bg;">
   <table border="0" cellpadding="10" cellspacing="0">
      <tr><td align="left" valign="top" nowrap>
      <mvt:item name="fonts" param="ctgy_font">
      <mvt:item name="customerlink" />
      <mvt:item name="affiliatelink" />
      <mvt:item name="category_tree" />
      </mvt:item>
      </td></tr>
   </table>
</td><td align="left" valign="top" width="80%">
   <br>
   <blockquote>

      <mvt:comment>Test for desired product code</mvt:comment>
        <mvt:if expr="l.settings:product:code EQ 'YOUR_PRODUCT_CODE_HERE'">

      <mvt:comment>Check to see if customer is logged in</mvt:comment>
      <mvt:if expr="g.Basket:CUST_ID">

      <mvt:comment>Check to see if customer is a member of your availability group</mvt:comment>
      <mvt:item name="toolkit" param="agroup|acount" />
      <mvt:foreach iterator="customer_agroup" array="customer_agroups">

      <mvt:comment>Set test variable for use later in the page</mvt:comment>
      <mvt:if expr="l.settings:customer_agroup:name EQ 'YOUR_AVAILABILITY_GROUP'">
      <mvt:item name="toolkit" param="sassign|staffid|1" />
      <mvt:item name="prod_ctgy_hdft" param="prod_header" />
      <mvt:item name="prod_ctgy_hdft" param="prod_header" />
      <mvt:item name="product_display" />

      <mvt:if expr="l.settings:product_count NE 0">
      <br><br>
      <mvt:item name="fonts" param="hdr_font">
      <b>Related Item(s)</b><br>
      </mvt:item>

      <mvt:item name="product_list" />
      </mvt:if>
      <mvt:item name="prod_ctgy_hdft" param="prod_footer" />
      </blockquote>

      </mvt:if>
      </mvt:foreach> <mvt:comment>End Availability Group Array</mvt:comment>
      </mvt:if> <mvt:comment>End display product details if in Availability Group</mvt:comment>

      <mvt:comment>If customer is logged in but staffid variable not set, display continue shopping link</mvt:comment>
      <mvt:if expr="g.Basket:CUST_ID AND (g.staffid NE '1')">
      <p>This page is for internal use only.</p><br><br><br>
     <p><a href="http://domain.com"><img src="graphics/00000001/continue_shopping.jpg" alt="Continue Shopping"></a></p>

     <mvt:comment>Otherwise, if customer is not logged in, display login</mvt:comment>
      <mvt:elseif expr="g.staffid NE '1'">

      <p>This page is for internal use only.  Staff members may log in below.</p>
      <form method="post" action="&mvt:global:secure_sessionurl;">
      <input type="hidden" name="Store_Code" value="&mvte:store:code;">
      <input type="hidden" name="Screen" value="PROD">
      <input type="hidden" name="Product_Code" value="YOUR_PRODUCT_CODE_HERE">
      <label for="user">Username</label>
      <input type="text" id="user" size="20" name="Customer_Login" value="&mvte:global:Customer_Login;">
      <br><br>
      <input type="radio" name="Action" value="LOGN" checked="checked" style="display: none;">
      <label for="pass">Password:</label>
      <input type="password" id="pass" size="20" name="Customer_Password">
      <br><br>
      <mvt:item name="buttons" param="Login" />
      <br><br>
      </form>

      </mvt:if>

      <mvt:comment>For all other products, display the regular layout</mvt:comment>
      <mvt:else>

      <mvt:item name="product_display" />

      <mvt:if expr="l.settings:product_count NE 0">
      <br><br>
      <mvt:item name="fonts" param="hdr_font">
      <b>Related Item(s)</b>
      <br>
      </mvt:item>

      <mvt:item name="product_list" />
      </mvt:if>

      <mvt:item name="prod_ctgy_hdft" param="prod_footer" />

      </blockquote>

      </mvt:if> <mvt:comment>End conditional to test for product code<mvt:comment>

      </td></tr>

      <tr><td align="left" valign="bottom">
      <mvt:item name="hdft" param="footer" />
      </td></tr>
   </table>

<mvt:item name="hdft" param="global_footer" />
</mvt:item>
</html>
  • Twitter
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • Yahoo! Bookmarks
  • Technorati

Happy Mid-Year!

July 2nd, 2008 by Tiny Queen

Ok, ok, I know there isn’t really such a thing as Happy Mid-Year. But one of my New Year’s Resolutions for this year was to post regularly to my blog. It doesn’t take a rocket scientist to see that didn’t exactly happen. So I figured rather than beat myself up over it, I’d declare a new Mid-Year Resolution.

In honor of Happy Mid-Year, I’d like to express some thoughts on the new Miva Merchant 5.5. A party atmosphere is definitely fitting here. Miva Merchant 5.5 not only provides a more aesthetic admin interface, it breaks out some handy new features for developers and store owners alike.

Among my favorites is the new Quick Find feature in the top navigation. The ability to instantly do a product, category, order or customer search without having to first expand multiple menus comes in very handy.

Another favorite is the new category and product sorting feature. Click through to a category, select Category Order: Show and simply enter the new sort order in the text boxes. Click Update to re-order multiple categories or products at once, or enter the new display order number in a single box and hit Enter on your keyboard to move that item to the new location.

The new SEO options are a great benefit to store owners. Products and Categories now have built-in meta tags and store owners can set up search engine friendly links with just a click.

Designers and developers will greatly benefit from the new Dreamweaver integration and the frameworks system. There are still a few bugs being worked out here, but these features show great promise for helping non-technical designers and store owners build an attractive, user friendly site.

Developers will also be pleased to have full access to the underlying template system. Category tree and attribute templates are now fully accessible without module purchases, making creation of a completely custom layout a breeze.

The launch of 5.5 hasn’t been without its hiccups, but the new MM management has shown great responsiveness in dealing with them. If you liked the earlier versions of Miva Merchant, the new MM5.5 will definitely please.

My only complaint about the new look is that the “Log in securely” link is no longer very prominent on the admin login page. My favorite webhost for both Miva Merchant hosting and non-Miva sites, Hostasaurus, suggested this easy to implement solution. Just add the following lines to your .htaccess file to force admin pages to secure so that remembering to click the link is no longer an issue.

RewriteEngine On
RewriteCond %{REQUEST_URI} /mm5/admin.mvc
RewriteCond %{SERVER_PORT} !443
RewriteRule (.*) https://www.domain.com/mm5/admin.mvc [R]
  • Twitter
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • Yahoo! Bookmarks
  • Technorati