Extending Headway standard blocks – part 1

My current client work requires a sticky navigation menu and having invested in Headway Themes I’d like to be able to do it via vanilla blocks but that option in missing.

Well organized code

Since blocks are written using using OOP techniques extending a base block, like PHP-class extension, should not be a drama.
Headway comes organized in neat and clear folders and the code for the navigation block resides in

.../wp-content/themes/headway/library/blocks/navigation.php

I call this good folder organization.

I can re-use code, first time for me

One of the selling points of object-oriented programming is that code is re-usable and that’s the case here. The file navigation.php defines the HeadwayNavigationBlock class and my first guess is that creating a block, maybe via the handy grunt-init block template, that defines a class extending HeadwayNavigationBlock class will yield me a perfect copy of the default navigation menu.

<?php
namespace stickynav;

class Block extends \HeadwayNavigationBlock
{

    public $id = 'stickynav';
    public $name = 'Headway Sticky Navigation';
    public $options_class = 'HeadwayNavigationBlockOptions';
    public $description = 'Extends the default navigation block to make it sticky.';
}

The code above will, in fact, produce an exact copy of the original block

Sticky nav here
Sticky nav here

Please note that I’m using the same block options of the original navigation blocks to populate StickyNav one

public $options_class = 'HeadwayNavigationBlockOptions';

One might not want the sticky navigation to be sticky

Absurd as it might be that’s a possibility hence I will add an option to the block to disable *stickiness. To do so I will extend the navigation block options, the HeadwayNavigationBlockOptions class defined in the navigation.php file, in the sticky nav options class

<?php
namespace stickynav;

class BlockOptions extends \HeadwayNavigationBlockOptions
{
}

The extension is an empty one and simply pointing my custom block to use this new option class lands me an exact copy of the default navigation block along with its options.

public $options_class = '\stickynav\BlockOptions';

To add the options I will now insert a new setting voice in the navigation block “Orientation” section, a simple check box to activate and deactivate the stickiness. The class handling a block options will define the $tabs and $inputs arrays and populate those with options (the format once again in the official documentation), I will get hold of the defined inputs to add mine.

Reading the source code

The file containing the source code for HeadwayBlockOptionsAPI class is in

../wp-content/themes/headway/library/api/api-block.php

and a quick glance reveals that breadcrumbs have been left for developers to plug into the classes and extend those (I like these guys)

class HeadwayBlockOptionsAPI extends HeadwayVisualEditorPanelAPI
{ 

...

//Allow developers to modify the properties of the class and use functions since doing a property 
//outside of a function will not allow you to.
$this->modify_arguments($args);

...

Plugging in

Overriding the modify_arguments method in my \stickynav\BlockOptions class will allow me to, well, modify the arguments.
A word of caution: the class HeadwayNavigationBlockOptions itself will override that method and hence I will override it again in my class to add my option keeping the same exact method signature (which I’ve peeked in the file .../wp-content/themes/headway/library/blocks/navigation)

<?php
namespace stickynav;

// extend the navigation options class
class BlockOptions extends \HeadwayNavigationBlockOptions
{
    // override \HeadwayNavigationBlockOptions::modify_arguments
    public function modify_arguments($args = false)
    {
        // call \HeadwayNavigationBlockOptions::modify_arguments
        parent::modify_arguments($args);

        // add the stickiness option in the orientation tab
        $this->inputs['orientation']['stickiness'] = array(
            'type' => 'checkbox',
            'name' => 'stickyness',
            'label' => 'Sticky',
            'default' => true,
            'tooltip' => 'When scrolled past the navigation block will stick to the top of the page'
            );
    }
}

And that’s the final result

An option!
An option!

In the next post I will cover adding the actual stickyness and using the option.

11 thoughts on “Extending Headway standard blocks – part 1

  1. Could you just use a child theme functions.php to add this to the existing navigation block. That way you are extending the block vs duplicating it which results in 2 blocks?

    1. I do not like using themes, be it child themes or fully developed themes, to add functionality to the site: I will use plugins for that. I can very well think of using the customized block in other client projects and the portability a plugin grants is a must.
      About block duplication: that’s true but I’ve developed 12 custom blocks until now and all are added to the block list: I prefer having many options and the block list is a developer/designer zone where I assume one can find its way.

      1. Thanks for the clarification. I do agree it is better adding functionality from a plugin than a child theme.

        However the reason I asked was more for the benefit of Headway users. Since many of them already have a child theme setup with Headway for these kinds of modifications.

        1. Then you are absolutely right: I guess all the code I post using plugins could very well be copied and pasted into functions.php file.

        1. I’ve looked into the code but could not find any hook. The wrapper panel extends the HeadwayVisualPanelAPI class, and while that makes it possible extending it on its own, it does not define any filter or action in it. Which is quite strange and probably more of an unforeseen possibility rather than an imposed limit: Headway is otherwise full of hooks.

I appreciate your input