Most of us who have worked with WordPress for the last decade or so have lamented the lack of a templating language whenever it comes to front-end logic.
There are teams that have done this, such as Roots, and it’s admirable. It’s opinionated nature can make it incredibly easy to work with a project or more trouble than necessary. It depends on the project, the team, and so on. But I’m not here to talk about Roots. (Check it out if you have time.)
Anyway, as with most things in development, compromises can be made. Though there isn’t any native templating built into WordPress, this doesn’t mean we can’t introduce something approximating that when it comes to our frontend functionality.
First, remember that WordPress has a convention that if you prefix a function with ‘get’, then it means it’s going to retrieve the value for you, but it’s up to you to do something with the value. For example, get_the_content()
will retrieve content for the post in question but it won’t actually render it. On the other hand, the_content()
will retrieve the content and will render it.
I mention this because if you’re going to separate your logic in a similar way, it’s important to follow this convention (though I’m personally partial to the PSR12 way of naming functions with camelCase
).
Secondly, remember that we’re now writing code in a time where it’s more than acceptable to mix multiple languages into a single file. This means that one file may include HTML, JavaScript, CSS, and maybe even some type of PHP. This isn’t how it’s always been and it isn’t how it has to be, but React ushered a lot of this into the mainstream.
All that to say, while it’s completely possible to set up your templates that look something like this:
<?php // Check $userId is set or can be retrieved in whatever way works for you. ?>
<li>Phone Number: <a href="tel:<?php echo get_user_meta($userId, 'phone_number', true) ?: 'Not Provided'; ?>"><?php get_user_meta($userId, 'phone_number', true) ?: 'Not Provided'; ?></a></li>
<li>Email Address: <a href="mailto:<?php echo strtolower(get_user_by('id', $userId)->user_email); ?>"><?php echo strtolower(get_user_by('id', $userId)->user_email); ?></a></li>
This is noisy and if you want to use those same function calls again, you’ll have to make sure they are used every single place throughout your codebase exactly as they are called here. Maybe that’s okay, maybe not.
If you’re building a large site or any application, it’s going to create more work than not, though.
You can separate the logic a bit so even though it’s not a full on templating language it still separates some of the rendering logic so the frontend isn’t so visually noisy. Plus, it allows you to update the code in one place rather than in every single template that uses it (yes, I know we could use partials or even some other smaller component of a partial that can be reused throughout the project but then you get into potential markup or design challenges with doing that).
This will make sure that the function is retrieve only the data that you need and leaves the rest of the markup and styling to be done elsewhere. Even better, it can be used in templates, in partials, or in fragments (or whatever they are called right now).
Anyway, this means that your template may look something like this:
<section id="contact-info">
<ul>
<li>Phone Number: <a href="tel:<?php echo getPhoneNumber($userId); ?>"><?php echo getPhoneNumber($userId); ?></a></li>
<li>Email Address: <a href="mailto:<?php echo getEmailAddress($userId); ?>"><?php echo getEmailAddress($userId); ?></a></li>
</ul>
</section>
And then the code behind the function call looks something like this:
/**
* Retrieves the phone number associated with the specified user.
*
* @param int $user_id The ID of the user to retrieve the phone number for.
*
* @return string|false The phone number of the user, or false if not found.
*/
function getPhoneNumber(int $userId)
{
return (
get_user_meta($userId, 'phone_number', true) ?:
'Not Provided'
);
}
/**
* Retrieves the email address associated with the specified user.
*
* @param int $user_id The ID of the user to retrieve the email address for.
*
* @return string|false The email address of the user, or false if not found.
*/
function getEmailAddress(int $userId)
{
return strtolower(
get_user_by('id', $userId)->user_email
);
}
And though you’re not straight up calling a template in terms of using brackets and the properties of a model (which you technically could, but that’s another post), you’re at least still able to get the raw data with which you can work in your template.
Maybe the methodology discussed in this article strikes you as out of date, old, or even unfamiliar. And despite how I may have come off, I’m not necessarily against mixing languages in a single file, but I do think it’s important – in an application that has no templating language – to do what we can to incorporate a pattern of development that meets us half way.
It doesn’t require third-party dependencies and it doesn’t require a paradigm shift. Just keep the functionality required for retrieving and returning the data separate and have the presentation call said function. Then mark it up and style it however you want.