Raw Fields Formatters
This module provides formatters that expose field values as raw, structured data instead of HTML. This is useful for passing field data directly to components in Single-Directory Components (SDC) or in JSON rendering pipelines.
RAW Fields Formatters exposes Drupal field values as structured data instead of rendered HTML. Assign a raw formatter in Manage display, collect the result with the module's renderer service, and you get a plain PHP array of typed values — ready to hand to a Single-Directory Component as props, or to serialise as JSON.
It depends on nothing but Drupal core, ships no configuration, no route and no database table, and adds nothing to a site that does not call it.
The problem it solves
Single-Directory Components want data: a URL, an alt text, a title, a boolean. Drupal field formatters produce markup. Bridging the two usually means one of three unpleasant options — writing a bespoke preprocess function for every field of every component, digging values out of $node->get('field_x')->… by hand and losing the display configuration, or parsing rendered HTML back into data.
This module keeps the field display layer where it belongs. The view mode still decides which fields appear and in what order, site builders still configure it in the UI, and what comes out the other end is data rather than markup.
How it works
Two steps. First, set the fields of a view mode to the matching Raw … formatter in Manage display. Then ask the renderer service for the data:
$renderer = \Drupal::service('raw_fields_formatters.renderer'); $display = \Drupal::service('entity_display.repository') ->getViewDisplay('node', $node->bundle(), 'card'); $data = $renderer->getData($display->build($node));
For a card view mode holding a title, a body, an image and a link, $data is:
[ 'title' => 'A title', 'body' => ['value' => 'Some filtered markup', 'format' => 'basic_html'], 'image' => ['url' => 'https://…/card.webp', 'alt' => 'A cat', 'width' => 600, 'height' => 400], 'link' => ['url' => '/blog/a-title', 'title' => 'Read on', 'external' => FALSE], ]
A component then consumes those props directly — {{ image.url }}, {{ image.alt }}, {{ body.value }} — with no preprocess code in between. The README shows a full component template.
Values are properly typed: a boolean field is a real true, an integer a real int. Each formatter also offers a key override, so a field_titre can arrive as the title prop your component expects, and a force as array option, so a list stays a list even when the entity happens to hold a single value.
Before you install: it renders nothing on its own
This is the first thing everyone trips over, so it is worth stating plainly. Assigning a raw formatter is only half the setup. These formatters produce no markup, and the module wires nothing up automatically. A field set to a raw formatter and never passed through the renderer service is simply invisible on the page — no warning, no error.
The module is a building block for a theme or a module you write, not a drop-in display plugin.
Two consequences follow. Every component of a view mode you pass through the renderer must use a raw formatter, because anything else is skipped. And because the fields are never rendered, no cache metadata bubbles up on its own: the renderer hands you the metadata, and you have to merge it into the render array you build. Skip that and your output is never invalidated when the content changes. The README covers both.
Available formatters
Nothing is required beyond Drupal core. Each formatter targets a field type, and needs whichever module provides it — most of them core modules you already have. A formatter whose module is absent never shows up, because the field type it targets does not exist either, so installing this module never drags anything else onto the site.
- Raw String —
string,string_long; andtelephonewith the core Telephone module - Raw Boolean, Raw Integer, Raw Decimal —
boolean,integer,decimal,float - Raw Entity —
entity_reference; nests the data of the referenced entity, built from a chosen view mode - Raw List Value —
list_integer,list_float,list_string; needs the core Options module - Raw Formatted Text —
text,text_long,text_with_summary; needs the core Text module. Applies the text format and exposes the format and the summary - Raw Image URL —
image; needs the core Image module. Optional image style, exposes the URL, alt, title and the resulting dimensions - Raw URL —
link; needs the core Link module. Resolves the stored URI to a usable URL and keeps the link title - Raw Paragraph —
entity_reference_revisions; needs Entity Reference Revisions, included in Paragraphs - Raw Icon —
ui_icon; needs UI Icons - Raw Geolocation Lat/Lng —
geolocation; needs Geolocation
Access and filtering
What comes out of the module is meant to be as safe as what comes out of core. Referenced entities and image files are checked for view access, so an unpublished node or one denied by node access never reaches your data. Formatted text goes through its text format, as core does — with an explicit opt-out for consumers that filter the value themselves.
Requirements
- Drupal 11
- PHP 8.3+
And nothing else. There is no dependency on any contrib module, and none on any optional core module either.
How it compares
This is not a replacement for JSON:API or GraphQL, which expose entities over HTTP to a decoupled front end. RAW Fields Formatters stays inside Drupal's render pipeline and targets the opposite case: a classic Drupal theme whose templates are components fed with props. If you are building a decoupled site, reach for JSON:API instead.
Project status
The module is at an alpha stage: it is used in production by its maintainer, covered by unit and kernel tests and a CI pipeline, but the data structure it returns may still change between alpha releases — see the release notes before updating. Alpha releases are not covered by the Drupal security advisory policy.
Issues and merge requests are welcome in the issue queue. A change is expected to come with its test.