Input Types v3.28
tl;dr
- Go straight to the example in the cookbook if you just want to see how a custom input type looks like.
- See the Built-in Input Types section in the menu to learn about WPCE's built-in input types.
Since WPCE v3.5, input types have no longer been a fixed entity defined by the WPCE plugin itself. Instead, additional input types could be registered from the outside.
Since then, the input type system experienced various iterations (documented here) and underwent a major overhaul in v3.28 in such a way that any input types registered from the outside can now be just as powerful as WPCE's built-in input types.
What Makes an Input Type?
An input type consists of a unique name, a Vue component for rendering it into the editor's property form and some options declaring its meta behavior.
Registering an Input Type
The registration interface is accessible through the WPCE instance's registerInputType method, so it should be used during the wpce_instance_added event:
import RadioInput from './RadioInput.vue'
document.addEventListener('wpce_instance_added', function (event) {
const editor = event.detail.instance
editor.registerInputType('radio', RadioInput, {
// additional options
})
})Rendering an Input Type
In theory, this would be a fully valid input type component:
<template>
<input v-model="model" />
</template>
<script setup>
const model = defineModel()
</script>However, most of the times when rendering the input type, some context information is needed. Such context can be received through the useInputType() composable, exposed on the global instance manager's inputTypeUtils property:
const {
/**
* Refers to the document node being edited.
*/
node,
/**
* Refers to the definition of the property which has the input type
* assigned, in particular including an `input` property with
* instructions for the input type.
*/
property,
/**
* Passing this function a callback will execute it just before
* the property form is saved. Use this to perform side effects
* that are not part of the input's value itself.
*/
onCommit,
/**
* Passing this function a callback will execute it after the
* input has been successfully validated. The callback may throw
* an error to still mark the input value as invalid.
* This is useful in situations where basic validation may be achievable
* without the component, but some more sophisticated validation
* requires the component to be rendered.
*/
onValidate,
/**
* Passing this function a callback will execute it when the
* input value has been deemed invalid. This is useful for performing
* side effects that should happen when the input is invalid.
*/
onInvalid,
} = window.wpce.inputTypeUtils.useInputType()Additional Options
These options configure the input type's behavior independently from its rendering.
layout
How the label/description and the interactive part of the input type should be arranged in a property form.
'auto' (the default) uses built-in heuristics for dispay, usually arranging it as a row.
'custom' will completely omit any label/description attached to the property and only render the input type component itself.
Type:
'row' | 'column' | 'auto' | 'custom'getDefaultValue
A callback which returns the default value for an element's property. This function is called, for example, when a new element node is created.
A property's defaultValue option takes precedence over this.
Type:
(context: {
/**
* The property definition for which the
* default value should be returned
*/
property: Wpce.Definition.Property,
/**
* Instance of the surrounding editor's `WPCE_Core` class
*/
wpce: WpceCoreClass
}) => anyvalidate
A callback which validates the value of an element's property. If an error occurs, an error message string should be thrown.
If the input type has nested properties, the callback should proactively take care and run wpce.runValidator() on them.
Type:
(
/**
* The value to validate
*/
value: Wpce.Definition.Value,
/**
* Additional context
*/
context: {
/**
* The property definition for which the
* default value should be returned
*/
property: Wpce.Definition.Property
/**
* The document node being edited
*/
node: Wpce.Document.Node
/**
* Instance of the surrounding editor's `WPCE_Core` class
*/
wpce: WpceCoreClass
},
) => boolean | Promise<boolean>checkDirty
A callback which checks if, given an old and a new version, an element's property value did change.
Type:
(
/**
* The new value to compare
*/
newValue: Wpce.Definition.Value,
/**
* The old value to compare
*/
oldValue: Wpce.Definition.Value | undefined,
/**
* Additional context
*/
context: {
/**
* The property definition for which the
* default value should be returned
*/
property: Wpce.Definition.Property
/**
* The document node being edited
*/
node: Wpce.Document.Node
/**
* Instance of the surrounding editor's `WPCE_Core` class
*/
wpce: WpceCoreClass
},
) => booleanadditionalGuids
An array of RFC 9535 JSONPath expressions which can be used to identify additional GUIDs in the input type's property value. Knowledge of these GUIDs is essential e.g. for reassigning them on node duplication.
INFO
When evaluating additional GUIDs, the JSONPath expression's $ root will be the property value itself.
Type:
string[]getNestedProperties
A callback to receive information about nested properties and how to find them from an element node property's value.
Type:
(context: {
/**
* The value to validate
*/
value: any
/**
* The input type options for the property being edited
*/
input: Wpce.Definition.InputType,
}) =>
/**
* A Map object mapping RFC 9535 JSONPath queries to
* nested property input definitions
*/
Map<string, Wpce.Definition.InputType>embeddedDocuments
An array of RFC 9535 JSONPath expressions pointing to whole document root nodes embedded in the property value.
INFO
When evaluating additional GUIDs, the JSONPath expression's $ root will be the property value itself.
Type:
string[]conditions
A semi-declarative set of conditions the current property value can be evaluated against.
Type:
Record<
string,
(
/**
* The current value to evaluate against
*/
value: Wpce.Definition.Value,
/**
* The payload passed when evaluating the condition
*/
payload: unknown,
context: {
/**
* The property definition for which the
* conditions should be evaluated
*/
property: Wpce.Definition.Property<T>
/**
* The document node being edited
*/
node: Wpce.Document.Node
/**
* Instance of the surrounding editor's `WPCE_Core` class
*/
wpce: WpceCoreClass
},
) => boolean
>