André: Mod Rewrite -> nix verstehen!

Hallo zusammen,

ich bin gerade an dem Punkt wo wahrscheinlich alle mal waren die sich mit Mod Rewrite beschäftigt haben, Brainf**k! ;)

Ich baue meine Seite immer mit einem Template System zusammen, wobei die URLs immer so aussehen:

www.meine-seite.de/index.php?cid=leistungen/reparatur

Nun ist das wenig suchmaschinenfreundlich und ich würde gerne solche schönen URLs haben:

www.meine-seite.de/leistungen/reparatur.html

Die richtige Regel wäre doch diese hier, oder?

RewriteEngine On RewriteRule ^([^/]*).html$ /index.php?cid=$1 [L]

Klappt leider nicht. Des Weiteren habe ich überhaupt nicht verstanden, welche URLs ich in den internen Menüs angeben muss. Wenn ich die schöne URL angebe, versteht meine index.php ja gar nicht welche html-Datei sie aufrufen soll, die Variable "cid" existiert ja gar nicht. Andererseits würde man bei der ursprünglichen URL die blöde URL sehen.

Ich verstehe nur noch Bahnhof, bitte helft mir.

Danke!

LG André

  1. Hallo und guten Abend,

    Ich baue meine Seite immer mit einem Template System zusammen, wobei die URLs immer so aussehen:

    Templatesystem oder CMS oder etwas Selbstgebautes?

    Wie sieht denn die Seitenorganisation aus? Werden die Strukturen und und die Ordnung in einer Datenbank festgelegt, oder machst Du das ganz klassisch mit Verzeichnisstrukturen.

    Ich frage das deshalb, weil es mit Verzeichnisebenen am leichtesten zu verstehen wäre.

    Grundlegend sollte man beachten, dass eine Ressource unter der angegebenen URL/URi (extra-Diskussion zur Nomenklatur folgt bestimmt gleich *g*) zu finden sein muss, wenn es Sinn haben soll :-)

    Das bedeutet aber auch, dass das System für alle internen Links auch dieselbe URL/Uri benutzen sollte, denn die Suchmaschinen sollen ja gerade diese "schöne URL" abspeichern und indizieren.

    Die Seiten könnten also folgendermaßen verwaltet werden (vereinfacht):

    id | Titel der Seite | xpath für Link | Modulzugehörigkeit | in-Menu-Flag | gültig bis 1 | Home - example.com | / | general | nein | 2015-06-13 2 | Home - example.com | / | general | ja | 3 | Gästebuch example.com | /guestbook/ | guestbook | ja | 4 | Gästebuch Verwaltung | /guestbook/admin/ | guestbook | lookup |

    usw.

    Über xpath und gültig bis besteht ein Unique Index
    Auf id liegt ein autoincrement (unique) Index

    So könnte Dein System die Links mit Hilfe des xpath aufbauen, und beim Request in der Tabelle nachschlagen, welche ID gerade dazu gehört.

    Für den Aufbaue einer Navigation werden nur diejenigen Einträge berücksichtigt, bei denen das Menu-Flag auf ja steht, oder bei angemeldetem User und "lookup", ein Rechteeintrag in in einer Rechtetabelle vorhanden ist.

    Soweit nur als einfaches Denkbeispiel

    Nun kannst Du dir ein Rewrite fertig machen, dass alle Anfragen auf dein Script mit der Datenbankabfrage umlenkt. Das ist einfach und Du musst es nie ändern. Die Anpassungen finden in der Datenbank statt.

    Grüße
    TS

    1. Hallo TS,

      […] URL/URi (extra-Diskussion zur Nomenklatur folgt bestimmt gleich *g*) […]

      http://wiki.selfhtml.org/wiki/Glossar:URI

      Bis demnächst
      Matthias

      --
      Signaturen sind bloed (Steel) und Markdown ist mächtig.
  2. Tach!

    Klappt leider nicht.

    Klappt nicht als Fehlerbeschreibung. Was passiert denn statt deiner Erwartung?

    RewriteRule ^([^/]*).html$ /index.php?cid=$1 [L]

    ^ und $ bedeuten, dass du den kompletten Pfad betrachtet haben möchtest. Dann kommt eine Gruppierung, die das .html ausschließt. Und in ihr drin möchtest du alle Zeichen haben, die kein / sind, davon beliebig viele. Aber du hast da / drin.

    Des Weiteren habe ich überhaupt nicht verstanden, welche URLs ich in den internen Menüs angeben muss. Wenn ich die schöne URL angebe, versteht meine index.php ja gar nicht welche html-Datei sie aufrufen soll, die Variable "cid" existiert ja gar nicht.

    Was du in deine Verweise schreibst, löst beispielsweise beim Klicken einen Request aus. Der wird zunächst von mod_rewrite umgeschrieben und dann hat deine index.php einen Eintrag in $_GET namens cid.

    dedlfix.

    1. RewriteRule ^([^/]*).html$ /index.php?cid=$1 [L]

      ^ und $ bedeuten, dass du den kompletten Pfad betrachtet haben möchtest. Dann kommt eine Gruppierung, die das .html ausschließt.

      Mit ^ und $ als "kompletten Pfad" kann ich mich ja noch anfreunden (besser: ^ steht für den Anfang des zu vergleichenden Textes, $ für das Ende), aber die folgende Gruppierung schließt .html nicht aus, das ist falsch beschrieben.

      Die Gruppierung, das, was da in runden Klammern steht, umfasst eine beliebige Anzahl, auch keines, () von Zeichen ([]) mit Ausnahme (^) des Schrägstrichs (zusammen: [^/]).

      Danach folgt der Text .html, der vorhanden sein muss, und zwar am Ende des Textes ($).

      Das Muster passt auf ".html" wie auch auf ".html.html".

      1. Es wäre doch sehr erleichternd, ließe sich der Markdown-Scheiss hier zumindest für einen Beitrag komplett abschalten.

        Es nervt.

        Nicht nur, dass bei längeren Absätzen die Übersichtlichkeit flöten geht, weil keine neuen Zeilen möglich sind, es wird auch selbst einfachster Code, kurze Schnippsel, zur Unlesbarkeit verhunzt. Den ganzen Beitrag in "kein Markdown" einhüllen geht aber auch nicht, nein, man darf jedes beknackte Zeichen einzeln maskieren.

        Ein Technikforum, das mehr wert auf Spielkram und Klickibunti legt als darauf, Technik einfach beschreiben zu können.

        1. @@Adalbert Andersbart

          Nicht nur, dass bei längeren Absätzen die Übersichtlichkeit flöten geht, weil keine neuen Zeilen möglich sind,

          ?? Entweder du willst einen neuen Absatz (mit Leerraum zum vorigen) oder du willst keinen neuen. Aber Zeilenumbrich mitten im Absatz?

          Geht übrigens mit zwei Leerzeichen vorm Zeilenumbruch.
          Siehe hier.

          Ein Technikforum, das mehr wert auf Spielkram und Klickibunti legt

          Nein, Klickibunti wäre ein WYSIWYG-Editor. Markdown ist so ziemlich das Gegenteil davon.

          Und ich will Markdown auch nicht verteidigen. Ich glaub nicht, dass das für die Allgemeinheit die beste Wahl ist.

          LLAP 🖖

          --
          Ist diese Antwort anstößig? Dann könnte sie nützlich sein.
      2. Hallo,

        Danach folgt der Text .html, der vorhanden sein muss, und zwar am Ende des Textes ($).

        naja, fast richtig. Zumindest der String "html" muss am Ende des Textes vorhanden sein; der Punkt davor steht ja für ein beliebiges Zeichen.
        Ergo: Nach der Gruppierung, die alles einfangen soll, was kein Slash ist, soll noch ein beliebiges Zeichen folgen und dann der Abschluss "html". Daraus folgt aber, dass der Ausdruck nur matcht, wenn "/html" am Schluss steht; jedes andere Zeichen wäre ja schon durch die davorstehende Gruppierung aufgefressen worden (Greediness).

        Das Muster passt auf ".html" wie auch auf ".html.html".

        Unter anderem.

        So long,
         Martin

        1. Hi,

          naja, fast richtig. Zumindest der String "html" muss am Ende des Textes vorhanden sein; der Punkt davor steht ja für ein beliebiges Zeichen.
          Ergo: Nach der Gruppierung, die alles einfangen soll, was kein Slash ist, soll noch ein beliebiges Zeichen folgen und dann der Abschluss "html". Daraus folgt aber, dass der Ausdruck nur matcht, wenn "/html" am Schluss steht; jedes andere Zeichen wäre ja schon durch die davorstehende Gruppierung aufgefressen worden (Greediness).

          falsch. Die Gierigkeit hat da ihre Grenzen, wo das Gesamt-Match gefährdet wäre.

          Wenn Du z.B. ^(.+)(.+)$ hättest, könnte das nach Deiner Logik niemals ein Match ergeben, da alle Zeichen bereits von der ersten Klammer erfaßt würden. Es kommt aber dabei raus, daß die erste Klammer alle Zeichen außer dem letzten erfaßt, die zweite das letzte Zeichen.

          cu,
          Andreas a/k/a MudGuard

          1. Moin,

            [...] Daraus folgt aber, dass der Ausdruck nur matcht, wenn "/html" am Schluss steht; jedes andere Zeichen wäre ja schon durch die davorstehende Gruppierung aufgefressen worden (Greediness).

            falsch. Die Gierigkeit hat da ihre Grenzen, wo das Gesamt-Match gefährdet wäre.

            oh, wie clever. Man lernt nie aus ...

            Wenn Du z.B. ^(.+)(.+)$ hättest, könnte das nach Deiner Logik niemals ein Match ergeben, da alle Zeichen bereits von der ersten Klammer erfaßt würden.

            Richtig, genau das hätte ich erwartet.

            Es kommt aber dabei raus, daß die erste Klammer alle Zeichen außer dem letzten erfaßt, die zweite das letzte Zeichen.

            Ich hätte nicht gedacht, dass der regex-Algorithmus so schlau ist. Danke für die Klarstellung.

            Ciao,
             Martin

            1. Hi,

              Ich hätte nicht gedacht, dass der regex-Algorithmus so schlau ist. Danke für die Klarstellung.

              Ich empfehle: Jeffrey Friedl: Mastering Regular Expressions

              Sehr gutes Buch!

              cu,
              Andreas a/k/a MudGuard

        2. Hallo und guten Morgen Martin,

          naja, fast richtig. Zumindest der String "html" muss am Ende des Textes vorhanden sein; der Punkt davor steht ja für ein beliebiges Zeichen.

          André ist nur auf Markdown reingefallen. Er hatte gepostet:

          RewriteEngine On 
          RewriteRule ^([^/]*)\.html$ /index.php?cid=$1 [L]
          

          Aber es ist vermutlich sowieso nicht die Rewrite-Rule, die er braucht :-)

          Grüße
          TS

          1. Hi,

            naja, fast richtig. Zumindest der String "html" muss am Ende des Textes vorhanden sein; der Punkt davor steht ja für ein beliebiges Zeichen.

            André ist nur auf Markdown reingefallen. Er hatte gepostet:

            RewriteEngine On 
            RewriteRule ^([^/]*)\.html$ /index.php?cid=$1 [L]
            

            ah, verstehe. Das hatte ich tatsächlich nicht gesehen, sondern nur das durch Markdown verhunzte Ergebnis. Dann ist mein Einwand natürlich erst recht nichtig.

            Schönes WE,
             Martin

          2. Lieber TS,

            naja, fast richtig. Zumindest der String "html" muss am Ende des Textes vorhanden sein; der Punkt davor steht ja für ein beliebiges Zeichen.

            André ist nur auf Markdown reingefallen. Er hatte gepostet:

            RewriteEngine On 
            RewriteRule ^([^/]*)\.html$ /index.php?cid=$1 [L]
            

            Da warst Du jetzt schneller. Mit dem Tablet hat man doch ein Handycap. :-O

            Aber es ist vermutlich sowieso nicht die Rewrite-Rule, die er braucht :-)

            Sehe ich auch so. Aber solange man nicht weiß, wie sein System funktioniert, kann man da gar nichts empfehlen.

            Spirituelle Grüße
            Euer Robert
            robert.r@online.de

            --
            Möge der wahre Forumsgeist ewig leben!
          3. @@TS

            Falsch:

            André ist nur auf Markdown reingefallen.

            Richtig:

            Markdown ist für dieses Forum nicht geeignet.

            LLAP 🖖

            --
            Ist diese Antwort anstößig? Dann könnte sie nützlich sein.
          4. ha!

            Aber es ist vermutlich sowieso nicht die Rewrite-Rule, die er braucht :-)

            Einfach weitermachen, bei den paar Zeichen ist eine gewisse Wahrscheinlichkeit gegeben, so dass nach einer hinreichenden Anzahl an Versuchen, noch zu Lebzeiten des Entwicklers, was Brauchbares dabei herauskommt.

            Schrecklich schwieriger hatte es die Evolution

            <cite>Eine beliebte, bis zum Überdruß strapazierte Variante ist Thorpes Beispiel der Affenhorde, die auf 100 Schreibmaschinen herumhämmert, in der Hoffnung, durch Zufall eine von Shakespeares Werken zu reproduzieren. Die Wahrscheinlichkeit, daß dies über einen vergleichsweise kurzen Zeitraum gelänge, sei Hekatomen mal größer als die Wahrscheinlichkeit, durch Zufall ein Enzym, wie das Cytochrom C entstehen zu lassen. In die Alltagssprache übersetzt heißt dies, es ist unmöglich. Tatsächlich läßt sich die Wahrscheinlichkeit, die festgelegte Aminosäuresequenz einer Enzymkette aus 100 Gliedern, mit 1 : 20100 berechnen.</cite>

            Qualle

            --Dag ;--)

        3. Liebe Mitdenker, liebe Wissende, liebe Neugierige,

          Danach folgt der Text .html, der vorhanden sein muss, und zwar am Ende des Textes ($).

          naja, fast richtig. Zumindest der String "html" muss am Ende des Textes vorhanden sein; der Punkt davor steht ja für ein beliebiges Zeichen.

          Da ist der OP nuer auf Markdown reingefallen.
          Schau es dir nochmal an ;-)

          Das Muster passt auf ".html" wie auch auf ".html.html".

          Spirituelle Grüße
          Euer Robert
          robert.r@online.de

          --
          Möge der wahre Forumsgeist ewig leben!
      3. Tach!

        RewriteRule ^([^/]*).html$ /index.php?cid=$1 [L]

        ^ und $ bedeuten, dass du den kompletten Pfad betrachtet haben möchtest. Dann kommt eine Gruppierung, die das .html ausschließt.

        Mit ^ und $ als "kompletten Pfad" kann ich mich ja noch anfreunden (besser: ^ steht für den Anfang des zu vergleichenden Textes, $ für das Ende), aber die folgende Gruppierung schließt .html nicht aus, das ist falsch beschrieben.

        Im Sinne der exakten Formulierung der Beschreibung von regulären Ausdrücken hast du recht. Wenn man aber mal davon ausgeht, was der OP zu erreichen versucht, finde ich meine Formulierung nicht ganz verkehrt. Er hat da ein .html und das will er im Ergebnis nicht haben, also wird es durch die Klammern der Gruppierung aus ihr ausgeschlossen - also aus der Gruppierung, nicht aus dem gesamten Ausdruck.

        Das Muster passt auf ".html" wie auch auf ".html.html".

        Ist vermutlich kein Beinbruch. Da kommen sowieso jede Menge Requests mit anderen Fehlern und unerwünschten Zugriffsversuchen. Die kann man nicht alle in der Regel ausschließen, das muss dann in der auswertenden Routine abgefangen und zu einem 404 geleitet werden. Dass davon keine selbst generierten Links betroffen sind, muss der OP ausreichend selbst testen.

        dedlfix.

  3. @@André

    www.meine-seite.de/index.php?cid=leistungen/reparatur

    Nun ist das wenig suchmaschinenfreundlich

    Doch. Der Suchmaschine ist es völlig egal, ob ein URI kryptisch oder menschenlesbar ist – sie findet die Seite. (Ranking ist nochmal was ganz anderes.)

    und ich würde gerne solche schönen URLs haben:

    www.meine-seite.de/leistungen/reparatur.html

    Die sind vor allem für Menschen schön, nicht für Maschinen.

    Und das nächste Mal bitte als Beispieldomain nicht irgendeine bestehende verwenden, sondern eine nach BCP 32 dafür vorgesehene.

    LLAP 🖖

    --
    Ist diese Antwort anstößig? Dann könnte sie nützlich sein.