Utilizing XSLT with Xtento’s Order Export Magento Module

Overview Example

When working with an ERP integration or another system that requires Magento data to be in a very specific format there are a couple of options. You could write a custom module to handle converting the Magento data directly into the format that the end product requires, or you could use an already built module for it.

Recently I found myself in a situation where a client had a custom ERP integration that needed re-formatted data. Additionally, the format was quite a bit outside the format of the Magento data. For a situation like this, I turn to using XTENTO Order Export as it comes with an XSLT option.

This will only be covering the XSLT portion of this. XTENTO has excellent documentation on how to utilize their product.

XSLT in it’s simplest form is a language to convert XML into other formats such as HTML or XML formatted differently.

If you have some XML structured like the following:

<?xml version="1.0" encoding="UTF-8"?>
		<buster>
			<first_name>Jamie</first_name>
			<last_name>Hyneman</last_name>
			<pet_name>Zero</pet_name>
		</buster>
		<buster>
			<first_name>Karie</first_name>
			<last_name>Byron</last_name>
			<pet_name>Gertie</pet_name>
		</buster>

Maybe you just want to get the pet names from this document. The following XSLT code would accomplish that goal.

 <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns_xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <ul>
            <xsl:for-each select="buster">
                <li>
                    <xsl:value-of select="pet_name" />
                </li>   
            </xsl:for-each>
        </ul>   
    </xsl:template>
    </xsl:stylesheet>

The output from the XSLT above is below, considering the size of the data sample we could have done this manually and it would not have been an overwhelming amount of work.

         Zero
        Gertie

Now that we have a working knowledge of what XSLT is used for, as well as an idea of what kind of results we can achieve, let us move onto something a bit more useful. We will be converting a Magento order XML from Cute Cats Inc. into an XML format that their ERP is expecting.

This is business critical as people need their cute cat pictures to go out, so the faster the better from the client perspective.

For the purposes of the following examples, we will be working with an order, of the following products:

 Product Name        Product Sku      Product Qty         Product Price
Cat, Awesome        150-sku-01          1                   $699.00
Cat, Cool           150-sku-02          1                   $555.00

The following is an example of the XML structure we will be working with. Magento stores its orders in a predictable fashion via XML. This example is not exact but it is close enough for the purposes of our examples.

     <!-- simplification of how magento stores order information in an xml -->
    <!-- Cute Cats Incorporated - We specialize in cuteness -->
    <orders>
        <order>
            <increment_id>100000034</increment_id>
            <order_item>
                <name>Cat, Awesome</name>
                <sku>150-sku-01</sku>
                <qty>1</qty>
                <price>699.000</qty>
            </order_item>
            <order_item>
                <name>Cat, Awesome</name>
                <sku>150-sku-01</sku>
                <qty>1</qty>
                <price>699.000</qty>
            </order_item>
        </order>
    </orders>

The format that we are trying to reach is like this example:

     <!-- example ERP format for orders -->
    <!-- Business as Usual LLC - ERP Division -->
    100000034,1 
    <!-- Order Id, number of order (if you had multiple orders this would increment) -->
    Cat Awesome,150-sku-01,1.0000,699.0000, <!-- Item Name, Sku, QTY, Price -->
    Cat Cool,150-sku-02,1.0000,555.0000, <!-- <!-- Item Name, Sku, QTY, Price -->

To accomplish this we will create an XSL template which will be used for all the orders from Magento. An XSLT template is defined in order to give the XML predefined locations to be output within the document.

The basic structure of an XSL Template is like this:

     <?xml version="1.0"?>
    <!-- the files tag is to hold every file we work with, its one in most cases with XTENTO -->
    <files>
        <!-- the file tag is for each individual file -->
        <!-- you can control the name of the file output here as seen in the filename attribute -->
    <file filename="%lastorderincrementid%.so">
    <!-- the xsl:stylesheet is where the actual xsl begins it is important to include the xmlns to php for XTENTO -->
    <xsl:stylesheet version="1.0" xmlns_xsl="http://www.w3.org/1999/XSL/Transform" xmlns_php="http://php.net/xsl">
        <!-- the output method text tells the xsl what kind of output it will be  -->
        <xsl:output method="text"/>
        <!-- constants are declared if you plan to use them for more than one thing I generally create one for separators -->
        <xsl:variable name="sepstart" select="'"'"/>
        <xsl:variable name="sepend" select="','"/>
        <!-- I also create one for an empty value if my csv will have one -->
        <xsl:variable name="emptyval" select="'~'" />
        <!-- xsl template match this tells it what character to match on for the template -->
        <xsl:template match="/">
            <!-- Template will go here -->
            <!-- This is where we will be doing most of the work in this blog -->        
        </xsl:template>
    </xsl:stylesheet>
    </file>
    </files>

We can define constant variables, these can hold field separators as I have done, or any value you want to remain constant, you can then refer to these throughout the XSLT template.

     <xsl:variable name="sepstart" select="'"'"/>
    <xsl:variable name="sepend" select="','"/>
    <xsl:variable name="emptyval" select="'~'" />

Using Simple Fields

I plan to examine three cases with this system that are useful, a simple example, an example using PHP native functionality, and a more complex solution that uses custom built static methods to compare data to an admin field. This multi-layered complexity allows you to change the data as needed to fit practically any requirements.

For the purpose of our simple example we are going to look at a case where we need a simple CSV output with: the sku of every item ordered, the quantity ordered, and the price.

Using XTENTO we will have some basic structure already in place allowing us to loop over order items, and gain access to the data contained within.

         <!-- Loop Example -->
    <xsl:for-each select="orders/order">
        <!-- loop over orders here -->
    </xsl:for-each>

Simple Fields – Example 1

First let’s look at how we work with pulling basic field data off of an xml node.

     <xsl:value-of select="sku"/>

This would return the following:

     150-sku-01,

This is not a lot of code, and it is fairly readable in that form as well. You will get the value of whatever node is selected (in this case, “SKU”).

So to put together some data using the looping we have looked at and how to pull data from nodes would look like:

     <xsl:for-each select="orders/order">
        <!-- order id -->
        <xsl:value-of select="increment_id"/>
        <xsl:value-of select="$sepend" />
        <xsl:text>
</xsl:text> <!-- this inserts a line break -->
        
        <xsl:for-each select="items/item">
            <!-- loop over order items -->

            <!-- sku -->
            <xsl:value-of select="sku"/>
            <xsl:value-of select="$sepend" />

            <!-- qty ordered -->
            <xsl:value-of select="qty_ordered"/>
            <xsl:value-of select="$sepend" />

            <!-- price -->
            <xsl:value-of select="price"/>
            <xsl:value-of select="$sepend" />
            <xsl:text>
</xsl:text>
    
        </xsl:for-each>
    </xsl:for-each>

Which would output the following:

     100000034, <!-- order id -->
    150-sku-01,1.0000,699.0000, <!-- sku, qty ordered, price -->
    150-sku-02,1.0000,555.0000, <!-- sku, qty ordered, price -->

With only a short template in XSLT, the order has already been changed from a long XML document into a short little piece of CSV data, with exactly the details desired.

PHP Functions – Example 2

Now for a more complex example, where we can call to some PHP native functionality. It is possible to use any PHP function directly from the XSL Template. In this case, I want to include the title or name of my products, but they include commas so that is an issue as it would break the CSV structure. There are a couple of ways to solve this, one will address the entire document as a whole and then this more focused approach.

First, let’s look at calling a PHP Function by itself:

 <xsl:value-of select="php:functionString('preg_replace','/[,]/', '',name)"/>

This allows us to call the PHP function “preg_replace”, pass in a regex to strip out commas, and then replace those. We pass in the field id that we are wanting to pass in as a parameter to it, much as we would when using the function within our regular use of PHP.

So if we were to plug that into the XSL template we already have from above it would look like:

 ...
<xsl:for-each select="items/item">
        <!-- loop over order items -->

        <!-- name -->
        <xsl:value-of select="php:functionString('preg_replace','/[,]/', '',name)"/>
        <xsl:value-of select="$sepend" />

        <!-- sku -->
        ...

This will output the following:

     100000034,
    Cat Awesome,150-sku-01,1.0000,699.0000,
    Cat Cool,150-sku-02,1.0000,555.0000,

As you can see we now have the names of those two very important products, “Cat Awesome” and “Cat Cool” which is the backbone of Cute Cats Inc.

Advanced Functionality – Example 3

Let’s say for the purposes of our example that our client Cute Cats Inc. wants to offer free shipping to wholesale customers, who have a specific wholesale_id, which they can set in the admin (once built in another module). These people are after all selling their most important products so let’s take special care of them. In order to accomplish this, we will need to create a static method to perform the task.

To do this first we have to create an XSL.php helper in a module following Magento best practices, like so:

     /**
    *
    * app/code/local/CLS/OrderExport/Helper/Xsl.php
    */
    class CLS_OrderExport_Helper_Xsl extends Xtento_OrderExport_Helper_Xsl
    {
        const XML_FREE_SHIPPING_WHOLESALE_ID = 'path/to/admin/config/field';
        
        /**
        * Return if free shipping is available based on the wholesale id in the admin
        * @param $orderId
        *
        * @return int
        */
        
        static function getIsFreeShippingAvailable($orderId)
        {
            $freeShippingWholesaleId =        
                 Mage::getStoreConfig(self::XML_FREE_SHIPPING_WHOLESALE_ID);
            /** @var  $order Mage_Sales_Model_Order*/
                $order = Mage::getModel('sales/order')->load($orderId);
                $customer =   
                 Mage::getModel('customer/customer')->load($order->getCustomerId());

                if ($customer->getWholesaleId() == $freeShippingWholesaleId) {
                return 1;
            }

                return 0;
        }   
        
    }

Then we need to call that function and pass in the entity_id from the order to the method so it can accomplish the logic work.

 ...
    <!-- free shipping 1 for yes, 0 for no -->
    <xsl:value-of select="php:functionString('CLS_OrderExport_Helper_Xsl::getIsFreeShippingAvailable',entity_id)"/>
    <xsl:value-of select="$sepend" />
    
    <xsl:text>
</xsl:text>
    
    <xsl:for-each select="items/item">
...

With that done we are now able to use the custom functionality giving us an output of:

     100000034,1
    Cat Awesome,150-sku-01,1.0000,699.0000,
    Cat Cool,150-sku-02,1.0000,555.0000,

This lines up exactly with what the ERP integration is expecting from our client. Not only have we accomplished the task, we did not have to manually edit any XML, or write more than one short method in PHP.

Summary

As you can see using the XTENTO module gives you a lot of speed to hit the ground running with, you can use it out of the box with a few lines of XSLT to format the text in any format required, and with a little extra engineering you can perform complex logic to make the output mimic what you need it to say. Below we have the entire XSLT template we have written all compiled into one entry.


 <?xml version="1.0"?>
    <!-- the files tag is to hold every file we work with, its one in most cases with XTENTO -->
    <files>
        <!-- the file tag is for each individual file -->
        <!-- you can control the name of the file output here as seen in the filename attribute -->
    <file filename="%lastorderincrementid%.so">
    <!-- the xsl:stylesheet is where the actual xsl begins it is important to include the xmlns to php for XTENTO -->
    <xsl:stylesheet version="1.0" xmlns_xsl="http://www.w3.org/1999/XSL/Transform" xmlns_php="http://php.net/xsl">
        <!-- the output method text tells the xsl what kind of output it will be I have never used anything other than text -->
        <xsl:output method="text"/>
        <!-- constants are declared if you plan to use them for more than one thing I generally create one for seperators -->
        <xsl:variable name="sepstart" select="'"'"/>
        <xsl:variable name="sepend" select="','"/>
        <!-- I also create one for an empty value if my csv will have one -->
        <xsl:variable name="emptyval" select="'~'" />
        <!-- xsl template match this tells it what character to match on for the template -->
        <xsl:template match="/">
            <!-- Template will go here -->
            <xsl:for-each select="orders/order">
        
                <!-- order id -->
                <xsl:value-of select="increment_id"/>
                <xsl:value-of select="$sepend" />
                
                <!-- free shipping 1 for yes, 0 for no -->
                <xsl:value-of select="php:functionString('CLS_OrderExport_Helper_Xsl::getIsFreeShippingAvailable',entity_id)"/>
                <xsl:value-of select="$sepend" />
                <xsl:text>
</xsl:text> <!-- this inserts a line break -->
        
                <xsl:for-each select="items/item">
                    <!-- loop over order items -->
                    
                    <!-- name -->
                    <xsl:value-of select="php:functionString('preg_replace','/[,]/', '',name)"/>
                    <xsl:value-of select="$sepend" />

                    <!-- sku -->
                    <xsl:value-of select="sku"/>
                    <xsl:value-of select="$sepend" />

                    <!-- qty ordered -->
                    <xsl:value-of select="qty_ordered"/>
                    <xsl:value-of select="$sepend" />

                    <!-- price -->
                    <xsl:value-of select="price"/>
                    <xsl:value-of select="$sepend" />
                    <xsl:text>
</xsl:text>
                </xsl:for-each>
    
            </xsl:for-each>
        </xsl:template>
    </xsl:stylesheet>
    </file>
    </files>

The XTENTO module links up seamlessly with the Magento interface, giving you a good place to drop in your XSL Template. It also brings with it some other functionality you can leverage to make use of Magento’s data.

Some of those other features that are of use within the XTENTO Export XSL are:

     <!-- static output -->
    <xsl:text>Whatever you want to output goes here.</xsl:text>
    
    <!-- mapping if/then/else -->
    <xsl:choose>
        <xsl:when test="shipping_method='abc'"><xsl:text>output this text</xsl:text></xsl:when>
        <xsl:when test="shipping_method='xyz'"><xsl:text>output something else</xsl:text></xsl:when>
        <xsl:otherwise><xsl:text>nothing matches, output this</xsl:text></xsl:otherwise>
    </xsl:choose>
    
    <!-- replace all characters in fields -->
    <file filename="file_name.csv" search=",;" replace="--"> 
    <!-- this is actually across all fields so much wider than the preg_replace example above which is only a single field-->

You can find purchase information at Xtento Order Export Module & their Documentation is also available.

Icon Fonts in Magento 2: A Foundation

Icons have a storied history on the web. In the bad old days, they were treated like any other images on a web page, implemented using individual image elements. This carried several negative implications, among them poor semantics and excessive HTTP requests as every icon image on a page were loaded separately. A much-improved method emerged with image replacement using CSS, pseudo-elements, and sprites. A CSS-based approach left HTML semantics undisturbed, and sprite images cut down on unnecessary asset requests with single large images combined with background positioning, instead of an image per icon.

Of course, even the CSS sprite technique still has the chief downfall that it’s image-based. This means that image editing software is required to create or edit sprites, whether or not you are creating your own icons or pulling them in from elsewhere. It also means that at the end of the day your icons are a flat set of pixels, subject to resolution limitations. (Note the Magento 1 responsive theme’s use of two distinct sizes of sprite image, in order to accommodate high pixel density displays like Retina devices.) An approach fast gaining wide adoption today, which cuts images out of the story entirely, is that of icon fonts. Magento 2’s native theme fully embraces this technique.

Using fonts for icons makes sense for a lot of reasons. In reality, iconography has always had more in common with text than content images; icons are glyphs that communicate meaning to the audience. And in technical terms, font glyphs are vector information that can scale up to any resolution. Of course, if you’re a web developer used to working with image-based icons, it’s likely that you have no small degree of discomfort with generating your own font files. Luckily, the growing adoption of icon fonts means there are great tools available for you. The native Magento theme provides the framework you need for implementation, and in this article, I’ll introduce you to a foundation that will leave you even better equipped for customizing Magento’s icons easily.

A Brief Overview of Magento’s Icon CSS

You’ll find the icon font files for the Magento Blank theme in lib/web/fonts/Blank-Theme-Icons (in the typical multiple file formats to support all user agents). lib/web/css/source/lib/variables/_typography.less defines the font icon path and name, and in the Magento Blank theme web/css/source/_icons.less uses these to define the icon font face itself, to be used in all CSS declarations.

The final relevant piece to be aware of is lib/web/css/source/lib/variables/_icons.less, where LESS variables are defined to store the Unicode characters that correspond to the right font glyphs for each icon. This will be a handy reference for you when needing to re-assign said character codes to new icons.

The defined icon font face and the character variables are used throughout the theme LESS code to define icons, usually through a call to the lib-icon-font mix-in.

Armed with this info about the CSS structure for customizing icon fonts, you’ve got a great starting point; change the variables defining the icon font path and name, and you’ve successfully replaced the native icons with your own. But that still leaves the question of how to generate your own icon font in the first place.

Font Libraries and Tools

You’ve got two main options for defining custom icons for your Magento theme: Create your own, or cherry pick some from available libraries. There are online tools that support either approach and allow you to wrap up your custom creation in a final font. A great example, and the one covered here is IcoMoon.

This font generation tool has a number of free and paid icon sets from which you can pick and choose. It also supports other features important for your Magento icon customization: importing of existing fonts, importing of your own custom icon SVGs, and importing/exporting your selections as JSON-based configuration, so that you can pick up straight from an already configured icon set. IcoMoon also features a fairly robust editing interface for adjusting the scaling and positioning of individual icons.

Using IcoMoon, you can start with an imported font like Magento’s native icons, make your desired tweaks by removing some and adding others, and then re-export a finished font. Of the five file types that Magento makes available natively, IcoMoon’s are missing only woff2. That’s not a problem, though, since there are plenty of tools out there for font file type conversion as well. Try Everything Fonts. IcoMoon’s final package handily includes JSON configuration and example CSS as well, though you’ll be eschewing said CSS in favor of Magento’s native structure.

Caveats and an Enhanced Starter Package

I said earlier that, once you’ve got your custom icon font in hand, replacing Magento’s native icons would be as simple as setting the right LESS variables for the font path and name. It would be great if that were the case. Unfortunately, if you’re using Magento Blank as your theme starting point and plan to customize it with available libraries, you’re likely to run into a snag: the size of the icons in the Blank font relative to their bounding box is significantly smaller than the typical fonts you’ll find on IcoMoon. Combining drop-in replacements with the font sizes and line heights in the Blank theme will result in unusually large icons compared with the spaces where they’re used.

There are two ways to approach this problem. The first is to scale down any icons you are using in your custom set using IcoMoon’s aforementioned editing interface. With this approach, you avoid any CSS changes, but you’ll have to touch every icon you wish to include in your custom font.

The second approach is to customize CSS font sizes and line heights to match the more typical icon sizes. This has the benefit of not needing to worry about sizing icons every time you drop a new one in, but it carries some up front overhead. It would be nice if a few typical icon sizes were defined in LESS variables for just such a customization. Unfortunately, the definition of these sizes is considerably more scattershot throughout the various module LESS source files in Magento. It’s a lucky break, then, that the Magento Luma example theme contains a more typically sized icon font, along with corresponding font sizes.

If you want to extend the leaner, more vanilla Magento Blank with your theme instead of extending Luma, the latter at least provides an appropriate boilerplate from which to extract the right styles to normalize icon sizes. And that’s exactly what I’ve done in this starter theme package. This theme extends Blank but uses the Luma icon font, containing appropriate CSS resets for sizing. You will note that these resets are contained within the theme’s _extend.less, meaning that it supersedes rather than replaces the baseline styles. While this leads to slightly more bloated compiled CSS, it’s a trade-off to avoid entirely duplicating a myriad of core theme files, since the vast majority of styles in said files won’t change from Blank. (The resulting _extend.less also provides a precise reference for which relevant styles should be tweaked if further re-sizing is needed.)

Note that this package is a work in progress, and you may find areas I’ve missed where further size tweaking is needed.

Pulling it All Together

Because of the sizing issue with the Blank theme, you should first decide which of the following approaches you want to take with your custom icons:

  • Approach A: Size your icons to match the CSS sizing in the Blank theme
  • Approach B: Directly extend the Luma theme
  • Approach C: Implement CSS to match the more typical icon size

Which approach is best? That probably depends on how many icons you intend to customize with drop-in replacements. If you’re replacing only a few, Approach A may work best for you. If you’re really giving your theme a distinct flavor with a wholesale new icon set, though, Approach B or C may be the way to go.

If you’re using Approach C, obtain this starter icon theme. You can install and extend this theme, or copy its styles directly into your own theme.

  1. In (IcoMoon, import the SVG font file for your starting icon font (e.g., Luma-Icons). Navigate to the IcoMoon App and use Import Icons. Conveniently, your imported font will be collected into its own set.
  2. For the icons you want to replace, remove the existing glyphs from the set.
  3. Choose your replacement icons. Use the Icon Library to add other free or paid icon sets if desired. Then select your replacements and choose Copy Selection to Set from the settings menu of your custom set.
  4. If you’ve created your own custom icons, use Import to Set from the settings menu of your custom set.
  5. Switch to the Generate Font tab at the bottom of the IcoMoon interface and make sure to set the correct Unicode character values for all new icons. Use the variable reference in lib/web/css/source/lib/variables/_icons.less. (If you’re uncertain which character codes match which icons, you can take note of them in your initial imported font before removing the originals.)
  6. If you’re using Approach A (i.e., sizing icons to match the CSS of the Blank theme), switch to Edit mode in IcoMoon, choose each new icon, and use the “Scale” feature to size the icon down to match the default Blank icons.
  7. Name your font. Use “Edit Info” from the settings menu of your icon set.
  8. Download the font package by switching to the Generate Font tab at the bottom of the interface, then choose “Download” from the same tab.
  9. Get the woff2 file format to round out the five formats Magento makes available for its default fonts. Head to a resource like Everything Fonts and use the conversion tools.
  10. Copy all font file types from the font directory of your downloaded package into your theme at web/fonts.
  11. In web/css/source/_theme.less in your theme, set @icons__font-path and @icons__font-name appropriately with the file path and name of your new icon font.
  12. If you discover you need any further tweaks to icon CSS sizing, use web/css/source/_extend.less to implement these tweaks.

Why We Still Do Tradeshows

When you think of “traditional” marketing, you probably think of television commercials, newspaper ads, billboards, etc. Trade shows are generally lumped in that category as well. And traditional marketing is dead, right? Content is king! Digital marketing reigns supreme! For the most part, I would agree with that sentiment. Content and digital marketing are trackable, measurable and less expensive. And we are living in a digital world.

With all of that being said – we still do trade shows. We do ‘em, and we love ‘em. Yes, they are a very large expense and you cannot get the level of data you can with digital marketing.

But – we love them because in this hyper-digital world it gives us the opportunity to connect with people face to face. We love people. We love spreading joy and building relationships. I go more in-depth about this here, but the gist is – People. Connections. Real Conversations. Through those connections, we grow and strengthen our brand presence in the digital commerce ecosystem.

We also love them because, for us, they generate more leads than any other source. Tradeshows put us in front of a captive audience that is already within the scope of a specified industry. While you can directly target potential customers with digital marketing, an ad only says WHAT we do, not who we are. And if you do try to say who you are in an ad, it is very difficult not to come off as pretentious or cliche. A lot of companies do what we do, but only we do things the Classy way. As our name suggests, we are a unique company and we can convey that much more easily in person.

In addition, trade shows give us the opportunity to network with our peers. If you take the opportunity to talk to people who are doing what you’re doing, you can learn so much as well as build valuable partnerships.

As the world continues to move more and more online, we like to have our foot in both the digital and physical world. We’ll help get your business online, but we want to do it as face-to-face as we can. As we make our plans for 2017, we are actively adding more and more conferences and trade shows. So keep watching our website and social media for where you can find us, and score some sweet swag (for you and your kids).

Google Analytics and Magento 2

Google Analytics is an important tool for merchants in the eCommerce and Magento communities because it allows merchants to make informed decisions about their website based on their users’ interactions. With the advent of Magento 2, it’s important to understand how the new version utilizes and integrates with Google Analytics. If you’re familiar with Magento 1, you’ll remember that Google Analytics was fairly easy to setup so you could quickly view reporting data. What about Magento 2? Don’t worry, integration with Google Analytics offers additional features with the same setup ease.

What’s the Same?

  • Universal Analytics – Magento 2 still features the same quick-and-easy Google Analytics setup. It’s just a matter of enabling the Google Analytics setting and adding your account number. Thankfully, the deprecated option of ‘Google Analytics’ (as opposed to ‘Universal Analytics’) is no longer around to add confusion during setup.

alt text

  • Adwords – this hasn’t changed in Magento 2; it’s still just as easy as adding your Conversion ID and Label.
  • E-commerce Tracking – One very powerful feature that seems to fly under the radar is eCommerce tracking. This feature is a must-have for any eCommerce site and lets you track transaction and product data on your site. If you already use Google Analytics with Magento, you get this feature with almost no setup. The only thing required to start using eCommerce tracking is to enable this feature in your Google Analytics account. Magento does the rest.

alt text

  • Google Tag Manager – Magento 2 Enterprise Edition includes the option to use Google Analytics via the flexible option of Google Tag Manager.

What’s New?

Magento 2 supports a Google Analytics feature called Content Experiments. This feature allows you to setup A/B tests on your Magento site to track how different versions of pages perform. Although its simplicity makes it a good solution for small-scale A/B tests, I don’t think it’s a good solution for complicated A/B testing.

To set up content experiments, (and after toggling the feature on in Magento admin configuration settings), there are only two steps:

1. A new experiment needs to be setup in your Google Analytics account. This is pretty straightforward. (Make sure to select the option to manually insert code and save this for the next step). You can follow the instructions from Google here.

alt text

2. Connect the new experiment with Magento. Create at least two new CMS pages, (this can be done with any number of different variants), your ‘original’ version and a ‘variant’. Place the javascript snippet from the experiment setup in the previous step under the new tab, ‘Page Experiments’. Just like other Google Analytics features, Magento handles rendering the snippet in the correct place on the front end.

alt text

That’s it! The way this simple example experiment has been set up, half of the visitors will be sent to the original page and half to the variant. You can track how your experiments are trending in the reporting section of your Google Analytics account under Behavior > Experiments.

To learn more about how Classy Llama approaches A/B testing check out this post.

What else?

A lot of our clients are interested in eCommerce tracking. And while the eCommerce tracking provided by Google Analytics provides a lot of good data, it can sometimes be hard to visualize or grasp what you’re looking at. This is where goals and funnels come in.

  • Setup your goal(s). This can be done many different ways depending on what you are wanting to track and how your user interacts with the site. Google provides documentation on setting this up different ways. A basic example of a goal is a user completing an order (reaching the success page).

alt text

  • One thing to keep in mind: By default, Google tracks views on secure urls separately from unsecured urls. So if you use a destination goal which includes both secure and unsecured pages, you will need to setup cross domain tracking.
  • The funnel visualization view (Under Conversions > Goals) can provide great insight into how users are moving through your website and reveal pages that have unusual rates of drop-off.

alt text

Another common thing to track is cross-selling/upsells. A merchant may want to know how often an advertised cross-sell product is clicked. To accomplish this, an event (or trigger if using Google Tag Manager) needs to be setup to let Google know when a cross-sell product is clicked. You can do this in Google Tag Manager, or by adding some javascript: javascript ga('send', 'event', 'cross-sell', 'click', '{product-id}'); Then in the Google Analytics dashboard, setup an event goal:

alt text

Both of these goal examples can easily be modified to include different steps in the flow or more complicated events. You can view reporting details about any of the goals you’ve set up under Conversions > Goals > Overview.

These are fairly simple examples, that just skim the top of what this feature can provide.

Summary

By expanding the features in the integration of Google Analytics, Magento 2 empowers merchants to make informed decisions about their site. And the setup ease of content experiments, eCommerce tracking, and the other Google Analytics features allow merchants to focus their efforts on improving the performance of their website.

Contact Us