Linuchs: HTML-Code ungesampelt auf Webseite zeigen - geht das? NICE TO HAVE

problematische Seite

NICE TO HAVE

Moin,

bisher habe ich HTML-Code-Schnippsel in die Dokumentation kopiert und in der Kopie die < durch &lt; ersetzt, aber bei der nächsten Programmänderung ist die Doku dann veraltet.

Wäre schön, zu einem bestimmten Kapitel der Platzhalter-Datei (Template) zu verlinken und im Browser den Code wie im Text-Editor zu sehen.

Kann man einen HTML-Code mit irgendwas umschließen, damit der Code vom Browser nicht ausgeführt, sondern nur als Text gezeigt wird?

Meine ausführbaren Programme holen sich NUR die Zeilen zwischen <!-- [...] --> und <!-- [/...] -->, deshalb kann ich davor und dahinter beliebigen Code setzen, der den Programmlauf nicht beeinflusst. Auch javascript.

Das hier bringt nicht das Ergebnis, nur als Idee:

<pre id=form_zugangscode>
<!-- [form_zugangscode] -->
<form ...>
  ...
</form>
<!-- [/form_zugangscode] -->
</pre>

Die aufwändige Lösung wäre ein PHP-Programm, das sich den Code-Schnippsel holt, alle < durch &lt; ersetzt und dann anzeigt. Aber vielleicht get's ja einfacher.

Gruß, Linuchs

  1. problematische Seite

    Hallo Linuchs,

    ein solches Element gibt es - als dafür vorgesehenes Element - meines Wissens nicht. HTML Elemente werden immer geparsed. Fast...

    Ein möglicher Workaround hätte <![CDATA[ ]]> sein können, aber CDATA Sektionen sind im normalen HTML nicht zugelassen, das ist XML und ist daher bestenfalls in einem SVG Element möglich (was Dir nicht hilft).

    Das einzige HTML Element, dessen Inhalt nicht als HTML geparsed wird, ist <script>. Und hier kannst Du ansetzen, denn der Browser führt Script nur als JavaScript aus, wenn es einen MIME-Typ für JavaScript hat. Alles andere ignoriert es. type="text/javascript" ist der Default, aber du kannst beliebig anderes setzen. Hinzu kommt, dass der Browser im Agent-Stylesheet eine Regel dieser Art enthält:

    script {
        display: none;
    }
    

    und die kannst Du überschreiben.

    <script type="text/html">
    <ul>
      <li>Beispielliste Punkt 1</li>
      <li>Beispielliste Punkt 2</li>
    </ul>
    </script>
    

    Das machst Du mit dieser CSS Regel sichtbar:

    script[type='text/html'] {
      display: block;
      white-space: pre;
      font-family: monospace;
      /* Nach Geschmack mit weiteren Zutaten verfeinern */
    }
    

    Rolf

    --
    sumpsi - posui - obstruxi
    1. problematische Seite

      Servus!

      Hallo Linuchs,

      ein solches Element gibt es - als dafür vorgesehenes Element - meines Wissens nicht.

      Führer gab's mal: HTML/Elemente/xmp (Wird von Browsern auch noch verstanden, aber ohne Garantie für die Zukunft!

      HTML Elemente werden immer geparsed. Fast...

      Herzliche Grüße

      Matthias Scharwies

      --
      Eigentlich hatte ich heute viel vor - jetzt habe ich morgen viel vor!
      1. problematische Seite

        Hallo Matthias Scharwies,

        xmp

        Wird auch heute noch verstanden, hat aber - zumindest in Chrome - nicht mehr die "Parse mich nicht" Semantik.

        HTML-Maskierer

        Ist etwas, was ich auch schon überlegt hatte. Die Frage war dann, wo ich den Quellcode hinterlege - und kam auf ein <script> Element. Und dann fiel mir auf: Das kann man ja auch sichtbar machen.

        Ein Problem entsteht nur, wenn der Beispielcode <script></script> enthält, in dem Moment geht es schief, weil der script-Block vorzeitig beendet wird.

        Die Alternative könnte ein <template> Element sein, aber dann braucht man wirklich JavaScript, um den Template-Inhalt in den Code-Rahmen zu übertragen.

        Ein HTML Maskierer, um den HTML Code darzustellen, ist allerdings nicht erforderlich. Das Wiki-Beispiel ist in dieser Beziehung mehrfacher Müll - sorry, falls es von Dir stammt.

        1. Der Inhalt der textarea müsste im click-Handler ausgelesen werden, nicht vor dem click-Handler. So, wie es jetzt ist, wird eine Benutzereingabe nicht verarbeitet.
        2. Unclean Code: htmlSpecialChars tut zu viel, es darf nur die Maskierung ausführen. Die Zuweisung an das output-Element gehört davon getrennt
        3. Das Ergebnis von str.replace müsste wieder an str zugewiesen werden
        4. Die Maskierung ist komplett unnötig, wie sich durch die fehlende Zuweisung zeigt. Auslesen des innerHTML einer Textarea liefert bereits HTML Symbole statt <&>, und wenn ich etwas an die innerText Eigenschaft eines Elements zuweise, brauche ich eh nicht zu maskieren
        5. innerText ist ein IE Erbe, besser ist textContent.

        TL;DR: Ein HTML Maskierer ist in JavaScript zumeist überflüssig. Ich habe jederzeit die Wahl zwischen innerHTML und textContent, je nach Bedarf.

        Wenn ich mich bis 15:00 nicht drum gekümmert habe, komme ich erst morgen dazu.

        Rolf

        --
        sumpsi - posui - obstruxi
        1. problematische Seite

          Servus!

          Hallo Matthias Scharwies,

          xmp

          Wird auch heute noch verstanden, hat aber - zumindest in Chrome - nicht mehr die "Parse mich nicht" Semantik.

          HTML-Maskierer

          Wenn ich mich bis 15:00 nicht drum gekümmert habe, komme ich erst morgen dazu.

          +1

          Herzliche Grüße

          Matthias Scharwies

          --
          Eigentlich hatte ich heute viel vor - jetzt habe ich morgen viel vor!
          1. problematische Seite

            Hallo Matthias,

            done

            Rolf

            --
            sumpsi - posui - obstruxi
    2. Hallo Rolf,

      du bist ein Zauberer (für jede Illusion eine Lösung). Das funktioniert hervorragend. Nun kann ich in der Doku zu jedem Kapitel verlinken.

      Ich teste gerne Grenzen aus, funktioniert auch ein script im script?

      https://remso.eu/100/p124_de.htm#form_gruppenmitglied

      <script id=form_gruppenmitglied type="text/html">
      <!-- [form_gruppenmitglied] -->
      ...
        <script>
          console.log ("Test: script in script" );
        </script>
      <!-- [/form_gruppenmitglied] -->
      </script>
      

      Das erste script zeigt im normalen Programmlauf den Text in der Konsole, beendet aber die „Spezial-anzeige“ der Dokumentation vorzeitig. Damit kann ich leben und weiterarbeiten. Danke nochmal.

      1. Hallo Linuchs,

        das Thema script-in-script hat mich nicht losgelassen. Ich habe jetzt diesen Vorschlag, mit einem template-Element (welches Du mutmaßlich in deinen Codeschnipseln nicht verwendest):

        <p>Beispiel 1:</p>
        
        <template class="example-code"><ul>
          <li>Beispielliste 1 Punkt 1</li><script></script>
          <li>Beispielliste 1 Punkt 2</li>
        </ul></template>
        
        <p>Beispiel 2:</p>
        
        <template class="example-code"><ul>
          <li>Beispielliste 2 Punkt 1</li><script></script>
          <li>Beispielliste 2
        

        mit diesem Helper-Script:

        document.querySelectorAll(".example-code").forEach(sample => {
          let htmlConvert = document.createElement("div");
          htmlConvert.appendChild(sample.content.cloneNode(true));
        
          let showSample = document.createElement("samp");
          showSample.className = "example-code";
          showSample.textContent = htmlConvert.innerHTML;
          sample.after(showSample);
        });
        

        Je template mit class="example-code" wird die Pfeilfunktion durchgeführt, und sie fügt einfach hinter dem Template ein <samp>-Element ein mit dem HTML Text des Template-Inhalts. Damit das geht, muss der Template-Inhalt erstmal in ein HTML Element übertragen werden. Dazu ist das <div>-Element da (das ist temporär und wird nicht ins DOM gestellt), dort kann ich mit innerHTML dann auch einfach den HTML Quelltext des Beispiels auslesen und ihn als textContent ins <samp>-Element setzen. Ein in JavaScript geschriebener HTML Maskierer ist nicht nötig.

        Du müsstest noch etwas CSS ergänzen, um samp.example-code schick zu machen. Es braucht zumindest white-space:pre.

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Hallo Rolf,

          das Thema script-in-script hat mich nicht losgelassen.

          Nachdem dein erster Vorschlag so hervorragend funktionierte, dachte ich: Schalte die gesamte Code-Anzeige mit einem script aus und nur die Formulare wieder ein.

          Das wäre ein realistischer script-im-script Fall.

          Aber jetzt mache ich erstmal im Tagesablauf weiter ...

          Gruß, Linuchs

  2. problematische Seite

    Die aufwändige Lösung wäre ein PHP-Programm, das sich den Code-Schnippsel holt, alle < durch &lt; ersetzt und dann anzeigt. Aber vielleicht get's ja einfacher.

    Das ist 1. nicht „aufwändig“ und 2. willst Du bitte einfach htmlspecialchars( $txt ) verwenden.

    1. problematische Seite

      Hallo Raketenwilli,

      okay, da hast Du eigentlich eine deutlich einfachere Lösung. Einfach die .htm Dateien der Doku nach .php umbenennen. Der Abruf der Dokuseiten wird damit etwas teurer, weil dann PHP ausgeführt werden muss, aber so viele Leute werden diese Seiten nicht abrufen.

      Für das Verfassen der Doku ist es dann sicherlich einfacher. Nix mehr kopieren, einfach so:

      <?php require_once("doku_tools.php"); ?>
      
      DOKU
      BLAH
      BLUB
      TEXT
      <?php get_snippet("foo.php", "form_gruppenmitglied" ?>
      BLAH
      BLUB
      <?php get_snippet("foo.php", "menu_verteiler" ?>
      LABER
      FASEL
      

      get_snippet liest die Quelldatei und holt den von Linuchs entsprechend markierten Bereich heraus. Passt 😀

      Rolf

      --
      sumpsi - posui - obstruxi