MB: PlugIn Manager entwickeln

moin,

Ich möchte einen PlugIn-Manager schreiben.

Ich hab lauter Ideen, wie ich spezielle Probleme in jeinem jeweiligen Projekt lösen kann. Dazu muss man eine Art Kern schreiben, der die grundlegenden Dinge abarbeiten kann. Die PlugIns überlassen dann die grundlegende Arbeite dem Kern und knnen sich dann der Lösung widmen. Insofern braucht man nicht für jede Lösung die in einem Projekt realisiert wird, intern einen eigenen Kern schreiben. (Ich hab es in einer App gemacht die seeehr statisch war)

Ich hab leider im Internet keine Möglichkeit gefunden (Tutor, abstrakte Anleitung) wie man sowas macht. Beispiele gibts genügend (z.B. Drupal).

Einen heranghehensweise habe ich dennoch schon im Kopf. Man benötigt denke ich FS, Fehlerbehandlung, Caches für eine Manager.

habe ich nowas vergessen?

lgmb

  1. Ich hab leider im Internet keine Möglichkeit gefunden (Tutor, abstrakte Anleitung) wie man sowas macht.

    Beispiele gibts genügend (z.B. Drupal).

    ?

    ... dann studiere doch den Quellcode der Beispiele. Hilfreich dabei sind Debugger (die funktionieren auch bei Code der funktioniert 😉)

    1. moin,

      ... dann studiere doch den Quellcode der Beispiele. Hilfreich dabei sind Debugger (die funktionieren auch bei Code der funktioniert 😉)

      Ok ohne Zweifel. Aber es ist mir von der Komplexität her zu anstrengen. Das gibt meine Kapazität bei den anderen Sachen nicht her 😕. Ich kann mich einlassen aber dann muss ich in meinem Leben alles ausbleden und dann bekomme ich es sicherlich hin. Der Aufwand ist mir echt zu groß, also warum nicht Tutorien oder Anleitungen zur Hand nehmen?

      lgmb

  2. Hallo MB,

    sprichst Du von Plugins, oder von einem Framework?

    Von Plugins spricht man, wenn man eine Basis-Anwendung hat, die allein funktionsfähig ist, aber definierte Andockpunkte hat, wo Code hinzugefügt werden kann.

    Ein Framework kann sich darum kümmern, alle HTTP Requests grundsätzlich entgegen zu nehmen, Objekte für die allgemeine Steuerung zu erzeugen, ggf. auch nach bestimmten Regeln die Requestparameter (GET und POST) zu parsen, zu prüfen und in Objekten abzulegen. Diese Objekte sind Teil des Modells.

    Über einen Router ermittelst Du dann die Klasse, die für die Verarbeitung des konkreten Requests zuständig ist - den Controller. Der Controller erzeugt weitere Modellklassen über Datenbankzugriffe, wobei gerne ein Repository zum Einsatz kommt. Und am Schluss erzeugt er eine Objektstruktur, die zusammen mit einem Template-Namen als ViewModel einer generischen Template-Engine übergeben wird, um die Ausgabe zu rendern.

    Vertraute Begriffe?

    Die kommen aus dem Konzept Model - View - Controller (MVC) oder seiner Variante Model - View - ViewModel (MVVM). Wenn Du Futter für deine Konzeption brauchst, mach Dich darüber mal schlau.

    Es sei denn, das weißt Du alles schon und ich habe dein Anliegen missverstanden.

    Rolf

    --
    sumpsi - posui - clusi
    1. moin,

      Von Plugins spricht man, wenn man eine Basis-Anwendung hat, die allein funktionsfähig ist, aber definierte Andockpunkte hat, wo Code hinzugefügt werden kann.

      Danke ich kennne mich mit dem Design Pattern MVC aus 😉. Hab ja selbst was geschrieben aber es ist mir peinlich es zu präsentieren, weil ich aus dieser Sache mich weioter entwickelt habe.

      lgmb

      1. moin,

        moin,

        Von Plugins spricht man, wenn man eine Basis-Anwendung hat, die allein funktionsfähig ist, aber definierte Andockpunkte hat, wo Code hinzugefügt werden kann.

        Was ist der Unterschied zu PlugIn und Modul gibt es überhaupt unterschiede? Und wenn ja, auf auf Compuzterwissenschafts Ebene oder speziell auf PHP Ebene??? Das würd mich jetzt mal interessieren.

        Ein Framework kann sich darum kümmern, alle HTTP Requests grundsätzlich entgegen zu neh. […].

        Danke ich kennne mich mit dem Design Pattern MVC aus 😉. Hab ja selbst was geschrieben aber es ist mir peinlich es zu präsentieren, weil ich aus dieser Sache mich weioter entwickelt habe.

        lgmb

        1. Hallo MB,

          Was ist der Unterschied zu PlugIn und Modul

          Es ist eine Teilmengenbeziehung. Der Begriff "Modul" ist sehr weit reichend, selbst wenn man nur den Modulbegriff der Softwareentwicklung betrachtet...

          PlugIns sind spezielle Module, die

          • die Anforderungen einer speziellen Schnittstelle erfüllen. Diese Schnittstelle wird von der Plugin-fähigen Anwendung festgelegt.
          • sich dynamisch nachladen lassen

          Das lässt sich auf tausenderlei Arten implementieren.

          Rolf

          --
          sumpsi - posui - clusi
          1. moin,

            PlugIns sind spezielle Module, die [...]

            supi!!! Dann habe ich es doch Begriffen 😀. Dankeschön für die Auffrischung. Ich meine PlugIns.

            lgmb

  3. moin,

    Ich möchte einen PlugIn-Manager schreiben.

    Ich hab lauter Ideen, wie ich spezielle Probleme in jeinem jeweiligen Projekt lösen kann. Dazu muss man eine Art Kern schreiben, der die grundlegenden Dinge abarbeiten kann. Die PlugIns überlassen dann die grundlegende Arbeite dem Kern und knnen sich dann der Lösung widmen. Insofern braucht man nicht für jede Lösung die in einem Projekt realisiert wird, intern einen eigenen Kern schreiben. (Ich hab es in einer App gemacht die seeehr statisch war)

    Genau das ist der Sinn einer Vererbung in OOP: Du hast eine Basiklasse (Kern) und eine Klassenerweiterung (Plugin) welche bei Bedarf die Methoden der Basisklasse überschreibt.

    Leider versteht PHP dies als Klassenerweiterung, also ich finde der Begriff Erweiterung ist falsch. Denn die abgeleitete Klasse in einer solchen Hierarchie erweitert ja nicht sondern spezialisiert (wie Du ja auch feststellst).

    Eine andere Form dafür kennt PHP als Interface. Es wäre also zu überlegen ob Du Dein Pluginmodell als Interface oder Klassenerweiterung konzipierst.

    Wie das bei mir ausschaut siehst Du hier.

    MFG

    1. moin,

      […] Eine andere Form dafür kennt PHP als Interface. Es wäre also zu überlegen ob Du Dein Pluginmodell als Interface oder Klassenerweiterung konzipierst.

      Es geht weit aus Komplexer zu. Ich verwende sicherlich Interfaces auf den PlugIn-Manager bezogen der diese einbindet. Aber Interface allein reichen nicht. Jedoch wenn man's simplifiziert, kann ich es mir Vorstellen allein Interfaces zu verwenden. Aber das wäre dann sehr statisch.

      lgmb

      1. hi,

        mit dem was PHP unter Interface versteht konnt ich mich noch nie anfreunden. Von daher implementiere ich mein FW-Interface als eine ganz normale Klassenerweiterung. und seit ich HTML::Template für PHP entdeckt habe, entwickle ich mein PHP FW mit wachsender Feude. Und natürlich kam ich auch nicht umhin, eine eigene Klassenerweiterung für HTML::Template zu schreiben, genauer gesagt überschreibt die nur den Konstruktor. Und zwar so, daß ein Template auch mal als Plain/Text übergeben werden kann. Z.B. für meine Klasse NotFound:

        <?php
          # hier steht die Klase
        ?>
         und hier steht das Template
        

        Ansonsten will ja HTML::Template eine Datei haben. Im Übrigen läuft ein Web-Framework stets auf ein Interface hinaus. Ganz einfach deswegen weil die Abläufe in einem Request/Response-Zyklus immer dieselben sind.

        Viel Spaß noch dabei.

        1. moin,

          mit dem was PHP unter Interface versteht konnt ich mich noch nie anfreunden.

          Ok? Das ist doch gängiges OOP Zeugs mit Interfaces und Inheritances. Ich hab hier im Forum und bei Tutors gelehnt, das Interface eine total feine Sache ist, bezogen auf Design Patterns (z.B. Structure Pattern). Das ist dir doch nicht neu oder verstu ich mich da?.

          lgmb

          1. moin,

            mit dem was PHP unter Interface versteht konnt ich mich noch nie anfreunden.

            Ok? Das ist doch gängiges OOP Zeugs mit Interfaces und Inheritances. Ich hab hier im Forum und bei Tutors gelehnt, das Interface eine total feine Sache ist, bezogen auf Design Patterns (z.B. Structure Pattern). Das ist dir doch nicht neu oder verstu ich mich da?.

            Natürlich ist das alles OOP und alles nichts Neues. Nur PHP unterscheidet eben zwischen interface und class. So muß z.B. eine interface-Erweiterung sämtliche Methoden definieren die das Basis-Interface vorschreibt. Eine Klassenerweiterung hingegen definiert nur Methoden die den Anwendungsfall spezialisieren.

            So überlagert die hier vorgestellte Klasse nur die control()-Methode. Meine NotFound class hingegen hat gar keine control()-Methode und überlagert nur die bodybuild()-Methode weil das Template für den BODY aus einer anderen Quelle geladen wird.

            Sofern das Template namentlich im file-Attribut genannt ist, lädt bodybuild() (der Basisklasse) automatisch das Template von da und muss in der Klassenerweiterung nicht neu definiert werden.

            So einfach kann OOP sein 😉

            1. moin,

              Ach dawie gerade von Templates sprechen Table Constructor

              lgmb

              1. moin,

                Ach dawie gerade von Templates sprechen Table Constructor

                Das hat doch mit Templates nichts zu tun. Und HTML mit PHP zu erzeugen ist äußerst unschön. Guck Dir mal ne richtige Templateengine an, danach möchtest Du nie wieder HTML mit PHP erzeugen.

                Schön Sonntag.

                1. moin,

                  moin,

                  Ach dawie gerade von Templates sprechen Table Constructor

                  Das hat doch mit Templates nichts zu tun.

                  Ok, ok, in Ordnung. Was ist im -Software Ingenieur teschnischen Sinn- ein Template? Das möchte ich gern von „Dir“ persönlich wissen. Vermutlich verstehen wir beide unter dem Begriff, ein wenig was anderes, dewegen ist die Frage wichtig.

                  Und HTML mit PHP zu erzeugen ist äußerst unschön.

                  Pflichte ich dir total bei. Deswegen mache ich den Kontextwechsel so gering wie möglich.

                  Guck Dir mal ne richtige Templateengine an, danach möchtest Du nie wieder HTML mit PHP erzeugen.

                  habe ich.

                  lgmb

                  1. moin,

                    moin,

                    Ach dawie gerade von Templates sprechen Table Constructor

                    Das hat doch mit Templates nichts zu tun.

                    Ok, ok, in Ordnung. Was ist im -Software Ingenieur teschnischen Sinn- ein Template? Das möchte ich gern von „Dir“ persönlich wissen. Vermutlich verstehen wir beide unter dem Begriff, ein wenig was anderes, dewegen ist die Frage wichtig.

                    Ein Template ist eine Layout-Datei die vom Programmcode unabhängig ist. So können für HTML::Template erstellte Templates sowohl in c, in Perl als auch in PHP gerendert werden weil es diese TE eben für c, Perl und PHP gibt.

                    Das Template für eine Tabelle sähe z.B. so aus (nur der LOOP-Teil):

                    <TMPL_LOOP NAME="names">
                      <tr>
                        <td> %name% </td>
                        <td> %vname </td>
                      </tr> 
                    </TMPL_LOOP>
                    

                    Und wie Du sehen kannst gibt es da nichts was auf Perl, PHP oder C hindeutet und das ist ja auch das Ziel, Code von Layout strikt zu trennen. So hatte ich Kunden die haben ihre Shoptemplates selbst erstellt und mussten nur sagen welche Platzhalter da drin sind, damit ich als Programmierer die Werte dafür bereitstelle.

                    Letzteres ist dann auch der Knackpunkt in der Softwareentwicklung: Nicht HTML erzeugen sondern nur noch die Daten in Templates zu rendern.

                    Was das für die Produktivität bedeutet dürfte klar sein. Einmal hinsichtlich Teamarbeit und zum Anderen hinsichtlich Zeitersparnis.

                    Schließlich können Templates aus unterschiedlichen Quellen geladen werden, Dateien, Datenbanken, Netzwerk und in Ausnahmefällen liegt das Template auch mal in der Klassendatei wo man das auch da sauber vom Code trennen kann.

                    Und auch wenn Du Perl nicht magst: Das sind alles Dinge die in Perl sozusagen der Programmieralltag sind. Es ist nie verkehrt mal zu gucken was die Anderen machen und wie sie es machen. Als PHP den Siegeszug im Web antrat, hatten Perlentwickler dem Prinzip von eingebettetem Code längst den Rücken gekehrt und die Entwicklung in Richtung Templateengines vorangetrieben.

                    MFG

                    1. Tach!

                      Ein Template ist eine Layout-Datei die vom Programmcode unabhängig ist. So können für HTML::Template erstellte Templates sowohl in c, in Perl als auch in PHP gerendert werden weil es diese TE eben für c, Perl und PHP gibt.

                      Das Template für eine Tabelle sähe z.B. so aus (nur der LOOP-Teil):

                      <TMPL_LOOP NAME="names">
                        <tr>
                          <td> %name% </td>
                          <td> %vname </td>
                        </tr> 
                      </TMPL_LOOP>
                      

                      In diesem Template wird für die Logik (im Beispiel die Schleife) eine dritte Sprache verwendet. Das kann man so machen, wenn die Templates aus Gründen unabhängig von einer konkreten bereits vorhandenen Programmiersprache sein müssen. Das ist aber nicht überall zwingende Notwendigkeit, und so kann man durchaus statt der dritten Sprache die Programmiersprache des Systems für diese Logik-Teile verwenden, inklusive bereits vorhandener Unterstützung dafür in der IDE (Syntaxhervorhebung, Debugging).

                      Und wie Du sehen kannst gibt es da nichts was auf Perl, PHP oder C hindeutet und das ist ja auch das Ziel, Code von Layout strikt zu trennen.

                      Die strikte Trennung ist kein allgemeingültiges Ziel sondern nur notwendig in Anwendungsfällen, wo das Template in verschiedenen Systemen unabhängig verwendet werden muss.

                      Was das für die Produktivität bedeutet dürfte klar sein. Einmal hinsichtlich Teamarbeit und zum Anderen hinsichtlich Zeitersparnis.

                      Gegenzurechnen wäre der Aufwand, die dritte Sprache lernen zu müssen. Ob das immer eine Zeitersparnis ergibt, darf je nach Komplexität der dritten Sprache bezweifelt werden.

                      Schließlich können Templates aus unterschiedlichen Quellen geladen werden, Dateien, Datenbanken, Netzwerk und in Ausnahmefällen liegt das Template auch mal in der Klassendatei wo man das auch da sauber vom Code trennen kann.

                      Auch das ist nicht überall Notwendigkeit.

                      dedlfix.

                    2. moin,

                      Ein Template ist eine Layout-Datei die vom Programmcode unabhängig ist. […]

                      Das sind wir uns einig.

                      Das Template für eine Tabelle sähe z.B. so aus (nur der LOOP-Teil): […]

                      Was ist der unterschied zu meinem Komplexerem Template wo du nicht weißt wieviele <tr>s und <td>man hat??? Ich hingegen brauch mich um keine Tabellen Templates mehr zu kömmern da mein Template alles schon erledigt.

                      <table>
                        <colgroup>
                        ...
                        </colgroup>
                        <thead>
                          ...
                        </thead>
                        <tbody>
                          ...
                        </tbody>
                        <tbody>
                          ...
                        </tbody>
                        <tbody>
                          ...
                        </tbody>
                        <tfoot>
                          ...
                        </tfoot>
                      </table>
                      

                      Und wie Du sehen kannst gibt es da nichts was auf Perl, PHP oder C hindeutet […]

                      das ist richtig, aber was ist denn, wenn ich nur für eine Programmiersprache und für ein bestimmtes CMS ein Template erstellen will was gefordert ist. Was dann? @dedlfix hat erwähnt

                      […] und das ist ja auch das Ziel, Code von Layout strikt zu trennen.

                      Das sind wir uns einig ohne Frage.

                      Letzteres ist dann auch der Knackpunkt in der Softwareentwicklung: Nicht HTML erzeugen sondern nur noch die Daten in Templates zu rendern.

                      bin ich genau bei dir

                      Was das für die Produktivität bedeutet dürfte klar sein. Einmal hinsichtlich Teamarbeit und zum Anderen hinsichtlich Zeitersparnis.

                      Es ist nie verkehrt mal zu gucken was die Anderen machen und wie sie es machen.

                      Da stimme ich dir persönlich voll und ganz zu. Ohne frage.

                      Aber was hat das Schlussentlich mit meinem Template zutun? @Rolf B hat Helper-Funktionen erwähnt, @dedlfix hat die 'extrem' strikte Trennung relativiert, dass man das machen kann aber nicht muss.

                      lgmb

                      1. moin,

                        Ein Template ist eine Layout-Datei die vom Programmcode unabhängig ist. […]

                        Das sind wir uns einig.

                        Das Template für eine Tabelle sähe z.B. so aus (nur der LOOP-Teil): […]

                        Was ist der unterschied zu meinem Komplexerem Template wo du nicht weißt wieviele <tr>s und <td>man hat???

                        Siehe mein Beispiel mit <TMPL_LOOP>. Da erzeugt die TE Tabellen mit beliebig vielen Zeilen und das praktische daran ist, daß eine Datenbankabfage genau diese Datenstruktur liefert welche die TE zum Rendern braucht. So wird die Ergebnismenge 1:1 der TE übergeben.

                        Und dann denke mal an Kundenwünsche und Skalierbarkeit. Stell Dir vor ein Kunde möchte in seiner Tabelle zusätzliche Spalten oder Spalten ausblenden. Sowas hast Du über ein Template in wenigen Minuten erledigt und wie ich schon schrieb, sowas kann der Kunde ggf. auch selber machen.

                        Des Weiteren gibt es auch Überlegungen hnisichtlich systemübergreifender Datenstrukturen. Und siehe da, auch für JavaScript gibt es Templateengines, die mit denselben Datenstrukturen rendern wie HTMLTemplate. So übergibst Du das Ergebnis einer Datenbankabfrage ganz einfach als JSON in die Response für einen AJAXRequest wie diese DEMO zeigt.

                        MFG

                        1. PS

                          Des Weiteren gibt es auch Überlegungen hnisichtlich systemübergreifender Datenstrukturen. Und siehe da, auch für JavaScript gibt es Templateengines, die mit denselben Datenstrukturen rendern wie HTMLTemplate. So übergibst Du das Ergebnis einer Datenbankabfrage ganz einfach als JSON in die Response für einen AJAXRequest wie diese DEMO zeigt.

                          Von Progressive Enhancement ist hier gelegentlich die Rede. Praktisch geht es darum, eine bestehende Anwendung die auf Submit basiert anwenderfreundlicher zu machen. Und auch hier zeigt es sich als sehr vorteilhaft wenn die darzustellenden Daten über ein Template gerendert werden.

                          So wird bei einem native Submit das Template serverseitig gerendert, nach der Erweiterung auf JavaScript hingegen wird das Template im Browser gerendert. I.d.R. erfordert eine solcher Erweiterung nur eine einzige Zeile serverseitig, denn die Daten die zu rendern sind, liegen ja bereits vor. D.h., daß diese Daten anstatt sie serverseitig zu rendern nu noch zu serialisieren sind für eine Response mit dem Enctype application/json.

                          Damit haben wir serverseitig wie clientseitig genau dieselbe Datenstruktur und: Auch dasselbe Template!

                          MFG

                          1. problematische Seite

                            Und hier ist die Demo, Serverseitig habe ich dazu nur die Kontrollstruktur erweitert:

                                    if( $this->param('showroutes') ){
                                        $this->STASH['native'] = 1;
                                    }
                                    else if( $this->param('xhr') ){
                                        $this->CONTENT = json_encode($this->STASH,1);
                                    }
                            

                            wie lange würdest Du mit Deinem Tabellenerzeuger dafür benötigen?

                            MFG

                          2. Hallo pl,

                            das ist natürlich ganz praktisch, wenn man auf diese Weise zwischen JS-enabled und JS-free umschalten kann. Da zahlt es sich dann aus, dass die TE an sich sehr kompakt ist und wenig Code braucht. Die kann man dann relativ leicht doppelt implementieren.

                            Sowas sollte man sich aber gut überlegen und möglichst nach einem fertigen Produkt suchen. Deine TE ist sehr einfach gestrickt. Die Regexe sehen so aus, als wären sie bei „komplexer“ Logik überfordert.

                            Dieses Template

                            @if_foo@
                               foo! foo!
                            @else@
                               tralala
                            @endif@
                            
                            @if_bar@
                               barabarabar
                            @else@
                               flöt
                            @endif@
                            

                            sollte deine greedy if/else regex .replace(/@if_(\w+)@(.*?)@else@(.*?)@endif@/gm bereits in den digitalen Wahnsinn treiben.

                            Rolf

                            --
                            sumpsi - posui - clusi
                        2. moin,

                          Siehe mein Beispiel mit <TMPL_LOOP>. Da erzeugt die TE Tabellen mit beliebig vielen Zeilen und das praktische daran ist, daß eine Datenbankabfage genau diese Datenstruktur liefert welche die TE zum Rendern braucht. So wird die Ergebnismenge 1:1 der TE übergeben.

                          Ich rede nicht von TE (Template Engine) sondern von einem einfachen Template. Feiner Unterschied! Wenn ich eine TE mit diesem Code vorstellen würde, dann wäre deine „Kritik“, meiner Meinung nach, völlig berechtigt.

                          Meine Template kann wahlweise eine ganze Tabelle in Zeitlichen abständen befüllt werden, ohne jegliche Kopplung. Man muss nur entsprechende externe Klassen befüllen eben, auserhalb das T:

                          $ta = new TableAttributs( 'id', 'class', 1, 1 );
                          $tcol = new TableColum( 'id', 'class', '1' );
                          $tset = new TableSettings( 'id', 'class', null, [ $tcol, $tcol, $tcol, $tcol ] );
                          $tc = new TableCell( 'foobar', $ta );
                          $tr = new TableRow( [ $tc, $tc, $tc, $tc ] );
                          $ts = new TableSection( [ $tr, $tr ], $ta );
                          $t = new TableConstructor( 'Foo Bar', $tset, $ts, $ts, $ts );
                          

                          geht auch so

                          echo new TableConstructor(
                            null,
                            new TableSection( [
                              new TableRow( [
                                new TableCell( 'foobar' )
                              ] );
                            ] );
                          );
                          

                          Ergebnis:

                          <table>
                            <tbody>
                              <tr>
                                <td>foobar</td>
                              </tr>
                            </tbody>
                          </table>
                          

                          mit den selben Template das ich vorgestellt habe. Dann hast du alles in einem rutsch. Aber is noch nicht ausgereift.

                          Neben bei erwähnt, ich schreibe zukünftig TE's die ich dann vorstellen werde und da kannst du sehr gern Kritik üben die von mir gewünscht ist. Is ja n Forum.

                          lgmb

                          1. Mitnichten kritisiere ich Deinen Code. Ganz im Gegenteil! Es ist jedoch so, daß man auch einst (vor 20 Jahren) in Perl Libraries entwickelte die genau das tun was Du heute mit Deinem Code beabsichtigst. Nur darauf wollte ich hinweisen. So haben auch wir Perlentwickler in unseren Anwendungen jahrzehntelang Code mitgeschleppt ohne diesen zu nutzen. Und es ist genau diese Erfahrung die mich dazu brachte ein eigenes Framework zu entwickeln.

                            Beispielsweise gab es eine Methode start_html() für Instanzen der Perlklasse CGI. Von dieser Funktion ist in meinem FW nur der Name geblieben als eine Methode von Instanzen meiner Perl- oder PHPklassen. Schließlich wird diese Methode zum Aufbau einer jeden Response vom Enctype text/html benötigt.

                            Im Gegensatz zu CGI::start_html() erzeugt meine Methode jedoch kein HTML sondern rendert ein Template. Und siehe da, es ist völlig egal, ob die Methode start_html() die Instanz einer PHPklasse oder die Instanz einer Perlklasse ist, das Template ist dasselbe.

                            Aber letztendlich zählt nur das was man selber tut. MFG

                            1. moin,

                              Mitnichten kritisiere ich Deinen Code. […]

                              Das habe ich damn falsch verstanden und ich entschulige mich persönlich und in aller Form für die Zurechtweisung.

                              lgmb

                          2. Hallo MB,

                            es ist letztlich egal, ob Du das Template in PHP oder mit Mitteln einer Template-Engine schreibst. Wichtig ist die Trennung zwischen Business- und Ausgabelogik, und die hast Du.

                            Ob Du tatsächlich spezifische Klassen für Table, TableRow, TableCell etc brauchst, dann kann man diskutieren. Eventuell führt das ins over-engineering. Ein OOP-Template muss zwei Dinge können:

                            • sich an den Datenstrukturen des Business- oder Viewmodels entlanghangeln
                            • einige HTML Bausteine ausgeben können: Elemente ohne Inhalt (<img>), Elemente mit leerem Inhalt (<div />, Elemente mit Inhalt (<form>, </form>) und Inhalt hineinsetzen, Attribute an Elemente kleben sowie Text ausgeben. Korrekter Kontextwechsel inbegriffen.

                            D.h. letztlich läuft es auf die Grundbausteine der EDV hinaus: Sequenz, Alternative und Iteration.

                            Das führt dann dazu, dass Du einen Objektbaum aus Template-Objekten aufbaust, der deine Ausgabe beschreibt, und dann die render-Methode der Baumwurzel aufrufst. Der Rest entwickelt sich dann von selbst. Das ist aber nicht unbedingt effizient. PHP muss die Klassen laden, du musst sie instanziieren, erst dann kannst Du ausgeben. Sowas ist gut, wenn man den geladenen Baum mehrfach verwenden kann, aber genau das geht in PHP ja nicht. Für jeden neuen Web-Request wird der Speicher geputzt.

                            Deswegen ist ein in PHP programmiertes Template, das Du bei Bedarf einfach mit include einbindest, die bessere Lösung.

                            Ich hab mal gegoogelt - guck mal was Ian Burris macht. Der bettet es sogar in eine Klasse ein und das includete Template hantiert dann auf $this->... herum. Kann man machen, muss man nicht. Es muss nur eine Konvention geben, was der includete Code vorzufinden erwartet.

                            Ein anderes Beispiel für diese Idee ist Smarty. Da gibt's zwar eine eigene Templatesprache, aber Smarty "kompiliert" das beim ersten Verwenden in PHP und führt dann dieses PHP aus. Das Smarty-Objekt bekommt ein Array mit Daten-Elementen, die dann im Template zur Verfügung stehen. Damit ist das Template strikt vom Rest des Codes getrennt und kann auf nichts zugreifen, was ihm nicht erlaubt ist. Gerade, wenn Templates von Dritten gebaut werden, kann das interessant sein.

                            Rolf

                            --
                            sumpsi - posui - clusi
                            1. moin,

                              Ob Du tatsächlich spezifische Klassen für Table, TableRow, TableCell etc brauchst, dann kann man diskutieren. Eventuell führt das ins over-engineering.

                              ich führchte. Es ist ja zum Lern Zweck und um mich zu präsentieren

                              PHP muss die Klassen laden, du musst sie instanziieren, erst dann kannst Du ausgeben.

                              Ich überlegte ob es sinnvoll ist das ganze zu cachen

                              Sowas ist gut, wenn man den geladenen Baum mehrfach verwenden kann, aber genau das geht in PHP ja nicht. Für jeden neuen Web-Request wird der Speicher geputzt.

                              auf das gecachte zugreifen? Dann spart man sich auch das 1000-fache laden PHP Klassen.

                              lgmb

                              1. Hallo MB,

                                da bin ich nicht weit genug drin, um sagen zu können, ob man instanziierte Objektbäume cachen kann. Ich hätte da meine Zweifel.

                                Wenn es geht, musst Du auf jeden Fall darauf achten, dass die Runtime-Daten, also das, was Du zum Ausgeben brauchst, nur auf dem Stack landet (also als Parameter weitergeht) und nicht im Template-Objekt. Denn wenn es gecached werden kann, wird es für hunderte Requests vieler verschiedener User genutzt.

                                Rolf

                                --
                                sumpsi - posui - clusi
                              2. Ob Du tatsächlich spezifische Klassen für Table, TableRow, TableCell etc brauchst, dann kann man diskutieren. Eventuell führt das ins over-engineering.

                                ich führchte. Es ist ja zum Lern Zweck und um mich zu präsentieren

                                Ich habe mal eine ähnliche Templating-Engine geschrieben. Ich habe aber nicht für jeden Elementtypen eine eigene Klasse angelegt, sondern nur eine Klasse Element und ein paar abgeleitete Klassen für Spezialfälle. Für die einzelnen Elementtypen habe ich dann einzelne Factory-Funktionen geschrieben. Das ist viel Code, aber dafür eine simple Architektur. Wenn es dir hilft: https://github.com/Teein/Html

                                PHP muss die Klassen laden, du musst sie instanziieren, erst dann kannst Du ausgeben.

                                Ich überlegte ob es sinnvoll ist das ganze zu cachen

                                Absolut, aber Caching ist mitunter sehr schwierig zu implementieren.

              2. moin,

                Ach dawie gerade von Templates sprechen Table Constructor

                Ach grad gelesen, das Perlmodul CGI.pm aus dem Jahre 1997 kann auch Tabellen und beliebige HTML-Elemente erzeugen. Ganz ähnlich wie Du das machst. Hast Du die Idee von da?

                    :html2
                        Import all methods that generate HTML 2.0 standard elements.
                
                    :html3
                        Import all methods that generate HTML 3.0 elements (such as <table>,
                        <super> and <sub>).
                
                    :html4
                        Import all methods that generate HTML 4 elements (such as <abbrev>,
                        <acronym> and <thead>).
                

                MFG

                1. moin,

                  Ach dawie gerade von Templates sprechen Table Constructor

                  Ach grad gelesen, das Perlmodul CGI.pm aus dem Jahre 1997 kann auch Tabellen und beliebige HTML-Elemente erzeugen. Ganz ähnlich wie Du das machst. Hast Du die Idee von da?

                  Ach schön, aber nein nicht konkret. Ich hab meine eigenen grauen Zellen angestrengt. Die Idee und Konzepte habe ich aus vielerleih Ereignissen gezogen: Hier im Forum (auch bei dir in deinen Beträgen), im Tutorium, in Lehrbücher etc.. Die konkrete Umsetzung ist in meinem Denkstübchen entstanden mit UML: CD.

                  lgmb

                  1. Beim Lesen der Beiträge hier kommen mir auch viele Ideen 😉

            2. Hallo pl,

              So muß z.B. eine interface-Erweiterung sämtliche Methoden definieren die das Basis-Interface vorschreibt.

              Unter Erweiterung verstehst Du extends, nicht implements, ja? Aber Interfaces können Methoden erben:

              interface IAnimal {
                 public function move();
              }
              
              interface IMammal extends IAnimal {
                 public function move();   // unnötig!
                 public function cry();
              }
              

              Oder sowas hier?

              abstract class Animal implements IAnimal {
                  public function move() {
                      echo "Hä? Wie geht das?<br>";
                  }
              }
              
              class Cat extends Animal implements IMammal {
                  public function move() {
                      echo "Tapp Tapp Tapp<br>";
                  }
                  public function cry() {
                      echo "Miau<br>";
                  }
              }
              

              An dieser Stelle ist es interessant, ob man IAnimal::move in IMammal wiederholt hat oder nicht. Hat man es getan, dann verlangt PHP vor 5.3 die move-Methode in der Cat-Klasse. Hat man es nicht getan, dann kann Animal::move von Cat geerbt werden. Cat kann aber auch selbst move implementieren und Animal::move überschreiben.

              Das älteste Förmchen, das ich im Sandkasten gefunden habe, ist PHP 5.0.4. Auch damit funktionierte das. Es gibt da auch noch PHP 4 Versionen, aber da sich die OOP-Implementierung von PHP 4 auf 5 stark geändert hat, compilierte der obige Code damit nicht und es ist heute auch nicht mehr relevant.

              Rolf

              --
              sumpsi - posui - clusi
    2. Tach!

      Genau das ist der Sinn einer Vererbung in OOP: Du hast eine Basiklasse (Kern) und eine Klassenerweiterung (Plugin) welche bei Bedarf die Methoden der Basisklasse überschreibt.

      Nein, wieviele Plugins man am Ende zum Projekt hinzufügen möchte, weiß man zur Entwicklungszeit normalerweise nicht. Für diese unbekannte Anzahl Möglichkeiten je eine Basisklasse bereitzustellen, ist jedenfalls keine gescheite Vorgehensweise. Vererbung ist nicht die Technik, in der man Plugins grundlegend implementiert. Ein Plugin ist üblicherweise ein eigenes Modul, das erst zur Laufzeit hinzugefügt wird und nicht ins Programm hineinkompiliert. Ob dabei Vererbung verwendet wird oder nicht, ist ein Implementierungsdetail.

      Leider versteht PHP dies als Klassenerweiterung, also ich finde der Begriff Erweiterung ist falsch. Denn die abgeleitete Klasse in einer solchen Hierarchie erweitert ja nicht sondern spezialisiert (wie Du ja auch feststellst).

      Warum soll das keine Erweiterung sein? Die Grundfunktionalität der Basisklasse wird um spezielle Funktionalität erweitert. Und wenn abstrakte Methoden implementiert werden, ist das zweifellos eine Erweiterung.

      Eine andere Form dafür kennt PHP als Interface. Es wäre also zu überlegen ob Du Dein Pluginmodell als Interface oder Klassenerweiterung konzipierst.

      Plugins können auf einer Basisklasse aufbauen oder ein Interface implementieren, aber zwingende Voraussetzung ist das nicht. Die Kommunikation zwischen Basisprogramm und Plugin kann auch über Datenströme erfolgen.

      dedlfix.

      1. Hallo dedlfix,

        Für diese unbekannte Anzahl Möglichkeiten je eine Basisklasse bereitzustellen,

        ich glaube, jetzt liegst Du daneben.

        Man kann durchaus eine Art PDK (Plugin Developer Kit) anbieten, bestehend aus einer Basisklasse, von der alle Plugins erben, plus einem oder einigen Interfaces, die dem Plugin bereitgestellt werden und über die es Dienste der Basis-Application nutzen kann. Das kann dem Plugin einiges an Boilerplate-Code ersparen, bzw. es hilft, die Kommunikation mit der Basis-Application zu standardisieren.

        Eine eigene Basisklasse in der Application für jedes denkbare Plugin wäre Unsinn, das führt die Plugin-Idee ad absurdum.

        Datenströme

        Sicherlich. Aber genormt sein müssen die auch, und auch dafür sind vorgefertigte Helper nützlich. Ein PDK in der einen oder anderen Form braucht man immer. Wenn es der Anbieter der Basis-Application nicht tut, dann tut es jeder Plugin Entwickler für sich...

        Rolf

        --
        sumpsi - posui - clusi
        1. Tach!

          Für diese unbekannte Anzahl Möglichkeiten je eine Basisklasse bereitzustellen,

          ich glaube, jetzt liegst Du daneben.

          Man kann durchaus eine Art PDK (Plugin Developer Kit) anbieten, bestehend aus einer Basisklasse, von der alle Plugins erben, plus einem oder einigen Interfaces, die dem Plugin bereitgestellt werden und über die es Dienste der Basis-Application nutzen kann.

          Ja, man kann OOP als Codebasis für Plugins nehmen. Aber das ist keine Voraussetzung. Plugins zu entwickeln ist nicht "der Sinn von Vererbung".

          Eine eigene Basisklasse in der Application für jedes denkbare Plugin wäre Unsinn, das führt die Plugin-Idee ad absurdum.

          Wenn man ein Plugin einbinden möchte, braucht man einen Registriermechanismus und definierte Schnittstellen, um die Funktionalität des Plugins anzusprechen. Wenn das lediglich über Vererbung passieren soll, braucht jedes Plugin ein Pendant im Basiscode von dem es erben kann. - Oder seine Beschreibung war zumindest für mich missverständlich.

          dedlfix.

          1. Hallo dedlfix,

            braucht jedes Plugin ein Pendant im Basiscode

            Die Betonung liegt auf ein. Will man ein OOP-PDK anbieten, muss es genau eine abstrakte Plugin-Klasse geben, und über Eigenschaften/Methoden dieser Klasse kommt das Plugin an das API der Basis-Application heran. Es gibt ggf. mehrere Variationen dieser Basisklasse, die dann aber alle von einer AbstractPlugin-Klasse erben sollten. Oder die Basisklasse stellt ein API mit unterschiedlichen Verbindungspunkten bereit, und unterschiedliche Plugins verbinden sich mit unterschiedlichen Stellen. Das festzulegen ist Sache der Plugin-fähigen Application.

            Rolf

            --
            sumpsi - posui - clusi
            1. Tach!

              Die Betonung liegt auf ein. Will man ein OOP-PDK anbieten, muss es genau eine abstrakte Plugin-Klasse geben, und über Eigenschaften/Methoden dieser Klasse kommt das Plugin an das API der Basis-Application heran.

              Das ist mir schon klar, dass man das Plugin-System so designen kann, dass Plugins eine Basisklasse beerben oder ein Interface implementieren. Aber Vererbung ist für eine Plugin-Technik keine Voraussetzung. Meine Kritik an pl bezog sich auf seine (so von mir verstandene) Aussage, dass man Plugins per Vererbung einbindet. "Du hast eine Basiklasse (Kern) und eine Klassenerweiterung (Plugin) [...]" Da ist nicht die Rede von einer Basisklasse für alle Plugins. Die Basisklasse gehört in seiner Aussage nicht zum Plugin, sondern ist das Gegenstück dazu im Kern. Sowas ist kein Plugin sondern eine Erweiterung des Codes um weitere Funktionalität.

              Wenn der Kern zum Beispiel für drei Funktionalitäten braucht, wie spricht er die denn an, wenn er lediglich die Basisklasse kennt? Ich kann mir da nur vorstellen, dass es drei Basisklassen gibt oder eine Basisklasse mit drei speziellen Methoden. Aber wie gesagt, sowas ist nicht das, was ich als Plugin-System bezeichnen würde.

              Ein Plugin-System ist für mich im Wesentlichen eine Liste von Hooks, und dazu je eine Liste von Plugins. Diese Liste bildet sich aber erst zur Laufzeit, nachdem das System die zur Verfügung stehenden Plugins gesucht und gefunden hat und die Plugins für die diversen Hooks registriert wurden, für die sie Funktionalität anbieten. Dazu gehört auch, dass für beliebig viele Hooks kein Plugin existiert. In meinem Model ist das Gegenstück zum Plugin der jeweilige Hook. Und dieser Hook ist keine (Basis)klasse sondern ein eine Stelle im Code, die über einen Bezeichner die Pluginverwaltung befragt, ob dafür etwas registriert und auszuführen ist. Da dazu kein Plugin existieren muss, kann der Hook keine abstrakte Basisklasse sein, weil solche ohne implementierende überschreibende Klassen nicht instantiiert werden können.

              dedlfix.

  4. habe ich nowas vergessen?

    Es gäbe noch, neben der Möglichkeit der Klassenerweiterung/Vererbung die Möglichkeit Code durch Traits zu erweitern bzw. zu spezialisieren.

    MFG

    1. Tach!

      Es gäbe noch, neben der Möglichkeit der Klassenerweiterung/Vererbung die Möglichkeit Code durch Traits zu erweitern bzw. zu spezialisieren.

      Auch das wird im allgemeinen nicht mit dem Begriff Plugin bezeichnet.

      Plugins erweitern ein fertiges Programm um optionale Dinge. Was du in diesem Thread beschreibst, sind Erweiterungen des Codes.

      dedlfix.