Data Structures

Understanding Divi's Data Structure

⏱ 16 min

Divi’s storage model is a genuinely different problem from Elementor’s, and it’s currently in the middle of a real transition worth understanding before you write any parsing code. Classic Divi encodes its entire layout as nested shortcodes directly in post_content. Divi 5 is moving away from that toward a JSON-based format. This lesson covers both, and how to tell which one you’re actually looking at on a given site.

What you'll learn in this lesson
The classic Divi shortcode format
How et_pb_section, et_pb_row, et_pb_column, and module shortcodes nest inside post_content.
Why shortcode attributes are the settings
Where a module's styling and behavior actually live, versus its visible text content.
The Divi 5 shift away from shortcodes
A new JSON format, a migration process, and a backward-compatibility window.
How to safely parse shortcodes at all
Using WordPress's own shortcode functions instead of hand-rolled regex.
Prerequisites

Lesson 1’s framing of the gap. Ideally a WordPress site running Divi so you can compare this lesson’s description against your own site’s actual post_content.

Step 1: Classic Divi stores layout as shortcodes in post_content

Unlike Elementor, classic Divi doesn’t use a separate post meta field for its layout. The entire page structure is written as nested WordPress shortcodes directly inside post_content, using Divi’s own shortcode names: [et_pb_section] for a top-level section, [et_pb_row] for a row inside it, [et_pb_column] for a column inside a row, and module shortcodes like [et_pb_text], [et_pb_image], or [et_pb_button] for the actual content inside a column. A simple page might look like this in raw post_content:

[et_pb_section fb_built="1" admin_label="Hero"]
  [et_pb_row admin_label="Row"]
    [et_pb_column type="4_4"]
      [et_pb_text admin_label="Headline" text_orientation="center"]
        <h1>Welcome to our site</h1>
      [/et_pb_text]
    [/et_pb_column]
  [/et_pb_row]
[/et_pb_section]

Divi hides this view entirely inside its own visual builder, the raw shortcode text only becomes visible if you inspect post_content directly (via WP-CLI, the database, or by temporarily switching away from Divi’s builder view on the post).

Step 2: Attributes are the settings, tag content is often the body

Where Elementor puts everything in a settings object, Divi splits it across two places. Shortcode attributes (type="4_4", text_orientation="center", and so on) hold styling and configuration, the same role Elementor’s settings object plays. For modules whose primary content is a body of text or markup, like et_pb_text, that content sits between the opening and closing shortcode tags rather than in an attribute. Other modules encode their entire content as attributes, for example et_pb_button typically carries its button text and link as attributes rather than tag content. There isn’t one universal rule across every Divi module, confirm which pattern a specific module uses by inspecting a real saved page before writing code that assumes one or the other.

Global modules complicate this further

Divi supports global modules and global layouts, referenced by an ID attribute (for example global_module="12345") rather than by their full shortcode markup appearing inline. If you’re editing a page that uses a global module, the actual settings you need to change may live on a different post entirely (the library item the global module points to), not inline in the page’s own post_content. Check for a global_module or similar reference attribute before assuming the shortcode you’re looking at holds the real content.

Step 3: Divi 5 is moving away from shortcodes

Elegant Themes has been explicit that Divi 5 replaces this shortcode-based storage with a new JSON format, described by Elegant Themes as conceptually similar to how the WordPress block editor stores its own data, aimed at faster rendering and fewer bugs from deeply nested shortcode attribute parsing. Upgrading to Divi 5 triggers a migration process that converts existing shortcode-based content to the new format, and Elegant Themes has said old shortcodes continue to work for a transition period for backward compatibility.

Before writing any Divi parsing code
Check the Divi version installed
Divi 5's storage format is genuinely different from every version before it.
Check whether the migration has actually run
A Divi 5 install can still hold pages in the old shortcode format until migrated.
Inspect post_content directly, don't assume
wp post get <id> --field=post_content on your own real page, every time.

Step 4: Parse shortcodes with WordPress’s own functions, not regex

Because Divi shortcodes nest arbitrarily deep and can share attribute names across different module types, hand-rolled regex to find and edit one specific shortcode is genuinely risky, it’s easy to match the wrong closing tag in a deeply nested structure. WordPress core ships real functions built for exactly this: get_shortcode_regex() generates a regex covering all registered shortcode tags, and shortcode_parse_atts() correctly parses a shortcode’s attribute string into an associative array, handling quoted values and boolean-style attributes the way WordPress itself does. Building on these core functions, rather than a custom pattern, keeps your parsing aligned with how WordPress (and Divi) already interpret the same markup.

Test it: confirm which format your site actually uses

# File: terminal
wp post get <post_id> --field=post_content

If you see readable shortcode markup like [et_pb_section], you’re looking at the classic format this lesson describes in detail. If you see something that looks like JSON or a Gutenberg-style block comment instead, the site has moved to Divi 5’s newer format, and you’ll need to verify that format’s real current shape directly against Elegant Themes’ own documentation before writing any parsing code against it, since it was still actively evolving at the time of writing.

Treating post_content as safe to string-replace

Even once you can locate a shortcode with get_shortcode_regex(), resist the urge to edit its attributes with a plain string replace. Divi shortcode attributes can contain HTML markup, quotes, and nested shortcodes as their value, a naive string replace can easily corrupt an attribute boundary and silently break the rest of the page, since Divi’s shortcode parser is order-sensitive top to bottom. Parse into a structured representation first, edit that, then re-serialize it back into shortcode text.

Recap

Classic Divi stores its entire layout as nested WordPress shortcodes directly inside post_content, section, row, and column shortcodes for structure, and module-specific shortcodes like et_pb_text for content, with settings split between shortcode attributes and, for some modules, the text between the opening and closing tags. Divi 5 is actively replacing that with a JSON-based format. Either way, use WordPress’s own get_shortcode_regex() and shortcode_parse_atts() rather than hand-rolled regex, and always confirm which format a given site is actually using before writing code against it.

Resources & further reading

← Understanding Elementor's Data Structure Building an Ability That Edits an Elementor Component Safely →