WordPress Create Dynamic Columns With Bootstrap

Peter Tsiampas Development 0 Comments

Situation: I was forced to use Bootstrap for a client WordPress site, I wanted the client to be able to add Widgets to a Footer Widget Area and those widgets would be rendered using Bootstrap’s row/column mark up.
I searched for a solution Online and what I found was not to my taste, to be honest I found a plethora of ugly code solutions to what seemed to be a simple problem. I even found people used jQuery to solve the problem (YUK!). My view is to code any rendering functions using the back end language, I also found solutions that used crazy if statements to create columns, once again it just seemed inflexible and rudimentary IMO.

The solution was pretty easy from a code perspective:

  1. Find out how many widgets need to be displayed.
  2. Divide that by 12 (Bootstrap’s max column markup)
  3. Then loop through each widget with the correct markup.

Most of my searching was trying to find the correct WordPress commands to get the information and then render the widget classes that were listed, Just wow what a journey. Here is a list of WP Commands I used:

  • is_active_sidebar( 'widget-area-slug' )
  • Determines if the “Sidebar” area is being used. Returns true or false.
  • wp_get_sidebars_widgets()
  • Creates an Array of sidebars with sub array of widgets. You can access the widgets using array syntax
  • register_sidebar()
  • The name of this is deceptive Sidebar makes you think of side bar on the website, but its just a widget area.

I also used a custom function (wpse_show_widget(side-bar-slug, widget-name)) that renders the correct widget by giving it the side bar slug and the widget name, I found this on Stacktrace, the guys a legend for posting it.

I finally found something that was clean and implemented dynamic columns depending on the number of widgets within the area.

I hope you find it useful.

Below is the code.

<footer class="c-layout-footer c-layout-footer-3 c-bg-dark">
    <div class="c-prefooter">
        <div class="container">
            <div class="row">
				<?php
				/* The footer widget area is triggered if any of the areas
				 * have widgets. So let's check that first.
				 *
				 * If none of the sidebars have widgets, then let's bail early.
				 */
				if ( ! is_active_sidebar( 'footer-area-widgets' ) ) {
					return;
				}

				if ( is_active_sidebar( 'footer-area-widgets' )
				) : ?>
					<?php
					$sideBarWidgets = wp_get_sidebars_widgets();
					$col_num        = floor( 12 / sizeof( $sideBarWidgets['footer-area-widgets'], true ) );
					foreach ( $sideBarWidgets['footer-area-widgets'] as $value ) {
						echo '<div class="col-sm-' . $col_num . '">';
						wpse_show_widget('footer-area-widgets', $value);
						echo '</div>';
					}
					?>
				<?php endif; ?>
            </div>
        </div>
    </div>
</footer>
// Adds a widget area.
	if (function_exists('register_sidebar')) {
		register_sidebar(array(
			'name' => 'Footer Area Widgets',
			'id' => 'footer-area-widgets',
			'description' => __( 'Footer will distribute across the footer', 'dexs' ),
			'before_widget' => '<div id="%1$s" class="c-container %2$s">',
			'after_widget'  => '</div>',
			'before_title'  => '<h3 class="c-font-uppercase c-font-bold c-font-white">',
			'after_title'   => '</h3>',
		));
	}

/**
 * Show a given widget based on it's id and it's sidebar index
 *
 * Example: wpse_show_widget( 'sidebar-1', 'calendar-2' )
 *
 * @param string $index. Index of the sidebar where the widget is placed in.
 * @param string $id. Id of the widget.
 * @return boolean. TRUE if the widget was found and called, else FALSE.
 */
function wpse_show_widget( $index, $id )
{
	global $wp_registered_widgets, $wp_registered_sidebars;
	$did_one = FALSE;

	// Check if $id is a registered widget
	if( ! isset( $wp_registered_widgets[$id] )
	    || ! isset( $wp_registered_widgets[$id]['params'][0] ) )
	{
		return FALSE;
	}

	// Check if $index is a registered sidebar
	$sidebars_widgets = wp_get_sidebars_widgets();
	if ( empty( $wp_registered_sidebars[ $index ] )
	     || empty( $sidebars_widgets[ $index ] )
	     || ! is_array( $sidebars_widgets[ $index ] ) )
	{
		return FALSE;
	}

	// Construct $params
	$sidebar = $wp_registered_sidebars[$index];
	$params = array_merge(
		array( array_merge( $sidebar, array('widget_id' => $id, 'widget_name' => $wp_registered_widgets[$id]['name']) ) ),
		(array) $wp_registered_widgets[$id]['params']
	);

	// Substitute HTML id and class attributes into before_widget
	$classname_ = '';
	foreach ( (array) $wp_registered_widgets[$id]['classname'] as $cn )
	{
		if ( is_string($cn) )
			$classname_ .= '_' . $cn;
        elseif ( is_object($cn) )
			$classname_ .= '_' . get_class($cn);
	}
	$classname_ = ltrim($classname_, '_');
	$params[0]['before_widget'] = sprintf($params[0]['before_widget'], $id, $classname_);
	$params = apply_filters( 'dynamic_sidebar_params', $params );

	// Run the callback
	$callback = $wp_registered_widgets[$id]['callback'];
	if ( is_callable( $callback ) )
	{
		call_user_func_array( $callback, $params );
		$did_one = TRUE;
	}

	return $did_one;
}

Leave a Reply

Your email address will not be published. Required fields are marked *