I'm in the process of transitioning a site to using PHPTAL templates, for now I am writing all new pages using templates while leaving the existing pages as is.
The older pages use a standard header and footer, a typical page has it's content generated like this:
printHeader();
//print page content
printFooter();
The new pages in PHPTAL will use the same standard header/footer so I'm moving them into macros. I want to use the same source HTML for both new and old page headers and footers. To accomplish this I want to edit the printHeader() and printFooter() functions to use a template to print the header and footer macros:
printHeader() {
$source = '<metal:use-macro="macros.xhtml/header" />';
$header = new PHPTAL()
$header->setSource($source);
echo $header->execute();
}
The problem I'm having is that my header contains the opening <html> and <body> tags, which are closed in the footer. PHPTAL is throwing an exception because my macros are not valid xml:
Not all elements were closed before end of the document. Missing: </tal:block></tal:block></tal:block></body></html></tal:block>
What's the easiest way around this? I've found a workaround using structure to include these tags as a string but it seems sloppy:
<tal:block metal:define-macro="header">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<tal:block tal:content="structure string:<html>" />
<head>
head content
</head>
<tal:block tal:content="structure string:<body>" />
header content
Is there a cleaner way to do this? Maybe some sort of tal attribute that will allow it to ignore the missing closing tags for <html> and <body>?
PHPTAL is designed to make outputting of malformed markup as hard as possible, and unclosed tags are malformed markup.
You should never have
printHeader/printFooterfunctions. You need to flip this inside-out and have something likeprintContent()function and call it from template that includes both header and footer:(it doesn't have to be function, you can assign output to a variable, you can call a macro, and macro name can be variable too).