Matrix Type

Hidden field for identifying repeater matrix item types

ProcessWire Matrix Type Module

A ProcessWire module for managing and displaying typed repeater matrix items with structured data extraction and flexible rendering.

Author: Maxim Semenov — maxim@smnv.org — smnv.org
Version: 1.0.9
Repository: github.com/mxmsmnv/InputfieldMatrixType
License: MIT

The Problem


When working with ProcessWire's Repeater Matrix fields, identifying the type of each matrix item on the frontend is not straightforward:

  • No built-in field exists to store human-readable type identifiers
  • Extracting structured data from different matrix types requires repetitive code
  • Creating JSON APIs or dynamic frontends becomes unnecessarily complicated

This module solves these problems by providing a dedicated fieldtype for storing type identifiers and a data processor for consistent extraction.

Overview


  • FieldtypeMatrixType — Custom fieldtype for storing matrix item type identifiers
  • InputfieldMatrixType — Admin interface for configuring matrix types
  • MatrixDataProcessor — PHP class for extracting and structuring matrix data

Features


  • Define unique type identifiers for each matrix item
  • Set human-readable display names
  • Automatic data extraction from repeater matrix fields
  • Structured output format (JSON-ready)
  • Built-in price and SKU field support
  • Support for multiple field types (text, images, options, pages, etc.)
  • Skip empty values automatically
  • Filter system fields automatically
  • Reliable type detection via native repeater_matrix_type + getMatrixTypes()

Installation


  1. Copy the module folder to /site/modules/InputfieldMatrixType/
  2. Go to Admin → Modules → Refresh
  3. Install FieldtypeMatrixType — InputfieldMatrixType installs automatically as a dependency

Module Structure


/site/modules/InputfieldMatrixType/
├── FieldtypeMatrixType.module.php
├── InputfieldMatrixType.module.php
├── MatrixDataProcessor.php
└── README.md

Setup


Step 1 — Create identifier fields

For each matrix type, create a separate field of type Matrix Type (FieldtypeMatrixType).

Step 2 — Configure each identifier field

Go to Admin → Fields → [field name] → Details tab and fill in:

  • Matrix Type Identifier — unique slug used in code (e.g. box)
  • Display Name — human-readable label (e.g. Box)

⚠ The Matrix Type Identifier is what $item['type'] returns in your template. It must match exactly what you use in your switch/if statements.

Step 3 — Add to matrix templates

In each matrix type template, add its corresponding identifier field. The field renders as a hidden input in the admin — no data entry needed from editors.

Usage


⚠ Namespace requirement

Template files must declare the namespace, otherwise new MatrixDataProcessor() will fail:

<?php namespace ProcessWire;

Basic example

<?php namespace ProcessWire;

$processorPath = wire('config')->paths->siteModules . 'InputfieldMatrixType/MatrixDataProcessor.php';
if (file_exists($processorPath)) require_once $processorPath;

$processor = new MatrixDataProcessor($page);
$items = $processor->getItems('your_matrix_field_name');

Use wire('config') instead of $config — it works reliably in all template contexts.

Data structure returned

[
    [
        'id'          => 1234,
        'type'        => 'sedan',       // Matrix Type Identifier
        'displayName' => 'Sedan',       // Display Name
        'sku'         => 'VIN-001',     // SKU field value if present
        'price'       => 24900.00,      // Price field value if present
        'fields'      => [              // All non-system fields with values
            [
                'name'  => 'make',
                'label' => 'Make',
                'type'  => 'FieldtypeText',
                'value' => 'Toyota'
            ],
            [
                'name'  => 'year',
                'label' => 'Year',
                'type'  => 'FieldtypeInteger',
                'value' => 2022
            ],
            [
                'name'  => 'transmission',
                'label' => 'Transmission',
                'type'  => 'FieldtypeOptions',
                'value' => ['Automatic']
            ],
            [
                'name'  => 'all_wheel_drive',
                'label' => 'All Wheel Drive',
                'type'  => 'FieldtypeCheckbox',
                'value' => true
            ],
        ]
    ]
]

Field value types

ProcessWire fieldtypePHP value returned
FieldtypeText / FieldtypeTextareastring
FieldtypeIntegerint
FieldtypeFloat / FieldtypeDecimalfloat
FieldtypeOptionsarray of title strings, e.g. ['Red', 'Blue']
FieldtypeCheckboxbool
FieldtypePagearray with id, title, url — or array of such arrays
FieldtypeImagearray with url, description, width, height

Empty values are skipped automatically — a field only appears in $item['fields'] if it has a non-empty value.

Examples


Case 1 — Real estate: Apartment, House, Land

Each property type has a completely different set of fields. Matrix field name: details

Identifier fields:

Field nameMatrix Type IdentifierDisplay Name
details_apartmentapartmentApartment
details_househouseHouse
details_landlandLand

Fields per type:

TypeFields
apartmentrooms (Integer), floor (Integer), floors_total (Integer), area_sqm (Float), bathroom_type (Options), balcony (Checkbox), elevator (Checkbox)
housearea_sqm (Float), land_area_sqm (Float), floors (Integer), garage (Checkbox), heating_type (Options)
landland_area_sqm (Float), land_category (Options), electricity (Checkbox), gas (Checkbox), water (Checkbox)

Template:

<?php namespace ProcessWire;

$processorPath = wire('config')->paths->siteModules . 'InputfieldMatrixType/MatrixDataProcessor.php';
if (file_exists($processorPath)) require_once $processorPath;

$processor = new MatrixDataProcessor($page);
$items = $processor->getItems('details');

foreach ($items as $item):
?>
<div data-type="<?= $item['type'] ?>">
    <h3><?= $item['displayName'] ?></h3>

    <?php foreach ($item['fields'] as $f): ?>
    <?php
        $val = $f['value'];
        if (is_array($val)) $val = implode(', ', $val);
        if (is_bool($val)) $val = $val ? 'Yes' : 'No';
        if ($val === null || $val === '') continue;
    ?>
    <div>
        <span><?= htmlspecialchars($f['label']) ?></span>
        <span><?= htmlspecialchars((string)$val) ?></span>
    </div>
    <?php endforeach ?>
</div>
<?php endforeach ?>

Case 2 — Alcohol shop: Wine, Cognac, Beer

Each drink type has its own set of characteristics. Matrix field name: drinks

Identifier fields:

Field nameMatrix Type IdentifierDisplay Name
drinks_winewineWine
drinks_cognaccognacCognac
drinks_beerbeerBeer

Fields per type:

TypeFields
winegrape_variety (Options), vintage_year (Integer), region (Text), sweetness (Options: Dry / Semi-dry / Semi-sweet / Sweet), color (Options: Red / White / Rosé), volume_ml (Integer)
cognacage_years (Integer), region (Text), distillery (Text), volume_ml (Integer)
beerstyle (Options: Lager / Ale / Stout / IPA / Wheat), ibu (Integer), abv (Float), filtered (Checkbox), volume_ml (Integer)

Template:

<?php namespace ProcessWire;

$processorPath = wire('config')->paths->siteModules . 'InputfieldMatrixType/MatrixDataProcessor.php';
if (file_exists($processorPath)) require_once $processorPath;

$processor = new MatrixDataProcessor($page);
$items = $processor->getItems('drinks');

foreach ($items as $item):
?>
<div data-type="<?= $item['type'] ?>">
    <h3><?= $item['displayName'] ?></h3>

    <?php if ($item['price']): ?>
    <div>$<?= number_format($item['price'], 2) ?></div>
    <?php endif ?>

    <?php foreach ($item['fields'] as $f): ?>
    <?php
        $val = $f['value'];
        if (is_array($val)) $val = implode(', ', $val);
        if (is_bool($val)) $val = $val ? 'Yes' : 'No';
        if ($val === null || $val === '') continue;
    ?>
    <div>
        <span><?= htmlspecialchars($f['label']) ?></span>
        <span><?= htmlspecialchars((string)$val) ?></span>
    </div>
    <?php endforeach ?>

    <button data-item-id="<?= $item['id'] ?>">Add to Cart</button>
</div>
<?php endforeach ?>

Skip Fields


The processor automatically skips:

  • System fields: id, name, parent, template, created, modified, createdUser, modifiedUser
  • repeater_matrix_type
  • price, sku (returned separately at the item level)
  • All FieldtypeMatrixType fields (used for type detection only)

To customize, modify the $skipFields array in MatrixDataProcessor.php.

Custom Formatting


Override formatValue() to add support for custom fieldtypes:

protected function formatValue($value, $field) {
    $fieldType = $field->type->className();

    switch($fieldType) {
        case 'YourCustomFieldtype':
            return $this->formatCustom($value);
        default:
            return parent::formatValue($value, $field);
    }
}

API Reference


// Constructor
$processor = new MatrixDataProcessor(Page $page);

// Get all items from a matrix field
$items = $processor->getItems(string $matrixFieldName = 'matrix');

Troubleshooting


Class "MatrixDataProcessor" not found
Add <?php namespace ProcessWire; at the top of your template file.

No items returned

  • Verify the matrix field name: $processor->getItems('your_field_name')
  • Check that items are published and the field has content

type returns "unknown"

  • Ensure each matrix type template has a FieldtypeMatrixType field added to it
  • Open the field in Admin → Fields → Details and fill in the Matrix Type Identifier

Requirements


  • ProcessWire 3.0+
  • PHP 8.1+

License


MIT — free to use and modify


Author: Maxim Semenov — maxim@smnv.org
Module Version: 1.0.9

More modules by Maxim Semenov

  • Context

    Export ProcessWire site context for AI development (JSON + TOON formats)
  • Ichiban

    Comprehensive SEO module: meta/OG/schema, audit, redirects, revisions, email reports.
  • WireWall

    Advanced traffic firewall with VPN/Proxy/Tor detection, rate limiting, and JS challenge
  • Subscribe

    Newsletter subscription handler with lists, double opt-in, honeypot, rate limiting and unsubscribe link.
  • Page Markdown

    Export any page to a clean Markdown file. Adds an export button to the page editor.
  • Legal Docs

    AI-powered legal document generator. Generates Privacy Policy, Terms of Use, Cookie Policy and more for 93 jurisdictions.
  • Plausible Analytics

    Plausible Analytics dashboard using Stats API v2 with page-edit widget, traffic trends chart, and geo/device tabs.
  • Collections

    Configurable page collections with table UI and REST API
  • Dimensions

    Stores product dimensions (L×W×H) and weight with selectable units of measurement.

All modules by Maxim Semenov

Install and use modules at your own risk. Always have a site and database backup before installing new modules.