Wie füge ich Stylesheets nur zu Seiten mit einem bestimmten Shortcode hinzu?

8

Ich führe eine Funktion auf Seiten aus, auf denen der Shortcode [make-me-a-map]verwendet wird. Es fügt Javascript in die Seite ein und erstellt eine Karte. Dieser Teil funktioniert gut (woot!), Aber ich habe Probleme damit, die Stylesheets auf ähnliche Weise nur diesen Seiten hinzuzufügen.

functions.php (Aktuell)

add_shortcode("make-me-a-map", "create_new_map");
add_action("wp_head", "style_my_new_map");

function create_new_map () {
    global $new_map_called_for;
    $map_called_for = true;

    wp_register_script('make-a-new-map', get_template_directory_uri() . '/js/new-map.js', array('jquery'), '0.1', true);
    wp_enqueue_script('make-a-new-map');
    }

function style_my_new_map() {
    global $new_map_called_for;
    if ($new_map_called_for == true) {
        $tDir = get_template_directory_uri();

        // Echo stylesheets because wp_register_style & wp_enqueue_style don't work atm
        // And add_action('wp_enqueue_script', 'style_my_new_maps') with those functions would add style to all pages
        // Not just the ones with [make-me-a-map] shortcode
        echo "<link rel='stylesheet' href='", $tDir, "/css/new-map.css' />", PHP_EOL;

        // Echo Javascript straight to page (couldn't do it with wp_enqueue_script) to let js code know the template directory
        echo '<script type="text/javascript">var templateDir = "', get_template_directory_uri(), '";</script>', PHP_EOL;
        $map_called_for = false;
    }
}

Dies scheint leider nicht zu funktionieren. Die Stile werden allen Seiten hinzugefügt.

Ich habe wp_register_style & wp_enqueue_style nicht verwendet, da dieser Fehler immer noch <Link />Tags aus diesen Funktionen zur Fußzeile hinzufügt .

Ich hätte add_action("wp_enqueue_scripts", "style_my_new_map")stattdessen verwenden können, add_action('wp-head', "style_my_new_map")aber soweit ich sehen und überprüfen kann, gibt es keinen Unterschied? Fügt die Stylesheets weiterhin allen Seiten hinzu.

Meine Frage besteht also eigentlich aus zwei Teilen: :)

  1. Warum funktioniert die aktuelle functions.php nicht und fügt allen Seiten Stile hinzu? Ich bin mir nicht sicher, ob es der globalAnruf oder der istif Aussage ist ...
  2. Wie kann ich die Stylesheets am besten nur in den Header der Seiten einfügen, auf denen der obige Shortcode verwendet wird, vorausgesetzt, ich kenne die Seiten-IDs usw. nicht?

Danke im Voraus! P.

Padraic
quelle
Bessere Diskussion hier: wordpress.stackexchange.com/questions/165754/…
JannieT

Antworten:

1

2 Fragen also 2 Antworten :)

Warum funktioniert die aktuelle functions.php nicht und fügt allen Seiten Stile hinzu? Ich bin mir nicht sicher, ob es sich um den globalen Aufruf oder die if-Anweisung handelt ...

Es funktioniert nicht aufgrund der Reihenfolge, in der diese Funktionen aufgerufen werden. Ihr Shortcode-Rückruf wird beim Rendern von Post-Inhalten aufgerufen (höchstwahrscheinlich the_contentFunktionsaufruf).

Beide wp_enqueue_scriptsund wp_headwerden viel früher aufgerufen: wp_headirgendwo in Ihrer Themendatei header.phpund wp_enqueue_scriptswährend des wp_headAnrufs.

Wie kann ich die Stylesheets am besten nur in den Header der Seiten einfügen, auf denen der obige Shortcode verwendet wird, vorausgesetzt, ich kenne die Seiten-IDs usw. nicht?

Ich glaube nicht, dass es so einen "besten" Weg gibt. Das ist überhaupt keine gute Idee. Browser zwischenspeichern CSS-Dateien. Wenn Sie also auf allen Seiten dasselbe CSS haben, wird es vom Browser nur einmal abgerufen. Wenn es viele CSS-Dateien für verschiedene Seiten gibt, muss der Browser alle abrufen. Ich würde es also überhaupt nicht tun und diese CSS-Stile in die globale CSS-Datei aufnehmen.

Obwohl, wenn Sie es nur auf Seiten einfügen müssen, die diesen Shortcode verwenden, dann (2 Lösungen, die bessere Wahl liegt bei Ihnen; ich denke, die zweite ist besser) ...

  1. Sie können diese Stile als Inline-Stile hinzufügen. Achten Sie nur darauf, sie nicht oft einzuschließen. Geben Sie sie also mit Ihrem Shortcode aus und stellen Sie sicher, dass sie nur einmal gedruckt werden.
  2. Da Beiträge bereits ausgewählt sind, können Sie beim Aufruf von wp_head/ wp_enqueue_scriptsdiesem Hook eine Funktion hinzufügen, ausgewählte Beiträge durchlaufen, prüfen, ob sie Ihren Shortcode enthalten, und Ihr CSS bei Bedarf in die Warteschlange stellen. (Natürlich wird es nicht sehr effizient sein).
Krzysiek Dróżdż
quelle
1
Ja, # 2 ist vielleicht weniger effizient, aber definitiv besser als Inline =) Jetzt funktioniert es, Prost!
Padraic
10

Dynamisches Laden von Skripten und Stilen mithilfe von Shortcode

Vorteile

  • Durchsucht nicht jedes Mal alle Beiträge, wenn der Shortcode aufgerufen wird.
  • Kann Stile und Skripte nur dynamisch hinzufügen, wenn sich ein Shortcode auf der Seite befindet.
  • Verwendet keine regulären Ausdrücke, da diese tendenziell langsamer als strstr()oder sind strpos(). Sie können zu Regex wechseln, wenn Sie Argumente akzeptieren müssen.
  • Reduziert Dateiaufrufe

Erklärung des Codes

  1. Findet die Shortcodes auf der Seite mit dem save_postHook nur, wenn der Beitrag keine Revision ist und mit dem angegebenen übereinstimmt post_type.

  2. Speichert die gefundenen Post-IDs als Array, add_option()wobei Autoload auf yes gesetzt ist, sofern der Eintrag nicht bereits vorhanden ist. Dann wird es verwendet update_option().

  3. Verwendet Hook wp_enqueue_scripts, um unsere add_scripts_and_styles()Funktion aufzurufen .

  4. Diese Funktion ruft dann get_option()auf, um unser Array von Seiten-IDs abzurufen. Wenn der Strom $page_idin der $option_id_arrayist, werden die Skripte und Stile hinzugefügt.

Bitte beachten Sie: Ich habe den Code aus OOP Namespaced-Klassen konvertiert, sodass ich möglicherweise etwas verpasst habe. Lass es mich in den Kommentaren wissen, wenn ich es getan habe.

Codebeispiel: Suchen von Shortcode-Vorkommen

function find_shortcode_occurences($shortcode, $post_type = 'page')
{
    $found_ids = array();
    $args         = array(
        'post_type'   => $post_type,
        'post_status' => 'publish',
        'posts_per_page' => -1,
    );
    $query_result = new \WP_Query($args);
    foreach ($query_result->posts as $post) {
        if (false !== strpos($post->post_content, $shortcode)) {
            $found_ids[] = $post->ID;
        }
    }
    return $found_ids;
}

function save_option_shortcode_post_id_array( $post_id ) {
    if ( wp_is_post_revision( $post_id ) OR 'page' != get_post_type( $post_id )) {
        return;
    }
    $option_name = 'yourprefix-yourshortcode';
    $id_array = find_shortcode_occurences($option_name);
    $autoload = 'yes';
    if (false == add_option($option_name, $id_array, '', 'yes')) update_option($option_name, $id_array);
}

add_action('save_post', 'save_option_shortcode_id_array' );

Codebeispiel: Shortcode Skripte und Stile dynamisch einschließen

function yourshortcode_add_scripts_and_styles() {
    $page_id = get_the_ID();
    $option_id_array = get_option('yourprefix-yourshortcode');
    if (in_array($page_id, $option_id_array)) {
        wp_enqueue_script( $handle, $src, $deps, $ver, $footer = true );
        wp_enqueue_style( $handle, $src , $deps);
    }
}

add_action('wp_enqueue_scripts', 'yourshortcode_add_scripts_and_styles');
CommandZ
quelle
Ich habe das noch nicht getestet, aber das ist die Antwort, nach der ich gesucht habe. Es scheint solch einen minimalen Nachteil zu haben.
Jacob Raccuia
@JacobRaccuia Ich habe das vor einiger Zeit getestet und es hat funktioniert. Ich weiß nicht, wie es mit neueren Versionen von WP funktioniert, aber ich bezweifle, dass sich angesichts der Art der Plattform viel geändert hat.
CommandZ
Deshalb habe ich viel Zeit damit verbracht, dies zu perfektionieren. Es hat schwerwiegende Nachteile, wenn der Benutzer den Shortcode in einem nicht traditionellen WP eingibt. Ich habe einen Hook geschrieben, um alle benutzerdefinierten Felder zu überprüfen, die möglicherweise zur Behebung dieses Problems beitragen könnten.
Jacob Raccuia
2

Das funktioniert bei mir:

function register_my_css () {
    wp_register_style('my-style', plugins_url('styles.css', __FILE__));
}

function register_my_scripts () {
    wp_register_script('my-script', plugins_url('scripts.js', __FILE__));
}

// only enqueue the scripts / styles when the short code is called
function do_my_shortcode () {
    wp_enqueue_style('my-style');
    wp_enqueue_script('my-script');

    // do short code stuff...
}

// register css
add_action('wp_enqueue_scripts', 'register_my_css');

// register javascript
add_action('wp_enqueue_scripts', 'register_my_scripts');

// register shortcode
add_shortcode('my-shortcode', 'do_my_shortcode');

Weitere Informationen hier: http://mikejolley.com/2013/12/sensible-script-enqueuing-shortcodes/

benedict_w
quelle
1
Nein, das gibt den Shortcode über dem Inhalt aus .
Fuxia
1
Das Problem hierbei ist, dass die Stile in der Fußzeile verlinkt werden. Es wird wahrscheinlich funktionieren. Aber es ist "falsch" und es wird nicht garantiert, dass es funktioniert.
Doug Cassidy
1

Sie können sich nach dem Ausführen der Hauptabfrage an eine Aktion anschließen und feststellen, ob Sie Ihre Stile und Skripts laden müssen.

add_action('template_include', 'custom_template_include');
function custom_template_include($template) {
    if (is_single() || is_page()) {
          global $post;
          if (has_shortcode($post->post_content, 'your_short_code')) {
              add_action('wp_enqueue_scripts, 'custom_enqueue_scripts');
          }
    } 
}

function custom_enqueue_scripts() {
    //Enqueue your stuff here. 
}
Lucas Stark
quelle
1
add_action( 'wp_enqueue_scripts', 'enqueue_shortcode_styles', 1 );
function enqueue_shortcode_styles() {

    global $post;

    if ( isset($post->post_content) && is_singular(array( 'post','page' ) ) && ! has_shortcode( $post->post_content, '$tag' ) ) {

    wp_enqueue_style( 'shortcode-styles', get_stylesheet_directory_uri() . '/style.css' );

    }

}

ich würde ... benutzen has_shortcode , um den Inhalt von $ post zu überprüfen und die Skripte mit wp_enqueue_scripts zu laden, aber es hängt davon ab, wo Ihre Shortcodes eingebettet sind.

Tauschen Sie $ tag mit Ihrem Shortcode-Tag im obigen Code aus.

Fügen Sie Ihrer untergeordneten Themenfunktionsdatei hinzu und ändern Sie die Bedingungen bei Bedarf.

Dev
quelle
0

Eine viel einfachere Lösung, die für mich funktioniert hat, bestand darin, das Skript außerhalb der Shortcode-Funktion zu registrieren und das Skript dann innerhalb der Funktion in die Warteschlange zu stellen. Dann lädt es das Skript nur auf Seiten mit Ihrem Shortcode.

wp_register_script('make-a-new-map', get_template_directory_uri() . '/js/new-map.js', array('jquery'), '0.1', true);
wp_register_style('make-a-new-map-style', get_template_directory_uri() . '/css/new-map.css');

add_shortcode("make-me-a-map", "create_new_map");
add_action("wp_head", "style_my_new_map");

function create_new_map () {
   wp_enqueue_script('make-a-new-map');
   wp_enqueue_style('make-a-new-map-style');

   global $new_map_called_for;
   $map_called_for = true;
}

Eine Beschreibung dieser Methode finden Sie hier: http://mikejolley.com/2013/12/sensible-script-enqueuing-shortcodes/

Beachten Sie, dass dadurch das CSS in die Fußzeile geladen wird, was möglicherweise nicht wünschenswert oder W3C-gültig ist. In meinem Fall war das kein Problem.

stellarcowboy
quelle
0

Sie können es einfach so machen:

// shortcode hook
add_shortcode("make-me-a-map", "create_new_map");

// shortcode callback
function style_my_new_map() {
    global $new_map_called_for;
    if ($new_map_called_for == true) {
  wp_register_script('make-a-new-map', get_template_directory_uri() . '/js/new-map.js', array('jquery'), '0.1', true);
  wp_enqueue_script('make-a-new-map');

// the rest of your codes
    }
}

Es funktioniert auch für Stylesheets. Um Ihr Stylesheet zuletzt zu laden, fügen Sie Ihrem Shortcode-Hook folgende Zahlen hinzu:

add_shortcode("make-me-a-map", "create_new_map", 9999);

Ich habe es getestet und es funktioniert.

Ari
quelle
0

Dynamisches Laden von Skripten und Stilen mithilfe von Shortcode

Dies ist erweiterter Code für die oben von Commandz bereitgestellte Lösung .

Ich habe festgestellt, dass seine Methode am besten und praktikabler ist, da die Datenbankoption an fast allen Hooks verfügbar ist.

Es wurde geändert, um das Auftreten von Shortcodes nur für den aktuellen Beitragsinhalt zu ermitteln, anstatt alle Beiträge zu durchlaufen. Dies kann langsamer sein, wenn die Anzahl der Beiträge groß ist.

Sie wird hier in zwei Zeilen geändert, nachdem eine weitere Variable $ post_id von der Aktion save_post an die Funktion find_shortcode_occurences () übergeben wurde.

if( !empty($post_id) ) {
    $args['posts__in'] = $post_id; 
}

Code für beide Funktionen geändert

function find_shortcode_occurences($shortcode, $post_id='', $post_type = 'page') {
    $found_ids = array();
    $args         = array(
        'post_type'   => $post_type,
        'post_status' => 'publish',
        'posts_per_page' => -1,
    );

    if( !empty($post_id) ) {
        $args['posts__in'] = $post_id; 
    }

    $query_result = new WP_Query($args);
    foreach ($query_result->posts as $post) {
        if (false !== strpos($post->post_content, $shortcode)) {
            $found_ids[] = $post->ID;
        }
    }
    return $found_ids;
}

add_action('save_post', 'save_option_for_sppro_pages' );
function save_option_for_sppro_pages( $post_id ) {
    if ( wp_is_post_revision( $post_id ) ) {
        return;
    }
    $option_name = 'database-option';
    $shortcode = 'shortcode-name';
    $id_array = find_shortcode_occurences($shortcode, $post_id);
    $autoload = 'yes';
    if (false == add_option($option_name, $id_array, '', 'yes')) {
        $current_value = get_option($option_name);
        $new_value = array_merge($current_value, $id_array);
        update_option($option_name, $id_array);
    }
}

Außerdem wurde eine weitere Variable hinzugefügt, sodass Sie unterschiedliche Namen für die Datenbankoption und den Shortcode-Namen haben können.

OmAk
quelle