Hans-Joachim: BB-Code Parserklasse von Christian Seiler

Hallo,

weil ich ein Problem beim verschachteln von BB-Code hatte, hat mir Siechfred (https://forum.selfhtml.org/?t=90730&m=544411) die Parserklasse von Christian Seiler empfohlen.

Ich muss ja gestehen, dass es länger als lang gedauert hat bis ich mich darin zurecht gefunden habe. Jetzt finde ich mich aber so lala zurecht... Ich teste zurzeit mit der Testdatei "bbcode_test.php", welche Christian auf seiner Seite bereitstellt.

Jetzt wäre ich froh Hilfe zu bekommen, von jemanden der diese Klasse kennt...
In der Testdatei wird über folgenden Code der Klasse mitgeteilt, welche BB-Codes verwendet werden (auszugsweise):

$bbcode->addCode ('b', 'simple_replace', null, array ('<b>', '</b>'), 'inline', array ('listitem', 'block', 'inline', 'link'), array ());

Ich denke, dass über die beiden letzten Arrays festgelegt wird, ob und in welchem BB-Code dieser Code (in dem Fall [b]) verschachtelt werden darf.
Liege ich hierbei ersteinmal richtig?

Ich würde gern wissen, was diese einzelnen Arrayinhalte...

array ('listitem', 'block', 'inline', 'link')

...bedeuten?

Ich würde mich freuen, wenn mir das jemand erklären könnte.

Vielen Dank
Hans-Joachim

  1. Hallo Hans-Joachim,

    Ich muss ja gestehen, dass es länger als lang gedauert hat bis ich mich darin zurecht gefunden habe.

    Ich weiß, meine Dokumentation ist nicht so toll. :-(

    $bbcode->addCode ('b', 'simple_replace', null, array ('<b>', '</b>'), 'inline', array ('listitem', 'block', 'inline', 'link'), array ());

    Ich denke, dass über die beiden letzten Arrays festgelegt wird, ob und in welchem BB-Code dieser Code (in dem Fall [b]) verschachtelt werden darf.
    Liege ich hierbei ersteinmal richtig?

    Ja.

    Ich würde gern wissen, was diese einzelnen Arrayinhalte...

    array ('listitem', 'block', 'inline', 'link')

    ...bedeuten?

    Gar nichts. :-) Das sind von Dir frei verwendbare Namen. Du kannst da auch 'hans' und 'joachim' reinschreiben.

    Im drittletzen Parameter (hier: 'inline') definierst Du den sog. "Inhaltstyp" eines Codes. Diesen kannst Du frei wählen. Der vorletze Paramter gibt an, innerhalb welcher Inhaltstypen der Code vorkommen darf. Der letzte Parameter gibt an, innerhalb welcher Inhaltstypen der Code *nicht* vorkommen darf. Allerdings hat der letzte Parameter die Besonderheit, dass alle aktuell bereits geöffneten Codes angeschaut werden während der vorletzte Parameter nur den zuletzt geöffneten Code betrifft.

    Bsp: [a] hat den Inhaltstyp 'ich' und [b] hat den Inhaltstyp 'du'. [a] und [b] sind so definiert:

    $bbcode->addCode ('a', [...], 'ich', array ('ich', 'du', 'block'), array ());
    $bbcode->addCode ('b', [...], 'du', array ('ich'), array ('du'));

    [a] ist folglich überall erlaubt, [b] nur in 'ich' aber nicht in 'du'.

    Folgende Beispiele:

    - [a]Hallo[/a]
          Würde akzeptiert werden, [a] ist ja überall erlaubt (s.u. bzgl. 'block').
     - [b]Hallo[/b]
          Würde ignoriert werden, [b] ist ja nur innerhalb von 'ich' erlaubt (s.u. bzgl. 'block').
     - [a][b]Hallo[/b][/a]
          Würde akzeptiert werden.
     - [a][b][a]Hallo[/a][/b][/a]
          Würde akzeptiert werden.
     - [a][b][a][b]Hallo[/b][/a][/b][/a]
          [a][b][a] würde akzeptiert werden, das innere [b] würde ignoriert werden und somit würde das "[b]Hallo" wie normaler Text behandelt werden (normalerweise würde nur das "Hallo" wie normaler Text behandelt werden.

    Sonderfall: Wenn gar kein Code offen ist, dann ist der aktuelle Inhaltstyp 'block'. Man kann den natürlich auch selbst für eigene Codes verwenden.

    Ist das ganze jetzt klarer geworden?

    Viele Grüße,
    Christian

    1. Hallo Christian,

      Bsp: [a] hat den Inhaltstyp 'ich' und [b] hat den Inhaltstyp 'du'. [a] und [b] sind so definiert:

      $bbcode->addCode ('a', [...], 'ich', array ('ich', 'du', 'block'), array ());
      $bbcode->addCode ('b', [...], 'du', array ('ich'), array ('du'));

      [a] ist folglich überall erlaubt, [b] nur in 'ich' aber nicht in 'du'.

      Ahhh, jetzt machts langsam "Klick".
      Wäre es dann nicht einfacher, dem Inhaltstyp gleich dem BBCode zu nennen? :
      $bbcode->addCode ('a', [...], 'a', array ('a', 'b', 'block'), array ());
      $bbcode->addCode ('b', [...], 'b', array ('a'), array ('b'));

      So würde mir es persönlich am besten gefallen...
      Nun hoffe ich mal, dass ich es richtig verstanden habe.

      Sonderfall: Wenn gar kein Code offen ist, dann ist der aktuelle Inhaltstyp 'block'. Man kann den natürlich auch selbst für eigene Codes verwenden.

      Also sind alle Inhaltstypen frei wählbar bis auf "block", welches für "alles" bzw. "das Gesamte" definiert ist?

      Ist das ganze jetzt klarer geworden?

      Im Moment erscheint mir es ersteinmal wie ein "klick" "lichtblick" *g*
      Ich werde mich ransetzten und sehen, ob ich weiterhin alles kapiere.
      Wenn ich wieder irgendwo "hänge" werde ich hier wieder schreiben, vorausgesetzt, der Thread ist nicht schon im Archiv gelandet.

      Danke für die Antwort
      Hans-Joachim

      1. Hallo Hans-Joachim,

        Ahhh, jetzt machts langsam "Klick".
        Wäre es dann nicht einfacher, dem Inhaltstyp gleich dem BBCode zu nennen?

        Das kannst Du gerne machen, wenn es Dir so gefällt. :-) Und Du hast es bis hierhin auch richtig verstanden, falls Du das fragen wolltest. ;-)

        Sonderfall: Wenn gar kein Code offen ist, dann ist der aktuelle Inhaltstyp 'block'. Man kann den natürlich auch selbst für eigene Codes verwenden.
        Also sind alle Inhaltstypen frei wählbar bis auf "block", welches für "alles" bzw. "das Gesamte" definiert ist?

        Ich weiß nicht, ob Du das richtig verstanden hast und Dich nur falsch ausdrückst oder ob Du mich da falsch verstanden hast. 'block' ist für die äußerste Ebene definiert. Beispiel:

        [a][b]Hallo[/b][/a], [c]Tschüß[/c]!

        Hier müßten [a] und [c] in 'block' erlaubt sein, weil sie eben direkt im Text vorkommen, [b] dagegen müsste nicht in 'block' erlaubt sein (könnte natürlich auch), muss dagegen in [a] erlaubt sein. Klar?

        Viele Grüße,
        Christian

        1. Hallo Christian,

          ...'block' ist für die äußerste Ebene definiert. Beispiel:

          [a][b]Hallo[/b][/a], [c]Tschüß[/c]!

          Hier müßten [a] und [c] in 'block' erlaubt sein, weil sie eben direkt im Text vorkommen, [b] dagegen müsste nicht in 'block' erlaubt sein (könnte natürlich auch), muss dagegen in [a] erlaubt sein. Klar?

          Jetzt hab ichs verstanden :)

          Danke für deine Mühe,
          Hans-Joachim

      2. Hallo Hans-Joachim,

        Ich werde mich ransetzten und sehen, ob ich weiterhin alles kapiere.
        Wenn ich wieder irgendwo "hänge" werde ich hier wieder schreiben, vorausgesetzt, der Thread ist nicht schon im Archiv gelandet.

        Falls er das ist, kannst Du mich zu diesem Thema gerne auch per Mail kontaktieren, schließlich bin ich ja der Autor der Klasse.

        Viele Grüße,
        Christian

      3. Hallo Hans Joachim,

        Wäre es dann nicht einfacher, dem Inhaltstyp gleich dem BBCode zu nennen? :
        $bbcode->addCode ('a', [...], 'a', array ('a', 'b', 'block'), array ());
        $bbcode->addCode ('b', [...], 'b', array ('a'), array ('b'));

        Ich habe bei mir z.B. den Inhaltstyp für die drei Schriftformatierungen gesetzt:

        $bbcode->addCode ('b', [...], 'b_u_i', array ('b_u_i', 'block'), array ());
        $bbcode->addCode ('u', [...], 'b_u_i', array ('b_u_i', 'block'), array ());
        $bbcode->addCode ('i', [...], 'b_u_i', array ('b_u_i', 'block'), array ());

        Des Weiteren habe ich noch BB-Codes für die zentrierte sowie rechte Textausrichtung. Dort habe ich diese beiden wiederum zum Inhaltstyp "center_right" zusammengefasst.
        Somit hat man nicht als so viel Arbeit beim festlegen der möglichen Verschachtelungen.

        Gruß
        Erri

  2. Hallo Christian Seiler,

    ich habe mir auch deine BB-Code Parser-Klasse zu Gemüt gezogen und ich muss sagen, ich bin hellauf begeistert. Das ist eine wirkliche Erleichterung für das einbinden von BB-Code.
    Ich werde sie in meine Website einbinden, natürlich mit Hinweis auf den Autor. (Wer sich so ne Mühe macht :-) )

    Ich habe gerade ein Problem mit den Listen. Bei jedem Listenelement wird bei mir ein <br> angehängt. Kannst du mir vielleicht einen Tipp geben, wo ich dies abstellen kann?

    Noch eine Frage:
    Du ersetzt mittels nl2br() die Zeilenumbrüche, allerdings wird somit kein valides HTML erstellt, weil die Funktion statt <br> <br /> ausgibt. Somit wollte ich die Funktion "nl2br()" mit der "str_replace()" ersetzen. Somit müsste ich aber dieser Funktion Argumente übergeben. Dies habe ich leider nicht hinbekommen.
    Vielleicht weißt du, wie ich dies realisieren könnte?

    Zurzeit habe ich es so gelöst, dass ich vor der Ausgabe alle "<br />" mit...

    $text = str_replace("<br />", "<br>", $bbcode->parse ($_POST['text']) );

    ... ersetze.

    Ich würde mich sehr über eine Rückantwort freuen.
    Viele Grüße und Vielen Dank
    Erri

    1. Hallo Christian Seiler,

      ich habe gerade noch etwas, was nicht so richtig funktionieren will.
      Und zwar habe ich gerade versucht, diese Smiliefunktion "einzubauen".
      Dabei bin ich folgendermaßen vorgegangen:

      1. Funktion vor "if ($_SERVER['REQUEST_METHOD'] == 'POST')" eingefügt:

      //Smilies ersetzen
      function replace_smilie ($text) {
          // hier sollten die Ersetzungen durchgeführt werden, z.B. so:
          $text = str_replace (':-)', '<img src="../imgs/smilies/icon_smile.gif" alt=":-)">', $text);
          return $text;
      }

      2. Parserfunktion registriert:

      // Smilies
      $bbcode->addParser ('replace_smilie', array ('block',[...]));

      Das Problem ist, dass der Text des images nicht in HTML umgesetzt wird, sondern als normaler Text ausgegeben wird.
      <img src="../imgs/smilies/icon_smile.gif" alt=":-)">

      Liegt es vielleicht an der htmlspecialchars() ?
      Aber dann dürften ja die anderen Tags (z.B. <b>) auch nicht in HTML umgesetzt werden, oder?

      Viele Grüße und Vielen Danke
      Erri

      1. Hallo Erri,

        // Smilies
        $bbcode->addParser ('replace_smilie', array ('block',[...]));

        Das Problem ist, dass der Text des images nicht in HTML umgesetzt wird, sondern als normaler Text ausgegeben wird.
        <img src="../imgs/smilies/icon_smile.gif" alt=":-)">

        Liegt es vielleicht an der htmlspecialchars() ?

        Ja. Es hängt von der Reihenfolge ab, wie die Parserfunktionen registriert werden. In dieser Reihenfolge werden sie dann ausgfehürt. Beispiel:

        $bbcode->addParser ('replace_smilie', ...);
        $bbcode->addParser ('htmlspecialchars', ...);

        -----------------------
        <Hallo> :-)
        -----------------------
        wird zu:

        -----------------------
        &lt;Hallo&gt; &lt;img src=&quot;../imgs/smilies/icon_smile.gif&quot; alt=&quot;:-)&quot;&gt;
        -----------------------
        (Dein Problem)

        Lösung:

        $bbcode->addParser ('htmlspecialchars', ...);
        $bbcode->addParser ('replace_smilie', ...);

        Dann wird:

        -----------------------
        <Hallo> :-)
        -----------------------

        zu:

        -----------------------
        &lt;Hallo&gt; <img src="../imgs/smilies/icon_smile.gif" alt=":-)">
        -----------------------
        (korrekt)

        Aber dann dürften ja die anderen Tags (z.B. <b>) auch nicht in HTML umgesetzt werden, oder?

        Bei den Tags selbst greifen die Parserfunktionen nicht.

        Viele Grüße,
        Christian

        1. Hi Christian,

          Liegt es vielleicht an der htmlspecialchars() ?

          Ja. Es hängt von der Reihenfolge ab, wie die Parserfunktionen registriert werden. In dieser Reihenfolge werden sie dann ausgfehürt.

          Super, jetzt funktioniert das so, wie ich es haben wollte :-)
          Ich find mich immer besser mit deiner Klasse zurecht!

          Vielen Dank und Viele Grüße
          Erri

    2. Hallo Erri,

      Ich werde sie in meine Website einbinden, natürlich mit Hinweis auf den Autor. (Wer sich so ne Mühe macht :-) )

      Danke. :)

      Ich habe gerade ein Problem mit den Listen. Bei jedem Listenelement wird bei mir ein <br> angehängt. Kannst du mir vielleicht einen Tipp geben, wo ich dies abstellen kann?

      Das hängt mit der Art des Parsers zusammen. Der erkennt nämlich erst, dass der alte Listenpunkt zuende ist, wenn der neue schon angefangen hat. (ist ja auch klar, das Ende der Zeile kann man ja schlecht als Ende des Listenpunkts werten, der Listenpunkt könnte ja über mehrere Zeilen gehen) Es gibt eine "Möglichkeit", das mehr oder weniger zu umgehen, siehe Dir dazu mal den Quelltext meiner Beispieldatei an: http://www.christian-seiler.de/projekte/php/bbcode/bbcode_test.php bzw. http://www.christian-seiler.de/projekte/php/bbcode/bbcode_test.php.txt.

      Noch eine Frage:
      Du ersetzt mittels nl2br() die Zeilenumbrüche, allerdings wird somit kein valides HTML erstellt, weil die Funktion statt <br> <br /> ausgibt. Somit wollte ich die Funktion "nl2br()" mit der "str_replace()" ersetzen. Somit müsste ich aber dieser Funktion Argumente übergeben. Dies habe ich leider nicht hinbekommen.
      Vielleicht weißt du, wie ich dies realisieren könnte?

      Entweder:

      function ersetze_br ($text) {
        return str_replace (...);
      }
      $bbcode->addParser ('ersetze_br', ...);

      oder: $bbcode->addParser (create_function ('$text', 'return str_replace ("\n", "<br>\n", $text);'), ...);

      Siehe auch: http://de3.php.net/de/create_function

      Viele Grüße,
      Christian