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 [caption id=“attachment_622” align=“aligncenter” width=“1024”]Sticky nav here Sticky nav here[/caption] 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 [caption id=“attachment_627” align=“aligncenter” width=“1024”]An option! An option![/caption]

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