• Hallo zusammen,

    ich möchte die Ausgabe von Produkt-Attributen ändern bzw. den Funktionsumfang erweitern. z.B. habe ich Ein Produkt, welches zu mehreren Maschinen div. Hersteller passt (attribute:maschinentyp). Die Attribut-Items sind nach dem Muster

    "Hersteller1 Maschine-A3 | Hersteller1 Maschine-XY | Hersteller2 Maschine CD12 | ..."

    hinterlegt. Die Ausgabe soll nun per Hersteller gruppiert werden und nur der Maschinentyp angezeigt werden:

    Hersteller1: Maschine-A3, Maschine-XY
    Hersteller2: Maschine CD12, ...

    Im Template additional_information.php kommt dies bei

    do_action( 'woocommerce_product_additional_information', $product );

    an. Die eigentliche Funktion

    wc_display_product_attributes()

    ist in wc-template-functions.php, liefert aber nur Strings zurück, bzw. klickbar wenn das Attribut als Archiv angelegt ist.

    Nun könnte ich diese ja nach meinem Gusto abändern, habe aber das Gefühl, dass das keine sehr elegante Lösung ist und bei einem Update eh wieder rückgängig gemacht wird.

    Wie löst man solche Problemstellungen generell? An welcher Stelle können Funktionserweiterungen dauerhaft eingepflegt werden? Und wie rufe ich diese ab?

    Oder hat jemand ein Plugin parat, welches gewünschte Funktionalität bereitstellt?

    • Dieses Thema wurde geändert vor 3 Monaten, 1 Woche von melonlemon.
    • Dieses Thema wurde geändert vor 3 Monaten, 1 Woche von melonlemon.
    • Dieses Thema wurde geändert vor 3 Monaten, 1 Woche von melonlemon.
Ansicht von 3 Antworten – 1 bis 3 (von insgesamt 3)
  • Thread-Starter melonlemon

    (@melonlemon)

    Weil ich so ungeduldig war, hab ichs nun mal so versucht:

    • Enfold->Enfold Child Theme erstellt.
    • woocommerce/templates/single-product/* nach enfold-child/woocommerce/ kopiert.
    • wc_display_product_attributes_neu() nach enfold-child/functions.php kopiert und dort
    • add_action('woocommerce_product_additional_information_neu', 'wc_display_product_attributes_neu', 10); angelegt.
    • in additional-information.php aufdo_action( 'woocommerce_product_additional_information_neu', $product ); abgeändert.

    Ist das so üblich oder war das zu umständlich?

    Ich nutze WooCommerce selber nicht, möchte aber auf einen Teil deiner Frage etwas ausführlicher eingehen:

    Wie löst man solche Problemstellungen generell? An welcher Stelle können Funktionserweiterungen dauerhaft eingepflegt werden? Und wie rufe ich diese ab?

    do_action() erstellt eine Programmierschnittstelle.
    add_action() bindet an dieser Schnittstelle eine Funktion ein.

    Dazu ein Beispiel:

    Nehmen wir an, du hast eine recht einfache PHP-Funktion, die einen Text im Header ausgeben soll:

    function say_hello() {
      $output = "Hello";
      echo $output;
    }
    add_action( 'wp_head', 'say_hello' );

    Mit dem Befehl add_action() wird die Funktion say_hello ausgeführt, wenn im Header der Hook wp_head verwendet wird. (Dazu verwenden Programmierer im Template header.php die Funktion wp_head(), die den Befehl do_action( 'wp_head' ); ausführt.)

    Nun ist unsere Funktion nicht sonderlich flexibel. Benutzer wollen vielleicht das Wort „Hello“ in einen HTML-Tag packen. Hierfür definieren wir zuerst mit do_action() zwei Schnittstellen:

    function say_hello() {
      $output = "Hello";
      do_action('beforehello');
      echo $output;
      do_action('afterhello');
    }
    add_action( 'wp_head', 'say_hello' );

    Diese Schnittstellen kann ein Programmierer nun mit add_action() nutzen, um eine eigene Funktion einzubinden. Das erste Argument ist der Name der vorher definierten Schnittstelle, das zweite Argument der Name einer eigenen Funktion, die an dieser Stelle ausgeführt werden soll:

    add_action('beforehello', 'opening_comment_tag');
    function opening_comment_tag() {
    	echo '<!--';
    }
    
    add_action('afterhello', 'closing_comment_tag');
    function closing_comment_tag() {
    	echo '-->';
    }

    Ergebnis ist die Ausgabe als HTML-Kommentar <!--Hello-->.

    Damit eine Änderung eines Codes mit add_action() nicht überschrieben wird, muss er an einer Stelle gespeichert werden, die bei einem Update nicht überschrieben wird.

    Speicherst du den Code in der functions.php eines Themes, geht die Änderung bereits mit dem nächsten Theme-Update verloren. Das wäre also die denkbar schlechteste Lösung.
    Hast du, um Anpassungen am Theme dauerhaft zu sichern, ein Child-Theme erstellt und fügst den Code in der functions.php des Child-Themes ein, geht deine Änderung nur bei einem Theme-Wechsel verloren. Das halte ich aber auch noch nicht für ideal. Vielleicht willst du irgendwann einen „Tapetenwechsel“ und entscheidest dich für ein anderes Theme – schwups, ist die eigene Anpassung verschwunden.

    Alternativ kannst du ein eigenes Plugin erstellen. Das klingt dramatischer, als es ist. Du brauchst deinem Code nur einen so genannten Plugin-Header voranstellen:

    <?php
    /*
     * Plugin Name: Say Hello Änderungen
     * Description: Fügt ein HTML-Tag vor und nach "Hello" ein.
     * Autor: Melon Lemon
     */
    
    // Plugin nur in WordPress ausführen
    defined( 'WPINC' ) || exit;
    
    // Ab hier der Code mit den Anpassungen …
    add_action('beforehello', 'opening_comment_tag');
    function opening_comment_tag() {
    	echo '<!--';
    }
    
    add_action('afterhello', 'closing_comment_tag');
    function closing_comment_tag() {
    	echo '-->';
    }

    Das speicherst du z.B. als Datei say-hello-changes.php in einem Verzeichnis say-hello-changes, komprimierst das Verzeichnis und schon hast du ein Plugin, dass du im Menü Plugins > Neues Plugin hinzufügen hochladen kannst.

    Hierbei besteht allerdings noch eine Restgefahr, dass das Plugin später wieder von jemandem deaktiviert wird, weil man sich nicht mehr daran erinnert, wofür es eigentlich gebraucht wurde. Wenn das Plugin für den Betrieb der Website zwingend notwendig ist, kannst du deshalb die Datei say-hello-changes.php alternativ in dem Verzeichnis wp-content/mu-plugins speichern. Das Verzeichnis musst du selber anlegen. mu-plugins steht als Abkürzung für „must use plugins„, also Plugins, die zwingend verwendet werden müssen.

    In diesem Verzeichnis werden immer nur PHP-Datei ausgeführt, die nicht in einem Unterverzeichnis liegen. Du kannst aber z.B. eine Datei load.php verwenden, die dann eine Datei in einem Unterverzeichnis aufruft:

    <?php // mu-plugins/load.php
    require WPMU_PLUGIN_DIR.'/say-hello-changes/say-hello-changes.php';

    Plugins in diesem Must-Use-Verzeichnis sind selbst für den Administrator der Website nicht ohne weiteres sichtbar. Du bekommst dann auch nicht mit, wenn es für ein Plugin Updates gibt. Automatisch aktualisiert werden sie ebenfalls nicht. Es sollte deshalb abgewogen werden, ob diese drastische Methode wirklich nötig ist.

    Eine einfachere, aber auch kontrovers diskutierte Alternative ist die Verwendung des Plugins Code Snippets, mit dem du ebenfalls Code einbinden kannst. Das Plugin bietet dir die Möglichkeit, deinen Code mit einer Beschreibung und Schlagwörtern abzuspeichern. Hier könnte man vermerken, wofür der Code gedacht ist und dass er nicht deaktiviert werden darf.
    Dass dieses Plugin nicht überall mit Begeisterung gesehen wird, hat damit zu tun, dass unbedarfte Anwender auch Code einbinden könnten, der Sicherheitslücken schafft. Die Gefahr sehe ich aber bei eigenen Plugins genauso gegeben. Trotzdem ist diese sehr einfache Lösung mit Vorsicht zu genießen.

    Ich hoffe, diese etwas ausführlich geratene Antwort erklärt, was es mit do_action() und add_action() auf sich hat und wo man Anpassungen mit diesen Funktionen dauerhaft speichern kann.

    Viel Erfolg.

    Thread-Starter melonlemon

    (@melonlemon)

    hallo @pixolin , danke für die ausführliche Antwort, hat mir gut geholfen. ich bin jetzt soweit, ein child-theme ordentlich aufzusetzen. functions.php läuft soweit, aber andere template-dateien werden nicht erkannt. hast du ne Idee warum? master-theme ist storefeont

Ansicht von 3 Antworten – 1 bis 3 (von insgesamt 3)