web-dev-qa-db-fra.com

Limiter le widget à une barre latérale enregistrée spécifique

J'ai un widget que je veux seulement être autorisé à être utilisé avec la barre latérale single.php. Quand j'ai référencé le codex pour register sidebar , il n'y a pas moyen de limiter les widgets dans le tableau. J'ai fait des recherches avec "Widget limite WordPress à publier", mais ce ne sont que des plug-ins renvoyés dans mes résultats de recherche. Lorsque je modifie mes paramètres de recherche en page pour voir si je peux obtenir un résultat, je fais référence à:

Existe-t-il un moyen de cibler un widget uniquement pour la variable id dans le register_sidebar? Je ne veux pas utiliser un plugin, je veux apprendre à le coder correctement.

MODIFIER:

Par commentaires, j'ai un widget personnalisé. cela est appelé dans mon singles.php en tant que <?php get_sidebar( 'foobar' );?>. Quand quelqu'un est dans admin, je veux limiter l'application du widget:

 enter image description here 

Donc, dans l'image ci-dessus, je veux seulement l'option Post Sidebar. Je pourrais coder durement tout cela dans le fichier sidebar-foobar.php mais j'essaie d'apprendre à utiliser davantage les widgets.

4

Ma connaissance de jquery est encore quasi inexistante, donc je ne suis pas sûr si la solution fonctionne comme l'a suggéré @Howdy_McGee dans les commentaires.

Quoi qu’il en soit, à titre de référence, à partir du lien

remplacez simplement 'your_widget' par le nom de votre widget dans le code ci-dessous (deux emplacements).

L'événement 'sortreceive' n'est appelé que lorsque le widget est ajouté à la barre latérale, alors que 'sortstop' est appelé chaque fois que vous déplacez le widget dans la barre latérale ou que vous le supprimez.

'sortstop' est également appelé lorsque le widget est ajouté, mais pour une raison quelconque, ui.input n'est pas défini correctement, j'ai donc utilisé 'sortreceive' pour couvrir cela.

jQuery('div.widgets-sortables').bind('sortstop',function(event,ui){
  var id = jQuery(ui.item).attr('id');
  if (id) {
    var widget_type = id.match(/widget-[0-9]+_(.+)-[0-9]+/i)[1];
    if (widget_type == 'your_widget') {
    // do stuff;
    }
  }
})

jQuery('div.widgets-sortables').bind('sortreceive',function(event,ui){
  var id = jQuery(ui.item).attr('id');
  var widget_type = id.match(/widget-[0-9]+_(.+)-__i__/i)[1];
  if (widget_type == 'your_widget') {
    // do stuff;
  }
})

J'ai récemment travaillé sur une réponse où un widget spécifique peut être supprimé du tableau de widgets d'une barre latérale spécifique. Ici, nous utilisons le filtre sidebars_widgets pour supprimer un widget spécifique de toutes les barres latérales, à l’exception de la barre latérale où il devrait se trouver.

En bref, un widget ajouté de manière incorrecte à une barre latérale ne sera pas affiché au début du programme et ne renverra pas non plus true avec une vérification is_active_sidebar() si ce widget est le seul widget ajouté à cette barre latérale spécifique.

Vous pouvez essayer le code suivant, assurez-vous simplement de modifier les valeurs du widget et de la barre latérale en conséquence.

add_filter( 'sidebars_widgets', function ( $sidebars_widgets )
{
    // Return our filter when we are on admin screen
    if ( is_admin() )
        return $sidebars_widgets;

    /**
     * Widget we need to target. This should be the name/id we used to register it
     *
     * EXAMPLE
     * parent::__construct(
            'widget_category_posts', 
            _x( 'Category Posts Widget', 'Category Posts Widget' ), 
            [ 'description' => __( 'Display a list of posts from a selected category.' ) ] 
        );
     *
     */
    $custom_widget  = 'widget_category_posts';
    // The sidebar ID we need to run the widget in
    $sidebar_accept = 'sidebar-2';

    // We have come this far, let us wrap this up
    // See if our custom content widget exists is any sidebar, if so, get the array index
    foreach ( $sidebars_widgets as $sidebars_key=>$sidebars_widget ) {
        // Skip the wp_inactive_widgets set, we do not need them
        if ( $sidebars_key == 'wp_inactive_widgets' )
        continue;

        // Only continue our operation if $sidebars_widget are not an empty array
        if ( $sidebars_widget ) {
            foreach ( $sidebars_widget as $k=>$v ) {

                /**
                 * Look for our custom widget, if found, unset it from the $sidebars_widgets array
                 * @see stripos()
                 */
                if ( stripos( $v, $custom_widget ) !== false ) {
                    // If we are on a single page and the sidebar is $sidebar_accept, do not unset
                    if ( is_single() && $sidebars_key == $sidebar_accept )
                        continue;

                    unset( $sidebars_widgets[$sidebars_key][$k] );
                }
            } // endforeach $sidebars_widget
        } // endif $sidebars_widget
    } // endforeach $sidebars_widgets

    return $sidebars_widgets;
});

En conclusion, il ne s'agit que d'une solution de contournement PHP qui ne fonctionne que pour le front-end, mais je vous exhorte à rechercher une solution jquery appropriée dans laquelle un widget est uniquement lié à une barre latérale spécifique dans le backend . Comme je le disais, la solution jQuery du lien n’a pas été testée et je ne sais pas si cela fonctionne vraiment.

2
Pieter Goosen

En plus de vos scripts, j'ai écrit le script qui masque les barres latérales de la liste déroulante (je ne pouvais le trouver nulle part). J'ai fait de l'ingénierie inverse du code Wordpress original de widgets.js pour écrire cela.

La solution complète permettant de glisser-déposer uniquement vers les barres latérales spécifiées et de filtrer la liste déroulante (il vous suffit de l'insérer dans votre script d'administrateur jQuery prêt pour le document):

function allowedSidebars(allowed)
{
    // this variable will have index of first visible sidebar
    var first = null;
    $('.widgets-chooser-sidebars li').removeClass('widgets-chooser-selected').each(function(index)
    {
        // the data('sidebarId') is set up by wordpress, let's make us of it
        if(-1 === $.inArray($(this).data('sidebarId'), allowed))
        {
            $(this).hide();
        }
        else if(first == null)
        {
            first = index;
        }
    });
    // choose first visible sidebar as default
    if(first != null)
    {
        $('.widgets-chooser-sidebars li').eq(first).addClass('widgets-chooser-selected');
    }
}
$('#available-widgets .widget .widget-title').on('click.widgets-chooser', function()
{
    var widget = $(this).closest('.widget');
    // we want to run our script only on slideDown, not slideUp
    if(!widget.hasClass('widget-in-question'))
    {
        // there is only one sidebar list per all widgets, so we have to show all the sidebars every time
        $('.widgets-chooser-sidebars li').show();
        switch(widget.find('input[name="id_base"]').val())
        {
            // your widgets here
            case 'your_widget_id':
                // allowed sidebars for widget
                allowedSidebars(['your-sidebar-id', 'your-second-sidebar-id']);
            break;
        }
    }
});
// this will make drag and drop working only for specified sidebars
$('.widget').on('dragcreate dragstart', function( event, ui ) {
    var id = $(this).find('input[name="id_base"]').val();
    // probably you may want to change it to switch
    if(id == 'your_widget_id')
    {
        $(this).draggable({
            connectToSortable: '#your-sidebar-id, #your-second-sidebar-id'
        });
    }
});
1
icetique