Добавление div для переноса содержимого виджета после заголовка виджета

10

Я пытаюсь добавить div к содержимому виджета в моей динамической боковой панели.

Вот код регистрации;

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>',
    ));

Но этот код вызывает вот так;

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

Вот что я пытаюсь сделать;

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

Как это можно сделать?

MBraiN
источник

Ответы:

18

В дополнение к ответу Toscho, вот что вам нужно для надежного решения:

// 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;
}

Из ответа Тошо:

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">',
));

Что это делает:

  • проверяем параметры для зарегистрированной боковой панели для виджетов , оканчивающихся на 2 закрывающих <div>с
  • проверяет, нет ли названия
  • если нет, он изменяет before_widgetвывод, чтобы показать div содержимого открывающего виджета

Вы можете использовать этот подход для изменения аргументов боковой панели другими способами, основанными на настройках экземпляра виджета.

sanchothefat
источник
У меня проблема с этим: некоторые виджеты (например, WP по умолчанию) устанавливают заголовок по умолчанию, если оставить это поле пустым. Итак, ваша функция добавляет div, потому что в этот момент в параметрах нет заголовка, но виджет добавляет его потом, и код испортился. Знаете ли вы, как проверить заголовок из «внутри» виджета? Спасибо
Cmorales
Не без добавления виджета с помощью проверки виджетов или какого-то ужасно сложного кода, чтобы сделать виджет молча, а затем проанализировать его на предмет заголовка ... Буду думать
sanchothefat
Может быть , поможет подключение к этому codex.wordpress.org/Function_Reference/the_widget ? Они используют это (по другой причине) в этой статье wp.smashingmagazine.com/2012/12/11/…
Cmorales
1
the_widget()не используется в dynamic_sidebar()функции, это средство вызова любого виджета с опциями, которые вы указали на месте. Это еще одно место для фильтрации, поэтому мое решение не охватывает эту возможность. Приветствия
sanchothefat
2

Добавьте второй divк параметру 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">',
    ));
Фуксия
источник
Это не удастся, если нет названия виджета - это может быть сделано, хотя
sanchothefat
Да, это не удается, когда нет названия ..
MBraiN
Я добавил ответ с некоторым кодом, чтобы исправить проблему с заголовками. Вероятно, следует объединить с Тошо, но у него уже есть эпический представитель :)
sanchothefat
2

Мне понравилась идея ответов @tosco и @sanchothefat - однако я боролся с этой комбинацией, потому что, хотя empty( $settings[ 'title' ]действительно мог бы возвращать true, сам виджет мог бы выводить заголовок по умолчанию, если ни один не установлен. Это название затем завернутые в before_titleи after_titleразметке и снова разрывах страниц. Так или иначе, с некоторыми виджетами по умолчанию.

Проще просто придерживаться стандартных параметров регистрации виджетов;

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>',
));

и затем добавьте действие фильтра согласно ответу Marventus здесь;

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
источник
3
и это работает только для «Текстовых виджетов»
Silver Moon
1

Вот что вы делаете для достижения этой цели:

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">',
    ))

Когда нет названия, вы получите:

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

Когда есть название, вы получите:

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

Чтобы убедиться, что первый пустой content-div не отображается в последнем случае, вы добавляете это в свой css:

.sidebar-box .content:empty {display:none !important;}
cjbj
источник
0

Посмотрев на предыдущие ответы, я думаю, что решил проблему, с которой Cmorales идентифицировал ответ sanchothefat. Определите ваш виджет следующим образом:

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' => ''
) );

Важно, чтобы before_titleи after_titleзначения по умолчанию были удалены. После некоторых проб и ошибок я заметил, что первый фильтр, который показывал заголовок по умолчанию, был widget_title. Затем используйте widget_titleфильтр так:

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;
}

В основном, <div class="panel-heading"><h3 class="panel-title">это мой before_titleи </h3></div>мой after_title. И наконец, используйте, dynamic_sidebar_paramsчтобы добавить закрывающий div для нашего переноса контента:

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

Это не красиво, но это работает.

спенсер
источник
Первоначально был очень взволнован этим подходом, но я столкнулся с проблемой с виджетами, которые используют esc_html ($ title) (то есть BuddyPress). В этом случае добавленный HTML-код отображается без экранирования и не отображается в интерфейсе.
Райан
0

Я просто немного изменил код, чтобы не трогать register_sidebar . Зарегистрировать боковую панель обычным способом:

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>',
));

И ниже приведен модифицированный код из решения 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;
}
Разон К.
источник
0

Как упоминалось в комментариях, некоторые основные виджеты добавляют свой собственный заголовок, который затем дважды оборачивается содержимым div. Чтобы удалить их, вы можете просто вернуть пустую строку. Единственным недостатком является то, что вы должны ввести все названия вручную.

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 );

Поправьте меня, если я что-то здесь упускаю, но я думаю, что это довольно солидно.

Azragh
источник