# Blocks

In HivePress, [templates](/developer-docs/framework/templates.md) are defined as arrays of blocks. With blocks, it’s easy to re-use and customize specific layout parts without affecting the whole template.

Each block type is implemented as a PHP class with properties and methods that determine the behavior and rendering of the block HTML content. You can use any of the existing block types in templates or even create a new one if required.

### Creating block types

If you are developing a custom HivePress [extension](/developer-docs/tutorials/create-a-custom-hivepress-extension.md), you may need to create a new block type. To do this, create a new `class-{block-type}.php` file (use lowercase letters, numbers, and hyphens only) in the `includes/blocks` extension subdirectory and HivePress will load it automatically.

{% hint style="info" %}
It’s good practice to re-use the existing HivePress block types and avoid creating new ones if possible. For example, a new type may be required if you need a completely new UI element, or if it requires some custom logic.
{% endhint %}

Then, define the block type PHP class. The class name should be based on the file name but with underscores instead of hyphens and no lowercase restriction (e.g. `Foo_Bar` class for the `class-foo-bar.php` file). Pick a name that is unique enough to avoid conflicts with other HivePress block types.

```php
<?php
namespace HivePress\Blocks;

use HivePress\Helpers as hp;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;

class Foo_Bar extends Block {

	// Declare the block properties.
	protected $say_hello;

	public function __construct( $args = [] ) {

		// Set the property defaults.
		$args = hp\merge_arrays(
			[
				'say_hello' => false,
			],
			$args
		);

		parent::__construct( $args );
	}

	public static function init( $meta = [] ) {

		// Add label and settings for Gutenberg.
		$meta = hp\merge_arrays(
			[
				'label'    => 'Hello World',

				'settings' => [
					'say_hello' => [
						'label'  => 'Say Hello',
						'type'   => 'checkbox',
						'_order' => 123,
					],
				],
			],
			$meta
		);

		parent::init( $meta );
	}

	protected function boot() {
		// Do something after the block is loaded.

		parent::boot();
	}

	public function render() {

		// Render the block HTML content.
		$output = '<h1>';

		if ( $this->say_hello ) {
			$output .= 'Hello World!';
		} else {
			$output .= 'Silence...';
		}

		$output .= '</h1>';

		return $output;
	}
}

```

The code example above defines a new `Foo_Bar` block type. It has a single `say_hello` property set to `false` by default. This block type is also registered in the Gutenberg editor with the "Hello World" label and a single checkbox option for changing the `say_hello` property value. If this property is set to `true`, the block outputs the **H1** heading with "Hello World!" text. If not, the "Silence..." text is displayed instead.

Registering the block type in Gutenberg via the `init` method is required only if it's not template-specific and you want to allow adding this block to any page in **WordPress > Pages**. Setting a label is enough to register the block type, but you can also define the extra block settings as an array of [fields](/developer-docs/framework/fields.md) in the `settings` parameter.

Also, a custom block type can be based on another type's PHP class, allowing you to re-use its properties and methods without repeating the code:

```php
<?php
namespace HivePress\Blocks;

use HivePress\Helpers as hp;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;

class Foo_Bar extends Container {

	// Override properties and methods of Container type.
}

```

In the same way, you can create custom block types for your HivePress extension.

### Customizing block types

You can customize any of the existing block types using [hooks](https://hivepress.github.io/hook-reference/). For example, the code below adds a new checkbox option to the **Listings** block settings in the Gutenberg editor. It allows users to check and save it after inserting the **Listings** block into the editor.

```php
add_filter(
	'hivepress/v1/blocks/listings/meta',
	function( $meta ) {
		$meta['settings']['my_custom_option'] = [
			'label'  => 'My Custom Option',
			'type'   => 'checkbox',
			'_order' => 123,
		];

		return $meta;
	}
);
```

The code example below checks if the option we've just added is checked and adds a custom CSS class to the **Listings** block HTML container.

```php
add_filter(
	'hivepress/v1/blocks/listings',
	function( $args ) {
		if ( isset( $args['my_custom_option'] ) && $args['my_custom_option'] ) {
			$args = hivepress()->helper->merge_arrays(
				$args,
				[
					'attributes' => [
						'class' => [ 'my-custom-class' ],
					],
				]
			);
		}

		return $args;
	}
);
```

Similarly, you can customize any block type in HivePress or its extensions.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hivepress.io/developer-docs/framework/blocks.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
