outlandish / oowp
A plugin for WordPress that makes post types easier to manage
Requires
- php: >=8.0
- composer/installers: ^1.0 || ^2.0
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- v4.x-dev
- 4.0.1
- 4.0.0
- v3.x-dev
- 3.0.7
- 3.0.6
- 3.0.5
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- v2.x-dev
- 2.2.12
- 2.2.11
- 2.2.8
- 2.2.7
- 2.2.6
- 2.2.5
- 2.2.4
- 2.2.3
- 2.2.2
- 2.2.0
- 2.1.3
- 2.1.2
- 2.1.1
- 2.1.0
- 2.0.7
- 2.0.6
- 2.0.5
- 2.0.4
- 2.0.3
- 2.0.2
- 2.0.1
- 2.0.0
- 0.9.2
- 0.9.1
- v0.9
- dev-2022-08-16-prospect-misc-posttype
- dev-19-exc-attachments
- dev-fix-global-post
- dev-get_posts_fields_fix
- dev-delete-post-hook
- dev-master
- dev-fix_create_function
- dev-alt-global-post
This package is auto-updated.
Last update: 2026-09-27 07:59:59 UTC
README
- Contributors: harryrobbins, tamlyn, rasmuswinter, mattKendon, sdgluck, joaquimds
- Tags: connections, custom post types, relationships, templating
- Version: 4.0
- Requires at least: 6.2
- Tested up to: 6.2
- License: GPL-3.0-or-later
- License URI: https://www.gnu.org/licenses/gpl-3.0.html
Overview
OOWP is a tool for WordPress theme developers that makes templating in WordPress more sensible. It replaces
The Loop and contextless functions such as the_title() with object-oriented
methods such as $event->title(), $event->parent() and $event->connected('people').
OOWP is designed to be used with themes with custom post types such as
Events, People, Places, Articles, Recipes, etc. It doesn't currently work with the default post types
(Post, Page) but this will be addressed in the forthcoming v1.0 release.
It is designed to work with the excellent Posts 2 Posts plugin by Scribu and the just-as-excellent Advanced Custom Fields plugin by Elliot Condon and requires these plugins in order to take full advantage of its awesomeness. Some of the code samples below assume you have these plugins installed.
Instead of having to deal with The Loop and/all the weird WordPress magic of changing what the_post() refers to behind the scenes you can write nice object-oriented code like this:
foreach ( Place::fetchAll() as $place ) { echo "<h2>Articles about {$place->title()}</h2>"; foreach ( $place->connected(Article::postType()) as $article ) { echo '<h3>' . $article->htmlLink() . '</h3>'; echo $article->excerpt(); } }
Nice isn't it? If it's not nice and makes no sense whatsoever to you then you should either learn about object-oriented PHP (definitely a good idea) or look elsewhere (we won't be offended).
Theme structure
At Outlandish we use Bedrock to structure our projects and we recommend you do the same. It produces a folder structure like this:
.
├── composer.json # → Manage versions of WordPress, plugins & dependencies
├── config # → WordPress configuration files
├── vendor # → Composer packages (never edit)
└── web # → Web root (vhost document root)
├── app # → wp-content equivalent
├── mu-plugins # → Must use plugins
├── plugins # → Plugins
├── themes # → Themes - see below
└── uploads # → Uploads
└── wp # → WordPress core (never edit)
See the Bedrock documentation for more detail.
We structure our theme folders like this:
.
└── web # Web root (vhost document root)
├── app # wp-content equivalent
├── themes # Themes
├── sample-theme # An oowp-structured theme
├── assets # For static assets
├── fonts # webfont files
├── img # images used in the theme
├── js # the Javascript for the project which is minified and moved to ../public using a filewatcher
├── scss # SCSS which is transpiled into CSS and moved to the ../public folder using a filewatcher
├── public # Where assets from ../assets get built to by compiler scripts
├── src # The main theme files
├── PostTypes # For 'model' classes that represent custom post types. We often have five or more custom post types
├── BasePost.php # An abstract base post that contains functionality common to all the post types in this project (we often have more complex class hierarchies for, for example, hierarchical and non-hierarchical post-types)
├── Blog.php # A class representing the 'blog' custom post type
├── Author.php # A class representing the 'author' custom post type
├── ...
├── Router # → For 'controllers' that route URLs to responses via the relevant models and views
├── Router.php # → The file which contains the mapping of routes (URL patterns) to controller functions that will generate and return a response
├── Views # → For 'view' classes that subclass the OowpView or RoutemasterOowpView class
├── Components # → For smaller templates that make up larger views
├── Layout.php # → An outer 'layout' file that usually contains the header and footer and which is wrapped around the other views
├── DefaultPostView.php # → A view that will be used to render single posts where no other template is defined
├── Layout.php # → A view that will be used to render index/listing pages such as the homepage, blog index or category archive
Install
Whack it in WordPress's mu-plugins directory and hack away at it until it works. Or wait until we create some better instructions.
Basic usage
Once you have installed the plugin all WP_Query will return WordpressPost objects so that you can use the
$post->title() syntax.
There are a range of simplified method names such as $post->title(), $post->excerpt(), and $post->content() as
well as some useful helpers such as $post->htmlLink().
Using custom post types
OOWP makes it easy to register custom post types. The base WordpressPost class defines
some sensible defaults for the arguments to register_post_type (which can easily be overridden
in subclasses), so you simply need to pass the custom post type class names to the PostTypeManager's
registerPostTypes function:
PostTypeManager::get()->registerPostTypes([ ClassA::class, ClassB::class, ... ]);
Once registered, each class's onRegistrationComplete function is called, so that additional post-registration
functionality can be performed at the right time (see below). The wordpress actions oowp/post_type_registered and
oowp/all_post_types_registered can also be utilised.
Using OOWP custom post types makes it easier to structure your code by putting all your custom code - such as getting the time and place of an event - into the relevant custom post class.
Connecting Custom post types
This functionality requires the Posts 2 Posts plugin
OOWP uses the Post2Post plugin to make it easy to connect and retrieve related posts. This functionality is designed to be used in place of the Tag and Category taxonomies that ship with WordPress. This has the advantage of reducing the number of different object types and methods that developers have to deal with, and allows the attaching of additional metadata such as author, geolocation, etc. to 'categories', which is not well supported by WordPress.
To register a connection between two post types use the static registerConnection on a class, passing in another
post type and any connection options (see p2p_register_connection_type from Post2Post):
ClassA::registerConnection(ClassB::postType(), ['cardinality' => 'many-to-many']);
Once you have registered this connection you can then easily fetch connected posts in your page templates using the
WordpressPost->connected() method (see example above).
WordPress.org
Unfortunately, for new projects WordPress is not accepting libraries as plugins which they host. So direct usage with (non-WPackagist) Packagist is the only sensible way to manage this dependency.