feat: short-form level for every module with a heading title (trial)
contact-form, cta, toggle, accordion-item, slide, number-counter and team-member (name) take level like heading/blurb; paths from Divi's conversion outlines, checked live with divi-shortform-check.php. A test keeps the guide's field table in sync with ShortformMap. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
This commit is contained in:
@@ -31,7 +31,9 @@ Neue Divi-Inhalte beschreibt man als JSON-Knoten. `lit-divi-insert` (in `nodes`)
|
||||
Icon-Liste) bekommen ihre Einträge in `items`; der Eintragstyp ergibt sich von selbst.
|
||||
- `label` fehlt → Admin-Label „<Abschnitt> – <Modul>“, z. B. „Hero – Button“; Zeilen „Hero – Zeile“, eine Zeile
|
||||
in einer Spalte „Hero – Zeile (innen)“. Abschnitten deshalb ein Label geben.
|
||||
- `heading` ohne `level` wird `h2` (eine Seite hat meist schon eine `h1` im Titel).
|
||||
- `heading` ohne `level` wird `h2` (eine Seite hat meist schon eine `h1` im Titel). Auch Module mit Titel
|
||||
(`blurb`, `cta`, `toggle`, Akkordeon-Eintrag, Slide, `contact-form`, `number-counter`, `team-member`) nehmen
|
||||
`level` (`h1`–`h6`); ohne `level` gilt Divis Standard (beim Kontaktformular `h1` – daher meist `h2` setzen).
|
||||
|
||||
## Kurzform-Felder
|
||||
|
||||
@@ -42,20 +44,20 @@ Neue Divi-Inhalte beschreibt man als JSON-Knoten. `lit-divi-insert` (in `nodes`)
|
||||
| `button` | `text`, `url`, `new_window` (true/false) |
|
||||
| `image` | `image_id` (Mediathek, setzt URL/ID/Alt), `src`, `alt`, `title`, `url` |
|
||||
| `blurb` | `title`, `url`, `content`, `image_id`, `src`, `alt`, `level` |
|
||||
| `cta` | `title`, `content`, `button_text`, `button_url` |
|
||||
| `cta` | `title`, `content`, `button_text`, `button_url`, `level` |
|
||||
| `icon` | `url`, `title` |
|
||||
| `divider` | `show`, `color` |
|
||||
| `testimonial` | `author`, `job_title`, `company`, `company_url`, `content`, `portrait_id`, `portrait_url` |
|
||||
| `team-member` | `name`, `position`, `content`, `image_id`, `image_url` |
|
||||
| `accordion` → `accordion-item` | Eintrag: `title`, `content`, `open` |
|
||||
| `team-member` | `name`, `position`, `content`, `image_id`, `image_url`, `level` (des Namens) |
|
||||
| `accordion` → `accordion-item` | Eintrag: `title`, `content`, `open`, `level` |
|
||||
| `tabs` → `tab` | Eintrag: `title`, `content` |
|
||||
| `toggle` | `title`, `content`, `open` |
|
||||
| `toggle` | `title`, `content`, `open`, `level` |
|
||||
| `gallery` | `image_ids` (Liste von Anhang-IDs) |
|
||||
| `slider` → `slide` | Eintrag: `title`, `content`, `button_text`, `button_url`, `image_id`, `src`, `alt` |
|
||||
| `contact-form` → `contact-field` | Formular: `title`, `email`, `success_message`, `submit_text`; Feld: `title`, `id`, `type` (`input`, `email`, `text`, `checkbox`, `radio`, `select`), `required` |
|
||||
| `slider` → `slide` | Eintrag: `title`, `content`, `button_text`, `button_url`, `image_id`, `src`, `alt`, `level` |
|
||||
| `contact-form` → `contact-field` | Formular: `title`, `level`, `email`, `success_message`, `submit_text`; Feld: `title`, `id`, `type` (`input`, `email`, `text`, `checkbox`, `radio`, `select`), `required` |
|
||||
| `map` → `map-pin` | Karte: `address`, `lat`, `lng`, `zoom`; Pin: `title`, `content`, `address`, `lat`, `lng` |
|
||||
| `video` | `src`, `thumbnail` |
|
||||
| `number-counter` | `number`, `title`, `percent` |
|
||||
| `number-counter` | `number`, `title`, `percent`, `level` |
|
||||
| `social-media-follow` → `social-media-follow-network` | Eintrag: `network` (z. B. `facebook`), `url`, `label` |
|
||||
| `icon-list` → `icon-list-item` | Eintrag: `text` |
|
||||
| `code` | `content` – nur, wenn kein natives Modul passt (Warnung) |
|
||||
|
||||
@@ -166,6 +166,7 @@ final class ShortformMap
|
||||
'content' => $content,
|
||||
'button_text' => $buttonText,
|
||||
'button_url' => $buttonUrl,
|
||||
'level' => $level,
|
||||
]),
|
||||
'icon' => self::module(null, [
|
||||
'url' => self::field('icon.innerContent', 'url', 'url', 'Linkziel'),
|
||||
@@ -190,12 +191,28 @@ final class ShortformMap
|
||||
'content' => $content,
|
||||
'image_id' => $media('image.innerContent', ['url', null, null], 'Foto aus der Mediathek'),
|
||||
'image_url' => self::field('image.innerContent', 'url', 'url', 'Foto-URL'),
|
||||
'level' => self::field(
|
||||
'name.decoration.font.font',
|
||||
'headingLevel',
|
||||
'level',
|
||||
'Überschriftenebene des Namens h1–h6'
|
||||
),
|
||||
]),
|
||||
'accordion' => self::module(null, [], 'accordion-item'),
|
||||
'accordion-item' => self::module('title', ['title' => $title, 'content' => $content, 'open' => $open]),
|
||||
'accordion-item' => self::module('title', [
|
||||
'title' => $title,
|
||||
'content' => $content,
|
||||
'open' => $open,
|
||||
'level' => $level,
|
||||
]),
|
||||
'tabs' => self::module(null, [], 'tab'),
|
||||
'tab' => self::module('title', ['title' => $title, 'content' => $content]),
|
||||
'toggle' => self::module('title', ['title' => $title, 'content' => $content, 'open' => $open]),
|
||||
'toggle' => self::module('title', [
|
||||
'title' => $title,
|
||||
'content' => $content,
|
||||
'open' => $open,
|
||||
'level' => $level,
|
||||
]),
|
||||
'gallery' => self::module('image_ids', [
|
||||
'image_ids' => self::field('image.advanced.galleryIds', null, 'ids', 'Anhang-IDs, z. B. [12, 33]'),
|
||||
]),
|
||||
@@ -208,9 +225,11 @@ final class ShortformMap
|
||||
'image_id' => $media('image.innerContent', ['src', null, 'alt'], 'Bild aus der Mediathek'),
|
||||
'src' => self::field('image.innerContent', 'src', 'url', 'Bild-URL'),
|
||||
'alt' => self::field('image.innerContent', 'alt', 'text', 'Alt-Text'),
|
||||
'level' => $level,
|
||||
]),
|
||||
'contact-form' => self::module(null, [
|
||||
'title' => $title,
|
||||
'level' => $level,
|
||||
'email' => self::field('email.advanced.receiver', null, 'text', 'Empfänger (leer = Admin-E-Mail)'),
|
||||
'success_message' => self::field('module.advanced.successMessage', null, 'text', 'Text nach Absenden'),
|
||||
'submit_text' => self::field('button.innerContent', 'text', 'text', 'Beschriftung Absenden'),
|
||||
@@ -244,6 +263,7 @@ final class ShortformMap
|
||||
'number' => self::field('number.innerContent', null, 'text', 'Zahl'),
|
||||
'title' => $title,
|
||||
'percent' => self::field('number.advanced.enablePercentSign', null, 'onoff', 'Prozentzeichen anzeigen'),
|
||||
'level' => $level,
|
||||
]),
|
||||
'social-media-follow' => self::module(null, [], 'social-media-follow-network'),
|
||||
'social-media-follow-network' => self::module('url', [
|
||||
|
||||
@@ -202,4 +202,41 @@ final class ModuleCatalogTest extends TestCase
|
||||
self::assertSame('richtext', $catalog->pathKind('divi/text', 'content.innerContent'));
|
||||
self::assertIsString($catalog->kinds('divi/text')['content.innerContent']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trial feedback: every short-form module with a heading title offers `level` (Divi's
|
||||
* conversion outlines map header_level/title_level to <title>.decoration.font.font headingLevel).
|
||||
*/
|
||||
public function testModulesWithAHeadingTitleOfferLevel(): void
|
||||
{
|
||||
$expected = [
|
||||
'heading' => 'title', 'blurb' => 'title', 'cta' => 'title', 'toggle' => 'title',
|
||||
'accordion-item' => 'title', 'slide' => 'title', 'contact-form' => 'title',
|
||||
'number-counter' => 'title', 'team-member' => 'name',
|
||||
];
|
||||
foreach ($expected as $type => $element) {
|
||||
$level = ShortformMap::fields($type)['level'] ?? null;
|
||||
self::assertNotNull($level, $type);
|
||||
self::assertSame($element . '.decoration.font.font', $level['path'], $type);
|
||||
self::assertSame('headingLevel', $level['sub'], $type);
|
||||
self::assertSame('level', $level['kind'], $type);
|
||||
}
|
||||
}
|
||||
|
||||
/** The field table of the divi-shortform guide lists every short-form field. */
|
||||
public function testShortformGuideTableListsEveryField(): void
|
||||
{
|
||||
$guide = (string) file_get_contents(dirname(__DIR__, 5) . '/docs/guides/divi-shortform.md');
|
||||
$rows = array_values(array_filter(
|
||||
explode("\n", $guide),
|
||||
static fn (string $line): bool => str_starts_with($line, '| `')
|
||||
));
|
||||
foreach (ShortformMap::types() as $type) {
|
||||
$row = current(array_filter($rows, static fn (string $line): bool => str_contains($line, '`' . $type . '`')));
|
||||
self::assertIsString($row, $type . ' has a row');
|
||||
foreach (array_keys(ShortformMap::fields($type)) as $field) {
|
||||
self::assertStringContainsString('`' . $field . '`', $row, $type . '.' . $field);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user