toscho.design

Deppenlink entfernen

Achtung: Künftig verwende bitte mein Plugin Remove Redundant Links. Es überwindet viele Schwächen der unten vorgestellten Version, und es kann automatisch aktualisiert werden. Darin findest du eine gut dokumentierte PHP-Klasse, die du auch ohne WordPress verwenden kannst.


Richtige Links führen auf eine neue Seite. Ein Deppenlink auf die alte. Der Klick bewirkt schlicht ein Neuladen; er irritiert den Leser, verlängert die Liste des Zurück-Buttons und trägt zum allgemeinen Informationsrauschen auf der Seite bei. Ganz mieses Interaktionsdesign.

Viele aktuelle Blogs und Content-Management-System produzieren solche Deppenlinks, und nur wenige Autoren machen sich die Mühe, diese wieder zu entfernen. Schade.

Dabei läßt sich das Problem ganz einfach lösen: Der Autor weiß, wie sein Quellcode vor der Ausgabe aussieht, und welche Seite gerade aufgerufen wird. Jetzt muß er nur noch die passenden Stellen im Code ersetzen – und schon ist er kein Depp mehr. Und seine Leser müssen eine Entscheidung weniger treffen.

In meinen WordPress-Themes benutze ich ein PHP-Script, das die gesamte Ausgabe des HTML-Codes abfängt, aufräumt und dann sauber ausliefert. Darin findet sich diese Funktion:

Update 16.11.2010: Gelöscht, war Mist.

Alte Version

Diese Version sollte nicht mehr verwendet werden; ich lasse sie nur stehen, weil schon Beiträge andernorts darauf verweisen.

/**
 * Entfernt Deppenlinks.
 *
 * @author Thomas Scholz <http://toscho.de>
 * @param string $str Zu filternder String
 * @return string
 */
function remove_self_links($str)
{
    $_SERVER['REQUEST_URI'] = strip_tags($_SERVER['REQUEST_URI']);
    /* Absolute URLs zu absoluten Pfaden. 
     * Zweimal str_replace() ist schneller als einmal preg_replace().
     */
    $str    = str_replace(
        'href="http://'. $_SERVER['SERVER_NAME'], 'href="', $str);
    $str    = str_replace(
        "href='http://". $_SERVER['SERVER_NAME'], "href='", $str);
    /* Links auf die Startseite sind jetzt leer, müssen gefüllt werden. */
    $str    = str_replace(array("href=''", 'href=""'), "href='/'", $str);
    /* Links auf die aktuelle Seite entfernen. Nur bei GET. */
    if ( 'GET' != $_SERVER['REQUEST_METHOD'] )
    {
        return $str;
    }
    $str    = preg_replace('~<a\s*([^>]*)href\s*=\s*(["|\'])'
        . $_SERVER['REQUEST_URI'] . '\\2([^>]*)>(.*)</a>~Umis',
        '<span title="Hier befinden Sie sich gerade." class="current">'
        . "\\4" . '</span>',
        $str);
    return $str;
}

In WordPress kann man sich diese Funktion entweder in die eigenen Scripte einbauen, oder man schreibt sie in die eigene functions.php und setzt ganz oben in die header.php folgende Zeile:

ob_start('remove_self_links');

Das reicht schon. Damit erwischt man nicht nur Links in der Navigation, sondern auch beispielsweise in der Übersicht einer Kategorie.

Anhand der Klasse current kann man diese Nicht-Links jetzt auch mit CSS ansprechen:

.current {
    color:      #777;
    background: #fff;
}

Natürlich funktioniert das nicht nur in WordPress, sondern mit jeder Seite, die mit PHP generiert wird. Da kann man entweder mit dem generellen ob_start() für alles arbeiten oder so:

<?php
/* Puffer starten. */
ob_start();
?>
<!-- normaler HTML-Code, beispielsweise die Navigation -->
<?php
/* Puffer abfangen. */
$clean = ob_get_contents();
/* Puffer leeren. */
ob_end_clean();
/* Aufräumen. */
$clean = remove_self_links($clean);
/* Ausgeben. */
echo $clean;
/* Fertig. */
?>

Löst ihr dieses Problem anders? Wie? Oder gar nicht? Warum?

43 Kommentare

  1. Dennis Frank am 30.01.2009 · 18:31

    Und wenn es mal schnell gehen muss oder man den HTML-Code nicht ändern kann, reicht manchmal auch ein bisschen CSS-Kosmetik um den Link vor normalen Benutzern zu tarnen:

    a.current,
    a.current:hover {
       cursor: default;
       text-decoration: none;
       color: #000;
       }
    

    (Die nötigen Properties sind natürlich individuell unterschiedlich.)

  2. GwenDragon am 02.02.2009 · 19:52

    Ich bin immer noch ein Pseudo-Depp im Blog. ;)
    Bevor der Deppenlink schwindet, muss ich erst die Plugins für Kategorien, Tags und Breadcrumbs umprogrammieren.
    Demnächst, eben.

    Derzeit sind die aktuellen Links anwählbar, um schneller in der Navigation zurück zu kommen, aber wenigstens fett ausgezeichnet.

    Nicht sehr toll als USability. Aber es geht noch.
    Ich muss mal die Navigation des Blogs überdenken.

  3. Thomas Scholz am 02.02.2009 · 20:52

    Dein Blog ist bestimmt in Perl geschrieben, oder? Da kannst du doch auch Outputbuffering verwenden.

    Hier im Blog fasse ich zum Entfernen der Deppenlinks kein einziges Plugin an; ich sorge einfach dafür, daß die Reparatur zuletzt arbeitet. Das spart das ganze Gefrickel.

  4. Dieter am 05.02.2009 · 14:19

    Also ich habe das Problem bisher leider nicht gelöst, sondern nur etwas abmildern können.
    Ich setze das WordPress-Plugin Breadcrumb NavXT ein. Dort sowie beim aktivem Menüpunkt meiner Hauptnavigation habe ich für die aktuelle Seite den Link nicht nur mit Fettdruck gestaltet, sondern auch noch mit der Standardfarbe schwarz versehen und den Mauszeiger an normalen Text angepasst.

    Dein PHP-Skript bekam ich leider nicht umgesetzt. Dafür fehlt es mir (noch?) an den entsprechenden PHP-Kenntnissen. Leider!

  5. Thomas Scholz am 05.02.2009 · 14:29

    Schreibe die Funktion (den ersten großen Quelltext) in die Datei functions.php deines aktuellen Themes.
    In die header.php des Themes schreibst du ganz oben, direkt nach dem <?php den zweiten Code:

    ob_start('remove_self_links');

    Das sollte in jedem WordPress funktionieren, und Programmierwissen brauchst du dazu nicht.

  6. Dieter am 05.02.2009 · 16:38

    Danke für den Hinweis, dass man den Code jeweils noch in php und ?> setzen muss.
    Damit funktionierte es! Super!

    Leider zerhaute es mir dafür dann das Layout.

    Konkret: Tabreiter der aktiven Seite war weg und der Linktext oberhalb und bei Blogbeiträgen verschwand (verständlicherweise) das als CSS-Image eingefügte Icon dafür, so dass der "Nichtlink" einen unschönen Einzug bekam.
    Ich gehe davon aus, dass sich das über entsprechende CSS-Festlegungen für Nichtlinks in den Navigationsbereichen beheben lässt. Allerdings ist meine CSS-Datei viel zu groß. Da muss ich noch einmal in mich gehen, ob ich dafür einen so großen Aufwand betreiben sollte.

  7. Thomas Scholz am 05.02.2009 · 16:58

    Ersetze einfach das #nav_main ul li.current_page_item a in der green_2col_right.css durch #nav_main ul li .current. Das war’s schon.

  8. Dieter am 05.02.2009 · 17:18

    Herzlichen Dank für Deine Hilfe.

    Das war es aber leider nicht schon. Der Tab mit dem "Nichtlink" springt hoch und die Startseite lässt sich dann nicht mehr über die Hauptnavigation aufrufen. Und das ist nur das, was mir direkt auffiel. Das ist mir ein zu hoher Anpassungsaufwand. Habe noch bedeutsamere Baustellen.

  9. Klaus am 01.04.2009 · 15:40

    Hallo Thomas,

    ich wollte mich ausdrücklich für dein Script zum "Deppenlink" entfernen bedanken.
    Meine PHP-Kenntnisse sind äußerst rudimentär, mit WordPress fange ich gerade an und trotzdem hat es einwandfrei geklappt.

    Bis dann im XHTML-Forum.
    Gruß
    Klaus

  10. k am 19.05.2009 · 11:44

    Servus Toscho,

    so ganz hab ich die Problematik noch immer nicht verstanden. Du versuchst hier was genau? Bitte um Erklärung.

  11. Thomas Scholz am 19.05.2009 · 12:38

    @k: Ich entferne den Link auf die Startseite, wenn du auf der Startseite bist, und den auf auf die Kontaktseite, wenn du auf der Kontaktseite bist. Und so weiter.

  12. d. am 04.07.2009 · 18:25

    idee & script klingen gut, leider bekomme ich es aber nicht in wordpress umgesetzt. ich verwende in meinem eigenen theme bisher KEINE functions.php.

    wie soll ich das script denn dann einbinden?

    und mein menü ist aktuell so gestaltet:

    #navmenu{
    text-align: left;
    text-decoration: none;
    list-style-type: none; list-style-image: none;}
    #navmenu a:link, #navmenu a:visited{ 
    text-decoration:none;
    font-size: 16px;
    font-weight: bold;
    color:white;
    border: 1px dashed #ffffff;
    padding: 2px;}
    #navmenu a:active, #navmenu a:hover{
    text-decoration: none;
    color: #333366;
    background-color: #FFffff;
    border: 1px dashed #333366;
    padding: 2px;}
    #navmenu ul { margin:0; padding:0; float:left; width:100%; list-style-type:none; }
    #navmenu ul li { display:inline; margin-right:10px; padding:0; float:left;}
    #navmenu ul li.page_item a { display:block; text-decoration:none; }

    Reicht im Anschluss Dein...

    .current {
        color:      #777;
        background: #fff;
    }

    ? oder muss ich das in meine #navmenu einbinden?

    danke für hilfe!

  13. Thomas Scholz am 04.07.2009 · 19:04

    @d.: Du kannst den Code auch ganz oben in die header.php schreiben, vor die erste HTML-Ausgabe.

    Ob du nur .current {} schreibst oder #navmenu .current {} hängt davon ab, wie die aktuelle Seite in deinem Menu aussehen soll.

  14. mike am 06.06.2010 · 13:59

    Die Idee an sich finde ich sehr gut.
    Ich sehe nur ein kleines Problem, wo ich mir uneinig bin, wer/was in Sachen Usability gewinnt: nämlich der sogenannte "Permanentlink".
    Sicher, den kann $User sich auch aus der Adressleiste kopieren, aber für den einen oder anderen mag es bequemer sein, diesen rechtsmausig zu kopieren. (für was auch immer, in Mail einfügen etc.)

    Irgendwelche Meinungen dazu?

  15. Thomas Scholz am 06.06.2010 · 14:28

    @mike: Ich halte sehr wenig von diesen Links:

    • Wer weiß, was der Permalink ist, der findet diese Adresse auch so. Die Adressleiste oder der Tab bieten sie ja an.
    • Wer es nicht weiß, der braucht den Link erst recht nicht.
    • Beim Anhören einer Seite wirkt der Link ebenso verwirrend wie jeder andere redundante Link.
    • Bei der Navigation per Tastatur hat man einen unnötigen Zwischenschritt. Nicht alle Browser bieten eine räumliche Navigation an.

    Insgesamt sehe ich also mehr Nach- als Vorteile.

  16. mike am 06.06.2010 · 14:38

    Ok, danke, bin fast überredet ;)
    Mal schauen, ob noch wer Pro-link-argumente in petto hat, ansonsten setze ich das mal zeitnah um. Bisher nie wirklich drüber nachgedacht.

  17. Fritz am 07.06.2010 · 01:17

    Hallo Thomas,

    du hast es vermutlich eh bemerkt, dass ich dich zitiert habe:
    http://webdesign.weisshart.de/blog/2010/06/06/eine-seite-soll-nicht-auf-sich-selbst-verlinken/

    Aber nun zur Pro- und Kontra-Frage:
    Das geilste Argument: Google belohnt den Deppenlink!?
    Davon wollte mich heute tatsächlich jemand per Twitter überzeugen.
    Das Problem? Dieser Jemand rankt bei Google saumäßig gut.

    Und nun?

  18. Thomas Scholz am 07.06.2010 · 01:27

    @Fritz: Eine wissenschaftliche Untersuchung hat mal gemessen: In Gegenden mit vielen Störchen lag die Geburtenrate auffällig hoch. Kausalität tritt nicht dort auf, wo es einem gerade paßt. ☺

    Sachlich betrachtet gibt es keinen Grund, warum eine Seite relevanter sein soll, die sich selbst verlinkt. Das halte ich für Unfug.

  19. Heinz-Georg am 12.07.2010 · 21:28

    Hallo Thomas,

    das, was ich Stunden gesucht hab!

    Ich finde bei mir bloß nicht wo die Formatierung herkommt. Ich habe in der style.css eine Klasse .current angelegt, aber die Seite reagiert da nicht drauf.

    Ich bin zwar mit der aktuellen Formatierung ganz zufrieden, wüsste aber gern wo ich das verändern kann.

    Vielleicht kannst du mir kurz helfen.

    Danke
    Heinz-Georg

  20. Thomas Scholz am 12.07.2010 · 21:46

    @Heinz-Georg: In der Seite, die du hier im Kommentar angegeben hast, funktioniert es; die Formatierung wird angewandt. Sie ist nur wenig deutlich. Wenn du mal einen anderen Hintergrund verwendest, siehst du das Ergebnis sicher besser.
    Nebenbei: Das Theme Twenty Ten solltest du nicht direkt bearbeiten, sonst gehen deine Änderungen beim nächsten Update verloren. Lege lieber ein Child Theme an.

  21. Heinz-Georg am 14.07.2010 · 19:08

    Hallo Thomas,
    ich weiß nicht, wo er die Formatierung her hat. Ich habe in style.css folgenden code eingefügt:
    .current {
    color: #777;
    background: #fff;
    }
    Also müsste die Schrift doch blau sein!?

    Zu dem zweiten Punkt, das wusste ich vorher nicht, hab aber schon einiges in ein paar php Dateien und der style.css geändert. Kann ich da das Theme nicht besser ganz umbenennen?

    Gruß & Danke
    Heinz-Georg

  22. Thomas Scholz am 14.07.2010 · 23:34

    @Heinz-Georg: #777; ist Dunkelgrau. Blau wäre beispielsweise #007.

    Und ja, du kannst das Theme auch umbenennen. Dann profitierst du natürlich nicht mehr von den Verbesserungen der Updates.

  23. Heinz-Georg am 16.07.2010 · 07:43

    Hej Thomas,

    ich hatte mich noch nie mit der Hexadezimale Kurzform beschäftgt, was ich jetzt nachgeholt hab. Hatte die drei Zahlen in den PS Farbwähler eingegeben und der zeigte mir blau. Oh.

    Die Seite ist eh fast nur statisch, das mit Chlid Theme mach ich beim nächsten Projekt.

    Nochmals Danke
    Heinz-Georg

  24. Thomas am 20.07.2010 · 10:55

    Ausgezeichneter Guide. Ich habe dieses Umstand immer auf eine etwas kompliziertere Art und Weise realisiert.
    So ist es aber um einiges eleganter!

  25. Andreas Borutta am 15.09.2010 · 16:08

    Sehr nützliches Skript! Herzlichen Dank.

    Bisher habe ich die Navi für jede einzelne Seite - um den Deppenlink zu vermeiden - immer manuell erstellt.

    Im Site-Titel von Startseiten findet man ebenfalls häufig einen Deppenlink.
    Zum Beispiel auf alistapart.com.

    Muster:
    <h1><a href="/" title="Zur Startseite">Lorem Ipsum</a></h1>

    Auf der Startseite will man:
    <h1>Lorem Ipsum</h1>

    Das erzeuge ich weiterhin händisch.

  26. Andreas am 05.11.2010 · 00:14

    Großartiges, kleines Script!

    Was habe ich immer umständlich ausgeblendet, nun aber, versprach das Script saubere Abhilfe:

    Unter meiner lokalen Testumgebung funktioniert es reibungslos.
    Habe eins, zwei, drei - alles weiter umgebaut und anschließend auf den Server hochgeladen. Das, was lokal(Apache) erwartungsgemäß lief, ist Online schlichtweg nicht zu sehen.

    Woran kann das nur liegen?

  27. Thomas Scholz am 05.11.2010 · 01:21

    @Andreas: Eventuell kommt dir ein zweites Outputbuffering in die Quere. Wenn du beispielsweise nach dem ob_start('remove_self_links'); noch ein ob_start('ob_gzhandler'); stehen hast, so bekommt das Script nur komprimierten Code vor die Nase, mit dem es nichts mehr anfangen kann.
    Oder ein anderes Script leert den Outputbuffer zu zeitig, dann bekommt mein Script nur noch einen leeren String zu Gesicht.

    Vielleicht hilft dir schon ein error_reporting(E_ALL | E_NOTICE); ganz am Anfang der Datei?

  28. Andreas am 05.11.2010 · 13:32

    Danke für die schnelle Hilfe. ☺ Ich nutze übrigens kein WordPress.
    Das Error_reporting zeigt keine Fehler an.

    Wenn es doch lokal funktioniert, wie sollten dann die nachfolgenden Zeilen in:
    D:\xampp\htdocs\...\...\includes\classes\Template.class.php (3 hits)
    Line 56: ob_start();
    Line 58: $data = ob_get_contents();
    Line 59: ob_end_clean();

    online stören???

    Liegts möglicherweise an 1&1?

  29. Thomas Scholz am 05.11.2010 · 16:34

    @Andreas: ob_end_clean() leert den Puffer und deaktiviert die Ausgabe-Pufferung. Aus dem Fragment ersehe ich natürlich keinen Zusammenhang, also kann ich dir nicht mehr dazu sagen. Sieh auch mal bei ob_start() nach, da stehen einige hilfreiche Hinweise im Handbuch.

  30. Andreas am 05.11.2010 · 19:57

    @Thomas Scholz: Hut ab, Thomas,
    man sollte bei Verwendung Deines großartigen Scripts beim Webhoster 1&1 die 3 Angaben $_SERVER['REQUEST_URI'] durch $_SERVER['REDIRECT_SCRIPT_URI'] ersetzen.
    Jetzt funktioniert das Scripten.
    Dank für Alles, insbsondere der zeitnahen Unterstützung!

  31. Thomas Scholz am 05.11.2010 · 21:40

    @Andreas: Interessant. Was steht denn in $_SERVER['REQUEST_URI'] drin? Oder ist das gar nicht gesetzt? Läuft PHP bei dir als Modul oder über CGI?

  32. Andreas am 05.11.2010 · 23:49

    @Thomas Scholz: PHP läuft als Modul. Abfrage auf $_SERVER['REQUEST_URI'] zeigt ein Pfad auf, Beispiel: kunden/1/48566314/htdocs/ ...

  33. Thomas Scholz am 06.11.2010 · 07:10

    @Andreas: Der unsinnige Wert reicht nach einer bösen Fehlkonfiguration. Weise 1&1 bitte mal darauf hin, daß solche Pfade in REQUEST_URI nichts verloren haben, ja?

    Ich habe jetzt die Funktion so geändert, daß sie auch diesen Fall hoffentlich abfängt. Außerdem habe ich den regulären Ausdruck genauer erklärt und die Performance ein wenig verbessert.
    Testest du die Version 1.1 das bitte mal?

  34. Francesco am 06.11.2010 · 08:16

    Bei mir betrachtet Version 1.1 jeden Link als Deppenlink und wandelt ihn um. ☻

  35. Thomas Scholz am 16.11.2010 · 02:11

    Eine neue Fassung des Scriptes findet ihr jetzt im Pluginverzeichnis auf WordPress.org: Remove Redundant Links.

  36. Sven am 07.04.2011 · 19:26

    @Thomas Scholz: Erstmal Danke für das Plugin. Funktioniert prima. Nur eine Sache will bei mir nicht funktionieren (vielleicht hab ich da aber auch was falsch verstanden): Wenn ich bei replace_a ein span eintrage, dann wandelt das Plugin mir alle anchor in spans um ... was ja irgendwie nicht so Sinn der Sache ist, oder? ;).
    Hm, ich glaube ich muß mir das noch mal in Ruhe ansehen.

  37. Andreas am 18.04.2011 · 20:58

    Lokal läuft die aktuelle Version Deines Scriptes, beim Provider 1&1 jedoch nicht ...

  38. Sven am 06.12.2011 · 22:14

    Hm, ich habe gerade ein kurioses Problem, wenn ich das Remove-Redundant-Links-Plugin verwende und für eine Lytebox data-rel="lytebox" verwenden will. Mit aktivierten Plugin wird da bei der Ausgabe rel="lytebox" und data="-" draus.
    Da wird wohl etwas zu gut gefiltert.
    Im Moment kann ich noch nicht so recht sehen welcher Teil des Skripts da Schuld sein könnte.

  39. Thomas Scholz am 07.12.2011 · 00:06

    @Sven: Danke, ist notiert. Ich muß es ohnehin nochmal anfassen, weil auch mit beim Ersetzen des Elementes <a> ein Fehler auftritt. Falls du mal irgendwo einen minimalen Testfall ablegen könntest, als Gist beispielsweise, wäre das sehr hilfreich. :)

  40. Sven am 07.12.2011 · 13:49

    @Thomas Scholz: Ich hab's für mich gelöst bekommen indem ich in der class.Remove_Redundant_Links.php in parse_attributes im Regulären Ausdruck \W durch [^A-Za-z0-9-] (irgendwo habe ich gesehen, dass jemand anstelle meiner Zeichenfolge [\W-] empfohlen hat, aber das macht bei mir nicht dasselbe) ersetzt habe.
    Damit funktioniert jetzt soweit ich sehe für mich alles wie gewünscht. Das wird jetzt nicht unbedingt die beste und ultimative Lösung sein, aber im Moment reicht mir das so.

  41. Thomas Scholz am 07.12.2011 · 20:23

    @Sven: Ja, das sollte genügen. Mittelfristig will ich jeden Regex aus der Klasse verbannen, das verträgt sich mit Markup einfach nicht.

  42. Sven am 07.12.2011 · 20:35

    @Thomas Scholz: Da bin ich ja mal gespannt auf das überarbeitete Plugin (wenn's dann irgendwann soweit ist ;-)).
    Ich hatte schon überlegt, ob man über sowas wie benutzerdefinierte Felder dem Plugin vorgeben könnte das es bestimmte Strings ignorieren soll, aber das kann vielleicht auch nach hinten losgehen oder ist vielleicht auch für manche zu kompliziert.

  43. Thomas Scholz am 07.12.2011 · 21:06

    Ich habe in diesem Jahr noch zwei Deadlines und möchte nicht für jeden einzelnen Bugfix eine neue Version ausgeben. Wird also erst Anfang Januar wieder.