Listenansicht einer Kategorie um Anzeigefeld erweitern

Hallo Zusammen,

ich besitze grundlegende HTML, PHP, mySQL und Bootstrap Kenntnisse und passe meinen Onlineshop (Vers. 4.10.3) gerade in meiner Testumgebung an.
Nun möchte ich, wie in der Überschrift beschrieben, In der Listenansicht von Artikeln einer Kategorie links vom Artikelfoto die Zahl des Feldes OXSPOS aus der Tabelle oxobject2category mit anzeigen.
Ich habe die listitem_line.tpl auch schnell ausgemacht und mir ist dieser Blockaufbau auch soweit klar, was ich aber nun nicht weiß ist:
Wie gehe ich da jetzt ran, um diese Information aus der Tabelle zu ziehen?

Bei einer SQL Abfrage mach ich einen select mit einem leftjoin und schwupps habe ich die benötigte verknüpfte Information.

Ich möchte auch keine fertige Lösung für diesen Block Inhalt, den ich in der tpl ergänzen muss, mir geht es um die Logik bzw. Vorgehensweise.

Die tpl müsste ich ja hier ergänzen, gleich nach dem DIV mit der Klasse row:

<div class="row">
    <div class="col-xs-12 col-sm-2">
      <div class="picture">
        [{block name="widget_product_listitem_line_picturebox"}]
        <a id="[{$testid}]" href="[{$_productLink}]" title="[{$product->oxarticles__oxtitle->value}] [{$product->oxarticles__oxvarselect->value}]">
          <img src="[{$oViewConf->getImageUrl('spinner.gif')}]" data-src="[{$product->getThumbnailUrl()}]" alt="[{$product->oxarticles__oxtitle->value}] [{$product->oxarticles__oxvarselect->value}]" class="img-responsive">
        </a>
        [{/block}]
      </div>
    </div>
    <div class="col-xs-6 col-sm-4">
      [{block name="widget_product_listitem_line_titlebox"}]
      <div class="title">
        <a id="[{$testid}]" href="[{$_productLink}]" title="[{$product->oxarticles__oxtitle->value}] [{$product->oxarticles__oxvarselect->value}]">[{$product->oxarticles__oxtitle->value}] [{$product->oxarticles__oxvarselect->value}]</a>
      </div>
      [{/block}]

      [{block name="widget_product_listitem_line_description"}]
      <div class="description">
        [{if $recommid}]
        <p>[{$product->text}]</p>
        [{else}]
        [{oxhasrights ident="SHOWSHORTDESCRIPTION"}]
        [{$product->oxarticles__oxshortdesc->rawValue}]
        [{/oxhasrights}]
        [{/if}]
      </div>
      [{/block}]

Es werden ja vorab in der Datei die Variablen deklariert, z.B.:

[{assign var="product"         value=$oView->getProduct()}]

Und dann im Block entsprechend die Informationen angezeigt.

Aber woher weiß ich jetzt, wie ich mir den select für OXPOS zusammenbaue?
Oder andersrum gefragt: wie ist der Weg von der DB-Tabelle in die tpl?

Viele Grüße
Thomas

Man müsste jetzt den Weg “nur” aus dem Template in die Datenbank zurückverfolgen, etwa so;

  1. im Kategorien-Template list.tpl werden die Produkte über diese Ffunktion geladen:
$oView->getArticleList()
  1. “getArticleList” finden wir in alist.php, dort steht dann
$this->_loadArticles($oCategory);
  1. _loadArticles verweist uns auf
$oArtList->loadCategoryArticles($sActCat, $aSessionFilter);
  1. in oxArticleList::loadCategoryArticles() findet man
$sSelect = $this->_getCategorySelect($sArticleFields, $sCatId, $aSessionFilter);
  1. und in _getCategorySelect findet man endlich SQL Query
        $sSelect = "SELECT $sFields, $sArticleTable.oxtimestamp FROM $sO2CView as oc left join $sArticleTable
                    ON $sArticleTable.oxid = oc.oxobjectid
                    WHERE " . $this->getBaseObject()->getSqlActiveSnippet() . " and $sArticleTable.oxparentid = ''
                    and oc.oxcatnid = " . $oDb->quote($sCatId) . " $sFilterSql ORDER BY $sSorting oc.oxpos, oc.oxobjectid ";
  1. und weil oxobject2category bereits als “oc” im der Query vorhanden ist, müssen wir nur noch oc.oxpos in die Liste der Felder aufnehmen

  2. und schwuppdiwupp zeigt vardump oxpos Feld an:

["oxarticles__oxpos"]=>
  object(oxField)#533 (1) {
    ["rawValue"]=>
    string(1) "0"
  }

das wars :wink:

Hi Vanilla,

dank Dir für die Hilfestellung. Ich will das gerade mal nachvollziehen, also hab ich den Debug-Modus auf 8 gestellt und möchte mal eben sicher gehen, dass wir beide die gleiche list.tpl meinen, Du schreibst:

1) im Kategorien-Template list.tpl werden die Produkte über diese Ffunktion geladen:
PHP Code:
$oView->getArticleList()  

Aha, also bei mir müsste das ja dann die “views/flow/tpl/widget/product/list.tpl” sein.
Wenn ich die öffne, zeigt der Code:

[{if !$type}]
    [{assign var="type" value="infogrid"}]
[{/if}]

[{if !$iProductsPerLine}]
    [{assign var="iProductsPerLine" value=4}]
[{/if}]

[{if $type == 'infogrid'}]
    [{assign var="iProductsPerLine" value=2}]
[{elseif $type == 'grid'}]
    [{assign var="iProductsPerLine" value=4}]
[{elseif $type == 'line'}]
    [{assign var="iProductsPerLine" value=1}]
[{/if}]

<div class="boxwrapper" id="boxwrapper_[{$listId}]">
    [{if $head}]
        [{if $header == "light"}]
            <div class="page-header">
                <span class="h3">[{$head}]</span>

                [{if $subhead}]
                    <small class="subhead">[{$subhead}]</small>
                [{/if}]
            </div>
        [{else}]
            <div class="page-header">
                <h2>
                    [{$head}]
                    [{if $rsslink}]
                        <a class="rss" id="[{$rssId}]" href="[{$rsslink.link}]" target="_blank">
                            <i class="fa fa-rss"></i>
                        </a>
                    [{/if}]
                </h2>

                [{if $subhead}]
                    <small class="subhead">[{$subhead}]</small>
                [{/if}]
            </div>
        [{/if}]
    [{/if}]

    [{assign var="productsCount" value=$products|@count}]
    [{if $productsCount gt 0}]
        [{math equation="x / y" x=12 y=$iProductsPerLine assign="iColIdent"}]

        <div class="list-container" id="[{$listId}]">
            [{foreach from=$products item="_product" name="productlist"}]
                [{counter print=false assign="productlistCounter"}]
                [{assign var="testid" value=$listId|cat:"_"|cat:$smarty.foreach.productlist.iteration}]

                [{if $productlistCounter == 1}]
                    <div class="row [{$type}]View newItems">
                [{/if}]

                <div class="productData col-xs-12[{if $type != 'line'}] col-sm-6 col-md-[{$iColIdent}][{/if}] productBox">
                    [{oxid_include_widget cl="oxwArticleBox" _parent=$oView->getClassName() nocookie=1 _navurlparams=$oViewConf->getNavUrlParams() iLinkType=$_product->getLinkType() _object=$_product anid=$_product->getId() sWidgetType=product sListType=listitem_$type iIndex=$testid blDisableToCart=$blDisableToCart isVatIncluded=$oView->isVatIncluded() showMainLink=$showMainLink recommid=$recommid owishid=$owishid toBasketFunction=$toBasketFunction removeFunction=$removeFunction altproduct=$altproduct inlist=$_product->isInList() skipESIforUser=1 testid=$testid}]
                </div>

                [{if $productlistCounter%$iProductsPerLine == 0 || $productsCount == $productlistCounter}]
                    </div>
                [{/if}]

                [{if $productlistCounter%$iProductsPerLine == 0 && $productsCount > $productlistCounter}]
                    <div class="row [{$type}]View newItems">
                [{/if}]
            [{/foreach}]

            [{* Counter resetten *}]
            [{counter print=false assign="productlistCounter" start=0}]
        </div>
    [{/if}]
</div>

Da finde ich keine Funktion "$oView->getArticleList()"
Oder sehe ich den Wald vor lauter Bäumen nicht?

Ich habe ein Template höher angefangen: list.tpl unter pages/ und nicht widgets/

Gesendet von meinem SM-G920F mit Tapatalk

Jep, vielen Dank dafür.
Ganz ehrlich: Wie Du Dich da mal eben fix durchorientiert hast, das schnall ich nicht so auf Anhieb.
Ich glaube, mir fehlen doch noch einige grundlegende Kenntnisse vom ganzen Framework und dem Entwurfsmuster MVC.
Da ich das aber gerne lernen möchte, frage ich hiermit mal an, welche Literatur Du noch empfehlen würdest? Das OXID-Kochbuch besitze ich, aber da finde ich auch keine detaillierten Erklärungen zur Struktur.
Ich muss mich wohl noch viel intensiver mit PHP und auch SMARTY beschäftigen, damit kleine Anpassungen nicht in endlosen Suchen hier im Forum enden.

Viele Grüße
Thomas

Richtige Werkzeuge erleichtern die Arbeit bei solchen Sachen, z.b. wenn man eine anständige IDE (Entwicklungsumgebung) hat, kann man mit einem Hotkey die Liste aller list.tpl aufrufen oder per einen einzigen Klick auf den Funktionsnamen die Klasse, wo diese Funktion definiert wurde, aufrufen und auch zu der Funktion springen. Ohne IDE wäre es schon mal 4-5 Minuten Suchen, Navigieren und Vergleichen.
Und zum Anderen entwickelt man mit der Zeit auch ein Gespür um den Sinn und Zweck von Funktionen anhand deren Namen zu erkennen. Die Namen sind zum Glück sehr aussagekräftig.

So richtige Literatur gibts zu OXID nicht wirklich.
Hier entsteht gerade ein bisschen was:
http://oxid-eshop-developer-documentation.readthedocs.io/en/latest/
und sonst
https://oxidforge.org/de/ + dort verlinkte Blogs.

[QUOTE=vanilla thunder;186818]Man müsste jetzt den Weg “nur” aus dem Template in die Datenbank zurückverfolgen, etwa so;

  1. im Kategorien-Template list.tpl werden die Produkte über diese Ffunktion geladen:
$oView->getArticleList()
  1. “getArticleList” finden wir in alist.php, dort steht dann
$this->_loadArticles($oCategory);
  1. _loadArticles verweist uns auf
$oArtList->loadCategoryArticles($sActCat, $aSessionFilter);
  1. in oxArticleList::loadCategoryArticles() findet man
$sSelect = $this->_getCategorySelect($sArticleFields, $sCatId, $aSessionFilter);
  1. und in _getCategorySelect findet man endlich SQL Query
        $sSelect = "SELECT $sFields, $sArticleTable.oxtimestamp FROM $sO2CView as oc left join $sArticleTable
                    ON $sArticleTable.oxid = oc.oxobjectid
                    WHERE " . $this->getBaseObject()->getSqlActiveSnippet() . " and $sArticleTable.oxparentid = ''
                    and oc.oxcatnid = " . $oDb->quote($sCatId) . " $sFilterSql ORDER BY $sSorting oc.oxpos, oc.oxobjectid ";
  1. und weil oxobject2category bereits als “oc” im der Query vorhanden ist, müssen wir nur noch oc.oxpos in die Liste der Felder aufnehmen

  2. und schwuppdiwupp zeigt vardump oxpos Feld an:

["oxarticles__oxpos"]=>
  object(oxField)#533 (1) {
    ["rawValue"]=>
    string(1) "0"
  }

das wars ;)[/QUOTE]

Wie meinst Du das genau?

  1. und weil oxobject2category bereits als “oc” im der Query vorhanden ist, müssen wir nur noch oc.oxpos in die Liste der Felder aufnehmen

Denn [{$product->oxarticles__oxpos->value}] zeigt mir den Wert nicht an

Gruß
Thomas

Bei mir funktioniert es. Wurde tmp/ geleert?

Yes Sir, tmp wurde geleert, so sieht das integrierte DIV aus:

<div class=“col-xs-1 col-sm-1”>
[{block name=“widget_product_listitem_line_titlebox”}]
[{$product->oxarticles__oxpos->value}]
[{/block}]
</div>

Ich habe ein ChildTheme auf Basis flow erstellt und nur die listitemline.tpl kopiert und angepasst, müssen evtl. noch mehr tpl´s ins Child?

>> Nachtrag: auch im parent flow getestet: wird nicht angezeigt, irgendetwas muss noch fehlen.

versuch mal mit rawValue statt value. oder ggf rawValue()
Ich habe vorhin angefangen meinen Dev-Server neuzuinstallieren, kann selbst leider nicht mehr testen

ne, funktioniert beides nicht.
Wenn ich

<div class="col-xs-1 col-sm-1">
[{block name="widget_product_listitem_line_titlebox"}]
[{$product->oxarticles__oxid->value}]
[{/block}]
</div>

eingebe, zeigt er mir die ID des Artikels an, das klappt ja.

Ich hab ansonsten ja nichts gemacht, außer diesen Schnipsel eingebaut, muss ich evtl. noch irgendwo etwas anderes ergänzen?

In #2 5) fehlt was, wenn ich das richtig sehe:

SELECT $sFields, $sArticleTable.oxtimestamp, [B]oc.oxpos[/B] FROM $sO2CView as oc left join $sArticleTable
                    ON $sArticleTable.oxid = oc.oxobjectid
                    WHERE " . $this->getBaseObject()->getSqlActiveSnippet() . " and $sArticleTable.oxparentid = ''
                    and oc.oxcatnid = " . $oDb->quote($sCatId) . " $sFilterSql ORDER BY $sSorting oc.oxpos, oc.oxobjectid

das steht unter Punkt 6 :wink:

Yeahhh, rubbercut, das war eine Punktlandung, wenn ich den Select mit oc.oxpos ergänze klappt es, so wie ich es mir wünsche.
Wenn Vanilla das so meinte mit der Ergänzung im Select, hab ich das nicht gepeilt, sorry.
Ich dachte, der Select wäre bereits vollständig mit

SELECT $sFields......FROM $sO2CView as oc....

. Ich war der Meinung, dass die oxpos bereits in $sFields berücksichtigt wird.

Jetzt haut es hin, besten Dank.

Gruß
Thomas

[QUOTE=vanilla thunder;187195]das steht unter Punkt 6 ;)[/QUOTE]

Das stimmt, aber was sollte es anders sein? :rolleyes: