DM Blog

Extending the WP_Post Class

by #code

In a previous blog post, I had mentioned that I’m quasi-extending WordPress’ built-in WP_Post class:

You may have noticed that I’m using an Article class which doesn’t exist in WordPress. That’s because I’m extending the global $post object and using this everywhere in my custom plugin and theme. (Actually, the WP_Post class is defined as final and therefore can’t be extended so it’s not really extending the object, but you get what I mean.)

So here’s how I’m doing it:

Base Value Objects Class

First, I have an abstract class called Base_ValueObjects (view on GitLab):

  • All value objects in my plugin extend this class.
  • The constructor (__construct()) is protected so that new objects can’t be created externally.
  • The factory() method takes a php object (or array) as input and this object is also protected.
  • The __call() method is a getter/setter for properties. If the property doesn’t exist in the class, the value is retrieved from the object that was passed to the factory() method when creating the object.
  • Some helper functions are included to help with dates and date intervals. These helper methods can be overridden by the extending class, if necessary.

Article Class

The Article class (view on GitLab) extends the Base_ValueObjects class and includes some helper functions. Anywhere I need to access the $post object, I use an $article object instead:

$article = Article::factory($post);

Use Example

Here’s a quick example of how this can make things easier:

<?php
while (have_posts()) :
	the_post(); $article = Article::factory($post);?>

	<article id="post-<?php echo $article->ID();?>">
		<header class="entry-header">
			<a href="<?php echo $article->permalink();?>">
				<div class="post-thumbnail">
					<img src="<?php echo $article->thumbnail();?>" alt="Article Thumbnail" />
				</div>
				<h1 class="entry-title"><?php echo $article->post_title();?></h1>
			</a><?php

			// only display the geodata if we have it
			if ($article->is_geotagged()) :?>
				<span class="geo">
					<a href="https://maps.google.com/maps?z=15&amp;q=<?php
						echo $article->post_meta('geo_latitude').'+'.$article->post_meta('geo_longitude');?>" title="<?php
						echo $article->post_meta('geo_address');?>" class="place" rel="external"><?php echo $article->post_meta('geo_address');?>
					</a>
				</span><?php
			endif;?>
		</header>
		…
	</article><?php
endwhile;?>

You can read more about my custom plugin and theme or view all of the code on GitLab. I hope this helps!