DocumentationDownload

Forms, dynamic data, components, bindings and media

Nucleo 0.2+Free~27 min readUpdated October 31, 2026

Forms with fields and actions, PHP components for the site, bindings to WordPress data and saving images.

On this page

01Overview

The nc/native-form block describes a form in JSON: fields, steps and actions. The compiler saves the normalized configuration in the nc/native-form slot of the document. On every request the slot writes the nonce, the context post and the outcome. The visitor submits the form to the REST endpoint nucleo/v1/form/<doc>/<node>. The endpoint reads the configuration from the published document, validates the values and runs the actions in order.

Components are PHP classes written in a plugin of the site. They register data sources for nc/collection and actions for nc/native-form with the nucleo/register_components hook.

Bindings connect a property of a node (content.<name> or settings.<name>) to a WordPress field. The compiler writes the fixed values of the page right away. The others become tokens of the nc/bind slot, resolved on every request.

The media part saves images in the library with a check of the real type, and generates AVIF and WebP copies if the site turns them on.

All functions in this chapter are free.

02Native form: definition

Form configuration

What it does: defines a form with fields, steps, actions, texts and options. The configuration is normalized, and invalid entries are silently discarded.

How to use it: nc/native-form node in the document. Minimal example:

{ "id": "m1", "type": "nc/native-form",
  "settings": {
    "fields": [ { "name": "email", "type": "email", "label": "Email", "required": true } ],
    "actions": [ { "type": "save" }, { "type": "email", "to": "admin", "subject": "New contact", "body": "{fields}" } ]
  },
  "content": { "submitLabel": "Send" } }

Parameters (settings):

NameTypeAllowed valuesDefaultNotes
fieldsarrayfield objects (see below)[]At most 40. Fields after the 40th are discarded.
stepsarray{ "title": string }[]One step per entry. Entries without a string title are discarded.
actionsarrayobjects with type among otp, save, email, webhook, create-post, component[]Actions with an unknown type are discarded.
redirectstringhome, page:<slug> or a URL''Destination after a successful submission. See "Outcome and redirect".
captchabooleantrue, falsetruefalse removes the site captcha from this form.
groupNumberingstringnone, letters, numbers, letters-box, numbers-boxnoneNumbers the legends of field groups. Any other value means none.

Texts (content, translatable):

KeyDefault
submitLabelSend
successMessageThank you.
errorMessageSomething went wrong. Try again.
codeLabelVerification code
nextLabelNext
backLabelBack
sentMessageWe sent a code to your email.
sendCodeLabelGet the code
verifyLabelVerify
otpFailedMessageWe could not send the code by email. Try again later.
expiredMessageThe code has expired. Request a new code: your answers stay in the form.
captchaMessageComplete the anti-spam check and try again.
requiredMarknone
optionalMarknone

The defaults are translatable strings of the nucleo domain. An empty text, or a text with only spaces, keeps the default.

Permissions: who saves the document.

Edition: Free

Known limits: 40 fields. Field name with ^[a-z][a-z0-9_]{0,31}$. The block is not allowed inside a card of nc/query or nc/collection (card_block_not_allowed).

Field types

What it does: each field produces an HTML control and a validation rule on the server.

How to use it: entry of settings.fields with name and type.

Parameters (field attributes):

NameTypeAllowed valuesDefaultNotes
namestring^[a-z][a-z0-9_]{0,31}$, uniquerequiredA field with an invalid or repeated name is discarded.
typestringtext, email, tel, url, textarea, number, date, select, radio, checkboxes, checkbox, consent, hidden, contextrequiredAn unknown type discards the field.
labelstringtext''Label or legend.
requiredbooleantrue, falsefalseOnly a literal true makes the field required.
helpstringtext''Help text linked with aria-describedby.
stepinteger>= 00Step index. An index beyond the last step goes to the last one.
maxLengthinteger>= 12000 for textarea, 200 for the othersApplies to text types.
min, maxnumber or stringnumber, or date Y-m-d''For number and date.
decimalsinteger>= 00Decimal places of number. The HTML step attribute is 1 or 10^-decimals (at most 15 digits).
placeholderstringtext''For text, email, tel, url, textarea.
optionsarray`{ "value": string\number, "label"?: string }`[]For select, radio, checkboxes. Empty value: option discarded. Without label the value is used.
valuestring or numbertext''Fixed value of hidden.
fromstringpost.id, post.title, post.urlrequired for contextA context field without a valid from is discarded.
widthstringfull, halffullTwo consecutive half fields sit side by side on wide screens.
groupstringtext''Consecutive fields with the same group sit in a fieldset with that legend.

Controls and values:

typeControlSubmitted value
text, email, tel, urlinput of the matching type with maxlengthstring without HTML tags
textareatextarea with maxlengthstring without HTML tags
numberinput type="number" with min, max, stepnumeric string
dateinput type="date" with min, maxY-m-d
selectselect with an empty first optionone of the option values
radiogroup of radio buttons in a fieldsetone of the option values
checkboxesgroup of checkboxes, name <name>[]list of option values
checkbox, consentone checkbox with value="1"1
hiddeninput type="hidden"always the value of the configuration
contextno controlid, title or URL of the context post, read by the server

Permissions: as the form configuration.

Edition: Free

Known limits: consent behaves like checkbox. Nucleo does not save the date, text or version of the consent. requiredMark and optionalMark do not appear on checkbox, consent, hidden and context. The form does not accept files.

Steps

What it does: splits the fields into steps. Each step is a fieldset with legend equal to title.

How to use it: settings.steps and step on each field. The view.js script shows one step at a time with the nextLabel and backLabel buttons. Without script all steps stay visible.

Parameters: steps[].title (string).

Permissions: as the form configuration.

Edition: Free

Known limits: the server always validates all fields on the final submission. Without steps there is a single fieldset without legend.

Document validation

What it does: checks the configuration when the document is saved. An error blocks the save.

How to use it: automatic, inside the document validation.

Parameters: None

Permissions: as saving the document.

Edition: Free

Known limits: error codes returned:

CodeWhen
duplicate_fieldRepeated field name.
bad_optionsselect, radio or checkboxes without options.
bad_stepstep of the field >= number of steps, or > 0 without steps.
otp_firstotp is not the first action, or its field is not of type email.
otp_stepstep of the otp action outside 0…steps-2, or email field in a step after step.
unknown_fieldfield of otp, to/replyTo with field:x, or placeholder {field:x} in subject, body, title, fields, input with an undeclared field.
unverified_recipientemail action with to: field:x and no valid otp action on the same field.
unknown_post_typecreate-post with a content type outside the model.
bad_statuscreate-post with status other than draft and pending.
unsafe_urlwebhook with a url that does not start with https://.
unknown_componentcomponent action with a name that is not registered.

03Native form: submission

Submission endpoint

What it does: receives a form submission, applies the checks and returns the outcome.

How to use it: POST /wp-json/nucleo/v1/form/<doc>/<node>, body application/x-www-form-urlencoded with the form fields and the service fields. With the header X-Nucleo-Form: 1 the response is JSON. Without the header the response is a 303 redirect to _nc_back with nc_form=<node>, nc_status=done|error|otp|code|verified and, for otp, nc_ticket.

Parameters (service fields):

NameTypeAllowed valuesDefaultNotes
_nc_noncestringform noncerequiredSee "Form nonce".
_nc_hpstringempty''Honeypot.
_nc_ctxintegerid of a post0Context post. Valid only if published.
_nc_backstringURL of the same sitehomeReturn target for the submission without script. Goes through wp_validate_redirect.
_nc_ticketstringOTP ticket''Second OTP submission or verification at an intermediate step.
_nc_codestring6 digits''OTP code.
_nc_otpstringsend, verify''Code at an intermediate step.
_nc_proofstringverified ticket''Final submission after the verification at a step.
g-recaptcha-response, h-captcha-response, cf-turnstile-response, frc-captcha-responsestringprovider token''Only with captcha on.

Order of the checks: document and node, honeypot, nonce, rate limit, captcha, OTP flow, validation, actions.

OutcomeHTTPcode
Document not published, protected by password, or node missing404nucleo_form_not_found
Honeypot filled in200none: success response, no action
Invalid nonce403bad_nonce
Limit exceeded429rate_limited
Captcha not passed403captcha
Invalid fields422invalid, with errors per field
Wrong code422otp_wrong
Ticket or proof expired410otp_expired
Code email not sent500otp_failed
Action failed500action_failed
Successful200status: done, otp, code or verified

Permissions: public (permission_callback __return_true). The detail field of action_failed is visible only to users with manage_options, or when the environment is local or development. The filter nucleo/forms/error_detail changes the choice.

Edition: Free

Known limits: 5 submissions per minute per IP and form. 10 code verifications per minute per IP and form, with a separate counter. 3 OTP codes every 15 minutes per normalized address (lowercase, no spaces, no +tag). The IP comes from REMOTE_ADDR, or from X-Forwarded-For if the proxy is listed in the nucleo/trusted_proxies filter.

Form nonce

What it does: returns a fresh nonce. The nonce does not depend on the logged-in user.

How to use it: GET /wp-json/nucleo/v1/form/<doc>/<node>/nonce. Response { "nonce": "…" } with Cache-Control: no-store. The script asks for it before every submission, because the page cache can serve an expired nonce.

Parameters: doc and node in the path.

Permissions: public.

Edition: Free

Known limits: HMAC of wp_nonce_tick() and of the action nucleo_form:<doc>:<node>. Valid for the current tick and the previous one, as wp_verify_nonce. 404 if the form does not exist in the published document.

Value validation

What it does: validates the submitted values against the declared fields. It ignores undeclared fields and context fields.

How to use it: automatic on every submission.

Parameters: None

Permissions: public, as the endpoint.

Edition: Free

Known limits: rules and messages:

TypeRuleMessage
allrequired and emptyThis field is required.
emailFILTER_VALIDATE_EMAILEnter a valid email address.
urlvalid URL with scheme http or httpsEnter a valid web address starting with http or https.
tel^[0-9 +().-]{5,30}$Enter a valid phone number.
text typeslength <= maxLengthThe text is too long.
number^-?[0-9]+(\.[0-9]+)?$, decimals <= decimals, between min and maxEnter a valid number., Too many decimal places., Enter a value within the allowed range.
datereal date Y-m-d between min and maxEnter a valid date., Enter a date within the allowed range.
select, radiovalue among the optionsChoose one of the options.
checkboxesevery value among the optionsChoose one or more of the options.
checkbox, consentvalue 1Invalid value.

Text types lose HTML tags and the spaces at the edges. hidden always uses the value of the configuration, not the submitted one.

Outcome and redirect

What it does: shows the outcome message. With settings.redirect it sets the destination page after a successful submission.

How to use it: redirect accepts home, page:<slug> and the other internal link references, or a URL. The internal reference resolves like the links of the page. The JSON response done contains redirect if the destination exists.

Parameters: settings.redirect (string).

Permissions: public.

Edition: Free

Known limits: a reference without published content does not produce redirect. An unsafe URL (javascript: etc.) is discarded by esc_url_raw. Without script the 303 redirect always returns to _nc_back: the slot reads nc_status and shows only done, error and otp.

04Native form: actions

Action execution

What it does: runs the actions after validation, in the declared order. otp does not run here. The first error stops the following ones.

How to use it: settings.actions.

Parameters: see the sections of the single actions.

Permissions: public, as the endpoint.

Edition: Free

Known limits: the visitor sees errorMessage. The details go to the PHP log with the prefix [nucleo] form <node>, action <type>:. Actions already run are not rolled back.

Placeholders in texts

What it does: replaces the placeholders in the texts of the email, create-post and component actions.

How to use it: {field:<name>}, {post.id}, {post.title}, {post.url}, {site.name}, {fields}. {fields} writes a line label: value for each field that is not context and has a value. Lists are joined with , .

Parameters: None

Permissions: public.

Edition: Free

Known limits: a single pass: an inserted value is not read again as a placeholder. An unknown placeholder stays as it is. The result is plain text.

save action: storing submissions

What it does: saves the submission as a private post of type nucleo_submission.

How to use it: { "type": "save" }. Title <node> – <Y-m-d H:i:s>. Meta _nc_form (<doc>:<node>), _nc_data (values), _nc_context (id of the context post or 0).

Parameters: None

Permissions: the nucleo_submission type requires manage_options to create, edit, read private posts and delete.

Edition: Free

Known limits: the type has show_ui on but show_in_menu off: no menu item. The interface shows only the title, not the values. Nucleo does not delete submissions over time, nor when the plugin is deactivated. Submissions do not clear the collection caches and do not appear in collections.

email action

What it does: sends a plain text email.

How to use it: { "type": "email", "to": "admin", "subject": "…", "body": "…", "replyTo": "field:email" }.

Parameters:

NameTypeAllowed valuesDefaultNotes
tostringadmin, field:<name>, email addressadminadmin is the admin_email option. field:<name> requires an otp action on the same field.
subjectstringtext with placeholders''On one line only.
bodystringtext with placeholders''
replyTostringfield:<name>noneOnly if the value is a valid email.

Permissions: public.

Edition: Free

Known limits: invalid recipient: error invalid recipient. Sending failed: error wp_mail did not send the message. The sending goes through the development mail log: in development the email goes to the log.

webhook action

What it does: sends the submission as a JSON POST to an external URL.

How to use it: { "type": "webhook", "url": "https://…" }. Body: { "form": "<doc>:<node>", "fields": {…}, "context": <id>|null }.

Parameters: url (string, https, required).

Permissions: public.

Edition: Free

Known limits: the URL goes through a safety check: only https, no credentials, no localhost, only public IPs. Timeout 5 seconds. Errors: unsafe webhook URL, network error, HTTP status <code> for responses >= 400. The code does not sign the request and does not retry.

create-post action

What it does: creates a content of a model type and writes its fields.

How to use it: { "type": "create-post", "postType": "iscrizione", "status": "pending", "title": "{field:nome}", "fields": { "email": "{field:email}" } }.

Parameters:

NameTypeAllowed valuesDefaultNotes
postTypestringslug of a model typerequired
statusstringdraft, pendingrequired
titlestringtext with placeholders''
fieldsobjectmodel key → text with placeholders{}String values only.

Permissions: public.

Edition: Free

Known limits: invalid fields: the created content is deleted and the error reports the details. Errors tipo di contenuto fuori dal modello and status not allowed.

component action

What it does: runs a PHP action registered by a plugin of the site.

How to use it: { "type": "component", "name": "acme/crm", "input": { "email": "{field:email}" } }. Without input the action receives all the field values. With input the strings go through the placeholders and the other values stay as they were. Then the input is validated against inputSchema(), permitted() is checked and run() is called.

Parameters: name (string), input (object, optional).

Permissions: public. The action decides with permitted().

Edition: Free

Known limits: errors component action not registered, component action not permitted, JSON schema errors, component action failed or ActionResult::message. ActionResult::data stays on the server.

OTP code at final submission

What it does: verifies the email address before running the actions.

How to use it: first action { "type": "otp", "field": "email" }. First submission: validation, a 6-digit code for each email, response status: "otp" with ticket. Second submission with _nc_ticket and _nc_code: verification, then the actions with the values saved in the ticket.

Parameters:

NameTypeAllowed valuesDefaultNotes
fieldstringname of an email fieldrequired
subjectstringtextYour verification codeTranslatable.
bodystringtextYour code: {code}
ttlinteger5–30 (minutes)15Values out of range are set to the limits.
stepinteger0…steps-2noneSee the next section.

Permissions: public.

Edition: Free

Known limits: in the text of the OTP email only {code}, {site.name}, {post.title}, {post.url} apply. The other placeholders become empty. The ticket is a transient nucleo_otp_<md5> with the HMAC hash of the code. 5 attempts per ticket: from the sixth the ticket expires. The ticket is used only once, even with parallel requests. In the classic flow an expired ticket returns errorMessage, not expiredMessage.

OTP code at an intermediate step

What it does: asks for and verifies the code when leaving the step step, before the following steps.

How to use it: { "type": "otp", "field": "email", "step": 0 }.

  1. _nc_otp=send: the server validates the fields of the steps up to step, sends the code and responds status: "code" with ticket. It sets the cookie nucleo_otp_<doc>_<node> (HttpOnly, SameSite=Strict, Secure on HTTPS, 1 hour).
  2. _nc_otp=verify with _nc_ticket and _nc_code: responds status: "verified". The verified ticket is valid for 30 minutes from the first verification.
  3. Final submission with _nc_proof=<ticket>: full validation, then the proof is used only once.

Parameters: as the otp action, with step.

Permissions: public.

Edition: Free

Known limits: without the cookie the ticket is not valid. The proof is valid only for the same document, node and address. Invalid proof: 410 otp_expired with expiredMessage. Without script the form uses the classic flow.

What it does: the quality rule form.action.consequential (R4.4) flags the forms with actions that leave the site. They are webhook, create-post, component, and email with to other than admin or empty.

How to use it: the warning blocks publication. The agent asks the user for consent and publishes with acknowledge and the consent in reason.

Parameters: None

Permissions: as publication, see nucleo/doc-publish.

Edition: Free

Known limits: the rule concerns the consent of the person who publishes, not the privacy consent of the visitor. For the visitor there is the field type consent.

05Native form: anti-spam

Honeypot

What it does: adds the trap field _nc_hp off screen with CSS. A submission with the field filled receives a fake success and no action.

How to use it: automatic in every form.

Parameters: None

Permissions: public.

Edition: Free

Known limits: None found.

Captcha

What it does: shows a captcha above the buttons of every native form and verifies the token with the provider.

How to use it: one provider per site, in the nucleo_captcha option. Set it in Nucleo AI → Settings, Captcha tab, or with nucleo/settings-set, group captcha. nucleo/settings-get reads provider, site key, secretSet and threshold, never the secret. settings.captcha: false removes it from a form.

Parameters (group captcha):

NameTypeAllowed valuesDefaultNotes
providerstring'', recaptcha, recaptcha-v3, hcaptcha, turnstile, friendly'''' turns the captcha off.
siteKeystringpublic key''Required with a provider.
secretstringsecret key''Required with a provider. Write only.
thresholdnumber0–10.5Minimum score for recaptcha-v3.

Permissions: manage_options; scope nucleo:admin for the abilities.

Edition: Free

Known limits: the captcha applies to the submission without ticket and to _nc_otp=send, not to the verification and to the final submission with ticket or proof. Provider unreachable or response >= 500: the check passes (fail-open). recaptcha-v3 also requires the action nucleo_form. Unknown key in the group: error Unknown captcha key. The provider scripts come from external CDNs (Google, hCaptcha, Cloudflare, jsDelivr for Friendly Captcha).

06Nucleo emails

Sending and outcome of emails

What it does: sends the Nucleo emails (OTP codes and email actions) with wp_mail. It records the outcome of the last sending in the nucleo_mail_status option.

How to use it: automatic. The hooks wp_mail_failed and wp_mail_succeeded update the outcome. nucleo/site-describe reports in warnings a failure from the last 7 days not followed by a successful sending.

Parameters: None

Permissions: none for sending. The warning is read with nucleo/site-describe.

Edition: Free

Known limits: the hooks are registered in admin, REST, CLI and cron, not in frontend requests. Deactivating the plugin deletes nucleo_mail_status.

Development mail log

What it does: in development it stores the Nucleo emails in the nucleo_dev_mail option instead of sending them. The sending is reported as successful.

How to use it: active in local unless define('NUCLEO_DEV_MAIL', false). In development it requires define('NUCLEO_DEV_MAIL', true). The log is never enabled in staging and production. The filter nucleo/dev_mail (default true) turns it off even where it is allowed. Read it with nucleo/mail-log.

Warning

The log is never enabled in staging and production. It stores OTP codes in plain text.

Parameters (nucleo/mail-log):

NameTypeAllowed valuesDefaultNotes
limitinteger1–2020Entries from the most recent.

Permissions: manage_options; scope nucleo:admin.

Edition: Free

Known limits: last 20 emails, at most 24 hours. Body cut at 5000 characters. The log contains the OTP codes in plain text. A cron (nucleo_dev_mail_prune) removes the expired entries every day. Deactivation deletes the option. The emails of WordPress and of the other plugins are sent as usual.

07Extensible components

Component registration

What it does: collects the data sources and the actions of the site's plugins in one registry.

How to use it: the plugin hooks into nucleo/register_components. The first call to Components::instance() runs it.

add_action('nucleo/register_components', static function (\Nucleo\Extend\Components $components): void {
    $components->add(new \Acme\Components\DataSources\Eventi());
    $components->add(new \Acme\Components\Actions\Crm());
});

PHP API of Nucleo\Extend\Components:

  • public static function instance(): self
  • public function add(DataSource|Action $component): void
  • public function dataSource(string $name): ?DataSource
  • public function action(string $name): ?Action
  • public function describe(): array — names, labels and schemas, never the code.

The component blocks use another hook, nucleo/register_blocks. The local command nucleo component new <data-source|action|block> <name> generates the plugin, the classes and the registration.

Parameters: component name with ^[a-z0-9-]{1,40}\/[a-z0-9-]{1,40}$, that is <vendor>/<name>.

Permissions: none at runtime. The plugin is installed and activated like a WordPress plugin.

Edition: Free

Known limits: an invalid or already used name (also across data source and action) is discarded with _doing_it_wrong. The PHP code never goes through REST, MCP or push.

Data source (DataSource)

What it does: provides items to nc/collection with "source": "component".

How to use it: implements Nucleo\Extend\DataSource:

  • public function name(): string
  • public function label(): string
  • public function schema(): array — params, fields, optional ttl
  • public function read(array $params, int $page, int $perPage): DataPage

DataPage has items (list of maps of scalar values or null) and total. In the document: "source": "component", "component": "acme/eventi". The param filters pass the parameters. In the card it is read with the bind { "source": "item", "field": "<field>" }.

Parameters (schema()):

NameTypeAllowed valuesDefaultNotes
paramsobjectkey → JSON Schema (string, integer, number, boolean, enum)requiredread() receives parameters already validated.
fieldsobjectkey → {type, label}requiredFields of each item.
ttlinteger>= 0 seconds3000 = no cache.

Permissions: public for reading, as the collection.

Edition: Free

Known limits: invalid parameters or unregistered source: empty collection. On saving, an unregistered source gives unknown_component. The collection does not compute counts per option.

Action (Action)

What it does: runs site code when a native form is submitted.

How to use it: implements Nucleo\Extend\Action:

  • public function name(): string
  • public function label(): string
  • public function inputSchema(): array — JSON Schema of type object
  • public function permitted(array $input, ActionContext $context): bool
  • public function run(array $input, ActionContext $context): ActionResult

ActionContext has formId (node), documentId, contextPostId, ip. ActionResult has ok, message (for the visitor) and data (stays on the server), with the constructors ActionResult::ok(string $message = '') and ActionResult::fail(string $message). Use in the form: see "component action".

Parameters: None beyond the methods.

Permissions: decided by permitted().

Edition: Free

Known limits: see "component action".

List of components

What it does: returns the registered data sources and actions, with name, label and schema.

How to use it: nucleo/components-list. Response { ok, dataSources: [{name, label, schema}], actions: [{name, label, inputSchema}] }.

Parameters: None

Permissions: edit_pages; scope nucleo:read.

Edition: Free

Known limits: does not list the component blocks: they appear in catalog-get.

Activating a components plugin

What it does: activates a components plugin already on disk. It installs nothing and receives no code.

How to use it: nucleo/component-activate with { "plugin": "nucleo-components" }. The file must be WP_PLUGIN_DIR/<plugin>/<plugin>.php with the header Nucleo Components. The local command nucleo component deploy copies the plugin to a local WordPress.

Parameters:

NameTypeAllowed valuesDefaultNotes
pluginstring^[a-z0-9][a-z0-9-]{0,60}$requiredFolder and name of the main file.

Permissions: activate_plugins; scope nucleo:admin.

Edition: Free

Known limits: errors not_found, not_component, activation_failed. Plugin already active: ok with already: true. Every call goes to the audit log.

08Bindings

Bind syntax

What it does: connects a property of a node to a WordPress field.

How to use it: bind key of the node. The key is content.<name> or settings.<name> declared by the block.

{ "id": "h1", "type": "nc/heading",
  "bind": { "content.text": { "source": "post", "field": "title", "fallback": "Untitled" } } }

Parameters (bind value):

NameTypeAllowed valuesDefaultNotes
sourcestringpost, term, author, site, nucleo, acf, metabox, jetengine, woo, user, query, param, itemrequired
fieldstringnot emptyrequiredSee "Sources and fields".
fallbackstringtext''Value when the field is empty or missing.

Permissions: who saves the document.

Edition: Free

Known limits: a key not declared by the block gives the error bind key not declared in the block. The sources user and query are not allowed in cards.

Sources and fields

What it does: reads the value of the field from the indicated source.

How to use it: nucleo/bind-fields lists the fields of a content type.

Parameters:

sourcefieldValue
posttitle, excerpt, date, url, image, meta:<key>Current post. image is the URL of the large size of the featured image.
sitename, description, urlSite data.
authorname, bio, urlAuthor of the current post.
termname, description, url, slug, count, or key of a model field on the taxonomyTerm of the card or queried term. Never a post.
usernameLogged-in user. Empty for anonymous visitors.
querysearch, found, pageMain query of the request: searched text, total results, current page. Not allowed in cards.
nucleo<key> or <repeater>.<index>.<subfield> (index from 0)Field of the content model.
acffield nameget_field(). An array with url returns the URL. Without ACF it reads the meta.
metaboxfield idrwmb_meta(). Without Meta Box it reads the meta.
jetenginemeta keyMeta of the post.
wooprice, regular_price, sale_price, sku, stock_status, ratingWooCommerce product of the post. Prices come from wc_price without HTML. Empty without WooCommerce or if the post is not a product.
itemitem keyCurrent item of a card (component source or row of nc/repeater).
paramparameter nameParameter of a reusable section. It resolves when the section is expanded.

nucleo fields by type: boolean → 1 or empty; image → URL of the attachment; relation → title of the first linked content if published; select → labels joined with , ; whole repeater → no value.

Permissions: nucleo/bind-fields requires edit_posts; scope nucleo:read.

Edition: Free

Known limits: only strings and numbers become text. Arrays, objects, false and null give the fallback. The filter nucleo/bind_fields adds fields to the bind-fields list, not sources to the resolver.

Static and dynamic values

What it does: decides whether a bind resolves at save time or on every request.

How to use it: automatic. In page documents the sources other than user, query, woo, term and item are read at compile time. The value goes into the node and the page records the dependency bind:<source>:<field>. In the other cases the compiler writes a token __NCB<n>__ and the nc/bind slot replaces it on every request. Layout and sections are always dynamic.

Parameters: None

Permissions: none.

Edition: Free

Known limits: an empty static value uses the fallback. Inside a card the bind reads the current item. Outside, the queried post.

Value escaping

What it does: applies the right escape to each dynamic value.

How to use it: automatic. content.html uses wp_kses_post. The keys ending with src, url, href or poster use esc_url. The others use esc_html.

Parameters: None

Permissions: none.

Edition: Free

Known limits: None found.

Recompilation when meta changes

What it does: recompiles a page when a meta read by one of its static binds changes.

How to use it: automatic on added_post_meta and updated_post_meta. It applies to the dependencies bind:metabox:<key>, bind:acf:<key>, bind:post:meta:<key>.

Parameters: None

Permissions: none.

Edition: Free

Known limits: meta with the _ prefix are ignored. Deleting a meta does not recompile. The watcher is registered in admin, REST and CLI, not in frontend requests.

09Media

Saving images

What it does: saves an image as an attachment of the media library, with alternative text and title.

How to use it: internal, used by nucleo/media-import and nucleo/media-upload. It checks the real type with getimagesizefromstring, not the declared header. The file extension comes from the real type. The save goes through media_handle_sideload, so WordPress generates the intermediate sizes.

Parameters: None for the user.

Permissions: those of the abilities that use it.

Edition: Free

Known limits: formats image/jpeg, image/png, image/webp, image/gif, image/avif. Empty content or >= 10 MB: download_failed. Type not allowed: unsupported_type.

Import from URL

What it does: downloads a public image and saves it in the library.

How to use it: nucleo/media-import. Response { ok, id, url, width, height } or { ok: false, error }.

Parameters:

NameTypeAllowed valuesDefaultNotes
urlstringhttps URL of a public hostrequired
altstringtextrequiredEmpty string for decorative images.
titlestringtextnoneTitle of the attachment.

Permissions: upload_files; scope nucleo:write.

Edition: Free

Known limits: UrlGuard with DNS resolution: error invalid_url for private hosts, localhost, credentials or a scheme other than https. Timeout 15 seconds. Response other than 200: download_failed. File name from the URL path. Does not recognize duplicates.

Upload from base64

What it does: saves an image sent in base64. An identical file already uploaded is returned without duplicating it.

How to use it: nucleo/media-upload. Response { ok, id, url, width, height, file, sha1, existing }.

Parameters:

NameTypeAllowed valuesDefaultNotes
filestringname with extensionrequiredGives the name of the saved file. The extension comes from the real type.
datastringbase64required
altstringtext''
titlestringtextnone

Permissions: upload_files; scope nucleo:write.

Edition: Free

Known limits: invalid base64: invalid_data. A duplicate is recognized with the SHA-1 in the _nucleo_sha1 meta and with the original file name (<name> or <name>-<n>). Images above 2560 px are compared on the original file, not on the -scaled copy.

AVIF and WebP formats

What it does: generates AVIF and WebP copies of the original and of the intermediate sizes. nc/image and nc/post-image offer them in <picture>, with the original as fallback.

How to use it: turned on with the site option imageFormats, for example ["avif", "webp"], through nucleo/site-options-set. Images uploaded later get the formats by themselves. For the ones already present use nucleo/media-formats. In image blocks formats: "off" turns the sources off.

Parameters (nucleo/media-formats):

NameTypeAllowed valuesDefaultNotes
idsarray of integer1–50 ids of image attachmentsnoneOther ids are skipped.
missingbooleantrue, falsefalseOnly the images without any of the formats turned on.
limitinteger1–5020Applies without ids. Order by ascending id.

Response { ok, done: [{id, formats}], enabled, supported, remaining }.

Permissions: nucleo/media-formats requires upload_files; scope nucleo:write. nucleo/site-options-set requires manage_options; scope nucleo:admin.

Edition: Free

Known limits: option imageFormats with duplicates or values other than avif and webp: invalid_input. Empty option: media-formats responds formats_disabled. Only the formats that the server image editor can write (supported) are generated. The format equal to the original is skipped. The files are named <file>.<format> in the same folder and listed in the _nucleo_formats meta. The srcset uses only the sizes with the proportions of the original. Deleting the attachment deletes the copies too. An editor error on one size skips it silently.

Esc
↑↓ to select↵ to openEsc to closeLocal search, no data sent