it-swarm.com.de

Skripte/Stile in Warteschlange stellen, wenn ein Shortcode vorhanden ist

Wie können Skripte und/oder Stile für die Verwendung in Plugins registriert/in die Warteschlange gestellt werden?

Ich habe vor kurzem ein Plugin einfaches Plugin erstellt, um dem Benutzer Avatar/Gravatar einen Shortcode hinzuzufügen. Ich habe verschiedene Stiloptionen für die Anzeige des Avatars (quadratisch, rund usw.) und habe mich dafür entschieden, die CSS direkt in den Shortcode selbst einzufügen.

Jetzt ist mir jedoch klar, dass dies kein guter Ansatz ist, da der CSS-Code jedes Mal wiederholt wird, wenn der Shortcode auf einer Seite verwendet wird. Ich habe mehrere andere Ansätze auf dieser Site gesehen und der wp-Codex hat sogar zwei eigene Beispiele, so dass es schwierig ist zu wissen, welcher Ansatz am konsistentesten und schnellsten ist.

Hier sind die Methoden, die mir derzeit bekannt sind:

Methode 1: Direkt in den Shortcode aufnehmen - Dies ist das, was ich derzeit im Plugin mache, aber es scheint nicht gut zu sein, da es den Code wiederholt.

class My_Shortcode {
function handle_shortcode( $atts, $content="" ) {
/* simply enqueue or print the scripts/styles in the shortcode itself */
?>
<style type="text/css">

</style>
<?php
    return "$content";
     }
}
add_shortcode( 'myshortcode', array( 'My_Shortcode', 'handle_shortcode' ) );

Methode 2: Verwenden Sie die Klasse zum bedingten Einreihen von Skripten oder Stilen

class My_Shortcode {
    static $add_script;
    static function init() {
        add_shortcode('myshortcode', array(__CLASS__, 'handle_shortcode'));
        add_action('init', array(__CLASS__, 'register_script'));
        add_action('wp_footer', array(__CLASS__, 'print_script'));
    }
    static function handle_shortcode($atts) {
        self::$add_script = true;
        // shortcode handling here
    }
    static function register_script() {
        wp_register_script('my-script', plugins_url('my-script.js', __FILE__), array('jquery'), '1.0', true);
    }
    static function print_script() {
        if ( ! self::$add_script )
            return;
        wp_print_scripts('my-script');
    }
}
My_Shortcode::init();

Methode 3: Verwenden von get_shortcode_regex();

function your_prefix_detect_shortcode() {

    global $wp_query;   
    $posts = $wp_query->posts;
    $pattern = get_shortcode_regex();

    foreach ($posts as $post){
        if (   preg_match_all( '/'. $pattern .'/s', $post->post_content, $matches )
            && array_key_exists( 2, $matches )
            && in_array( 'myshortcode', $matches[2] ) )
        {
            // css/js 
            break;  
        }    
    }
}
add_action( 'wp', 'your_prefix_detect_shortcode' );

Methode 4: Verwenden von has_shortcode();

function custom_shortcode_scripts() {
    global $post;
    if( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'myshortcode') ) {
        wp_enqueue_script( 'my-script');
    }
}
add_action( 'wp_enqueue_scripts', 'custom_shortcode_scripts');
51
Bryan Willis

Ich habe einen anderen Weg gefunden, der für mich gut funktioniert:

Hier ist ein Beispiel-Plugin mit dieser Methode, mit dem Sie get_avatar als Shortcode verwenden können. Das Stylesheet wird nur in die Warteschlange gestellt, wenn der Shortcode vorhanden ist.

Verwendung (ID ist standardmäßig der aktuelle Benutzer):

[get_avatar id="" size="32" default="mystery" alt="Profile Photo" class="round"]

function wpse_165754_avatar_shortcode_wp_enqueue_scripts() {
    wp_register_style( 'get-avatar-style', plugins_url( '/css/style.css', __FILE__ ), array(), '1.0.0', 'all' );
}

add_action( 'wp_enqueue_scripts', 'wpse_165754_avatar_shortcode_wp_enqueue_scripts' );
if ( function_exists( 'get_avatar' ) ) {
    function wpse_165754_user_avatar_shortcode( $attributes ) {

        global $current_user;
        get_currentuserinfo();

        extract( shortcode_atts(
                     array(
                         "id"      => $current_user->ID,
                         "size"    => 32,
                         "default" => 'mystery',
                         "alt"     => '',
                         "class"   => '',
                     ), $attributes, 'get_avatar' ) );

        $get_avatar = get_avatar( $id, $size, $default, $alt );

        wp_enqueue_style( 'get-avatar-style' );

        return '<span class="get_avatar ' . $class . '">' . $get_avatar . '</span>';
    }

    add_shortcode( 'get_avatar', wpse_165754_user_avatar_shortcode' );
}
42
jblanche

Bevor ich mit der Beantwortung beginne, muss ich sagen, dass CSS und JS in Bezug auf dieses Thema nicht dasselbe sind.

Der Grund ist einfach: Während das Hinzufügen von js zum Hauptteil der Seite (in der Fußzeile) ein gängiger und gültiger Weg ist, muss CSS im Abschnitt <head> der Seite platziert werden: Auch wenn die Mehrheit der Browser CSS ordnungsgemäß rendern kann Seitenkörper, das ist kein gültiger HTML-Code.

Wenn ein Shortcode gerendert wird, wurde der Abschnitt <head> bereits gedruckt. Dies bedeutet, dass js problemlos in der Fußzeile hinzugefügt werden kann, aber CSS muss hinzugefügt werden bevor der Shortcode gerendert wird.

Skripte

Wenn Ihr Shortcode nur js benötigt, haben Sie Glück und können einfach wp_enqueue_script im Rumpf des Shortcode-Rückrufs verwenden:

add_shortcode( 'myshortcode', 'my_handle_shortcode' );

function my_handle_shortcode() {
  wp_enqueue_script( 'myshortcodejs', '/path/to/js/file.js' );
  // rest of code here...
}

Dabei wird Ihr Skript nur einmal in die Fußzeile eingefügt, auch wenn der Shortcode mehrmals auf der Seite verwendet wird.

Stile

Wenn Sie für den Code Stile benötigen, müssen Sie handeln, bevor der Shortcode tatsächlich gerendert wird.

Hierfür gibt es verschiedene Möglichkeiten:

  1. sehen Sie sich alle Posts in der aktuellen Abfrage an und fügen Sie bei Bedarf die Shortcode-Stile hinzu. Dies ist, was Sie in Methode 3 und 4 in OP tun. Tatsächlich tun beide Methoden dasselbe, aber has_shortcode wurde in WP 3.6 hinzugefügt, während get_shortcode_regex seit Version 2.5 verfügbar ist. Verwenden Sie get_shortcode_regex daher nur, wenn Sie Ihr Plugin mit älteren Versionen kompatibel machen möchten.

  2. fügen Sie auf allen Seiten immer den Shortcode-Stil hinzu

Probleme

Problem mit # 1 ist die Leistung. Regex sind ziemlich langsame Vorgänge und das Starten von Regex in einer Schleife aller Posts kann die Seite konsistent verlangsamen. Darüber hinaus ist es in Themes eine ziemlich häufige Aufgabe, nur Post-Ausschnitte in Archiven und vollständigen Inhalt mit Shortcodes nur in einzelnen Ansichten anzuzeigen. In diesem Fall startet Ihr Plugin bei der Anzeige eines Archivs in einer Schleife einen regulären Ausdruck, um einen Stil hinzuzufügen, der niemals verwendet wird: eine unnötige doppelte Auswirkung auf die Leistung: Verlangsamung der Seitengenerierung + zusätzliche unnötige HTTP-Anforderung

Problem mit # 2 ist wieder Leistung. Das Hinzufügen eines Stils zu allen Seiten bedeutet, dass eine zusätzliche HTTP-Anforderung für alle Seiten hinzugefügt wird, auch wenn diese nicht benötigt wird. Auch wenn die Generierungszeit der serverseitigen Seiten nicht beeinflusst wird, gilt dies für die gesamte Renderzeit der Seite und für alle Websiteseiten.

Was sollte ein Plugin-Entwickler also tun?

Ich denke, das Beste ist, eine Optionsseite zum Plugin hinzuzufügen, auf der Benutzer auswählen können, ob der Shortcode nur in der Einzelansicht oder sogar in Archiven behandelt werden soll. In beiden Fällen ist es besser, eine andere Option bereitzustellen, um auszuwählen, für welche Beitragstypen die Kurzwahl aktiviert werden soll.

Auf diese Weise kann "template_redirect" angehängt werden, um zu prüfen, ob die aktuelle Abfrage den Anforderungen entspricht, und in diesem Fall den Stil hinzuzufügen.

Wenn der Benutzer den Shortcode nur in einzelnen Post-Ansichten verwendet, empfiehlt es sich, zu prüfen, ob der Post einen Shortcode enthält oder nicht: Wenn nur eine Regex erforderlich ist, sollte die Seite nicht so stark verlangsamt werden.

Wenn der Benutzer die Verwendung von Shortcode auch in Archiven wählt, würde ich es vermeiden, Regex für alle Posts auszuführen, wenn die Anzahl der Posts hoch ist, und nur den Stil einreihen, wenn die Anforderungen an die Abfragetauglichkeit erfüllt sind.

Was in dieser Hinsicht als "hoch" zu betrachten ist, sollte darin bestehen, einige Leistungstests durchzuführen oder alternativ eine weitere Option hinzuzufügen und den Benutzern eine Auswahl zu geben.

25
gmazzap

Für mein Plugin habe ich festgestellt, dass Benutzer manchmal einen Theme Builder haben, dessen Shortcode in Metadaten posten gespeichert ist. Hier ist, was ich verwende, um festzustellen, ob mein Plugin-Shortcode in aktuellen Post- oder Post-Metadaten vorhanden ist:

function abcd_load_my_shorcode_resources() {
       global $post, $wpdb;

       // determine whether this page contains "my_shortcode" shortcode
       $shortcode_found = false;
       if ( has_shortcode($post->post_content, 'my_shortcode') ) {
          $shortcode_found = true;
       } else if ( isset($post->ID) ) {
          $result = $wpdb->get_var( $wpdb->prepare(
            "SELECT count(*) FROM $wpdb->postmeta " .
            "WHERE post_id = %d and meta_value LIKE '%%my_shortcode%%'", $post->ID ) );
          $shortcode_found = ! empty( $result );
       }

       if ( $shortcode_found ) {
          wp_enqueue_script(...);
          wp_enqueue_style(...);
       }
}
add_action( 'wp_enqueue_scripts', 'abcd_load_my_shorcode_resources' );
5
zdenekca

Ich mache so:

class My_Shortcode {

    function __construct() {
        do_action('my_start_shortcode'); // call
....

und catch hook in anderen Funktionen (oder anderen Plugins):

function wpse_3232_load_script(){
    wp_enqueue_script('js-myjs');
}
add_action('my_start_shortcode','wpse_3232_load_script',10);
2

Ich habe für mein eigenes Plugin herausgefunden, ob der Shortcode im Text-Widget vorhanden ist.

function check_shortcode($text) {

  $pattern = get_shortcode_regex();

   if (   preg_match_all( '/'. $pattern .'/s', $text, $matches )
        && array_key_exists( 2, $matches )
        && in_array( 'myshortcode', $matches[2] ) )
    {
        // myshortcode is being used

        // enque my css and js
        /****** Enqueu RFNB  ******/
        wp_enqueue_style('css-mycss');
        wp_enqueue_script('js-myjs');

        // OPTIONAL ALLOW SHORTCODE TO WORK IN TEXT WIDGET
        add_filter( 'widget_text', 'shortcode_unautop');
        add_filter( 'widget_text', 'do_shortcode'); 

    }

  return $text;

}
add_filter('widget_text', 'check_shortcode');
1
Gino

WordPress hat eine eingebaute Funktion, um etwas basierend auf einem bestimmten Shortcode-Präsentationsstatus zu tun. Der Funktionsname lautet has_shortcode() . Mit dem folgenden Code können Sie Ihren Stil und Ihre Skripte in eine Warteschlange einreihen.

Hier habe ich die is_a( $post, 'WP_Post' ) verwendet, um zu überprüfen, ob das $post-Objekt zur WP_Post-Klasse gehört, und ich habe $post->post_content verwendet, um den Inhalt der Posts zu überprüfen.

if ( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'shortcode_tag') ) {
    wp_enqueue_style( 'handle', get_template_directory_uri() . '/your_file_filename.css' );
}
1
Arif Rahman

Ich habe eine Kombination aus dem Beispielcode der Wordpress-Seite für has_shortcode () und der Antwort zndencka erstellt. Mir ist aufgefallen, dass die Funktion has_shortcode in Wordpress 3.6 hinzugefügt wurde. Deshalb überprüfe ich zuerst, ob die Funktion vorhanden ist. Vielleicht ist diese Überprüfung ein bisschen veraltet, da laut wordpress ihre eigenen Statistiken nicht mehr viele Benutzer unter WordPress 3.6 sind.

// This makes sure the styling is already enqueued in the header, so before the shortcode loads in the page/post
function enqueue_shortcode_header_script() {
    global $post;
    if ( function_exists( 'has_shortcode' ) ){  // is added in wordpress 3.6
        // Source: https://codex.wordpress.org/Function_Reference/has_shortcode
        if( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'my_shortcode') ) {
            wp_enqueue_style( 'shortcode-css' );
        }
    }
    else if ( isset($post->ID) ) { // Small percentage wordpress users are below 3.6 https://wordpress.org/about/stats/
        global $wpdb;
        $result = $wpdb->get_var(
          $wpdb->prepare(
              "SELECT count(*) FROM $wpdb->postmeta " .
              "WHERE post_id = %d and meta_value LIKE '%%my_shortcode%%'",
               $post->ID )
        );
        if (!empty( $result )) { wp_enqueue_style( 'shortcode-css' ); }
    }
}
add_action( 'wp_enqueue_scripts', 'enqueue_shortcode_header_script');
0
Vasco