Grundlagen Modulentwicklung Backend | Anzeigen von Datenbankinhalten

Moin und guten Tag

Ich habe hier mal Grundsätzliche Fragen zur Modulentwicklung. Nach gefühlten 30 tausend Seiten und kein weiterkommen, hoffe ich das man hier mal, was Grundsätzliches klären kann.

So nun zur eigentlichen Sache. Wenn man im Backend Datenbankinhalte anzeigen will, wehrt sich Oxid mit allen zur Verfügung stehenden Mitteln, diese Inhalte auch anzuzeigen.
Dafür muss, so wie ich es verstanden habe, eine Anweisung her, das Oxid an der gewünschten Stelle, diesen Inhalt auch anzeigen darf. Dafür muss es dann drei Dateien geben.

  1. Die metadata.php
  2. Eine .tpl Datei (Hier sind es drei)
  3. Eine .php Datei.

Da man ohne Beispiel was man will schlecht Fragen klären kann, habe ich mal ein kleines Projekt vorbereitet das in der Artikelansicht die zu den Artikel gehörigen tags als Liste anzeigt. Ist ja nicht ganz uneigennützig. :slight_smile: Aber ich denke das dies wohl zu gebrauchen ist und das dadurch grundsätzliche Fragen geklärt werden.

Die metadata.php

<?php
/**
 * Module information
 * Das Modul erweitert die Admin Artikelansicht um ein weiteres Feld.
 * Dort sollen die Tags oder auch Stichworte zu den dazugehörigen Artikel angezeigt werden.
 * Die Tags sind in der Tabelle "oxartextends" unter dem Feld "oxtags" zu finden.
 * oxartextends__oxtags
 */
$aModule = array(
    'id'           => 'mbm',
    'title'        => 'Mein Backend Modul',
    'description'  => array(
    	'de' => 'Ich lasse mal diese ganzen Einträge leer, weil die zur Funktion nicht relevant sind.',
    	'en' => ''
    ),
    'thumbnail'    => '',
    'version'      => '',
    'author'       => '',
    'email'        => '',
    'url'          => '',
    'extend'       => array(
        'article_list' 		=> 'mein_modul/mein_modul_title/controllers/article_list'
    ),
    'blocks' => array(
        array('template' => 'article_list.tpl', 'block'=>'admin_article_list_colgroup', 'file'=>'mbm_article_list_colgroup.tpl'),
        array('template' => 'article_list.tpl', 'block'=>'admin_article_list_sorting', 'file'=>'mbm_article_list_sorting.tpl'),
        array('template' => 'article_list.tpl', 'block'=>'admin_article_list_item', 'file'=>'mbm_article_list.tpl'),
    )
);

Dazu natürlich die .tpl Dateien. Es sind hier drei weil einzelne Blöcke bearbeitet werden müssen. Eine bessere Lösung kenn ich nicht. Erst einmal habe ich die artikel_list.tpl aus dem Standart application/views/admin/tpl Ordner genommen. Dort sind die drei Blöcke die ersetzt werden. In rot ist hinzugefügt worden.

  1. [{block name=“admin_article_list_colgroup”}]
<col width="3%">
            <col width="10%">
            <col width="25%">
            <col width="30%">
            <col width="30%">
            <col width="2%">
  1. [{block name=“admin_article_list_sorting”}] Obwohl ich dies nicht hinbekomme
<td class="listheader first" height="15" width="30" align="center"><a href="Javascript:top.oxid.admin.setSorting( document.search, 'oxarticles', 'oxactive', 'asc');document.search.submit();" class="listheader">[{ oxmultilang ident="GENERAL_ACTIVTITLE" }]</a></td>
            <td class="listheader"><a href="Javascript:top.oxid.admin.setSorting( document.search, 'oxarticles', 'oxartnum', 'asc');document.search.submit();" class="listheader">[{ oxmultilang ident="GENERAL_ARTNUM" }]</a></td>
            <td class="listheader" height="15"> <a href="Javascript:top.oxid.admin.setSorting( document.search, 'oxarticles', '[{ $pwrsearchfld|oxlower }]', 'asc');document.search.submit();" class="listheader">[{assign var="ident" value=GENERAL_ARTICLE_$pwrsearchfld }][{assign var="ident" value=$ident|oxupper }][{ oxmultilang ident=$ident }]</a></td>
            <td class="listheader" ><a href="Javascript:top.oxid.admin.setSorting( document.search, 'oxarticles', 'oxshortdesc', 'asc');document.search.submit();" class="listheader">[{ oxmultilang ident="GENERAL_SHORTDESC" }]</a></td>
            <td class="listheader" colspan="2"><a href="Javascript:top.oxid.admin.setSorting( document.search, 'oxarticles', 'oxtags', 'asc');document.search.submit();" class="listheader">[{ oxmultilang ident="GENERAL_TAG" }]TAG</a></td>
          </code>

3. [{block name="admin_article_list_item"}]
<code>
 [{ if $listitem->blacklist == 1}]
            [{assign var="listclass" value=listitem3 }]
        [{ else}]
            [{assign var="listclass" value=listitem$blWhite }]
        [{ /if}]
        [{ if $listitem->oxarticles__oxid->value == $oxid }]
            [{assign var="listclass" value=listitem5 }]
        [{ /if}]
        <td valign="top" class="[{ $listclass}][{ if $listitem->oxarticles__oxactive->value == 1}] active[{/if}]" height="15"><div class="listitemfloating">&nbsp</a></div></td>
        <td valign="top" class="[{ $listclass}]"><div class="listitemfloating"><a href="Javascript:top.oxid.admin.editThis('[{ $listitem->oxarticles__oxid->value }]');" class="[{ $listclass}]">[{ $listitem->oxarticles__oxartnum->value }]</a></div></td>
        <td valign="top" class="[{ $listclass}]" height="15"><div class="listitemfloating"> <a href="Javascript:top.oxid.admin.editThis('[{ $listitem->oxarticles__oxid->value }]');" class="[{ $listclass}]">[{ $listitem->pwrsearchval|oxtruncate:200:"..":false }]</a></div></td>
        <td valign="top" class="[{ $listclass}]"><div class="listitemfloating"><a href="Javascript:top.oxid.admin.editThis('[{ $listitem->oxarticles__oxid->value }]');" class="[{ $listclass}]">[{ $listitem->oxarticles__oxshortdesc->value|strip_tags|oxtruncate:45:"..":true }]</a></div></td>

        <td valign="top" class="[{ $listclass}]"><div class="listitemfloating"><a href="Javascript:top.oxid.admin.editThis('[{ $listitem->oxarticles__oxid->value }]');" class="[{ $listclass}]">[{ $listitem->oxartextends__oxtags->value|strip_tags|oxtruncate:45:"..":true }]</a></div></td>

        <td class="[{ $listclass}]">
          [{if !$readonly}]
              <a href="Javascript:top.oxid.admin.deleteThis('[{ $listitem->oxarticles__oxid->value }]');" class="delete" id="del.[{$_cnt}]"title="" [{include file="help.tpl" helpid=item_delete}]></a>
          [{/if}]
        </td>

Diese Block Namen sind auch in der metadata.php wiederzufinden.

Dann wird wohl noch die .php Datei zur Anweisung das auch an der gewünschten Stell die Daten angezeigt werden sollen.
Die wird hier article_list.php genannt. Und liegt im Ordner mein_modul/mein_modul_title/controllers/article_list.php

Und das ist der Knackpunkt. Was genau muss da stehen, damit Datenbankinhalte angezeigt werden können? Die Inhalte sind unter oxartextends__oxtags zu finden.

Es wäre schön wenn man hier eine saubere Lösung findet, die man so oder so ähnlich, in abgewandelter Form, auch für andere Projekte die Inhalte für das Backend anzeigen sollen.

Wow. 118 Views, und keiner weiß etwas.:rolleyes:

Also nur mal klarstellen. Ich will nicht Programmierer werden und nicht kommerziell Module vertreiben. Falls das beruhigt.:wink:

Mir reicht ja schon ein Link zu einer wirklich hilfreichen Seite. In der Art wie(w3schools).
Und ja, ich habe auch einen Controller dazu. Welcher aber nicht funktioniert weil zu wenig Wissen. Deshalb habe ich den auch nicht mit gepostet.

Natürlich habe ich schon durch das Forum gewühlt und diverse Seiten besucht. Aber leider waren die Tipps nicht erfolgreich.

Ich will ehrlich sein: Ich hab jetzt nicht alles gelesen, aber wenn ich deine Headline richtig verstehe, dann sollte Dir das eigentlich helfen.

http://www.mibexx.de/oxid-eshop-erweiterungen-teil-4/

Kenne ich. Wie soll man durch ein schlechtes Video denn lernen?

Außerdem erweckt das in mir ungeahnte Wutgefühle. Leider kann ich nicht durch den Bildschirm greifen und den Typen schüttel. Vielleicht ein Video machen, in dem ich ihm vorschlage mal was zu schreiben?:smiley:

Aber trotzdem danke.

Normalerweise kannst du Daten von Objekten einfach anzeigen mit $objekt->tabelle__feld->value. Bei Tags ist das etwas komplizierter weil die Daten in einer anderen Tabelle stehen und daher nicht mit dem Objekt geladen werden. Man kann sich aber z.B. in article_main.php anschauen wie die Tags geladen werden:


            //loading tags
            $oArticleTagList = oxNew("oxArticleTagList");
            $oArticleTagList->loadInLang($this->_iEditLang, $oArticle->getId());
            $oArticle->tags = $oArticleTagList->get();

Das ist für einen Artikel. Netterweise werden beim Laden der Artikelliste in article_list::render() schon alle Artikel in einer Schleife bearbeitet, so dass wir das einfach an der Stelle einfügen können:


            foreach ($oList as $key => $oArticle) {
                $sFieldName = "oxarticles__{$sPwrSearchFld}";

                // formatting view
                if (!$myConfig->getConfigParam('blSkipFormatConversion')) {
                    if ($oArticle->$sFieldName->fldtype == "datetime") {
                        oxRegistry::get("oxUtilsDate")->convertDBDateTime($oArticle->$sFieldName);
                    } elseif ($oArticle->$sFieldName->fldtype == "timestamp") {
                        oxRegistry::get("oxUtilsDate")->convertDBTimestamp($oArticle->$sFieldName);
                    } elseif ($oArticle->$sFieldName->fldtype == "date") {
                        oxRegistry::get("oxUtilsDate")->convertDBDate($oArticle->$sFieldName);
                    }
                }

                $oArticle->pwrsearchval = $oArticle->$sFieldName->value;
                $oList[$key] = $oArticle;
                
                //Ab hier ist der Code eingefügt:
                //loading tags
                $oArticleTagList = oxNew("oxArticleTagList");
                $oArticleTagList->loadInLang($this->_iEditLang, $oArticle->getId());
                $oArticle->tags = "";
                foreach ($oArticleTagList->get() as $sTag){
                    $oArticle->tags .= $sTag . ", ";
                }
            }

Dabei wurde der Code ein wenig geändert, damit gleich ein fertig formatierter String anstatt eines Objekts in $oArticle->tags steht.

Dann kann man das ins Template einfügen:

<td valign="top" class="[{ $listclass}]"><div class="listitemfloating">[{ $listitem->tags }]</div></td>

und die Tags werden angezeigt. Jetzt noch das ganze als Modul mit Klasse erweitern und Blocks und fertig.

Mit den Tags hatte ich schon mal ausprobiert, aber leider aus der articel_main.tpl.

Ich habe das mal eingefügt, funktioniert aber noch nicht. Die php Datei ist noch nicht richtig. Ich finde da irgendwie kein Logik hinter.

Hier mal der php Code:

<?php

class mbm_article_list extends oxAdminList
{
protected $_sThisTemplate = 'mbm_article_list.tpl';

    public function render()
    {
        $ret = parent::render();

        // Hier der Code aus der Orginal php
         foreach ($oList as $key => $oArticle) {
                $sFieldName = "oxarticles__{$sPwrSearchFld}";

                // formatting view
                if (!$myConfig->getConfigParam('blSkipFormatConversion')) {
                    if ($oArticle->$sFieldName->fldtype == "datetime") {
                        oxRegistry::get("oxUtilsDate")->convertDBDateTime($oArticle->$sFieldName);
                    } elseif ($oArticle->$sFieldName->fldtype == "timestamp") {
                        oxRegistry::get("oxUtilsDate")->convertDBTimestamp($oArticle->$sFieldName);
                    } elseif ($oArticle->$sFieldName->fldtype == "date") {
                        oxRegistry::get("oxUtilsDate")->convertDBDate($oArticle->$sFieldName);
                    }
                }

                $oArticle->pwrsearchval = $oArticle->$sFieldName->value;
                $oList[$key] = $oArticle;

                //Ab hier ist der Code eingefügt:
                //loading tags
                $oArticleTagList = oxNew("oxArticleTagList");
                $oArticleTagList->loadInLang($this->_iEditLang, $oArticle->getId());
                $oArticle->tags = "";
                foreach ($oArticleTagList->get() as $sTag){
                    $oArticle->tags .= $sTag . ", ";
                }
            }
            //Hier endet der Code aus der Orginal php

        return $ret;
    }
   }

Hier mal ein Bild wie es momentan aussieht:

Wenn du den Code so direkt einfügst so wie ich ihn geposted hab funktioniert es. Probiere das mal zuerst und dann fang an Schritt für Schritt ein Modul daraus zu bauen. Beispielsweise:

<?php

class mbm_article_list extends oxAdminList
{
protected $_sThisTemplate = 'mbm_article_list.tpl';

ist falsch, du brauchst weder einen eigenen Controller noch ein komplettes eigenes Template, weil es beides für die Artikelliste schon gibt. Du musst also article_list.php erweitern (extends …_parent) und in article_list.tpl Blocks austauschen, das war’s.

Und das stimmt auch nicht:


    'extend'       => array(
        'article_list' 		=> 'mein_modul/mein_modul_title/controllers/article_list'
    ),

weil du hier eine Klasse mit einer Klasse erweitern willst, die den exakt gleichen Namen hat wie das Original. Am Ende der Zeile sollte also “mbm_article_list” stehen, die Datei sollte mbm_article_list.php heißen und mit

class mbm_article_list extends mbm_article_list_parent

anfangen.

Ja, das hatte ich zwischenzeitlich auch schon eingetragen. Das funktionierte nicht.
Dies jetzt auch nicht.

Ich will mal das Pferd andersrum aufzäunen. Und poste mal die mbm_article_list.php ohne deinen Code. Da muss ja der Fehler sein.

Alles was in rot ist, ist variabel (denke ich) Der Rest statisch. (muß also immer?)

<?php

class mbm_article_list extends mbm_article_list_parent
{
protected $_sThisTemplate = 'mbm_article_list.tpl';

    public function render()
    {
        $ret = parent::render();

        // Hier der Code aus der Orginal php
         
         
            //Hier endet der Code aus der Orginal php

        return $ret;
    }
   }

[QUOTE=Medicus;177577]Ja, das hatte ich zwischenzeitlich auch schon eingetragen. Das funktionierte nicht.
[/QUOTE]
Der Code funktioniert so wie ich ihn geposted habe. Versuche doch mal nicht 5 Dinge gleichzeitig zu machen sondern eins nach dem anderen. Schreib den Code in die original-Dateien bis es funktioniert. Dann mach ein Modul draus und die Änderungen in den original Dateien rückgängig, Schritt für Schritt.

Und lies Tutorials. Der Code den du jetzt gepostet hast, tut nichts außer dass er ein neues Template lädt. Du hast aber in der Metadata kein Template angegeben (“templates”-Array). Du musst auch gar kein neues Template laden weil an den Stellen die du ändern willst Block-Tags vorhanden sind, du kannst also Blöcke ersetzen (“blocks”-Array). Das hatte ich auch schon geschrieben:

du brauchst weder einen eigenen Controller noch ein komplettes eigenes Template,

Hallo Medicus,

schön das du meine Videos angeschaut hast. Mich würde interessieren, was dir daran nicht gefallen hat. Vielleicht kann ich es beim nächsten mal besser machen.

Zu deiner letzten Frage. Du brauchst nur das folgende als Basis:


<?php
class mbm_article_list extends mbm_article_list_parent
{
  
}

Die Methoden müssen nur aufgenommen werden, wenn du diese auch Erweitern möchtest.

Zu den Tags könntest du es z.B. so machen:


<?php
class mbm_article_list extends mbm_article_list_parent
{
    public function render()
    {
        $ret = parent::render();

        $oList = $this->getItemList();
        if ($oList)
        {
            $oArticleTagList = oxNew("oxArticleTagList");
            foreach ($oList as $key => $oArticle) {
                $oArticleTagList->loadInLang($this->_iEditLang, $oArticle->getId());
                $oArticle->tags = "";
                foreach ($oArticleTagList->get() as $sTag){
                    $oArticle->tags .= $sTag . ", ";
                }
                $oList[$key] = $oArticle;
            }
        }
        $this->_aViewData['mylist'] = $oList;

        return $ret;
    }
}

Mal die was grundlegendes, dies ist ja ein Anwender Forum in der Hauptsache. Das teilt sich auf in, die, die was machen möchten (mal schauen), die was machen wollen und anwenden (Coder) , und die die was können (Programmierer).

Ich bin (Coder).
So, das war der Grundsatz.

Mir geht es darum das grundsätzlich die meisten verstehen wie was funktioniert. Da haperst manchmal in auch in der Kommunikation zwischeneinander.
Also bitte nicht böse sein, wenn mal etwas kritikmäßig rüberkommt. ( Das sind bloß die Nerven)

Dieses Beispiel soll nur dazu dienen, grundsätzlich klarzustellen, wie man Datenbankinhalte im Backend anzeigen kann. Das Beispiel ist ein “nice to have”. Wenn alles funktioniert, stelle ich das ganze gern als Download bereit.

Den Rest beantworte ich gleich auch noch.

@mibexx

Ich habe jetzt nicht alle Teile deiner “Serie” gesehen, aber ich fand es vorallem für Anfänger gut und verständlich erklärt. Ich finde YT Videos auch gut. Bleib dabei, und danke für die Arbeit:)

@Medicus

[QUOTE=Medicus;177564]Kenne ich. Wie soll man durch ein schlechtes Video denn lernen?

Außerdem erweckt das in mir ungeahnte Wutgefühle. Leider kann ich nicht durch den Bildschirm greifen und den Typen schüttel. Vielleicht ein Video machen, in dem ich ihm vorschlage mal was zu schreiben?:smiley:

Aber trotzdem danke.[/QUOTE]

Diesen Beitrag finde ich völlig deplaziert. Wenn Du lieber Anleitungen liest als Videos schaust, schreibe welche oder mach es besser. Hier aber die Arbeit anderer schlecht zureden, ist völlig am Ziel vorbei.

@leofonic
Dein Code funktioniert leider nicht. Warum weiß ich noch nicht. Ich überprüfe noch.
Und für die Coder ist es immer wichtig., das ein Code komplett ist. Also in der .php Datei muß der Inhalt mindest ein <?php aufweisen. Ansonsten ist das nur text. (der versteht das sonst nicht :slight_smile: )

@mibexx
Dieser Code funktioniert.

Der erste Teil ist aus der article_list php.
Der zweite teil ist aus der article_main.php. Der ist bei @leofonic und @mibexx ähnlich.

Zum komplett funktionieren muss noch die Suche und Sortierung funktionierbar gemacht werden. Mal schauen.

Hier ist noch einmal der Grundcode und wie gehabt der rote Teil ist variabel.



 <?php
class mbm_article_list extends mbm_article_list_parent
{
    public function render()
    {
        $ret = parent::render();
  //Ab hier ist der Code eingefügt:
       
//Ab hier endet der Code eingefügte Code:

        return $ret;
    }
} 

@leofonic
http://forum.oxid-esales.com/showthread.php?t=39195#post177581

Das muss ich erst einmal durchlesen und nachvollziehen. Das der Fehler bei mir liegt, ist wohl offensichtlich. Trotzdem Danke für die Hilfe. Die auf jedem Fall auf fruchtbaren Boden fällt. :slight_smile:

@mibexx
http://forum.oxid-esales.com/showthread.php?t=39195#post177582
Zu deiner Frage zum Video.

Ich finde Videos grundsätzlich übel, eine Antipathie wenn du so magst.

Die Video Qualtität ist zu schlecht für mich, als das ich ich vernünftig Text erkenne. Das immer wieder, so geht es ,oh doch nicht, zurück, aber so, ist nicht wirklich professionell und zieht alles in die Länge.
Blöd ist ist auch das man mit Videos schlecht querlesen und Verständigungs arhythmik nicht von vom User angepasst werden kann. (Da kannst du aber nichts für)

Besser wäres Textbeiträge zu den Videos zu verfassen. Dann ist das Ziel erreicht.

[QUOTE=Medicus;177596]@leofonic
Dein Code funktioniert leider nicht. Warum weiß ich noch nicht. Ich überprüfe noch.
Und für die Coder ist es immer wichtig., das ein Code komplett ist. Also in der .php Datei muß der Inhalt mindest ein <?php aufweisen. Ansonsten ist das nur text. (der versteht das sonst nicht :slight_smile: )[/QUOTE]
Natürlich funktioniert der, das ist kein Modulcode. Den solltest du direkt in article_list.php einfügen, daher auch kein php-Tag, weil das natürlich nur der relevante Teil der ORIGINAL-Datei ist. Damit du verstehst, wie und warum man was ändern muss um die Tags überhaupt anzuzeigen. Der Code von mibexx ist absolut identisch nur per copy/paste in ein Modul eingefügt, also schon zwei Schritte weiter.

@leofonic
ich weiß nicht so genau ob ich dich richtig verstehe. Wenn ich deinen Code (pur und ohne zusatz) in die mbm_article_list.php einfüge und dann das Modul aktiviere, erscheint im Listframe meine Startseite. Das Mainframe ist unverändert.

Was habe ich da falsch gemacht?

[QUOTE=leofonic;177606]das ist kein Modulcode. Den solltest du direkt in article_list.php einfügen[/QUOTE]
Ohne Modul!

Ahh, jetzt verstehe ich. Ja das funktioniert.

Das so zusagen hardcoded. :slight_smile: Also nicht für das Modul, sondern um die Funktion an sich zu testen.
Übrigens, da fehlte ein } am Ende.

Lesen, verstehen, machen. Mindestens eins von den dreien habe ich nicht gemacht.:smiley:

Ja um den Entstehungsprozess zu zeigen:

  1. Nachschauen wie Tags angezeigt werden können in article_main.php
  2. Einfügen dieses Codes, der ja für einen einzelnen Artikel ist, in die bestehende Artikel-Schleife in article_list.php. So bekommt jeder Artikel die Property “tags”.
  3. Auslagern der Änderung in ein Modul. Um nicht die ganze Methode kopieren zu müssen, wird die Schleife aus article_list.php im Modul nachgebaut. So kann man erst parent::render() ausführen und dann den eigenen Code. Das ist dann der Code von mibexx.

Ich packe mal das Modul “Artikel Tags anzeigen” hier herein.

Die Suche der Tags und die Sortierung der Tags, sind im Quelltext ausgeklammert, weil nicht funktionsfähig.

Wer mag und kann, sollte das auch ändern. Es währe dann aber nett, dies dem Forum auch zur Verfügung zu stellen.