A 10X eCommerce Search Experience

Recently, one of our favorite clients reached out to us because they were facing some significant issues with their online eCommerce search experience.  Searches were irrelevant and non-performant, faceting worked sometimes, but slowly, and simple things like exporting or paginating results failed miserably. 

The previous technology stack that was implemented included 3-4 disparate systems (WordPress / WooCommerce, FacetWP, DataTables), none of which effectively communicated to each other. The result was an experience that felt like a Frankenstein-mismatched-mashup of components and the overall UX (user experience) was sub-par, to say the least. Our technical challenges were not insignificant:

  1. Research and determine the best technical platform to act as a single source of truth for the entire search experience.
  2. Document existing functionality and prioritize feature parity.
  3. Implement and test new system against feature parity matrix, measuring for key heuristics like speed, search relevance, and the experience feeling fully internally integrated. 

The Best Technical Platform

Arguably the most important decision – this was also the easiest decision. Because of the fact that our client wisely chose to host their eCommerce site at Liquid Web with their new Managed WooCommerce product, we already had tight integration with Algolia for their site search results. Carrying that over to the faceted search experience was a natural evolution of this feature. Not everyone who uses Algolia is aware of this, but they provide more than just insanely fast search (via their Autocomplete and InstantSearch libraries, which Liquid Web leverages). In fact, their faceted search experience is just as fast as their normal autocomplete search – and it’s so much more powerful. Because they provide all of this power, and it was already available to us – using Algolia was a no-brainer.

What Exactly is Faceting?

Great question! You’ve likely already used a faceted search experience if you’ve ever shopped at Amazon. When you search for something, and it shows you different prices, review, categories, or other areas to “drill down” by? That’s faceting. Here’s a simple example:

Choosing the Right Framework

Having decided upon Algolia as our platform of choice – we had another important choice to make. We were completely replacing the entire user experience here, so there was a strong case to be made in replacing the existing patchwork with something built upon a more maintainable framework. Already set on leveraging the InstantSearch.js library from Algolia, using a JavaScript framework for the new interface made a lot of sense to us. Having worked with most modern JavaScript UI libraries – we settled on using Vue.JS. We found it to be more opinionated than Backbone.JS, more progressive than Ember and Angular, and easier to work with than React. We were delighted to find that Algolia already had great support for Vue.JS via their GitHub repos.

Well-Tested or Robust?

Our final platform-level challenge came after reviewing the aforementioned Vue.JS + Algolia starter interface. We realized quickly that the level of integration between Algolia and Vue.JS in their v1 public release was insufficient. Upon some quick investigation of open branches and pull requests against the repo, we realized that they were deep into active development on v2 of their integration – and v2 was much more powerful. Making a difficult decision between using something more battle-tested, but not nearly robust enough – or something that was still in active development, but potentially a much better long-term foundation – we made the tough call of investing in the future, potential bugs and all – we went with v2.

Finally, after making our way through the foundational project decisions, we were ready to get into the weeds and tackle building out a new interface. The first step for us here was not writing code, but writing lots and lots of words to document existing functionality.

Feature Parity

When you’re completely rebuilding something from scratch, it’s easy to sometimes miss the forest for the trees. As developers, we can become so enamored with the new and shiny that we forget that our only goal is to solve our client’s problems. If we’re not doing that, we’re failing. While much of the existing interface was broken in a lot of interesting ways – there was a lot that it was doing effectively. 

In order to make sure that we not only fixed what was broken, but didn’t break what worked well – we need to document every feature of a system that was completely undocumented, and which we had very little initial involvement in building. Due to our collaborative approach to technical partnership with our clients, we were able to work together with our client to identify everything the existing system was doing, prioritize the features, and ensure that we were able to execute everything that existed previously in the new system.

Our only goal is to solve our client’s problems. If we’re not doing that, we’re failing.

While it may sound like a simple experiment to document existing features – this exercise exposed areas of potential complexity that were hidden in plain sight. One great example of this was sorting the table of product results. Each category of products had a default sorting algorithm applied to the results that were unique to that category. In the previous system, driven by a MySQL database, sorting was a fairly straight-forward (although, in this instance, a very broken) process.

A Different Paradigm

With Algolia – while it’s tempting to carry over database-driven paradigms – it’s not a database. It’s a search index. While there is some overlap carried into this paradigm – sorting is not one of those. Where we could sort by a given column in a table in the previous interface, in the new interface, we had to create a new replica index for every column we wanted to sort by. This meant creating over 30 replica indexes and using Algolia’s API to determine which index to use when sorting. 

In the end, we ended up with a task list of nearly one hundred features to maintain parity with. This included (but was definitely not limited to):

  • Default sort order for results, per category
  • Custom facets and facet order per category
  • Custom columns in the tabular results, per category
  • Integrated CSV export (we used the great json2csv package for this)
  • A built-from-scratch mobile/responsive experience, imitating the existing experience driven by WooCommerce Product Tables and dataTables.js. We used Vue-MQ for this.

Risk Assessment 

Finally, the fact that we used alpha software was ultimately a net win, but that doesn’t mean it wasn’t without challenges. The v1 package was well-documented – while the v2 package was mature in many ways, documentation was not one of them. In recent days (and even hours), they’ve made great progress on documentation – but we were flying blind for a good amount of the work we completed.

This introduced a number of roadblocks along the way – but we can’t possibly say enough wonderful things about the developer support from the folks at Algolia. They were massively helpful – with every documentation question, issue logged, support request, etc – they went above and beyond to help and even improve their alpha releases based on our feedback.

Implementation

Now that we had a clear technical specification to build from; we had to take the decisions we made, the knowledge we had, and the risks we were assuming — and put them all into practice. A project of this magnitude is bound to produce no small amount of hills to climb. Rather than outline every step of the implementation, I’ll share a couple of the challenges we faced and how we overcame them.

Numeric Indexing

I mentioned this briefly earlier: Algolia has a very different architectural paradigm than a MySQL database. It’s a search index, which means it works differently than a standard RDBS. One of the things Algolia is very good at, which the existing implementation was not executing well at all, is sorting by just about anything in the dataset.

“Anything” – in our case, often meant large datasets, sorted by a number. Unfortunately, the way that the existing WooCommerce Algolia plugin works, it’s not possible to have a taxonomy that is comprised entirely of numeric terms to be indexed numerically. In laymen’s terms, that means that where you might expect results to be sorted naturally like 1, 5, 12, 18, 25, 32, 85, 100 – they would instead be sorted like so:1, 12, 18, 100, 25, 32, 5, 85 Not exactly helpful.

In order to fix this, we were able to use an existing filter within the WooCommerce / Algolia plugin to ensure that numeric strings were sent to Algolia as numbers, rather than strings:

function algolia_numeric_index( array $attributes, WP_Post $post ) {
    $product = wc_get_product( $post );

    if ( ! $product ) {
        return $attributes;
    }

	foreach ( $attributes['taxonomies'] as $taxonomy => $terms ) {
		foreach ( $terms as $index => $term ) {
			if ( is_numeric( $term ) ) {
				$attributes['taxonomies'][ $taxonomy ][ $index ] = (float) $attributes['taxonomies'][ $taxonomy ][ $index ];
			}
		}
	}

    return $attributes;
}

add_filter( 'algolia_post_product_shared_attributes'           , 'algolia_numeric_index', 10, 2 );
add_filter( 'algolia_searchable_post_product_shared_attributes', 'algolia_numeric_index', 10, 2 );

This simple fix allowed us to fix a number of broken indexes, ensuring the sorting experience for users and for our client worked really smoothly. 

Integrating with WooCommerce…and everything else

While this new experience was being built as its own self-contained Vue.JS app – we still needed it to integrate to other parts of the site. The site navigation, driven by WordPress, needed to dictate to the Algolia facets which category should be shown. The app needed to be able to add items to the cart via WooCommerce. Thankfully, these problems were fairly easy to solve.

For integrating the menu items, and specifically clicking them, into the Vue app – we assigned the app to a global variable and emitted events against that scope when the menu items were clicked:

window.zaoAlgoliaApp = new Vue({
  el: '#zao-algolia-app',
  render: h => h(App)
});

var menuItems = document.querySelectorAll( '#top-category-menu .items' );

for (var i = 0; i < menuItems.length; i++) {
	menuItems[i].addEventListener('click', function(event) {
		event.preventDefault();
		window.zaoAlgoliaApp.$emit( 'menuItemClicked', this.href );
	});
}

This simple approach made it relatively straight-forward to listen for these events within the app and route the requests and refine the facets accordingly. 

For the ability to add results to the WooCommerce cart, we created a small Add to Cart component that mimicked the standard WooCommerce Add to Cart button. Passing the Algolia item along as a property made this effort fairly inconsequential:

<template>
	<form autocomplete="off" v-if="this.item.in_stock" :action="formActionUrl" class="cart" method="post" enctype="multipart/form-data">
		<div class="quantity">
			<label class="screen-reader-text" :for="getPostId">Quantity</label>
			<input autocomplete="off" type="number" :id="getPostId" class="input-text qty text" step="1" min="0" max="" name="quantity" value="1" title="Qty" size="4" pattern="[0-9]*" inputmode="numeric" aria-labelledby="">
		</div>
		<button type="submit" @click="addToCart( $event )" class="button alt add_to_cart_button ajax_add_to_cart" style="outline: none;">Add</button>
	</form>
	<span v-else>Out of stock</span>
</template>

<script>
export default {
	props: [ 'item' ],
	name : 'WCAddToCart',
	methods : {
		deleteMessages() {
			jQuery( '.woocommerce-messages' ).fadeOut().remove();
		},
		addToCart( e ) {
			var $ = jQuery;
			var $thisbutton = $( e.target );
			var item = this;

			item.deleteMessages();

			e.preventDefault();

			$thisbutton.removeClass( 'added' );
			$thisbutton.addClass( 'loading' );

			var data = { sku : this.item.sku, product_id : this.item.post_id };

			// Trigger event.
			$( document.body ).trigger( 'adding_to_cart', [ $thisbutton, data ] );

			// Ajax action.
			$.post( wc_add_to_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'add_to_cart' ), data, function( response ) {

				if ( ! response ) {
					return;
				}

				document.querySelector( 'header.woocommerce-products-header' ).insertAdjacentHTML( 'afterend', response.fragments.messages.replace( 'Continue shopping', 'View Cart' ).replace( window.location.href, wc_add_to_cart_params.cart_url ));

				setTimeout( function() {
					item.deleteMessages();
				}, 5000 );

		});
	    }
	},
	computed: {
		formActionUrl() {
			return window.location.pathname + '?add-to-cart=' + this.item.post_id;
		},
		getPostId() {
			return 'quantity_' + this.item.post_id;
		}
	}
}
</script>

The Results

Remember – our metric of success is not about lines of code (~1,000), not about how much fun we had with development challenges (a lot) or how fancy and shiny the frameworks we used are (so fancy, so shiny) – it’s about solving the client’s problems.

To reiterate: 

  1. Slowness – Pages would reload anytime categories were changed, anytime breakpoints were triggered (via portrait to landscape changes, browser resizing, etc.), any time searches were performed, or facets were selected. This added 1-2 seconds of load time for almost every interface interaction.
  2. Accuracy – Pagination would always show links for pages for the entire dataset, and result counts for the entire dataset, not just for the filtered set. Sorting would only sort current page, not the entire set. Exports would not take into account filters or search queries. Filtering by one facet would inconsistently affect other facets. 
  3. Overall experience – UX for facets was clunky, everything was slower than expected, the entire experience did not feel well-integrated.

So – did we fix it?

  1. Slowness – the interactions in the previous experience would often take a minimum of 500ms, with an approximate upper boundary around 2500ms. With Algolia powering everything – from the export, to the searching, to the faceting, to the sorting and pagination – the average interaction is essentially imperceptible – between 1 and 80ms, averaging around 30-40ms. This represents a minimum improvement of around 10x – but comparing experiences, it feels like 100x. 
  2. Accuracy – one of the more powerful elements of Algolia is just how accurate it can be. Not all accuracy is created equally.  For example – when a user searches for model numbers, we have little to no typo tolerance, as they’re searching for a very specific number, and any fuzziness would be likely to return irrelevant results. However, if they’re searching for a color or material – typing Blak or Sliver or Lether should return the relevant results – typos and all! Thanks to Algolia’s powerful customizable ranking algorithms, this is exactly how the new interface works. On top of all of that – the primary issues they were facing with exporting, searching, sorting and filtering were all easily resolved.
  3. Overall UX – in any UX, it’s easy to get weighed down in numbers and metrics – but at the end of the day, how it feels is what matters most. The magic of a completely rebuilt app in a modern JavaScript framework, on top of a lightning-fast service like Algolia cannot be overstated. Taking a core user experience from being painful to powerful, from janky to joyful – this is why we do what we do 🤗

But Wait, There’s More!

In addition to these goals that were very much a matter of execution – we’re also very attuned to our client’s strategic goals. As a bootstrapped startup, two things are eminently important for this client: 1) Keeping expenses low 2) Getting as much actionable data as possible.

To this end, our client wanted a way to be able to gather some data around how people were searching, filtering, paginating, etc. For example – to be able to track when a person types a search into the search input. and they have to click a pagination link to find the result. That gives some helpful insights into how to make search results more relevant for users.

The only problem is that Algolia makes this type of insight available – but it’s at a pricing tier that costs more than ten times as much as they were already paying. Being aware of these conflicting constraints, we got creative.

We were already using Heap Analytics for tracking data on their site. Creating custom events for faceting, paginating, searching (and a small number of other actions) using Heap’s Event Visualizer established a quick, easy way to gather this actionable insight – at no additional cost to our client. Wins all around!

If you’re reading this, wondering to yourself, “Wow, I have some of the same problems with our website – can these folks help me?” – we’d be honored to hear how we can serve you. Fill out the form below and get in touch.

Qpractice case study, Zao client spotlight, Zao WordPress web development, Zao WordPress eCommerce development, Zao WordPress plugin development, custom WordPress plugin,

Zao Client Spotlight: An Interview with Qpractice’s Lisa League

Earlier this week, we shared the technical breakdown of the work we did for Qpractice, including a run down of the extensive custom plugin development and functionality we added to the site.

I had a chance to chat with Lisa League, designer and founder of Qpractice, to get a more in-depth look at what Qpractice does, why she chose Zao, and her experience working with us.

Tell us a little bit about your work.

The NCIDQ exam is used in the US and Canada for [interior designer] licensing and certification. I teach several courses that prepare designers to take the exam. Designers who want to move ahead in their career, junior level and senior level designers looking to advance and take on higher paying projects. It’s typically commercially focused, because the exam has to do with health, safety, and welfare, [with a focus on] building codes, accessibility codes, etc. [The test is] not [focused on] interior design or decoration, but regulations and codes–on interior architecture, like the non-structural part of the building, plumbing, electrical, mechanical systems, stuff like that.

The exam reviews both what designers learn in school, as well as what you learn on the job. The exam is not available to everyone; you must meet certain requirements in education and years of work experience to be eligible to take it.

What was the major reason you needed a developer?

I had pretty much done everything myself since I started. I was creating content to work with customers or members, as well as providing customer support and doing the website design and development. I learned how to do quite a lot, but couldn’t go beyond the out of the box capabilities.

Qpractice case study, Zao client spotlight, Zao WordPress web development, Zao WordPress eCommerce development, Zao WordPress plugin development, custom WordPress plugin,

I wanted to enhance what I could offer to my customers, so I wanted to work with developers. I worked with other developers a year ago, but to be able to continue on, Qpractice needed a team, [rather] than individuals that might get booked on a project [and be unavailable]. I needed the availability, as well as more than one person working on the site, and wanted continuity, support, and ongoing development.

How were you handling this before?

I was handling it all myself, with some backup from a support team that offers task based support. If it was something I couldn’t do, I would hand it off to them. They were taking one off small tasks, rather than major feature set development. When I needed somebody to take care of one thing or update plugins at night, it worked great, but more extensive features and ongoing development wasn’t within their scope.

How did you first hear about Zao?

I contacted several well-known, well-respected Genesis custom theme developers and they recommended Zao.

What led you to choose Zao over any other agency?

I talked to a lot of people, but what it boiled down to was Zao’s follow up and [willingness to] take the time. I hired Zao to scope the project, which provided the kind of feedback I didn’t get from other developers. When Zao [gave a] preliminary look into [the site], they did an excellent job digging in, seeing what I had, what I needed, why I needed it, and what we can do better. Not everybody does that.

What were the big successes of this project?

I’ve been able to offer different courses and products than I’ve offered before. Now, I can package them together and offer them at a higher price point. I also now offer an e-book for sale and delivery is totally automated, so I don’t have to spend any additional time while it adds to my revenue.

[Zao also] improved the product that I have, and make sure everything is kept up to date. We added some things that simplified [my work and the user experience], and offered tools that allow my customers to better track their progress, as well as tools for me to better manage my members and control member access.

How has Zao helped you achieve your goals for this year?

A website is like a living breathing organism, so it’s always going to need something. They’ve enabled me to take the whole big picture and break it up into parts, do what I need to do now (while making money from that), and then go forward [to the next piece]. It provides an opportunity to regroup [before diving into the next phase] and to profit on what we’ve already developed.

Qpractice case study, Zao client spotlight, Zao WordPress web development, Zao WordPress eCommerce development, Zao WordPress plugin development, custom WordPress plugin,

Do you have numbers regarding Zao’s impact on your success?

I doubled my revenue for the first two months of this year compared to last year.

If someone was on the fence about working with Zao, what would you tell them?

I would tell them to put the time and money into the discovery/scoping process, because that’s critical. You’d have a really good doctor [take a look] before you go under for a major surgery. You want [a developer] to look at what’s happening, break it all down, figure out what you need and why you need it, as well as any alternate ways to achieve what you want, and then make recommendations based on that.

I have put money into software and custom development in the past, only to find it was something I had to scrap. It’s better to spend the time and money upfront and really break it apart, and what you think that you want to do may not be what you end up doing–or it might be, but there might be things you didn’t think of. Zao offers that.

Do you have anything you’d like to add about your experience?

I just enjoy working with the team at Zao. You don’t want people to just do a job, but you want to hire people you enjoy working with.

Qpractice case study, Zao client spotlight, Zao WordPress web development, Zao WordPress eCommerce development, Zao WordPress plugin development, custom WordPress plugin,

Zao Client Spotlight: Our Collaboration with Qpractice

One of Zao’s goals includes taking on complex projects that require in-depth strategy. We don’t want to merely solve problems, but add value to the technology our clients are using. We take a boy scout approach to the work we do: Always leave the campground cleaner than we found it.

This means not only cleaning up what messes we may find when we arrive, but ensuring our clients have sustainable technology that benefits them in the future.

We recently had the pleasure of completing an initial phase with Qpractice, a website built to help interior designers prepare for the NCIDQ exam. So far it has been a complex, but extremely exciting collaboration with Lisa League, designer and founder of Qpractice. We’re here to share what we’ve done so far, and be sure to check out our interview with Lisa to hear her thoughts on working with Zao!

What Qpractice Does

The NCIDQ exam is an interior design licensing and certification test offered in the US and Canada. According to Lisa, it tends to be commercially oriented, with a focus on health, safety, and welfare. It tests designers on their understanding of necessary codes and regulations, making sure they can demonstrate their understanding of the non-structural part of the building (like plumbing, electrical, mechanical systems, etc.).

The exam tests knowledge interior designers should have accumulated both during their education and from their work experience. The NCIDQ exam can be a crucial element in an interior designer’s career trajectory; designers often seek out the exam to move up to a senior design position or land higher profile, higher paying projects.

Qpractice aims to help interior designers prepare for the NCIDQ exam by providing extensive opportunities for trial, error, and education. The Qpractice site provides practice tests that in many ways mirror the real NCIDQ exam, allowing designers to become familiar with the format and feel confident when facing the exam live.

Zao’s work on Qpractice

Like any ongoing project on a live, thriving site, as we worked through the initial phase, the scope was extended to cover new and emerging (and sometimes urgent) issues and inconveniences. Zao updated much of Qpractice’s existing system, as well as revamped the entire theme, added functionality, and created several plugins to better serve Qpractice’s needs. The NCIDQ exam also recently added a new quiz format, and Qpractice needed to have that created for test takers continued comfort and familiarity with the exam.

The discovery process

As we do with most of our clients, we did a significant code and performance audit before diving in. JT talked about how vital the discovery process is before, and it’s a staple in the way we approach projects. For Qpractice, we made recommendations for custom features that can be added, as well as data migrations from one plugin to another, and more.

During discovery, we don’t always recommend changes. Sometimes we recommend staying with the current solution if it’s best serving our client’s needs. We believe this is just as important as adding the new and shiny features.

Qpractice was set up using Sensei and WooCommerce Memberships, and we suggested that they continue to do so. From our initial discovery document:

  • Sensei – Given the high level of integration with custom functionality plugins and the purpose Sensei provides on your site, we’d recommend keeping it as your quiz management solution. Developing a custom quiz management solution would offer minimal long-term benefit and incur a high short-term cost.
  • WooCommerce Memberships – Based on our discussions with you, the most recent changes to WooCommerce that have resolved outstanding issues, and the cost of switching membership platforms, we recommend sticking with WooCommerce Memberships.

We aren’t kidding when we say Zao is working on behalf of our clients at every turn.

Once the discovery document was sent and we got the approval from Lisa, we went straight to work.

Order up: adjusting Genesis and making the menu

Lisa wanted to make some adjustments and add new elements to the Qpractice theme, but wanted to stay on Genesis.

One of the big pieces that took a lot of time and effort was the way the menu functions. We overhauled the entire menu system in terms of functionality and mobile responsiveness. It’s a specific implementation that works responsibly, as well as opens and closes according to different user actions. When logged in, Qpractice users have access to an additional menu with custom functionality as well.

The entire site is now device agnostic, which is particularly important for appealing to new users and making it possible for existing users to access information like the study guide, grades, and more, with ease.

Creating seamless integrations

On Qpractice, these three tools are integrated to offer the most to users, as well as make the business easy to run. Sensei powers the Qpractice learning and quiz systems, WooCommerce Memberships controls access to those systems, and WooCommerce powers the eCommerce component of the site.

Between these three tools, there were lots of bits and pieces that needed cleaning up. When one would update, it would often introduce a bug to one of the others, and it would impact the entire setup negatively. Zao’s first step in improving the Qpractice site was obvious: we triaged a bunch of bugs popping up in the integrations between Sensei, WooCommerce, and WooCommerce Memberships, as well as submitting several pull requests against their respective repos.

Side note: This is where retainers become necessary. Plugin teams have their technical goals in mind when they’re building their product, but they do not have your specific ecosystem in mind when they release. That’s why paying to have a technical partner to bridge the gap between the technology and your specific needs is so valuable.

Simple, but lovely features

WooCommerce Product Bundles price shortcodes

Qpractice uses WooCommerce’s Product Bundles, but there wasn’t a good way to output the price for the each product in the bundles and show the user what each item cost and just how much they were saving. The shortcode is super easy to use (of course), and makes solving this problem extremely simple.

WooCommerce Product Bundles, WooCommerce WordPress websites, WooCommerce development, WordPress web development

Custom message bar

Zao added a way for Qpractice to flash a message bar at the top of the site. We wanted it to integrate nicely with the Qpractice menu and show up in certain scenarios set by the admin. Although there are plugins that offer this kind of functionality, most of them only create a message bar that shows universally across the site, and we wanted to give Qpractice more control over this component of the site. The message can be shown across the site entirely, or the site admin can toggle it to show exclusively to logged out users, which is particularly useful as a promotional tool.

All the WordPress plugins

As mentioned, the Qpractice site is using Sensei, WooCommerce Memberships, and WooCommerce.

Additionally, we migrated Qpractice from another affiliate plugin to AffiliateWP, built by Pippin’s Plugins. They create great products and support AffiliateWP incredibly well; we felt confident that AffiliateWP would put Qpractice’s site (and affiliate program) in good hands.

Once again, we make sure our clients are gaining the most value from their technology, which means setting them up with what we believe to be the best products, and there’s no doubt that AffiliateWP falls into that category.

Custom WordPress plugin development

Qpractice had some specific needs and problems to resolve that existing plugins couldn’t address, so we did one of the things we do best: we built them.

We encourage all of our clients to open source the plugins we create for them, and Lisa was especially enthusiastic about creating products that are open sourced and available to the public. Not all of them are open sourced just yet, but many of them are.

Bulk Boot for Sensei

The way that Sensei is built means that users are signed up indefinitely unless they remove themselves, but this presented a problem for Qpractice, which operates on a seasonal schedule. At the end of every season, they needed to be able to remove access to the courses and encourage users to sign up for the next season, should they want to do so.

We discussed the fact that booting learners from a course is actually a pretty intense operation performance-wise and that it needed to be an asynchronous operation. As a result, we decided the best course of action was to add an optional turtle to help the user’s anxiety levels.

Bulk Boot for Sensei, Qpractice, Bulk Boot WordPress plugin, WordPress plugin development, custom WordPress plugin development

We wrote Bulk Boot for Sensei to give Qpractice the ability to bulk remove all learners from a specific course at the end of the season. Now, tidying up user access in Sensei is super easy.

Sensei Advanced Quizzes

The Qpractice site already had a plugin that extends Sensei, adding additional functionality, and we built upon that to add more useful tools in the admin area.

One of the most frustrating things about Sensei is that it dumps all questions/question-types in one big listing in the admin without faceted filters for drilling down to certain types of questions. Qpractice has a variety of question types that act a certain way, and Lisa had no way to search by the group. We created a tool that adds columns and filters to allow advanced sorting so she has a much easier time of filtering.

WordPress plugins, WordPress WooCommerce Sensei, using WooCommerce Sensei, WordPress eCommerce development, WordPress educational development,

WooCommerce Custom Product Redirects

Zao created a custom plugin called WooCommerce Custom Product Redirects. This plugin is not only a great sales and customer support tool, but it allows the Qpractice site to direct their users to information they may find crucial for using the products they’re purchasing.

With WooCommerce Custom Product Redirects, if a user has a product in their cart and makes a purchase, they will be redirected to relevant content set by the site admin. If the site admin has a relevant tutorial to the product being purchased, they may decide to custom redirect to that tutorial for the customer’s benefit. If there are two products that have URLs, the site admin can define priority, ensuring that their customers get any and all pertinent information automatically delivered to them post-purchase.

WooCommerce VitalSource Redemption Codes

Qpractice offers an e-book that is delivered by a third party, but purchased through the Qpractice site. Qpractice needed a way to keep an inventory of codes and her stock in WooCommerce without spending a lot of time keeping track of it manually.

With WooCommerce VitalSource Redemption Codes, every time a user purchases a product stored on a third party site, it associates one of the codes (in Qpractice’s case, a free code for the e-book) with that user so they can find the code on their receipt, and so inventory is neatly kept in WooCommerce.

This plugin was written specific to VitalSource, a Qpractice partner. We will likely adjust it and make it open source soon–stay tuned!

Zao Sensei Media Attachments

We created an alternative to a WooCommerce plugin that allows the site admin to associate media items with a lesson and ensures the media shows up in the resources list for associated courses. Zao Sensei Media Attachments now serves the same function, but uses CMB2 to create a better user interface. CMB2 simplifies the admin fields and provides more filters for modification.

WordPress plugins, Zao WordPress plugins, WordPress plugin development, Qpractice, working with Qpractice, e-commerce website development, eCommerce website development, hire a developer, looking for an eCommerce developer, WordPress eCommerce,

CMB2 Snippet Library: Associate WordPress Menu Field

We also contributed one of the features back to the CMB2 code snippet library. With this feature, Qpractice can select or create a curated WordPress custom menu to associate with a quiz or lesson and that menu will be displayed by placing the “Associated Post Menu” in the corresponding sidebar widget area.


Working with Qpractice has been an absolute delight. Lisa is a creative powerhouse, suggesting all kinds of ideas that we had the opportunity to create into a tangible, functional reality. We’re on the next phase of the project, and we’re all too excited to see what comes next. We’ll keep you posted!

Check back later this week for an interview with Lisa sharing her perspective of the project. 

WordPress developers, WordPress eCommerce developers, Zao, Justin Sainton, Justin Sternberg, Cancer Tutor, best WordPress developers, what it's like to work with a WordPress developer, why choose Zao, Zao web development reviews, WordPress web development

Zao Client Spotlight: An Interview with Reggie Black of Cancer Tutor

One of the things Zao prides itself on is taking on complex projects that require in-depth strategy and not only solve problems, but add value to the technology our clients are using. We take a boy scout approach to the work we do: Always leave the campground cleaner than you found it.

This means not only cleaning up what messes we may have found when we arrived, but leaving our clients with sustainable technology that benefits them in the future–both short and long-term.

We recently worked with Cancer Tutor, a website dedicated to providing valuable information on natural cancer treatment and prevention. Cancer Tutor is affiliated with and supported by prominent cancer researchers and the Independent Cancer Research Foundation, Inc., and aims to empower cancer patients to have unfettered access to information about alternative methodologies for their illness–and share their successes and failures.

You can read more about the work we did with them over at our portfolio (and check back–we may have another post here in the future delving into the technical dirty details of the work as well!).

Reggie Black, the head honcho over at Cancer Tutor, was generous enough to chat with us about why he chose Zao and how he felt about the project.

Zao WordPress web development, Zao WordPress plugin, WordPress developers, Justin Sainton, Justin Sternberg, Zao on WordPress, building WordPress tools, Cancer Tutor, Cancer Tutor website, websites on WordPress, find a WordPress developer, find a WordPress plugin developer, find a WordPress ecommerce developer, ecommerce solutions, ecommerce developers

If you’ve been wondering what it’s like to work with Zao or why our clients go with us, here’s some insight:

Why did Cancer Tutor seek out a developer?

We were building something new. Something that had not really been done before, there was no template or plugin to compare it to. So we needed someone who could dream as big as we can.

We get a lot of crazy ideas for things we would like to build. It takes a very special combination of developer and people-person to really understand what and how we want to do certain things.

Zao seemed to get “it” instantly. Even from the first wireframe we sent over, they understood our vision and direction. They were the first developers we had spoken to that took a genuine interest in understanding our project from day one.

Was there an emotional component to the problem you were looking to solve? What emotions did you or other stakeholders feel because of what was going on?

It was a little bit frustrating to hear some people tell us it can’t be done or shouldn’t be done through WordPress, and the fact that we had not seen others do it before to prove that it was possible made it difficult for us to express the vision that was inside of our head. It was very satisfying to be told that we could do it, and [that] Zao could tackle it. They happily accepted the challenge and took on every new problem that we threw their way.

What led you to choose Zao over any other agency?

Response time. Clear Communication. Hustle.

I sent them a wireframe and specs for the project late on a Friday night. I got a response on Saturday morning! Zao wanted to do video call to see each other face to face (which I love). I could visually see the wheels turning in their head and I could tell they were genuinely excited by the project.

During our first call it became evident very quickly that they had already done a very thorough analysis of our wireframes and asked us very hard questions about the project (which I also loved).

What was the solution to these hurdles?

Magic wizardry. I have no idea how Zao pulled off some of the stuff we asked them to do. It always got done, though.

What was the biggest takeaway or success of this project?

We launched on time! That was a huge success. There were so many moving parts between our internal team, designers, other developers, and Zao. There were many times during the project that we were flying by the seat of our pants. Zao always got their part done plus a little extra…without ever complaining. They displayed an incredible attitude throughout the entire project.

Zao WordPress web development, Zao WordPress plugin, WordPress developers, Justin Sainton, Justin Sternberg, Zao on WordPress, building WordPress tools, Cancer Tutor, Cancer Tutor website, websites on WordPress, find a WordPress developer, find a WordPress plugin developer, find a WordPress ecommerce developer, ecommerce solutions, ecommerce developers

How do you feel about your site now compared to when you were first searching for a developer?

The answer is now we feel like we have someone who can keep up with our craziness.

Me: Hey, I thought of this thing…let me tell you about it.

Zao: Yeah, we will have that done next week.

You guys get it instantly. One phone call and we’re on the same page. Even with the additional stuff we added, you were able to knock it out of the park

Are there any other comments or feedback you have for us about your project?

You guys have been, hands down, the most fun team we have ever worked with. “Making work fun again” should be your campaign. There were some incredibly funny moments in Slack and I really appreciated how you kept everything light-hearted.

Had we not gone with Zao, I know we could not have gotten this done on time. [You] were flexible with our crazy schedule and always got [the] work done.


Don’t be jelly! Getting your jam on with Zao is easy peasy; all you have to do is get in touch.