how to fix breadcrumb from bad result and url - php

I have attached a breadcrumb and is now running. but how to tidy up the results in order to function.
this code
<?php
$crumbs = explode("/",$_SERVER["REQUEST_URI"]);
foreach($crumbs as $crumb){
ucfirst(str_replace(array(".php","_"),array(""," "),$crumb) . ' ');
}
$urls = "http://example.com";
foreach($crumbs as $crumb){
$urls .= "/".$crumb;
echo '<li><a href="'.$urls.'">';
echo $crumb;
echo '</a></li>';
}
?>
and the result is
Home / / pages / contact
How to remove one slash after home?
and result for the url
http://example.com//pages/contact
i've tried to fix but still not solved

Add each 'breadcrumb' to an array in your loop, and then implode the array after the loop, adding the slashes.
$urls = "http://example.com";
$breadcrumbs = array();
foreach($crumbs as $crumb){
$breadcrumbs[] = "<li><a href='$urls/$crumb'>$crumb</a></li>";
}
echo '/'.implode('/',$breadcrumbs);

Related

Breadcrumb menu PHP generating additional blank anchor links

Lets say I have the following URL:
https://site.website/products/products-level-2
And on products-level-2 I have a breadcrumb hero section. What I'm expecting to see is:
Products / Products Level 2
However, with my current approach, I'm seeing:
/ Products / Products Level 2 /
^^ the above has the following HTML output:
<!-- link 1 - not needed -->
<a class="crumbMenu" href="site.website"> </a>
<span class="slash">/</span>
<!-- link 2 -->
<a class="crumbMenu" href="site.website//products">Products </a>
<span class="slash">/</span>
<!-- link 3 -->
<a class="crumbMenu" href="site.website//products/products-level-2">Products Level 2</a>
<span class="slash">/</span>
<!-- link 4 - not needed -->
<a class="crumbMenu" href="site.website//products/products-level-2"> </a>
<span class="slash">/</span>
The above has the following issues:
It's outputting blank / not needed anchor links.
In the href, it's outputting double // (i.e. site.website//products)
I also do not want the last item (i.e products level 2) to be a link (since the user is viewing the breadcrumb on that page).
I don't want / to appear at the start and end of the breadcrumb.
Here is my current approach:
<?php
// 1. Get URL
$crumbs = explode("/",$_SERVER["REQUEST_URI"]);
$address = $_SERVER['HTTP_HOST'];
// 2. Strip extras
$build = '';
foreach($crumbs as $crumb){
$build .= '/'.$crumb;
$crumb = ucfirst(str_replace(array(".php","_"),array(""," "),$crumb) . ' ');
echo
"<a class='crumbMenu' href=".$address.$build.">".$crumb."</a>
<span class='slash'>/</span> ";
}
?>
To solve 1,2,4 just remove the leading and trailing slashes. To solve 3 you need to make a simple if:
// 1. Get URL
$crumbs = explode("/", trim($_SERVER["REQUEST_URI"], '/'));
$address = $_SERVER['HTTP_HOST'];
// 2. Strip extras
$build = '';
$lastKey = count($crumbs) - 1;
foreach($crumbs as $key => $crumb){
$build .= '/'.$crumb;
$crumb = ucfirst(str_replace(array(".php","_"),array(""," "),$crumb) . ' ');
echo $key < $lastKey
? "<a class='crumbMenu' href=".$address.$build.">".$crumb."</a>
<span class='slash'>/</span>"
: $crumb;
}
Demo: https://3v4l.org/BqD7C
Solution:
The final working code you end up with is as follows:
<?php
// 1. Get URL
$crumbs = explode("/",$_SERVER["REQUEST_URI"]);
array_filter($crumbs);
$count = count($crumbs);
$address = $_SERVER['HTTP_HOST'];
// 2. Strip extras
$build = '';
$i = 0;
foreach($crumbs as $crumb) {
$href = (++$i != $count ? 'href="' . $address . $build . '"' : '');
$build .= '/'.$crumb;
$crumb = ucfirst(str_replace(array(".php","_"),array(""," "),$crumb) . ' ');
echo
"<a class='crumbMenu' " . $href . ">".$crumb."</a>
<span class='slash'>/</span> ";
}
?>
Explanation:
1. It's outputting blank / not needed anchor links.
Simply run array_filter, this will remove any blank elements in the array.
array_filter($crumbs);
2. In the href, it's outputting double // (i.e. site.website//products)
The reason this happens is because it iterates through the blank element in the array first and as this adds a forward slash by default, by the second loop there is already a forward slash present, so it doubles up.
This issue is solved in the solution to question 1.
3. I also do not want the last item (i.e products level 2) to be a link (since the user is viewing the breadcrumb on that page).
After running array_filter on $crumbs you'll want to count how many elements are in the array using:
$count = count($crumbs);
Then when you are looping through the array, you'll want to workout when the loop is the last loop of the array:
$i = 0;
foreach($crumbs as $crumb) {
$href = (++$i != $count ? 'href="' . $address . $build . '"' : '');
// ...rest of foreach
$build .= '/' . $crumb;
$crumb = ucfirst(str_replace(array(".php","_"),array(""," "),$crumb) . ' ');
echo "<a class='crumbMenu' " . $href . ">".$crumb."</a><span class='slash'>/</span> ";
}
4. I don't want / to appear at the start and end of the breadcrumb.
This was resolved with my solution to your first question right at the top of this answer.
/* A character used as a divider between the breadcrumbs */
$separator = ' / ';
/* The current page uri from which to build breadcrumb trail */
$uri='https://'.$_SERVER['HTTP_HOST'].'/products/computers/microsoft/laptops/acer/professional';
/* capture the path and explode to create an array - removing empty entries in the process */
$crumbs=array_filter( explode( '/', parse_url( $uri, PHP_URL_PATH ) ) );
/* The host and protocol for building correct links */
$host=sprintf( '%s://%s/', parse_url( $uri, PHP_URL_SCHEME ), parse_url( $uri, PHP_URL_HOST ) );
/* placeholder array to store generated links */
$html=[];
/* iterate through the array and build relevant HTML content - append to output array */
foreach( $crumbs as $index => $crumb ){
/* tweak the text displayed */
$crumb = ucfirst( str_replace( array( ".php", "_" ), array( "", " " ), $crumb ) );
/* the path should be all the previous breadcrumb crumbs */
$path=[];
for( $i=1; $i < $index; $i++ ) $path[]=$crumbs[ $i ];
$path=implode( DIRECTORY_SEPARATOR, $path );
/* create the link used in the html display */
$html[]= ( $index==count( $crumbs ) ) ? sprintf('<span>%s</span>', $crumb ) : sprintf("<a href='%s%s' class='crumbMenu'>%s</a>", $host, $path, $crumb );
}
echo $uri, "
<style>
#breadcrumbs{border:1px solid gray;padding:1rem;font-family:calibri,verdana,arial}
#breadcrumbs *{padding:1rem;}
#breadcrumbs a,
#breadcrumbs span:hover{color:blue}
#breadcrumbs a:hover{color:red;}
#breadcrumbs span{font-weight:bolder;}
</style>
<div id='breadcrumbs'>",
implode( $separator, $html ),
"</div>";

Dynamically get page link based on breadcrumb level

I'm trying to create a breadcrumb menu via PHP and have the following so far:
<?php
// 1. Get URL
$crumbs = explode("/",$_SERVER["REQUEST_URI"]);
$address = 'http://'.$_SERVER['HTTP_HOST'];
// 2. Strip extras
foreach($crumbs as $crumb){
$crumb = ucfirst(str_replace(array(".php","_"),array(""," "),$crumb) . ' ');
echo ""."<span class='crumbMenu'>".$crumb."</span>";
}
?>
Let's say I have the following page hierarchy: Products > Products Level 2 > Products Level 3
The above code will spit out:
Products
Products Level 2
Products Level 3
Which is correct. However, the links are not.
After reading up on HTTP_HOST, I'm certain my approach is wrong, but unsure on what other approach I can take to dynamically get each crumb items link?
Links I am getting:
localhost:8080
Links I am expecting:
Products: /products
Products Level 2: /products/products-level-2
Products Level 3: /products/products-level-2/products-level-3
You seem to have forgotten about adding routes to $address variable, so all your breadcrumbs point to base server address. Try the following:
<?php
// 1. Get URL
$crumbs = explode("/",$_SERVER["REQUEST_URI"]);
$address = 'http://'.$_SERVER['HTTP_HOST'];
// 2. Strip extras
$build = $address.'/products';
foreach($crumbs as $crumb){
if(in_array($crumb, [$_SERVER['HTTP_HOST'], 'products'])) {
continue;
}
$build .= '/'.$crumb;
$crumb = ucfirst(str_replace(array(".php","_"),array(""," "),$crumb) . ' ');
echo ""."<span class='crumbMenu'>".$crumb."</span>";
}
?>
It is very hard to ready your echo which is not helpful. I created small function which should do what you have asked for. Feel free to modify it for your needs.
$crumbs = "/x/y/z";
$address = "localhost:8080";
$crumbs = explode('/', $crumbs);
$end = '';
$href = '';
foreach ($crumbs as $crumb) {
$crumb = str_replace('.php', '', $crumb);
$end .= $crumb . ' ';
$href .= $crumb . '/';
}
echo("HREF => " . $href);
echo("\n");
echo("TITLE => " . $end);

How do i display list items from php array

Ive been trying make this display as html list items it just a string that i explode then loop over each item i cant get it to out put correctly. Could some one please show me where im going wrong or suggest an new approch.
this is what ive tried
$path = "1/2/3/4";
$expath = explode("/",$path);
$ret = '';
echo '<ul>';
foreach ($expath as $pitem) {
echo '<li><a href='.$ret .= $pitem. "/".'>'.$pitem.'</a></li>';
}
echo '</ul>';
.
Desired out put on hrefs
1
1/2
1/2/3
1/2/3/4
Desired visual out LIs
1
2
3
4
Output i get be warned
1
12/>212/>23/>312/>23/>34/>4
$path = "1/2/3/4";
$expath = explode("/", $path);
echo '<ul>';
foreach ($expath as $i => $pitem) {
$slice = array_slice($expath, 0, $i + 1);
$path = implode('/', $slice);
echo '<li>' . $pitem . '</li>';
}
echo '</ul>';
$list = explode("/", "1/2/3/4");
This will create an array $list as:
echo $list[0]; // 1
echo $list[1]; // 2
echo $list[2]; // 3
echo $list[3]; // 4
This line is the problem: echo '<li><a href='.$ret .= $pitem. "/".'>'.$pitem.'</a></li>';
Should be formatted like:
echo "<li><a href='{$ret}={$pitem}/'>{$pitem}</a></li>";
or echo '<li>'.$pitem.'</li>';
Its because your $ret. Place that inside the loop. In your code you concatenate $pitem with $ret all older $ret values also get concat.
Try
<?php
$path = "1/2/3/4";
$expath = explode("/",$path);
echo '<ul>';
foreach ($expath as $pitem) {
$ret = '';
echo '<li><a href='.$ret .= $pitem. "/".'>'.$pitem.'</a></li>';
}
echo '</ul>';
If you want = sign tobe there in the url then just change echo by following
echo "<li><a href='$ret=$pitem/'>$pitem</a></li>";
PHP echo with double quotes will print variable value.

How to remove the trailing double arrows "»" from breadcrumbs on the home page only

I found this useful PHP snippet and made a couple small modifications, but I have not been able to figure out how to exclude the home page from showing the trailing "»" after the word "Home". As a result, it ends up looking like this... Home » .
Is there a simple way to remove this without changing the way the breadcrumbs appear on any other page?
<?php
function breadcrumbs($sep = ' » ', $home = 'Home') {
//Use RDFa breadcrumb, can also be used for microformats etc.
$bc = '<div xmlns:v="http://rdf.data-vocabulary.org/#" id="crums">'.$text;
//Get the website:
$site = 'http://'.$_SERVER['HTTP_HOST'];
//Get all vars en skip the empty ones
$crumbs = array_filter( explode("/",$_SERVER["REQUEST_URI"]) );
//Create the home breadcrumb
$bc .= '<span typeof="v:Breadcrumb">'.$home.''.$sep.'</span>';
//Count all not empty breadcrumbs
$nm = count($crumbs);
$i = 1;
//Loop the crumbs
foreach($crumbs as $crumb){
//Make the link look nice
$link = ucfirst( str_replace( array(".php","-","_"), array(""," "," ") ,$crumb) );
//Loose the last seperator
$sep = $i==$nm?'':$sep;
//Add crumbs to the root
$site .= '/'.$crumb;
//Make the next crumb
$bc .= '<span typeof="v:Breadcrumb">'.$link.''.$sep.'</span>';
$i++;
}
$bc .= '</div>';
//Return the result
return $bc;}
?>
<p><?= breadcrumbs() ?></p>
You have to remove the separator character that is put each time after "Home". Add it only if there is something after "Home".
$crumbs = array_filter( explode("/",$_SERVER["REQUEST_URI"]) );
//Count all not empty breadcrumbs
$nm = count($crumbs);
$i = 1;
// Add first separator if there is at least one crumb
$homesep = $nm == 0?'':$sep;
//Create the home breadcrumb
$bc .= '<span typeof="v:Breadcrumb">'.$home.''.$homesep.'</span>';
//Loop the crumbs
foreach($crumbs as $crumb){
...
}

Breadcrumb displays query string

I would like my breadcrumb script to display the page name only(example: pic), instead of page name + query string if exists(example: pic).
This is my breadcrumb script:
<?php
$crumbs = explode("/",$_SERVER["REQUEST_URI"]);
foreach($crumbs as $crumb){
echo '<li class="active">';
echo ucfirst(str_replace(array(".php","_",),array(""," "),$crumb) . ' ');
echo '</li>';
}
?>
How do I exclude everything after ".php"?
Thank you for your help
use parse_url() function for getting the parts of the url
You may use this after some editing
<?php
$parsed=parse_url($_SERVER["REQUEST_URI"]);
$crumbs = explode("/",$parsed['path']);
print_r(parse_url($_SERVER["REQUEST_URI"]));
foreach($crumbs as $crumb){
echo '<li class="active">';
echo ucfirst(str_replace(array(".php","_",),array(""," "),$crumb) . ' ');
echo '</li>';
}
?>
<?php
$crumbs = explode("/",$_SERVER["PHP_SELF"]);
$html="";
foreach($crumbs as $crumb){
$crumb = ucfirst(str_replace(array(".php","_"),array(""," "),$crumb));
if(trim($crumb)!=""){
$html .= '<li class="active">'.$crumb.'</li>';
}
}
$html = "<li>".ucfirst($_SERVER["HTTP_HOST"])."</li>".$html;
echo $html;
?>

Categories