Skip to content

Instantly share code, notes, and snippets.

@bseddon
Last active January 24, 2024 01:15
Show Gist options
  • Save bseddon/e6efc870773049c9fa7033e214adf773 to your computer and use it in GitHub Desktop.
Save bseddon/e6efc870773049c9fa7033e214adf773 to your computer and use it in GitHub Desktop.
Different WordPress theme by users

When developing a large application in WordPress one option is to implement it as a theme rather than a series of plugins. When the project has multiple developers, a challenge then is how to provide each developer their own environment. If the site is standalone then each developer can have their own local WP instance. But what about the database? If different developers are adding records to different databases how are they merged.

Anyway, in my scenario there's a simpler approach. Let each developer have their own copy of the theme within the themes folder. The only requirement then is to be able to allow each user to choose or to be allocated a specific theme. This is really easy to do.

The main function is the one that reacts to the 'wp_loaded' action. The action function looks to see what theme template folder is defined in user meta for the user and returns it. Otherwise it returns a default theme folder.

The rest of the code adds a dropdown of the available themes to the user profile page and saves the the selection if/when the profile is updated.

<?php

/*
    Plugin Name: User switch theme
    Description: Swap the theme based on the user.
    Version: 0.1
    Author: Bill Seddon
    Author URI: https://github.com/bseddon
    License: GPL v3
*/

/**
 * Replace the theme with one from user meta data if one exists.
 * The plugins_loaded action is called before any theme work occurs
 */
add_action('plugins_loaded', function() 
{
    $user = wp_get_current_user();
    if ( ! isset( $user ) || $user->ID == 0 ) return;

    // Get the 'theme' user meta data value
    $theme = get_user_meta( $user->ID, 'theme', true );
    if ( ! empty( $theme ) )
    {
        error_log( "wp_loaded: $theme" );
        // Replace the theme with the one from the user meta data
        add_filter('template', function($template) use ($theme) {
            return $theme;
        });
        // Replace the stylesheet with the one from the user meta data
        add_filter('stylesheet', function($stylesheet) use ($theme) {
            return $theme;
        });
    }
});

/**
 * Present a drop down list of themes to the user.
 * @param object $user The user object currently being edited.
 */
function edit_user_template_name( $user )
{
	// If there is no user, there is no theme to add
	if ( $user == "add-new-user" || ! current_user_can( 'administrator' ))
	{
		return;
	}

    ?>
  
	<h3><?php _e( 'Set personal thene' ); ?></h3>
  
	<table class="form-table">
  
		<tr>
			<th><label for="theme"><?php _e( 'Testing theme to use' ); ?></label></th>

			<td>
<?php
                // Get the user's theme
                $theme = get_user_meta( $user->ID, 'theme', true );

                // Get the current theme
                // Can't use the 'current_theme' as it's always the theme of person reviewing the user profile

                if ( empty( $theme ) ) 
                {
                    // Use the option save in appearance->themes as the default
                    $theme = get_option( 'template', false ); 
                }

                // Get the list of themes
                $themes = wp_get_themes();

                // Create a drop down list of themes
                $theme_list = "<select name='theme' id='theme'>";
                foreach ( $themes as $theme_name => $theme_data )
                {
                    $theme_list .= "<option value='$theme_name' " . selected( $theme_name, $theme, false ) . ">$theme_name</option>";
                }
                $theme_list .= "</select>";

                echo $theme_list;
?>
			</td>
		</tr>
	</table>
<?php 
}
  
add_action( 'show_user_profile', 'edit_user_template_name' );
add_action( 'edit_user_profile', 'edit_user_template_name' );
add_action( 'user_new_form', 'edit_user_template_name' );

/**
 * Save the selected theme for the user.
 * @param int $user_id The ID of the user to save the terms for.
 */
function save_user_template_name( $user_id )
{
	/* Make sure the current user can edit the user and assign terms before proceeding. */
	if ( !current_user_can( 'edit_user', $user_id ) )
	  return false;
  
	$theme = $_POST['theme'];

    if ( ! empty( $theme ) && $theme != "fwsbi" )
    {
        update_user_meta( $user_id, 'theme', $theme );
    }
    else
    {
        delete_user_meta( $user_id, 'theme' );
    }
}

add_action( 'personal_options_update', 'save_user_template_name' );
add_action( 'edit_user_profile_update', 'save_user_template_name' );
add_action( 'user_register', 'save_user_template_name' );
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment