Viewing Error Backtraces for Ambiguous Error Messages

There are many times when working with the Magento front end that I get a very ambiguous error message.

I usually just search the entire codebase for the error message code, locate the place where the exception is getting caught, and then temporarily modify the code to Mage::log() the following data: $e->getMessage(), $e->getTraceAsString(), etc…

I just came across an exception handler in the Mage_Checkout_MultishippingController class that passed the generic exception message as well as the Exception class itself to Mage::getSingleton(‘checkout/session’)->addException(). Here’s the code (from line 219 of the containing file):

        catch (Exception $e) {
            Mage::getSingleton('checkout/session')->addException(
                $e,
                Mage::helper('checkout')->__('Data saving problem')
            );
            $this->_redirect('*/*/addresses');
        }

I dug into the Mage::getSingleton(‘checkout/session’)->addException() class and realized that it logged the exception code to the var/logs/exception.log file (it only logs the exception if logging is enabled in System > Preferences > Developer). This means that instead of locating and hacking up core files to see exceptions that are thrown, in a lot of cases, you can just monitor the contents of the exception.log file.

If you’re developing on a Mac machine, you can monitor the contents of the exception.log file using the Console app. If you’re on a Linux box, you can use “tail -f var/log/exception.log” to monitor the contents of this file.

Hopefully this helps you in your debugging efforts!

The Evaluation Process: An Introduction to the Perceived Cost/Benefit Relationship

Before I drill down into the actual Value Presentation, it is important to have a complete understanding of the relationship between Perceived Value and Perceived Cost, which I briefly mentioned in the previous article on Traffic Quality.

We are evaluating things all the time.  We don’t even recognize much of the evaluation that takes place.  It’s usually automatic, subconscious.

This process of evaluation can be broken down into the rising and falling of two perceptions:  Perceived Cost and Perceived Benefit.  To be clear, the cost of something is not just money.  Cost is the receipt of something negative or the release of something positive whereas Benefit is the release of something negative or the receipt of something positive.

When you buy insurance, you give up something positive (your money, your mental energy to think through all the insurance options, and your time talking to the pesky insurance agent), which altogether represents your Cost.  How valuable that Cost is to you depends on your perception, which is why Perceived Cost is what truly matters.  If you sacrifice the Cost, you lose something negative (a certain degree of risk in your life) and you gain something positive (peace of mind), which altogether is your Benefit.  How valuable that is, again, depends on your perception and subjective evaluation of that Benefit.  I’m sure the insurance agents reading this are howling at how much I just oversimplified their jobs.  My apologies.

This is nothing new, though.  This is elementary sales, which is why I’m not going to take any more of my or your time regurgitating it.  I’ll tell you about something unique.

Any time a value presentation is made, be it a candy bar in the checkout rack at a grocery store, a pair of earrings online, or a proposal to marry, there is an initial phase when you open your mind “file cabinet” and pull the “folder” associated with whatever value is being presented.  As you open this folder, certain things will jump out at you, influencing your initial perceived cost and benefit of the value presented.  What is in that folder, what items you pull first, and how much each item affects you depends on two things:

1.  Your history with the value presented

2.  How it is initially presented

This initial reaction to the value presentation is the “First Impression” Phase of the value presentation, which is discussed in greater detail in the next article in the series.

If, at any point, you determine that continuing to give attention to the value presentation isn’t worth the time and energy required to do so, you direct your attention elsewhere and you close the folder and refile it.  This is the act of saying “no” to a transaction.  It might be no for now or no never, but for whatever reason, you decide you are not going to complete the transaction.  We will delve more deeply into what happens when you refile the corresponding folder, but for now, simply understand that the moment you say “no,” the value presentation is over.

A complete and successful value presentation consists of a few vital constituents:

1.  Perceived Benefit Surplus (at which your perceived benefit exceeds your perceived cost)

2.  Commitment (at which you decide to commit to the transaction)

3.  Transaction (at which you consummate the commitment by giving the cost and receiving the benefit or initiating the contract committing both/all parties to do so)

Calls to action (CTAs) will not succeed if the Point of Perceived Benefit Surplus has been reached.  Naturally, visitors will reach that point at different times and for different reasons, which is why it’s typically an effective strategy to give visitors the opportunity to purchase at all times.  You never know when they’ll be ready to bite… I mean, buy.  However, excessive and glaring CTAs can have a negative effect on a visitor’s perceived benefit as they begin to get the feeling that you’re just trying to sell them on something rather than genuinely build value into their life.

It’s also important to note here that the point at which a visitor makes a commitment to the transaction is not the same point at which they complete the transaction.  The time between the commitment and the transaction should be as short and simple as possible.  The more complex and time-consuming it is, the more chance the frustration  of the transaction process or the “cold feet” effect could keep it from happening.  Consider how many wedding engagements do not result in the “sealed deal” of an actual marriage.  Have you ever heard of a wedding being called off because of how frustrating the wedding planning process was?  That’s precisely the same reason you should make it as easy and quick as possible to go from commitment to transaction.  (by the way, I’m not promoting the idea that you should get married the day after you’re engaged to make sure the marriage actually happens… if you’re that uncertain about your future spouse’s commitment, maybe it’s time to slow down and consider NOT sealing the deal.  🙂  )

It’s very important to realize that people continue to evaluate the object even after the commitment and transaction.  Most people consider their business a success if they can get people to pay them money for whatever it is they sell.  I think that’s near-sighted.  Businesses that are built to last give as much attention to the post-transaction evaluation process as they do to the pre-transaction evaluation process.  If you’re just trying to get people to buy your stuff, you’re a con artist.  It’s not about building value into their lives.  It’s about making money…  Had a bit of a soap box moment there.

But even from a purely sustainable basis, you have to think about how your customers/clients will evaluate your offering once they are experiencing it, and even as they reflect on the experience.

Consider the purchase of a candy bar.  You are waiting in line at the grocery store.  It’s late.  You haven’t cooked dinner yet, and you’re hungry.  You see that familiar brown-packaged candy bar with the blue letters and the white secondary color, and you hear those familiar words “Hungry?  Why wait…”  And you grab the candy bar as your perceived benefit rises far above the perceived cost of the nutty, nougatty, caramelly deliciousness.  You begin to get impatient because all you want to do is tear off the glossy covering and devour the bar in four equal bites, but your social cost of embarrassment rises above the perceived value of eating first, paying later, so you do not take that action.  The line is horrendously long, and as you wait interminably, a new thought suddenly comes to your mind…  All those calories will go right to your butt.  You know this.  Past consumptions of equal quality and deliciousness have proven it.  Your brain begins to open up all of the corresponding stigmas associated with gaining weight, and as your mind descends into the depths of the health and social repercussions of partaking in the excellence in your sweating hand, you quickly close that mind folder and tightly squeeze the snack to ensure it cannot escape.  This action causes the exterior chocolate covering of the bar to cave in.  You’ve damaged the candy bar.  Now it’s official.  You absolutely cannot put it back now.  Your moral fiber rears its head at the thought of switching to an uncrumpled version.  The moral cost of such a heinous act is far greater than the 50 cents required to buy it.  Your appetite laughs to itself as it has successfully used your moral compass for its own devices…

Have I said enough?  I hope you can see how complex a seemingly simple evaluation process can be.  And you haven’t even purchased the candy bar yet!  What would happen if you got to the checkout lady, and she made a comment about how obese you are and how the candy bar “aint going to help that situation?”  Or after the transaction, what would happen if you bit into the candy bar and discovered a grub worm inside?  Your actions and perceptions about that candy bar would likely change significantly.

The more you can accurately analyze that process, the better you will be at presenting and delivering value to your customers or clients.  As this series progresses, we will break down and analyze each phase of the evaluation process.

Feel free to ask questions and make comments in the comment section.  I am very actively involved with comments for these articles, so I will respond!

Editing Magento’s Footer Links

To follow up on our post about editing Magento’s top links, I thought I might as well write an article about editing the footer links while I’m at it.  I’d recommend reading our post about using a local.xml file before getting started on this post.  This post might not make much sense until you read it. [NOTE: This specific example assumes you are using the blank theme. Layout handles may differ from theme to theme.]

In local.xml:

<?xml version="1.0"?>
<layout version="0.1.0">
    <default>
        <reference name="footer_links">
            <!-- Add custom links. Pretty self-explanatory.
            Dig into app/code/core/Mage/Page/Block/Template/Links.php for more info -->
            <action method="addLink" translate="label title">
                <label>About Us</label>
                <url>about</url>  <!-- can use a full url if not using urlParams below -->
                <title>About Us</title>
                <prepare>true</prepare> <!-- set true if adding base url param -->
                <urlParams helper="core/url/getHomeUrl"/> <!-- base url - thanks @Russ! -->
                <!-- there are a few param you can send to do different things in <urlParams> 
                         dig into app/code/core/Mage/Core/Model/Url.php, around line 803 -->                   
 
                <!-- below adds #add-fragment to the end of your url -->
                <!-- <urlParams><_fragment>add-fragment</_fragment></urlParams> -->
 
                <!-- below adds ?add-query to the end of your url -->
                <!-- <urlParams><_query>add-fragment</_query></urlParams> -->
 
                <!-- below gives you a new session id (i think...)-->
                <!-- <urlParams><_nosid>true</_nosid></urlParams> -->
 
                <!-- below replaces double quotes, single quotes, greater than, and less than signs 
                         to their respective url escaped replacements (%22, %27, %3E, %3C) -->
                <!-- <urlParams><_escape>i'm-a-blog-url</_escape></urlParams> -->
 
                <position>1</position>
                <liParams/>
                <aParams>class="top-link-about-us"</aParams>
                <beforeText></beforeText>
                <afterText></afterText>
            </action>
 
            <!-- Remove 'Site Map' Link - Default Position: 10
            Original link adding in catalog.xml -->
            <action method="removeLinkByUrl"><url helper="catalog/map/getCategoryUrl" /></action>
 
            <!-- Remove 'Search Terms' Link - Default Position: 20
            Original link adding in catalogsearch.xml-->
            <action method="removeLinkByUrl"><url helper="catalogsearch/getSearchTermUrl" /></action>
 
            <!-- Remove 'Advanced Search' - Default Position: 30
            Original link adding in catalogsearch.xml-->
            <action method="removeLinkByUrl"><url helper="catalogsearch/getAdvancedSearchUrl" /></action>
 
            <!-- Remove 'Contact Us' link - Original link in contacts.xml
            <!-- Best bet to go to Magento's Admin > System > Configuration > (left sidebar) Contacts
            > Contact Us Enabled = NO -->
            <!-- You can pass the full url, which is a hassle if you have dev and stage sites -->
            <action method="removeLinkByUrl"><url>http://YOUR_SITE.com/contacts/</url></action>
            <!-- see comments below for making a custom helper to remove contacts link
            no matter what your base url is  -->
	</reference>
 
        <!-- By default, Magento sets a static footer block. Find it in the admin under
        CMS > Static Blocks.
	<reference name="footer">
            <!-- Remove Magento's default static block and use the 'addLink' method above
            to add your custom and inline links.  I use the 'unsetChild' method as often as
            possible as opposed using the more final <remove name="cms_footer_links"/>
            just in case I want to add the block somewhere else -->
            <action method="unsetChild"><name>cms_footer_links</name></action>
 
            <!-- Remove all the other Magento links - "Site Map, Search Terms, Advanced Search, and
            Contact Us" -->
            <action method="unsetChild"><name>footer_links</name></action> <!-- Magento 1.4.x -->
	</reference>
</default>
</layout>

If all else fails, you can edit template/page/template/links.phtml. However, if you can make all your changes in local.xml, your life will be so much easier when it comes to upgrading Magento and making future edits.

Editing Magento’s Top Links (The Better Way)

You might need to read the post about using a local.xml file before this post makes much sense.

We offer all our clients a completely customized design from scratch, which means changing anything – including those annoying defaulted top links.  This post will show you how to edit your top links (without editing core layout files which may change when you update Magento) by utilizing a local.xml file. You can even add your own custom links without touching any template files! [NOTE: This specific example assumes you are using the blank theme. Layout handles may differ from theme to theme.]

In local.xml:

<?xml version="1.0"?>
<layout version="0.1.0">
    <default>
        <reference name="root">
            <reference name="top.links">
                <!-- Add custom links. Pretty self-explanatory.
                Dig into app/code/core/Mage/Page/Block/Template/Links.php for more info -->
                <action method="addLink" translate="label title">
                    <label>About Us</label>
                    <url>about</url>  <!-- can use full url also -->
                    <title>About Us</title>
                    <prepare>true</prepare> <!-- set true if adding base url param -->
                    <urlParams helper="core/url/getHomeUrl"/> <!-- base url - thanks @Russ! -->
                    <!-- there are a few param you can send to do different things in <urlParams> 
                             dig into app/code/core/Mage/Core/Model/Url.php, around line 803 -->                   

                    <!-- below adds #add-fragment to the end of your url -->
                    <!-- <urlParams><_fragment>add-fragment</_fragment></urlParams> -->

                    <!-- below adds ?add-query to the end of your url -->
                    <!-- <urlParams><_query>add-fragment</_query></urlParams> -->

                    <!-- below gives you a new session id (i think...)-->
                    <!-- <urlParams><_nosid>true</_nosid></urlParams> -->

                    <!-- below replaces double quotes, single quotes, greater than, and less than signs 
                             to their respective url escaped replacements (%22, %27, %3E, %3C) -->
                    <!-- <urlParams><_escape>i'm-a-blog-url</_escape></urlParams> -->

                    <position>1</position>
                    <liParams/>
                    <aParams>class="top-link-about-us"</aParams>
                    <beforeText></beforeText>
                    <afterText></afterText>
                </action>

                <!-- Removes 'My Account' link - Default position: 10 -->
                <action method="removeLinkByUrl"><url helper="customer/getAccountUrl"/></action>

                <!-- Removes 'Wishlist' link - Default position: 20 -->
                <!-- for Magento 1.3.x -->
                <action method="removeLinkByUrl"><url helper="wishlist/"/></action>

                <!-- for Magento 1.4.x -->
                <remove name="wishlist_link"/>

                <!-- Removes 'My Cart' AND 'Checkout' links
                Default position: 40 and 50 respectively -->
                <remove name="checkout_cart_link"/>

                <!-- To re-add 'My Cart' or 'Checkout' after removing both -->
                <block type="checkout/links" name="checkout_cart_link_custom">
                    <action method="addCartLink"></action>
                    <action method="addCheckoutLink"></action>
                </block>
            </reference>
        </reference>
    </default>

    <customer_logged_out>
        <!-- Removes 'Log In' link - Default position: 60 -->
        <reference name="top.links">
            <action method="removeLinkByUrl"><url helper="customer/getLoginUrl"/></action>
        </reference>
    </customer_logged_out>

    <customer_logged_in>
        <!-- Removes 'Log Out' link - Default position: 60 -->
        <reference name="top.links">
            <action method="removeLinkByUrl"><url helper="customer/getLogoutUrl"/></action>
        </reference>
    </customer_logged_in>

</layout>

If you absolutely cannot find a way to customize your top links using these methods, you can edit the /template/page/template/links.phtml

Optimizing Your E-Commerce Conversion Rate: The Two Conversion Criteria

E-commerce traffic is worthless if you are not converting any of your traffic into sales.  The percentage of visits that result in a purchase is called the conversion rate.  So much emphasis is put on generating traffic, but it’s only the first step in building e-commerce revenue and profitability.  It is typically very expensive from a holistic resource perspective (money, time, focus, etc.) to generate traffic, so to pay no attention to conversion rate is committing a cardinal e-commerce sin.  There are a few critical components that determine how high your conversion rate will be.

Step back for a moment.  What would it take to produce a 100% conversion rate?  Every single time someone visited your site, they would purchase something.  Anytime a visitor meets two criteria, they make a purchase.  There are many factors that affect each of these criteria, and I will analyze each of them in this article and following articles.

THE TWO CONVERSION CRITERIA

(Here it is.  The secret recipe for converting visits to sales.)

To convert a visit into a purchase, the visitor must:

1.  Perceive the value of what you offer is higher than the value of the cost to acquire it.

2.  Have the resources to absorb the cost at the point of purchase.

I will analyze these Conversion Criteria from the perspective of a different set of variables.  While it isn’t a quantitative measurement, you can determine the likelihood that an individual will make a purchase via a cubic equation:  Traffic Quality x Value Presentation x Ease of Purchase.  If you have a very high value for any of these variables, it doesn’t necessarily mean you will have a high conversion rate.  Just as with the broader e-commerce revenue equation I covered in the first post of this series (Traffic x Conversion Rate x Average Order Size = Revenue), attention must be given to each of the variables to optimize the outcome.  If any one of them is shirked, it can ruin all of the efforts made to improve the other two.  While you cannot attach a numeric value to these variables as easily as you can to the Revenue variables, it’s still important to understand conceptually because the conversion variables relate in the same way as the revenue variables.

In the next article, I will dig into the first variable that affects conversion rate:  Traffic Quality.

The Better Way to Modify Magento Layouts

In this article, I’m going to be covering what I believe to be a very effective way of modifying the layout of any Magento theme.

For several of the first Magento themes I built, I copied the layout files from the default or blank theme into the custom theme layout folder. I would then modify the layout files directly, editing or commenting out content in files like: catalog.xml, page.xml, checkout.xml, etc… I never liked editing these files directly, as I knew that when it came time to upgrade to a newer version of Magento that had upgraded the layout files, I’d have to merge the changes into the new layout files.

One day, I was digging through the Magento code relating to layout files and discovered a bit of code that made me realize that it was possible to just place a local.xml file in my custom theme’s layout folder and have it loaded automatically by Magento. (this code is on line 283 in /app/code/core/Mage/Core/Model/Layout/Update.php in the fetchFileLayoutUpdates() method).

Due to Magento’s brilliant tags, it’s possible to do just about anything you want without having to edit any of the default layout files.

Before delving into the code, let’s look at the advantages/disadvantages of this method:

Advantages

  • Allows you to upgrade themes without having to merge in changes
  • All custom layout changes are centralized, allowing developers to more easily make changes to custom theme elements

Disadvantages

  • At first, it’s slower to use this method than hacking up the standard layout files directly
  • You will have one more place to look where the site might be pulling code (template phtmls, standard layout files, admin layout updates, AND local.xml)

Here is the slimmed down, commented local.xml from one of our recent projects:

<?xml version="1.0"?>
<layout version="0.1.0">

<default>

	<reference name="head">
		<!-- Magento looks in /skin/frontend/<INTERFACE>/<THEME>/js/buyprinting.js
		for this file -->
		<action method="addItem"><type>skin_js</type><name>js/buyprinting.js</name></action>

		<!-- This removes the item that was set in the page.xml file -->
		<action method="removeItem"><type>skin_js</type><name>js/iehover-fix.js</name></action>

		<!-- Magento looks in /js/prototype/element.storage.js for this file -->
		<action method="addJs"><name>prototype/element.storage.js</name></action>

		<action method="addCss"><stylesheet>css/buyprinting.css</stylesheet></action>
	</reference>

	<reference name="header">
        <!-- This adds a CMS block that can be called from the template file associated with the header block. -->
		<block type="cms/block" name="cms_quick_help">
			<action method="setBlockId"><block_id>quick_help</block_id></action>
		</block>

        <!-- The remove tag removes the blocks with the specified name from the layout -->
		<remove name="top.menu"/>
		<remove name="store_language"/>
		<remove name="breadcrumbs"/>
	</reference>

	<reference name="top.nav">
		<remove name="catalog.topnav"/>
	</reference>

	<reference name="left">
		<remove name="left.newsletter"/>
		<remove name="left.permanent.callout"/>
		<remove name="catalogsearch.leftnav"/>

        <!-- When you use the remove tag, it removes any blocks with the specified name from
            the entire layout, regardless of the context. So, if I remove right.newsletter in
            the <default> context and that name is used in say the <catalog_product_view> context,
            then both blocks will be removed.  Because remove operates on the global context,
            you can only remove an element once.  Since <remove name="right.newsletter" /> is
            being called in catalogsearch.xml, we have to unset it, or else we'll get an error.

            The line below only unsets the block from the parent's context, not the global
            layout context -->
		<action method="unsetChild"><name>right.newsletter</name></action>
	</reference>

	<reference name="right">
        <!-- Some blocks have to be removed using remove, others via unsetChild.
            I've not spent the time digging into the code to figure out why -->
		<remove name="right.permanent.callout"/>
		<remove name="catalog.compare.sidebar"/>
		<remove name="left.reports.product.viewed"/>
		<action method="unsetChild"><name>sale.reorder.sidebar</name></action>
		<action method="unsetChild"><name>wishlist_sidebar</name></action>
		<action method="unsetChild"><name>right.reports.product.viewed</name></action>
		<remove name="cart_sidebar"/>
	</reference>

</default>

<!-- CATALOG PAGES -->
	<catalog_product_view><!-- 2columns-right -->
		<reference name="root">
			<action method="setTemplate"><template>page/2columns-left.phtml</template></action>
		</reference>
		<reference name="content">
			<reference name="product.info">
				<block type="cms/block" name="cms_product_info_tabs">
					<action method="setBlockId"><block_id>product_info_tabs</block_id></action>
				</block>
				<block type="catalog/product_view" name="product.clone_prices" as="prices" template="catalog/product/view/price_clone.phtml"/>
				<action method="unsetChild"><name>tierprices</name></action>
				<action method="unsetChild"><name>addto</name></action>
				<remove name="addto"/>
				<reference name="product.info.options.wrapper.bottom">
					<action method="unsetChild"><name>product.tierprices</name></action>
				</reference>
			</reference>
		</reference>
	</catalog_product_view>

</layout>

I hope with article has given you some direction as to how you can improve you Magento theming skills. If you have any additional tips/comments on coding layouts, please suggest them in the comments section.

The Smart Method of Loading Collections

One fairly unknown feature of Magento collections is that you actually don’t have to call ->load() on a collection before being able to access the items in the collection. So you can do this:

$orders = Mage::getResourceModel('sales/order_collection')->addAttributeToSelect('*');
# The load method is not necessary, as iterating through a collection automatically loads it, if it hasn't already been loaded.
# $orders->load();
foreach($orders as $order){
    echo 'Order Id: ' . $order->getId() . "n";
}

The base Varien_Data_Collection class implements the IteratorAggregate (http://php.net/manual/en/class.iteratoraggregate.php) interface which extends the Traversable (http://www.php.net/manual/en/class.traversable.php) interface. When a class extends the Traversable interface, it guarantees that that class can be iterated through using foreach(). When foreach is called on a collection, it calls the getIterator() method in the Varien_Data_Collection class and uses the value returned from that method as the value that the foreach iterates through. This is the getIterator() method:

    public function getIterator()
    {
        $this->load();
        return new ArrayIterator($this->_items);
    }

This auto-loading functionality works for both EAV and flat-table collections.

As you can see, a collection ensures that it is loaded before running through a for each loop. Note: collections can only be loaded once per instantiation. If you want to reload a collection, you have to call the clear() method, and then reset the select and filters before calling the load() method again.

Knowing that collections function in this way allows you to write code without explicit calls to load(). This ultimately should result in more flexible code. You can have a method in a block that loads a collection. That collection can then either be called by a template file and iterated through, or you can have another method that loads the collection from the first method, and then adds additional selects/filters to it. This practice of not explicitly calling the load() results in more flexible and reusable code.

Saving the Value of a Specific Attribute from a Model

In Magento, it’s very easy to save all the data in a model by running $model->save();. (Note: In this blog post, model refers to an EAV model, not a flat resource model) This saves all the attributes for the model to their respective attribute tables. There are times when saving the value of just one of the model attributes is desirable.

A couple cases where you’d want to do this:

  • You’ve been passed a model from an event, and you aren’t sure if the data in that model can be safely saved.
  • You are saving many models and want to make your save operations as efficient as possible

Here is how you’d save just one attribute of a product model:

$product = Mage::getModel('catalog/product')->load(1);
$product->setName('Some Random Name');
$product->getResource()->saveAttribute($product, 'name');

PHP Single vs. Double Quotes

For a long time, I’ve been a proponent of using single-quotes as opposed to double-quotes when assigning string literals (strings containing no variables) to a variable (eg: $var = ‘string’; VS $var = “string”). I just did some research to find out how much (if any) impact using single-vs-double quotes had on performance.

The results were fairly consistent: Time 1: 5.9485120773315 ($c = “test ” . $i; ) Time 2: 7.0326972007751 ($c = “test $i”; ) Time 3: 5.9164550304413 ($c = ‘test ‘ . $i; ) It’s clear that embedding variables in strings is less efficient, but the difference between normal single-vs-double quotes is negligible (at least on our server configuration with this test). Despite the lack of clear performance benefits, I still think it is best practice to use single-quotes when using string literals, as it denotes that a string doesn’t contain any variables. One benefit of this is that when skimming code, you can more quickly process which variables are string literals vs strings with embedded variables. The Zend Framework Coding Standard also recommends this practice:http://framework.zend.com/manual/en/coding-standard.coding-style.html

The Three Keys to Boost E-Commerce Revenue

Introduction

No matter what you sell online, there are three core constituents to revenue:  Traffic, Conversion Rate, and Average Order Size.  In fact, it’s a cubic equation: Revenue = Traffic (#) x Conversion (%) x Average Order Size ($).  So if you generate 21,000 visits in a month with a conversion rate of 3.00% and an average order size of $156.23, your revenue is $98,424.90 (21,000 x 3.00% x $156.23).

If you can analyze each of these variables effectively, the e-commerce world is your banana.  I hope that by the end of this article series, you’ll understand the “sub-variables” that affect each of these core revenue variables, equipping you with the tools to optimize your e-commerce revenue (btw, many of these principles apply to business in general, not just e-commerce).

This first article will relate to generating Traffic and the variables that affect it.

Keys to Traffic

Traffic is calculated according to the following equation:  Unique Visitors x Average Visit Frequency

Keys to unique visitor traffic are Medium (where they found your site) and Presentation (what they experienced through the medium/media that made them visit).  The key to repeat traffic is the Visit Experience (their evaluation of their visit retrospectively).  Every single person that visits your site has a corresponding medium and presentation history, and if they visit the site more than once, they have an experience history as well.

Medium

The primary factors of a medium are relevance and accessibility.

The key relevance question:  Is the medium used connecting with the kind of people that will see value in what you offer and need it now or at some point in the future, preferably in the near future?

The key accessibility question:  Is it easy for the recipient of the message to take action in response to the message?

Presentation

Every presentation has a persuasive effect that depends on two variables:  To WHOM it’s presented to and WHAT is presented.  WHAT you communicate is worthless without the right audience (they need what you’re offering and they need it now or soon), and likewise, it doesn’t matter how targeted and ripe your audience is for what you’re presenting if WHAT you communicate is poorly constructed.  In fact, it can do more harm than good to make a poor presentation to the right audience by appearing unprofessional and incapable of delivering quality.

The presentation variables depend heavily on the medium in question.  If it is word-of-mouth, the presentation is what is being communicated by the referrer to the referee.  What are they saying about your site and what you offer?  If it’s search marketing, is what you’re communicating in your ad relevant and does it point to a highly relevant landing page?  Are you using highly targeted keywords with ad copy that is tailored to those keywords?  There are quality questions to ask for each medium, and they vary significantly.  But all media should be based on the same quality questions:  Are we communicating to the right audience?  Are we communicating the right message to that audience to effect the desired behavior (click a link, request a quote, submit an e-mail address, buy a product, etc.).

Visit Experience

Experience is the single factor that determines whether a unique visitor becomes a repeat visitor.  In short, visit experience, how a visitor evaluates their visit retrospectively, is defined by if the visitor:

1.  Felt that the content was relevant to them

2.  Felt that they could navigate and access what they wanted easily and intuitively

3.  Has a compelling, memorable reason to return.

If these three criteria are met, the experience will likely develop into a repeat visit.

E-commerce traffic means nothing if you can’t convert that traffic into sales.  In my next post, I’ll discuss the key to optimizing the conversion rate.

Contact Us