Reihenfolge der Directories mit addTemplateDir falsch

Hallo zusammen,

ich arbeite mich gerade in Shopware ein und versuche seit gestern verzweifelt, Plugins zum Laufen zu bringen. Genauer gesagt: Plugins, bei denen Templates erweitert werden. Ich habe schnell gemerkt, dass die Plugins an sich funktionieren und ich mich an Events dranhängen kann, nur sobald Templates erweitert werden sollten, ist einfach nichts passiert (keine Fehlermeldung, aber eben auch keine Template-Änderung).

Ich konnte den Fehler nun so weit zurückverfolgen, dass es an der Reihenfolge der Directories liegt, die in der Smarty-Variable template_dir liegen. Wenn ich das richtig verstanden habe, wird dieses Array von vorne durchlaufen und sobald ein Template-Match in einem entsprechenden Verzeichnis gefunden wurde, wird das Template verwendet. Heißt für mich: wenn ich ein Template erweitern möchte, muss mein Plugin-View-Verzeichnis VOR den regulären (Responsive/Bare)-View-Verzeichnissen in template_dir liegen.

Das ist aber nicht der Fall. Wenn ich ein Verzeichnis über

$view->addTemplateDir(
            __DIR__. 'Views'
        );

hinzufüge, wird es an letzter Stelle in template_dir abgelegt. Wenn ich händisch eingreife und die Position z.B. mit array_reverse tausche, sodass mein Plugin-Verzeichnis vorne liegt, funktioniert es! Aber es wird eben hinten angefügt. Und nicht nur bei den von mir erstellten Plugins, sondern bei allen Plugins, also auch den offiziellen von Shopware und weiteren Drittanbieter-Plugins.

Woran kann das liegen? Ich entwickel auf Windows 10 mit Zend Server CE, PHP 5.6.4 und MySQL Server 5.5. Shopware Version 5.1.6, wobei ich auch 5.1.0 und 5.2.6 ausprobiert habe und auch hier tritt der Fehler auf. Ich habe schon gelesen, dass Windows und Shopware sich nicht so vertragen. Meine Kollegen arbeiten jedoch mit der gleichen Entwicklungsumgebung und bei ihnen funktioniert alles reibungslos, ich bezweifle also, dass es daran liegt.

Hoffe, jemand kann mir weiterhelfen.

Viele Grüße
Malte :slight_smile:

Hi zusammen,

ok, anders gefragt: liegt es überhaupt daran, in welcher Reihenfolge die Templates in $template_dir liegen? Wenn ich die addTemplateDir() Methode aus der Enlight_Template_Manager Klasse: 

    /**
     * Add template directory(s)
     *
     * @param string|array $template_dir directory(s) of template sources
     * @param string $key of the array element to assign the template dir to
     * @param null $position
     * @return Smarty current Smarty instance for chaining
     */
    public function addTemplateDir($template_dir, $key = null, $position = null)
    {
        if (is_array($template_dir)) {
            foreach ($template_dir as $k => $v) {
                $this->addTemplateDir($v, is_int($k) ? null : $k);
            }
            return $this;
        }
        $_template_dir = $this->getTemplateDir();

        if ($position === self::POSITION_PREPEND) {
            if ($key === null) {
                array_unshift($_template_dir, $template_dir);
            } else {
                $_template_dir = array_merge(array($key => $template_dir), $_template_dir);
                $_template_dir[$key] = $template_dir;
            }
        } elseif ($key !== null) {
            $_template_dir[$key] = $template_dir;
        } else {
            $_template_dir[] = $template_dir;
        }

        $this->setTemplateDir($_template_dir);
        return $this;
    }

richtig deute, stimmt es, dass die addTemplateDir() im Plugin das Verzeichnis einfach hinten dran hängt. Beispiel:

Am Anfang sieht die $template_dir so aus:

Array
(
    [0] => MEIN_VERZEICHNIS\themes\Frontend\Responsive\
    [1] => MEIN_VERZEICHNIS\themes\Frontend\Bare\
)

Wenn ich jetzt im Plugin folgenden Code aufrufe:

$view->addTemplateDir(
            __DIR__. '\Views'
        );

wird zunächst die addTemplateDir() in der Enlight_View_Default-Klasse aufgerufen, die den Methodenaufruf einfach an die oben gezeigte Enlight_Template_Manager Klasse weiterdelegiert. Im Parameter $template_dir der addTemplateDir() Methode steht jetzt einfach ein String mit meinem neuen Verzeichnis. Die Überprüfung 

if (is_array($template_dir))

ist false, also wird die Abfrage übersprungen. Mit

$_template_dir = $this->getTemplateDir();

wird das aktuelle Template-Dir zwischengespeichert (das, was oben steht, also die zwei Verzeichnisse Responsive und Bare). Da keine $position angegeben ist, trifft auch die nächste if-Abfrage nicht zu, da der $key null ist, trifft auch der elseif-Part nicht zu. Bleibt nur 

$_template_dir[] = $template_dir;

womit mein neues Plugin-Verzeichnis einfach hinten im $_template_dir Array abgelegt ist und damit so aussieht:

Array
(
    [0] => MEIN_VERZEICHNIS\themes\Frontend\Responsive\
    [1] => MEIN_VERZEICHNIS\themes\Frontend\Bare\
    [2] => MEIN_VERZEICHNIS\engine\Shopware\Plugins\Community\Frontend\MEIN_PLUGIN\Views\
)

Oder habe ich da irgendwo einen Denkfehler?

Was ich jetzt nicht verstehe: wieso klappt das dann normalerweise? Laut der Smarty Template-Vererbung wird das $template_dir Array von vorne durchlaufen und stoppt, sobald es ein Match findet. Wenn er also in Responsive oder spätestens in Bare das Template findet, sucht es nicht weiter, stößt somit also gar nicht auf mein Plugin-Verzeichnis, geschweige denn auf meine dort hinterlegten Templates.

Wieso funktioniert das dann aber bei anderen? Wo in Shopware wird die Reihenfolge von $template_dir so verändert, dass doch zunächst die Plugin-Verzeichnisse durchsucht werden und erst dann die Basis-Template-Verzeichnisse? Das einzige, was ich in diese Richtung gefunden habe, sind die protected $injectBeforePlugins Attribute in den Theme.php Dateien, die bei mir aber auch keine Auswirkung haben.

Also kurzum, kann mir jemand verraten, wieso das trotzdem funktioniert? :smiley:

Viele Grüße
Malte

Zeig doch mal eines deiner Template, das du einbindest.

Viele Grüße

z.B. das Template aus dem Demo-Plugin aus der Dev-Doku:

{extends file="parent:frontend/index/index.tpl"}

{block name="frontend_index_navigation_categories_top_include" prepend}

    
        .slogan-box {
            width:100%;
            text-align:center;
        }
        .slogan {
            {if $italic}font-style:italic;{/if}
            font-size:{$sloganSize}px;
        }
    


    
        {$slogan}
    
{/block}

Tritt aber wie geschrieben bei allen Plugins auf, die ein Template erweitern/verändern wollen.

Wenn ich das richtig gesehen habe, ist die $injectBeforePlugins Variable nur für JS und Less, dürfte damit also nichts zu tun haben. Ich hab jetzt die Inheritance Klasse in den Theme-Komponenten entdeckt, so richtig komme ich da auch nicht weiter. Die Sache ist ja auch, dass ich nicht denke, dass es an Shopware selbst liegt, weil der Fehler über alle drei getesteten Shopware-Versionen hinweg auftaucht. An meiner Entwicklungsumgebung dürfte es aber eigentlich auch nicht liegen, weil die Kollegen die gleiche nutzen. Sehr, sehr merkwürdig :confused:

Mit prepend gibt es unerwartete Probleme, wenn der gleiche block mehrfach erweitert wird.

Probier mal:

{block name=“frontend_index_navigation_categories_top_include”}
    // … dein template

    // den parent einfügen
    {$smarty.block.parent}
{/block}

Viele Grüße

Danke für den Tipp, hat leider nichts gebracht.

Und es tritt ja wie gesagt bei allen Plugins auf. Auch bei den offiziellen von Shopware. Und dies war jetzt ja auch aus dem Shopware Developer Guide, da sollte man ja eig. annehmen, dass das funktioniert. :confused:

Okay, es muss an der Entwicklungsumgebung liegen. Lokal unter Windows mit Zend Server 5.6, verschiedenen PHP-Versionen und MySQL Server 5.5 funktioniert es nicht. Über eine Ubuntu-VM funktioniert es sofort, mit den gleichen Shopware-Dateien, die unter Windows nicht liefen (gleiches Verzeichnis). Also, falls jemand das gleiche Problem hat: ich weiß zwar nicht, WARUM es diesen Fehler unter Windows gibt, aber unter einer Linux-Entwicklungsumgebung kriegt ihr es zum Laufen.

Viele Grüße
Malte

Hallo zusammen,

 

auch ich versuche mich gerade in Shopware einzuarbeiten und habe das beschriebene Problem…

Gibt es eine Lösung?

Ich verwende eine ganz einfache Umgebung zum Testen:

 

XAMPP v3.2.2
Die Dateien modifiziere ich gerade einfach aus dem Explorer heraus. Der Shop läuft und das Backend auch…

 

Aber: Die Slogans werden nicht angezeigt…

 

Viele Grüße

 

HeimArt

 

Edit: Jetzt habe ich gerade gesehen, dass sich das Plugin-System mit Version 5.2 geändert hat… Liegt es vielleicht daran? Ich nutze Shopware 5.2.21…