Incluindo uma div para quebrar o conteúdo do widget após o título do widget

10

Estou tentando adicionar uma div ao conteúdo de um widget na minha barra lateral dinâmica.

Aqui está o código de registro;

register_sidebar(array(
        'name' => "Sidebar1",
        'id' => 'home-sidebar-1',
        'before_widget' => '<div class="sidebar-box">',
        'after_widget' => '</div>',
        'before_title' => '<div class="title">',
        'after_title' => '</div>',
    ));

Mas esse código causa assim;

<div class="sidebar-box">
    <div class="title">{WIDGET TITLE}</div>
     {WIDGET CONTENT}
</div>

Aqui está o que estou tentando fazer;

<div class="sidebar-box">
    <div class="title">{WIDGET TITLE}</div>
    <div class="content">
           {WIDGET CONTENT}
    </div> 
</div>

Como pode ser feito?

MBraiN
fonte

Respostas:

18

Além da resposta de Toscho, aqui está o que você precisa para uma solução robusta:

// if no title then add widget content wrapper to before widget
add_filter( 'dynamic_sidebar_params', 'check_sidebar_params' );
function check_sidebar_params( $params ) {
    global $wp_registered_widgets;

    $settings_getter = $wp_registered_widgets[ $params[0]['widget_id'] ]['callback'][0];
    $settings = $settings_getter->get_settings();
    $settings = $settings[ $params[1]['number'] ];

    if ( $params[0][ 'after_widget' ] == '</div></div>' && isset( $settings[ 'title' ] ) && empty( $settings[ 'title' ] ) )
        $params[0][ 'before_widget' ] .= '<div class="content">';

    return $params;
}

Da resposta de Toscho:

register_sidebar(array(
    'name' => "Sidebar1",
    'id' => 'home-sidebar-1',
    'before_widget' => '<div class="sidebar-box">',
    'after_widget' => '</div></div>',
    'before_title' => '<div class="title">',
    'after_title' => '</div><div class="content">',
));

O que isso faz é:

  • verifica as configurações da barra lateral registrada em busca de widgets que terminam em 2 <div>s de fechamento
  • verifica se não há título
  • caso contrário, ele modifica a before_widgetsaída para mostrar a div de conteúdo do widget de abertura

Você pode usar essa abordagem para alterar os argumentos da barra lateral de outras maneiras, com base nas configurações da instância do widget.

sanchothefat
fonte
Eu tenho um problema com isso: alguns widgets (como os padrão do WP, por exemplo) definem um título padrão se você deixar em branco. Portanto, sua função adiciona a div porque não há um título nos parâmetros nesse momento, mas o widget a adiciona posteriormente e o código é confuso. Você sabe como verificar o título "dentro" do widget? Obrigado
Cmorales
Não sem adicionar um widget por cheque widget ou algum código terrivelmente complexa para processar o widget silenciosamente, em seguida, analisá-lo para um título ... Vai ter um pensar
sanchothefat
Talvez se prender a este codex.wordpress.org/Function_Reference/the_widget ajudaria? Eles o usam (por outro motivo) neste artigo wp.smashingmagazine.com/2012/12/11/…
Cmorales
11
the_widget()não é usado na dynamic_sidebar()função, é um meio de chamar qualquer widget com as opções especificadas no local. É outro lugar para filtrar, portanto, minha solução não cobre essa eventualidade. Cheers
sanchothefat
2

Adicione o segundo divao parâmetro title:

register_sidebar(array(
        'name' => "Sidebar1",
        'id' => 'home-sidebar-1',
        'before_widget' => '<div class="sidebar-box">',
        'after_widget' => '</div></div>',
        'before_title' => '<div class="title">',
        'after_title' => '</div><div class="content">',
    ));
fuxia
fonte
Isso falha se não houver título do widget - mas pode ser feito
sanchothefat 3/12/12
Sim, falha quando não há título ..
MBraiN 3/12/12
Adicionei uma resposta com algum código para corrigir o problema dos títulos. Provavelmente deve ser mesclado com Toscho de realmente mas ele tem rep épica já :)
sanchothefat
2

Gostei da ideia das respostas @tosco e @sanchothefat - no entanto, lutei com essa combinação porque, embora empty( $settings[ 'title' ]possa realmente retornar verdadeiro, o widget em si pode gerar um título padrão se nenhum estiver definido. Este título é então envolto nos before_titlee after_titlede marcação e, novamente, as quebras de página. Esse é o caso de alguns dos widgets padrão de qualquer maneira.

Mais fácil de seguir os parâmetros de registro padrão do widget;

register_sidebar(array(
    'id' => 'sidebar1',
    'name' => __( 'Sidebar 1', 'bonestheme' ),
    'description' => __( 'The first (primary) sidebar.', 'bonestheme' ),
    'before_widget' => '<div class="block">',
    'after_widget' => '</div>',
    'before_title' => '<div class="block-title">',
    'after_title' => '</div>',
));

e adicione uma ação de filtro conforme a resposta de Marventus aqui;

http://wordpress.org/support/topic/add-html-wrapper-around-widget-content

function widget_content_wrap($content) {
    $content = '<div class="block-content">'.$content.'</div>';
    return $content;
}
add_filter('widget_text', 'widget_content_wrap');
rabmcnab
fonte
3
e isso funciona apenas para "Widgets de texto"
Silver Moon
1

Aqui está o que você faz para conseguir isso:

register_sidebar(array(
        'name' => "Sidebar1",
        'id' => 'home-sidebar-1',
        'before_widget' => '<div class="sidebar-box"><div class="content">',
        'after_widget' => '</div></div>',
        'before_title' => '</div><div class="title">',
        'after_title' => '</div><div class="content">',
    ))

Quando não houver título, você receberá:

<div class="sidebar-box"><div class="content">
{CONTENT}
</div></div>

Quando houver um título, você receberá:

<div class="sidebar-box"><div class="content">
</div><div class="title">
{TITLE}
<div class="content">
{CONTENT}
</div></div>

Para garantir que o primeiro content-div vazio não seja exibido no último caso, adicione-o ao seu css:

.sidebar-box .content:empty {display:none !important;}
cjbj
fonte
0

Depois de analisar as respostas anteriores, acho que resolvi o problema que Cmorales identificou com a resposta de sanchothefat. Defina seu widget da seguinte maneira:

register_sidebar( array(
    'name' => 'Sidebar',
    'id' => 'sidebar',
    'before_widget' => '<div class="panel panel-default %2$s" id="%1$s">',
    'after_widget' => '</div>',
    'before_title' => '',
    'after_title' => ''
) );

É importante que os padrões before_titlee after_titlesejam removidos. Após algumas tentativas e erros, observei que o primeiro filtro que mostrava um título padrão era widget_title. Em seguida, use o widget_titlefiltro da seguinte maneira:

function widget_title( $title ) {
    if ( $title )
        $title = '<div class="panel-heading"><h3 class="panel-title">' . $title . '</h3></div>';
    $title .= '<div class="panel-body">';
    return $title;
}

Basicamente, <div class="panel-heading"><h3 class="panel-title">é meu before_titlee </h3></div>é meu after_title. Por fim, use dynamic_sidebar_paramspara acrescentar uma div de fechamento ao nosso pacote de conteúdo:

function dynamic_sidebar_params( $params ) {
    $params[0]['after_widget'] = '</div>' . $params[0]['after_widget'];
    return $params;
}

Não é bonito, mas funciona.

Spencer
fonte
Estava inicialmente muito empolgado com essa abordagem, mas tive um problema com widgets que usam esc_html ($ title) (ou seja, BuddyPress). Nesse caso, o HTML adicionado é exibido como escapado e não renderizado no front-end.
Ryan
0

Eu apenas altero levemente o código para não precisar tocar em register_sidebar . Registre uma barra lateral de maneira regular:

register_sidebar(array(
    'name' => "Sidebar1",
    'id' => 'home-sidebar-1',
    'before_widget' => '<div class="sidebar-box">',
    'after_widget' => '</div>',
    'before_title' => '<div class="title">',
    'after_title' => '</div>',
));

Abaixo está o código modificado da solução da Sanchothefat:

/**
 * If no title given then add widget-content wrapper to before_widget
 * If title given then add content wrapper to before_widget
*/
add_filter('dynamic_sidebar_params', 'check_widget_template');
function check_widget_template($params){
    global $wp_registered_widgets;

    $settings_obj = $wp_registered_widgets[$params[0]['widget_id']]['callback'][0];
    $the_settings = $settings_obj->get_settings();
    $the_settings = $the_settings[$params[1]['number']];

    if (isset($params[0]['id']) && $params[0]['id'] == 'home-sidebar-1') {
        if (!isset($the_settings['title']) && empty($the_settings['title'])) {
            $params[0]['before_widget'] .= '<div class="widget-inner">';
            $params[0]['after_widget']  .= '</div>';
        } else {
            $params[0]['after_widget']  .= '</div>';
            $params[0]['after_title']   .= '<div class="widget-inner">';
        }
    }

    return $params;
}
Razon K.
fonte
0

Como mencionado nos comentários, alguns widgets principais adicionam seu próprio título, que são agrupados duas vezes com a div de conteúdo. Para removê-los, você pode simplesmente retornar uma string vazia. A única desvantagem é que você deve inserir todos os títulos manualmente.

function remove_default_widget_title( $title, $instance = [], $id = '' ) {
    if ( isset($instance['title']) && trim($instance['title']) == '' ) {
        return '';
    }
    return $title;
};
add_filter( 'widget_title', 'remove_default_widget_title', 10, 3 );

Corrija-me se estiver faltando alguma coisa aqui, mas acho que é bastante sólido.

Azragh
fonte