Read HTML Metadata to Describe a Template
For an application I had to write a selector for a bunch of *.html files in a folder.
That's fairly easy by doing:
foreach (glob("*.html") as $filename) {
$files[] = '<option>'.basename($filename).'</option>';
}
echo sprintf('<select>%s</select>', implode('',$files));
and get a list of template filenames, that you can stuff in a <select>
.
But with that, you have to use descriptive filenames and it's a bit of a bare-bone experience.
Why not add some meta information about the template file into the template file itself and use that for a richer presentation with some javascript dropdown like Select2?
For that we add some good old <meta>
tags into the html>head
and parse them with the get_meta_tags()
.
The template file look like this:
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="template:author" content="TEST, test@gmail.com">
<meta name="template:name" content="Two Columns Layout">
<meta name="template:description" content="This is a Two Column Layout">
<meta name="template:icon" content="template-2col.svg">
<meta name="template:color" content="orange">
<title>{{ @page.title }} - {{ @page.subtitles }}</title>
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700">
<link rel="stylesheet" type="text/css" href="/assets/css/print.css">
<style type="text/css">
body {
font-family: Roboto, sans-serif;
}
</style>
</head>
<body class="A4">
</body>
</html>
It includes a template author, the filename for an icon, stored somewhere on thee server and a title/description to show in the dropdown. All this information is used in the javascript dropdown/combobox.
Next you read all the HTML files in a directory and get_meta_tags
while looping through them.
foreach (glob("/path/*.html") as $filename) {
$meta[basename($filename)] = get_meta_tags($filename);
}
print_r($meta);
$meta
now contains something like this:
(
[alternative_template.html] => Array
(
[template:author] => TEST, test@gmail.com
[template:name] => 2 Spalten Testlayout
[template:description] => Zweispaltiges Template über die gesamte Breite
[template:icon] => template-2col.svg
[template:color] => orange
)
[print-wide.html] => Array
(
[template:author] => TEST, test@gmail.com
[template:name] => 1 Spalte
[template:description] => Einspaltiges Template über die gesamte Breite
[template:icon] => template-1col.svg
[template:color] => #379a9a
)
[print.html] => Array
(
[template:author] => TEST, test@gmail.com
[template:name] => 2 Spalten
[template:description] => Zweispaltiges Template über die gesamte Breite
[template:icon] => template-2col.svg
[template:color] => #000
)
)
that lets you use the name of the template and an icon for the advanced combo box, select, dropdown... you name it, of your choice.
That's it!
There might be a case where you have to read the meta tags not from a HTML file, but from a <html>
string.
Here it's best to parse the HTML with DOMDocument
and access the <meta>
tags with a xpath
query.
See the following example.
$html = '
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="template:author" content="TEST, test@gmail.com">
<meta name="template:name" content="Two Columns Layout">
<meta name="template:description" content="This is a Two Column Layout">
<meta name="template:icon" content="template-2col.svg">
<meta name="template:color" content="orange">
<title>{{ @page.title }} - {{ @page.subtitles }}</title>
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700">
<link rel="stylesheet" type="text/css" href="/assets/css/print.css">
<style type="text/css">
body {
font-family: Roboto, sans-serif;
}
</style>
</head>
<body class="A4">
</body>
</html>
';
function get_meta_tags_from_string($html) {
$doc = new DOMDocument();
libxml_use_internal_errors(true);
$doc->loadHTML($html);
libxml_clear_errors();
$xpath = new DOMXPath($doc);
$nodes = $xpath->query('//head/meta[@name]');
$meta = [];
foreach($nodes as $node) {
$meta[$node->getAttribute('name')] = $node->getAttribute('content');
}
return $meta;
}
$meta = get_meta_tags_from_string($html);