Jaki jest pomysł na rejestrację / kolejkowanie skryptów i / lub stylów do użytku we wtyczkach?
Niedawno stworzyłem wtyczkę prostą wtyczkę, aby dodać awatar użytkownika / gravatar z krótkim kodem. Mam różne opcje wyświetlania awatara (kwadratowy, okrągły itp.) I postanowiłem umieścić css bezpośrednio w samym krótkim kodzie.
Zdaję sobie jednak sprawę, że nie jest to dobre podejście, ponieważ będzie powtarzać css za każdym razem, gdy na stronie zostanie użyty krótki kod. Widziałem kilka innych podejść na tej stronie, a kodeks wp ma nawet dwa własne przykłady, więc trudno jest ustalić, które podejście jest najbardziej spójne i najszybsze.
Oto metody, które obecnie znam:
Metoda 1: Uwzględnij bezpośrednio w krótkim kodzie - tak właśnie robię we wtyczce, ale nie wydaje się dobra, ponieważ powtarza kod.
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' ) );
Metoda 2: Użyj klasy do warunkowego kolejkowania skryptów lub stylów
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();
Metoda 3: Używanie 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' );
Metoda 4: Używanie 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');
źródło
Method 4: Using has_shortcode();
najlepiej, ponieważ zapewni to, że skrypty i style zostaną załadowane jeden raz, jeśli treść postu ma krótki kod, niezależnie od jego wielokrotnego użycia. Chociaż może nie działać w przypadku użycia krótkiego kodu w widżetach lub na pasku bocznym, nie jestem jednak pewien. Jeśli dotyczy wtyczki, nie polecam wiązania skryptów za pomocą shortcode, ponieważ niektórzy mogą wywołać twoją funkcję zamiast shortcode, aby uzyskać pożądany wynik.Odpowiedzi:
Znalazłem inny sposób, który działa dla mnie dobrze:
Podczas inicjowania wtyczki nie kolejkuj swoich skryptów i stylów, ale zarejestruj je za pomocą
wp_register_style
iwp_register_script
.Następnie możesz załadować skrypt / styl na żądanie. Na przykład podczas renderowania krótkiego kodu za pomocą
wp_enqueue_style("your_style")
iwp_enqueue_script("your_script")
.Oto przykładowa wtyczka korzystająca z tej metody, która pozwala używać get_avatar jako shortcode. Arkusz stylów jest kolejkowany tylko wtedy, gdy występuje krótki kod.
Użycie (domyślnie id dla bieżącego użytkownika):
[get_avatar id="" size="32" default="mystery" alt="Profile Photo" class="round"]
źródło
wp_enqueue_scripts
hak już się pojawił. (Skróty są analizowane, podczasthe_content
których jest częścią przechwytywaniathe_post
, co oznacza, że kolejkowanie podczas analizowania jest zbyt późne, chyba że skrypt został już zarejestrowany)Przed rozpoczęciem odpowiedzi muszę powiedzieć, że w tym temacie css i js nie są takie same.
Powód jest prosty: podczas gdy dodawanie js do treści strony (w stopce) jest powszechną i prawidłową drogą, css musi być umieszczony w
<head>
sekcji strony: nawet jeśli większość przeglądarek potrafi poprawnie renderować css na stronie body, to nie jest poprawny kod HTML.Gdy renderowany jest krótki kod,
<head>
sekcja została już wydrukowana, oznacza to, że można dodać js bez problemu w stopce, ale css musi zostać dodany przed renderowaniem krótkiego kodu.Skrypty
Jeśli twój shortcode potrzebuje tylko js, masz szczęście i możesz go użyć
wp_enqueue_script
w treści zwrotnej shortcode:W ten sposób skrypt zostanie dodany do stopki i tylko raz, nawet jeśli krótki kod zostanie użyty więcej niż jeden raz na stronie.
Style
Jeśli kod wymaga stylów, musisz działać, zanim skrót zostanie zrenderowany.
Można to zrobić na różne sposoby:
spójrz na wszystkie posty w bieżącym zapytaniu i dodaj style krótkiego kodu, jeśli to konieczne. Tak właśnie postępujesz w metodzie nr 3 i nr 4 w OP. W rzeczywistości obie metody robią to samo, ale
has_shortcode
zostały dodane w WP 3.6, podczas gdyget_shortcode_regex
są dostępne od wersji 2.5, więc używajget_shortcode_regex
tylko, jeśli chcesz, aby Twoja wtyczka była kompatybilna ze starszymi wersjami.zawsze dodawaj styl krótkiego kodu na wszystkich stronach
Zagadnienia
Problem z numerem 1 dotyczy wydajności. Regex to dość powolne operacje i uruchomienie wyrażenia regularnego w pętli wszystkich postów może konsekwentnie spowalniać stronę. Ponadto w motywach dość powszechne jest wyświetlanie tylko fragmentów postów w archiwach i wyświetlanie pełnej zawartości ze skrótami tylko w pojedynczych widokach. Jeśli tak się stanie, gdy zostanie wyświetlone archiwum, wtyczka uruchomi dopasowanie pętli regularnej w pętli w celu dodania stylu, który nigdy nie będzie używany: niepotrzebny wpływ na podwójną wydajność: spowolnienie generowania strony + dodatkowe niepotrzebne żądanie HTTP
Problem z nr 2 to znowu wydajność. Dodanie stylu do wszystkich stron oznacza dodanie dodatkowego żądania HTTP dla wszystkich stron, nawet jeśli nie jest to potrzebne. Nawet jeśli nie ma to wpływu na czas generowania strony po stronie serwera, całkowity czas renderowania strony się zmieni i dla wszystkich stron witryny.
Co powinien zrobić programista wtyczek?
Myślę, że najlepszą rzeczą jest dodanie strony wtyczki do opcji, w której użytkownicy mogą wybrać, czy shortcode powinien być obsługiwany tylko w widoku pojedynczym, czy nawet w archiwach. W obu przypadkach lepiej jest podać inną opcję wyboru, dla których typów postów włącz skrót.
W ten sposób można
"template_redirect"
przechwycić, czy bieżące zapytanie spełnia wymagania, i w takim przypadku dodać styl.Jeśli użytkownik zdecyduje się używać shortcode tylko w pojedynczych widokach postów, dobrym pomysłem jest sprawdzenie, czy post ma shortcode, czy nie: gdy wymagany jest tylko jeden wyrażenie regularne, nie powinien on zbytnio spowalniać strony.
Jeśli użytkownik zdecyduje się na użycie shortcode nawet w archiwach, unikałbym uruchomienia wyrażenia regularnego dla wszystkich postów, jeśli liczba postów jest wysoka, i po prostu kolejkuje styl, jeśli zapytanie pasuje do wymagań.
To, co należy uznać za „wysokie” pod tym względem, to skorzystanie z niektórych testów wydajności lub, alternatywnie, dodanie innej opcji i wybór dla użytkowników.
źródło
<style>
tagi w treści dokumentu są teraz prawidłowe zgodnie ze specyfikacją W3C. w3.org/TR/html52/document-metadata.html#the-style-elementW przypadku mojej wtyczki stwierdziłem, że czasami użytkownicy mają narzędzie do tworzenia motywów, w którym krótki kod jest przechowywany w metadanych post . Oto, czego używam do wykrycia, czy mój krótki kod wtyczki jest obecny w bieżących postach lub metadanych :
źródło
Tak robię:
i złap haczyka w innych funkcjach (lub innych wtyczkach):
źródło
Dowiedziałem się o własnej wtyczce, czy w widżecie tekstowym występuje krótki kod.
źródło
WordPress ma wbudowaną funkcję do robienia czegoś na podstawie określonego stanu prezentacji Shortcode. Nazwa funkcji to
has_shortcode()
. Możesz użyć następującego kodu, aby uporządkować swój styl i skrypty.Tutaj użyłem
is_a( $post, 'WP_Post' )
do sprawdzenia, czy$post
obiekt należy doWP_Post
klasy i$post->post_content
sprawdziłem zawartość postu.źródło
Zrobiłem kombinację przykładowego kodu ze strony Wordpress dla has_shortcode () i odpowiedzi udzielonej przez zndencka . Zauważyłem, że funkcja has_shortcode została dodana w Wordpress 3.6, dlatego najpierw sprawdzam, czy funkcja istnieje. Być może ta kontrola jest nieco przestarzała, ponieważ według wordpress nie ma wielu użytkowników poniżej wordpress 3.6 .
źródło
Rzeczywiście możemy warunkowo ładować pliki CSS i JS za pomocą krótkiego kodu, bez korzystania z nadmiernie skomplikowanych funkcji:
Po pierwsze, załóżmy, że wcześniej zarejestrowaliśmy wszystkie nasze pliki CSS / JS (być może po
wp_enqueue_scripts
uruchomieniu)Następnie sprawdźmy naszą funkcję shortcode:
Prosty. Gotowy. Ergo: możemy „warunkowo” ładować pliki css / js (tylko gdy działa [shortcode]).
Rozważmy następującą ideologię:
prep_css_and_js()
funkcji ładuję WSZYSTKIE pliki .css / .js, które znajdują się w określonych folderach ...Teraz, gdy WP widzi je jako zarejestrowane skrypty, możemy rzeczywiście wywoływać je warunkowo, w oparciu o prawdziwość sytuacji, w tym między innymi
my_shortcode_func()
Korzyści: (bez MySQL, bez zaawansowanych funkcji i bez filtrów)
Bibliografia:
źródło