When we set out to commercialize WordPress plugins, we started by building out in plugin-form the different functionalities we’ve built over the years for various clients while working as a web development agency.
It was clear from the beginning that, even just half a year into the business, we will have multiple plugins with some serious overlap among them when it comes to performing certain repetitive tasks.
We explained in another article what a framework is and why we use one — basically because that was the solution to our problem. And the good news was also that we were already using a framework of sorts!
The beta test
The idea of a framework for WordPress plugins was not new. The first attempt was made by Tony back in 2017 when building 4 sites with overlapping custom functionality for the same client.
The 4 sites had the same custom functionality, but looked different and had different ranges of products. Even back then, the idea was to have an easy way to build code once, and have it deployed on all 4 websites worry-free. This was meant to minimize development time for us, development cost for the client, and thus increase overall satisfaction for both parties!
That first version of the framework was inspired by the WordPress Plugin Boilerplate project (originally built by Tom McFarlin and taken over in 2015 by Devin Vinson).
Some key differences were the fact that our framework was built to be used as an mu-plugin as opposed to a traditional plugin (to avoid the client accidentally deactivating it) and it featured 3 concepts:
- Plugin extensions — these were their own projects designed to be placed inside a special folder of the framework; their purpose was to modify and/or extend the functionality of an existing plugin. For example, for the WooCommerce plugin, we’ve built an extension that let us easily output text in different locations on the product page or easily remove certain elements, like the coupon form on the checkout page.
- Module extensions — these were their own projects designed to be placed inside a different special folder of the framework; they acted as regular WP plugins, providing specific functionalities independent of other plugins. For example, a module we’ve built was for gathering customer reviews in a WooCommerce shop.
- Local custom extensions — these were files added in their own yet again separate folder that were supposed to modify the functionality of the current website. While the rest of the framework was supposed to be unchanged across all sites it would be installed on, these files were specific for just one website. Think of it like a functions.php file, but within the mu-plugins folder (…and more than one file).
This framework took 5 months to build back in 2017 and was done by November of that year. In fairness, it also included the first module and plugin extensions to fit the client’s use-case.
The second-gen, first general-use version
In March of 2018, after the framework was successfully used in production for 5 months already, we found out that the framework can be used to speed up development of websites of other clients as well.
Many features built within the plugin extensions were reusable for our other clients as well. The trick was to have a user interface to turn those features on/off and have the ability to customize them slightly.
At the time, the framework was tightly integrated with the Advanced Custom Fields plugin for handling settings (that was a requirement of the client the framework was built for originally). So we went a step further and added framework-specific admin pages filled with on/off buttons and other setting fields (all powered by ACF).
By middle of April 2018, the framework became more general-purpose and got its first official release (v1.0.0, although technically, this was the second generation). We called it our “DWS Custom Extensions Core” and you can glance over it on Github, if you’re so inclined.
The first public release framework
We spent about a year-and-a-half working with this framework. During that time, it was used on about 10 client websites and we gathered a lot of experience with what worked and what didn’t.
For example, we decided that its tight-coupling with ACF was a problem. We love ACF, but it also has its shortcomings, especially as the number of posts in the database grows into the tens-of-thousands or even hundreds-of-thousands scale.
Another issue was the mu-plugin design. It had its pros, but we discovered there were more cons than expected. Also, as the projects grew in size, we needed to rely more-and-more on 3rd-party libraries like Guzzle and it wasn’t practical to keep bundling them with the framework (since there were still many websites that didn’t need all these 3rd-party libraries).
During Fall 2019, Fatine took the lead on decoupling the framework from ACF. It was the quickest way to keep the framework “fresh” but it was clear that we needed a better long-term solution. For the time being though, version 2 of the framework was made publicly available (technically, the third generation) and together with it, two adapter extensions for supporting ACF and CMB2 as settings libraries.
With this release, we also made the repository public on GitHub.
Starting anew (the current framework)
In April 2020, Tony started work on the 4th-generation of the DWS WordPress Framework. Originally, it was supposed to be simply version 3.0 of our existing Core, but as development went along, it became clear that it’s best to start from scratch and rethink everything with the end-goal of building the best framework he could.
Version 1 of the 4th-gen framework was completed by May 2021 and it’s being used in all of our plugins, both free and premium. It’s composed of 7 distinct Composer packages that build on top of each other and they are all licensed GPLv3+. All packages are readily available for use in your own projects, if you so wish.
This is the history and motivation behind our WordPress framework. It’s the result of 12 years of web development experience, 5 years of WordPress experience, and over a year of full-time work (from the first gen to the current build).