SR
Click to open github profile
Usage

Custom Element Types

Learn how you can add your own element type for plugins.


You can use the EVENT_REGISTER_ELEMENT_TYPES event to define custom element types. An element Type has it's own transformer and query. We will try that out with the awesome Navigation Plugin. Here's how to set it up:

Initialize Event Listener

Add the following code to your module or plugin to register your custom transformer:

./modules/queryapiextension/Queryapiextension.php
use modules\queryapiextension\transformers\NavigationTransformer;

use samuelreichoer\queryapi\events\RegisterElementTypesEvent;
use samuelreichoer\queryapi\models\RegisterElementType;
use samuelreichoer\queryapi\services\ElementQueryService;

Event::on(
    ElementQueryService::class,
    ElementQueryService::EVENT_REGISTER_ELEMENT_TYPES,
    function (RegisterElementTypesEvent $event) {
        $event->elementTypes[] = new RegisterElementType([
            'elementTypeClass' => 'verbb\navigation\elements\Node',
            'elementTypeHandle' => 'navigation',
            'allowedMethods' => ['limit', 'handle', 'id'],
            'transformer' => NavigationTransformer::class,
        ]);
    }
);

In this example:

  • elementTypeClass specifies the full class name of the element type you want to add.
  • elementTypeHandle defines the handle that you use later for quering from that element type.
  • allowedMethods defines all allowed methods that you can later use in the query builder.
  • transformer adds the json transformer for beautiful responses.

Creating a Transformer

The Transformer processes the data for the response. Here’s an example for the NavigationTransformer:

./modules/queryapiextension/transformers/NavigationTransformer.php
<?php

namespace modules\queryapiextension\transformers; // Change this to your namespace

use samuelreichoer\queryapi\transformers\BaseTransformer;
use verbb\navigation\elements\Node;

class NavigationTransformer extends BaseTransformer
{
    protected Node $navigation;

    public function __construct(Node $navigation)
    {
        parent::__construct($navigation);
        $this->navigation = $navigation;
    }

    /**
     * Transforms the Navigation Node into an array.
     *
     * @param array $predefinedFields
     * @return array
     */
    public function getTransformedData(array $predefinedFields = []): array
    {
        return [
            'metadata' => $this->getMetaData(),
            'title' => $this->navigation->title,
            'url' => $this->navigation->getUrl(),
            'type' => $this->navigation->getTypeLabel(),
            'level' => $this->navigation->level,
        ];
    }

    /**
     * Retrieves metadata from the Navigation Node.
     *
     * @return array
     */
    protected function getMetaData(): array
    {
        return array_merge(parent::getMetaData(), [
            'id' => $this->navigation->id,
            'siteId' => $this->navigation->site->id,
            'status' => $this->navigation->getStatus(),
        ]);
    }
}

Usage

After that you should be able to query from the new added navigation element type like that:

/v1/api/queryApi/customQuery?elementType=navigation&handle=main-navigation&all=1

You can use all query params that you have added through the allowedMethods property and all of the special parameters (e.g. one=1 and all=1).


Copyright © 2025 Samuel Reichör