web-dev-qa-db-de.com

Laden von Skripten nur, wenn ein bestimmter Shortcode oder ein bestimmtes Widget vorhanden ist

Ich brauchte eine Möglichkeit, um den Inhalt einer Seite/eines Beitrags zu filtern, bevor er geladen wurde, damit ich dem Header Skripte hinzufügen konnte, wenn ein bestimmter Shortcode vorhanden war. Nach langem Suchen stieß ich auf http://wpengineer.com

function has_my_shortcode($posts) {
    if ( empty($posts) )
        return $posts;

    $found = false;

    foreach ($posts as $post) {
        if ( stripos($post->post_content, '[my_shortcode') )
            $found = true;
            break;
        }

    if ($found){
        $urljs = get_bloginfo( 'template_directory' ).IMP_JS;

    wp_register_script('my_script', $urljs.'myscript.js' );

    wp_print_scripts('my_script');
}
    return $posts;
}
add_action('the_posts', 'has_my_shortcode');

das ist absolut genial und hat genau das getan, was ich brauchte.

Jetzt muss ich es ein bisschen weiter ausbauen und das Gleiche für Sidebars tun. Es kann sich um einen bestimmten Widget-Typ, einen Shortcode, ein Code-Snippet oder irgendetwas anderes handeln, um zu identifizieren, wann das Skript geladen werden muss.

Das Problem ist, dass ich nicht herausfinden kann, wie ich auf den Inhalt der Seitenleiste zugreifen kann, bevor die Seitenleiste geladen wird (das betreffende Thema hat mehrere Seitenleisten).

16
Ashley G

Sie können die Funktion is_active_widget verwenden. Z.B.:

function check_widget() {
    if( is_active_widget( '', '', 'search' ) ) { // check if search widget is used
        wp_enqueue_script('my-script');
    }
}

add_action( 'init', 'check_widget' );

Um das Skript auf der Seite zu laden, auf der nur das Widget geladen wird, müssen Sie in Ihrer Widget-Klasse den Code is_active_widget () hinzufügen. Siehe z. B. das Standard-Widget für aktuelle Kommentare (wp-includes/default-widgets.php, Zeile 602):

class WP_Widget_Recent_Comments extends WP_Widget {

    function WP_Widget_Recent_Comments() {
        $widget_ops = array('classname' => 'widget_recent_comments', 'description' => __( 'The most recent comments' ) );
        $this->WP_Widget('recent-comments', __('Recent Comments'), $widget_ops);
        $this->alt_option_name = 'widget_recent_comments';

        if ( is_active_widget(false, false, $this->id_base) )
            add_action( 'wp_head', array(&$this, 'recent_comments_style') );

        add_action( 'comment_post', array(&$this, 'flush_widget_cache') );
        add_action( 'transition_comment_status', array(&$this, 'flush_widget_cache') );
    }
19
sorich87

Ich wollte nur eine Lösung vorstellen, an der ich gearbeitet habe und die es mir ermöglichte, meine Implementierung etwas vielseitiger zu gestalten. Anstatt die Funktion auf eine Vielzahl von Shortcodes prüfen zu lassen, habe ich sie geändert, um einen einzelnen Shortcode zu suchen, der auf eine Skript-/Stilfunktion verweist, die in die Warteschlange gestellt werden muss. Dies funktioniert sowohl für Methoden in anderen Klassen (z. B. für Plugins, die dies möglicherweise nicht selbst ausführen) als auch für Funktionen im Gültigkeitsbereich. Legen Sie einfach den folgenden Code in functions.php ab und fügen Sie die folgende Syntax zu jeder Seite/jedem Post hinzu, auf der Sie spezifisches CSS und JS wünschen.

Page/Post-Syntax: [loadCSSandJS function = "(class-> method/function name)"]

functions.php code:

function page_specific_CSSandJS( $posts ) {
  if ( empty( $posts ) )
    return $posts;

  foreach ($posts as $post) {

    $returnValue = preg_match_all('#\[loadCSSandJS function="([A-z\-\>]+)"\]#i', $post->post_content, $types);

    foreach($types[1] as $type) {
      $items = explode("->",$type);
      if (count($items) == 2) {
        global $$items[0];      
        if( method_exists( $$items[0], $items[1] ))
          add_action( 'wp_enqueue_scripts', array(&$$items[0], $items[1]) );
      }
      else if( !empty( $type ) && function_exists( $type ))
        add_action( 'wp_enqueue_scripts', $type );
    }
  }

  return $posts;
}

Auf diese Weise können Sie auf einer Seite so viele hinzufügen, wie Sie möchten. Denken Sie daran, dass Sie zum Laden eine Methode/Funktion benötigen.

3
Nick Caporin

mit Wordpress 4.7 gibt es eine andere Möglichkeit, dies in Ihrer functions.php-Datei zu erreichen.

add_action( 'wp_enqueue_scripts', 'register_my_script');
function register_my_script(){
  wp_register_script('my-shortcode-js',$src, $dependency, $version, $inFooter);
}

zuerst müssen Sie Ihr Skript registrieren , das nicht auf Ihrer Seite gedruckt wird, es sei denn, Sie stellen es in eine Warteschlange, wenn Ihr Shortcode aufgerufen wird.

add_filter( 'do_shortcode_tag','enqueue_my_script',10,3);
function enqueue_my_script($output, $tag, $attr){
  if('myShortcode' != $tag){ //make sure it is the right shortcode
    return $output;
  }
  if(!isset($attr['id'])){ //you can even check for specific attributes
    return $output;
  }
  wp_enqueue_script('my-shortcode-js'); //enqueue your script for printing
  return $output;
}

der do_shortcode_tag wurde in WP 4.7 eingeführt und ist in der Dokumentation für neue Entwickler pages zu finden.

1
Aurovrata

Vielen Dank, dass Sie diesen Tipp geteilt haben! Es bereitete mir ein bisschen Kopfschmerzen, weil es zuerst nicht funktionierte. Ich denke, es gibt ein paar Fehler (vielleicht Tippfehler) im Code über has_my_shortcode und ich habe die Funktion wie folgt umgeschrieben:

function has_my_shortcode( $posts ) {

        if ( empty($posts) )
            return $posts;

        $shortcode_found = false;

        foreach ($posts as $post) {

            if ( !( stripos($post->post_content, '[my-shortcode') === false ) ) {
                $shortcode_found = true;
                break;
            }
        }

        if ( $shortcode_found ) {
            $this->add_scripts();
            $this->add_styles();
        }
        return $posts;
    }

Ich denke, es gab zwei Hauptprobleme: Die break befand sich nicht im Gültigkeitsbereich der if-Anweisung, und dies führte dazu, dass die Schleife immer bei der ersten Iteration unterbrochen wurde. Das andere Problem war subtiler und schwer zu entdecken. Der obige Code funktioniert nicht, wenn der Shortcode das allererste ist, was in einem Beitrag geschrieben wird. Ich musste den Operator === verwenden, um dies zu lösen.

Wie auch immer, vielen Dank, dass Sie diese Technik geteilt haben, sie hat mir sehr geholfen.

1
jekbau