Status: COMPLETE — all phases shipped; 5.0.0 released Created: 2026-07-03
Consolidate the PHP (v3) and Python (v4) engines onto a single shared
schema, and retire the lossy HTML-intermediate translate path. 5.0 ends
with one conversion semantics — the lossless universal-element model — with
both engines as conforming implementations of the same spec.
The 4.7–4.11 line completed both prerequisites:
- All 14 frameworks parse natively in Python (parsers) and all 14 have Python converters — the lossless engine is feature-complete.
- The PHP engine mirrors the same verified schemas (real-format verification v4.4.0–v4.6.0) and shares the canonical responsive model.
What still differs is the interchange shape: PHP passes
DEVTB_Component objects (type/attributes/content/children);
Python passes Elementor-shaped element dicts
(elType/widgetType/settings/elements). Converters on each side
carry ad-hoc adapters for the other's vocabulary (e.g. the Python
Gutenberg converter's _convert_component translation layer). 5.0 removes
that seam.
The universal element document — normatively specified in
schema/universal-element.schema.json
— is the Python engine's element-dict shape, chosen because every converter
in both engines already consumes it (directly in Python; via adapters in
PHP):
{
"elements": [
{
"id": "abc123",
"elType": "section | container | column | widget",
"widgetType": "heading",
"settings": {"title": "…", "header_size": "h2"},
"elements": [],
"isInner": true,
"responsive": {"styles": {…}, "fields": {…}}
}
],
"version": "", "title": "", "meta": {}
}Settings use the Elementor-style key vocabulary already shared by all 14
Python parsers (title/header_size, editor, text + link{url, is_external}, image{url, alt}, testimonial_*, tabs[], icon_list[],
html, …). The responsive object is the canonical model from v4.5.0
(breakpoints desktop/tablet/phone, states default/hover).
- Publish the JSON Schema as the normative spec.
- Add
DEVTB_Component::to_universal()so the PHP engine can emit the canonical shape. - Add a dual-engine conformance suite: shared real fixtures (Elementor kitchen-sink, DIVI kitchen-sink, the real Breakdance export) are parsed by BOTH engines; outputs must validate against the schema and agree on extracted content. Runs in CI with the Python suite.
DEVTB_Universal(core) bridges both directions:components_to_document()anddocument_to_components().- Translator entry points:
parse_to_universal($content, $source)andtranslate_universal($document, $target). - REST:
source/targetacceptuniversalon/translate— send a universal document as input, or receive the parsed document as output. - Cross-engine interchange is conformance-tested in both directions (Python-parsed → PHP-converted and PHP-parsed → Python-converted).
- The Python Gutenberg converter's ad-hoc component adapter is gone:
translation_bridge.interchangemirrorsDEVTB_Component::to_universal()exactly — the conformance suite assertscomponent_to_element(to_array()) == to_universal()on real fixtures — and the converter delegates to it. Collection vocabularies (icon_list,wp_gallery,selected_icon,alert_*, CTA links) now survive the component round trip in both engines.
DEVTB_Translator::translate()routes every pair through parse → universal → convert (all 182 pairs green through the matrix). The v3 mapping engine survives only as the content-extraction fallback, gated by a content-survival check on the universal round trip.devtb translateis a deprecated alias riding the same lossless path (removed in 5.0); the Python CLI acceptstranslateas an alias oftransform, and unregistered Python pairs go through the universal route behind a runtime fidelity gate.- Fidelity metrics (content strings preserved / total, route used) are reported per conversion in translator stats and both CLIs.
- The cross-source fidelity matrix (
tests/python/test_universal_matrix.py) holds every Python converter to ≥90% content survival from every source parser — the Python analog of the PHP 182-pair matrix. All 14 converters handle nested structural shapes, the full canonical widget vocabulary, and fall back content-preservingly;translation_bridge.interchangeis now fully bidirectional (element ⇄ component, both PHP mirrors).
- The HTML-intermediate pipeline is gone:
class-mapping-engine.phpdeleted (the v3 similarity-scoring mapper), the translator's mapping-fallback branch removed — the content-survival check is now an advisory warning quantified by the per-conversion fidelity stat. All 182 matrix pairs pass on the universal route alone. - The
DEVTB_Componentshape is no longer an interchange format anywhere: no public surface accepts or emits it (REST never did; the mapping engine was its last pipeline consumer). It survives only as the PHP engine's internal model and as deprecated back-compat input to Python converters (slated for 5.1 review). translatealias retained for one minor (removed in 5.1).- Single documented engine story: “one schema, two conforming runtimes.”
Phases 1–2 are additive. Phase 3 changes internals but preserves CLI/REST surfaces. Phase 4 is the 5.0.0 breaking release; deprecations land at least one minor release ahead.
- Dropping the PHP runtime (WordPress hosts need it — it stays as a conforming implementation).
- New framework coverage (orthogonal to consolidation).