ウィジェットのタイトルの後にウィジェットのコンテンツをラップする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>

どうすればできますか?

回答:


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

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

これは何ですか:

  • 登録されたサイドバーの設定をチェックして、2つの終了<div>sで終わるウィジェットを探します
  • タイトルがないかチェックします
  • そうでない場合は、before_widget出力を変更して、開始ウィジェットのコンテンツdivを表示します

このアプローチを使用して、ウィジェットインスタンスの設定に基づいて他の方法でサイドバーの引数を変更できます。


私はそれに問題があります:空白のままにすると、一部のウィジェット(たとえば、WPのデフォルトのウィジェット)がデフォルトのタイトルを設定します。そのため、その時点ではparamsにタイトルがないため、関数はdivを追加しますが、ウィジェットが後でそれを追加し、コードがめちゃくちゃになります。ウィジェットの「内」からタイトルを確認する方法を知っていますか?ありがとう
Cmorales 2013年

ウィジェット小切手または静かにウィジェットをレンダリングするためにいくつかの恐ろしく複雑なコードによって、ウィジェットを追加することなく、その後のタイトルのためにそれを解析していない...だと思う必要があります
sanchothefat

たぶん、このcodex.wordpress.org/Function_Reference/the_widgetにフックすると役立つでしょうか?彼らは、この記事では(他の理由で)それを使用wp.​​smashingmagazine.com/2012/12/11/...
Cmorales

1
the_widget()dynamic_sidebar()関数では使用されません。指定されたオプションを使用してウィジェットを呼び出す手段です。ただし、これはフィルター処理の別の場所なので、私のソリューションではその不測の事態をカバーしません。乾杯
sanchothefat

2

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

タイトルの問題を修正するためのコードを含む回答を追加しました。おそらくToschoとマージする必要がありますが、彼はすでに壮大な担当者を持っています:)
sanchothefat

2

@toscoと@sanchothefatの両方の答えのアイデアが好きでした。しかし、empty( $settings[ 'title' ]実際にはtrueを返す可能性がある一方で、ウィジェット自体がデフォルトのタイトルを設定していない場合、デフォルトのタイトルを出力する可能性があるため、この組み合わせに苦労しました。次に、このタイトルがbefore_titleand 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');

3
これは「テキストウィジェット」でのみ機能します
シルバームーン

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

0

以前の回答を検討した後、サンモテファトの回答で特定された問題を修正したと思います。次のようにウィジェットを定義します。

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_titleafter_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で2回ラップされます。それらを削除するには、空の文字列を返すだけです。唯一の欠点は、すべてのタイトルを手動で入力する必要があることです。

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

ここに何か足りない場合は修正してください。しかし、それはかなりしっかりしていると思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.