LESS-Files von Plugins überschreiben/erweitern

kam von hier: ankundigungen-und-news-f17/5-0-0-release-candidate-veroffentlicht-t26196-100.html#p114828 [quote=„kayyy“][quote=„hec“][quote=„kayyy“]quote=„VolkerSchröder“: das erweiterte Menu ist aktiviert. Das Mega Menü wird ja auch angezeigt. Aber wo kann ich es konfigurieren??? /quote Über das Backend garnicht - Hier musst du die entsprechende Less Datei anpassen, oder dir eine eigene Less / CSS Datei schreiben, um es deinem Style anzupassen.[/quote] Hallo, ich versuche, das Advanced Menu via LESS zu ändern. Also habe ich ein eigenes Theme erstellt und dort die Datei frontend/_public/src/less/all.less angelegt, in der ich verschiedene CSS-Selektoren des Advanced Menus überschreibe. Wenn ich den Cache leere und Theme Cache neu aufbaue, wird meine LESS-Datei auch compiliert - allerdings werden die LESS-Files des Advanced Menu-Plugins DANACH eingebunden, so dass meine Anpassungen gerade wieder überschrieben werden. Ist das das beabsichtige Verhalten? Wie würde man am schlausten vorgehen, um die LESS-Einstellungen des Plugins zu überschreiben? Danke und freundliche Grüße, Sven[/quote] Das wird wohl daran liegen, dass die all.less entsprechend alle less files lädt. Versuche doch einmal eine less Datei anzulegen und nennen diese bspw. „advanced-menu.less“. Packe diese dann an das ende der all.less per Import @import "advanced-menu"; Generell sollte man denke ich die Struktur behalten, man könnte also bspw. auch noch einen weiteren Ordner anlegen und diesen bspw. „custom“ nennen und dort die Datei packen und diese entsprechend laden. Ich habe gerade keine Zeit das mal zu testen, ansonsten wenn es keine vielen Anweisungen sind kannst du natürlich auch !important nutzen.[/quote] Den Code in eine andere Datei auszulagern und diese zu importieren ändert nichts. Aber meine all.less importiert ja auch nicht alle anderen LESS-Files (das machen rekursiv die all.less-Files des Bare- und Responsive-Themes). !important funktioniert natürlich, finde ich aber unschön :wink: Wenn ich den Code unter https://github.com/shopware/shopware/bl … r.php#L161 richtig verstehe, ist es aber eh so gewollt, dass zunächst alle Theme-LESS-Files compiliert werden und erst anschließend die der Plugins. Gibt es seitens Shopware eine Empfehlung, wie man LESS-Files von Plugins update-sicher überschreibt/erweitert? Danke, Sven

Da bin ich auch sehr dran interessiert. Gerade mal mit der Template Struktur von Shopware 4 vertraut gemacht und dann was ganz neues, uff. Gruß

Ich habe gestern auch anhand der Doku meine less eingefügt, hatte aber keine Auswirkungen. Eigene als auch vorhandene (innerhalb von _modules oder _components). Habe eins meiner Plugins für die 5er angepackt, und im Prinzip fehlt nur noch die less-Einbindung. Ich habe die Doku mit ein paar Core-Plugins verglichen und Unterschiede festgestellt. Bsp. ist die Ordnerstruktur im adanced menu anders, dadurch wird im less-Listener auch ein anderer Pfard inkludiert. Wenn das jemand mit seinem Plugin am laufen hat wüsste ich das gerne, dann hab ich nämlich etwas falsch :smiley: Schöne Grüße, Niklas

Schau mal hier, vielleicht findest du da was Brauchbares: themes-und-design-f101/eigenes-script-und-css-bzw-less-einbinden-t26300.html#p115022

Hallo Uwe, ich bin nur leider bei Plugins und nicht Templates … :frowning: /\*\* \* Registers all necessary events and hooks. \*/ private function subscribeEvents() { // Subscribe the needed event for less merge and compression $this-\>subscribeEvent( 'Theme\_Compiler\_Collect\_Plugin\_Less', 'addLessFiles' ); } /\*\* \* Provide the file collection for less \* \* @param Enlight\_Event\_EventArgs $args \* @return \Doctrine\Common\Collections\ArrayCollection \*/ public function addLessFiles(Enlight\_Event\_EventArgs $args) { $less = new \Shopware\Components\Theme\LessDefinition( //configuration array(), //less files to compile array( \_\_DIR\_\_ . '/Views/responsive/frontend/\_public/src/less/all.less' ), //import directory \_\_DIR\_\_ ); return new Doctrine\Common\Collections\ArrayCollection(array($less)); } Das habe ich nämlich alles schon drin, wird aber nicht ausgeführt bzw. führt keine Änderungen am Frontend aus. In der Doku hier zu sehen: https://devdocs.shopware.com/developers … ate-guide/ Schöne Grüße! Niklas

[quote=„useg“]Schau mal hier, vielleicht findest du da was Brauchbares: themes-und-design-f101/eigenes-script-und-css-bzw-less-einbinden-t26300.html#p115022[/quote] Da wird leider nur beschrieben, wie man nachträglich JS und CSS einbindet, es geht ja aber um LESS. Im Moment sehe ich nur die Option, für LESS, das nach LESS von Plugins eingebunden werden soll, in ein eigenes (als letztes geladenes) Plugin auszulagern. Oder gibt es noch einen anderen Trick?

[quote=„hec“]Im Moment sehe ich nur die Option, für LESS, das nach LESS von Plugins eingebunden werden soll, in ein eigenes (als letztes geladenes) Plugin auszulagern. Oder gibt es noch einen anderen Trick?[/quote] Ja, so wie in der Doku beschrieben :smiley: [quote]Adding LESS files to your theme The built-in LESS compiler searches for a file named all.less in the frontend/_public/src/less directory. You just have to create the necessary directory structure and your LESS code will automatically converted to CSS on the fly.[/quote] Schöne Grüße, Niklas

[quote=“TeichDatensysteme”][quote=“hec”]Im Moment sehe ich nur die Option, für LESS, das nach LESS von Plugins eingebunden werden soll, in ein eigenes (als letztes geladenes) Plugin auszulagern. Oder gibt es noch einen anderen Trick?[/quote] Ja, so wie in der Doku beschrieben :smiley: [quote]Adding LESS files to your theme The built-in LESS compiler searches for a file named all.less in the frontend/_public/src/less directory. You just have to create the necessary directory structure and your LESS code will automatically converted to CSS on the fly.[/quote] Schöne Grüße, Niklas[/quote] Ich mache das ja so wie beschrieben - und das Überschreiben von LESS-Files des Bare- oder Responsive-Themes funktioniert einwandfrei. Aber: es werden zunächst die LESS-Files der Themes verarbeitet (zuerst Bare, dann Responsive, dann mein eigenes) und DANACH die LESS-Files der eingebundenen Plugins. (vgl. auch https://github.com/shopware/shopware/blob/next/engine/Shopware/Components/Theme/Compiler.php#L161) Daher kann ich im Theme nicht das LESS von Plugins überschreiben (weil das, was ich überschreibe, anschließend von den Einstellungen des Plugins wieder überschrieben wird). Und dafür (also dem Überschreiben von Plugin-LESS-Files) suche ich nach einer Lösung.

Hallo zusammen, möglicherweise verstehe ich irgendetwas verkehrt, aber im Prinzip könnt ihr eure eigenen Styles doch einfach durch eine größere Selektor-Weite hervorheben. Heißt: Wenn im Standard bspw. folgender Style verwendet wird: .myParent .myChild { color: red; } dann könnte man diesen Style eben mit einem größeren Selektor überschreiben, beispielsweise so: .myParent div.myChild { color: blue; } Oder habe ich das Problem falsch verstanden? Gruß, Patrick :shopware:

Hallo zusammen, gerne möchte ich ein wenig Licht ins Dunkel bringen. Anfangen möchte ich aber mit ein wenig Grundsätzlichen - die Vererbungshierarchie. Wir haben die Hierarchie in Shopware 5 komplett transparent und offen gestaltet. Hier ein Vergleich zwischen Shopware 4 und Shopware 5: Shopware 4: [list] [*] _default (wird als Erstes geladen)[/*] [*] _emotion[/*] [*] Farb-Template[/*] [*] Plugins (wird als Letztes geladen)[/*][/list] Hierdurch konnten Plugins alles überschreiben. In Shopware 5 hat sich das Verhalten wie folgt verändert: Shopware 5: [list] [*] Bare (wird als Erstes geladen)[/*] [*] Responsive[/*] [*] Plugins[/*] [*] Farb-Theme[/*][/list] Nun zu den hier geschilderten Problemen - wir haben hier mit zwei unterschiedlichen Verhalten zu tun. 1. Verhalten - Überschreiben von LESS-Dateien von einen Plugin Unsere Empfehlung ist hier ein eigenes Theme anzulegen. Die Einbindung von LESS-Dateien gestaltet sich hier sehr einfach. Dazu legt ihr innerhalb eueres Themes die folgende Ordner-Struktur an: frontend/\_public/src/less …und legt innerhalb des „less“-Ordners eines „all.less“-Datei an. Shopware liest diese „on-the-fly“ aus, wenn der Theme aktiviert ist. Euere LESS-Datei befindet sich dann ganz am Ende des Compiler-Steps (siehe hierzu auch die Vererbungshierarchie) und ihr könnt die Selektoren übernehmen und die Properties überschreiben 2. Verhalten - Über ein Plugin LESS-Dateien eines anderen Plugins überschreiben Bei dem Verhalten, welches @hec geschildert wird, muss aber ein andere Herangehensweise verwendet werden. Hier sollen LESS-Dateien von einen Plugin von einen anderen Plugin überschrieben werden. Dazu muss zum einen die LESS-Datei(en) des Plugins über das Event „Theme_Compiler_Collect_Plugin_Less“ registriert werden, damit der LESS-Compiler diese im Compile-Step berücksichtigt. Das Beispiel von @TeichDatensysteme ist hier vollkommen richtig. Das Problem, welches hier aber vorliegt, ist dass ihr nicht wisst an welcher Stelle das Plugin geladen wird. Wir haben natürlich auch so einen Fall berücksichtigt. Wir haben ein festes Namingschema für die Benennung von HTML-Elementen festgelegt. Des Weiterem sind wir hingegangen und haben die Selektortiefe auf maximal 3 Ebenen beschränkt. Ihr müsst also in diesen Fall einen höherwertigen Selektor wählen, sprich einen Selektor mit 4 Ebenen, damit ihr auch diese Styles überschreiben könnt. Das Beispiel von @Patrick Stahl ist hier vollkommen richtig. Viele Grüße, Stephan Pohl :shopware:

[quote=„Stephan Pohl“]Hallo zusammen, Shopware 5: [list] [*] Bare (wird als Erstes geladen)[/*] [*] Responsive[/*] [*] Plugins[/*] [*] Farb-Theme[/*][/list] Nun zu den hier geschilderten Problemen - wir haben hier mit zwei unterschiedlichen Verhalten zu tun. 1. Verhalten - Überschreiben von LESS-Dateien von einen Plugin Unsere Empfehlung ist hier ein eigenes Theme anzulegen. Die Einbindung von LESS-Dateien gestaltet sich hier sehr einfach. Dazu legt ihr innerhalb eueres Themes die folgende Ordner-Struktur an: frontend/\_public/src/less …und legt innerhalb des „less“-Ordners eines „all.less“-Datei an. Shopware liest diese „on-the-fly“ aus, wenn der Theme aktiviert ist. Euere LESS-Datei befindet sich dann ganz am Ende des Compiler-Steps (siehe hierzu auch die Vererbungshierarchie) und ihr könnt die Selektoren übernehmen und die Properties überschreiben [/quote] Hallo, meine Absicht war es, mit der LESS-Datei in meinem Theme die des Advanced Menu Plugins zu überschreiben (also das 1. von dir genannte Verhalten). Ich habe ein Theme angelegt und die all.less gefüllt. Sie wird auch verarbeitet, allerdings steht das resultierende CSS VOR dem CSS des Advanced Menu Plugins (wird also von diesem überschrieben). Müsste nach der genannten Hierarchie mein CSS nicht NACH dem CSS des Plugins stehen? (meinen Code kann ich gerade leider nicht posten - hole ich aber nach, sobald ich wieder am richtigen Rechner bin) Danke, Sven

Hallo, ich habe es gerade nochmal reproduziert: [list] [*] Shopware 5 RC1 installiert[/*] [*] im First Run Wizard die Demodaten installiert[/*] [*] Plugin erweitertes Menü installiert + aktiviert[/*] [*] im Theme-Manager neues Theme erstellt (auf Basis von Responsive)[/*] [*] advanced-menu.less vom Advanced Menu als all.less in mein Theme kopiert, darin eine neue Farbe definiert sowie 2 (sinnfreie) Selektoren ergänzt, damit ich den Code im späteren CSS wiederfinde[/*] [*] Theme aktivieren, Theme-Cache neu aufbauen, Cache leeren[/*][/list] Hier meine all.less: @myAdvMenuColor: #0000ff; .HALLOHALLO .anfang { color: @myAdvMenuColor; } // Advanced menu container that contains every category listing .advanced-menu { .clearfix(); .unitize-max-width(1260, 16); .box-shadow(0 10px 25px -15px #000); .tap-highlight-color(rgba(0, 0, 0, 0)); background: @btn-secondary-text-color; width: 100%; position: absolute; color: @myAdvMenuColor; z-index: 10000; .menu--list { list-style: none; display: block; } .content--wrapper { .unitize-margin(20, 20); position: relative; } .menu--delimiter { content: ""; width: 1px; background: @border-color; position: absolute; display: block; top: 0; bottom: 0; } .menu--teaser { .unitize-padding(10, 10, 0, 20); position: relative; float: left; } .teaser--image { .unitize-height(250); width: 100%; background-repeat: no-repeat; background-size: cover; background-position: center center; display: block; + .teaser--headline, + .teaser--text { .unitize(margin-top, 40); } } .teaser--headline { .unitize(font-size, 21); .unitize-margin(0, 0, 20, 0); font-weight: bold; } .menu--list-item { .hyphens(auto); word-break: normal; word-wrap: break-word; } .menu--list-item-link { .unitize-padding(5, 0); .unitize(font-size, 16); .transition(all 0.1s ease); color: @myAdvMenuColor; display: block; &:hover { .unitize-padding(5, 0, 5, 3); color: @link-color; } } .button-container { .unitize(font-size, 16); .unitize-padding(20, 30, 20, 0); background: @myAdvMenuColor; color: @btn-secondary-text-color; font-weight: bold; .button--category { .unitize-padding(20, 50); .transition(padding .1s ease); color: @btn-secondary-text-color; position: relative; &:hover { .unitize-padding(20, 50, 20, 55); } } .icon--arrow-right { .unitize(font-size, 12); .unitize(-6, 16, margin-top); position: absolute; top: 50%; .unitize(right, 30); } .button--close { .unitize-padding(20, 20); .unitize(-20, 16, margin-top); float: right; cursor: pointer; } } .menu--container { display: none; &:first-child { border-left: block; } &.menu--is-active { display: block; } } .menu--level-0 { .unitize-padding(10, 10, 0, 10); float: left; &.columns--1 { .column-count(1); } &.columns--2 { .column-count(2); } &.columns--3 { .column-count(3); } &.columns--4 { .column-count(4); } } .menu--level-1 { .unitize-margin(5, 0, 0, 20); } .menu--level-2 { .unitize-margin(0, 0, 5, 20); } .item--level-0 { .unitize(padding-bottom, 40); display: inline-block; position: relative; .menu--list-item-link { font-weight: bold; } } .item--level-1 { &:last-child { margin: 0; } .menu--list-item-link { .menu--list-item-link(); font-weight: normal; } } .item--level-2 .menu--list-item-link { .unitize(font-size, 14); + .menu--level-3 { .unitize-margin(0, 0, 5, 20); } } .item--level-3 .menu--list-item-link { .unitize(font-size, 12); } } .navigation-main .navigation--list .navigation--entry.is--hovered { .border-radius-multi(3px, 3px); .tap-highlight-color(rgba(0, 0, 0, 0)); background: @myAdvMenuColor; .navigation--link { background: @myAdvMenuColor; color: @btn-secondary-text-color; } } @media screen and (min-width: @desktopViewportWidth) { .advanced-menu .content--wrapper { .unitize-margin(40, 40); } } .HALLOHALLO .ende { color: @myAdvMenuColor; } Ich würde nun erwarten, dass der Balken im Dropdown des Advanced Menus blau wird - er bleibt aber dunkelgrau. Ein Blick in die generierte CSS-Datei zeigt, dass das CSS des Plugins am Ende der Datei steht, das CSS meines Themes davor. Somit überschreibt das Original-LESS mein Theme-LESS (wenn ich im Firebug das CSS des Plugins entferne, wird der Balken dann auch wirklich blau). Ist das das beabsichtigte Verhalten? Wenn ja, finde ich die von Stephan Pohl genannte Hierarchie mißverständlich (denn danach müsste mein LESS später ausgewertet werden als das LESS des Plugins), würde dann aber zur Lösung meines eigentlichen Problems halt die Selektoren konkreter benennen oder mit !important arbeiten oder mein LESS in ein Plugin auslagern. Oder habe ich beim Erstellen irgendwas falsch gemacht oder vergessen? Danke, Sven

Ich habe auch schon Stunden damit verbracht und keine Lösung gefunden. Man müsste eben die Reinfolge wie es in die Css oder Less geschieben wird selbst mit einen Wert bestimmen können ähnlich wie “z-index”. Oder mit den anlegen eines zusätzlichen Ordner in /frontend/_public/src/less z.B _plugins der vom System am Ende eingefügt wird. zur Zeit hilft nur “!important”

@hec, @useg kann mir einer von euch beiden Zugang zu eurer Testinstallation geben? Dann würde ich mir das Verhalten gerne anschauen und prüfen was man machen kann. Gruß

@Thomas, ich schick dir eine PM

@hec ich habe folgendes Plugin geschrieben: [code]<?php use Doctrine\Common\Collections\ArrayCollection;

class Shopware_Plugins_Frontend_LessHierarchy_Bootstrap extends Shopware_Components_Plugin_Bootstrap
{
/**
* Install plugin method
*
* @return bool
*/
public function install()
{
$this->subscribeEvents(); return true; } /** * subscribeEvents */ private function subscribeEvents() { $this->subscribeEvent( ‘Theme_Compiler_Collect_Plugin_Less’, ‘onCollectLessFiles’ ); } /** * onCollectLessFiles * @return ArrayCollection */ public function onCollectLessFiles() { $lessDir = __DIR__ . ‘/…/…/…/…/…/…/themes/Frontend/MeinTheme/frontend/_public/src/less/’; $less = new \Shopware\Components\Theme\LessDefinition( array(), array( $lessDir . ‘plugin.less’ ), $lessDir ); return new ArrayCollection(array($less)); } }[/code] Mir gefällt die Lösung zwar noch nicht aber so funktioniert es bei dir erst einmal :slight_smile:

@hec: bevor man so einen aufriss macht mit eigenem theme etc? Wieso nicht so wie es die Shopware Jungs vorgeschalgen haben zB: .navigation-main .advanced-menu { // … dein code zum überschreiben des advanced menu css/less } !important ist ja auch nicht schön. beste grüße

[quote=„Thomas“]@hec ich habe folgendes Plugin geschrieben: … Mir gefällt die Lösung zwar noch nicht aber so funktioniert es bei dir erst einmal :-)[/quote] Hallo Thomas, danke erstmal für das Plugin werde er die nächsten Tage mal testen. Ich hoffe das es seitens Shopware noch einen interne Lösung gibt. [quote=„thom“]@hec: bevor man so einen aufriss macht mit eigenem theme etc? Wieso nicht so wie es die Shopware Jungs vorgeschalgen haben zB: .navigation-main .advanced-menu { // … dein code zum überschreiben des advanced menu css/less } !important ist ja auch nicht schön. beste grüße[/quote] Um die Übersicht bei Änderungen in der CSS bzw Less nicht zu verlieren, ist es für mich auf jeden Fall besser die identischen Einträge zu überschreiben und diese nicht noch zu erweitern und !important sollte schon so wenig wie möglich verwendet werden.

[quote=„thom“] .navigation-main .advanced-menu { // … dein code zum überschreiben des advanced menu css/less } [/quote] Das ist die Lösung mit den erweiterten Selektoren. Ich würde halt vom Ablauf her das gerne generell so machen, dass ich die benötigten Selektoren aus dem CSS/LESS übernehme und den Inhalt einfüge, den ich gern geändert hätte. (wie von Stefan Pohl als 1. Verhalten beschrieben) Allerdings verhält es sich leider nicht so, dass mein LESS am Ende des Compiler-Steps steht (das LESS der Plugins kommt noch danach).

[quote=“Thomas”]@hec ich habe folgendes Plugin geschrieben: … Mir gefällt die Lösung zwar noch nicht aber so funktioniert es bei dir erst einmal :-)[/quote] Danke für das Plugin. Ich habe es noch folgendermaßen erweitert: [code]<?php use Doctrine\Common\Collections\ArrayCollection;

class Shopware_Plugins_Frontend_LessHierarchy_Bootstrap extends Shopware_Components_Plugin_Bootstrap
{

/**
 * Install plugin method
 *
 * @return bool
 */
public function install()
{
    $this->subscribeEvents(); return true; } /\*\* \* @return array \*/ public function enable() { return ['success' =\> true, 'invalidateCache' =\> ['template', 'theme'] ]; } /\*\* \* subscribeEvents \*/ private function subscribeEvents() { $this-\>subscribeEvent( 'Theme\_Compiler\_Collect\_Plugin\_Less', 'onCollectLessFiles', PHP\_INT\_MAX ); } /\*\* \* onCollectLessFiles \* @param Enlight\_Event\_EventArgs $args \* @return ArrayCollection \*/ public function onCollectLessFiles(Enlight\_Event\_EventArgs $args) { $pathResolver = $this-\>get('theme\_path\_resolver'); $template = $args-\>getTemplate(); $lessDir = $pathResolver-\>getLessDirectory($template); $lessFiles = new ArrayCollection(); $less = new \Shopware\Components\Theme\LessDefinition( array(), array( $lessDir . DIRECTORY\_SEPARATOR . '\_after-plugins.less' ), $pathResolver-\>getPublicDirectory($template) ); $lessFiles-\>add($less); return $lessFiles; } } [/code] Gemachte Änderungen: [list] [\*] der Pfad zur LESS-Datei steht nicht fest im Plugin, sondern wird aus dem jeweils aktiven Theme gezogen[/\*] [\*] das Plugin steht als letztes in der Verarbeitungsliste, so dass es auch wirklich alle anderen Plugins überschreiben kann[/\*] [\*] der Name der LESS-Datei lautet \_after-plugins.less[/\*] [\*] beim Aktivieren wird automatisch der Cache geleert[/\*][/list] Folgendes will ich noch machen, muss jetzt aber erstmal weg: [list] [\*] nicht nur das aktuelle Theme bearbeiten, sondern auch die Parent-Themes (analog [url=https://github.com/shopware/shopware/blob/next/engine/Shopware/Components/Theme/Compiler.php#L359]https://github.com/shopware/shopware/bl ... r.php#L359[/url])[/\*] [\*] DI der benötigten Services statt holen per $this-\>get()[/\*][/list] Grüße, Sven
1 „Gefällt mir“