I had a good shower idea. You know, those ideas that flit into your head but don’t often linger around too long. Well, I had this one idea and decided to run with it, but I gave myself just the weekend to make it happen.

I also have a newborn baby, so my weekends now don’t really look like they used to, but I gave it a go.

I built the bare bones of a possible product. I built it quickly and simply. I used open-source tools and a few free integrations.

I think my weekend MVP is a great example of how to approach creating a product. How to test your assumptions and protect against over-development too early.

It’s also a fantastic example of how WordPress can be used as a foundation for product development.

I’ll run through my process, from (shower) ideation through to launch.

Oh, the site is called https://wpleads.co if you want to see it before reading on!

The idea

Every month I organise the Brighton WordPress meetup group. There is one question that I often get asked by freelancers and contractors there:

Do you know anyone looking for someone to work on their project?

Brighton WordUp Meetup
Photo of our monthly meetup

Freelancers want work. They want new clients and they want good clients. I’ve been fairly booked up this year and regularly forward on any leads I receive in my inbox to others in the community.

We have a need, a market and a solution.

We also have a clear value proposition – these leads can make you money.

My idea was simple. It wasn’t totally unique; there are others out there selling leads. However, the WordPress niche did not have a site providing leads.

Ok, that’s enough to get started. Let’s not over-think this. Let’s get started and test.

I was at a fantastic talk by Jayde Adams where she talked about what an MVP is.

It stands for Minimum Viable Product by the way. She said we often misunderstand and misuse the word MVP.

We build fully fledged products and call them an MVP. ‍🙄

She said a better word to use is experiment. So this MVP is an experiment.

We’re going to create an experiment to test our proposition: that the WordPress community might be interested in purchasing Project Leads.

 

Designing the Experiment

Experiments should focus on the minimal possible variables. If we throw too many elements into the mix we will cloud the results or let our assumptions distort what has happened.

I had established the market and now wanted to test whether anyone would purchase access to the leads. I didn’t want to test much more that. Was it possible to sell with just the promise of leads, without social proof, without smart on-boarding, without making the leads scarce or exclusive.

And if I didn’t sell any memberships to get these leads I wanted to collect feedback which could inform the next stage in experiments.

With this in mind I decided upon the following components:

  • A landing page
  • A clear and concise call to action
  • A demo
  • Payment and User registration
  • Access to User Dashboard

Designing the process and choosing the tools

The key tools used are:

I think that you can make all sorts of MVP experiments with just this toolset. The best part is once you have built it, you have foundations to grow or try out another experiment to refine your product.

The main infrastructure to manage the landing page, user registration and user-based access is perfect for WordPress and ProdPress.

WordPress as a robust CMS and ProdPress to provide a scalable backend for developing functionality. Even though this MVP was designed as a lean experiment, it’s good to start with scalability in mind.

For the payment processing, I decided upon Stripe because it has a fantastic checkout module. This is easy to integrate with. As with a lot of things made by Stripe, it’s made with developers in mind.

I could take payment and then call my own function to register the user.

For displaying the actual leads I decided upon using Airtable. It had a free package which lets me add data, filter it and embed it into the site. I could create one view for public display and one view for paid display.

 

Full Disclosure: ProdPress is the creation of my fellow developer Hazlitt and myself (Elliot).

The User Flow

The key was to make the journey from CTA to leads as frictionless as possible. I also wanted to take payment up front and then pass the user through the registration process.

I decided upon the following:

  • Call to action button
  • Payment using Stripe Checkout
  • Register the provided email as a new user
  • Log user in
  • Display a form to set a password
  • Redirect user to the embedded Airtable to view core offering

Building the site

The foundation of the site is WordPress and ProdPress. For the front-end I want to use Bootstrap as the UI is clean and I can build quickly with it.

For that reason I use the Understrap WordPress theme, which takes the best practices from the Underscores theme project and merges it with the Bootstrap framework. It also comes with NPM and Gulp bundled which helps us write quickly and performant code.

We only need one plugin – the ProdPress core plugin. Yay!

Theme Code

We take a copy of the Understrap Child Theme and modify that.

I want to have a blog page, so I have created a file called home.php and call the archive:

<!--?php get_template_part( 'archive' ); ?-->

I’ve also amended the footer.php file with some custom text.

Other than styling that is pretty much all we need to do with the theme because we are using ProdPress for everything else.

This might seem trivial, but separating out our core code and styling is an enormous help in scaling later.

ProdPress Code

I have pulled in a starter ProdPress app from GitHub and added the Bootstrap Modal Login module. Both this module and the modules functionality are recent additions to ProdPress that I added to help speed up development.

Firs,t we want to redirect our home page to use ProdPress. To do so, I head to my config.php file in my ProdPress app. This is where we manage custom routing.

I simply add:

$custom_routes = array(
'' => 'home/home'
);

 

This redirects the root of the site to the method called home() in the controller file called home.

So our next step is to create a controller in our controller folder called home.php

I’ll show you the method I’ve written for it and then run you through what it does:

 

function home() {

// load model
$this->load_model('redirects_model');

// redirect to dashboard if logged in
$this->redirects_model->home_redirect();

// load views
get_header();

// output modals
$this->load_module_controller('bs_modal_login', 'bs_modal_login');
$this->bs_modal_login->display_login_modal();
$this->bs_modal_login->display_reset_pass_modal();

// views
$this->load_view('wrappers/wrapper_start');
$this->load_view('home/logged_out');
$this->load_view('wrappers/wrapper_end');

// get footer
get_footer();
}

 

This controller does 3 things.

  1. We check if a user is logged in and if so redirect them to use a a different method.
  2. Then we load the header and the various modals required for the BootStrap Modal Module
  3. We output our logged out content and a Footer

I’ll take a look at our home_redirect method to demonstrate how separation of code works.

Here is the full file of redirects_model.php:

<?php  

class redirects_model extends pp_app_model {

        function __construct() {

            parent::__construct();

        }


        function home_redirect() {

            if (is_user_logged_in()) {
                wp_redirect('dashboard');
            }

        }

}

?>

We can see above that this simple function just checks if a user is logged in using a standard WordPress function and then redirects to /dashboard.

ProdPress is managing our routing and first checks if a controller called dashboard.php exists. As it does it will then load the default class in that file.

This looks like:

function default() {

// load view
get_header();
$this->load_view('wrappers/wrapper_start');
$this->load_view('home/logged_in');
$this->load_view('wrappers/wrapper_end');
get_footer();

}

This is even simpler. We just load the headers, a wrapper (which is just a div with a container class), our content and a footer.

logged_in.php exists in views/home/logged_in.php and simply shows some text and the embed.

<div class="home--intro mt-3 mb-5">
<h1>Let's get you some work!</h1>
</div>
<iframe class="airtable-embed" style="background: transparent; border: 1px solid #ccc;" src="https://airtable.com/embed/XXXX?backgroundColor=red&viewControls=on" width="100%" height="533" frameborder="0"></iframe>

I hope that quick run through demonstrates how to create a simple and effective dashboard for logged in and logged out states.

There are more controllers to manage the account creation and password setting process, but not much else.

How did it do?

Even thought I have skirted over the specifics of how this MVP was built, it’s a long post. I’ll follow this up with another post outlining:

  • What I learnt from the MVP
  • What I would do differently
  • Some of the business logic behind the scenes
  • Is wpleads.co worth pursuing