Cms: Bard: unable to save when text includes a hard line break

Created on 12 Jul 2019  ·  8Comments  ·  Source: statamic/cms

I paste some text into Bard, resulting in the value of BardFieldtype to contain the following (minified, as string):

[
    {
        "type": "paragraph",
        "content": [
            {
                "type": "text",
                "text": "Vorbereitungszeit ca. 10 Minuten "
            },
            {
                "type": "hard_break"
            },
            {
                "type": "text",
                "text": "Backzeit ca. 15 Minuten"
            }
        ]
    },
    {
        "type": "heading",
        "attrs": {
            "level": 3
        },
        "content": [
            {
                "type": "text",
                "text": "Rezept für 4 Personen"
            }
        ]
    },
    {
        "type": "bullet_list",
        "content": [
            {
                "type": "list_item",
                "content": [
                    {
                        "type": "paragraph",
                        "content": [
                            {
                                "type": "text",
                                "text": "1 Baguette"
                            }
                        ]
                    }
                ]
            },
            {
                "type": "list_item",
                "content": [
                    {
                        "type": "paragraph",
                        "content": [
                            {
                                "type": "text",
                                "text": "50 ml Olivenöl"
                            }
                        ]
                    }
                ]
            },
            {
                "type": "list_item",
                "content": [
                    {
                        "type": "paragraph",
                        "content": [
                            {
                                "type": "text",
                                "text": "4 Ochsenherztomaten"
                            }
                        ]
                    }
                ]
            },
            {
                "type": "list_item",
                "content": [
                    {
                        "type": "paragraph",
                        "content": [
                            {
                                "type": "text",
                                "text": "1 rote Zwiebel"
                            }
                        ]
                    }
                ]
            },
            {
                "type": "list_item",
                "content": [
                    {
                        "type": "paragraph",
                        "content": [
                            {
                                "type": "text",
                                "text": "2 Knoblauchzehen"
                            }
                        ]
                    }
                ]
            },
            {
                "type": "list_item",
                "content": [
                    {
                        "type": "paragraph",
                        "content": [
                            {
                                "type": "text",
                                "text": "250g Mozzarella"
                            }
                        ]
                    }
                ]
            },
            {
                "type": "list_item",
                "content": [
                    {
                        "type": "paragraph",
                        "content": [
                            {
                                "type": "text",
                                "text": "Salz"
                            }
                        ]
                    }
                ]
            },
            {
                "type": "list_item",
                "content": [
                    {
                        "type": "paragraph",
                        "content": [
                            {
                                "type": "text",
                                "text": "grober Pfeffer"
                            }
                        ]
                    }
                ]
            },
            {
                "type": "list_item",
                "content": [
                    {
                        "type": "paragraph",
                        "content": [
                            {
                                "type": "text",
                                "text": "½ Bund Basilikum"
                            }
                        ]
                    }
                ]
            },
            {
                "type": "list_item",
                "content": [
                    {
                        "type": "paragraph",
                        "content": [
                            {
                                "type": "text",
                                "text": "4 EL Mazzetti Bio Cremaceto"
                            }
                        ]
                    }
                ]
            }
        ]
    },
    {
        "type": "paragraph",
        "content": [
            {
                "type": "text",
                "text": "Utensilien: Backofen, Messer, Brett, Löffel, Backblech, Backpapier."
            }
        ]
    },
    {
        "type": "paragraph",
        "content": [
            {
                "type": "text",
                "text": "Video Headline 24 (2XL)"
            }
        ]
    },
    {
        "type": "paragraph",
        "content": [
            {
                "type": "text",
                "text": " Caption 14(S) Credit 14 (S)"
            }
        ]
    },
    {
        "type": "ordered_list",
        "attrs": {
            "order": 1
        },
        "content": [
            {
                "type": "list_item",
                "content": [
                    {
                        "type": "paragraph",
                        "content": [
                            {
                                "type": "text",
                                "text": "Backofen vorheizen (Ober-/Unterhitze: 200 °C/Umluft: 175 °C). Baguette aufschneiden und der Länge nach in Streifen schneiden. Mit Olivenöl beträufeln und auf oberer Schiene im Ofen ca. 5 Minuten backen."
                            }
                        ]
                    }
                ]
            },
            {
                "type": "list_item",
                "content": [
                    {
                        "type": "paragraph",
                        "content": [
                            {
                                "type": "text",
                                "text": "In der Zwischenzeit Tomaten waschen, trocken tupfen, den oberen Teil als Deckel abschneiden und das Kerngehäuse mit einem Löffel auskratzen. Zwiebel und Knoblauch schälen und in feine Würfel schneiden."
                            }
                        ]
                    }
                ]
            },
            {
                "type": "list_item",
                "content": [
                    {
                        "type": "paragraph",
                        "content": [
                            {
                                "type": "text",
                                "text": "Mozzarella abtropfen und in Würfel schneiden. Tomaten auf ein mit Backpapier ausgelegtes Blech legen und mit Zwiebel, Knoblauch und Mozzarella befüllen. Mit Salz und Pfeffer würzen. Deckel auf die Tomaten setzen und auf mittlerer Schiene im Ofen ca. 15 Minuten backen."
                            }
                        ]
                    }
                ]
            },
            {
                "type": "list_item",
                "content": [
                    {
                        "type": "paragraph",
                        "content": [
                            {
                                "type": "text",
                                "text": "Basilikum waschen, trocken schütteln und Blätter klein hacken."
                            }
                        ]
                    }
                ]
            },
            {
                "type": "list_item",
                "content": [
                    {
                        "type": "paragraph",
                        "content": [
                            {
                                "type": "text",
                                "text": "Deckel der Tomaten abnehmen und jede Tomate mit 1 EL Mazzetti Bio Cremaceto beträufeln. Tomaten mit Basilikum garnieren und mit Baguette servieren."
                            }
                        ]
                    }
                ]
            }
        ]
    },
    {
        "type": "paragraph",
        "content": [
            {
                "type": "text",
                "marks": [
                    {
                        "type": "bold"
                    }
                ],
                "text": "Tipp:"
            },
            {
                "type": "text",
                "text": " Noch mehr italienisches Flair gibt es mit der Wahl von Ciabatta. Ciabatta ist ein flaches, breites Brot aus Mehl, Salz, Hefe, Wasser und Olivenöl. Die deutsche Übersetzung lauetet Pantoffel."
            }
        ]
    }
]

When I hit save, it throws:

[2019-07-12 13:37:13] local.ERROR: Undefined property: stdClass::$index {"userId":"30c0cce7-cfb2-4a03-bb81-f3286ca63cf6","exception":"[object] (ErrorException(code: 0): Undefined property: stdClass::$index at /var/www/core/app/Fieldtypes/Bard/SetNode.php:21)
[stacktrace]
#0 /var/www/core/app/Fieldtypes/Bard/SetNode.php(21): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError(8, 'Undefined prope...', '/var/www/core/a...', 21, Array)
#1 /var/www/polygon/vendor/scrumpy/prosemirror-to-html/src/Renderer.php(66): Statamic\\Fieldtypes\\Bard\\SetNode->text()
#2 /var/www/polygon/vendor/scrumpy/prosemirror-to-html/src/Renderer.php(62): Scrumpy\\ProseMirrorToHtml\\Renderer->renderNode(Object(stdClass))
#3 /var/www/polygon/vendor/scrumpy/prosemirror-to-html/src/Renderer.php(142): Scrumpy\\ProseMirrorToHtml\\Renderer->renderNode(Object(stdClass))
#4 /var/www/core/app/Fieldtypes/Bard/Augmentor.php(86): Scrumpy\\ProseMirrorToHtml\\Renderer->render(Array)
#5 /var/www/core/app/Fieldtypes/Bard/Augmentor.php(32): Statamic\\Fieldtypes\\Bard\\Augmentor->convertToHtml(Array)
#6 /var/www/polygon/app/Fieldtypes/CustomBard.php(31): Statamic\\Fieldtypes\\Bard\\Augmentor->augment(Array)
#7 /var/www/core/app/Fields/Field.php(174): App\\Fieldtypes\\CustomBard->process(Array)
[...]
blocked bug critical

All 8 comments

Can you share the original text you pasted so I can try to recreate it?

Sure, had to clean it up a bit first :)

<!DOCTYPE html>
<html lang="de">

<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title>Sponsored Article Body</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
</head>

<body class="bg-background min-w-sm leading-normal antialiased font-variant-numeric-lining-nums h-full">
    <div class="container bg-background mx-auto sm:max-w-sm md:max-w-md lg:max-w-lg mb-24 py-24">
        <div class="border-t border-black font-bold text-xl mb-32">Sponsored Article Body</div>

        <article class="lg:px-8">
            <div class="bg-white lg:py-40 md:py-40 sm:py-32 lg:px-190 md:px-88 sm:px-16">
                <div class="RichText RichText--sponsored">
                    <p>Vorbereitungszeit ca. 10 Minuten <br>
                        Backzeit ca. 15 Minuten
                    </p>
                    <h3>Rezept für 4 Personen</h3>
                    <ul>
                        <li>1 Baguette</li>
                        <li>50 ml Olivenöl</li>
                        <li>4 Ochsenherztomaten</li>
                        <li>1 rote Zwiebel</li>
                        <li>2 Knoblauchzehen</li>
                        <li>250g Mozzarella</li>
                        <li>Salz</li>
                        <li>grober Pfeffer</li>
                        <li>½ Bund Basilikum</li>
                        <li>4 EL Mazzetti Bio Cremaceto</li>
                    </ul>
                    <p>Utensilien: Backofen, Messer, Brett, Löffel, Backblech, Backpapier.</p>
                </div>

                <div class="block font-sansUI font-bold lg:text-2xl md:text-2xl sm:text-l mb-32 mt-48 text-black">Video
                    Headline 24 (2XL)</div>

                <img src="Sponsored%20Article%20Body_files/a.png" class="block" alt="" srcset="">

                <div class="RichText RichText--caption pt-8">
                    <span class="text-shade-dark">Caption 14(S)</span>
                    <span class="text-shade-light ml-4">Credit 14 (S)</span>
                </div>

                <div class="RichText RichText--sponsored">
                    <ol>
                        <li>
                            Backofen vorheizen (Ober-/Unterhitze: 200
                            °C/Umluft: 175 °C). Baguette aufschneiden und der Länge nach in Streifen
                            schneiden.
                            Mit Olivenöl beträufeln und auf oberer
                            Schiene im Ofen ca. 5 Minuten backen.
                        </li>
                        <li>
                            In der Zwischenzeit Tomaten waschen, trocken
                            tupfen, den oberen Teil als Deckel abschneiden und das
                            Kerngehäuse mit einem Löffel auskratzen.
                            Zwiebel und Knoblauch schälen und in feine Würfel schneiden.
                        </li>
                        <li>
                            Mozzarella abtropfen und in Würfel
                            schneiden. Tomaten auf ein mit Backpapier ausgelegtes Blech legen und
                            mit Zwiebel,
                            Knoblauch und Mozzarella befüllen. Mit Salz
                            und Pfeffer würzen. Deckel auf die Tomaten setzen und auf mittlerer
                            Schiene im Ofen
                            ca. 15 Minuten backen.
                        </li>
                        <li>
                            Basilikum waschen, trocken schütteln und Blätter klein hacken.
                        </li>
                        <li>
                            Deckel der Tomaten abnehmen und jede Tomate
                            mit 1 EL Mazzetti Bio Cremaceto beträufeln. Tomaten mit Basilikum
                            garnieren und mit Baguette servieren.
                        </li>
                    </ol>
                    <p><strong>Tipp:</strong> Noch mehr italienisches Flair gibt es mit der Wahl von Ciabatta. Ciabatta
                        ist ein flaches, breites Brot
                        aus Mehl, Salz, Hefe, Wasser und Olivenöl. Die deutsche Übersetzung lauetet Pantoffel.</p>
                </div>

            </div>
        </article>

    </div>

</body>

</html>

Select all, copy, paste, try to save.

The bug seems to be the hard_break in the first paragraph. Use Shift & Enter to make a linebreak somewhere in Bard to reproduce it.

Just confirming, you pasted an entire HTML document?

Just confirming, you pasted an entire HTML document?

No, we just hit Shit+Enter in Bard

Just confirming, you pasted an entire HTML document?

No, we rendered that HTML in a browser and copy-pasted the content from the browser tab.

But anyway, the hard break we insert using Shift+Enter is definitely a problem. Our process() method is here: https://github.com/statamic/three-cms/issues/568#issuecomment-513252111

In https://github.com/scrumpy/prosemirror-to-html there is a HardBreak.php node, but only in the tests/ directory. It's not in src/Nodes/ and not used in src/Renderer.php.

Was this page helpful?
0 / 5 - 0 ratings