Skip to content

Instantly share code, notes, and snippets.

@lbgm
Last active March 31, 2023 11:57
Show Gist options
  • Save lbgm/b0a5ef1da3362a0b6238a91e1d76d020 to your computer and use it in GitHub Desktop.
Save lbgm/b0a5ef1da3362a0b6238a91e1d76d020 to your computer and use it in GitHub Desktop.
Generate breadcrumbs with PHP, Usable for Google structured data

Using with Google Tag Manager

Place this code before the integration (as high as possible) of Google Tag Manager on your pages:

<?=Breadcrumb::c()->dataLayer()?>

You will now have two variables (SiteBreadcrumb and Breadcrumb) in the dataLayer of your container.

in GTM: With the SiteBreadcrumb variable, you will be able to identify eligible pages with a trigger; Then get the Breadcrumb variable and with this content in a custom tag, everything is done:

<script>
(function(){
var ld =
{
 "@context": "http://schema.org",
"@type": "BreadcrumbList",
"itemListElement": {{Breadcrumb}}
};
var s= document.createElement('script');
    s.setAttribute('type', 'application/ld+json');
    s.textContent = JSON.stringify(ld);
document.body.appendChild(s);
})();
</script>

Using Without Google Tag Manager

Put this snippet of code in the desired location and use Google's Rich Results Testing Tool to preview the result.

<?=Breadcrumb::c()->List()?>
<?php
#Breadcrumb List Generator
class Breadcrumb
{
public static function c()
{
static $instance;
if(!is_object($instance))
{
$instance= new Breadcrumb();
}
return $instance;
}
private function rglob($no,$root)
{
#find root firts elements
$objects = $this->sanitize($no,array_merge(glob("$root*.php",GLOB_NOSORT),glob("$root*",GLOB_ONLYDIR)));
#find each root first element sub
foreach ($objects as $object)
if(is_dir($object) && !is_link($object)) $objects= $this->sanitize($no,array_merge($objects,glob("$object/*",GLOB_NOSORT|GLOB_ONLYDIR)));
return $objects;
}
private function getItems()
{
#Exclusions. to exclude unwanted file or dir. add more yourself
$no=array("error","cgi-",".xml",".txt","_");
#Translations. add more yourself
$ts=array("index.php"=>"Home","index.html"=>"Home");
#for breadcrumb items store
$_barr=array();
#operating root, script path
$root=preg_replace('/\b(\w+.php)\b/',"",$_SERVER["SCRIPT_FILENAME"]);
#uribase
$uribase="https://".$_SERVER["HTTP_HOST"];//URL
#docRoot
$docRoot=$_SERVER["DOCUMENT_ROOT"];
#only dir aloowed
if(is_dir($root)){
#get all dirs, subdirs and files
$objects = $this->rglob($no,$root);
foreach($objects as $i=>$object){
#when $object has valid name
if($object != "." && $object != "..")
{
#create an array for item real positions from PATH
$tmp1=array_filter(array_merge(array(0),preg_split('@/@',str_replace($docRoot,"",$object),NULL,PREG_SPLIT_NO_EMPTY)));
#name
$n=basename($object);
#index
$index=array_search($n,$tmp1);
#url
$q=$uribase.str_replace($docRoot,"",$object);
#translate name
$n=array_key_exists($n,$ts)?$ts[$n]:$n;
#breadcrumb item
$_barr[]="\r\n{\"@type\": \"ListItem\",\r\n\"position\": $index,\r\n\"name\": \"$n\",\r\n\"item\": \"$q\"\r\n}\r\n";
}
}
}
#implode items with comma and return
$_barr=implode(",", $_barr);
return $_barr;
}
public function dataLayer()
{
#for Google Tag Manager dataLayer
$g=$this->getItems();
return "\r\n<script>\r\n(dataLayer= window.dataLayer || []).push({\r\n'SiteBreadcrumb':'allowed',\r\n'Breadcrumb': [$g]\r\n});\r\n</script>\r\n";
}
public function List()
{
#for Google ld+json directly
$g=$this->getItems();
return "\r\n<script type=\"application/ld+json\">\r\n{\r\n\"@context\": \"https://schema.org\"\r\n,\"@type\": \"BreadcrumbList\"\r\n,\"itemListElement\": [$g]}\r\n</script>\r\n";
}
private function sanitize($no,$aa)
{
#remove unwanted items from glob results
$f=$aa;
foreach ($no as $a => $x) {
foreach ($aa as $b => $y) {
# code...
if(strpos($y, $x)!==false)
unset($f[$b]);
}
}
return array_values($f);
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment