Create Widgetized Front Page – Tutorial


In the slack channel we (Paal, Rose and I) have been discussing ways to create a home page similar to many of the Genesis 'pro' home pages. The landing page sort that contain widgets to easily add landing page content from the customiser etc.

I've adapted a fair few of the Genesis themes in my time (Agency-pro, Atmospher-pro etc), so figured could take the same approach, but should be easier given the amazing Beans HTML and Actions APIs.

I wasn't wrong.

Widgetized Beans child theme with the basic concept working can be found here: https://github.com/JeffCleverley/WidgetizedBeans

The github repo contains a lot more inline commenting. I've removed that and things like namespacing for simplicity here.

Step 1. Register the Widget Areas

I put this directly in the functions.php for this tutorial, please put it wherever you keep your your functions.

First need to define a few of the constants the callbacks will be using:

define( 'CHILD_TEXT_DOMAIN', 'beans-learning-curve');
define( 'CHILD_THEME_DIR', get_stylesheet_directory() );

Then use beans_register_widget_area() to register the widgets. I've used array_map instead of a foreach loop.

add_action( 'widgets_init', 'wb_register_widget_areas' );
/**
 * Register the home page widget areas.
 *
 * @return void
 */
function wb_register_widget_areas() {

    $widgets_areas = array(
        array(
            'name'        => __( 'Home Top', CHILD_TEXT_DOMAIN ),
            'id'          => 'home-top',
            'description' => __( 'This is the top widget area on the landing page.', CHILD_TEXT_DOMAIN )
        ),
        array(
            'name'        => __( 'Home Middle', CHILD_TEXT_DOMAIN ),
            'id'          => 'home-middle',
            'description' => __( 'This is the middle widget area on the landing page.', CHILD_TEXT_DOMAIN )
        ),
        array(
            'name'        => __( 'Home Bottom', CHILD_TEXT_DOMAIN ),
            'id'          => 'home-bottom',
            'description' => __( 'This is the bottom widget area on the landing page.', CHILD_TEXT_DOMAIN )
        ),
    );

    array_map( 'beans_register_widget_area', $widgets_areas  );
}

https://www.getbeans.io/code-reference/functions/beans_register_widget_area/ https://secure.php.net/manual/en/function.array-map.php

Step 2. Create the Front Page Template and display the widgets

2.1 Create the template

In your theme directory add a new file:

front-page.php

2.2 Check to see if any of the home page widgets are active - if they are, then do stuff

In your front-page.php file add the following:

if ( is_active_sidebar( 'home-top' ) || is_active_sidebar( 'home-middle' ) || is_active_sidebar( 'home-bottom' ) ) {

    beans_replace_attribute( 'beans_primary', 'class', 'uk-width-medium-3-4', 'uk-container-center' );

    beans_modify_action_callback( 'beans_loop_template', 'wb_display_home_widget_layout' );

}

https://developer.wordpress.org/reference/functions/is_active_sidebar/ https://www.getbeans.io/code-reference/functions/beans_replace_attribute/ https://www.getbeans.io/documentation/using-actions/ https://www.getbeans.io/code-reference/functions/beans_modify_action_callback/

Use the WordPress is_active_sidebar() function to check to see if the home widgets are active.

If they are then the following happens

beans_replace_attributes() removes the UIKit uk-width-medium-3-4 class that limits the primary content area to 3/4 width, and replaces it with a full width centralised class - uk-container-center.

beans_modify_action_callback() removes and replaces the beans loop callback with my own callback that sets up the home page layout and then calls the function to render the widgets.

This Action API callback and it's brethren are amazing. With Genesis I needed to unhook a bunch of stuff but to do that, knowing the hook and specific callback, here I just replace the original callback with my new one.

2.3 Setup Home Page Layout and Render Widgets

First, the callback that sets up the home page layout contains a filter that calls a function to set the beans layout for the front-page. Then I create an array with the IDs of each of the registered widgets, then use array_map() to pass each of the items in the array to a function that will render them out.

function wb_display_home_widget_layout() {

    add_filter( 'beans_layout', 'wb_set_full_width_layout' );

    $home_widgets = [ 'home-top', 'home-middle', 'home-bottom' ];

    array_map( 'wb_render_home_page_widgets', $home_widgets );
}

https://secure.php.net/manual/en/function.array-map.php

Next we have the function that is used by array_map() to render each of the widgets. It does a check to make sure that this widget is active using the same function as earlier. If it is active, it loads a view that will display the widgets and markup.

function wb_render_home_page_widgets( $home_widget ) {

    if ( is_active_sidebar( $home_widget ) ) {
        include CHILD_THEME_DIR . '/views/home-widgets.php';
    }
}

https://developer.wordpress.org/reference/functions/is_active_sidebar/

We also add the callback function that will force the full width layout.

function wb_set_full_width_layout() {

    return 'c';
}

https://www.getbeans.io/code-snippets/force-a-layout

Don't forget to run Beans at the bottom

beans_load_document();

Step 3. Create the view to display the widgets

Create a new directory called views with the following path:

/beans-child-theme/views/

In this directory, add a view file. I called mine home-widgets.php.

In this file add the following:

<div class="uk-container uk-container-large uk-container-center <?php echo $home_widget; ?> widget-wrap">
    <?php echo beans_widget_area( $home_widget ); ?>
</div>

https://www.getbeans.io/code-reference/functions/beans_widget_area/

This view is loaded for each $home_widget, this variable stores the ID for the registered and active home widget. It is used to render out the widget area using thebeans_widget_area() function, and it is also used to add a css class to style the widget area.

Step 4. A little bit of styling

In the theme style.css file I added a bit of styling to separate out the widgets.

.home-top.widget-wrap,
.home-middle.widget-wrap,
.home-bottom.widget-wrap {
    padding: 30% 10%;
    background: white;
    text-align: center;
    margin: 10% auto;
}

Done

In the Gitbub repo the code varies slightly, it is namespaced so the callbacks are named differently, and it contains a lot of inline comments taking the reader through it step by step.

Because it has used all the Beans functions, this all works fine with the customiser. It is very basic, the child theme structure hasn't been modularised at all. Any feedback, forks, reviews, suggestions are welcomed.

Write a reply

Login or register to write a reply, it's free!