Developing for Gutenberg vs Beaver Builder

I want to start by saying that I didn’t want to do a Gutenberg vs Beaver Builder comparison, since in their current state I don’t see them as direct competitors. However developing for both tools is different enough I decided to write a comparison between developing for Gutenberg vs Beaver Builder, and why my preference is Beaver Builder.

Despite my preference of developing for Beaver Builder I think Gutenberg is a dramatic improvement over the classic editor and will be the foundation of a new era for WordPress, and you can read more about that in my WordPress Gutenberg Review.

My Development Environment

I’d like to give an overview of my two primary development environments as this is part of the basis for my preferences.

  • Personal Development Environment
    • I regularly work on a Mac OS X computer and Windows 10 computer. I use OneDrive to share all of my files between the two computers. Each are setup with Node, PHP, Phing, Git, etc. I develop directly on my dev web server (ssh-on-save) and then build and deploy where necessary. This allows me to move from one computer to another with no interruption, and no need to maintain a XAMP stack on each local computer.
  • Work Development Environment
    • My work environment is very similar, except that I’m working exclusively on a Windows 10 computer and all files are saved on a local network drive so that they can be shared with co-workers. We’re utilizing a dev/stage/prod server setup there as well (with ssh-on-save to dev).

Programming Languages

I also want to make it clear that I love both PHP and JavaScript and enjoy working with them both on a daily basis. The one caveat is that I question if JavaScript development is heading in the right direction. The features being added to JavaScript (at a rapid pace) are fantastic, but with the advent of NPM, and the desire to use modern features (not always supported by browsers yet), a need for build tools has become the norm and dramatically increased project complexity. For several years there was a growing sense across the web development community that jQuery was gross and added bloat to a site and that clean vanilla JS was superior (I don’t necessarily disagree), yet today we seem to have no problem including Bootstrap, React, Redux, among whatever other dependencies we need. This doesn’t even touch on the 1,500+ files used to create a “Hello World” React app (using create-react-app). All of that is to say that I question the wisdom of following suit with the WordPress editor, and my skepticism certainly affects my preferences between developing for Gutenberg vs Beaver Builder.

Why I Prefer Creating Modules Over Creating Blocks

Developer Reference

When learning to develop for a new tool one of the most important things is developer/API reference and examples. Both Gutenberg and Beaver Builder have solid developer reference, however in general I feel that Beaver Builder’s is better organized. Its examples in the reference (and the modules within the plugin itself) are also a great source of reference and the vast majority of the time code can be copied directly into your own custom modules and it will work. Conversely, Gutenberg is attempting to remain as developer friendly as possible and has provided reference in ES5 and ESNext (ES6+ and JSX), but there isn’t always example code in both versions, and there isn’t always context surrounding the code letting you know where/how it should be used.

Build Tools

If you’re serious about making Gutenberg blocks it’s all but mandatory to use build tools (node/webpack/babel/etc). Without this your project could end up enqueuing dozens of JS and CSS files, and none of the ESNext/JSX code will run in the browser. Getting your project setup to properly use these build tools is one of the biggest hurdles to get past when first starting out with Gutenberg, especially if you’re not already using them for other projects (such as React). As mentioned earlier I work off of a remote development server so this type of workflow isn’t ideal as I have to build (or have webpack watching my files and auto-build) and then upload them to my remote server to test. This adds an extra step and is less efficient, and if anyone has any recommendations as to how I could improve this workflow please leave a comment!

Alternatively, with Beaver Builder there is no need for build tools as there is no need for ESNext (unless you just really want to use it) or JSX. On top of that, to prevent dozens of JS and CSS files from being enqueued Beaver Builder renders out all of the necessary dependencies for a given page and caches that as a single JS and CSS file on the web server. So, as long as a module has been built correctly it’s as simple as editing your files, and saving them, and Beaver Builder handles the rest.

Programming Language

The vast majority of code for Gutenberg blocks is intended to be in JavaScript. This is fine in many cases, however it also means that any data used in BlockControls or InspectorControls that cannot be derived from the content itself, or is dynamic in nature must be piped to the front-end. So, any existing code bases where the data already exists in PHP must either be modified to make it available on the front-end (possibly by localizing it) or extend the Rest API so that it can be fetched. In an of itself this isn’t a problem, but it can add development time to a project.

Alternatively, Beaver Builder controls are defined in PHP as a series of nested arrays and they can be dynamically built using data already available in PHP, with no need for extending the WP Rest API or making Ajax API calls. This has been beneficial for me in several projects over the years I’ve used Beaver Builder as I was able to take an existing PHP app and build a Beaver Builder module for it with very little code duplication by utilizing the apps existing APIs.

Rigging a Block or Module

In order to setup the skeleton for a block you need to add necessary fields (components/elements) to a BlockControls or InspectorControls component and then setup all necessary event listeners. This is both a pro and a con as it gives you complete control over how everything is setup, but you also need to setup everything to make sure the state is updated as inputs change.

On the other hand, with Beaver Builder, rigging up a module is as simple as creating nested arrays that define the controls and their behavior – the vast majority of the time there is no need to worry about module state or event handling as that’s all taken care of by Beaver Builder itself. Once in a great while I’ve found the need to create my own field types, but that’s been a rarity. It’s so incredibly easy to setup advanced/complex input controls, such as repeatable sets of controls (called forms, that are re-usable throughout a project, in Beaver Builder).

Experience and Familiarity

Without any doubt I have more experience creating modules for Beaver Builder than creating blocks for Gutenberg. This is largely due to Beaver Builder being around several years longer than Gutenberg. Regardless, as open minded, and objective, as I’m trying to be about Gutenberg this experience, and familiarity, creates a natural bias towards Beaver Builder and this is something of which I’m very well aware. The flip-side of this is that once Gutenberg has been around for as long as Beaver Builder it has huge potential to be much more than it is right now.

The End Product

Gutenberg is now part of the WordPress core so it’s incredibly appealing to developers (including myself) to use a standard that is likely to be a part of WordPress for many years to come. On top of that blocks are super portable between instances of WordPress since there are no plugin dependencies. This is an undeniable benefit of Gutenberg over any third-party page builder product. Lastly, there will naturally be more designers, developers, and editors within the community than any plugin could ever hope to attract.

In spite of how I began this review, stating that I didn’t want to directly compare Gutenberg to Beaver Builder, it’s difficult not to when comparing the end product of a block vs a module and the environment in which each resides. Another way of putting it is that the sum of the editing experience is comprised of more than a single block or module, no matter how great they may be, but rather by the experience of using the editor or page builder as a whole. In each of their current states Beaver Builder has immeasurably more flexibility and features than Gutenberg and I know that my custom modules can easily be used in countless different ways.

In the end, I actually do enjoy creating blocks for Gutenberg; I just prefer creating modules for Beaver Builder.

WordPress Gutenberg Review

I think it’s important to know the history of my experience with WordPress in order to understand the basis for opinions, so this is where I will begin my WordPress Gutenberg review. I had my first real introduction to WordPress in 2012 when I made a site for a client that needed an easy to use CMS. My overall impression with WordPress at the time was overwhelmingly positive, however there was one point of contention – the editor. It wasn’t necessarily the fault of the editor as much as it was CMS’s in general, but I was surprised that there wasn’t an easy way to arrange and layout content in anything other than vertically linear. I ended up needing to place some custom HTML markup in the editor as part of the page content, which didn’t meet my goal of all content being easily editable by the site owner.

A little over a year later I once again found myself in the same situation, only this time the goal of all content being easily editable by the site editor(s) and owner(s) was now a requirement as I was working in a distributed environment with many content editors, most of which having no web development experience. I began researching the various ways to extend the editing experience and found it quite lacking – needing to cobble together various plugins, shortcodes, menus, widgets, custom post types, post meta and metaboxes, and custom page templates to make it all work. It did work, however even after training content editors they still struggled to understand how to edit site content and where it all lived within the WordPress admin.

The Rise of Page Builders

A little over a year later I began hearing about new WordPress plugins called Page Builders, such as Visual Composer, Divi, and Beaver Builder. In the end I decided on Beaver Builder and haven’t looked back since. With Beaver Builder, in many cases, I no longer needed other plugins (aside from the core list used on all sites), shortcodes, widgets, custom post types, post meta or metaboxes, or even custom page templates. It allowed me to style the site using brand guidelines and then turn it over to the site content editors where they were able to edit their content on one place, right on the page and on the front-end. It allowed me to separate concerns considerably between the responsibilities of developers and content editors, while still providing the editors with a huge amount of flexibility.

There were those in the WordPress community that looked down on page builders, seeing them as inferior to the custom code ways of the past. I can’t say that I blame them either; many of us had poor experiences with tools like DreamWeaver (or Microsoft FrontPage) and had lost trust in visual editors to build our HTML markup. Despite that, plugins like Beaver Builder worked incredibly well and output clean markup, and from my perspective page builders were obviously the future of website creation and editing in WordPress. There were simply too many benefits to Page Builders for them to not become mainstream.

Finally A New Editor Arrives: Gutenberg

With the rise in popularity of page builder plugins and a plethora of site building services such as Wix, Weebly, and Squarespace, among many others, WordPress needed to do something to stay competitive. The answer to this was: Gutenberg. Now, without any further introduction, here is my review of the Gutenberg editor, organized by role and broken down into pro/con lists.

From The Perspective of a Content Editor

Pros

  • User Interface Design: Though it is completely new, the design of the user interface fits very well with the rest of the WordPress admin and should help users to feel comfortable using the new editor.
  • User Interface Responsiveness: Since the entire Gutenberg interface is built using JavaScript it feel quick and responsive, even with dynamic elements.
  • User Interface Standardization: Prior to Gutenberg users may need to work with several different interfaces in order to edit their site, such as menus, widgets, metaboxes, settings pages, etc. With Gutenberg everything can now use the same interface: the block. This isn’t fully implemented yet, as of WordPress 5.0, but it’s already in the works and will drop in the next few major releases.
  • Design and Layout Abilities: Gutenberg offers page-builder-like features for content layout and style. Though relatively limited as of WordPress 5.0 I expect this to expand in the future as the next phase(s) of Gutenberg are implemented and third-party plugins are created.
  • Editor Tools: In order to assist users in crafting higher quality content there are at least two new tools available in Gutenberg. The first is Content Structure, which includes general information about the post and a Document Outline, which helps ensure headings are used properly. The second is a subtle accessibility notice when the color contrast between a block text color and background/cover color isn’t high enough to meet WCAG 2.0 AA or AAA specifications.

All of these things help to bring WordPress at least up to par with competitors, while also preparing it for the future.

Cons

  • User Experience:
    • On first impression I was quickly left feeling that it’s rather clunky and requires a lot of clicks to accomplish tasks. This will be explained in further detail below.
    • User Interface elements are hidden until hover/focus/save/etc. There needs to be a balance between keeping the interface simple and clean and showing users what they need, Gutenberg goes a little too far by hiding elements.
      • The block positioning controls (the drag handle) is only visible when hovering on the left 25% of a block. This should always be visible when a block has focus or is being hovered over (regardless of mouse position).
      • The block insert button (small + at the top center of a block) will only show if a block doesn’t presently have focus and if the mouse is hovered along the top edge of the block. The block already doesn’t have focus so the BlockControls will be hidden (and thus won’t interfere with the insert button) so the insert button should be visible regardless of mouse position.
    • When repositioning a block by dragging it up or down the drop-zone isn’t inline with the handle (on the left) so you actually have to move the mouse inward (closer to the center of the blocks), despite the fact that blocks (for the most part) stack vertically (which implies vertical repositioning), which makes the experience feel broken if you simply drag a block straight up and release (as it won’t work).
  • Specific Block Issues:
    • Columns: they’re are incredibly cumbersome to work with (clicking around in just the right spot to finally select the column itself to change its settings is a joke), and blocks within the columns block lose their drag handle so once a block is in a column it’s there for good (or until you delete it and make it again somewhere else). Also, during my time testing the columns block I also experienced a hard crash when I attempted to drag the column block into a drop-zone of the column block that I was moving and my browser tab closed and ended up losing a bit of work that was unsaved. All of this is inexcusable as the columns block is one of the few blocks that give Gutenberg any sort of real flexibility with layout, and will be instrumental in Gutenberg being capable of taking the place of page-builders.
    • List: They don’t allow you to press Tab or Shift+Tab to indent/outdent a list item. This is just a personal frustration that I ran into while creating this list for this review and several times found myself jumping down to the next block (when pressing Tab) when all I wanted to do was indent a list item. Really?
  • Gutenberg on mobile:
    • The Inspector Controls sidebar is full-width, even on something like an iPad (with ample screen space), and covers the page content so changes that are made cannot be previewed until the Inspector Controls are closed. This breaks the user experience, and defeats the whole purpose of having the editor UI built in JS where you can see changes live.

From the Perspective of a Developer, Extending the Editor and Creating Blocks

Pros

  • Standardization for development:
    • In the past there was no standardized way of extending the editor, which meant that it was almost entirely up to developers. Though this allows for a more broad spectrum of developers, ranging in skill from beginner to expert, to create extensions it also leads to fragmentation in implementation and severely limits the ability to share code. Conversely, developing for Gutenberg is largely standardized around blocks.

Cons

  • High barrier of entry:
    • Getting started developing for Gutenberg can be a fairly daunting task. Though Gutenberg blocks can be created with minimal PHP and ES5 JavaScript the expected standard is to be ES6+ with JSX, which requires some knowledge of React and build tools (Webpack and Babel). If simply creating a series of blocks this can be relatively straight forward, especially if using somethings like create-guten-block, however it can quickly become complicated if the plugin is doing more than creating new, simple/static, blocks.
  • Documentation:
    • Overall, the documentation is well written and fairly thorough, but the way that it’s organized left me not knowing what I didn’t know. Meaning, I didn’t know what to search for within the handbook because I was new to the terminology and the order of the handbook is such that the intermediate/advanced topics are buried within the chapters, coming after the massive list of Packages and Components. This initially left me with the impression that I had gone through all guided documentation that was available, which sent me to Google to fill in the gaps (which has a lot of outdated information as Gutenberg changed so much over its development cycle). There are also some challenges with the docs and examples where some examples are provided in ES5 and ESNext while others are only in ESNext (ES6+ and JSX). The Gutenberg examples provided by WordPress are also a great starting point, but don’t cover things such as the InspectorControls or ServerSideRender. Lastly, looking through the Gutenberg source on Github isn’t as helpful as it could be since that code needs to be built/transpiled so the code isn’t directly usable within your own project, and completely irrelevant if writing it in ES5.
  • Migrating existing projects to Gutenberg:
    • Existing plugin code bases that use PHP to render user input controls (such as for meta boxes, widgets, or shortcodes) must be rewritten in JavaScript, and whatever rendering/template system you’re using will now need to be built in JavaScript as well. Also, if those inputs used dynamic data it now also needs to be piped to the front-end so it can be used in JavaScript, likely via the REST API.

In closing, I think WordPress was in a position where it needed to make a big, bold, change or risk moving towards irrelevance as other more modern competitors eroded away at its market share. There seemed to be some internal confusion, at least early on, about what Gutenberg actually was: whether it was simply a replacement editor or a full site builder that merely begins with the replacing the editor. As the development cycle continued that messaging became more clear, and we now know that Gutenberg, phase 1, is just the first step towards being a full site builder. In my opinion I think it was largely a success, and the majority of the issues that I’ve outlined in this review can be resolved in future releases or by third-parties via plugins. The only exception to that is the development complexity challenges, but this appears to be the direction the web development industry is heading.

That said, I think Gutenberg still has a long ways to go in order for it to be a complete success. It will need to continue to evolve and grow in what it can do, with more and more advanced layout and styling features being added. For instance, as much of a giant leap forward Gutenberg is compared to the classic editor it still pales in comparison to something like the Wix editor.

All of this is a risk and gigantic opportunity for WordPress, and with the foundation in place I’m both hopeful and excited to see where things go from here.

Using a PHP Framework or Library in WordPress Plugins and Themes

Anyone who has spent a fair amount of time creating WordPress Plugins or Themes has likely also come across the need to package a PHP framework or library inside a plugin or theme. On the surface this is a fairly routine thing to do – simply copy the file into your plugin or theme, or use composer. There are lots of plugins out there using various PHP libraries and frameworks.

The Problems Begin

I’ve personally started including a PHP framework that I’ve created to help make development easier and add some features that I repeatedly use from project to project. At first this is great, and development is humming along, but eventually you’ll likely run into some problems, like I did. When WordPress loads it loads each activated plugin alphabetically (based on the plugin directory), so let’s say we have two plugins – one called “Analytics” and one called “Cache” and both include the same “Utilities” framework. When Analytics is loaded it will load the Utilities framework, and when Cache is loaded (depending on how the Utilities framework is built) it will either skip loading Utilities because it’s already been loaded or everything will come crashing down due to “Fatal error: Cannot redeclare class/function”. Assuming everything loaded properly, without any fatal errors, the Utilities framework is now loaded and available for use by Analytics and Cache, and you move on with development.

In a closed system where you control the entire stack, all dependencies, plugins, and themes this isn’t a problem. However, with WordPress the idea is that any number of plugins or themes may be installed by the end user, and in this case the developer of a plugin or theme doesn’t have control over what other dependencies, plugins, or themes get installed. So, back to the example from above, what if Analytics needs version 1.0.0 of the Utilities framework and Cache needs version 2.1.0 of the Utilities framework? Knowing the order in which plugins are loaded we know that the Analytics plugin will successfully load the 1.0.0 version of Utilities that is packaged with it, but Cache will be stuck with version 1.0.0 as well.

Assuming that the framework is just a simple class, one way around this problem is to rename the class based on it’s version, or namespace the framework based on it’s version. The problem with this solution is the implementation within your plugin or theme – each time the framework updates you have to update the calls to the framework, which makes maintenance a complete mess (not only for your plugin or theme but also for the developer of the framework). Making things worse, what if the framework is a package in itself, containing dozens of interface and class files?

As a quick side note, one could argue that the chances of this exact situation happening is quite unlikely. However, I think there’s a strong case to be made for plugin developers who make multiple plugins that are relevant to the same audience actually running into this problem. Especially if the plugin end-users happen to update one plugin (that includes a framework) but not another plugin (thus leaving one of the plugins with an outdated framework).

WordPress Hooks Are Our Friend

The solution that I came up with is similar to what the CMB2 toolkit uses, but is instantiated in a different way and uses namespacing as part of the solution. In my specific situation (using my own framework) I had the following requirements:

  • Ability load two separate version of the framework simultaneously.
  • Allow for the newest version to load in a way that guaranteed backwards compatibility.
  • No need for changing the framework namespace or class names with each version.

What I ended up with is a framework that adheres to the following versioning scheme:

  • Major version (1.0.0 to 2.0.0) releases are namespaced by including /v1/ or /v2/ in the namespace to allow for major version releases to run side-by-side with no conflicts. This allows one plugin to use version 1 while another uses version 2.
  • Minor version (1.0.0 to 1.1.0) releases only add new features (never remove) and do not change the interface of existing classes and methods to guarantee backwards compatibility. This allows plugins that expect an old version of the framework to still run properly with a newer version of the framework.
  • Dot version (1.0.0. to 1.0.1) releases only fix bugs and security issues and never change functionality.

The Code

This addresses version dependency issues, but in order to force the highest version of the framework to load I needed to add an init file. So, in the section of my plugin where all other dependencies are loaded I simply add a line such as this:

Which loads the init.php:

Lastly, in order to actually use the framework all I need to do is hook into the ‘after_setup_theme’ action, such as this:

The way all of this works is by each plugin or theme loading the framework init.php file which creates an instance of itself, using the singleton pattern. In the constructor it checks for the existence of a full version global number to compare against. If the current version of the framework is greater than the global version then it hooks into the ‘after_setup_theme’ action and sets the global version to be the same as its version. Lastly the callback for the ‘after_setup_theme’ performs a few checks to make sure that it’s attempting to load the highest version number and that the framework hasn’t been loaded yet, and then finally loads the main framework class.

Ultimately, it’s a fairly simple setup for using a PHP framework or library in a WordPress plugin that’s easy to implement and maintain. This is the solution that worked for me, but I’m sure there are other solutions out there so please share your thoughts, and what you’ve done, in the comments.

Search WordPress Users by Name

If you run a WordPress site with a large list of users and have ever needed to search for a specific user (from the Users > All Users admin page) there’s a good chance no users were found. The problem is that the default query only searches by nicename (username) and email address. However, if you need to search by first name, last name, or a custom user meta field, the default search query is all but useless. Thankfully, the Improved user search in backend plugin fixes this shortcoming, but unfortunately this plugin is outdated and won’t work if you’re running PHP 5.5 and WordPress 3.9 or higher.

So, I’ve gone ahead and created my own user query filter to fix the problem, and included some additional functionality to improve the usefulness of the user search.

 

This can simply be dropped into your theme’s functions.php file, or can be used to create a plugin. It will work as is, but if you have custom user meta fields, possibly added using Advanced Custom Fields, you can simply add the field key to the $usermeta_keys array to include it in the user query.

WordPress Menu Anchor

I recently had the need to add a series of anchor links to a WordPress menu that linked to specific sections of a page. I found this to be tedious, since the page URL needed to be hard coded into the custom link menu item and if the page URL was ever updated each anchor needed to be updated as well. To complicate things further, when looking at the custom link within the menu editor it’s not immediately obvious that the link is an anchor if the URL is longer than the input box.

What I wanted to be able to do is simply create a custom link menu item and set the link value to #my-custom-anchor. Generally if you create a custom link menu item and set the link to be something like #my-custom-anchor it will work, if you’re already on the page for the given anchor, however it will also navigate to “my-custom-anchor” even if you’re on another page where “my-custom-anchor” doesn’t exist.

What I needed was for the anchor to navigate to the desired page and then to the specific section of the page. To do this, the URL would need to have the page URL prepended to the anchor hash. This would allow anchor links to be clicked from anywhere on the website and still navigate to the correct page, and correct section, but if the page was already being viewed the page would not reload (so scrolling animations would still work as well).

Since all of the anchor links were nested under a page menu item, as illustrated in the example below, I was able to filter the menu and prepend the URL with the URL of its’ parent menu item.

Menu Structure Example

  • Page Menu Item 1
    • Page Section 1 Anchor Menu Item
    • Page Section 2 Anchor Menu Item
      • Page Section 2 Sub Section 1 Anchor Menu Item
      • Page Section 2 Sub Section 2 Anchor Menu Item
    • Page Section 3 Anchor Menu Item
  • Page Menu Item 2
  • Page Menu Item 3

In the above example each “Page Section… Menu Item” would link to “Page Menu Item 1” and scroll to the specified section of that page. This is very useful for long pages with many sections and sub-sections.

The Solution is in the Code

To accomplish this I created a menu filter function, that gets added to the themes functions.php file, that searches for menu items with URLs that begin with a # and then prepends the URL with the URL of its’ parent menu item.

This allowed me to create custom link menu items with easily readable anchor links, that could be nested, and would also dynamically update if the page URL ever changed. Another benefit to this method vs “hard coding” an anchor link menu item is that the URL continues to work in a Domain Mapped environment, and across dev, staging, and production environments as well.

WordPress Check if a Menu is Empty

While working with WordPress there are times that it can be very useful to check if a menu is empty before outputting markup. One example is for displaying dynamic, custom, menus in a sidebar where you may not want to output any markup if the menu is empty. This is actually the default functionality of the wp_nav_menu method, but generally menus are wrapped in modules and if the menu is empty one may want to omit the entire module. Since wp_nav_menu will return false if echo is set to false and the menu is empty we can use this with a simple conditional statement to determine if the menu module markup should be output or not.

Its a rather simple solution that just requires a solid understanding of the underlying functionality built into the nav-menu-template.php WordPress core file.

WordPress Custom Sectional Menu

WordPress Menus

With the release of WordPress 3.0 menus were introduced as a visually editable element within the dashboard, dramatically improving WordPress’ CMS capabilities. However, many large websites require menu systems that are a bit more flexible and dynamic that what the built-in menu system provides. For instance, have you ever needed to create a primary navigation menu that resolved to top-level sections of the website and a series of secondary navigation menus that resolved to sub-pages related to each top-level section? Sure, you can create one menu for the top-level primary navigation and another menu for each sub-section of the website and then create a page template corresponding to each of the sub-section menus. The problem with this approach is that you have to create and maintain so many different menus and page templates, not to mention if you’re planning to turn the site over to a client upon completion it requires them to learn and follow certain steps with each page that they create. What if, instead, we could create one master menu and use the regular page template? This is where a custom sectional menu comes in by use of the wp_nav_menu_objects filter hook.

Custom Sectional Menus

To do this we need to create a large nested menu, resembling something similar to the list below, and then set it to be the active menu for the primary and secondary theme locations.

  • top-level-menu-item1
    • sub-section-menu-item1
    • sub-section-menu-item2
    • sub-section-menu-item3
      • nested-sub-section-menu-item1
  • top-level-menu-item2
  • top-level-menu-item3
    • sub-section-menu-item1
    • sub-section-menu-item2
      • nested-sub-section-menu-item1
      • nested-sub-section-menu-item2
      • nested-sub-section-menu-item3

Using the nested menu example from above the primary navigation menu would always show the top-level-menu-items. However, when viewing a sub-section page, such as the page associated with “nested-sub-section-menu-item3” the secondary menu would only show the menu items that are nested under “top-level-menu-item3”. The only remaining question is, how exactly do we do this?

The Solution

I’ve put together a fairly simple function snippet that can be copied and pasted into your themes functions.php file.

Update September 17, 2014 – I’ve updated the lb_sectional_menu filter function to be much more efficient and less prone to error. The wp_nav_menu_objects filter is applied after all menu_items have been sorted/ordered so instead we can just look for menu_items with a menu_item_parent that is equal to zero (meaning that it’s a root parent menu_item) and allow menu_items until the next menu_item_parent equal to zero is encountered. This means the menu will work even if it’s a page, post, tag, custom link, etc. It will also work no matter how many menu items are nested.

This function allows you to build a single, nested, menu and then reuse it across the entire website, where it will dynamically display the necessary menu items for the section being viewed.

JavaScript Scroll Into View

There are times when you may want to add interactivity to your website based on the scroll position relative to an elements position but don’t want to use yet another jQuery plugin. This can be useful to check to see if an element has scrolled into view. So, below I’ve added a very simple function that accepts a jQuery selector string as its only parameter and then returns an object that contains position information about the desired element. All position attributes are boolean values so they can easily be used with conditional logic. The first is “visible” which will be set to true if the desired element is currently visible on the screen (partially or wholly). The second is “above” which will be set to true if the desired element is currently above what is visible on the screen. The last is “below” which will be set to true if the desired element is currently below what is visible on the screen.

This function can easily be used in combination with a the jQuery scroll method.

As you can see it’s easy to check if an element has scrolled into view by checking if it’s visible, above, or below the view. This could be used to add or remove classes to an element, and perhaps used to set an elements position to be fixed. There are jQuery plugins, such as ScrollMagic, which provide many more features and allow for much more complex interactivity, but for simple scroll based interactions the above function is quite useful.

As always please use the comments area to share your thoughts or suggestions for improvement.

Running a Development Copy of WordPress Multisite – Update

WordPress Multisite Updates

Back in January I wrote a guide which provided details on how to setup a WordPress Multisite environment for Production and Development that both shared the same database. Since then there have been several updates with the WordPress core and I’ve also come up with several fixes for the sunrise.php file, so I thought I would write a follow up guide. At the time of writing the original guide the only method to make the Development environment fully operational was to modify two core files, which goes against common practice and was especially problematic when it came to updating WordPress. So I would like to focus on the WordPress core updates, incorporated into WordPress 3.9, that allow for the use of a newly introduced filter instead of modifying the core files.

A Better Way of Doing Things

Prior to the WordPress 3.9 release, two core files, ms-settings.php and ms-blogs.php, both needed to be manually edited in order for the Development environment to function properly. Specifically, this fixed the issue where WordPress would check to see if the current request URI matched the site URL saved in the database and since the Development environment differed from the Production environment this test always failed and redirected to the Production environment. Thanks to the introduction of several new methods and most notably the new “pre_get_site_by_path” filter we can now prevent this redirect from happening by making WordPress think it’s being viewed from the correct URI.

To do this we need to add some additional code to our customized sunrise.php drop-in plugin to account for the “pre_get_site_by_path” filter.

The comments within the code explain what exactly is being done, and for further understanding look at the ms-loads.php WordPress core file. The only item not covered in the comments is the WP_PRODUCTION_DOMAIN defined variable, which should be defined in your wp-config.php file. Please read the original guide for full details.

Thankfully, that’s all there is to it! At this point we can undo the changes to the WordPress core files and don’t need to worry about making changes to core files with each new WordPress update.

Also, note that I’ve added some other filters to the sunrise.php file to allow all content (database and wp-content/uploads) to reside in a single location and thus be shared by the Production and Development environments without needing to clone any data. I’ve updated the original guide to reflect those additional filters.

As always I hope this has been helpful, and please leave comments if you have questions or comments.