web-dev-qa-db-fra.com

Rendre les catégories parentes non sélectionnables

J'aimerais que mes catégories ayant des catégories enfants ne soient pas sélectionnables sur la page de post article.

Ce que je veux faire est de supprimer la case à cocher avant leur étiquette.

J'ai consulté la documentation sur les filtres, mais je n'ai trouvé aucun filtre adapté à mes besoins.

2
koskoz

Je doute vraiment que ce soit filtrable, alors jQuery vient à la rescousse :)

Le code

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

function wpse_22836_remove_top_categories_checkbox()
{
    global $post_type;

    if ( 'post' != $post_type )
        return;
    ?>
        <script type="text/javascript">
            jQuery("#categorychecklist>li>label input").each(function(){
                jQuery(this).remove();
            });
        </script>
    <?php
}

Le résultat

no parent categories


Avancée

Il y a une mise en garde: chaque fois que vous sélectionnez une sous-catégorie, elle sort de la hiérarchie ...

Voici donc le code de l'excellent plug-in de Scribu, Catégorie Checklist Tree , associé au code précédent.

Sur l'écran d'édition de publication, après avoir enregistré une publication, vous remarquerez que les catégories cochées sont affichées en haut, brisant ainsi la hiérarchie des catégories. Ce plugin supprime cette "fonctionnalité".

Soit vous utilisez le code précédent et installez le plugin, soit vous le déposez simplement dans le functions.php de votre thème ou dans un plugin personnalisé du vôtre (préférable, afin que tous vos réglages soient indépendants du thème).

/*
Based on Category Checklist Tree, by scribu
Preserves the category hierarchy on the post editing screen
Removes parent categories checkbox selection
*/
class Category_Checklist {

    function init() {
        add_filter( 'wp_terms_checklist_args', array( __CLASS__, 'checklist_args' ) );
    }

    function checklist_args( $args ) {
        add_action( 'admin_footer', array( __CLASS__, 'script' ) );

        $args['checked_ontop'] = false;

        return $args;
    }

    // Scrolls to first checked category
    function script() {
?>
<script type="text/javascript">
    jQuery(function(){
        jQuery('[id$="-all"] > ul.categorychecklist').each(function() {
            var $list = jQuery(this);
            var $firstChecked = $list.find(':checked').first();

            if ( !$firstChecked.length )
                return;

            var pos_first = $list.find(':checkbox').position().top;
            var pos_checked = $firstChecked.position().top;

            $list.closest('.tabs-panel').scrollTop(pos_checked - pos_first + 5);
        });

        jQuery("#categorychecklist>li>label input").each(function(){
            jQuery(this).remove();
        });

    });
</script>
<?php
    }
}

Category_Checklist::init();
3
brasofilo

Presque exactement la même chose pour brasofilo, mon code ci-dessous tient compte également de différentes taxonomies et supprime la case à cocher pour les catégories parent au niveau supérieur, uniquement si elles ont des enfants. Cela permet de sélectionner d'autres catégories de premier niveau sans enfant. Je mets ce code simple dans le fichier functions.php de mon thème:

class Category_Checklist {

function init() {
    add_filter( 'wp_terms_checklist_args', array( __CLASS__, 'checklist_args' ) );
}

function checklist_args( $args ) {
    add_action( 'admin_footer', array( __CLASS__, 'script' ) );

    $args['checked_ontop'] = false;

    return $args;
}

// Scrolls to first checked category
function script() {
?>
<script type="text/javascript">
(function($){
    $('[id$="-all"] > ul.categorychecklist').each(function() {
        var list = $(this);
        var firstChecked = list.find(':checked').first();

        if ( !firstChecked.length )
            return;

        var pos_first = list.find(':checkbox').position().top;
        var pos_checked = firstChecked.position().top;

        list.closest('.tabs-panel').scrollTop(pos_checked - pos_first + 5);
    });

    $(".categorychecklist>li>label input").each(function(){
        if ($(this).parent().next('ul').hasClass('children')) {
            $(this).remove();
        }
    });

})(jQuery);
</script>
<?php
    }
}

Category_Checklist::init();
3
Mike Kormendy

Cela peut également être fait avec le plugin "Category Checklist Tree" pour maintenir la hiérarchie de la taxonomie comme le dit brasofilo et quelques CSS:

#categorychecklist > li > label.selectit > input { display: none !important; }

(#categorychecklist peut être remplacé par #yourcustomtaxonomychecklist pour l'appliquer à une taxonomie custo)

Pour ajouter ceci, ainsi que d’autres css à wordpress admin, les éléments suivants peuvent être ajoutés à functions.php:

function my_admin_head() {
    echo '<link rel="stylesheet" type="text/css"
    href="'.get_bloginfo('stylesheet_directory').'/admin.css">';
}
add_action('admin_head', 'my_admin_head');

Et ajoutez ensuite la feuille de style "admin.css à votre répertoire de thèmes et ajoutez le css ci-dessus

0
Peanut

J'ai utilisé une combinaison de ce qui précède pour obtenir ma solution. J'ai bien aimé l'approche css pure, mais l'action de clic sur l'étiquette changerait quand même l'attribut "vérifié" de la case à cocher même si elle n'était pas affichée. Voici ma solution, notez qu'il est difficile de masquer les deux premiers niveaux de catégories.

css:

#categorychecklist > li > label.selectit,
#categorychecklist > li > ul.children > li > label.selectit {cursor: text;}

#categorychecklist > li > label.selectit > input,
#categorychecklist > li > ul.children > li > label.selectit > input { display: none !important; }

js (si la case à cocher est masquée, annulez l'événement click. Cela fonctionnera à n'importe quel niveau):

$('#categorychecklist > li label.selectit').on('click', function(event) {
        if (!$(this).children("input").is(':visible'))
            event.preventDefault();
    });

Et pour référence sur admin:

function add_admin_assets() {
    wp_enqueue_style( "admin-custom-css", get_bloginfo('template_url').'/assets/styles/custom/admin.css');
    wp_enqueue_script('admin-custom-js', get_bloginfo('template_url').'/inc/js/admin.js', array(), null, true);
}
add_action('admin_head', 'add_admin_assets');
0
Nathan Pond

Voici ce que j'ai utilisé pour désactiver les catégories parentes et n'autoriser qu'une catégorie par publication. Ce code modifie également les catégories de modification rapide. Je souhaite la bienvenue à quelqu'un pour le nettoyer, je ne suis pas confiant en javascript.

J'ai eu la première partie ici: https://wordpress.org/support/topic/making-category-selection-radio-buttons

    /* ONLY ALLOW ONE CATEGORY PER POST */
add_action( 'admin_footer', 'catlist2radio' );
function catlist2radio(){
    echo '<script type="text/javascript">';
    echo 'jQuery("#categorychecklist .children input, #categorychecklist-pop .children input, .cat-checklist .children input")';
    echo '.each(function(){this.type="radio"});</script>';
}

/* DISABLE PARENT CATEGORIES FOR POSTS */
/*
Based on Category Checklist Tree, by scribu
Preserves the category hierarchy on the post editing screen
Removes parent categories checkbox selection
*/
class Category_Checklist {
    function init() {
        add_filter( 'wp_terms_checklist_args', array( __CLASS__, 'checklist_args' ) );
    }
    function checklist_args( $args ) {
        add_action( 'admin_footer', array( __CLASS__, 'script' ) );
        $args['checked_ontop'] = false;
        return $args;
    }

    // Scrolls to first checked category
    function script() {
?>
<script type="text/javascript">
    jQuery(function(){
        jQuery('[id$="-all"] > ul.categorychecklist').each(function() {
            var $list = jQuery(this);
            var $firstChecked = $list.find(':checked').first();
            if ( !$firstChecked.length )
                return;
            var pos_first = $list.find(':checkbox').position().top;
            var pos_checked = $firstChecked.position().top;
            $list.closest('.tabs-panel').scrollTop(pos_checked - pos_first + 5);
        });
        jQuery("#categorychecklist>li>label input").each(function(){
            jQuery(this).remove();
        });
    });
        jQuery(function(){
        jQuery('[id$="-all"] > ul.cat-checklist').each(function() {
            var $list = jQuery(this);
            var $firstChecked = $list.find(':checked').first();
            if ( !$firstChecked.length )
                return;
            var pos_first = $list.find(':checkbox').position().top;
            var pos_checked = $firstChecked.position().top;
            $list.closest('.tabs-panel').scrollTop(pos_checked - pos_first + 5);
        });
        jQuery(".cat-checklist>li>label input").each(function(){
            jQuery(this).remove();
        });
    });
        jQuery('#category-tabs .hide-if-no-js').remove();
</script>
<?php
    }
}
Category_Checklist::init();
0
Carole Magouirk

La solution suivante empêche que la case à cocher ne soit affichée. Cela semble être beaucoup plus propre à mon avis.

Je crée un lecteur personnalisé qui étend le Walker_Category_Checklist de base, qui remplace la fonction start_el afin qu’il puisse conditionnellement définir $args['list_only'] sur true. Dans ce cas, la fonction vérifie si nous avons un terme de niveau supérieur ($category->parent == 0) qui comporte des sous-termes ($args['has_children']) et, bien sûr, une vérification si nous utilisons la taxonomie appropriée. Ces conditions étant remplies, $args['list_only'] est défini sur true et la méthode parent est appelée, ce qui ne permet pas d'afficher la case à cocher pour cet élément maintenant.

class Wpse22836_Walker_Category_Checklist extends Walker_Category_Checklist {
    public function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
        if ( 'category' ==  $args['taxonomy'] 
                && $args['has_children'] 
                && 0 === $category->parent) {
            $args['list_only'] = true;
        }
        parent::start_el( $output, $category, $depth, $args, $id );
    }
}

Pour que WordPress utilise cette classe de promeneur au lieu de la classe d'origine, nous pouvons utiliser le filtre wp_terms_checklist_args dans wp_terms_checklist():

add_filter( 'wp_terms_checklist_args', function( $args, $post_id ) {
    $args['walker'] = new Wpse22836_Walker_Category_Checklist();
    return $args;
}, 10, 2 );

Cette solution présente l’avantage de fonctionner automatiquement dans tous les endroits utilisant la fonction principale wp_terms_checklist() et ne dépend pas de JavaScript.

0
JHoffmann