Back to Blog

WordPress Playground: Elevating Your WooCommerce Extension Demo Experience! 🌐✨

Google Tag Manager for WooCommerce PRO demo site

WordPress Playground as a WooCommerce Demo Page Engine

As a company specializing in creating extensions for e-commerce software, enabling comprehensive event tracking in tools like Google Analytics 4, Facebook Pixel, Google Ads, TikTok Pixel, and Pinterest, we're excited to introduce WordPress Playground as an engine of our demo site. This browser-side generated WordPress demo using WebAssembly (WASM) serves as a dynamic platform for showcasing our premium WooCommerce extension.

WordPress Playground was authored by Adam Zieliński. You can find more about the author and the WordPress Playground solution on his blog.

Setup Process and Challenges Encountered

The configuration began with a standard approach, placing an iframe on our website that linked to the core WordPress Playground hosted on the wordpress.net domain.

Challenge #1 - third-party cookies issue

Initially, we utilized the simplest, basic code snippet as presented in the documentation, placing it on our domain at https://demo-woocommerce.tagconcierge.com.

<iframe id="wp-playground" style="width: 1200px; height: 800px"></iframe>
<script type="module">
    import { startPlaygroundWeb } from 'https://unpkg.com/@wp-playground/client/index.js';

    const client = await startPlaygroundWeb({
        iframe: document.getElementById('wp-playground'),
        remoteUrl: `https://playground.wordpress.net/remote.html`,
        blueprint: {
            landingPage: '/wp-admin/',
            preferredVersions: {
                php: '8.0',
                wp: 'latest',
            },
            steps: [
                {
                    step: 'login',
                    username: 'admin',
                    password: 'password',
                },
                {
                    step: 'installPlugin',
                    pluginZipFile: {
                        resource: 'wordpress.org/plugins',
                        slug: 'friends',
                    },
                },
            ],
        },
    });

    const response = await client.run({
        // wp-load.php is only required if you want to interact with WordPress.
        code: '<?php require_once "/wordpress/wp-load.php"; $posts = get_posts(); echo "Post Title: " . $posts[0]->post_title;',
    });
    console.log(response.text);
</script>

The first challenge emerged due to the strict privacy settings in our developer's browser. The demo loaded from the wordpress.net domain couldn't initiate the service worker in the browser because of a different domain address (our tagconcierge.com domain). As the primary goal of our product demo page is to convince as many clients as possible of the value of our product, we had to find a solution that would work in every browser, regardless of privacy settings.

We decided to host WordPress Playground on our own domain, utilizing the open-source code available on GitHub. It was straightforward, thanks to the available releases with the built source of WordPress Playground. There was no need to delve into the code and tools used in the project. Simply uploading the files downloaded from GitHub made the page functional.

The next requirement was to install the WooCommerce plugin along with sample products and, of course, our plugin. We began by installing WooCommerce, which went smoothly using the Blueprint API. A simple modification to the example snippet sufficed, replacing the installation of the Friends plugin with the installation of the WooCommerce plugin.

{
  step: 'installPlugin',
  pluginZipFile: {
    resource: 'wordpress.org/plugins',
    slug: 'woocommerce',
  }
}

The next step was to install sample products, crucial for showcasing the functionality of our e-commerce plugin. Unfortunately, this became our...

Challenge #2 - sample products import

We aimed to achieve this using the Blueprint API (https://wordpress.github.io/wordpress-playground/blueprints-api/json-api-and-function-api#ImportFileStep), as outlined below.

{
  "step": "importFile",
  "file": {
    "resource": "url",
    "url": "https://assets.tagconcierge.com/sample-products.xml"
  }
}

Unfortunately, the products were not appearing in the database. Moreover, even attempting to import the file manually through the wp-admin panel within WordPress Playground did not yield success. That was the moment when we decided to independently compile WordPress Playground in our forked repository, installing WooCommerce and importing products at the Dockerfile level. The file responsible for building and configuring WordPress inside WordPress Playground can be found here.

# === Install WooCommerce ===
RUN cd wordpress/wp-content/mu-plugins && \
    # Install plugins
    for plugin_name in woocommerce;
      curl -L https://downloads.wordpress.org/plugin/{$plugin_name}.latest-stable.zip -o {$plugin_name}.zip && \
      unzip {$plugin_name}.zip && \
      rm {$plugin_name}.zip && \
      # Create entry file in mu-plugins root
      echo "<?php require_once __DIR__.'/$plugin_name/$plugin_name.php';" > $plugin_name.php; \
    done;

# === WooCommerce === #
RUN cd wordpress && ../wp-cli.phar --allow-root import wp-content/mu-plugins/woocommerce/sample-data/sample_products.xml --authors=create
RUN cd wordpress && ../wp-cli.phar --allow-root wc payment_gateway update bacs --enabled=1 --user=tagconcierge
RUN cd wordpress && ../wp-cli.phar --allow-root wc payment_gateway update cheque --enabled=1 --user=tagconcierge
RUN cd wordpress && ../wp-cli.phar --allow-root wc payment_gateway update cod --enabled=1 --user=tagconcierge

The above snippet added to the Dockerfile is responsible for installing WooCommerce, importing test products, and activating sample payment methods. After building WordPress Playground and updating the files on our test instance, we encountered another challenge.

Challenge #3 - syntax errors in WooCommerce files

After uploading the build along with our WooCommerce installation and product import snippet, we were confident that WooCommerce had been installed because the page returned a PHP syntax error in one of the WooCommerce files upon startup. As it turned out, the fragment in the Dockerfile that removed white spaces from the PHP code (to reduce the size of the Playground environment) was the cause of this behavior in the plugin.

We had to add an exception in this code snippet to ensure that the WooCommerce source remained unchanged during the build.

Our demo was taking shape as we intended: we had WooCommerce installed, test products, and activated test payment methods. Most of the essential functionalities for presenting the plugin were working correctly, except for one, essentially the most crucial functionality - the checkout process.

Challenge #4 - purchase process

It turned out that completing the entire purchase path, designed to demonstrate to our potential customers how to track the "purchase" event, was impossible.

 

The error message was quite concise, and debugging in the WordPress Playground environment was challenging due to the lack of direct access to the PHP code/environment. After several hours of debugging, it turned out that WordPress Playground does not support the HPOS (High-Performance Order Storage) used in the new version of WooCommerce by default. HPOS requires the creation of dedicated tables to store orders for optimizing the store's performance.

The solution to this problem was to disable HPOS using wp-cli during the WordPress image building stage by adding the following snippet to the Dockerfile.

RUN cd wordpress && ../wp-cli.phar --allow-root option add woocommerce_custom_orders_table_enabled no

At this point, we had a demo with fully functional WooCommerce and sample products installed.

Challenge #5 - our plugin installation

We reached the point where we had a fully functional WordPress within Playground. The next step was to install our plugin, as the ultimate goal of the entire project was to showcase its functionality to potential customers.

A dilemma arose - initially, we assumed installing our plugin through Blueprint API. However, this method had a significant drawback: all files downloaded by the browser (which is how Blueprint API operates) are publicly accessible. This meant that a more technically savvy user could potentially obtain our product directly from the source, defeating the purpose of showcasing the product in this manner. We concluded that the safest solution from a business perspective would be to install the plugin at the Dockerfile level. However, this approach has a notable drawback: every release of our plugin requires rebuilding and deploying our custom Playground environment. Fortunately, the Playground authors included deployment scripts based on GitHub Actions in the code, significantly simplifying the configuration of automatic rebuilding and deployment of the environment.

Installing our plugin required a similar exclusion of the plugin path from the script removing white spaces, as it was causing PHP syntax errors, similar to the ones encountered during WooCommerce installation.

Unfortunately, the Playground was unable to provide a correct list of active plugins, which led to the need for mocking (overwriting one of our plugin files during Dockerfile build) the function retrieving this information. This was necessary because our plugin has additional extensions, such as the Google Tag Manager for WooCommerce PRO: Wishlists add-on and Google Tag Manager for WooCommerce PRO: Multilingual add-on. These extensions are activated based on whether the plugins they extend (Polylang, WPML, WooCommerce Multilingual and Multicurrency, WooCommerce Wishlists, or WPC Smart Wishlist) are active.

As our plugin also offers server-side ecommerce event tracking integration, communicating directly with the backend server where WooCommerce is installed through Facebook API, TikTok API, or Google Analytics Measurement Protocol, this aspect of our demo still requires some work. The outgoing requests made by the "wp_remote_request" function are not functioning as expected. While this is not a critical functionality that we can tangibly showcase to potential clients (as it occurs server-side), it does not hinder the operation of the Playground in its current form.

Challenge #6 - third party plugins installation

As mentioned earlier, our plugin and its extensions support integration with other plugins, such as Polylang for managing multilingual sites. The installation of Polylang posed a challenge since it requires interaction with the Setup Wizard immediately after installation for full functionality. This issue was circumvented by using Blueprint API, executing requests to wp-admin during Playground loading. These requests simulate the normal process of going through the Polylang Setup Wizard.

Utilizing the following steps in Blueprint API allowed us to navigate through the Setup Wizard without manual interaction:

{
  "step":"request",
  "request":{
    "method":"POST",
    "url":"/wp-admin/admin.php?page=mlang_wizard",
    "formData":{
      "languages[]":"en_US",
      "save_step":"continue"
    }
  }
},
{
  "step":"request",
  "request":{
    "method":"POST",
    "url":"/wp-admin/admin.php?page=mlang_wizard&step=media",
    "formData":{
      "save_step":"continue"
    }
  }
},
{
  "step":"request",
  "request":{
    "method":"POST",
    "url":"/wp-admin/admin.php?page=mlang_wizard&step=untranslated-contents",
    "formData":{
      "language":"en_US",
      "save_step":"continue"
    }
  }
},
{
  "step":"request",
  "request":{
    "method":"GET",
    "url":"/wp-admin/admin.php?page=mlang_wizard&step=last"
  }
},

Correction - it almost helped. Unfortunately (or fortunately, prioritizing plugin security!), the authors of Polylang implemented nonce verification to avoid potential security vulnerabilities. For the purposes of our demo and test installation, we had to remove sections responsible for this verification, as otherwise, we wouldn't be able to install Polylang without manual interaction. We did it in Dockerfile this way:

# === Polylang === #
RUN sed -i 's/check_admin_referer/#check_admin_referer/g' wordpress/wp-content/mu-plugins/polylang/modules/wizard/wizard.php

Since our Google Tag Manager for WooCommerce PRO plugin is continuously evolving and improving, we anticipate many more integrations with third-party plugins in the future. Consequently, we expect additional challenges when it comes to their installation and configuration within the WordPress Playground environment. This dynamic landscape ensures that our demo platform will remain an active and valuable tool for showcasing the expanding capabilities of our plugin.

Conclusions

In summary, WordPress Playground emerges as a remarkable tool for creating demonstration sites, effectively minimizing the time and effort required to maintain a demo environment. This innovative solution significantly streamlines the process of updating plugins, reducing the risk of potential vulnerabilities. While there are challenges, particularly with higher entry barriers for non-standard configurations, it's important to acknowledge that this project is still in its early stages. As we eagerly anticipate the forthcoming development phases of WordPress Playground, we remain optimistic that the tool will evolve to address existing limitations. We've encountered our fair share of challenges, some quite challenging, but the simplicity and maintenance-free aspect of Playground (no server or database worries) totally won us over. We're genuinely excited about contributing to this groundbreaking technology. Pioneering is tough, no doubt, but having the chance to work alongside people like Adam from Automattic? That's incredibly rewarding.

 

Back to Blog