too long

what I want is use a html snippet as template with placeholders and load this template, fill with content and return the new html:

$html = '<table>
<tr id="extra">
    <td>###EXTRATITLE###</td>
    <td>###EXTRATOTAL###</td>
</tr>
</table>';

$temp = new DOMDocument();
$temp->loadHTML($html);
$str = $temp->saveHTML($temp->getElementById('extra'));

$dom = new DOMDocument();
$dom->loadHTML($html);
$dom->preserveWhiteSpace = false;

$element = $dom->getElementById('extra');
$element->parentNode->removeChild($element);

$data = [
    "key1" => "value1",
    "key2" => "value2",
];

foreach ($data as $key => $row) {
    $search = [ '###EXTRATITLE###', '###EXTRATOTAL###' ];
    $replace = [ $key, $row ];

    $el = $dom->createTextNode(str_replace($search, $replace, $str));
    $foo = $dom->documentElement->firstChild;
    $foo->appendChild($el);
}

echo preg_replace('~<(?:!DOCTYPE|/?(?:html|body))[^>]*>\s*~i', '', $dom->saveHTML());

problem are the entities and the wrong placement of the childs - could anyone fix this?

Here is an alternative approach:

$html = '<table><tr id="myselector"></tr></table>';

$doc = new DOMDocument();
$doc->loadHTML($html);
$tr = $doc->getElementById('myselector');

foreach ($data as $row) {
    $td = $doc->createElement('td', $row['value']);
    $tr->appendChild($td);
    //repeat as necessary
}

It does not use placeholders, but it should produce the desired result.


If the goal is to create a more complex templating system from scratch, it might make more sense to peruse the XPath documentation and leverage the associated XPath class.

I'm wondering why you're using PHP for this instead of JQuery - which makes this SUPER easy. I mean, I know you can, but i'm not sure you're doing yourself any favors.

I had a similar requirement where i wanted to use a template and get server-side values. What i ended up doing was creating a server-side array and converting this to JSON - in php json_encode($the_data_array);

then i had a standing script portion of my template that used jQuery selectors to get and set the values. This was really clean and much easier to debug that trying to generate the entire HTML payload from php. it also meant i could more easily separate the data file from the template for better caching and updates later.

i can try to update this with a fiddler example if you're not familiar with jQuery and need some guidance. just let me know.

Assuming you have a data mapping array like this:

$data = array(
    'PLACEHOLDER1' => 'data 1',
    'PLACEHOLDER2' => 'data 2',
);

Here is what you could do:

$html = '<table>
<tr id="myselector">
    <td>###PLACEHOLDER1###</td>
    <td>###PLACEHOLDER2###</td>
</tr>
</table>';

foreach( array_keys( $data ) as $key )
{
    $html = str_replace( '###'.$key.'###', $data[ $key ], $html );
}