Using taxonomies to implement radio buttons

王林
Release: 2023-09-04 14:46:02
Original
974 people have browsed it

Using taxonomies to implement radio buttons

WordPress’s custom taxonomy feature is great and allows you to organize your posts in various taxonomies, with all the hard work done for you. However, it can also be a bit limiting. When editing a post, your taxonomy terms have their own meta boxes, which appear as a checkbox list (for hierarchical taxonomies) or a tag cloud (for non-hierarchical taxonomies). These are your two options.

This can be problematic when you want to ensure that only one term is selected per post. Of course, you could hook the save_post hook and remove any "excess" terms, but that's not particularly user-friendly and certainly doesn't provide a great user interface. Sometimes it is more aesthetically desirable to present a taxonomy in a different way. This article will show you how to do this, all the code we discuss should be added to the functions.php file in your theme. We'll focus on radio buttons, but you can use any other input method, such as a drop-down menu.


Step 1Delete the default category box

WordPress automatically generates a taxonomy meta box, so our first task is to remove it so that we can generate our own taxonomy meta box in its place. I'm assuming our category name is "mytaxonomy" (you can replace this with "category" or "post_tag" if you want to change the WordPress tags or category meta box).

To remove the meta box we will use remove_meta_box which should be called from inside the function hooked into admin_menu. remove_meta_box Accepts three parameters.

  1. ID: This is the id attribute given to the div element containing the meta box. Typically, this would be "mytaxonomydiv" for hierarchical taxonomies and "tagsdiv-mytaxonomy" for non-hierarchical taxonomies.
  2. Post Type: The post type displayed in the meta box (e.g. "Post" or "Page", etc.). If your meta box appears for multiple different post types, you will need to call the remove_meta_box function for each type.
  3. Context: Normal, Advanced, or Side.
add_action( 'admin_menu', 'myprefix_remove_meta_box');
function myprefix_remove_meta_box(){
   remove_meta_box('mytaxonomydiv', 'post', 'normal');
}
Copy after login

Step 2 Add your own Metabox

Here we hook up the appropriately named add_meta_boxes hook using a function that will add our meta boxes. To do this, the function calls add_meta_box which requires quite a few parameters, including:

  1. ID: Same as above, give it anything unique.
  2. Title: The title of the meta box.
  3. Callback: The name of the function that will generate the internal structure of the metabox.
  4. Post type: Same as above. Again, you need to call this function individually for each post type.
  5. Context: Same as above.
  6. Priority: The priority in the context in which the box should be displayed.
 
//Add new taxonomy meta box
 add_action( 'add_meta_boxes', 'myprefix_add_meta_box');
 function myprefix_add_meta_box() {
     add_meta_box( 'mytaxonomy_id', 'My Radio Taxonomy','myprefix_mytaxonomy_metabox','post' ,'side','core');
 }

  function myprefix_mytaxonomy_metabox( $post ) {
     echo 'This is my taxonomy metabox';
  }
Copy after login

Overall, the above should remove the default meta box and replace it with your own meta box, currently it does nothing but display the message "This is my category meta box". The next step is to change the callback function to display what we want.


Step 3 Generate radio buttons

We want the meta box to look and behave as much as possible like the default meta box. Dig deeper into the WordPress core files and this is where you’ll find where metaboxes are generated internally. The custom function below will mimic the core function, but with some changes to how terms are displayed.

Let's take a detailed look at our function one at a time. The first bit sets some variables. You just need to change the $taxonomy variable to match your taxonomy name. Also note the $name variable. We give the input field the name tax_input[mytaxonomy]. This is the name entered in the default meta box. By doing this, WordPress will automatically handle updates to the post’s taxonomy terms.

//Set up the taxonomy object and get terms
$taxonomy = 'mytaxonomy';
$tax = get_taxonomy($taxonomy);//This is the taxonomy object

//The name of the form
$name = 'tax_input[' . $taxonomy . ']';

//Get all the terms for this taxonomy
$terms = get_terms($taxonomy,array('hide_empty' => 0));
Copy after login

We need the ID of the post's current term (we expect only one).

 
$postterms = get_the_terms( $post->ID,$taxonomy );
$current = ($postterms ? array_pop($postterms) : false);
$current = ($current ? $current->term_id : 0);
Copy after login

If you look at WordPress’ categories meta box, you’ll notice that a tab will display the “Most Common” terms. To recreate this, we need the 10 most popular terms. We use the get_terms function again, but this time select up to 10 terms and sort by count (number of posts with this classification).

$popular = get_terms( $taxonomy, array( 'orderby' => 'count', 'order' => 'DESC', 'number' => 10, 'hierarchical' => false ) );
Copy after login

Next, we want to display the "All Categories" and "Most Used" tabs (best practice is to use category tags whenever possible). If you don't need tabs, you can simply remove this bit:

<!-- Display tabs-->
<ul id="<?php echo $taxonomy; ?>-tabs" class="category-tabs">
	<li class="tabs"><a href="#<?php echo $taxonomy; ?>-all" tabindex="3"><?php echo $tax->labels->all_items; ?></a></li>
	<li class="hide-if-no-js"><a href="#<?php echo $taxonomy; ?>-pop" tabindex="3"><?php _e( 'Most Used' ); ?></a></li>
</ul>
Copy after login

Next, we want to set what displays on the "All Categories" tab:

<!-- Display taxonomy terms -->
<div id="<?php echo $taxonomy; ?>-all" class="tabs-panel">
	<ul id="<?php echo $taxonomy; ?>checklist" class="list:<?php echo $taxonomy?> categorychecklist form-no-clear">
		<?php   foreach($terms as $term){
			$id = $taxonomy.'-'.$term->term_id;
			echo "<li id='$id'><label class='selectit'>";
			echo "<input type='radio' id='in-$id' name='{$name}'".checked($current,$term->term_id,false)."value='$term->term_id' />$term->name<br />";
			echo "</label></li>";
		}?>
	</ul>
</div>
Copy after login

This essentially just displays a list inside a div element, with each list element being a radio option. Of course, you can simply replace this list with a drop-down menu or anything else you like.

Now we do the same thing with the "Most Used" tab:

<!-- Display popular taxonomy terms -->
<div id="<?php echo $taxonomy; ?>-pop" class="tabs-panel" style="display: none;">
	<ul id="<?php echo $taxonomy; ?>checklist-pop" class="categorychecklist form-no-clear" >
		<?php   foreach($popular as $term){
			$id = 'popular-'.$taxonomy.'-'.$term->term_id;
			echo "<li id='$id'><label class='selectit'>";
			echo "<input type='radio' id='in-$id'".checked($current,$term->term_id,false)."value='$term->term_id' />$term->name<br />";
			echo "</label></li>";
		}?>
	</ul>
</div>
Copy after login

第4步我们完整的回调函数

将其拼凑在一起,我们的完整功能是

//Callback to set up the metabox
function myprefix_mytaxonomy_metabox( $post ) {
    //Get taxonomy and terms
    $taxonomy = 'mytaxonomy';

    //Set up the taxonomy object and get terms
    $tax = get_taxonomy($taxonomy);
    $terms = get_terms($taxonomy,array('hide_empty' => 0));

    //Name of the form
    $name = 'tax_input[' . $taxonomy . ']';

    //Get current and popular terms
    $popular = get_terms( $taxonomy, array( 'orderby' => 'count', 'order' => 'DESC', 'number' => 10, 'hierarchical' => false ) );
    $postterms = get_the_terms( $post->ID,$taxonomy );
    $current = ($postterms ? array_pop($postterms) : false);
    $current = ($current ? $current->term_id : 0);
    ?>

    <div id="taxonomy-<?php echo $taxonomy; ?>" class="categorydiv">

        <!-- Display tabs-->
        <ul id="<?php echo $taxonomy; ?>-tabs" class="category-tabs">
            <li class="tabs"><a href="#<?php echo $taxonomy; ?>-all" tabindex="3"><?php echo $tax->labels->all_items; ?></a></li>
            <li class="hide-if-no-js"><a href="#<?php echo $taxonomy; ?>-pop" tabindex="3"><?php _e( 'Most Used' ); ?></a></li>
        </ul>

        <!-- Display taxonomy terms -->
        <div id="<?php echo $taxonomy; ?>-all" class="tabs-panel">
            <ul id="<?php echo $taxonomy; ?>checklist" class="list:<?php echo $taxonomy?> categorychecklist form-no-clear">
                <?php   foreach($terms as $term){
                    $id = $taxonomy.'-'.$term->term_id;
                    echo "<li id='$id'><label class='selectit'>";
                    echo "<input type='radio' id='in-$id' name='{$name}'".checked($current,$term->term_id,false)."value='$term->term_id' />$term->name<br />";
                   echo "</label></li>";
                }?>
           </ul>
        </div>

        <!-- Display popular taxonomy terms -->
        <div id="<?php echo $taxonomy; ?>-pop" class="tabs-panel" style="display: none;">
            <ul id="<?php echo $taxonomy; ?>checklist-pop" class="categorychecklist form-no-clear" >
                <?php   foreach($popular as $term){
                    $id = 'popular-'.$taxonomy.'-'.$term->term_id;
                    echo "<li id='$id'><label class='selectit'>";
                    echo "<input type='radio' id='in-$id'".checked($current,$term->term_id,false)."value='$term->term_id' />$term->name<br />";
                    echo "</label></li>";
                }?>
           </ul>
       </div>

    </div>
    <?php
}
Copy after login

第 5 步一点 JavaScript...

我在回调函数中对 ID 和单选按钮的命名非常谨慎。如果您现在尝试上述所有操作,您会发现 WordPress 会自动处理帖子术语的更新。此外,WordPress 的 javascript 自动处理选项卡导航。有一个轻微的问题。 “所有类别”单选按钮与“最常用的”单选按钮不同步。如果您决定放弃“最常用”选项卡,那么您可以忽略此部分。否则,我们只需要添加一点点 JavaScript 就可以解决这个问题。

我们想要向页面添加一些 javascript,因此在回调函数中,我们将使用一个钩子,当在管理中添加 javascript 时会触发该钩子。即 admin_enqueue_scripts 挂钩。由于我们将函数添加到回调函数内的此钩子上,因此仅在需要时才加载它。只需在上面的回调函数顶部添加这一行:

add_action('admin_enqueue_scripts','myprefix_radiotax_javascript');
Copy after login

当管理页面加载 JavaScript 时,这将触发我们的函数。这个函数只不过是注册我们的 javascript 并将其排入队列,我们​​希望将其加载到页脚中:

function myprefix_radiotax_javascript(){
	wp_register_script( 'radiotax', get_template_directory_uri() . '/js/radiotax.js', array('jquery'), null, true ); // We specify true here to tell WordPress this script needs to be loaded in the footer
	wp_enqueue_script( 'radiotax' );
}
Copy after login

现在对于我们实际需要的 javascript,在主题的 js 文件夹中创建一个文件。我们将其命名为 radiotax.js,下面是要放入其中的代码:

jQuery(document).ready(function($) {
	var taxonomy = 'mytaxonomy';
	$('#' + taxonomy + 'checklist li :radio, #' + taxonomy + 'checklist-pop :radio').live( 'click', function(){
		var t = $(this), c = t.is(':checked'), id = t.val();
		$('#' + taxonomy + 'checklist li :radio, #' + taxonomy + 'checklist-pop :radio').prop('checked',false);
		$('#in-' + taxonomy + '-' + id + ', #in-popular-' + taxonomy + '-' + id).prop( 'checked', c );
	});
});
Copy after login

那么这几行代码有什么作用呢?每当您选中一个单选按钮时,它都会取消选中所有其他单选按钮(在两个选项卡上),然后检查与该术语相对应的单选按钮。


结论

这样我们就完成了。 WordPress 为我们处理剩下的所有事情。不过还有改进的空间...添加新术语怎么样?我已经从我们的元框中省略了这一点,因为它实际上非常棘手。它将涉及更多的 JavaScript 以及服务器端的一些操作。


更新:

根据 Roberto 的要求,这里是 GitHub 上完整代码的链接。它是本教程中使用的代码的类实现,因此开始时您只需要更改顶部的类的静态变量。

The above is the detailed content of Using taxonomies to implement radio buttons. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template