Cuándo usar add_action ('init') vs add_action ('wp_enqueue_scripts')

10

En el tema functions.php de mi tema, estoy llamando a add_action para obtener una medida de control sobre dónde se carga jquery (en el pie de página junto con los otros scripts de mi tema).

El problema que tengo es que cuando uso add_action ('wp_enqueue_scripts'), solo parece activarse si no se cargan complementos. Sin embargo, el método add_action ('init') funciona en todos los casos.

No recuerdo por qué, pero creo que en este caso se prefiere add_action ('wp_enqueue_scripts'). Si eso es cierto, ¿cómo puedo hacer que funcione en todos los casos?

En functions.php

//if(!is_admin()){add_action('init', 'my_theme_init');} //THIS WORKS ALL THE TIME
//add_action('wp_enqueue_scripts', 'my_theme_init'); //THIS ONLY WORKS WHEN NO PLUGINS PRESENT

if(!is_admin())
{
    require_once(TEMPLATEPATH . '/functions_public.php');   
}

En functions_public.php

function my_theme_init()
{

/* PREVENT DUPLICATE COPIES OF JQUERY FROM PLUGINS
**************************************************/
wp_deregister_script('jquery');

/* LOAD THE LOCAL WORDPRESS COPY OF JQUERY AND THEME CUSTOM SCRIPTS IN THE FOOTER
***********************************************/
wp_register_script('jquery', get_bloginfo('template_directory').'/scripts.mythemescripts.js',false,false,true);

wp_enqueue_script('jquery');

}

El segundo método, que usa add_action ('wp_enqueue_scripts') aparentemente no se ejecuta en condiciones en las que hay un complemento que escribe las dependencias de script en el tema.

N2Mystic
fuente
55
Por favor, no registre su propia copia de jquery: use la versión incluida con WordPress, de lo contrario terminará rompiendo complementos :)
Stephen Harris
Estoy de acuerdo, en realidad estoy usando el que se envió con jQuery. Solo lo estoy cargando en un solo .js (mythemescripts.js) junto con los otros archivos js que necesita mi tema, para reducir las solicitudes http.
N2Mystic
En todos los navegadores, una vez que el script se solicita una vez desde su sitio, se almacena en caché localmente. Solo tendrá la solicitud HTTP adicional en la primera carga de la página. Si combina todos los scripts en uno solo, se verá obligado a cambiar esto cada vez que WP publique una actualización con una nueva versión de jQuery. Esta == pesadilla de mantenimiento.
EAMann
2
@EAMann, cuando el tema se instala por primera vez, y cada vez que guardo la página de opciones de mi tema, reescribo mythemescripts.js, cargando la última copia de la biblioteca jquery en él. Si el usuario actualiza su versión de WP, mi rutina de opciones de tema carga el jquery que viene con eso. Siempre está actualizado.
N2Mystic
El problema aún ocurre cuando una llamada jquery está contenida en el cuerpo del documento antes del pie de página. Aparentemente, jQuery (documento) .ready se dispara antes de que el script .js se cargue en el pie de página.
N2Mystic

Respuestas:

26

Muchos desarrolladores de complementos no hacen las cosas de la manera correcta. La forma correcta es engancharse wp_enqueue_scriptscomo lo que estás tratando de hacer.

Sin embargo, aquí está el orden de ejecución de los ganchos en una solicitud típica:

  • muplugins_loaded
  • registrado_taxonomía
  • tipo_de_publicación_registrada
  • plugins_loaded
  • sanitize_comment_cookies
  • setup_theme
  • load_textdomain
  • after_setup_theme
  • auth_cookie_malformed
  • auth_cookie_valid
  • set_current_user
  • en eso
  • widgets_init
  • registrarse_barra lateral
  • wp_register_sidebar_widget
  • wp_default_scripts
  • wp_default_stypes
  • admin_bar_init
  • add_admin_bar_menus
  • wp_loaded
  • parse_request
  • send_headers
  • parse_query
  • pre_get_posts
  • posts_selection
  • wp
  • template_redirect
  • get_header
  • wp_head
  • wp_enqueue_scripts
  • wp_print_styles
  • wp_print_scripts
  • ... mucho más

La cuestión es que a varios desarrolladores se les dijo originalmente que se conectaran initpara poner en cola sus scripts. Antes de tener un wp_enqueue_scriptgancho, esa era la forma "correcta" de hacer las cosas, y los tutoriales que perpetúan la práctica todavía están flotando en Internet, corrompiendo a los buenos desarrolladores.

Mi recomendación sería dividir su función en dos partes. Haga su wp_deregister_script/ wp_register_scripten el initgancho y use el wp_enqueue_scriptsgancho cuando realmente ponga en cola jQuery.

Esto lo mantendrá en el mundo de "hacerlo bien" para poner en cola sus scripts, y lo ayudará a protegerse de los cientos de desarrolladores que todavía "lo hacen mal" al cambiar jQuery por su versión concatenada antes de agregarlo a la cola .

También querrás agregar tu initgancho con alta prioridad:

add_action( 'init', 'swap_out_jquery', 1 );
function swap_out_jquery() {
    // ...
}
EAMann
fuente
2
Iba a recomendar esto, pero luego me di cuenta de que el OP en realidad estaba cancelando el registro de jQuery, y luego registraba un script completamente diferente y lo llamaba "jquery". No creo que sea una buena práctica alentar, y creo que una mejor ruta sería simplemente eliminar jQuery por completo , y luego colocar el script personalizado usando un controlador personalizado .
Chip Bennett
Punto a tener en cuenta sobre la priorityadición de acciones. Todo depende de cómo veas la prioridad. Si desea que el suyo se ejecute "primero", entonces un número menor es mejor, una prioridad más alta en el orden de la cola de ejecución. Pero si desea que el efecto de su función tenga prioridad sobre los demás, querrá que se ejecute más tarde, por lo que una mayor prioridad por "efecto". Y en este caso, probablemente sea un número más alto que desearía. Aunque hay poco mérito en cambiar la versión RTM de jquery, como sugiere el comentarista anterior.
Paul G.
3

Aquí hay varios problemas que están relacionados entre sí.

  1. El gancho de acción correcto para utilizar para poner en cola los scripts es wp_enqueue_scripts
  2. Para imprimir scripts en el pie de página vía wp_enqueue_script(), establezca el $footerparámetro entrue
  3. Sus add_action( $hook, $callback )llamadas no deben estar envueltas en nada; déjalos ejecutar directamente desdefunctions.php
  4. Debe poner sus is_admin()cheques condicionales dentro de su devolución de llamada
  5. No debe cancelar el registro de las secuencias de comandos incluidas en el núcleo de un tema, por ningún motivo. Incluso si su propósito es la concatenación de scripts, ese es el territorio del complemento .
  6. Si debe cancelar el registro de jquery, entonces wp_enqueue_scriptses demasiado tarde . Divida su código de baja / registro en una devolución de llamada enganchada init.
  7. Llamar a otro script "jquery" probablemente tampoco sea una buena práctica. Su mejor opción sería simplemente eliminar jQuery y luego cargar su script personalizado.
  8. Asegúrese de asignar una baja prioridad a su devolución de llamada, de modo que anule los complementos
  9. Usar en get_template_directory()lugar deTEMPLATEPATH

Poniendolo todo junto:

<?php
function wpse55924_enqueue_scripts() {
    if ( ! is_admin() ) {

        // Dequeue jQuery
        wp_dequeue_script( 'jquery' );

        // Register/enqueue a custom script, that includes jQuery
        wp_register_script( 'mythemescripts', get_template_directory_uri() . '/scripts.mythemescripts.js', false, false,true );
        wp_enqueue_script( 'mythemescripts' ); 
    }
}
add_action( 'wp_enqueue_scripts', 'wpse55924_enqueue_scripts', 99 );

Pero de nuevo: este no es realmente el mejor enfoque. Su mejor opción es simplemente eliminar las devoluciones de llamada de plugin add_action () que anulan el registro de core jQuery, o usar Plugins que no hacen algo tan imprudente como reemplazar jQuery incluido en el núcleo.

Chip Bennett
fuente
El OP combina la versión distribuida de WP de jQuery con otros scripts programáticamente para que su tema solo haga una solicitud HTTP para cargar todos los archivos JS. Por lo tanto, los scripts personalizados contienen jQuery y no romperán nada si se cargan de esta manera. Es necesario sobrescribir el identificador 'jquery' registrado para evitar cargar jQuery dos veces, una en el archivo JS combinado y otra vez por cualquier complemento que intente poner en cola jQuery por su cuenta.
EAMann
Es semántica y prácticamente _doing_it_wrong()llamar a algo que no es solo jQuery "jQuery". Además: jQuery en sí mismo simplemente puede retirarse para asegurarse de que no se cargue dos veces. La wp_dequeue_script()llamada solo debe realizarse con una prioridad suficiente para garantizar que nada la atrape después.
Chip Bennett