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.

Version: 1.1.0 Repository: github.com/mxmsmnv/InputfieldMatrixType

InputfieldMatrixType

Author: Maxim Semenov
Website: smnv.org
Email: maxim@smnv.org

If this project helps your work, consider supporting future development: GitHub Sponsors or smnv.org/sponsor.
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
  • Preserve numeric zero values for number fields
  • 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
FieldtypeFilearray with url, description, filesize, basename

Empty values are skipped automatically — a field only appears in $item['fields'] if it has a non-empty value. Numeric 0 is preserved for number fields; unchecked checkboxes are skipped.

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'] !== null): ?>
 <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)

You can customize skipped fields without editing the class:

$processor = new MatrixDataProcessor($page, [
 'addSkipFields' => ['internal_notes', 'supplier_cost']
]);
// Or replace the full skip list:
$processor = new MatrixDataProcessor($page, [
 'skipFields' => ['repeater_matrix_type', 'id', 'name']
]);

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, array $options = []);
// 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.1.0

More modules by Maxim Semenov

  • Context

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

    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
  • Dimensions

    Stores product dimensions (×ばつH) and weight with selectable units of measurement.
  • Ally (a11y)

    Self-hosted accessibility widget powered by Sienna (MIT). Adds font, contrast, language, and navigation tools to any page. No external CDN — the JS bundle is served from your own server.
  • Subscribe

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

    AI integration for ProcessWire. Supports Anthropic, OpenAI, Google, xAI, and OpenRouter.
  • Plausible Analytics

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

    Manage robots.txt file through the admin UI with presets and visual editor.

All modules by Maxim Semenov

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

AltStyle によって変換されたページ (->オリジナル) /