{"id":261,"date":"2026-04-05T17:17:11","date_gmt":"2026-04-05T15:17:11","guid":{"rendered":"https:\/\/ferrari2k.spdns.org\/blog\/?p=261"},"modified":"2026-04-05T17:17:11","modified_gmt":"2026-04-05T15:17:11","slug":"nextcloud-cookbook-parser-probleme","status":"publish","type":"post","link":"https:\/\/ferrari2k.spdns.org\/blog\/?p=261","title":{"rendered":"Nextcloud Cookbook Parser Probleme"},"content":{"rendered":"\n<p>Es gibt f\u00fcr Nextcloud die Cookbook App, mit der man einfach Rezepte von verschiedenen Quellen sammeln kann.<br>Leider sind manche Seiten nicht kompatibel und liefern beim Herunterladen eine Parser Fehlermeldung.<br>Dies betrifft z.B. die Picnic Seite.<br>Mit diesem Patch ist das Herunterladen wieder m\u00f6glich.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: diff; title: ; notranslate\" title=\"\">\nSubject: &#x5B;PATCH] adding support for next.js recipes embedded in an unattributed script tag\n---\nIndex: lib\/Helper\/HTMLParser\/HttpJsonLdParser.php\nIDEA additional info:\nSubsystem: com.intellij.openapi.diff.impl.patch.CharsetEP\n&lt;+&gt;UTF-8\n===================================================================\ndiff --git a\/lib\/Helper\/HTMLParser\/HttpJsonLdParser.php b\/lib\/Helper\/HTMLParser\/HttpJsonLdParser.php\n--- a\/lib\/Helper\/HTMLParser\/HttpJsonLdParser.php\t(revision a246a0eed8e757118599d2c74f407b181a70bba5)\n+++ b\/lib\/Helper\/HTMLParser\/HttpJsonLdParser.php\t(date 1775395557183)\n@@ -26,7 +26,7 @@\n \tpublic function parse(\\DOMDocument $document, ?string $url): array {\n \t\t$xpath = new \\DOMXPath($document);\n \n-\t\t$json_ld_elements = $xpath-&gt;query(&quot;\/\/*&#x5B;@type=&#039;application\/ld+json&#039;]&quot;);\n+\t\t$json_ld_elements = $xpath-&gt;query(&quot;\/\/*&#x5B;@type=&#039;application\/ld+json&#039;] | \/\/script&quot;);\n \n \t\tforeach ($json_ld_elements as $json_ld_element) {\n \t\t\tif (!$json_ld_element || !$json_ld_element-&gt;nodeValue) {\n@@ -58,9 +58,14 @@\n \t\t$json = json_decode($string, true);\n \n \t\tif ($json === null) {\n-\t\t\tthrow new HtmlParsingException($this-&gt;l-&gt;t(&#039;JSON cannot be decoded.&#039;));\n-\t\t}\n+\t\t\t$extractedJson = $this-&gt;extractNextJsJson($string);\n+\t\t\tif ($extractedJson === null) {\n+\t\t\t\tthrow new HtmlParsingException($this-&gt;l-&gt;t(&#039;JSON cannot be decoded.&#039;));\n+\t\t\t}\n \n+\t\t\t$json = json_decode($extractedJson, true);\n+\t\t}\n+\n \t\tif ($json === false || $json === true || !is_array($json)) {\n \t\t\tthrow new HtmlParsingException($this-&gt;l-&gt;t(&#039;No recipe was found.&#039;));\n \t\t}\n@@ -85,6 +90,34 @@\n \t\tthrow new HtmlParsingException($this-&gt;l-&gt;t(&#039;No recipe was found.&#039;));\n \t}\n \n+\t\/**\n+\t * Try to extract escaped JSON from a Next.js flight payload.\n+\t *\n+\t * Example:\n+\t * self.__next_f.push(&#x5B;1,&quot;{\\&quot;@context\\&quot;:\\&quot;https:\/\/schema.org\\&quot;,...}&quot;])\n+\t *\n+\t * @param string $rawContent\n+\t * @return string|null\n+\t *\/\n+\tprivate function extractNextJsJson(string $rawContent): ?string {\n+\t\tif (strpos($rawContent, &#039;self.__next_f.push(&#039;) === false) {\n+\t\t\treturn null;\n+\t\t}\n+\n+\t\t$matches = &#x5B;];\n+\t\t$matched = preg_match(&#039;\/self\\.__next_f\\.push\\(\\&#x5B;\\s*\\d+\\s*,\\s*&quot;((?:\\\\\\\\.|&#x5B;^&quot;\\\\\\\\])*)&quot;\/s&#039;, $rawContent, $matches);\n+\t\tif ($matched !== 1 || !isset($matches&#x5B;1])) {\n+\t\t\treturn null;\n+\t\t}\n+\n+\t\t$decoded = stripcslashes($matches&#x5B;1]);\n+\t\tif ($decoded === &#039;&#039;) {\n+\t\t\treturn null;\n+\t\t}\n+\n+\t\treturn $decoded;\n+\t}\n+\n \t\/**\n \t * Fix any JSON issues before trying to decode it\n \t *\nIndex: lib\/Helper\/Filter\/JSON\/FixInstructionsFilter.php\nIDEA additional info:\nSubsystem: com.intellij.openapi.diff.impl.patch.CharsetEP\n&lt;+&gt;UTF-8\n===================================================================\ndiff --git a\/lib\/Helper\/Filter\/JSON\/FixInstructionsFilter.php b\/lib\/Helper\/Filter\/JSON\/FixInstructionsFilter.php\n--- a\/lib\/Helper\/Filter\/JSON\/FixInstructionsFilter.php\t(revision a246a0eed8e757118599d2c74f407b181a70bba5)\n+++ b\/lib\/Helper\/Filter\/JSON\/FixInstructionsFilter.php\t(date 1775396186726)\n@@ -98,6 +98,11 @@\n \t\t\t\t\tcontinue;\n \t\t\t\t}\n \n+\t\t\t\tif ($this-&gt;jsonService-&gt;isSchemaObject($value, &#039;HowToTip&#039;, false)) {\n+\t\t\t\t\t$instructions&#x5B;$key] = &#x5B;$this-&gt;extractHowToStep($value)];\n+\t\t\t\t\tcontinue;\n+\t\t\t\t}\n+\n \t\t\t\tif ($this-&gt;jsonService-&gt;isSchemaObject($value, &#039;HowToSection&#039;, false)) {\n \t\t\t\t\t$newInstructions = $this-&gt;flattenHowToSection($value);\n \t\t\t\t\t$instructions&#x5B;$key] = $newInstructions;\n\n<\/pre><\/div>","protected":false},"excerpt":{"rendered":"<p>Es gibt f\u00fcr Nextcloud die Cookbook App, mit der man einfach Rezepte von verschiedenen Quellen sammeln kann.Leider sind manche Seiten nicht kompatibel und liefern beim Herunterladen eine Parser Fehlermeldung.Dies betrifft z.B. die Picnic Seite.Mit diesem Patch ist das Herunterladen wieder &hellip; <a href=\"https:\/\/ferrari2k.spdns.org\/blog\/?p=261\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-261","post","type-post","status-publish","format-standard","hentry","category-allgemein"],"_links":{"self":[{"href":"https:\/\/ferrari2k.spdns.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/261","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ferrari2k.spdns.org\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ferrari2k.spdns.org\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ferrari2k.spdns.org\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ferrari2k.spdns.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=261"}],"version-history":[{"count":1,"href":"https:\/\/ferrari2k.spdns.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/261\/revisions"}],"predecessor-version":[{"id":262,"href":"https:\/\/ferrari2k.spdns.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/261\/revisions\/262"}],"wp:attachment":[{"href":"https:\/\/ferrari2k.spdns.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=261"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ferrari2k.spdns.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=261"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ferrari2k.spdns.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=261"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}