Adding Layout Settings with Beaver Builder v1.7

TL;DR – BB1.7 has a new Layout Settings panel and here’s how you can add things to it!

Disclaimer – This article discusses prerelease software that should not be used on production sites until the released version is available.

Beaver Builder 1.7 (beta1 at the time of writing) offers a number of new things to make your layout creations even more beautiful but there’s one subtle unmentioned change that I think can have a really big impact. 1.7 introduces the Layout Settings panel. This panel, by default, allows you to add css and javascript that applies to just the page you’re working on. This is great because it gives you a quick-access place to add per-page styles and scripts and you can see the effects of the css as you type, something I’ve always used extra plugins for. This data travels with your template should you export it and import it into another site or simply save it and add it to another page. But what really makes this a BIG DEAL is what else we can add to the layout settings panel.

bb-layout-settings

I’ve been a fan of Advanced Custom Fields for a long time, especially since v5, and nearly every site I build needs some sort of custom metadata saved to each post or the site as a whole. A lot of times it is decisions like whether or not to show the header on a specific page, or maybe overlay the header on the hero image for pages that have one. While ACF is great, when the lever or knob you need to work with is on the page edit screen and you’re inside Beaver Builder doing layout work, it’s kind of a drag to leave the page or open a new tab to get at it. Enter layout settings.

Because there is now a settings panel on the layout itself (previously we only had global settings), we can add fields that have to do with that page’s design directly on the layout rather than on the post.

If you’re familiar with the programming concept of Model-View-Controller (MVC) you’ll see why this is a really good thing. In MVC terms, a post (or page, same thing) is the model; It’s the actual object that exists with no understanding of its own presentation. That means, in the Beaver Builder scenario, that a layout is the view – simply a layer of presentation that interprets a model within a given context. So if you think about our header setting example above, that’s actually a view’s concern, not a model’s. It only deals with how the design is rendered. It makes sense to be a setting on the Layout instead the post.

In addition to being properly structured there’s also the benefit of it simply being handy. When you’re in Beaver Builder, you can find the layout settings panel by clicking Tools > Layout Settings, so whenever you’re editing you don’t have to go far to adjust them.

Another benefit is that this data will travel with your layout rather than remain on the post. This may not seem like a big deal if you never move pages around from one site to another but it’s really important if you plan on having a WordPress install survive more than one design in its lifespan. It is also important if you plan on user testing multiple designs. One of the problems that often arises in WordPress themes is that themers base their css on brittle structures. For example, when you select a page as your ‘front page’ it is given a body class of ‘home’. This seems great cause it gives you something to hang your homepage styles off of. But what happens when you want to try another homepage design? You have a bunch of styles that may conflict hanging around. Or what happens when your marketing manager walks in and asks for another page just like the homepage but no-indexed so he can send PPC traffic to it and track it independently? All of your styling is hanging off of a class that won’t be there on the new page. This is not future-proof because the layout/styling decisions were hung on a structure that isn’t the layout itself. By adding design metadata directly to the layout, we can now have as many pages that look like that design as we want and they styling won’t break.

Hopefully you’re sold on why it’s good. If you aren’t, come talk to me. But lets jump into how we add settings to the layouts panel. This can be done from either a plugin or theme. If you’re in a theme, add the following code to your functions.php file. If you’re in a plugin, add it to your main file (or any included php file).

Filtering The Settings Form

Getting new settings onto the panel is as simple as knowing what filter to use. Beaver Builder passes all its settings forms through a single filter so we have a chance to modify them before they get rendered.

<?php
function demo_filter_settings_form($form, $id) {
    if ($id === 'layout') {
        // Modify the form array however we want
        $my_tab = array(
            'general' => array(
                'title' => 'General',
                'sections' => array(
                    'title' => 'My Cool Settings',
                    'fields' => array(
                        'header_style' => array(
                            'label' => 'Header Style',
                            'type' => 'select',
                            'options' => array(
                                '' => 'Default',
                                'hidden' => 'Hide Header',
                                'overlay' => 'Overlay Header'
                            )
                        )
                    )
                )
            )
        );
        $form['tabs']['my_tab'] = $my_tab;
    }
    return $form;
}
add_filter('fl_builder_register_settings_form', 'demo_filter_settings_form', 10, 2);
?>

Ok that’s a lot of nested arrays but when you read through it, its not that complicated what we’re doing. The filter is giving us the $form array as well as the $id of which form it is. The only $id we care about right now is the ‘layout’, so we listen for that. Then we construct a nested array for a new tab. Tabs have sections, sections have fields. Lastly we add our new tab to our $form[‘tabs’]. And assuming I’ve typed that in correctly, boom, we have a select box on our layout settings panel. Go try it. Maybe even go nuts and make two fields. Incidentally we could also set global fields by just testing for the ‘global’ $id instead.

layout-settings-header

So now what? How do we use the data we’ve saved? There are a few things we might want to do. We might want to use our setting to set a class on the body tag that we can use to style against. Or we might want to write some custom css into that page’s stylesheet based on our setting’s value. Here’s an example of each:

<?php
// Add <body> class based on setting
function demo_filter_body_class($classes) {
    $settings = FLBuilderModel::get_layout_settings();
    if ($settings->header_style) {
        $style = $settings->header_style;
        $classes[] = "header-style-$style";
    }
    return $classes;
}
add_filter('body_class', 'demo_filter_body_class');
?>

Or if you wanted to add some css to the page stylesheet, you could do something like this:

<?php
// Add CSS Styles to this page's stylesheet
function demo_filter_render_css($css, $nodes, $global_settings) {
    $settings = FLBuilderModel::get_layout_settings();
    if ($settings->header_style == 'overlay') {
        $css .= 'header { position:fixed; top:0; left:0; right:0; }';
    }
    return $css;
}
add_filter('fl_builder_render_css', 'demo_filter_render_css', 10, 3);
?>

Those are just a few things you might want to do with a setting but these come up a lot for me.

Hierarchical Settings, Learn to Love Them

If we really want an elegant settings system, we need a hierarchy. What we want is to set the default behavior for all pages, and then just change the ones that are different. In the past, I’ve always accomplished this by having a WordPress option field and a post meta field to match. You want the most specific value to win, so you check post meta, and if there’s no value set, then you check your site-wide option. But now we can do the exact same thing between Beaver Builder’s global settings and layout settings. Simply add the same fields to both the global ($id = ‘global’ ) settings panel and the layout settings panel, and then when you go to pull your settings out and use them, check the layout settings first, and if there’s no value check the global. You could even make it easy on yourself and wrap it up in a function.

function get_builder_setting($key, $default_value) {
    $layout_settings = FLBuilderModel::get_layout_settings();
    $global_settings = FLBuilderModel::get_global_settings();
    if ($layout_settings->{$key}) {
        return $layout_settings->{$key};
    } else if ($global_settings->{$key}) {
        return $global_settings->{$key};
    }
    return $default_value;
}

Now just do the same things we did in the examples above but call your function with the name of your setting to get the value and it will check from most-specific to least, ending finally in your default value if you set one. Hope this helps you think about ways of extending Beaver Builder to fit your workflow. If you have any questions or my code examples aren’t working (oops) I’m happy to help. Come visit the Beaver Builder slack channel. I’m around quite a bit and there are lots of helpful BB fans to answer questions!

Advertisements

Leave a Reply

Required fields are marked *.

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s