Skip to main content

Preprocessing Data

Inevitably when working with data you want to massage saved data before passing it on to the rendering system. This is why RJSF includes a way to define and use render preprocess plugins. This render preprocessing service is not used in the module and is provided only as a helper/utility to integrate with other systems and patterns. Using the service is as simple as

$processed = \Drupal::getContainer()->get('rjsf.render.preprocessor')->preprocess(
$values,
$componentDef['renderPreprocess'] ?? [],
$componentDef['component']['schema'],
$componentDef['component']['uiSchema'] ?? []
);

Adding preprocess plugins to your schema

To add preprocessors to your schema add a new top level property renderPreprocess at the same level as schema and uiSchema. The renderPreprocess structure is similar to uiSchema in that the property structure from schema should be matched to apply $plugins to properties you want to preprocess. $plugins is expected to be an object or array of objects referencing. When multiple plugins are added for one field the plugins are chained with the first plugin passing the processed value to the second plugin and so on until all plugins have run.

Each preprocessor object needs to contain a $plugin value mapping to the plugin id for the preprocessor and optionally a $vars key representing an object of variables available for a specific preprocessor.

Examples of how to implement preprocessors can be found in src/Plugin/Rjsf/RenderPreprocess)

Result of preprocessing

When any property of a form is run through a preprocessor then the output will contain the preprocessed results alongside data that wasn't preprocessed with all original data being available under the original property.

The example below shows how the data changes when the linkField is run through the link preprocessor.

Original data

[
'linkField' => [
'entity' => [
'uuid' => '1111-11111-11111-1111',
'id' => '11',
'type' => 'node',
'bundle' => 'article',
],
'title' => 'A link title',
],
'otherField' => 'example string',
]

Processed data

[
"linkField" => [
"url" => "/article/article-title-path",
"title" => "A link title",
],
"otherField" => "example string"
"original" => [
"linkField" => [
"entity" => [
"uuid" => "1111-11111-11111-1111",
"id" => "11",
"type" => "node",
"bundle" => "article",
],
"title" => "A link title",
],
"otherField" => "example string",
]
]

Examples

Single preprocess plugin

{
"schema":{
"type":"object",
...,
"properties":{
"exampleField":{
"title":"Example field",
"type":"string"
}
}
},
"uiSchema":{...},
"renderPreprocess":{
"exampleField":{
"$plugins":{
"$plugin":"preproccess_plugin_id"
}
}
}
}

Multiple preprocess plugins

{
"schema":{
"type":"object",
...,
"properties":{
"exampleField":{
"title":"Example field",
"type":"string"
}
}
},
"uiSchema":{...},
"renderPreprocess":{
"exampleField":{
"$plugins":{
"$plugin":[
{
"$plugin":"preproccess_plugin_id",
"$vars":{
"var_1":"some value",
"var_2":"some value"
}
},
{
"$plugin":"preproccess_plugin_id_2",
"$vars":{
"var_1":"some value",
"var_2":"some value"
}
}
]
}
}
}
}

Preprocessing items in an array

{
"schema":{
"type":"object",
...,
"properties":{
"exampleField":{
"title":"Example field",
"type":"array",
"items":{
"exampleItemField":{
"type":"string"
}
}
}
}
},
"uiSchema":{...},
"renderPreprocess":{
"exampleField":{
"items":{
"exampleItemField":{
"$plugins":{
"$plugin":{
"$plugin":"preproccess_plugin_id",
"$vars":{
"var_1":"some value",
"var_2":"some value"
}
}
}
}
}
}
}
}