PetOffice

My Headless Theme for WordPress

Next.jsWordPress

This theme has two objectives:

  1. Backend Content Restriction:
    Prevents content from being displayed in the WordPress admin backend, ensuring the focus is on external rendering.
  2. CRUD Notification:
    Sends a ping to the external App whenever posts or pages are created, updated, or deleted, facilitating cache invalidation or synchronisation.

If you want to just use it, please download here

Basic File Structure

In order to comply with the minimum requirements for a WordPress theme, you will need the following files:

  • style.css
  • index.php

style.css (Theme Metadata)
The metadata in this file is needed for WordPress to recognise the theme. Here’s an example:

/*
   Theme Name: HeadlessBackend
   Description: Redirects the front end to domain.com
   Version: 1.0
   Author: Matt Davis
*/

Since this is a headless theme, the front-end rendering is not handled here so you don’t need any templates, instead I am going to redirect the user to the front end app, or, if the user is logged in, display a link to the admin page.

This is what your index.php should look like:

<?php
if (!is_user_logged_in()) {
    header( "Location: http://localhost:3000/" );
}
else {
    echo '<a href="/wp-admin" class="button">Go to Admin</a>';
}

“Hang on a sec!” (I hear you say) “what if my APP isn’t at http://localhost:3000/?”

Oh, good point… how about we make that configurable in the settings page?

For that we need a functions.php page in our theme and in that functions.php file add the following:

<?php 
// Register the settings
function headlesswp_api_settings_init() {
    // Add a new settings section
    add_settings_section(
        'headlesswp_api_settings_section',
        'Headless WP API Settings',
        'headlesswp_api_settings_section_callback',
        'general'
    );

    // Register the API URL setting
    register_setting('general', 'headlesswp_api_url', [
        'type' => 'string',
        'description' => 'API URL for cache invalidation',
        'sanitize_callback' => 'esc_url',
        'show_in_rest' => true,
    ]);

    // Add the API URL field
    add_settings_field(
        'headlesswp_api_url',
        'API URL',
        'headlesswp_api_url_callback',
        'general',
        'headlesswp_api_settings_section'
    );
}

// Section description callback
function headlesswp_api_settings_section_callback() {
    echo '<p>Enter the API URL and secret key for your application.</p>';
}

// API URL field callback
function headlesswp_api_url_callback() {
    $value = get_option('headlesswp_api_url', '');
    echo '<input type="url" id="headlesswp_api_url" name="headlesswp_api_url" value="' . esc_attr($value) . '" class="regular-text">';
}

So now, if you go to your settings > general options page: /wp-admin/options-general.php
You should see this API URL field where you can save you frontend app url.

Now we have to update the index.php page to read the API URL variable that we have saved, using get_option(‘headlesswp_api_url’, ”)

<?phpif (!is_user_logged_in()) {    $url = get_option('headlesswp_api_url', '');    header( "Location:" . $url);}else {    echo '<a href="/wp-admin" class="button">Go to Admin</a>';}