borisbaer: Wie Darstellung und Inhalt trennen?

problematische Seite

Hallo zusammen,

erst mal Off-Topic:

In den letzten Wochen und Monaten habe ich einiges zu JavaScript (jQuery konnte ich sogar ganz ad acta legen), PHP und SQL gelernt, worüber ich als Laie erst mal wahnsinnig froh bin. Als ich mit dem Bau meiner Website angefangen habe, dachte ich überhaupt nicht, so weit zu kommen. Allein schon ein Login-System zu haben oder etwas Umfangreicheres zu programmieren schien mir utopisch. Sehr viel davon habe ich den Leuten hier zu verdanken (v.a. Gunnar Bittersmann und Rolf B.). Daher möchte ich an dieser Stelle mal meinen ganz herzlichen Dank aussprechen für alles.

On-Topic:

Ich bin jetzt an einem Punkt, an dem sich mir immer mehr und mehr die Frage aufdrängt, wie ich Inhalt und Darstellung am besten trenne. Es scheint hierbei wohl mehrere Möglichkeiten zu geben. Bisher habe ich alles über PHP-Funktionen gemacht. Zum Beispiel so:

MARKER(
    'item', // type
    '324px', // position: top
    '606px', // position: left
    '1-2-1-half-moon-grass', // id bzw. input name
    'width: 94px; height: 74px; right: 4px; bottom: 100%; border-width: 1.5px 1.5px 0 0;', // posLine
    'bottom: calc(100% - 7px); right: calc(100% + 3px);', // posName
    $HALFMOONGRASS . ' × 3' // name
);

Obiger Code bezieht sich auf eine Kartenmarkierung (siehe problematische Seite).

Die HTML-Darstellung dazu sieht so aus:

<?php

function MARKER( $type, $top, $left, $id, $posLine, $posName, $name ) { ?>

    <div class="marker <?= $type ?>" style="top: <?= $top ?>; left: <?= $left ?>;">
        <input name="<?= $id ?>" type="checkbox">
        <div class="line" style="<?= $posLine ?>">
            <div class="name <?= $type ?>" style="<?= $posName ?>"><?= $name ?></div>
        </div>
    </div>

<?php }

Das klappt immerhin. Mir scheint dies eine Trennung von Darstellung und Inhalt zu sein. Die „strings“ (z.B. $name) sind zum Großteil in PHP-Variablen gespeichert. So könnte man wohl auch relativ einfach Mehrsprachigkeit nachträglich implementieren.

Jetzt muss ich aber noch mal betonen: Ich bin Laie. Ich habe keinen „ganzheitlichen“ oder „systematischen“ Zugang zu der Thematik. Daher weiß ich nie ganz genau, ob ich gerade Murks mache. Das ist das Beste, was ich mit meinen aktuellen Kenntnissen in Bezug auf Trennung von Darstellung und Inhalt kenne und kann.

Gunnar hatte mir ja bereits zweimal eine Verlinkung zu seiner Star-Trek-Seite gepostet, wo er die Daten mit JSON-LD einfügt. Ich kenne JSON eigentlich kaum, weiß nur, dass man da sozusagen Rohdaten systematisch abspeichern kann. Der einzige Berührungspunkt damit war, glaube ich, als ich einmal Texte aus dem Spiel Sunless Sea kopieren wollte, die sich in JSON-Dateien befanden.

Jedenfalls stellen sich mir zwei Fragen:

  1. Mache ich Murks mit meiner PHP-Funktionen-Lösung?
  2. Gibt es eine bessere Alternative?

Bei JSON kann ich keine Strings mit HTML-Code rausziehen, oder? Nur reinen Text gewissermaßen, d.h. JSON bietet sich meinem Verständnis nach nicht an, um <span style="letter-spacing: .1em">B</span>aum als String einzufügen, sondern nur Baum. PHP kann Ersteres jedoch. Wie dem auch sei, ich würde mich über Empfehlungen und Meinungen zur Trennung von Darstellung und Inhalt freuen.

Vielen Dank schon mal!

  1. problematische Seite

    Lieber borisbaer,

    1. Mache ich Murks mit meiner PHP-Funktionen-Lösung?
    2. Gibt es eine bessere Alternative?
    1. Es sieht definitiv danach aus.
    2. Mit an Sicherheit grenzender Wahrscheinlichkeit ja.

    Bei JSON kann ich keine Strings mit HTML-Code rausziehen, oder?

    Man kann Daten JSON-gerecht maskieren/codieren. Dazu gehören insbesondere die Zeichen " und /, welche mit einem Backslash maskiert werden müssen, da sie ansonsten als Sonderzeichen mit bestimmter Bedeutung interpretiert werden.

    Wenn Du Inhalt, Layout und Funktionalität gut voneinander trennen willst, dann überlegst Du Dir, was HTML-Code in PHP zu suchen hat, was PHP in JavaScript-Code zu suchen hat, und was CSS-Code in HTML zu suchen hat. Wenn Du dann auf die Antwort „gar nichts“ kommst, bist Du auf dem richtigen Weg.

    In PHP-Code sollte ausschließlich PHP-Code stehen. HTML kann aus einer anderen Quelle kommen, z.B. aus Template-Dateien (HTML-Dateien) oder Datenbank-Spalten (HTML-Code als String-Daten). Allerdings kann PHP so ziemlich jede Art von Daten an den Browser senden, auch dynamisch zusammengesetztes JavaScript oder CSS. Das PHP-Script muss dem Browser nur sagen, um welchen Dateityp es sich handelt.

    Liebe Grüße

    Felix Riesterer

    1. problematische Seite

      Servus!

      Lieber borisbaer,

      1. Mache ich Murks mit meiner PHP-Funktionen-Lösung?
      2. Gibt es eine bessere Alternative?
      1. Es sieht definitiv danach aus.
      2. Mit an Sicherheit grenzender Wahrscheinlichkeit ja.

      In PHP-Code sollte ausschließlich PHP-Code stehen. HTML kann aus einer anderen Quelle kommen, z.B. aus Template-Dateien (HTML-Dateien) oder Datenbank-Spalten (HTML-Code als String-Daten).

      @Felix Riesterer hat es ja schon verlinkt, ich möchte es aber noch einmal herausstellen:

      Felix hat einen Kurs geschrieben, der in einer Einführung erst auf die Trennung der Zuständigkeiten und die Unterscheidung von Geschäftslogik vs Darstellungslogik eingeht.

      Das wird in den nächsten 4 Kapiteln an praktischen Beispielen weiter erklärt.

      Herzliche Grüße

      Matthias Scharwies

      --
      Einfach mal was von der ToDo-Liste auf die Was-Solls-Liste setzen.“
      1. problematische Seite

        Hallo Matthias,

        Felix hat einen Kurs geschrieben, der in einer Einführung erst auf die Trennung der Zuständigkeiten und die Unterscheidung von Geschäftslogik vs Darstellungslogik eingeht.

        Das wird in den nächsten 4 Kapiteln an praktischen Beispielen weiter erklärt.

        diesen Artikel hatte ich sogar schon gelesen. Allerdings gibt der Beispielcode in zwei Zeilen einen Fehler aus:

        $tmp = DOMDocument -> loadHTMLFile('home.html');
        

        syntax error, unexpected -> (T_OBJECT_OPERATOR)

        Der gleiche Fehler erscheint auch hier ...

        $page = DOMDocument -> loadHTMLFile("$requested.html");
        

        Pfeiloperatoren kenne ich bisher nur aus JavaScript, aber irgendwas scheint hier nicht zu stimmen.

        Im Browser wird folgende Fehlermeldung angezeigt: Fatal error: Uncaught Error: Undefined constant "DOMDocument" in D:\Websites\games.model\index.php:3 Stack trace: #0 {main} thrown in D:\Websites\games.model\index.php on line 3

        1. problematische Seite

          Hallo borisbaer,

          ich will Felix da nicht ins Wiki hineingrätschen - möglicherweise hat sich da was bei gedacht und es ist keine valide PHP Syntax mehr.

          Aber grundsätzlich ist DOMDocument der Name der Klasse und kann mit dem Pfeiloperator zusammen nicht verwendet werden. Eigentlich sollte es so aussehen:

          $tmp = new DOMDocument();
          $tmp->loadHTMLFile('home.html');
          

          Der Pfeil dient in PHP zum Verweis von Objekten auf ihre Eigenschaften oder Methoden. In JavaScript macht man dafür einfach einen Punkt.

          DOMDocument ist aus meiner Sicht nicht mehr wirklich brauchbar. Es ist auf dem Stand vom HTML 4 stehen geblieben und erbricht sich gerne mal über HTML 5 Konstrukte. Generell wird wohl aktuell https://github.com/Masterminds/html5-php als Ersatz empfohlen, keine Ahnung ob das die einzige Lib ist. Um die einzubinden brauchst Du aber den composer.

          Rolf

          --
          sumpsi - posui - obstruxi
          1. problematische Seite

            Hallo borisbaer,

            ich will Felix da nicht ins Wiki hineingrätschen - möglicherweise hat sich da was bei gedacht und es ist keine valide PHP Syntax mehr.

            Aber grundsätzlich ist DOMDocument der Name der Klasse und kann mit dem Pfeiloperator zusammen nicht verwendet werden. Eigentlich sollte es so aussehen:

            $tmp = new DOMDocument();
            $tmp->loadHTMLFile('home.html');
            

            Der Pfeil dient in PHP zum Verweis von Objekten auf ihre Eigenschaften oder Methoden. In JavaScript macht man dafür einfach einen Punkt.

            Ah, danke. Ja, jetzt entsinne ich mich wieder eines OOP-PHP-Tutorials. Methoden sind so etwas Ähnliches wie Funktionen und Eigenschaften so etwas Ähnliches wie Variablen.

            Ich durchblicke den Teil Verarbeitung und Datenausgabe im Tutorial von Felix leider nicht. Es geht beim Kapitel Verarbeitung wohl darum, HTML nicht mit PHP zu vermischen, sondern sämtliche HTML-Teile, die man benötigt, einfach über PHP reinzuholen.

            Jetzt hatte ich ja oben z.B. die Funktion MARKER als Beispiel angegeben. Ich hole mir meinen HTML-Schnipsel über include und füge einfach die benötigten Leerstellen bzw. Parameter ein. Inwiefern jetzt die Parameter optimiert werden könnten, interessiert mich vorerst gar nicht, sondern zunächst möchte ich wissen, ob das vom Prinzip her passt.

            Ich wüsste nicht, wie ich anders beim HTML-Element mit der class .marker, den variablen Teil von dem statischen trennen sollte als über eine PHP-Funktion, die dann über include eingefügt wird.

            Wenn ich doch z.B. die Funktion MARKER($parameter1, $parameter2) verwende, dann muss ich doch in der Funktion zwangsläufig PHP mit HTML vermischen, da sich die Variablen bzw. Parameter im HTML-Element an der jeweils richtigen Stelle befinden müssen.

            Soll ich etwa keine Funktionen verwenden?

            1. problematische Seite

              Hallo borisbaer,

              man kann über dieses Tutorial geteilter Meinung sein. Meine Projekte mit PHP (alle hobbymäßig) sind nie so vorgegangen. Ich hatte dieses Tutorial bisher nicht gesehen. Einiges darin mag auch eine Stilfrage sein.

              Sicherlich ist es nett, wenn man ein formal vollständiges, aber für die Seite unfertiges HTML Dokument für die Unterseiten hat und dessen Inhalte in ein Template für die eigentliche Seite hineinmontiert. Einfach nur title und body herüberzuziehen ist für reale Webseiten aber deutlich zu kurz gesprungen.

              Und der Teil des Tutorials, der so richtig ins Eingemachte gehen will, wurde dann ja auch nicht mehr geschrieben (Interpretation von eigenen Templates). Was ich gut finde, denn letztlich IST PHP eine fertige Template-Sprache und ich kann mit include und <?= ... ?> Bausteine und Werte einfügen.

              PHP ist aber in dem Moment am Ende, wo Du parametrierbare Bausteine hast. Dein MARKER ist ein solcher. Was Du mit include hereinholst, kannst Du zur Not über globale Variablen mit Daten versorgen, das würde ich aber nie empfehlen. Da ist die MARKER-Funktion schon besser.

              Ich habe mich mal eine Zeitlang mit Smarty beschäftigt. Das ist eine eigenständige Template-Sprache, die vom Smarty-Compiler in PHP übersetzt wird (und zwar im Hintergrund, du merkst nichts davon). Dort kannst Du eigene Bausteine erzeugen und mit PHP realisieren, und diese Bausteine können auch Parameter haben. Aber auch da wird es grenzwertig, wenn Du eine Seite mehr oder weniger im Freistil zusammenbaust. Deine Kartenansicht ist etwas, was sich für ein allgemeingültiges Template aus meiner Sicht nicht eignet.

              Es ist gut, wenn man wiederverwendbare Bausteine hat, die Fragmente der Seite erzeugen können. Solange sie konstant sind, kann man sie mit include einbinden. Wenn sie mit Daten versorgt werden müssen, halte ich es für schlechten Stil, wenn die Bausteine sich diese Daten selbst beschaffen. Statt dessen müssen sie sie übergeben bekommen. Natürlich kann man einen Katalog von "well known variables" wie $site_name erstellen und diese in den Templates zur Benutzung freigeben, so wie Felix das im include-Kapitel macht. Aber das dürfen nur ein paar sein, die wirklich auf jeder Seite gebraucht werden.

              Was mich ernsthaft stört, ist, dass die Templates den global namespace vermüllen. Das passiert in nav und in footer - aus meiner Sicht nicht empfehlenswert. Ich habe allerdings auch keine für Einsteiger brauchbare Lösung.

              Der Gedanke, mit include die Templates lediglich in Form einer Funktion zu laden und diese Funktion dann an der passenden Stelle aufzurufen, gefällt mir deutlich besser. Aber das ist meine eigene Sicht der Dinge, ob sich das für's Wiki eignet, weiß ich nicht. Ich weiß aber eins: Die Wiki-Artikelserie zeigt nur sehr einfache Aufgabenstellungen, mit denen man bei komplexeren Seiten schnell am Ende ist. Lass Dich davon darum inspirieren, aber sei frei, es nach deinem Geschmack auszubauen. Die MARKER Funktion ist okay, finde ich.

              Rolf

              --
              sumpsi - posui - obstruxi
            2. problematische Seite

              Lieber borisbaer,

              Soll ich etwa keine Funktionen verwenden?

              ganz anders: Versuche die Antwort auf „Was ist ein Marker?“ durch eine Liste an Eigenschaften zu beschreiben. Vielleicht so?

              {
                id: "1-2-1-half-moon-grass",
                text: "Halfmoongrass × 3",
                type: "item",
                x: 606,
                y: 324
              };
              

              Dann stellt sich die Frage, was ein solcher Marker alles können soll:

              • Automatische Position der Beschriftung
              • vertikale und horizontale Linien vom Ursprungspunkt zur Beschriftung ziehen

              Das alles kann man in Funktionen stecken, die dann als Methoden eines Marker-Objektes in einer Klasse definiert werden. Dabei kann man sich dann auch überlegen, ob man das tatsächlich mit CSS-Angaben in inline-Styles realisiert, oder gleich ein SVG ins Dokument schreibt. Die Marker-Klasse, die man für einen Marker benötigt, kann die nötigen Werte generieren, damit eine Map-Klasse ihr SVG damit bauen kann.

              Die Verwendung könnte so aussehen:

              $map = new \MarkedMap();
              
              $map->loadWebpImage(
                // path to webp image file
                './games/demons-souls/images/maps/map/boletarian-palace/the-lords-path/1.webp'
              );
              
              $map->addMarker(
                new \MapMarker([
                  'id' => '1-2-1-half-moon-grass',
                  'text' => 'Halfmoongrass × 3',
                  'type' => 'item',
                  'x' => 606,
                  'y' => 324
                ])
              );
              

              Die im Beispiel angenommene \MarkedMap-Klasse könnte so aussehen:

              class MarkedMap {
                private img; // GD lib image object
                private markers = [];
              
                public function __construct () {
                  // noch nix zu tun
                }
              
                public function loadWebpImage ($path) {
                  $this->img = imagecreatefromwebp($path);
                }
              
                public function render () {
                  // ... magic ... -> SVG ...?
                  // ... magic ... -> <div>-Suppe mit leckeren inline-styles?
              
                  foreach ($this->markers as $marker) {
              
                    $rendering = $marker->render();
              
                    // tu was mit $rendering['label']['x']
                    // tu was mit $rendering['label']['y']
                    // tu was mit $rendering['label']['text']
              
                    if (!empty($rendering['lines'])) {
              
                      foreach ($rendering['lines'] as $line) {
              
                        // tu was mit $line['start']['x']
                        // tu was mit $line['start']['y']
                        // tu was mit $line['end']['x']
                        // tu was mit $line['end']['y']
                      }
                    }
                  }
                }
              
                public function setMarker ($marker) {
                  $this->markers[] = $marker;
                }
              }
              
              class MapMarker {
                private $id = uniqid();
                private $text = 'default text';
                private $type = 'item';
                private $x = 0;
                private $y = 0;
              
                public function __construct ($params) {
                  foreach ($params as $key => $value) {
                    if (property_exists($this, $key)) {
                      $this->{$key} = $value;
                    }
                  }
                }
              
                public function render ($img_height, $img_width) {
                  // Horizontale Position und Breite des Textes festlegen
              
                  // Ergebnis könnte das hier sein
                  $left = 52;
                  $top = 12;
                  $width = strlen($this->title);
              
                  return [
                    'label' => [
                      'x' => $left,
                      'y' => $top,
                      'text' => $this->title
                    ],
                    'lines' => [
                      // senkrechte Linie
                      [
                        'end' => ['x' => $this->x, 'y' => $top],
                        'start' => ['x' => $this->x, 'y' => $this->y]
                      ],
                      // waagrechte Linie
                      [
                        'end' => ['x' => $left + $width, 'y' => $top],
                        'start' => ['x' => $this->x, 'y' => $top]
                      ],
                    ]
                  ];
                }
              }
              

              Natürlich habe ich keine Ahnung oder Code-auf-die-Schnelle, was die render-Methode der \MarkedMap-Klasse hier genau macht. Das hängt zum Einen davon ab, ob Du nun SVG erzeugen möchtest, oder mit HTML/CSS-Mitteln hantieren willst. Die Marker bekommen eine eigene Klasse, damit sie ihre Positionierungen cleverer festlegen können, als das eine einzelne Methode in der ganzen \MarkedMap-Klasse könnte (sie wäre dann unhandlich groß und schwer wartbar).

              Die SVG-Lösung hat den Charme, dass Du dafür XML generierst, welches sich mit der DOMDocument-Klasse und ihren DOM-Methoden in PHP erzeugen lässt. Also kein XML-Code im PHP-Quelltext. Und anklickbare Links sind damit auch noch möglich (dazu muss natürlich die \MapMarker-Klasse passend erweitert werden)!

              Du merkst, ich tendiere zu einer Lösung, die SVG verwendet. Leider habe ich selbst damit kaum Erfahrung, kann also nur theoretisch SVG empfehlen. Eine konkrete Umsetzung würde aber Dein Wissen und Deine Erfahrung wesentlich weiter bringen!

              Liebe Grüße

              Felix Riesterer

              1. problematische Seite

                Hallo Felix,

                die Marker mit SVG zu erzeugen hatte ich ihm auch schon empfohlen. Ich befürchte nur, dass eine OOP Lösung ihn dann doch heillos überfordert. Aber vielleicht täusche ich mich ja auch 😉

                Rolf

                --
                sumpsi - posui - obstruxi
                1. problematische Seite

                  Hallo Rolf,

                  die Marker mit SVG zu erzeugen hatte ich ihm auch schon empfohlen. Ich befürchte nur, dass eine OOP Lösung ihn dann doch heillos überfordert. Aber vielleicht täusche ich mich ja auch 😉

                  SVG muss ich erst noch lernen! Klingt aber vielversprechend. Mit der OOP-Lösung hast du recht. Das überfordert mich im Moment noch. Aber ich werde mir das Ganze auf jeden Fall noch genauer anschauen. Es gibt bei YouTube ja Kurse dazu, in denen das ganz gut erklärt wird.

                  Im Prinzip funktioniert die OOP-Lösung mit ihren classes aber ähnlich wie die Lösung mit den PHP-Funktionen, nicht? Bei beiden habe ein parametrisiert Objekt, auch wenn die Funktion im eigentlichen Sinne kein Objekt ist. Ich bin mir sicher, dass die OOP-Lösung die modernere und elegantere Lösung darstellt (ohne wirklich viel Ahnung von OOP zu haben). Aber solange ich OOP nicht beherrsche, wäre doch wohl das Nächstbeste die Lösung mit den PHP-Funktionen, oder?

                  P.S.: Wie kann man bei den Beiträgen hier eigentlich einen einfachen Zeilensprung realisieren?

                  1. problematische Seite

                    Hallo borisbaer,

                    der Unterschied zwischen einer Methode (Funktion einer Klasse) und Funktion ist, dass die Methode das Objekt als Kontext hat und damit Daten bereitgestellt bekommen kann.

                    Wenn ich deine Karten objektorientiert darstellen wollte, würde ich dies tun:

                    • Eine Klasse "Karte" erstellen. Diese Klasse besitzt eine Eigenschaft "Hintergrund" für das Hintergrundbild und eine Eigenschaft "Elemente", worin ein Array mit den Kartenelementen steht. Und dann hat die Klasse eine Methode "Zeichne", woraufhin sie das HTML für sich selbst ausgibt und für alle Elemente die Zeichne
                    • Eine abstrakte Klasse "Kartenelement" erstellen, bspw. mit einer Methode "Zeiche()". In der abstrakten Klasse tut diese Methode nichts.
                    • Eine Klasse "Marker", abgeleitet von "Kartenelement", erstellen. Der Marker weiß, wo der Referenzpunkt des Markers ist und wie der Text und der Verbindungsstrich in Bezug auf den Referenzpunkt anzuordnen sind. Und er überschreibt die "Zeichne" Methode vom Kartenelement.

                    Gebrauch: Kartenobjekt erzeugen, mehrere Kartenelemente (z.B. Marker) erzeugen und der Karte zuordnen. Dann $karte->Zeichne() aufrufen. Und der Rest geschieht automatisch 😉

                    In einer high-level Form ist das schnell beschrieben. Konkret muss man sich das schon ordentlich erarbeiten. Da kommt dann vieles zusammen: PHP, HTML, CSS, SVG, OOP und jede Menge WTF…

                    Rolf

                    --
                    sumpsi - posui - obstruxi
                  2. problematische Seite

                    Hallo,

                    P.S.: Wie kann man bei den Beiträgen hier eigentlich einen einfachen Zeilensprung realisieren?

                    Einfache
                    Zeilenschaltungen
                    sind
                    hier
                    im
                    leider
                    nicht
                    machbar...

                    AußermanspartsicheinpaarLeerzeicheneinundverwendetsiedoppelt

                    Gruß
                    Kalk

                    1. problematische Seite

                      Hallo Tabellenkalk,

                      Du
                      bist
                      gemein

                      Hier steht's - zu finden über den Link gleich über dem "Nachricht speichern" Button.

                      Rolf

                      --
                      sumpsi - posui - obstruxi
          2. problematische Seite

            Lieber Rolf,

            $tmp = new DOMDocument();
            $tmp->loadHTMLFile('home.html');
            

            genau so: Erst eine Instanz der DOMDocument-Klasse erzeugen, dann damit Methoden aufrufen.

            Generell wird wohl aktuell https://github.com/Masterminds/html5-php als Ersatz empfohlen, keine Ahnung ob das die einzige Lib ist. Um die einzubinden brauchst Du aber den composer.

            Intern verwendet der HTML5-Parser von Mastermind tatsächlich die DOMDocument-Klasse. Er ist dazu gedacht, HTML5-Code zu einer DOMDocument-Instanz zu parsen, oder aus ihr wieder HTML5-Quellcode zu serialisieren. Das hat den Vorteil, dass man mit den vielen üblichen DOM-Methoden in PHP arbeiten kann.

            $html5 = new \Masterminds\HTML5(
              // keine HTML-Namespaces unterstützen
              ['disable_html_ns' => true]
            );
            
            // \DOMDocument-Instanz mit dem HTML5-Parser erzeugen
            $domdoc = $html5->loadHTML($html_code_string);
            
            // möglich: HTML4-Quelltext mit der \DOMDocument-Klasse ausgeben
            echo $domdoc->saveHTML(); 
            
            // besser: HTML5-Quelltext mit dem HTML5-Serializer ausgeben
            echo $html5->saveHTML($domdoc);
            

            Liebe Grüße

            Felix Riesterer

    2. problematische Seite

      Allerdings kann PHP so ziemlich jede Art von Daten an den Browser senden,

      PHP kann jede Art von Daten entweder selbst an beliebige Clients senden, ausgeben, in Dateien oder anderen Ressourcen speichern, an andere Server übergeben oder dem, das Skript aufrufendem Webserver zum Zweck des Antwortens auf den Request eines (beliebigen: muss kein Browser sein) Clients übergeben.

      Aber im Großen und Ganzen stimmt Deine Aussage schon…

      Grüße aus Ganzgenauheim.

    3. problematische Seite

      Man kann Daten JSON-gerecht maskieren/codieren. Dazu gehören insbesondere die Zeichen " und /, welche mit einem Backslash maskiert werden müssen, da sie ansonsten als Sonderzeichen mit bestimmter Bedeutung interpretiert werden.

      Man muss das aber nur dann tun, wenn man den JSON-Text selbst erstellen will.

      Die JSON-Encoder der Programmiersprachen machen das gerne automatisch.

      PHP:

      <?php
      header( 'Content-Type: text/json; charset=utf-8' );
      $var = '<span style="letter-spacing: .1em">B</span>aum';
      echo json_encode( $var ) . PHP_EOL;
      

      Ausgabe:

      "<span style=\"letter-spacing: .1em\">B<\/span>aum"
      

      JS:

      var str = '<span style="letter-spacing: .1em">B</span>aum';
      console.log( JSON.stringify( str ) );
      

      Ausgabe:

      "<span style=\"letter-spacing: .1em\">B<\/span>aum"
      

      Beide Sprachen können das HTML nach einem JSON-Decode auch in den Output - oder (mit geeigneten Methoden) ins DOM (Dokument) einbauen. Darüber hinaus ist auch der Inhalt egal: Das können beliebige Strings (so lange diese UTF-8-codiert wurden), Zahlen, Arrays, Objekte, sogar binäres Zeug sein, es müssen halt nur „Werte“ sein, welche die jeweilige Anwendung in eine Variable aufnehmen kann.

    4. problematische Seite

      Man kann Daten JSON-gerecht maskieren/codieren. Dazu gehören insbesondere die Zeichen " und /, welche mit einem Backslash maskiert werden müssen, da sie ansonsten als Sonderzeichen mit bestimmter Bedeutung interpretiert werden.

      Danke für die Aufklärung!

      Wenn Du Inhalt, Layout und Funktionalität gut voneinander trennen willst, dann überlegst Du Dir, was HTML-Code in PHP zu suchen hat, was PHP in JavaScript-Code zu suchen hat, und was CSS-Code in HTML zu suchen hat. Wenn Du dann auf die Antwort „gar nichts“ kommst, bist Du auf dem richtigen Weg.

      Das ist jetzt erst mal sehr kryptisch für mich. Wenn ich z.B. die Funktion MARKER einfügen will, die eben ein HTML-Element wiedergibt, aber jedes Mal einige Parameter verändert werden sollen, wie komme ich dann ohne z.B. CSS in HTML aus, um die Position des HTML-Elements zu ändern?

      In PHP-Code sollte ausschließlich PHP-Code stehen. HTML kann aus einer anderen Quelle kommen, z.B. aus Template-Dateien (HTML-Dateien) oder Datenbank-Spalten (HTML-Code als String-Daten). Allerdings kann PHP so ziemlich jede Art von Daten an den Browser senden, auch dynamisch zusammengesetztes JavaScript oder CSS. Das PHP-Script muss dem Browser nur sagen, um welchen Dateityp es sich handelt.

      Ich glaube, ohne ein einfaches, vollständiges step-by-step-Beispiel kann ich mir leider nicht wirklich vorstellen, wie das konkret auszusehen oder zu funktionieren hat.

    5. problematische Seite

      Hallo Felix,

      Wenn Du Inhalt, Layout und Funktionalität gut voneinander trennen willst, dann überlegst Du Dir, was HTML-Code in PHP zu suchen hat, was PHP in JavaScript-Code zu suchen hat, und was CSS-Code in HTML zu suchen hat. Wenn Du dann auf die Antwort „gar nichts“ kommst, bist Du auf dem richtigen Weg.

      ich habe endlich begriffen, was du damit gemeint hast. Seitdem ich mehr über MVC-Frameworks weiß und wie man damit arbeitet, konnte ich mittlerweile nahezu vollständig Darstellung und Inhalt auf meiner Website trennen. Alles an Textdaten wird in JSON-Dateien gelagert und die Darstellung wird ganz über Templates gesteuert. Keine haufenweise include-Befehle mehr.

      Ich bin zwar noch am Anfang, aber immerhin glaube ich, nun den richtigen Ansatz gefunden zu haben. Es gibt nur noch eine index.php, die sämtliche URL-Parameter verarbeitet.

      Wichtig wäre es wohl gewesen, auf PHP OOP zu verweisen, denn das kannte ich zu dem Zeitpunkt so gut wie gar nicht. Auf Template-Engines verzichte ich momentan, da ich ja keinen fremden Designer habe, der kein PHP kann. Insofern ist doch ein bisschen PHP in meinen HTML-Templates. Ich finde es nicht wirklich übersichtlicher, z.B. Twig-Synatx zu benutzen, nur um kein PHP im HTML zu haben (oder HTML im PHP, wie du meintest).

      Wollte nur kurz Rückmeldung geben. 😜

      Viele Grüße
      Boris

      1. problematische Seite

        Lieber borisbaer,

        ich habe endlich begriffen, was du damit gemeint hast.

        :-) das ist eine Errungenschaft! Ganz ohne Ironie: Es dauert, bis man sich als Laie zu solchen Denkmustern durchgearbeitet hat. Es ist ja auch nichts Intuitives daran, denn Software ist immer etwas Komplexes.

        Seitdem ich mehr über MVC-Frameworks weiß und wie man damit arbeitet,

        Das ist noch einmal ein dickes Brett zu bohren. Viele Web-Applikationen von Laien haben das nicht, weil es noch einmal eine Schicht Abstraktion mehr ist. Wenn Du damit zurecht kommst, dann nur weiter so!

        Alles an Textdaten wird in JSON-Dateien gelagert

        Ist das anstelle einer Datenhaltung mittels einer (SQL-)Datenbank? Prinzipiell keine schlechte Idee, weil es einen Angriffsvektor weniger hat (SQL-Injektionen). Vor allem wenn die Datenmenge überschaubar klein bleibt, und wenn die Komplexität der Daten gering ist (wenn keine Bezüge zwischen Daten bedacht werden müssen wie z.B. „alle Datensätze mit den Merkmalen X=a und Y im Bereich von b und c“), braucht es auch keine Datenbank. Selbst wenn Inhalte in mehreren Sprachvarianten angeboten werden sollen, sind JSON-Dateien eine gute Idee.

        und die Darstellung wird ganz über Templates gesteuert. Keine haufenweise include-Befehle mehr.

        Templates in PHP sind kein triviales Thema. Es gibt eine Reihe von guten Ansätzen, wie man das umsetzt. Je nach Anforderungen kann es nötig sein, eine Template-Sprache einzusetzen (PHP war ursprünglich genau das) wie z.B. Smarty. Mein Link auf unsere Einführung zu Templates sollte zeigen, dass das auch weitaus simpler gestrickt sein kann. Die Idee bleibt weiterhin, dass man gewisse Bereiche voneinander trennt. Und das setzt Du ja bereits um.

        Auf Template-Engines verzichte ich momentan, da ich ja keinen fremden Designer habe, der kein PHP kann. Insofern ist doch ein bisschen PHP in meinen HTML-Templates. Ich finde es nicht wirklich übersichtlicher, z.B. Twig-Synatx zu benutzen, nur um kein PHP im HTML zu haben (oder HTML im PHP, wie du meintest).

        Twig? Habe ich noch nie von gehört. Meinst Du Twig für Symfony? Wie gesagt, es kommt immer darauf an, was man benötigt, und wie man es umsetzen möchte.

        Wichtig wäre es wohl gewesen, auf PHP OOP zu verweisen, denn das kannte ich zu dem Zeitpunkt so gut wie gar nicht.

        Diese Art zu programmieren ist ebenfalls nicht intuitiv. Mein Lernweg begann mit nicht-objektorientierten Schreibweisen. Mag an meiner Altersgruppe liegen (bin mit dem C64 aufgewachsen), aber meine ersten Programme habe ich in BASIC und dann in Assembler geschrieben. Das hat nichts mit Objekten zu tun gehabt. Daher musste ich wirklich viel dazulernen, bis ich das Konzept wirklich verwenden konnte. Und selbst heute tendiere ich in PHP immer wieder zu prozeduraler Schreibweise, obwohl ich es mir damit nur unnötig schwer mache. In JavaScript fällt es mir dagegen deutlich leichter OOP einzusetzen.

        Wollte nur kurz Rückmeldung geben. 😜

        Das hat mich sehr gefreut! Und ich wünsche Dir weiterhin viel Spaß am Lernen und natürlich viel Erfolg für Deine Web-Projekte.

        Liebe Grüße

        Felix Riesterer

  2. problematische Seite

    Hallo borisbaer,

    Darstellung und Inhalt kann man auf vielen Ebenen trennen.

    Die MARKER Funktion ist reine Darstellung, sie bekommt ihren Textinhalt und ihre Position übergeben. Aber sie tut eigentlich noch zu wenig (und ob sie das richtige tut, bleibe dahingestellt.

    Für eine saubere Trennung müsste man charakterisieren, welche Darstellungen es für einen Marker gibt, und sich dann überlegen, wie man eine solche Marker-Funktion parametrieren sollte, um die Darstellung möglichst vollständig in der MARKER Funktion zu behalten. Wilde Style-Angaben in den Parametern sollte man vermeiden, sowas muss die MARKER-Funkton generieren.

    Nur als Beispiel - ich weiß nicht ob das für Dich so passend ist: Ein Marker hat

    • Einen Text
    • Ein Symbol für die Position des Objekts (Quadrat, Kreis
    • Eine zweiteilige Verbindungslinie
      • Teil 1: Horizontal links oder rechts vom Text. Wenn links vom Text, wird am linken Ende weitergeführt. Wenn rechts vom Text, wird am rechten Ende weitergeführt
      • Teil 2: Weiterführung vertikal oder diagonal aufwärts oder abwärts, bis zum Symbol

    Ich würde von einer MARKER Funktion erwarten, dass ich ihr nur dies Mitteile:

    • Art des Markers
    • Markersymbol (vielleicht)
    • Legendentext ("Selfforum-Beitrag Stufe 3")
    • Startpunkt der Linie (x,y)
    • Linienvektor Teil 1 (dx1, dy1)
    • Linienvektor Teil 2 (dx2, dy2)
    • Dann vielleicht noch Angaben zu Farben. Die sind vermutlich optional; eventuell kann man das ähnlich wie jQuery mit einem Optionen-Array machen.

    Ob der Text links oder rechts des Linienstartpunktes steht, ermittelt sich automatisch: Ist dx1 positiv, läuft die Linie nach rechts, der Text muss also links vom Startpunkt stehen. Wenn die Linie initial nach unten läuft, kann man den Text zentriert darüber setzen. Keine Ahnung, welche Linientypen Du hast, aber EIGENTLICH kann eine Linie dieser Art 64 Ausprägungen haben (jeder Teil in 8 mögliche Grundrichtungen) - d.h. da musst Du schlau programmieren, um daran nicht wahnsinnig zu werden. Wenn Du immer horizontal startest, sind es nur 8 Typen.

    Das ist nicht einfach, es ist abstrakt und eventuell programmierst Du da Dinge "auf Halde". Aber damit hättest Du dann einen Marker-Generator, den Du rein fachlich ansteuerst und der die Technik komplett kapselt.

    Mit SVG statt HTML wäre das Darstellen der Linien vermutlich leichter. Aber damit hättest Du dann eine weitere Komplikation drin…

    Rolf

    --
    sumpsi - posui - obstruxi
  3. problematische Seite

    Hallo borisbaer,

    für meinen Veranstaltungskalender gilt: Die URLs und die Durchlaufzeiten (Server) müssen kurz sein. Die Seite soll beim Benutzer in Sekundenfrist angezeigt werden.

    Bei umfangreichen Listen dauert die Anzeige aber 6 .. 10 sec. Unangenehm für den User.

    Das folgende gilt für diese Listen und für geschlossene Benutzergruppen, nicht für kleine öffentliche Webseiten:

    Anfangs habe ich Platzhalter-Dateien mit PHP aufgeblasen zu HTML-Dokumenten. Deutlich schneller geht es, wenn ich die Daten als CSV-String in die Platzhalter-Datei schreibe und Javascript erzeugt die HTML-Version.

    Der PHP-Durchlauf ist deutlich schneller, die zu übertragene Datenmenge deutlich kleiner. Alle Daten sind also längst beim Browser, während die konventionelle Methode noch das HTML-Dokument erzeugt.

    Ich konnte (gefühlt) nicht feststellen, dass die Aufbereitung des HTML-Dokuments mit Javascript langsamer sei als die Aufbereitung mit PHP. Und ich kenne keine Methode, wie man Darstellung und Inhalt krasser trennen könnte.

    Bei Bedarf gebe ich gerne weitere Auskunft.

    1. problematische Seite

      Hallo Linuchs,

      Bei umfangreichen Listen dauert die Anzeige aber 6 .. 10 sec.

      In diesem Fall muss man aber auch die Frage stellen, ob die Liste nicht zu groß ist und besser paginiert werden sollte. Wenn Du 6s brauchst, um eine Liste zu schicken, hat sie 1000 Zeilen oder mehr und DAS ist zu viel.

      Frage ist dann auch, wo die Zeit bleibt. 6s für HTML Generierung ist eine MENGE Zeit, entweder ist dein Server lahm, deine Template-Technik inperformant oder die verwendete Logik merkwürdig.

      Ein clientseitiges HTML-Rendering kann natürlich auch ok sein, sollte aber im Normalfall zweite Wahl sein, weil die Seite ohne JS dann gar nichts mehr tut.

      Rolf

      --
      sumpsi - posui - obstruxi
      1. problematische Seite

        Hallo Rolf,

        ob die Liste nicht zu groß ist

        Kunde fand meinen Vorschlag gut, sämtliche Adressen (hohe dreistellige Zahl) in einer nach Spalten sortierbaren Tabelle, die einige Stunden Bestand hat. Pro Adresse einige Links zu Bearbeitungs-Programmen, die im neuen Tab geöffnet werden.

        Die bearbeiteten Positionen der Liste kann man anklicken, werden grün hinterlegt. So kann man weitermachen, wenn man zurück auf der Liste ist.

        Die Alternative wäre die „Bedienung“ eines Filters und ständig neue Teilmengen vom Server abrufen. Umständlich, keine Kontrolle, was bereits bearbeitet ist.

        Rendering (mit JS) ... sollte aber im Normalfall zweite Wahl sein, weil die Seite ohne JS dann gar nichts mehr tut.

        Richtig. Und gut so, denn zahlreiche Hilfen werden bei Klick per Ajax vom Server geholt und eingeblendet.

        Zusatznutzen bringt der enthaltene CSV String, der kann dem Code entnommen und für eine Tabellenkalkulation / Laden einer DB-Tabelle genutzt werden. Oder mit einer anderen Platzhalter-Datei pur ausgegeben werden ohne Programmänderung.

    2. problematische Seite

      Lieber Linuchs,

      Bei umfangreichen Listen dauert die Anzeige aber 6 .. 10 sec. Unangenehm für den User.

      da stellt sich die Frage, wo genau die Zeit verbraucht wird. Wenn das Generieren des kompletten HTML-Dokuments auf dem Server passiert, dann darf man fragen, warum das so lange dauert. Üblicherweise ist man am Server an der ohnehin schnellsten Stelle.

      Die Zeit für das Rendering im Browser bei fertigem HTML ist eine Konstante. Da kommt man nicht daran vorbei. Das dauert eben.

      Die Zeit für das Generieren des HTML mit JavaScript (also eigentlich DOM, nicht HTML) kann noch länger dauern, als das serverseitige Generieren des Dokuments, je nach Leistung des Client-Gerätes. Ärgerlich wird es, wenn JavaScript den Prozessor mehr belastet, als die Rendering Engine, wenn sie ein HTML-Dokument parst und rendert, denn das verbraucht auf mobilen Geräten mehr Akku als nötig. Je öfter diese Leistung beim Besuch Deiner Seite abverlangt wird, desto stärker fällt dieser Effekt ins Gewicht.

      Die Übertragungsdauer sollte vernachlässigbar sein, da ein Download von wenigen Kilobyte und wenigen Megabyte heute fast gleich lange dauern sollte. Bis die Verbindung aufgebaut ist und die Daten fließen können, geht ohnehin schon ein Großteil der Wartezeit drauf. Die Datenmenge sollte dann kaum noch ins Gewicht fallen.

      Liebe Grüße

      Felix Riesterer

      1. problematische Seite

        Hallo Felix,

        Die Zeit für das Rendering im Browser bei fertigem HTML ist eine Konstante. Da kommt man nicht daran vorbei. Das dauert eben.

        Weswegen eine Paginierung immer Sinn ergibt. Mein Prozessor ist soo langsam nicht mehr, und er braucht für eine Table mit 1500 Rows und 15 Columns fast eine Sekunde zum vollständigen Rendern (die Zellen enthalten nur Text).

        Das Aufbauen des HTML geht zwar fix, aber die Layoutphase kostet dann. Das kann man visualisieren (ohne Dev-Tools):

        <script>
        const start = Date.now();
        </script>
        <table>
           <!-- MANY MANY ROWS -->
        </table>
        <script>
        const fertig = Date.now();
        
        window.addEventListener("load", function() {
           const fertig_fertig = Date.now();
        });
        </script>
        

        Das load-Event feuert, wenn das Rendering der geladenen Seite durch ist.

        Der Unterschied zwischen "start" und "fertig" sind 50ms und weniger. Aber von "fertig" bis "fertig_fertig" ist's dann fast eine Sekunde. Auf einem Mobilchen sieht es nochmal ganz anders aus.

        Und ein "schlechtes" Generieren mit JavaScript kann auch vorkommen - wenn man z.B. ein tr Element erst in die Table hängt und dann siebenunddrölfzig Spalten hinzufügt, statt zuerst die Spalten einzufügen und das tr Element dann als Ganzes einzufügen.

        Ein Tabellentool, mit dem ich mal zu tun hatte, hat sogar zuerst den kompletten Tabelleninhalt als HTML String aufgebaut und den dann dem innerHTML Property des table-Elements zugewiesen. Da gibt's erstaunliche Performance-Unterschiede.

        Rolf

        --
        sumpsi - posui - obstruxi
        1. problematische Seite

          @@Rolf B

          Das Aufbauen des HTML geht zwar fix, aber die Layoutphase kostet dann.

          Die Layoutphase geht auch fixer, wenn man fixed table layout einsetzt, insb. bei umfangreichen Tabellen.

          Bei automatic table layout hingegen schaut sich der der Browser die Inhalte sämtlicher Zellen an, um die Breiten der einzelnen Spalten zu berechnen. Das dauert …

          🖖 Живіть довго і процвітайте

          --
          When the power of love overcomes the love of power the world will know peace.
          — Jimi Hendrix
          1. problematische Seite

            Hallo Gunnar,

            ja, dachte ich auch. Aber meine Testseite ist bei fixed und automatic Table Layout gleich „schnell“.

            Aber vielleicht kannst Du mir ja sagen, was ich da falsch gemacht habe. Außer der Lesbarkeit, das Ding ist ein Experiment und wild zusammengekloppt.

            Rolf

            --
            sumpsi - posui - obstruxi
            1. problematische Seite

              @@Rolf B

              ja, dachte ich auch. Aber meine Testseite ist bei fixed und automatic Table Layout gleich „schnell“.

              Stimmt. 🤣

              Aber vielleicht kannst Du mir ja sagen, was ich da falsch gemacht habe.

              Den falschen URL angegeben? 🤔

              🖖 Живіть довго і процвітайте

              --
              When the power of love overcomes the love of power the world will know peace.
              — Jimi Hendrix
              1. problematische Seite

                Hallo Gunnar,

                autsch. https://test.borchmann.one/bigtable.php

                Wieso steckte denn noch die lokale Adresse im Puffer??

                Rolf

                --
                sumpsi - posui - obstruxi
      2. problematische Seite

        @@Felix Riesterer

        Die Übertragungsdauer sollte vernachlässigbar sein, da ein Download von wenigen Kilobyte und wenigen Megabyte heute fast gleich lange dauern sollte. Bis die Verbindung aufgebaut ist und die Daten fließen können, geht ohnehin schon ein Großteil der Wartezeit drauf. Die Datenmenge sollte dann kaum noch ins Gewicht fallen.

        Öhm, nein.

        Für den Rest hast du dir trotzdem ein Plus verdient.

        🖖 Живіть довго і процвітайте

        --
        When the power of love overcomes the love of power the world will know peace.
        — Jimi Hendrix
      3. problematische Seite

        Lieber Felix,

        Generieren des HTML mit JavaScript kann noch länger dauern, als das serverseitige Generieren des Dokuments, je nach Leistung des Client-Gerätes.

        Vor Jahren hatten wir schon diese Diskussion.

        Sagen wir mal so: So manches Produkt (z.B. Rasenmäher, Fahrrad, Ikea) wird in Teilen geliefert und vom Fachhändler oder Kunden zusammengebaut. Vorteil sind Zeit(Kosten)ersparnis beim Produzenten und kompakte kostengünstige Verpackung für den Versand.

        Ist doch allgemein üblich, wieso sträubst du dich gegen diese Idee?

        1. problematische Seite

          @@Linuchs

          Sagen wir mal so: So manches Produkt (z.B. Rasenmäher, Fahrrad, Ikea) wird in Teilen geliefert und vom Fachhändler oder Kunden zusammengebaut. Vorteil sind Zeit(Kosten)ersparnis beim Produzenten und kompakte kostengünstige Verpackung für den Versand.

          Bleiben wir mal bei dem Vergleich, aber richtig:

          Zeit:
          Du bestellst einen Schrank. Der wird fertig zusammengebaut (serverseitig generiertes HTML) am Mittwoch um 13:00 geliefert und steht um 13:02 da, wo er hinsoll.
          vs.
          Du bestellst einen Schrank. Der wird in Einzelteilen (JSON) am Mittwoch um 13:00 geliefert und du (der Browser) bist die nächsten 3 Stunden damit beschäftigt, das IKEA-Puzzle zu lösen.
          Kosten:
          Du bestellst den fertig zusammengebauten (PHP) Schrank für 600 Euro.
          vs.
          Du bestellst den Schrank in Einzelteilen für 400 Euro mit Aufbauservice (JavaScript) – da kommen nochmal 200 Euro drauf. Die (Entwicklungs-)Kosten sind dieselben.

          🖖 Живіть довго і процвітайте

          --
          When the power of love overcomes the love of power the world will know peace.
          — Jimi Hendrix
          1. problematische Seite

            Hallo Gunnar,

            ich bin kein Guru, niemand muss meinen Ideen folgen. Ich kann lediglich die eine oder andere anbieten.

            da kommen nochmal 200 Euro drauf. Die (Entwicklungs-)Kosten sind dieselben.

            Ja, für mich als Endverbraucher bleiben die Kosten bei Fremdmontage gleich, wenn ich es selbst mache, habe ich 200€ gespart.

            Warum sollte ich als Produzent einen Schrank teuer von Hand zusammenbauen und für den Versand der Hohlräume zahlen, wenn der Empfänger die Luft selbst hinzufügen kann?

            Bist du Produzent von Mogelpackungen?

            1. problematische Seite

              Hallo Linuchs,

              Warum sollte ich als Produzent einen Schrank teuer von Hand zusammenbauen (...), wenn der Empfänger die Luft selbst hinzufügen kann?

              Wie diskutiert: Es gibt Empfänger, die sind darin etwas ungeschickt. Aber Du hast deine Usecases benannt und für Dich ist es sinnvoll. Solange Dir kein Anwender sagt, dass deine Seite ihm den Akku leerlutscht oder schlicht nicht korrekt rendert, passt das aus meiner Sicht. An Deiner Stelle hätte ich versucht, die Knackpunkte im mühsamen manuellen Fertigungsprozess zu finden. Dem nachzuschalten wäre dann noch ein automatischer Zusammenfalter, dessen Gegenstück am Werk im Browser zu finden ist (sprich: gzip Kompression für dynamische Inhalte - im IIS schaltet man die getrennt von statischen Inhalten frei, ich weiß nicht wie der Indianer das macht)

              Rolf

              --
              sumpsi - posui - obstruxi
              1. problematische Seite

                Hallo Rolf,

                (sprich: gzip Kompression für dynamische Inhalte - im IIS schaltet man die getrennt von statischen Inhalten frei, ich weiß nicht wie der Indianer das macht)

                soweit ich weiß, tut der Indianer das selbständig, wenn der Client im entsprechenden Accept-Header des Requests sagt: "Kann ich."

                Einen schönen Tag noch
                 Martin

                --
                Deutschland: Das Land der Dichter und Denker, Richter und Henker.
            2. problematische Seite

              @@Linuchs

              ich bin kein Guru, niemand muss meinen Ideen folgen. Ich kann lediglich die eine oder andere anbieten.

              Und ich kann dir lediglich versichern, dass ich deinen Ideen auch nicht folgen würde, wenn du ein Guru wärst.

              Ja, für mich als Endverbraucher bleiben die Kosten bei Fremdmontage gleich, wenn ich es selbst mache, habe ich 200€ gespart.

              Und hier kommt der Vergleich ins Hinken. Anders gesagt: du verlässt ihn.

              Der Schrank (HTML) muss montiert werden. Ob das nun werkseitig (serverseitig) oder bei dir zuhause (im Browser) geschieht, der Code dafür muss geschrieben werden. Die Kosten für PHP- und JavaScript-Code nehmen sich da nichts. Bezahlen musst du so oder so.

              🖖 Живіть довго і процвітайте

              --
              When the power of love overcomes the love of power the world will know peace.
              — Jimi Hendrix
          2. problematische Seite

            Hallo Gunnar,

            Bleiben wir mal bei dem Vergleich, aber richtig:

            zwei kleine Ergänzungen:

            Zeit:
            Du bestellst einen Schrank. Der wird fertig zusammengebaut (serverseitig generiertes HTML) am Mittwoch um 13:00 geliefert und steht um 13:02 da, wo er hinsoll.

            Lieferzeit ca. 3 Wochen.

            vs.
            Du bestellst einen Schrank. Der wird in Einzelteilen (JSON) am Mittwoch um 13:00 geliefert und du (der Browser) bist die nächsten 3 Stunden damit beschäftigt, das IKEA-Puzzle zu lösen.

            kommt sofort.

            Kosten:
            Du bestellst den fertig zusammengebauten (PHP) Schrank für 600 Euro.
            vs.
            Du bestellst den Schrank in Einzelteilen für 400 Euro mit Aufbauservice (JavaScript) – da kommen nochmal 200 Euro drauf. Die (Entwicklungs-)Kosten sind dieselben.

            (Virtuelle) Server sind, je nach Belastung, nicht zwingend schneller als ein PC.

            Gruß
            Jürgen

            1. problematische Seite

              @@JürgenB

              Lieferzeit ca. 3 Wochen.

              So langsam ist PHP nun auch wieder nicht.

              Du bestellst einen Schrank. Der wird in Einzelteilen (JSON) am Mittwoch um 13:00 geliefert und du (der Browser) bist die nächsten 3 Stunden damit beschäftigt, das IKEA-Puzzle zu lösen.

              kommt sofort.

              Der Schrank steht aber nicht sofort.

              Außerdem wollen die Einzelteile (JSON) auch erstmal verpackt werden, sodass auch hier mit Lieferzeit zu rechnen ist.

              (Virtuelle) Server sind, je nach Belastung, nicht zwingend schneller als ein PC.

              Wer sagte was von PC? Wir leben in 2022. PCs sind wohl für die meisten inzwischen nicht mehr die üblichen Geräte, um im Web unterwegs zu sein.

              🖖 Живіть довго і процвітайте

              --
              When the power of love overcomes the love of power the world will know peace.
              — Jimi Hendrix
              1. problematische Seite

                Hallo Gunnar,

                (Virtuelle) Server sind, je nach Belastung, nicht zwingend schneller als ein PC.

                Wer sagte was von PC? Wir leben in 2022. PCs sind wohl für die meistens inzwischen nicht mehr die üblichen Geräte, um im Web unterwegs zu sein.

                und sind diese so viel langsamer als ein PC oder ein (überlasteter) Server? Endgeräte sind oft kaum ausgelastet. Und ob ich eine Seite als vollständiges Paket bekomme und nur rendern muss, oder ob es als JSON + Javascript + (evtl.) Template kommt und noch moniert und gerendert werden muss, sollte sich bei der CPU- und Akku-Belastung nicht zwingend unterscheiden. In vielen Gegenden ist der Traffic das bremsende Element.

                Aber auch ich würde eine Seite eher am Server unter bekannten Bedingungen zusammenbauen, als im Clienten. Ich denke, nur unter sehr speziellen Bedingungen ist letztres schneller bei Übertragung und Seitenaufbau.

                Wichtiger wäre mMn, die Seiten so zu cachen, dass Sie nicht bei jeden Aufruf, sondern nur bei jeder Datenänderung neu montiert werden müssen, es sei denn, zwischen zwei Änderungen liegen nur wenige Aufrufe.

                Gruß
                Jürgen

                1. Hallo Jürgen,

                  Wichtiger wäre mMn, die Seiten so zu cachen, dass Sie nicht bei jeden Aufruf, sondern nur bei jeder Datenänderung neu montiert werden müssen, es sei denn, zwischen zwei Änderungen liegen nur wenige Aufrufe.

                  Als Idee gespeichert.

                  Klar könnte ich nur den CSV String per Ajax holen und das auf dem Client vorhandene Rumpf-HTML per JS wieder aufblasen. Reduziert den traffic weiter.

                  Beim Programmieren der nächsten Liste greife ich die Idee wieder auf: Never touch a running system

                  Edit: Oder habe ich deine Idee falsch verstanden und du meinst Seiten, die gleichartig an mehrere User geschickt werden und auf dem Server gecacht werden sollen?

                  Damit hatte ich vor Jahren experimentiert. Der Programmieraufwand war hoch, denn bei Datenänderung mussten mehrere Caches gelöscht werden und bei zusätzlichen Programmen ging die Übersicht verloren. Da gibt jemand einen neuen Termin ein, will den auf der Startseite, auf dem Mitglieds-, Orts-, Typenkalender sehen ... Bei 200 Orten sind 600 Orts-Cashes zu verwalten, wenn jeder Ort + 20 km je drei Seiten hat. ...

                  Nach Mitternacht werden die Termine des vergangenen Tages gelöscht, alle Listen müssen bei Anforderung neu erstellt werden. Unübersichtlich.

                  Kompromiss war, im DB-Datensatz ein HTML-Snippet für die Kurzform, eines für die Langform des Termins abzulegen und die Listen aus dieses Snippets aufzubauen. Hat in der Durchlaufzeit des Servers, die unten rechts immer angezeigt wird, prozentual kaum was gebracht und beim traffic gar nichts.

                  1. Lieber Linuchs,

                    Da gibt jemand einen neuen Termin ein, will den auf der Startseite, auf dem Mitglieds-, Orts-, Typenkalender sehen ... Bei 200 Orten sind 600 Orts-Cashes zu verwalten, wenn jeder Ort + 20 km je drei Seiten hat. ...

                    habt ihr mal grundsätzlich jemanden drüber schauen lassen, der sich mit soetwas auskennt? Klingt nach ungünstiger Architektur.

                    Liebe Grüße

                    Felix Riesterer

  4. Ich habe noch nie (bewusst) gesehen, dass mehrere Templates bei gleichen Daten zur Verfügung stehen.

    Zu diesem Thema bin ich womöglich ein Extrem-Sportler. Da meine Kalender als iframe leicht in fremde Webseiten zu integrieren sind, habe ich einige Alternativen der Darstellung, die der Webseite des Mitglieds angepasst sind.

    Zum Beispiel Straßen-, Hafen-, Weinfest, Veranstaltungstyp 26

    • remso.eu/?TYP=26 Standard-Layout
    • remso.eu/?TYP=26&LO=mini Fachverband-Seite
    • remso.eu/?TYP=26&LO=dscl Segelclub
    • remso.eu/?TYP=26&LO=positionen erweitert
    • remso.eu/?TYP=26&LO=postit angepinnte Zettel der Events

    Selbstverständlich kann weiter gefiltert werden. Hier der Zettel für das nächste Event des Seemanns-Chor Vegesack, unabhängig vom Typ der Veranstaltung:

    • remso.eu/?LO=postit&VIP=606&posi=1