Gravity Forms
Сборка:
cd ../../../onepix/wp2lms && …(Turbo core) при необходимости;cd wp2lms-turbo-blocks-mos && npm run build. Корневыеnpm run build:core|blocksв monorepo отсутствуют.
Vendor block gravityforms/form is remapped to Turbo Twig + shared form controls. GF theme JS/CSS are not loaded on static pages.
Enablement
Section titled “Enablement”- Requires Gravity Forms plugin (
GFAPI). - Mapping / inserter / REST register when GF is active (independent of xAPI auth).
- Opt-in WP learner session: Settings → Turbo → Авторизация ученика по xAPI actor (
enable_xapi_actor_session). Without it, entries are guests (created_by = 0).
See also: XAPI_ACTOR_SESSION.md.
Architecture
Section titled “Architecture”- Editor: allowlist via
BlockMapping; category «Вставки» after Tripetto. - Static render:
GFAPI::get_form→FieldTypeRegistry→GravityForm.twig. - Client: deferred
gravity-form.js(frontendScripts) → AlpineturboGravityForm. - Submit:
POST /wp-json/wp2turbo/v1/gravity-forms/submit→GFAPI::submit_form(primary). - Fallback (when REST transport fails, e.g. local nginx 405):
admin-ajax.php?action=heartbeatwith nesteddata[wp2t]→ same controller.
Progress / blocking
Section titled “Progress / blocking”Block supports progressAward / progressAmount («Установить прогресс»). On successful submit: data-turbo-progress="gravity-form" → markRootProgressPassed (via window.wp2turboMarkProgress).
Step progress chrome (N/M + bar) is UI-only for multipage forms — not LMS progress.
Multipage
Section titled “Multipage”Page breaks (page fields) become pages[]. UX mirrors Question Bank: badge, track fill, opacity enter animation, focus + live region. Single-page forms hide the chrome.
Supported field types
Section titled “Supported field types”Standard: text, textarea, number, hidden, html, section, page, select, radio, checkbox, image_choice, multi_choice.
Advanced: email, phone, website, password, name, address, date, time, fileupload, list, multiselect, consent, poll, quiz, survey, likert, rank, rating.
Poll / Quiz honor GF Poll Type / Quiz Type (inputType: radio | select | checkbox) and render the matching choice control.
After submit, when Gravity Forms Polls is active and the form has display results enabled, REST returns structured pollResults (per-field choices with label, ratio, count, selected). Confirmation text keeps the thank-you message only — vendor .gpoll_* HTML is stripped. Alpine renders horizontal CSS bars (.wp2turbo-poll-results), not Chart.js / Mermaid / addon CSS.
Survey honors Survey Field Type (inputType):
| Type | UI |
|---|---|
likert |
Horizontal scale (labels + radio track); multi-row table when gsurveyLikertEnableMultipleRows |
rank |
Same SortableJS UI as Question Sort (⋮⋮ + ↑↓) → hidden CSV of choice values; needs sortable frontend script |
rating |
Star radios (reversed flips choice order like GF) |
radio / checkbox / select / text / textarea |
Existing choice / text controls |
Post: post_title, post_content, post_excerpt, post_tags, post_category, post_image, post_custom_field.
Optional: username when the User Registration addon is present. chainedselect is unsupported in Turbo static (shows fallback UI; hidden when «Скрыть неподдерживаемые поля» is on).
Unsupported (fallback UI): captcha / turnstile / recaptcha / signature / repeater / dropbox / pipe / all pricing & payment types.
Phone mask
Section titled “Phone mask”Turbo phone fields use the RU mask +7 999 999 99 99 with placeholder +7 999 123 45 67 (example digits, not #). Paste of 8… / 7… / 10-digit national numbers is normalized. GF “standard” (US) validation is relaxed for these values on Turbo submit.
Section Break
Section titled “Section Break”Renders label/description around the shared Gutenberg Separator component (Separator/Separator.twig, wide style).
Image Choice
Section titled “Image Choice”Choice images come from GF file_url / attachment_id (resolved to a media URL at render).
File upload
Section titled “File upload”Modern dropzone: drag-and-drop, remove, reorder (when multipleFiles), client checks for allowed extensions, maxFiles, and maxFileSize (MB → bytes; falls back to WordPress max upload size).
Conditional Logic
Section titled “Conditional Logic”Client-side field visibility mirrors GF Conditional Logic (show / hide, all / any).
Operators: is, isnot, contains, starts_with, ends_with, greater_than, less_than. Checkbox sub-inputs (input_N.M) are supported.
Rule values must match the choice value configured in GF (not only the label text).
Also supported (same rule model):
- Page skip —
pagefieldconditionalLogic→pagesMeta[i].conditionalLogic; hidden pages are skipped by Next/Previous. - Next button —
nextButton.conditionalLogic/ text on the page field → show/hide Next and optional label. - Submit button —
form.button.conditionalLogic→submitConditionalLogic.
Next / Submit are disabled (like Question Choice) until all visible required controls on the current page are filled (canGoNext / canSubmit).
Merge tags
Section titled “Merge tags”- At render:
GFCommon::replace_variables_prepopulateviaGravityFormsMergeTagsfor title, description, confirmation HTML, labels, defaults, HTML content, choice text, button labels. Entry-dependent tags (e.g.{quiz_score}) stay unresolved until submit. - HTML fields: after merge tags, content runs through GF’s shortcode path (
[embed]+do_shortcode), so Gutenberg reusable/pattern shortcodes such as[wp_reusable_render id='1062']render as normal front-end HTML inside the form. Assets required by those blocks must already be available on the page (or baked into a static compile). - After submit: confirmation / merge tags from
GFAPI::submit_form(unchanged).
Default values
Section titled “Default values”GF Default Value (and selected choices / per-input defaults on Name & Address) are passed as defaultValues into Alpine so x-model does not wipe HTML defaults. Merge tags in defaults are prepopulated at render. Calculation fields ignore static defaults (live formula wins).
Client validation
Section titled “Client validation”Required / format / min–max (Number) / maxLength checks run in the browser as the user types (and on blur). Field messages appear under the control. Maximum Characters shows as a current/max badge (12px) in the control corner. Full GF rules still apply on REST submit.
Number calculations
Section titled “Number calculations”number fields with enableCalculation + calculationFormula get live Alpine recalculation (GFCalc subset: {…:id} → values, whitelist 0-9 -+/*(), numberFormat decimal_dot/comma). UI shows the result as plain text (hidden input for submit), not an editable control. Pricing fields are not supported. Server still recalculates with GFCommon::calculate on submit.
GF Form Editor (optional)
Section titled “GF Form Editor (optional)”Settings → Turbo → Скрыть неподдерживаемые поля Gravity Forms (hide_unsupported_gf_fields, default off). When on, gform_field_groups_form_editor / gform_add_field_buttons drop Pricing group and Turbo-unsupported types (captcha, signature, payment, …). Does not change runtime fallback on static pages. Not a Gutenberg allowlist.
Submit / caching
Section titled “Submit / caching”- UI + Conditional Logic run entirely in the browser (OK on cached HTML).
- Submit tries REST first:
POST /wp-json/wp2turbo/v1/gravity-forms/submit(JSON; multipart when files are present). - If REST transport fails (typical local nginx 405 / HTML error page), falls back to
admin-ajax.php?action=heartbeatwith nesteddata[wp2t](base64 values). Turbo intercepts heartbeat at priority 0. - Static HTML refreshes
wp_rest/ heartbeat nonces viadata[wp2t_boot]=1before submit (compile-time nonces are user-bound and expire). After a REST transport failure, the page sticks to heartbeat for the rest of the load. restNonceis embedded at render time; long-lived full-page caches may need a fresh nonce strategy.
Columns
Section titled “Columns”layoutGridColumnSpan and legacy gf_*_half|third|quarter → .wp2turbo-form__field--w-* in a 12-col grid.
Shortcodes
Section titled “Shortcodes”[gravityform id="N"] / [gravityforms id="N"] remapped by GravityFormsContentProcessor.
Builds
Section titled “Builds”npm run build:frontend --prefix ../../../onepix/wp2lms/src/Modules/Turbonpm run build:corenpm run build:blocks