Skip to content


Jeremy Ward edited this page Apr 1, 2019 · 2 revisions

What is OOPS-WP?

OOPS-WP is a lightly-opinionated collection of abstract classes, traits, and interfaces designed to promote object-oriented design thinking in WordPress development. Its primary goal is to give engineers the tools they need to quickly and consistently scaffold common WordPress data structures, such as custom post types, taxonomies, settings pages, REST API routes, Gutenberg blocks, widgets, shortcodes, and more, by using a composition and SOLID-based approach to plugin and theme architecture.

What is SOLID, and how does OOPS-WP follow it?

SOLID comprises the first 5 principles of object-oriented design:

  1. Single responsibility principle
  2. Open-closed principle
  3. Liskov substitution principle
  4. Interface segregation principle
  5. Dependency Inversion principle

You can read a really great article about SOLID at OOPS-WP promotes object-oriented programming and SOLID principles by defining a structure for how common structural elements should be initialized in WordPress plugins and themes. Specifically, OOPS-WP:

  • Promotes single-responsibility by making objects focus on a particular task: registering a post type, setting up the objects needed for a feature, registering an API route, etc.
  • Provides a set of objects which can be easily extended but not modified.
  • Allows changing of objects so long as they abide by the same contracts, meaning we can replace code more easily down the line.
  • Separates interfaces by defining contracts for particular structures (less so in 0.1.0, but moreso in future releases)
  • Leads to dependency inversion by promoting composition over inheritance.

OOPS-WP Structures and Utilities

Structures introduced in 0.1.0

Structures are abstract classes that can be extended during plugin and theme development, the result of which will become some kind of "thing" in WordPress - a post type, a shortcode, a widget, etc.


A Service in OOPS-WP represents a functional component in WordPress.

For instance, as a developer who is building a custom plugin for a client, you might be tasked with extending WordPress to provide some additional post types and taxonomies. You could create a ContentRegistrationService object that contains references to each individual post type and taxonomy, each of which would be represented by their own class file. The job of the service is to create each of those objects and to fire its hooks at runtime.


A ServiceRegistrar is an object that registers a collection of Services.

Continuing with the ContentRegistrationService example above, let's say that your client's plugin also required some custom REST API routes, some WP-CLI commands, and a few custom settings pages.

Instead of putting all of the logic for those different pieces of functionality into a single class or functions file, you could split the responsibility of each feature set into its own Service class: an ApiService, a CliService, and a SettingsService. The role of the ServiceRegistrar is to contain references to those individual services, creating their objects and triggering their WordPress hooks at runtime.


The PostType class is an object that can be extended to quickly register a new custom post type. It provides a small set of arguments needed to hook the post type with WordPress, and requires that you define a slug and an array of labels that WordPress will need to load it.


The EditorBlock class can be used when registering a new Gutenberg block with WordPress. It defines a set of abstract methods that your child class will define in order to give your blocks a type and paths to its assets.

Utilities introduced in 0.1.0

Utilities are interfaces and traits that your own classes can implement and use, ensuring that your objects define the methods that are needed at runtime. Generally, these interfaces are small, and importantly, they promote the L in SOLID - letting you switch out one kind of object for another in the future, so long as that new object still abides by the same interface.


The Hookable interface requires a single method, register_hooks, which should be implemented by objects that need to hook into WordPress. The register_hooks method helps keep all of those hooks in one place within a class file.


The Registerable interface can be used by classes that require some kind of "registration" with WordPress. Generally, these are objects that subsequently call some type of WordPress registration function, such as register_post_type, register_taxonomy, add_shortcode, etc.


The Runnable interface requires a single method, run, which can be implemented by objects that need to trigger some kind of process after instantiation. This might be something like a plugin or Service object, which first gets initialized, then subsequently needs to be run.

The run method helps support unit testing by classes that implement it, because boot-up logic that requires interaction with the WordPress APIs can be stored in here, allowing us to create new objects without tons of additional setup when writing tests.


The FilePathDependent trait can be used by objects that require some kind of reference to a file path. One such example is the EditorBlock class, which leverage this trait to indicate where the class is relative to its JavaScript and CSS assets.


The AssetsLocator interface can be implemented by objects that require some kind of URL reference to a file path. It differs from the FilePathDependent trait because the location of assets required by an object may not be within the file server and thus, is required by an object to define its method body.

Clone this wiki locally
You can’t perform that action at this time.