Search

Something that developers might find useful. Instead of using complex regular expressions or other weird string manipulation techniques to manipulate page output, you can use the DOMDocument classes in PHP. Here is an example that removes any anchor tag in the page <h2> (E.G. a Create New button):

        $doc = new DOMDocument();
        $doc->loadHTML($output);

        $xpath = new DOMXPath($doc);
        $query = '//h2/a';
        $a = $xpath->query($query)->item(0);

        $a->parentNode->removeChild($a);

        return $doc->saveHTML();

Get the page output by subscribing to the AdminPagePostGenerate delegate.

That’s cool, thanks for the tip!

Awesome!

Excellent idea. I used jQuery to do a lot of manipulation in the Custom Admin proof of concept, but it would make sense to do this using PHP instead, taking the load off of the client.

I’m sure I’m making a stupid mistake, but how do I add custom elements?

This:

if(Administration::instance()->Page instanceof contentSystemAuthors) {      
    // Create preference
    $fieldset = new DOMDocument();
    $fieldset->load('<fieldset class="settings"><legend>' . __('Custom Preferences') . '</legend><label>' . __('Language') . '<select name="fields[default_section]"></select></label></fieldset>');
    // Load current document
    $doc = new DOMDocument();
    $doc->loadHTML($context['output']);
    $xpath = new DOMXPath($doc);
    $query = "//fieldset[@class='settings']";
    $settings = $xpath->query($query)->item(0);
    $settings->parentNode->appendChild($fieldset);
    return $doc->saveHTML();
}

results in the following error:

Fatal error: Uncaught exception 'DOMException' with message 'Wrong Document Error'

You can’t mix elements from two DomDocuments in that way. But I think you can use a DocumentFragment to do this:

DOMDocumentFragment::appendXML

Hm, now the error is gone. But nothing seems to be inserted. I’ve been reading through the PHP documentation, but I think there is something fundamental I got wrong …

Edit: New error:

Fatal error: Call to a member function appendChild() on a non-object

Nils, I think this should helps you.

if(Administration::instance()->Page instanceof contentSystemAuthors) {
    // Load current document
    $doc = new DOMDocument();
    $doc->loadHTML($context['output']);
    $xpath = new DOMXPath($doc);

    // Create preference
    $content = sprintf('<fieldset class="settings"><legend>%s</legend><label>%s<select name="fields[default_section]"></select></label></fieldset>', __('Custom Preferences'), __('Language'));
    $fieldset = $doc->createDocumentFragment();
    $fieldset->appendXML($content);

    $query = "//fieldset[@class='settings']";
    $settings = $xpath->query($query)->item(0);
    $settings->parentNode->appendChild($fieldset);

    $context['output'] = $doc->saveHTML();
}

For future reference - this is working perfectly:

if(Administration::instance()->Page instanceof contentSystemAuthors) {
    // Load current document
    $doc = new DOMDocument();
    $doc->loadHTML($context['output']);
    $xpath = new DOMXPath($doc);
    // Create preference
    $content = '<fieldset class="settings">
                    <legend>' . __('Custom Preferences') . '</legend>
                    <label>' .  __('Language') . '<select name="fields[default_section]"></select></label>
                </fieldset>';
    $fieldset = $doc->createDocumentFragment();
    $fieldset->appendXML($content);
    $search = $xpath->query("//div[@class='actions']")->item(0);
    $search->parentNode->insertBefore($fieldset, $search);
    // save new output
    $context['output'] = $doc->saveHTML();
}               

It also works. Was exactly what nick said.

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details