Missing sidebar parameter “fix” – before_content

as you know the sidebar parameters from register_sidebar() that control the widget layout are

- before_widget
- after_widget
- before_title
- after_title

the problem is that you cannot implement certain type of designs because a parameter like ‘before_content‘ is missing.

Read More

for example:

<div class="container">
  <div class="title">
    title  
  </div>
  <div class="content">
    content
  </div>
</div>

a HTML structure like this is only possible if you add <div class="content"> in the after_title parameter. The problem is that if you do this, widgets without titles will break the page layout 🙁

so is there a solution to somehow add that <div class="content"> after div.title, or after div.container if title is missing?

Related posts

Leave a Reply

1 comment

  1. This code detects whether a title has been set, and if not, it changes the before_widget argument.

    add_filter( 'widget_display_callback', 'wpse4213_widget_display_callback', 10, 3 );
    function wpse4213_widget_display_callback( $instance, $widget, $args )
    {
        if ( empty( $instance['title'] ) ) {
            $args['before_widget'] = '<div class="container"><div class="content">';
            $widget->widget( $args, $instance );
            return false;
        }
        return $instance;
    }
    

    This code works because the widget_display_callback allows you to return false if you don’t want to display the widget. In this case we display the widget ourselves, so we don’t want WordPress to do it again. A hack, but it works.

    This function will fail if the widget supplies a default title (like most widgets bundled in the core distribution do). To detect this, I also created a function that first tries to render the widget in an output buffer. If we detect a title element in this output buffer the widget did have a default title – so we ignore the buffer and display it like a regular widget. But this can also break when the widget uses overactive caching, so we must try to flush that too. Did I mention this is a hack?

    add_filter( 'widget_display_callback', 'wpse4213_widget_display_callback', 10, 3 );
    function wpse4213_widget_display_callback( $instance, $widget, $args )
    {
        if ( empty( $instance['title'] ) ) {
            $args['before_widget'] = '<div class="container"><div class="content">';
            ob_start();
            $widget->widget( $args, $instance );
            $widget_content = ob_get_contents();
            ob_end_clean();
            if ( false !== strpos( $widget_content, 'widget-title' ) ) {
                // It did return a title!
                if ( method_exists( $widget, 'flush_widget_cache' ) ) {
                    $widget->flush_widget_cache();
                }
                return $instance;
            }
            echo $widget_content;
            return false;
        }
        return $instance;
    }