Support » Plugins » Code Snippet Insert Plugin mit function_exists Abfrage

  • Gelöst pezi

    (@pezi)


    Hallo!

    Es gibt sicher 1000e Plugins, welche Codes injizieren, Snippets verwalten. Wie zb. „Woody snippets“ uä. Das klappt auch ganz gut – solange man keine bereits vorhandenen PHP Funktionsnamen verwendet.
    Also was man in der functions.php eines Child-Themes macht, um eine (mit if function_exists umschlossene) Funktion des Parent-Themes neu zu schreiben.

    Doch welches dieser Code Insert Snippet … Plugins kann das auch?
    Überall die Fehlermeldung, dass die Funktion bereits deklariert sei.
    Leider hat mein Bekannter, von dem diese Frage stammt, manche Plugins einfach gelöscht, nicht notiert. Damit ist es ein Frage ins Blaue, ob jemand zufällig eins kennt, welches das kann?

    Danke!

Ansicht von 11 Antworten - 1 bis 11 (von insgesamt 11)
  • Hallo,
    sorry, aber was genau meinst du mit „ob jemand zufällig eins kennt, welches das kann?“ – ich kann mir nicht vorstellen, dass es ein Plugin gibt, das erkennt, ob eine Funktion bereits unter dem gleichen Namen wie eine andere Funktion deklariert wurde (wenn das die Frage gewesen sein sollte).
    Aber das erkennt man ja auch, wenn die Seite nicht funktioniert (redeclare-Fehler) 😉
    Viele Grüße
    Hans-Gerd

    Überall die Fehlermeldung, dass die Funktion bereits deklariert sei.

    Das ist noch ein Relikt aus frühen PHP-Versionen, die Entwicklern nicht die Möglichkeit gaben, Funktionen in einem Namespace zu nutzen und so Namenkollisionen vorzubeugen.

    Die einfachste Methode, auch ohne Namespaces Funktion eindeutig zu machen, ist eine individuelle Vorsilbe anzuhängen. Möchtest du, dass die Funktion add_shortcode() in deinem Plugin, Theme oder Code Snippet nicht mit der bereits vorhandenen Funktion im Core kollidiert, benennst du sie in z.B. pezi_add_shortcode() um. Oder du verwendest eine eigene PHP-Class und verwendest Funktionen innerhalb dieser Klasse.

    Das if-Statement if ( function_exists() ) { … } soll hingegen Funktionen in Plugins und Theme „pluggable“ machen, grob übersetzt überschreibbar. Umgangssprachlich könnte man das so ausdrücken: „Wenn der Benutzer nicht aus irgendwelchen Gründen bereits eine Funktion mit dem Namen XY definiert hat, dann kommt jetzt hier meine Version, bitteschön …“

    Wie auch immer: Funktions-Präfixe, PHP-Classes und if( function_exists() ) { … } kannst du sowohl in Plugins und Themes, als auch in Code Snippets verwenden – es ist überall valides PHP. Bekommst du eine Fehlermeldung, wird das Problem woanders liegen – z.B. dass du die erneute Deklaration einer Funktion zu spät einbindest und die Abfrage, ob die Funktion bereits vorhanden ist, bereits vorher ausgeführt wurde.

    Ein recht populäres (und IMHO sehr hübsch gemachtes) Plugin für den Einsatz eigener Code Snippets, das ich hier immer wieder empfehle, ist das Plugin (Trommelwirbel, Tusch! 🎉) Code Snippets. Der Einsatz macht Sinn, wenn du rasch eine kleine Lösung benötigst. Für den längerfristigen Einsatz kannst du besser ein eigenes Plugin schreiben. Das ist nicht viel mehr, als dem Code einen Header hinzuzufügen, das Verzeichnis zu komprimieren und dann per Upload zu installieren.

    Hallo @pixolin

    danke für die ausführliche Erklärung.

    Vorsilbe

    : Naja, dann ist die Funktion ja nicht überschrieben, sondern eine neue?
    Und Core Sachen will zumindest ich nicht überschreiben, aber manchmal eben Theme Funktionen ändern.

    Das if-Statement

    ist genau das was ich meine: Es funzt per functions.php, so eine Funktion des Parent-Themes zu überschreiben. Nicht aber mit den gängigen Code Inserter Plugins.
    Aber:
    Auch Code Snippet (habe ich selber seit ~ 8 Jahren im Einsatz, auch nur fürs temp testen am XAMPP) kann „pluggable“ Funktionen nicht erkennen!

    besser ein eigenes Plugin schreiben

    Der Tipp ist super, so ist die Sache echt einfacher zu handeln.

    Hallo @hage

    ich kann mir nicht vorstellen, dass es ein Plugin gibt, das erkennt, ob eine Funktion bereits unter dem gleichen Namen wie eine andere Funktion deklariert wurde

    Scheint tatsächlich keins zu geben …

    Aber was kann daran so schwer sein, so ein Plugin zu machen, welches die functions.php des Child … hmmm nachahmt, … oder gar diese Datei selbst über eine Art Benutzeroberfläche zugänglich macht?
    Sorry für die laienhaften Ausdrücke und so.

    Ich werde dem eigentlichen Fragesteller aber empfehlen, eben die umgebauten (überschreibbaren) Funktionen in die Child/functions.php zu geben. Ist ja nicht so schwer, aber manche wollen halt ein Plugin – Code rein, speichern, fertig.

    OK, das ist kein Problem der Code-Snippets-Plugins sondern hat damit zu tun, wie WordPress mit der Defintion von Funktionen umgeht.

    Nehmen wir an, du hast das Theme Twenty Nineteen installiert. Das Theme verwendet

    if ( ! function_exists( 'twentynineteen_setup' ) ) :
    	/**
    	 * Sets up theme defaults and registers support for various WordPress features.
    	 *
    	 * Note that this function is hooked into the after_setup_theme hook, which
    	 * runs before the init hook. The init hook is too late for some features, such
    	 * as indicating support for post thumbnails.
    	 */
    	function twentynineteen_setup() {
    
               // diverse Zeilen gelöscht
    
               add_theme_support(
                 'custom-logo',
                   array(
                     'height'      => 190,
                     'width'       => 190,
                     'flex-width'  => false,
                     'flex-height' => false,
                   )
               );
    }

    Nun möchtest du, dass dein Kunde nicht ein eigenes Logo einfügt. Dazu könntest du ein Child-Theme anlegen und dort die Funktion twentynineteen_setup() neu anlegen. Dabei kopierst du die Funktion des Parent Theme und lässt die Zeilen mit dem Custom-Logo weg. Die neue Funktion im Child-Theme würde vom Parent Theme erkannt; das Parent Theme legt die Funktion nicht nochmal an.
    Du kannst die Funktion aber nicht in einem Code Snippet verwenden, weil das Parent Theme zu diesem Zeitpunkt bereits die Funktion definiert hat. Resultat ist eine Fehlermeldung „Cannot redeclare function twentynineteen_setup.“
    Statt dessen kannst du aber die Funktion des Themes nachträglich korrigieren:

    add_action( 'init', 'my_twentynineteen_changes' );
    function my_twentynineteen_changes() {
    	remove_theme_support( 'custom-logo' );
    }

    Auch hier fällt für den Kunden dann die Möglichkeit weg, ein eigenes Logo einzufügen. Auch ein überschreiben mit anderen Werten ist möglich, um z.B. ein größeres Logo zu erlauben:

    add_action( 'init', 'my_twentynineteen_changes' );
    function my_twentynineteen_changes() {
      add_theme_support(
                 'custom-logo',
                   array(
                     'height'      => 300,
                     'width'       => 400,
                     'flex-width'  => true,
                     'flex-height' => true,
                   )
               );
    }

    Oft werden in Themes Funktionen mit einem Hook eingebunden, z.B. add_action( 'wp_footer', 'irgendwas' );. Das lässt sich in Plugins und Code Snippets durch remove_action( 'wp_footer', 'irgendwas' ); wieder entkoppeln und anschließend kannst du dann eine eigene Funktion mit add_action( 'wp_footer', 'irgendwas_anderes' ) einbinden.

    Hallo @pixolin, nochmals Danke

    Die Theorie rund um das WP-Management von Parent u Child Funktionen hatte ich eh oberflächlich gekannt – jetzt noch besser. Danke.

    Aber der Kern der Sache scheint dieser (und der nächste) Satz zu sein:

    Die neue Funktion im Child-Theme würde vom Parent Theme erkannt; das Parent Theme legt die Funktion nicht nochmal an.

    Klar, aber nur an, wenn die neue Funktion in der functions.php ist.

    Du kannst die Funktion aber nicht in einem Code Snippet verwenden, weil das Parent Theme zu diesem Zeitpunkt bereits die Funktion definiert hat.

    Ok, … nur … hmmm ich weiß nicht genau warum?
    Sind Plugin generierte Codes allg. später im Dokument als jene des Themes?
    Oder anders gefragt/gesagt:
    – Die functions.php (des Childs) checkt vor dem ausführen einer Funktion, ob im Parent eine gleichnamige, überschreibbare vorliegt.
    – Ein Plugin (selbst ein Code-Inserter) kann das nicht, kommt später dran – das Theme hat da seine Funktionen bereits erledigt?

    zT.

    Funktion des Themes nachträglich korrigieren

    und dem Rest muss sich noch öfters durchlesen, länger nachdenken was das heißt. In mein kleines Brain.exe passt nicht so viel auf einmal rein und meine Funktionen drehen sich grade um den Pizzaofen – Danke erstmal!

    Ok, … nur … hmmm ich weiß nicht genau warum?
    Sind Plugin generierte Codes allg. später im Dokument als jene des Themes? …
    Ein Plugin (selbst ein Code-Inserter) kann das nicht, kommt später dran – das Theme hat da seine Funktionen bereits erledigt?

    Ja, genau. Schau dir mal diesen Beitrag an:

    https://www.wpbeginner.com/wp-tutorials/how-wordpress-actually-works-behind-the-scenes-infographic/

    Das Plugin Code Snippets bindet die Snippets mit dem Hook after_setup_theme (Schritt 19) ein – also nach dem Laden des Child- und Parent Themes (Schritte 17 und 18).

    Du kannst ja mal die Funktion, die du überschreiben möchtest, in die wp-config.php einfügen (oberhalb von /* That's all, stop editing! Happy blogging. */). – Das ist natürlich nicht empfehlenswert und soll hier nur dem besseren Verständnis dienen.

    Das ist ja eine starke Liste! Was da alles abgeht, bis der Besucher was sieht ist, schon fantastisch.

    Also habe ich auch mal was kapiert, danke für die Erklärung! So spart man sich die weitere Sucherei nach Code-Plugins.

    Danke!

    Das mit dem

    Funktion des Themes nachträglich korrigieren

    habe ich inzwischen auch getestet und es klappt!
    Damit ergeben sich interessante Möglichkeiten – was außer den Beispielen noch alles geht, wird noch eine spannende Sache.

    Sorry wg. kurzer Antworten, ist nicht das ich die Hilfe nicht würdige. Im Gegenteil! Nur nach > 12 h auf Achse bin ich nicht mehr so tippfähig …

    DANKE!!!

    Sorry wg. kurzer Antworten, ist nicht das ich die Hilfe nicht würdige.

    Alles gut. Ich freue mich immer über Rückmeldungen, auch wenn sie kurz ausfallen. Und wenn dann noch der Thread-Ersteller den Thread irgendwann als „gelöst“ markiert … 😉

    ok, gelöst!

Ansicht von 11 Antworten - 1 bis 11 (von insgesamt 11)