En breadcrumb er en logisk navigation, der viser, hvor man befinder sig på et site. Altså et lille stykke navigation, der kan hjælpe folk til at få overblik over, hvor de befinder sig på et site.
Eksempelvis kan man støde på breadcrumb'en: "Forside / Web / Objects", hvis man går ind på http://www.jensgram.dk/web/objects/ . Sammenhængen er her tydelig og overblikket er der hurtigt.
Denne funktion findes på mange sites (fordi den er praktisk og giver gennemskuelighed), men folk opretter til stadighed spørgsmål i PHP-kategorien. Det var så meningen, at denne artikel skulle kaste lidt lys over sagen.
Det eneste krav er, at din struktur skal være som i ovenstående eksempel. Altså:
"www.ditdomæne.dk/mappe/måske_endnu_en_mappe/dinfil.php"
Funktionen kan selvfølgelig også laves ved strukturer som "www.ditdomæne.dk/?page=dinside", men denne kan jo variere meget, så det må vente...
Ja, hvorfor ikke? Jeg går ud fra at du er så meget inde i PHP, at du kender til termer som "funktioner", "argumenter", "variabler" og "array's". Hvis ikke så kig på http://dk.php.net/!
Vi starter med at lave vores funktion:
<?php
function breadcrumb()
{
$root = 'http://www.ditdomæne.dk/';
}
?>
Så langt, så godt. Det er så tanken, at jeg vil benytte variablen $_SERVER['PHP_SELF'] i selve funktionen til at hente placeringen af selve filen.
Jeg kunne også have valgt at bruge $_SERVER['HTTP_HOST'] i stedet for $root, men lad os nu bare holde fast ved den.
Hvis vi antager, at $_SERVER['PHP_SELF'] indeholder "/web/objects/index.php" så er det jo tydeligt, at vi skal have opdelt denne streng ved "/". Dette klarer explode():
<?php
function breadcrumb()
{
$root = 'http://www.jensgram.dk/'; // Domænet
$dirs = explode('/', $_SERVER['PHP_SELF']); // Split ved slashes
$size = sizeof($dirs)-1; // Antal biblioteker
$outp = '<a href="' . $root . '">Forside</a>';
$div = ' / '; // Streng mellem biblioteker i output
$fnam = substr($dirs[$size], 0, strrpos($dirs[$size], '.')); // Filnavn (mellem begyndelse af sidste element i $dirs-array'et og (sidste) punktum)
return $outp;
}
?>
Nu skete der jo en masse, men fortvivl ikke. Der venter forklaring.
$dirs vil (med ovenstående eksempel) være et array som følger:
Array (
0 => '',
1 => 'web',
2 => 'objects',
3 => 'index.php'
);
Dette skal vi bruge om lidt.
$size indeholder størrelsen af ovenstående array. Vi trækker en fra, da det første element er tom (strengen starter med '/'). Denne variabel skal også bruges snart.$outp indeholder på nuværende tidspunkt: '<a href="http://www.jensgram.dk/">Forside</a>'. Dette er det link, som jeg altid vil have stående (folk skal jo gerne kunne finde tilbage til forsiden).$fnam indeholder filnavnet. I dette tilfælde er det: 'index'. Dette ser måske lidt avanceret ud, men det er meget simpelt. Først henter vi positionen af det sidste punktum i det sidste element i $dirs ('index.php'). Dette gøres med strrpos(). Denne returnerer 5 i dette tilfælde (første bogstav er 0). Herefter benytter vi substr() til at hente fra tegn nu til tegn 5 ('index'). Så simpelt er det.Nu har vi faktisk alt hvad vi behøver til at løbe gennem bibliotekerne og lave links dertil. Til dette benytter jeg en for()-løkke:
<?php
function breadcrumb()
{
$root = 'http://www.jensgram.dk/'; // Domænet
$dirs = explode('/', $_SERVER['PHP_SELF']); // Split ved slashes
$size = sizeof($dirs)-1; // Antal biblioteker
$outp = '<a href="' . $root . '">Forside</a>';
$div = ' / '; // Adskillelse ved links mellem biblioteker i output
$fnam = substr($dirs[$size], 0, strrpos($dirs[$size], '.')); // Filnavn (mellem begyndelse af sidste element i $dirs-array'et og (sidste) punktum)
for ($i = 1; $i < $size; $i++) {
$outp .= $div . '<a href="' . $root . $dirs[$i] . '/">' . $dirs[$i] . '</a>'; // Lav adskillelse og link til det aktuelle bibliotek ($dirs[$i])
$root .= $dirs[$i] . '/'; // Tilføj det aktuelle bibliotek til $root.
}
return $outp;
}
?>
For()-løkken starter med at sætte en iterations-variabel ($i) til 1. Dette skyldes, at jeg vil benytte $dirs[$i] og jeg nævnte jo tidligere at $dirs[0] er tom. Desuden benytter jeg $i < $size som betingelse for løkken. Dette betyder, at jeg ikke får det sidste element i $dirs-array'et med (fil-delen), hvilket er meningen nu!
Inden i løkken tilføjes et link til hvert bibliotek til $outp-variablen (denne returneres senere). $div angiver, hvad der skal være i mellem link'ene. I dette tilfælde er det strengen ' / ', men man kan benytte al HTML (billeder etc.).
Vi tilføjer desuden det aktuelle bibliotek til $root, da vi jo skal benytte det til underbibliotekerne osv.
Status:
Vores script kan nu returnere:
'<a href="http://www.jensgram.dk/">Forside</a> / <a href="http://www.jensgram.dk/web/">web</a> / <a href="http://www.jensgram.dk/web/objects/">objects</a> / '
hvis $_SERVER['PHP_SELF'] indeholder:
'/web/objects/index.php'
Så kommer vi til selve filnavnet. Problemet er dog, at vi måske ikke vil have alle filer vist. For eksempel benytter jeg selv 'index.php' som indeks, hvilket vil sige at /mappe/ henviser til /mappe/index.php. Det kan således være rart at kunne undgår nogle filer, da 'mappe' vil være smartere i en breadcrumb end 'mappe' / 'index'.
Vi opretter derfor et array med "forbudte" filnavne. Vi tjekker så, om den aktuelle fil er deri når vi udskriver linket:
<?php
function breadcrumb()
{
$root = 'http://www.jensgram.dk/'; // Domænet
$dirs = explode('/', $_SERVER['PHP_SELF']); // Split ved slashes
$size = sizeof($dirs)-1; // Antal biblioteker
$outp = '<a href="' . $root . '">Forside</a>';
$div = ' / '; // Adskillelse ved links mellem biblioteker i output
$fnam = substr($dirs[$size], 0, strrpos($dirs[$size], '.')); // Filnavn (mellem begyndelse af sidste element i $dirs-array'et og (sidste) punktum)
$hide = array('index', 'default'); // Filernavne, der ikke skal linkes til
for ($i = 1; $i < $size; $i++) {
$outp .= $div . '<a href="' . $root . $dirs[$i] . '/">' . $dirs[$i] . '</a>'; // Lav adskillelse og link til det aktuelle bibliotek ($dirs[$i])
$root .= $dirs[$i] . '/'; // Tilføj det aktuelle bibliotek til $root.
}
if (in_array($fnam, $hide) == false) {
$outp .= $div . '<a href="' . $root . $dirs[$sizeof] . '">' . $fnam . '</a>'; // Skriv link til filnavn, hvis det ikke skal skjules
}
return $outp;
}
?>
Først og fremmeste har jeg tilføjet array'et $hide. Her kan du selv skrive, hvilke filer der ikke skal vises i din breadcrumb.
Jeg har også tilføjet et if()-statement. Betingelsen er, at filnavnet ($fnam) ikke skal være i array'et $hide. Til dette benyttes in_array(). Er filnavnet tilladt skrives det til $outp-strengen som derefter returneres.
Nu har vi faktisk en funktion, der vil returnere:
"Forside / web / objects", hvis man går ind på http://www.jensgram.dk/web/objects/index.php
Vi ser her, hvordan index.php sorteres fra, da navnet 'index' er i $hide-array'et.
Ovenstående er næsten hvad vi ønskede. Det ville dog være smart, hvis de forskellige elementer havde store begyndelsesbogstaver og underscores (_) blev lavet til mellemrum i link-teksterne (selvfølgelig ikke i selve link'ene!)
Dette klares med ucwords(), der laver det første tegn i hvert ord stort (uppercase) og strtr() til at ændre underscores til mellemrum. Begge dele sker kun i link-teksterne:
<?php
function breadcrumb()
{
$root = 'http://www.jensgram.dk/'; // Domænet
$dirs = explode('/', $_SERVER['PHP_SELF']); // Split ved slashes
$size = sizeof($dirs)-1; // Antal biblioteker
$outp = '<a href="' . $root . '">Forside</a>';
$div = ' / '; // Adskillelse ved links mellem biblioteker i output
$fnam = substr($dirs[$size], 0, strrpos($dirs[$size], '.')); // Filnavn (mellem begyndelse af sidste element i $dirs-array'et og (sidste) punktum)
$hide = array('index', 'default'); // Filernavne, der ikke skal linkes til
for ($i = 1; $i < $size; $i++) {
$outp .= $div . '<a href="' . $root . $dirs[$i] . '/">' . ucwords(strtr($dirs[$i], '_', ' ')) . '</a>'; // Lav adskillelse og link til det aktuelle bibliotek ($dirs[$i])
$root .= $dirs[$i] . '/'; // Tilføj det aktuelle bibliotek til $root.
}
if (in_array($fnam, $hide) == false) {
$outp .= $div . '<a href="' . $root . $dirs[$size] . '">' . ucwords(strtr($fnam, '_', ' ')) . '</a>'; // Skriv link til filnavn, hvis det ikke skal skjules
}
return $outp;
}
?>
Nu kan du indsætte en komplet breadcrumb med følgende:
<?php
print breadcrumb();
?>
Nemmere kan det da vist ikke blive?!
Stor tak til Jens Gram som har skrevet denne artikel. Besøg Jens på www.jensgram.dk
Tilføjet af Simon Glue den 14-02-2004
HEPHEY har copyright på al tekst, grafik og andet materiale på denne side. Materialet må ikke gengives uden tilladelse jævnfør lov om ophavsret.