0

I tried to write code to have a checkbox on Pages in the backend to check if I want to hide the title of the page in frontend. But I find that the post meta is sometimes reset to show the title even if I did set it to "hide the title". This only happens randomly when I edited a page or made some other changes. Please advise on what could be wrong or if there is a better way of doing it?

Here is my code in functions.php

function mysite_page_metabox() {
    add_meta_box( 
        'remove-title', 
        __('Hide Page Title', 'textdomain' ), 
        'hide_title_callback', 
        'page', 
        'side', 
        'high' 
    );
}
add_action( 'add_meta_boxes' , 'mysite_page_metabox');

function hide_title_callback() {
    $value = get_post_meta(get_the_ID(), '_mysite_meta_hide_title', true);
    ?>
    <?php if($value == "on") : ?>
        <label for="hide">Hide: </label><input type="checkbox" name="hide" checked>
    <?php else : ?>
        <label for="hide">Hide: </label><input type="checkbox" name="hide">
    <?php endif; ?> 
    <?php
}


// Save meta key and value
function mysite_save_postdata($post_id)
{
    if ( isset( $_POST['hide']) ) {
        update_post_meta(
            $post_id,
            '_mysite_meta_hide_title',
            sanitize_text_field( $_POST['hide'] )
        );
    } else {
        update_post_meta(
            $post_id,
            '_mysite_meta_hide_title',
            sanitize_text_field( "off" )
        );
    }
}
add_action('save_post', 'mysite_save_postdata');

In my content-page.php template-parts I call it like this:

<!--Start the hide title-->
    <?php 
        $hide_title_status = get_post_meta( get_the_ID(), '_mysite_meta_hide_title', true);
        $post_id = get_the_ID();
        if($hide_title_status == "off" || !metadata_exists( 'post', $post_id, '_mysite_meta_hide_title' ) ) :
    ?>
        <header class="entry-header">
            <?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
        </header><!-- .entry-header -->
    <?php endif; ?> <!--End the hide title-->
1

$value is always empty because post ID is missing. Pass the parameter ($post object) to the hide_title_callback() function and get the post ID right way.

Also, you should take care of nonces.

<?php
// pass the $post object
function hide_title_callback( $post ) {

    // you have to verify this nonce inside `mysite_save_postdata()`
    // https://codex.wordpress.org/Function_Reference/wp_nonce_field
    wp_nonce_field( 'mysite_action_name', 'mysite_nonce_field_name' );

    // now you have the post ID
    $value = get_post_meta( $post->ID, '_mysite_meta_hide_title', true );

    if( $value == "on" ) : ?>
        <label for="hide">Hide: </label><input type="checkbox" name="hide" checked>
    <?php else : ?>
        <label for="hide">Hide: </label><input type="checkbox" name="hide">
    <?php endif;
}

Verify the nonce

<?php
function mysite_save_postdata( $post_id ) {
    // https://codex.wordpress.org/Function_Reference/wp_verify_nonce
    if ( !wp_verify_nonce( $_POST['mysite_nonce_field_name'], 'mysite_action_name' ) ) {
        return;
    }

    if ( isset( $_POST['hide']) ) {
        update_post_meta(
            $post_id,
            '_mysite_meta_hide_title',
            sanitize_text_field( $_POST['hide'] )
        );
    } else {
        update_post_meta(
            $post_id,
            '_mysite_meta_hide_title',
            sanitize_text_field( "off" )
        );
    }
}

To keep the database a bit cleaner I personally should not save the 'off' meta value. I should remove the _mysite_meta_hide_title completely if checkbox is unchecked. So, it will exist if 'on' and do not if 'off'. if() statement in the hide_title_callback() will remain intact.

<?php
if ( ! isset( $_POST['hide'] ) ) {
    // unchecked
    delete_post_meta(
        $post_id,
        '_mysite_meta_hide_title',
    );
} else {
    // checked
    update_post_meta(
        $post_id,
        '_mysite_meta_hide_title',
        'on' // nothing to sanitize here
    );
}
1
  • thank you for the thorough answer. I will definitely consider your option to keep the database cleaner.
    – Feyt
    Feb 18 '19 at 10:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.