Ergebnis 1 bis 13 von 13

Thema: Datenbankabfrage aus FE-Template heraus

  1. #1
    Contao-Fan Avatar von Hendriks
    Registriert seit
    28.08.2009.
    Ort
    Stuttgart
    Beiträge
    275

    Frage Datenbankabfrage aus FE-Template heraus

    Hallo Kollegen.

    Ich weiss, Datenbankabfragen im Template sind nicht "Best Practice"; sind für gewisse "Kleinigkeiten" aber ganz praktisch und ok, denke ich...

    Unter Contao 3.0 klappten beispielsweise im Template ce_accordion noch Abfragen wie:

    PHP-Code:
    $this->import('Database');

    $nextAccordion $this->Database->prepare ("SELECT sorting FROM tl_content WHERE type = 'accordion' AND pid = ? AND sorting > ? AND invisible = 0")
                                    ->
    execute ($this->pid$this->sorting);

    $elements $this->Database->prepare ("SELECT headline FROM tl_content WHERE type != 'accordion' AND type != 'module' AND pid = ? AND sorting > ? AND sorting < ? AND invisible = 0 ORDER BY sorting")
                               ->
    execute ($this->pid$this->sorting$nextAccordion->sorting); 
    Hat sich da bis zur aktuellen Version 3.4. was geändert!?

    Oder woran könnte es ggf. noch liegen, dass das nun nicht mehr bei mir klappt?

    Mein konkretes Ziel ist es gerade, für einen custom Slider, diesmal im Artikel-Template, "lediglich" die Überschriften (headlines) der enthaltenenen Inhaltselemente abzufragen, um z.B. noch vor <?php echo implode('', $this->elements); ?> ein zusätzliches "Skip-Link-Menü" einfügen zu können!

    Man möge mir nachsehen, wenn ich hier vll. gerade Tomaten auf den Augen habe, oder in der jüngsten Weiterentwicklung von Contao 3 etwas verpasst haben sollte...

    Oder wie würde man diese Anforderung sonst am besten (und gleichzeitig unkompliziertesten) lösen?

    Jeder Hinweis ist willkommen. Danke!

  2. #2
    Contao-Urgestein Avatar von the_scrat
    Registriert seit
    24.02.2010.
    Ort
    Augsburg
    Beiträge
    2.051
    User beschenken
    Wunschliste

    Standard

    Hallo,

    normal müsste die DB Abfrage weiterhin im Template möglich sein.
    Probier doch mal statt $this->import und $this->Database folgendes

    PHP-Code:
    \Database::getInstance()->prepare(....)->execute(); 
    Programmers don't comment their code. It was hard to write, it should be hard to understand...

  3. #3
    Contao-Fan Avatar von Hendriks
    Registriert seit
    28.08.2009.
    Ort
    Stuttgart
    Beiträge
    275

    Standard

    Danke für den Tipp, klappt so aber leider auch nicht...

    Ich habe gerade keinen direkten Zugriff auf die error.log; doch als ich es mit meiner oben gezeigten Variante probiert hatte, kam auf jeden Fall folgende Fehlermeldung:

    Code:
    PHP Fatal error: Uncaught exception 'Exception' with message 'Too few arguments to build the query string' thrown in /var/www/html/cms/contao/3-04-00/system/modules/core/library/Contao/Database/Statement.php on line 332
    ...wenn das ein Hinweis ist...?

    EDIT: Mein oben gepostetes Statement in der Abfrage ist doch syntaktisch und inhaltlich einwandfrei, oder?!
    Geändert von Hendriks (15.12.2014 um 12:44 Uhr)

  4. #4
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.116
    Partner-ID
    10107

    Standard

    Zitat Zitat von Hendriks Beitrag anzeigen
    Danke für den Tipp, klappt so aber leider auch nicht...

    Ich habe gerade keinen direkten Zugriff auf die error.log; doch als ich es mit meiner oben gezeigten Variante probiert hatte, kam auf jeden Fall folgende Fehlermeldung:

    Code:
    PHP Fatal error: Uncaught exception 'Exception' with message 'Too few arguments to build the query string' thrown in /var/www/html/cms/contao/3-04-00/system/modules/core/library/Contao/Database/Statement.php on line 332
    ...wenn das ein Hinweis ist...?

    EDIT: Mein oben gepostetes Statement in der Abfrage ist doch syntaktisch und inhaltlich einwandfrei, oder?!
    Poste nochmal dein gesamtes Template, oder zumindest den relevanten Teil.

  5. #5
    Contao-Fan Avatar von Hendriks
    Registriert seit
    28.08.2009.
    Ort
    Stuttgart
    Beiträge
    275

    Standard

    Na gerne doch :-)

    Jetzt stelle ich mir das so im mod_article vor:

    PHP-Code:
    <?php

    \Database::getInstance()
        ->
    prepare ("SELECT headline AS headline FROM tl_content WHERE pid = ? AND type != 'module' AND sorting > ? AND invisible = 0 ORDER BY sorting")
        ->
    execute ($this->id);

    while (
    $elements->next()) {

        
    $arrHeadlines[] = $elements->headline;
    }

    $amount count($arrHeadlines);

    ?>
    <?php 
    if (strpos($this->class,"labeled tabbed group")!==false): ?>

    <div class="<?php echo $this->class?>"<?php echo $this->cssID?><?php if ($this->style): ?> style="<?php echo $this->style?>"<?php endif; ?>>
    <?php if (strpos ($this->class"tabbed") !== false): ?>

    <?php $i 1; foreach ($arrHeadlines as $headline): ?>
    <input id="i<?php echo $i?>" name="slides" type="radio"<?php if ($i == 1): ?> checked="checked"<?php endif; ?> />
    <?php $i ++; endforeach; ?>
    <?php 
    endif; ?>

    <div class="labels nav block"></div>

    <?php $i 1; foreach ($arrHeadlines as $headline): ?>
    <label for="i<?php echo $i?>" id="a<?php echo $i?>" onmouseover="click()"><?php echo $headline?></label><br />
    <?php $i ++; endforeach; ?>

    <div class="pointer"><div class="point"></div></div>

    <div class="slider">
    <?php endif; ?>
    <?php 
    echo implode(''$this->elements); ?>
    <?php 
    if (strpos($this->class,"labeled tabbed group")!==false): ?>

    </div>

    <div class="pages nav block" id="subpages">

    <p class="widget">
    <?php $i 1; foreach ($arrHeadlines as $headline): ?>
    <span><label for="i<?php echo $i?>"></label></span>
    <?php $i ++; endforeach; ?>
    </p>

    </div>

    </div>

    <?php endif; ?>
    <?php 
    if ($this->backlink): ?>

    <div class="back nav item" id="mainback">

    <h2><?php echo $GLOBALS['LD']['nav']['back']['mainback']['headline']; ?></h2>

    <p class="widget">
    <span class="back unit"><span class="aux">< </span><a class="back" title="<?php echo $GLOBALS['LD']['nav']['back']['mainback']['title']; ?>" href="<?php echo $this->backlink?>"><?php echo $GLOBALS['LD']['nav']['back']['mainback']['link']; ?></a></span>
    </p>

    </div>
    <?php endif; ?>

  6. #6
    Contao-Urgestein Avatar von the_scrat
    Registriert seit
    24.02.2010.
    Ort
    Augsburg
    Beiträge
    2.051
    User beschenken
    Wunschliste

    Standard

    Auf den ersten Blick schon, ich konnte jetzt keinen Fehler erkennen.
    Zumindest kommt die Fehlermeldung von der DB Abfrage, was schonmal heißt, dass die jetzt funktioniert.

    Ansonsten sagt die Fehlermeldung, dass wohl noch etwas nicht ganz richtig läuft. Da musst du jetzt einfach per try&error durch.

    Kommentier die 2. Abfrage mal aus => teste die 1. und schau was dabei rumkommt.

    Edit: die Leerzeichen hinter prepare () und execute () sind die so in deiner Abfrage? Ich würd das mal direkt dranhängen also prepare() und execute()
    Programmers don't comment their code. It was hard to write, it should be hard to understand...

  7. #7
    Contao-Urgestein Avatar von the_scrat
    Registriert seit
    24.02.2010.
    Ort
    Augsburg
    Beiträge
    2.051
    User beschenken
    Wunschliste

    Standard

    PHP-Code:

    \Database::getInstance() 
        ->
    prepare ("SELECT headline AS headline FROM tl_content WHERE pid = ? AND type != 'module' AND sorting > ? AND invisible = 0 ORDER BY sorting"
        ->
    execute ($this->id); 
    Na das kann ja nicht funktionieren, du hast in deiner Abfrage 2x einen Platzhalter (?) drin, im execute() ist aber nur 1x die $this->id.... da fehlt noch der Wert für "sorting"
    Programmers don't comment their code. It was hard to write, it should be hard to understand...

  8. #8
    Contao-Fan Avatar von Hendriks
    Registriert seit
    28.08.2009.
    Ort
    Stuttgart
    Beiträge
    275

    Standard

    Cool! Es klappt wieder! Danke für Eure Hilfe!

    Das "sorting" muss ich hier gar nicht berücksichtigen => habe ich ganz raus genommen.

    Und dann hatte ich auf die Eile gerade auch noch die wichtigste Variable im Code vergessen:

    PHP-Code:
    $elements 
    Hier nochmal der korrigierte, funktionierende Code meines mod_article Templates am Stück:

    PHP-Code:
    <?php

    $elements 
    = \Database::getInstance()->prepare ("SELECT headline AS headline FROM tl_content WHERE pid = ? AND type != 'module' AND invisible = 0 ORDER BY sorting")
                                        ->
    execute ($this->id);

    while (
    $elements->next()) {

        
    $arrHeadlines[] = $elements->headline;
    }

    $amount count($arrHeadlines);

    ?>
    <?php 
    if (strpos($this->class,"labeled tabbed group")!==false): ?>

    <div class="<?php echo $this->class?>"<?php echo $this->cssID?><?php if ($this->style): ?> style="<?php echo $this->style?>"<?php endif; ?>>
    <?php if (strpos ($this->class"tabbed") !== false): ?>

    <?php $i 1; foreach ($arrHeadlines as $headline): ?>
    <input id="i<?php echo $i?>" name="slides" type="radio"<?php if ($i == 1): ?> checked="checked"<?php endif; ?> />
    <?php $i ++; endforeach; ?>
    <?php 
    endif; ?>

    <div class="labels nav block"></div>

    <?php $i 1; foreach ($arrHeadlines as $headline): $line deserialize($headline); $lineFinal is_array($line) ? $line['value'] : $line?>
    <label for="i<?php echo $i?>" id="a<?php echo $i?>" onmouseover="click()"><?php echo $lineFinal?></label><br />
    <?php $i ++; endforeach; ?>

    <div class="pointer"><div class="point"></div></div>

    <div class="slider">
    <?php endif; ?>
    <?php 
    echo implode(''$this->elements); ?>
    <?php 
    if (strpos($this->class,"labeled tabbed group")!==false): ?>

    </div>

    <div class="pages nav block" id="subpages">

    <p class="widget">
    <?php $i 1; foreach ($arrHeadlines as $headline): ?>
    <span><label for="i<?php echo $i?>"></label></span>
    <?php $i ++; endforeach; ?>
    </p>

    </div>

    </div>

    <?php endif; ?>
    <?php 
    if ($this->backlink): ?>

    <div class="back nav item" id="mainback">

    <h2><?php echo $GLOBALS['LD']['nav']['back']['mainback']['headline']; ?></h2>

    <p class="widget">
    <span class="back unit"><span class="aux">< </span><a class="back" title="<?php echo $GLOBALS['LD']['nav']['back']['mainback']['title']; ?>" href="<?php echo $this->backlink?>"><?php echo $GLOBALS['LD']['nav']['back']['mainback']['link']; ?></a></span>
    </p>

    </div>
    <?php endif; ?>
    PS: Was haltet Ihr generell von so einer Art Lösung? Ok? Oder, wie sollte man so etwas Lehrbuch-mäßig anders/besser lösen?

  9. #9
    Contao-Urgestein Avatar von the_scrat
    Registriert seit
    24.02.2010.
    Ort
    Augsburg
    Beiträge
    2.051
    User beschenken
    Wunschliste

    Standard

    Cool! Na dann passts ja


    Zitat Zitat von Hendriks Beitrag anzeigen
    PS: Was haltet Ihr generell von so einer Art Lösung? Ok? Oder, wie sollte man so etwas Lehrbuch-mäßig anders/besser lösen?
    Nö, für den Fall passt die "Lösung". Ist halt ne Quick&Dirty, aber absolut ok. Wenn du die Lösung 100x im System brauchst, wäre ein richtiges Modul besser, aber für den Einzelfall kann man auch die DB Abfrage mal ins Template klopfen. Würde ich auch so machen.

    Fürs Protokoll:
    Die optimale Lösung wäre natürlich die ModuleArticle zu erweitern (über ein eigenes Modul), in diesem Modul die Abfrage zu erledigen und die Werte dann ans Template weiterzureichen. Somit wäre halt Template und Logik getrennt.
    Geändert von the_scrat (15.12.2014 um 13:11 Uhr)
    Programmers don't comment their code. It was hard to write, it should be hard to understand...

  10. #10
    Contao-Fan Avatar von Hendriks
    Registriert seit
    28.08.2009.
    Ort
    Stuttgart
    Beiträge
    275

    Standard

    Zitat Zitat von the_scrat Beitrag anzeigen
    Nö, für den Fall passt die "Lösung". Ist halt ne Quick&Dirty, aber absolut ok. Wenn du die Lösung 100x im System brauchst, wäre ein richtiges Modul besser, aber für den Einzelfall kann man auch die DB Abfrage mal ins Template klopfen. Würde ich auch so machen.
    Na, das tut mir jetzt auch mal gut zu hören (von einem, der wohl auch schon ne Weile bei Contao ist, und "Code rumschiebt".. ;-)!
    Geändert von Hendriks (15.12.2014 um 13:14 Uhr)

  11. #11
    Contao-Fan Avatar von Hendriks
    Registriert seit
    28.08.2009.
    Ort
    Stuttgart
    Beiträge
    275

    Standard

    Der Performance dürfte das doch eigentlich keinen Abbruch tun? Schon erst recht, wenn die Caches großzügig aktiviert sind, oder!?

  12. #12
    Contao-Urgestein Avatar von the_scrat
    Registriert seit
    24.02.2010.
    Ort
    Augsburg
    Beiträge
    2.051
    User beschenken
    Wunschliste

    Standard

    Also generell sollte die Performance davon nicht beeinträchtigt werden, die Abfrage würde ansonsten vom Modul übernommen werden und bleibt somit gleich.

    Jetzt muss ich aber noch kurz nachfragen, du hast dir das Template erstellt und wählst dieses aus, wo du das accordion hast, richtig? Ansonsten würde deine Abfrage ja bei jedem Artikel ausgeführt, ob der nun ein Accordion hat oder nicht und das wäre dann eher schlecht.
    Programmers don't comment their code. It was hard to write, it should be hard to understand...

  13. #13
    Contao-Fan Avatar von Hendriks
    Registriert seit
    28.08.2009.
    Ort
    Stuttgart
    Beiträge
    275

    Standard

    Wen's interessiert:

    1) Vorgabe:

    Ich benötigte eine (für Redakteure flexibel anwendbare) Slider-Lösung auf Inhaltselement-Basis; jedoch noch unter Contao 2.11

    genau so, wie sie ja nun in Contao 3.4 mittlerweile wunderbar integriert wurde!

    ...bis auf die Tatsache, dass die Entwickler in ihren Slider-Templates wohl bisher (noch) nicht die "Tabbed Content"- oder "Karteikarten-Reiter"-Variante berücksichtigt haben, die ja i.d.R. zusätzliche "Skip-Nav"-Blöcke (z.B. mit den Headlines der enthaltenen Inhaltselemente als Labels) benötigen!

    Habe dazu schon einen Feature-Request erstellt: https://github.com/contao/core/issues/7505

    2) Lösung:

    Da sich das Website-Konzept mittlerweile aber dahingehend herauskristallisiert hat, dass z.B. alle Produkt-Detail-Unterseiten tatsächlich jeweils immer nur genau aus einem einzigen "Tabbed Content"-Artikel (in dem also quasi jedes Inhaltselement automatisch eine "Karteikarte" ist) bestehen, habe ich mir gedacht, dass diese Artikel ohne die 2 zusätzlichen "Slider"-Umschlag-Inhaltselemente für die Redakteure doch viel "kugelsicherer" und auch übersichtlicher sind.

    Mit

    PHP-Code:
    <?php if (strpos($this->class,"labeled tabbed group")!==false): ?>
    füge ich nun direkt im mod_article Haupt-Template den als solchen klassifizierten Artikeln die benötigten (den Inhaltselementen vor und nachgestellten) Umschlag-Komponenten für diese speziellen "Tabbed Content"-Seiten hinzu...

    Einfach und gut! Oder?

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Lesezeichen

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •