it-swarm.com.de

wie man andere Plugins CSS-Dateien in einen Shortcode einbindet?

Ich habe ein Plugin programmiert, das unter anderem einen Shortcode erstellt. Dieser Shortcode erwartet einen post_id-Parameter, extrahiert den Inhalt dieses Posts und gibt den gefilterten Inhalt dieses Posts zurück (z. B. wendet er alle Filter an, sodass alle anderen Shortcodes in diesem Inhalt ausgeführt werden). Hier ist eine gekürzte Version des Codes:

public static function myshortcode($atts = null, $content = "")
{
  global $wp_filter, $merged_filters, $wp_current_filter, $post;

  if (is_array($atts))
    extract($atts, EXTR_OVERWRITE);

  $save_wp_filter = $wp_filter;
  $save_merged_filters = $merged_filters;
  $save_wp_current_filter = $wp_current_filter;
  $post = get_post($post_id);
  setup_postdata($post);
  $content = $post->post_content;
  $content = apply_filters('the_content', $content);        
  $content = str_replace(']]>', ']]>', $content);
  $wp_filter = $save_wp_filter;
  $merged_filters = $save_merged_filters;
  $wp_current_filter = $save_wp_current_filter;

  return $content;
}

Alle funktionieren einwandfrei, mit der Ausnahme, dass andere Plug-in-Shortcodes keine eigenen CSS-Dateien enthalten (z. B. enthält Ultimate Addons für Visual Composer eigene CSS-Dateien, die jedoch nicht enthalten sind, wenn sie auf diese Weise aufgerufen werden). Ich vermute, dass das Problem darin besteht, dass WP den Hook "the_content" für meinen Shortcode ausführt (nicht den, den ich explizit aufrufe, sondern den Hook, den WP selbst an erster Stelle aufruft, und das führt zu meiner Shortcode-Ausführung) Es ist bereits zu spät, CSS-Dateien in die Seite aufzunehmen (z. B. ist das <head> -Tag bereits geschlossen), und Wordpress hat zu diesem Zeitpunkt die Möglichkeit eingeräumt, CSS-Dateien nur in die Plugins aufzunehmen sieht nach Bedarf für die Seite aus (zB nur mein Plugin, da die Seite anfangs nur meinen Shortcode enthält).

Ich könnte wp_enqueue_style verwenden, um die erforderlichen CSS-Dateien von Drittanbietern explizit hinzuzufügen, aber das Problem ist, dass ich sie portabel einbinden möchte. Heute ist das Problem Ultimate Addons für VC, morgen wird Content Egg oder etwas anderes sein. Die beste Lösung wäre, die Funktion von WP aufzurufen, die die Entscheidung über die erforderlichen Plugins für die Seite trifft und sie aufruft, wobei sie der Funktion den tatsächlichen Inhalt übergibt, den die Seite nach meinem Shortcode haben wird ausgeführt, anstatt den Inhalt der Seite, bevor mein Shortcode fertig ist.

Existiert eine solche WP -Funktion?

BEARBEITEN:

Ja, zur Klarstellung nach Kommentaren ist mein Shortcode wie [embed_page id = "123"], außer dass ich ihn andersherum brauche, z. [embed_post id = "123"] auf einer Seite. Es besteht keine Schleifengefahr, da es nur zum Einbetten von Posts in Seiten und nicht für Posts verwendet werden soll. Und schließlich, ja, der eingebettete Inhalt enthält andere Shortcodes von Drittanbietern, die automatisch ihr eigenes CSS, JS, in die Warteschlange stellen sollen.

BEARBEITEN SIE NACH DEN ERHALTENEN ANTWORTEN:

Die kurze Antwort ist nein, es gibt keine solche Funktion in Wordpress. Die lange Antwort ist unten. Ich möchte sowohl @majick als auch @cjbj für ihre ausführlichen und detaillierten Antworten belohnen, aber ich muss eine auswählen ...

5
Lucio Crusca

Ich denke, Sie könnten dies umgehen, indem Sie die Shortcodes auf der Seite vorab ausführen, indem Sie die Inhaltsfilter anwenden, bevor der Header ausgegeben wird. Dies sollte es internen Shortcodes ermöglichen, die innerhalb des enthaltenen Posts ausgeführt werden, um alle Aktions-Hooks und damit alle benötigten Stylesheets/Ressourcen ordnungsgemäß hinzuzufügen.

add_action('wp_loaded','maybe_prerun_shortcodes');
function maybe_prerun_shortcodes() {
    if (is_page()) {
        global $post; 
        if (has_shortcode($post->post_content,'embed_post')) {
            $content = apply_filters('the_content',$post->post_content);
        }
    }
}

EDITMit den oben genannten Optionen werden nur Stylesheets und Ressourcen in die Warteschlange gestellt, die sich in innerhalb in der eingebetteten Veröffentlichung befinden sollte in diesen Fällen funktionieren, da beim Anwenden der Filter auf den aktuellen Seiteninhalt der eingebettete Shortcode ausgeführt wird, der dann Filter für den eingebetteten Beitrag anwendet (in Ihrer vorhandenen Funktion).

Um jedoch die Stylesheets für einen bestimmten Beitrag zu erhalten, müssten Sie diesen bestimmten Beitrag abrufen (weshalb die iframe-Methode in Anbetracht der bereits besprochenen Probleme in gewisser Weise funktioniert.)

Meine vorgeschlagene Problemumgehung in diesem Fall besteht darin, die in einen Beitrag geladenen Stilressourcen zu speichern, wenn der Beitrag geladen wird ...

add_filter('style_loader_tag','custom_store_style_tags',11,2)
function custom_store_style_tags($tag,$handle) {
    global $styletags; $styletags[$handle] = $tag;}
}

add_action('wp_footer','custom_save_style_tags');
function custom_save_style_tags() {
    global $embedstyles;
    if (is_single()) {
        global $styletags, $post; 
        update_post_meta($post->ID,'styletags',$styletags);
    } elseif (is_array($embedstyles)) {
        global $styletags;
        foreach ($embedstyles as $handle => $tag) {
            if (!array_key_exists($handle,$styletags)) {echo $tag;}
        }
    }
}

Dann können Sie den Shortcode verwenden, um die abzurufenden Style-Tags abzurufen, und der zweite Teil der obigen Funktion gibt sie in der Fußzeile aus:

public static function myshortcode($atts = null, $content = "")
{
  // EXISTING CODE SNIPPED

  global $embedstyles;
  $embedstyle = get_post_meta($post_id,'styletags',true);
  if (is_array($embedstyle)) {
      if (!is_array($embedstyles)) {$embedstyles = array();}
      $embedstyles = array_merge($embedstyle,$embedstyles);
  }

  return $content;
}

Dasselbe können Sie auch für Skripte über den script_loader_tag-Filter tun und die Variablen einfach so ändern, dass sie übereinstimmen ...

Natürlich besteht immer noch die Möglichkeit, dass einige body Klassen nicht von Stilen wie bereits von @cjbj erwähnt angesprochen werden, oder dass einige Skripte in der Fußzeile initialisiert werden, selbst wenn sie ordnungsgemäß in die Warteschlange gestellt wurden.

... und es berücksichtigt noch keine Inline-Stile/Skripte, die auf der Seite gedruckt (nicht in die Warteschlange gestellt) wurden ... aber es ist ein guter Anfang ... es hängt davon ab, wie weit Sie damit gehen möchten.

4
majick

Das mag eine dumme Idee sein, aber es könnte funktionieren:

1 Lassen Sie Ihren Shortcode zu einem iframemit einem benutzerdefinierten query_var ( Tutorial ) explodieren. So was:

<iframe src="http://www.example.com/?p=123&my_query_var=content_only"></iframe>

2 Erkennen Sie in Ihrem single.php den query_var und überspringen Sie in diesem Fall visuelle Kopf- und Seitenleisten sowie Fußzeilen - alles, was nicht mit dem Inhalt des Beitrags selbst verbunden ist.

Auf diese Weise laden Sie die Post wie gewohnt und vermeiden alle Probleme mit anderen Shortcodes, die nicht vollständig das tun, was sie tun sollten.

BEARBEITEN - ERKLÄRUNG NACH KOMMENTAR

Die Philosophie hinter diesem Ansatz ist, dass Sie keine Ahnung haben, was Plugins von Drittanbietern tun, möglicherweise sogar unabhängig von der Shortcode-Ausführung. Wenn Sie also versuchen, die Funktionsweise des Shortcodes abzufangen, können Sie dennoch Dinge übersehen. Beispielsweise kann ein Shortcode dazu führen, dass htmlgeneriert und eine css-Datei eingefügt wird. Das Plugin kann jedoch auch einen body_class hinzufügen, von dem der cssabhängt. Es gibt keine Möglichkeit zu wissen. Um sicherzustellen, dass sich das externe Plugin/der externe Shortcode wie erwartet verhält, ist es am besten, WP eine vollständige Seite laden zu lassen. Daher der iframename__.

Jetzt haben Sie das Problem, dass Sie eine vollständige Seite erhalten, einschließlich Kopfzeile, Menü, Seitenleisten und so weiter. Sie benötigen also eine Vorlage, die nur the_title() und the_content() und möglicherweise andere Teile des Posts ausführt. In gewisser Weise musst du WP sagen, dass du das nicht willst. WP muss wissen, ob ein normaler single.php oder ein Bare-Bones-Code generiert werden soll. Hier kommt der query_var ins Spiel. Indem Sie ihn der in Ihrem Shortcode generierten URL hinzufügen, geben Sie WP den Hinweis, dass dies kein normaler Aufruf von single.php ist. Dies ist immer noch relativ einfach, da Sie einen benutzerdefinierten query_var mit nur wenigen Codezeilen einrichten können.

Kompliziert wird es, wenn Sie Ihren Shortcode in einem Plugin haben wollen, weil Sie dann auch nicht wissen, was das Thema macht. Sie müssen das Thema überschreiben und Ihre nackten Knochen einfügen single.php. Da Sie nicht wissen, wie das Thema aufgebaut ist, können Sie nicht sicher sein, ob der Beitrag dasselbe Format wie das Thema hat. Sie könnten Ihr Plugin auch single.php analysieren lassen und unerwünschte Elemente entfernen, aber das ist eine wilde Vermutung. Es kann auch benutzerdefinierte Vorlagen wie single-custompage.php geben. Wenn Sie diesem Pfad folgen, ist es möglicherweise am besten, eine Optionsseite einzuschließen, auf der Benutzer die Stile der Beiträge festlegen können, die in Seiten enthalten sind.

3
cjbj
  • Laden Sie Visual Compose CSS

    function get_visual_composer_style($id) {
        return '<style>' . get_post_meta( $id, '_wpb_shortcodes_custom_css', true  ) .                 '</style>';
    }
    
  • Laden Sie CSS basierend auf dem Shortcode

    function custom_shortcode_scripts() {
        global $post;
        if( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'custom-shortcode') ) {
           wp_enqueue_script( 'custom-script');
        }
    }
    add_action( 'wp_enqueue_scripts', 'custom_shortcode_scripts');
    
2
Nefro