Last active
October 6, 2021 18:40
-
-
Save markfullmer/68d7d84090501c29b948b924040de3da to your computer and use it in GitHub Desktop.
Convert Zurb Foundation Accordion to generic details/summary using DomDocument
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$input = 'Some text<a href="#">Test</a><ul class="accordion" data-accordion role="tablist"> | |
<li class="accordion-navigation" role="presentation"> | |
<a href="#panel1d" role="tab" id="panel1d-heading" aria-controls="panel1d">Accordion 1</a> | |
<div id="panel1d" class="content active" role="tabpanel" aria-labelledby="panel1d-heading"> | |
Panel 1. Lorem ipsum dolor | |
</div> | |
</li> | |
<li class="accordion-navigation" role="presentation"> | |
<a href="#panel2d" role="tab" id="panel2d-heading" aria-controls="panel2d">Accordion 2</a> | |
<div id="panel2d" class="content" role="tabpanel" aria-labelledby="panel2d-heading"> | |
Panel 2. Lorem ipsum dolor<a href="#">foo</a> | |
</div> | |
</li> | |
<li class="accordion-navigation" role="presentation"> | |
<a href="#panel3d" role="tab" id="panel3d-heading" aria-controls="panel3d">Accordion 3</a> | |
<div id="panel3d" class="content" role="tabpanel" aria-labelledby="panel3d-heading"> | |
Panel 3. Lorem ipsum dolor | |
</div> | |
</li> | |
</ul>'; | |
$input2 = 'Some text<a href="#">Test</a><ul class="accordion" data-accordion=""> | |
<li class="accordion-navigation"><a href="#citations" aria-expanded="false">Citations</a><div> | |
<pre class="content" id="citations"><sup>1 Texas Department of Family and Protective Services. Family First Prevention Act. Retrieved from https://www.dfps.state.tx.us/Child_Protection/Family_First/default.asp | |
2 Chen, E., Brody, G. H., & Miller, G. E. (2017). Childhood close family relationships and health. The American psychologist, 72(6), 555–566. Retrieved from https://doi.org/10.1037/amp0000067 | |
</pre></div></li> | |
<li class="accordion-navigation"><a href="#pdf" aria-expanded="false">PDF Version</a><br> | |
<div class="content" id="pdf">test<a href="/sites/default/files/CFRPBrief_B0440121_SupportingPregnantandParentingTeensinCare.pdf" target="_blank">Supporting Pregnant and Parenting Teens in Care with Home Visiting (PDF)</a></div> | |
</li> | |
</ul>'; | |
function appendHTML(DOMNode $parent, $source) { | |
$tmpDoc = new DOMDocument(); | |
$tmpDoc->loadHTML($source); | |
foreach ($tmpDoc->getElementsByTagName('body')->item(0)->childNodes as $node) { | |
$node = $parent->ownerDocument->importNode($node, true); | |
$parent->appendChild($node); | |
} | |
} | |
function DOMinnerHTML(DOMNode $element) { | |
$innerHTML = ""; | |
$children = $element->childNodes; | |
foreach ($children as $child) { | |
$innerHTML .= $element->ownerDocument->saveHTML($child); | |
} | |
return $innerHTML; | |
} | |
function convertFoundationAccordion($text) { | |
$original = $text; | |
// LibXML requires that the html is wrapped in a root node. | |
$text = '<root>' . $text . '</root>'; | |
$dom = new \DOMDocument(); | |
$dom->preserveWhiteSpace = FALSE; | |
libxml_use_internal_errors(TRUE); | |
$dom->loadHTML(mb_convert_encoding($text, 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); | |
$uls = $dom->getElementsByTagName('ul'); | |
if ($uls->length === 0) { | |
return $original; | |
} | |
foreach ($uls as $ul) { | |
$classes = $ul->getAttribute('class'); | |
if (strpos($classes, 'accordion') === FALSE) { | |
continue; | |
} | |
$lis = $ul->getElementsByTagName('li'); | |
if ($lis->length === 0) { | |
continue; | |
} | |
$convert = TRUE; | |
$content = ''; | |
$titleObjects = []; | |
$bodyObjects = []; | |
foreach ($lis as $key => $li) { | |
if (!$convert) { | |
continue; | |
} | |
$classes = $li->getAttribute('class'); | |
if (strpos($classes, 'accordion-navigation') === FALSE) { | |
continue; | |
} | |
$titleObjects[$key] = $li->getElementsByTagName('a'); | |
$bodyObjects[$key] = $li->getElementsByTagName('div'); | |
if ($bodyObjects[$key][0] && $titleObjects[$key][0]) { | |
if (isset($bodyObjects[$key][0]->nodeValue) && isset($titleObjects[$key][0]->nodeValue)) { | |
$content .= '<details><summary>' . $titleObjects[$key][0]->nodeValue . '</summary>' . DOMInnerHTML($bodyObjects[$key][0]) . '</details>'; | |
} | |
else { | |
$convert = FALSE; | |
} | |
} | |
else { | |
$convert = FALSE; | |
} | |
} | |
if ($convert) { | |
$elem = $dom->createElement('div'); | |
appendHTML($elem, $content); | |
$ul->parentNode->replaceChild($elem, $ul); | |
} | |
} | |
// Get innerHTML of root node. | |
$html = ""; | |
foreach ($dom->getElementsByTagName('root')->item(0)->childNodes as $child) { | |
// Re-serialize the HTML. | |
$html .= $dom->saveHTML($child); | |
} | |
return $html; | |
} | |
$output = convertFoundationAccordion($input); | |
print_r($output); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment