Halloween Sale 15% off Ends in See the plans
PHP

Different Logo on Selected Pages

Adds a Page Logo box to the page editor so you can pick a different logo from the Media Library for that page. It replaces the site logo wherever the theme shows it, including the Site Logo block.

Don’t have WPIDE yet? Install it on your site

Code

// Post types that get the "Page Logo" box.
$wpide_page_logo_post_types = array( 'page' );

// Where the chosen image ID is stored.
$wpide_page_logo_meta_key = '_wpide_page_logo_id';

// Registered for the REST API so the block editor saves it with the page.
add_action( 'init', function () use ( $wpide_page_logo_post_types, $wpide_page_logo_meta_key ) {
    foreach ( $wpide_page_logo_post_types as $post_type ) {
        register_post_meta( $post_type, $wpide_page_logo_meta_key, array(
            'type'              => 'integer',
            'single'            => true,
            'default'           => 0,
            'show_in_rest'      => true,
            'sanitize_callback' => 'absint',
            'auth_callback'     => function ( $allowed, $meta_key, $post_id ) {
                return current_user_can( 'edit_post', $post_id );
            },
        ) );
    }
} );

add_action( 'add_meta_boxes', function () use ( $wpide_page_logo_post_types, $wpide_page_logo_meta_key ) {
    add_meta_box( 'wpide-page-logo', 'Page Logo', function ( $post ) use ( $wpide_page_logo_meta_key ) {
        $logo_id = (int) get_post_meta( $post->ID, $wpide_page_logo_meta_key, true );
        $preview = $logo_id ? wp_get_attachment_image( $logo_id, 'medium', false, array( 'style' => 'max-width:100%;height:auto;' ) ) : '';

        wp_nonce_field( 'wpide_page_logo_save', 'wpide_page_logo_nonce' );
        ?>
        <div class="wpide-page-logo" data-meta-key="<?php echo esc_attr( $wpide_page_logo_meta_key ); ?>">
            <div class="wpide-page-logo__preview"><?php echo wp_kses_post( $preview ); ?></div>
            <input type="hidden" name="wpide_page_logo_id" value="<?php echo esc_attr( $logo_id ? (string) $logo_id : '' ); ?>">
            <p>
                <button type="button" class="button wpide-page-logo__choose">Choose logo</button>
                <button type="button" class="button-link button-link-delete wpide-page-logo__remove"<?php echo $logo_id ? '' : ' hidden'; ?>>Remove</button>
            </p>
            <p class="description">Shown instead of the site logo on this page only.</p>
        </div>
        <?php
    }, $wpide_page_logo_post_types, 'side', 'low' );
} );

add_action( 'admin_enqueue_scripts', function ( $hook ) use ( $wpide_page_logo_post_types ) {
    $screen = get_current_screen();

    if ( in_array( $hook, array( 'post.php', 'post-new.php' ), true ) && $screen && in_array( $screen->post_type, $wpide_page_logo_post_types, true ) ) {
        wp_enqueue_media();
    }
} );

$wpide_page_logo_script = function () use ( $wpide_page_logo_post_types ) {
    $screen = get_current_screen();

    if ( ! $screen || ! in_array( $screen->post_type, $wpide_page_logo_post_types, true ) ) {
        return;
    }
    ?>
    <script>
    ( function () {
        var box = document.querySelector( '.wpide-page-logo' );
        if ( ! box || ! window.wp || ! wp.media ) {
            return;
        }

        var input = box.querySelector( 'input[name="wpide_page_logo_id"]' );
        var preview = box.querySelector( '.wpide-page-logo__preview' );
        var remove = box.querySelector( '.wpide-page-logo__remove' );
        var metaKey = box.getAttribute( 'data-meta-key' );
        var frame = null;

        // In the block editor, also store the value in the page itself so "Save" picks up the change.
        function setValue( id ) {
            input.value = id ? String( id ) : '';
            remove.hidden = ! id;
            if ( wp.data && wp.data.select( 'core/editor' ) ) {
                var meta = wp.data.select( 'core/editor' ).getEditedPostAttribute( 'meta' );
                if ( meta && Object.prototype.hasOwnProperty.call( meta, metaKey ) ) {
                    var change = {};
                    change[ metaKey ] = id || 0;
                    wp.data.dispatch( 'core/editor' ).editPost( { meta: change } );
                }
            }
        }

        box.querySelector( '.wpide-page-logo__choose' ).addEventListener( 'click', function () {
            if ( ! frame ) {
                frame = wp.media( {
                    title: 'Choose a logo for this page',
                    button: { text: 'Use as page logo' },
                    library: { type: 'image' },
                    multiple: false
                } );

                frame.on( 'select', function () {
                    var image = frame.state().get( 'selection' ).first().toJSON();
                    var img = document.createElement( 'img' );
                    img.src = image.sizes && image.sizes.medium ? image.sizes.medium.url : image.url;
                    img.alt = '';
                    img.style.maxWidth = '100%';
                    img.style.height = 'auto';
                    preview.textContent = '';
                    preview.appendChild( img );
                    setValue( image.id );
                } );
            }
            frame.open();
        } );

        remove.addEventListener( 'click', function () {
            preview.textContent = '';
            setValue( 0 );
        } );
    } )();
    </script>
    <?php
};

add_action( 'admin_footer-post.php', $wpide_page_logo_script );
add_action( 'admin_footer-post-new.php', $wpide_page_logo_script );

// Classic editor (and the meta box form the block editor sends after saving).
add_action( 'save_post', function ( $post_id, $post ) use ( $wpide_page_logo_post_types, $wpide_page_logo_meta_key ) {
    if ( ! isset( $_POST['wpide_page_logo_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['wpide_page_logo_nonce'] ) ), 'wpide_page_logo_save' ) ) {
        return;
    }

    if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || wp_is_post_revision( $post_id ) || ! in_array( $post->post_type, $wpide_page_logo_post_types, true ) || ! current_user_can( 'edit_post', $post_id ) ) {
        return;
    }

    $logo_id = isset( $_POST['wpide_page_logo_id'] ) ? absint( $_POST['wpide_page_logo_id'] ) : 0;

    if ( $logo_id && wp_attachment_is_image( $logo_id ) ) {
        update_post_meta( $post_id, $wpide_page_logo_meta_key, $logo_id );
    } else {
        delete_post_meta( $post_id, $wpide_page_logo_meta_key );
    }
}, 10, 2 );

// Swap the logo on the front end. This covers get_custom_logo(), the_custom_logo() and the Site Logo block.
add_filter( 'theme_mod_custom_logo', function ( $logo_id ) use ( $wpide_page_logo_post_types, $wpide_page_logo_meta_key ) {
    if ( is_admin() || ! did_action( 'wp' ) || ! is_singular( $wpide_page_logo_post_types ) ) {
        return $logo_id;
    }

    $page_logo = (int) get_post_meta( get_queried_object_id(), $wpide_page_logo_meta_key, true );

    return ( $page_logo && wp_attachment_is_image( $page_logo ) ) ? $page_logo : $logo_id;
}, 20 );

Notes

Add more post types at the top, for example array( 'page', 'post' ). Remove the page logo to go back to the site logo. The logo is shown at the size your theme or Site Logo block uses.

How to add this snippet

  1. Install WPIDE on your WordPress site (it is free) and open Code Snippets.
  2. Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
  3. It is added inactive: review the code and settings, then switch it on.

Have a snippet worth sharing?

Publish it to the library from WPIDE or right here. Sign in with any WordPress site that runs WPIDE, free or Pro. Public snippets are reviewed by the WPIDE team before they appear.

Which site should get this snippet?

Enter the address of your WordPress site. WPIDE opens there in a new tab with the snippet ready to review and save.

Remembered in this browser only, so you are asked once.

Report this snippet

Tell the WPIDE team what is wrong: broken code, something harmful, spam or copied work.