Search code examples
wordpressradio-buttoncategories

Making categories appear conditionally in the frontend with radio button in WordPress custom field


Problem solved: I would like to thank the user @kofeigen for his interest. He did such a great job. He made the system I wanted work exactly.

I added a custom field with a radio option to the category edit page. By selecting these radio buttons with 2 options, I want to determine whether the relevant category will appear in the category list in the frontend.

I cannot add the "checked" code dynamically to save the radio button as selected. I want to intervene in the category list that I previously listed in the front end. According to this option, I want to specify a condition in the category list in the front end and list the category names accordingly. I'm new to PHP and JavaScript. I'm more newbie to Javascript than PHP. Can you help with this?

Details: I think the radio button selected is recorded with javascript or PHP and the front end should call whichever radio button is selected in the query. I can't preserve the radio markup when saving the category.

add_action ( 'subjects_edit_form_fields', 'subjects_edit_tab_fields_callback', 10, 2 );
function subjects_edit_tab_fields_callback($tag, $taxonomy) {
$tab_id = $tag->term_id;
$cat_meta = get_option( "subjects_$tab_id");
?>
<tr class="form-field">
    <th scope="row" valign="top"><label for="tab_menu_select"><?php _e('option to show in category list'); ?></label></th>
    <span class="description"><?php _e('Appear in the category list?'); ?></span>
    <td>
        <div class="form-check">
            <input class="form-check-input" type="radio" name="flexRadioDefault" id="flexRadioDefault1" checked>
            <label class="form-check-label" for="flexRadioDefault1">Show in Tab Menu</label>
        </div>
        <div class="form-check">
            <input class="form-check-input" type="radio" name="flexRadioDefault" id="flexRadioDefault2">
            <label class="form-check-label" for="flexRadioDefault2">Doesn't Show in Tab Menu</label>
        </div>
    </td>
</tr>
<?php
}

Let me make the question clearer:

  1. As an administrator, I want to select the "show category" radio button on the category edit page and update the category.
  2. I do not want to see the category name that I specified with the radio button in the tab menu tab that I specially created on the home page of my website.
  3. Because if I list all the categories listed in the tab menu I created on the home page, the menu list will be very long. Also, I do not want to display every category name in the same region.

My fiction:

  1. Adding a custom field with a radio button to the edit category page.

    • I added the custom field.
  2. Making a selection (Show/Don't show) with the radio button and saving it as selected. - Here's the real problem.

  3. Category marked "Do not show"; Don't show it when listing the category in the frontend. - Categories are listed, no problem. Then I think I can specify a condition and list it again conditionally. This part is easier if I fix the radio button issue.

In fact, it may even be a single button. In other words, if it is checked, it should show it, if it is not checked, it should not show it. The checked category should not appear when listing categories name in the frontend, or it could be the other way around. the result is the same.

As a single radio button:

add_action ( 'subjects_edit_form_fields', function( $tag ){
  $radio_select = get_term_meta( $tag->term_id, 'tab_menu_select', true );
  ?>
  <tr class='form-field'>
    <th scope='row'><label for='tab_menu_select_list'><?php _e('Showing in tab menu'); ?></label></th>
    <td>
      <input type='checkbox' name='radio_select' id='radio_select' value='<?php echo $radio_select; ?>' <?php if ($_POST['radio_select'] == 'radio_select') echo 'checked'; ?>>
    </td>
    </tr> <?php
  });
add_action ( 'edited_subjects', function( $term_id ) {
  if ( isset( $_POST['radio_select'] ) )
    update_term_meta( $term_id , 'tab_menu_select', $_POST['radio_select'] );
});

My tab menu code block where I list the categories in the frontend:

<div class="container-fluid text-center my-5 px-md-5">
  <div class="nav nav-tabs d-flex flex-column flex-md-row justify-content-center" id="nav-tab" role="tablist">
    <?php $i = 0; ?>
    <?php
    $cats = get_terms([
      'taxonomy'       =>'subjects',
      'hide_empty'     =>false,
      'orderby'        =>'name',
      'posts_per_page' => -1,
      'order'          =>'DESC']);
      ?>
      <?php foreach($cats as $cat) { ?>
        <?php $i++; ?>
        <style>a.nav-link.active{background-color: #26ae61ba!important;color: #fff!important;border: none;}</style>
        <a class="nav-link <?php echo ($i == 1) ? 'active': ''; ?>" id="nav-startup-tab" data-bs-toggle="tab" href="#<?php echo $cat->slug ?>" role="tab" aria-controls="nav-startup" aria-selected="true"> <?php echo esc_html( $cat->name ); ?></a>
      <?php } ?>
    </div>

    <div class="tab-content" id="nav-tabContent">
      <?php $i = 0; ?>
      <?php foreach($cats as $cat){ ?>
        <?php $i++; ?>
        <?php
        $args = array(
          'post_type'       => 'custompost',
          'post_status'     => 'publish',
          'posts_per_page'  => -1,
          'tax_query'       =>array(
            array('taxonomy'  => 'subjects',
              'field'           =>'term_id',
              'terms'           =>$cat->term_id,
              'operator'        => 'IN'
            ),
          ),
        ); ?>
        <div class="tab-pane <?php echo ($i == 1) ? 'active show': 'fade'; ?>" id="<?php echo $cat->slug ?>" role="tabpanel" aria-labelledby="nav-startup-tab">
          <div class="row">
            <?php
            $the_query = new WP_Query($args);
            if( $the_query->have_posts()){
              while( $the_query->have_posts()): $the_query->the_post();
                $imagepath = wp_get_attachment_image_src(get_post_thumbnail_id(),'large');
                ?>
                <div class="col-md-3">
                  <img class="mt-4 mb-2" src="<?php echo $imagepath[0];?>" alt="Tab Menu Category Post Image">
                  <a href="<?php the_permalink(); ?>"><h6><?php the_title();?></h6></a>
                </div>
              <?php endwhile; } ?>
              <?php wp_reset_postdata();?>
            </div>
          </div>
        <?php } ?>
      </div>
    </div>

Solution

  • The code snippets below have been tested, and should fit your needs.

    flexRadioDefault

    flexRadioDefault is a property of the subjects custom taxonomy terms. When an administrator edits a subjects taxonomy term, a value (0 or 1) is assigned to flexRadioDefault in the wp_termmeta database table for that specific taxonomy term (flexRadioDefault and the term are linked in the wp_termmeta table by term_id). flexRadioDefault is the meta_key. 0 or 1 is the meta_value.

    subjects taxonomy terms that do not yet have a flexRadioDefault term meta key will be shown by default (i.e. as if they had the key with a value of 1).

    Update for the admin term.php edit taxonomy page

    add_action( 'subjects_edit_form_fields', 'subjects_edit_tab_fields_callback', 10, 2 );
    function subjects_edit_tab_fields_callback( $tag, $taxonomy ) {
        $term_id = $tag->term_id;
    
        // Check if the taxonomy term already has the term meta key 'flexRadioDefault'.
        // If it doesn't, use '1' (show) as the default value.
        $metadata_exists = metadata_exists( 'term', $term_id, 'flexRadioDefault' );
        if ( $metadata_exists ) {
    
            // @see {@link https://developer.wordpress.org/reference/functions/get_term_meta/}
            // The third argument (a boolean) determines if the meta_value should be read as
            // a single value (compared to being read as an array of values).
            $flexRadioDefault = get_term_meta( $term_id, 'flexRadioDefault', true );
        } else {
            $flexRadioDefault = 1;
        }
        ?>
        <tr class="form-field">
            <th scope="row" valign="top"><label for="tab_menu_select"><?php _e('option to show in category list'); ?></label></th>
            <span class="description"><?php _e('Appear in the category list?'); ?></span>
            <td>
                <div class="form-check">
                <input class="form-check-input" type="radio" name="flexRadioDefault" id="flexRadioDefault1" value="1" <?php checked( $flexRadioDefault, 1 ); ?>>
                    <label class="form-check-label" for="flexRadioDefault1">Show in Tab Menu</label>
                </div>
                <div class="form-check">
                    <input class="form-check-input" type="radio" name="flexRadioDefault" id="flexRadioDefault2" value="0" <?php checked( $flexRadioDefault, 0 ); ?>>
                    <label class="form-check-label" for="flexRadioDefault2">Doesn't Show in Tab Menu</label>
                </div>
            </td>
        </tr>
        <?php
    }
    

    Process the radio button value after form submission

    add_action( 'edit_subjects', 'update_subject_status', 10, 3 );
    function update_subject_status( $term_id, $tt_id, $args ) {
        if ( ! isset( $args )
            || 'subjects' != $args['taxonomy']
            || ! isset( $args['term_id'] )
        ) {
            return;
        }
    
        update_term_meta( $term_id, 'flexRadioDefault', $args['flexRadioDefault'] );
    }
    

    Update for the WP_Term_Query used to get the list of custom taxonomy terms in the tab menu code block

    The query searches for taxonomy terms that:

    1. have the flexRadioDefault term meta key with a value of 1 (show)
      OR
    2. do not have the flexRadioDefault term meta key at all (since they are shown by default).

    The only taxonomy terms that will be excluded are those that have the flexRadioDefault term meta key with a value of 0 (hide).

    $meta_args = array(
        'relation' => 'OR',
        array(
            'key'      => 'flexRadioDefault',
            'value'    => 1,
            'type'     => 'UNSIGNED',
            'compare'  => '='
        ),
        array(
            'key'      => 'flexRadioDefault',
            'compare'  => 'NOT EXISTS'
        )
    );
    
    $cats = get_terms(
        array(
            'taxonomy'   => 'subjects',
            'hide_empty' => false,
            'number'     => '',
            'orderby'    => 'name',
            'order'      => 'DESC',
            'fields'     => 'all',
            'meta_query' => $meta_args
        )
    );
    

    Update to WP_Query used in the tab menu code block

    'operator' => 'IN' should be used when the tax_query terms property is assigned to an array. Your terms property is assigned to an integer. So, 'operator' => 'IN' should be removed.