Laden von JavaScript / CSS für Shortcodes

Ich habe ein Plugin veröffentlicht, das einen Shortcode erstellt und eine JavaScript-Datei und eine CSS-Datei benötigt, um auf jede Seite geladen zu werden, die diesen Shortcode enthält. Ich könnte das Script / Style auf allen Seiten laden, aber das ist nicht die beste Vorgehensweise. Ich möchte nur die Dateien auf Seiten laden, die den Shortcode aufrufen. Ich habe zwei Methoden gefunden, dies zu tun, aber beide haben Probleme.

Methode 1 legt ein Flag innerhalb der Kurzwahlhandlerfunktion auf True fest und überprüft dann den Wert in einem wp_footer callback. Wenn es wahr ist, verwendet es wp_print_scripts() , um das JavaScript zu laden. Das Problem dabei ist, dass es nur für JavaScript und nicht für CSS funktioniert, da CSS innerhalb von deklariert werden sollte, was nur während eines frühen wp_head wie init oder wp_head .

Methode 2 wird früh ausgetriggers und “guckt voraus”, um festzustellen, ob der Shortcode im aktuellen Seiteninhalt vorhanden ist. Ich mag diese Methode viel besser als die erste, aber das Problem damit wird es nicht erkennen, ob die Vorlage do_shortcode() .

Ich versuche also, die zweite Methode zu verwenden und dann zu erkennen, ob eine Vorlage zugewiesen ist, und wenn ja, parse sie für den Shortcode. Bevor ich das tue, wollte ich jedoch überprüfen, ob jemand eine bessere Methode kennt.

Update: Ich habe die Lösung in mein Plugin integriert. Wenn jemand neugierig ist, es in einer Live-Umgebung zu sehen, können Sie es herunterladen oder durchsuchen .

Update 2: Ab WordPress 3.3 ist es jetzt möglich, wp_enqueue_script() direkt in einem Shortcode-Callback wp_enqueue_script() , und die JavaScript-Datei wird in der Fußzeile des Dokuments aufgerufen. Das ist technisch auch für CSS-Dateien möglich, sollte aber als schlechte Praxis betrachtet werden, da die Ausgabe von CSS außerhalb des -Tags gegen W3C-Spezifikationen verstößt, FOUC-Fälle verursachen und den Browser zwingen kann, die Seite erneut zu rendern.

Solutions Collecting From Web of "Laden von JavaScript / CSS für Shortcodes"

Basierend auf meiner eigenen Erfahrung habe ich eine Kombination von Methode 1 und 2 verwendet – das Architektur- und Fußzeilenskript von 1 und die “Look-ahead” -Technik von 2.

Für die Vorausschau verwende ich Regex anstelle von stripos ; persönliche Präferenz, schneller, und kann nach “missgebildeten” Shortcode suchen;

 preg_match( '#\[ *shortcode([^\]])*\]#i', $content ); 

Wenn Sie sich darüber Sorgen machen, dass Autoren do_shortcode manuell verwenden, würde ich entscheiden, sie anzuweisen, einen Aktionsaufruf zu verwenden, um Ihren vorregistrierten Stil manuell einzureihen.

UPDATE : Für den faulen Autor, der nie RTFM, eine Nachricht ausgeben, um den Fehler ihrer Wege zu markieren;)

 function my_shortcode() { static $enqueued; if ( ! isset( $enqueued ) ) $enqueued = wp_style_is( 'my_style', 'done' ); // cache it so we don't repeat if called over and over // do shortcode $output = ''; if ( ! $enqueued ) // you can output the message on first occurence only by wrapping it in the previous if $output .= < <Attention! You must enqueue the shortcode stylesheet yourself if calling do_shortcode() directly! 

Use wp_enqueue_style( 'my_style' ); before your get_header() call inside your template.

HTML; return $output; }

Ich bin spät dran, diese Frage zu beantworten, aber seit Ian diesen Thread auf der wp-hackers-Liste gestartet hat, war ich der Meinung, dass es sich lohnt, darauf zu antworten, besonders da ich geplant habe, einige Plugins, an denen ich gearbeitet habe, mit einer solchen function auszustatten.

Ein Ansatz, den Sie in Betracht ziehen sollten, besteht darin, das Laden der ersten Seite zu überprüfen, um zu sehen, ob der Shortcode tatsächlich verwendet wird, und dann den Status der Shortcode-Verwendung in einem Post-Metaschlüssel zu speichern. Hier ist wie:

Schritt-für-Schritt Anleitung

  1. Setzen Sie ein $shortcode_used Flag auf 'no' .
  2. Setzen Sie in der Shortcode-function das $shortcode_used Flag auf 'yes' .
  3. Setzen Sie eine 'the_content' Hook-Priorität 12 die ist, nachdem WordPress 'the_content' verarbeitet hat und post-meta für eine '' Verwendung des Schlüssels "_has_{$shortcode_name}_shortcode" . (Ein Wert von '' wird zurückgegeben, wenn für die Post-ID kein Post-Metaschlüssel existiert.)
  4. Verwenden Sie einen 'save_post' Hook, um das Post-Meta-Löschen des persistenten Flags für diesen Post zu löschen, falls der Benutzer die Verwendung von 'save_post' ändert.
  5. Verwenden Sie wp_remote_request() auch im 'save_post' Hook, um ein nicht blockierendes HTTP GET an den eigenen Permalink des wp_remote_request() zu senden, um das Laden der ersten Seite und das Setzen des persistenten Flags auszulösen.
  6. Zuletzt setzen Sie einen 'wp_print_styles' und überprüfen Sie Post-Meta für einen Wert von 'yes' , 'no' oder '' mit dem Schlüssel "_has_{$shortcode_name}_shortcode" . Wenn der Wert 'no' , dienen Sie nicht dem Äußeren. Wenn der Wert 'yes' oder '' gehen Sie voran und dienen Sie dem Äußeren.

Und das sollte es tun. Ich habe ein Beispiel-Plugin geschrieben und getestet, um zu zeigen, wie das alles funktioniert.

Beispiel-Plugin-Code

Das Plugin wacht über einen [trigger-css] shortcode auf, der die

Elemente auf der Seite weiß-auf-rot setzt, damit Sie sehen können, dass es funktioniert. Es nimmt ein css Unterverzeichnis an, das style.css Datei style.css mit diesem CSS enthält:

 /* * Filename: css/style.css */ h2 { color: white; background: red; } 

Und unten ist der Code in einem funktionierenden Plugin:

 < ?php /** * Plugin Name: CSS on Shortcode * Description: Shows how to conditionally load a shortcode * Author: Mike Schinkel  */ class CSS_On_Shortcode { /** * @var CSS_On_Shortcode */ private static $_this; /** * @var string 'yes'/'no' vs. true/false as get_post_meta() returns '' for false and not found. */ var $shortcode_used = 'no'; /** * @var string */ var $HAS_SHORTCODE_KEY = '_has_trigger-css_shortcode'; /** * */ function __construct() { self::$_this = $this; add_shortcode( 'trigger-css', array( $this, 'do_shortcode' ) ); add_filter( 'the_content', array( $this, 'the_content' ), 12 ); // AFTER WordPress' do_shortcode() add_action( 'save_post', array( $this, 'save_post' ) ); add_action( 'wp_print_styles', array( $this, 'wp_print_styles' ) ); } /** * @return CSS_On_Shortcode */ function this() { return self::$_this; } /** * @param array $arguments * @param string $content * @return string */ function do_shortcode( $arguments, $content ) { /** * If this shortcode is being used, capture the value so we can save to post_meta in the 'the_content' filter. */ $this->shortcode_used = 'yes'; return '

THIS POST WILL ADD CSS TO MAKE H2 TAGS WHITE ON RED

'; } /** * Delete the 'has_shortcode' meta value so that it can be regenerated * on first page load in case shortcode use has changed. * * @param int $post_id */ function save_post( $post_id ) { delete_post_meta( $post_id, $this->HAS_SHORTCODE_KEY ); /** * Now load the post asynchronously via HTTP to pre-set the meta value for $this->HAS_SHORTCODE_KEY. */ wp_remote_request( get_permalink( $post_id ), array( 'blocking' => false ) ); } /** * @param array $args * * @return array */ function wp_print_styles( $args ) { global $post; if ( 'no' != get_post_meta( $post->ID, $this->HAS_SHORTCODE_KEY, true ) ) { /** * Only bypass if set to 'no' as '' is unknown. */ wp_enqueue_style( 'css-on-shortcode', plugins_url( 'css/style.css', __FILE__ ) ); } } /** * @param string $content * @return string */ function the_content( $content ) { global $post; if ( '' === get_post_meta( $post->ID, $this->HAS_SHORTCODE_KEY, true ) ) { /** * This is the first time the shortcode has ever been seen for this post. * Save a post_meta key so that next time we'll know this post uses this shortcode */ update_post_meta( $post->ID, $this->HAS_SHORTCODE_KEY, $this->shortcode_used ); } /** * Remove this filter now. We don't need it for this post again. */ remove_filter( 'the_content', array( $this, 'the_content' ), 12 ); return $content; } } new CSS_On_Shortcode();

Beispiel Screenshots

Hier ist eine Reihe von Screenshots

Basic Post Editor, kein Inhalt

Beitragsanzeige, kein Inhalt

Basic Post Editor mit [trigger-css] Shortcode

Post-Anzeige mit [trigger-css] Shortcode

Nicht sicher, ob es 100% ist

Ich glaube, dass das oben genannte in fast allen Fällen funktionieren sollte, aber da ich gerade diesen Code geschrieben habe, kann ich nicht 100% ig sicher sein. Wenn Sie Situationen finden, in denen es nicht funktioniert, würde ich es gerne wissen, damit ich den Code in einigen Plugins beheben kann, denen ich gerade hinzugefügt habe. Danke im Voraus.

Googeln fand eine mögliche Antwort . Ich sage “Potential”, weil es gut aussieht, sollte funktionieren, aber ich bin nicht 100% überzeugt, dass es der beste Weg ist, es zu tun:

 add_action( 'wp_print_styles', 'yourplugin_include_css' ); function yourplugin_include_css() { // Check if shortcode exists in page or post content global $post; // I removed the end ' ] '... so it can accept args. if ( strstr( $post->post_content, '[yourshortcode ' ) ) { echo $csslink; } } 

Dies sollte in der Lage sein, zu überprüfen, ob der aktuelle Post einen Shortcode verwendet, und dem -Element entsprechend ein Stylesheet hinzuzufügen. Aber ich denke nicht, dass es für einen Index (dh mehrere Beiträge in der Schleife) Seite funktionieren wird … Es ist auch von einem 2-jährigen Blog-Post, so dass ich nicht einmal sicher bin, dass es mit WP 3.1.X funktioniert .

Mit einer Kombination aus TheDeadMedics Antwort und der get_shortcode_regex () -Dokumentation (die meine Shortcodes tatsächlich nicht gefunden hat) habe ich eine einfache function erstellt, mit der Skripte für mehrere Shortcodes in Warteschlangen eingereiht werden können. Da wp_enqueue_script () in shortcodes nur zur Fußzeile hinzugefügt wird, kann dies hilfreich sein, da es sowohl Kopf- als auch Fußzeilenskripte verarbeiten kann.

 function add_shortcode_scripts() { global $wp_query; $posts = $wp_query->posts; $scripts = array( array( 'handle' => 'map', 'src' => 'http://maps.googleapis.com/maps/api/js?sensor=false', 'deps' => '', 'ver' => '3.0', 'footer' => false ), array( 'handle' => 'contact-form', 'src' => get_template_directory_uri() . '/library/js/jquery.validate.min.js', 'deps' => array( 'jquery' ), 'ver' => '1.11.1', 'footer' => true ) ); foreach ( $posts as $post ) { foreach ( $scripts as $script ) { if ( preg_match( '#\[ *' . $script['handle'] . '([^\]])*\]#i', $post->post_content ) ) { // enqueue css and/or js if ( wp_script_is( $script['handle'], 'registered' ) ) { return; } else { wp_register_script( $script['handle'], $script['src'], $script['deps'], $script['ver'], $script['footer'] ); wp_enqueue_script( $script['handle'] ); } } } } } add_action( 'wp', 'add_shortcode_scripts' ); 

Endlich habe ich auch eine Lösung für das bedingte CSS-Laden gefunden, die für mein Plugin http://www.mapsmarker.com funktioniert und ich möchte es mit dir teilen. Es prüft, ob mein Shortcode innerhalb der aktuellen Template-Datei und header / footer.php verwendet wird und wenn ja, fügt das benötigte Stylesheet in die Kopfzeile ein:

  function prefix_template_check_shortcode( $template ) { $searchterm = '[mapsmarker'; $files = array( $template, get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'header.php', get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'footer.php' ); foreach( $files as $file ) { if( file_exists($file) ) { $contents = file_get_contents($file); if( strpos( $contents, $searchterm ) ) { wp_enqueue_style(' leafletmapsmarker', LEAFLET_PLUGIN_URL . 'leaflet-dist/leaflet.css'); break; } } } return $template; } add_action('template_include','prefix_template_check_shortcode' ); 

Für mein Plugin habe ich festgestellt, dass Benutzer manchmal einen Theme Builder haben, der Shortcode in Post-Metadaten gespeichert hat . Hier ist, was ich verwende, um zu erkennen, 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' ); 

weil CSS innerhalb deklariert werden sollte

Für CSS-Dateien können Sie diese in Ihre Shortcode-Ausgabe laden:

  

MY_CSS_LOADED Sie danach eine Konstante oder etwas wie MY_CSS_LOADED (schließen Sie das CSS nur ein, wenn die Konstante nicht gesetzt ist).

Beide Methoden sind langsamer als dieser Weg.

Für JS-Dateien können Sie dasselbe tun, wenn das zu ladende Skript eindeutig ist und keine externen Abhängigkeiten aufweist. Wenn dies nicht der Fall ist, laden Sie es in die Fußzeile, aber verwenden Sie die Konstante, um zu bestimmen, ob geladen werden muss oder nicht …

Script Logic ist ein WordPress-Plugin, mit dem Sie die volle Kontrolle über alle JavaScript- und CSS-Dateien haben. Mit diesem Plugin können Sie CSS- und JS-Dateien nur bei Bedarf auf bestimmten Seiten laden.

http://wordpress.org/plugins/script-logic/