2

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?

heppi75
  • 131
  • 10
  • SO is not a "give me the code" kind of girl. – Jay Blanchard Jan 19 '16 at 19:25
  • Why do you need a DOM parser if you just want to replace a few placeholders? – jeroen Jan 19 '16 at 19:28
  • Can´t you just go at the string with preg_replace instead? http://php.net/manual/en/function.preg-replace.php I´m also wondering why you want the DOM parser for this. – Daniel Lind Jan 19 '16 at 19:32
  • 2
    @DanielLind Probably because, well, [you know](http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454). – Michael Plotke Jan 19 '16 at 19:34
  • @DanielLind I [can't believe you would](http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454) suggest using regex when finally someone asks a question about how to do this the right way!? – scrowler Jan 19 '16 at 19:36
  • Ok, might not be to good then. I looked a little in the documentation and the first example at http://php.net/manual/en/domdocument.getelementsbytagname.php might actually help some. I guess that you can change the values of the nodes too with that somehow. – Daniel Lind Jan 19 '16 at 19:47
  • And this one for appending stuff in the found nodes http://php.net/manual/en/domdocument.importnode.php – Daniel Lind Jan 19 '16 at 19:49
  • Not to just be a critic, here are some [effective strategies for parsing HTML using PHP](http://stackoverflow.com/a/3577662/1307154). – Michael Plotke Jan 19 '16 at 20:17

3 Answers3

1

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.

Michael Plotke
  • 951
  • 1
  • 15
  • 38
1

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 );
}
Rainner
  • 589
  • 3
  • 7
  • You don't need a loop, you can use a placeholders array (the keys in your example) and a replacement array as parameters for `str_replace`. – jeroen Jan 20 '16 at 09:42
0

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.

Lindsay Ryan
  • 433
  • 3
  • 9