Absence Makes the Heart Grow Fonder or: Performing an XSLT Transformation on the Server

The MultiMarkdown ToC

Do you ever feel like you’re never finished? I do, and I’m not happy with the fact that I haven’t been able to make Scrivener trigger the mmd-xslt script following a compile to MultiMarkdown HTML. Fine. As with the original XML epiphany, I knew there had to be code to perform an XSLT transformation in PHP on the server. Certainly there is, and my content-doc.php content template has further evolved into an XSLT transformation powerhouse. If a custom variable is provided with a path to the XSLT file on disk, and that files exists, the code transforms the XML using the provided XSLT style sheet. Here is a snippet:

<header class="page-header">
    <?php
    $title = get_the_title();

    $docs_path = get_post_meta(get_the_ID(), 'docs_path', true);
    if($docs_path && file_exists($docs_path)) {
        libxml_use_internal_errors(true);
        $xml = simplexml_load_file($docs_path);
        foreach (libxml_get_errors() as $error) {
            error_log($error->message);
        }
        if($xml) {
            $title = $xml->head->title;
            $xslt_path = get_post_meta(get_the_ID(), 'xslt_path', true);
            if($xslt_path && file_exists($xslt_path)) {
                $xslt = simplexml_load_file($xslt_path);
                foreach (libxml_get_errors() as $error) {
                    error_log($error->message);
                }
                if($xslt) { 
                    $proc = new XSLTProcessor;
                    $proc->importStyleSheet($xslt);
                    $xml = simplexml_import_dom($proc->transformToDoc($xml));

                }
            }
        }
    }

    printf('<h1 class="entry-title">%s</h1>', $title);
    ?>
</header><!-- .entry-header -->

Notes

Something to take note of in the PHP code. transformToDoc returns a DOMDocument object and the $xml variable contains a SimpleXMLElement object returned by the simplexml_load_file() method. If you recall, we insert the XML into the page by echoing the proper child element using the asXml() method. Therefore in order to leave that code intact, I import the DOMDocument back into $xml.