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

20 jun 2012, 17:55:42
Vistas: 35.4K
Votos: 11

En el archivo functions.php de mi tema, estoy llamando a add_action para tener cierto 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'), parece que solo se ejecuta si no hay plugins cargados. Sin embargo, el método add_action('init') funciona en todos los casos.

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

En functions.php

//if(!is_admin()){add_action('init', 'my_theme_init');} //ESTO FUNCIONA SIEMPRE
//add_action('wp_enqueue_scripts', 'my_theme_init'); //ESTO SOLO FUNCIONA CUANDO NO HAY PLUGINS

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

En functions_public.php

function my_theme_init()
{

/* PREVENIR COPIAS DUPLICADAS DE JQUERY DE LOS PLUGINS
**************************************************/
wp_deregister_script('jquery');

/* CARGAR LA COPIA LOCAL DE JQUERY DE WORDPRESS Y LOS SCRIPTS PERSONALIZADOS DEL TEMA EN EL PIE DE PÁGINA
***********************************************/
wp_register_script('jquery', get_bloginfo('template_directory').'/scripts.mythemescripts.js',false,false,true);

wp_enqueue_script('jquery');

}

El segundo método, usando add_action('wp_enqueue_scripts') aparentemente no se ejecuta en condiciones donde hay un plugin presente que escribe dependencias de scripts en el tema.

5
Comentarios

Por favor no registres tu propia copia de jQuery - usa la versión incluida con WordPress, de lo contrario podrías romper plugins :)

Stephen Harris Stephen Harris
20 jun 2012 18:02:30

Estoy de acuerdo, de hecho estoy usando la que viene con jQuery. Solo la estoy cargando en un único archivo .js (mythemescripts.js) junto con los otros archivos js que necesita mi tema, para reducir las solicitudes http.

N2Mystic N2Mystic
20 jun 2012 18:11:11

En todos los navegadores, una vez que el script se solicita desde tu sitio una vez, se almacena en caché localmente. Solo tendrás la solicitud HTTP adicional en la primera carga de página. Si combinas todos los scripts en uno solo, te verás obligado a cambiarlo cada vez que WP lance una actualización con una nueva versión de jQuery. Esto == pesadilla de mantenimiento.

EAMann EAMann
20 jun 2012 18:17:05

@EAMann, cuando el tema se instala por primera vez, y cada vez que se guarda la página de opciones de mi tema posteriormente, estoy reescribiendo el archivo 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 del tema carga el jquery que viene con esa versión. Siempre está actualizado.

N2Mystic N2Mystic
20 jun 2012 18:22:28

El problema aún ocurre cuando una llamada a jquery está contenida en el cuerpo del documento antes del pie de página. Aparentemente jQuery(document).ready se dispara antes de que el script .js se cargue en el pie de página.

N2Mystic N2Mystic
19 feb 2014 19:53:19
Todas las respuestas a la pregunta 3
2
28

Muchos desarrolladores de plugins no hacen las cosas de la manera correcta. La forma correcta es engancharse a wp_enqueue_scripts como estás intentando hacer.

Sin embargo, aquí está el orden de los hooks que se ejecutan en una petición típica:

  • muplugins_loaded
  • registered_taxonomy
  • registered_post_type
  • plugins_loaded
  • sanitize_comment_cookies
  • setup_theme
  • load_textdomain
  • after_setup_theme
  • auth_cookie_malformed
  • auth_cookie_valid
  • set_current_user
  • init
  • widgets_init
  • register_sidebar
  • 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
  • ... y muchos más

El problema es que originalmente se les dijo a varios desarrolladores que usaran el hook init para encolar sus scripts. Antes de que existiera el hook wp_enqueue_script, esa era la forma "correcta" de hacerlo, y los tutoriales que perpetúan esta práctica todavía circulan por Internet, corrompiendo a desarrolladores que por lo demás son buenos.

Mi recomendación sería dividir tu función en dos partes. Haz tu wp_deregister_script/wp_register_script en el hook init y usa el hook wp_enqueue_scripts cuando realmente encoles jQuery.

Esto te mantendrá en el mundo de "hacerlo bien" al encolar tus scripts, y te protegerá de los cientos de desarrolladores que todavía "lo hacen mal" al reemplazar jQuery por tu versión concatenada antes de que lo agreguen a la cola.

También deberás agregar tu hook init con una prioridad alta:

add_action( 'init', 'swap_out_jquery', 1 );
function swap_out_jquery() {
    // ...
}
20 jun 2012 18:38:40
Comentarios

Iba a recomendar esto, pero luego me di cuenta de que el OP en realidad estaba desregistrando jQuery, y luego registrando un script completamente diferente y llamándolo "jquery". No creo que sea una buena práctica fomentar esto, y considero que un mejor enfoque sería simplemente eliminar jQuery completamente de la cola, y luego agregar el script personalizado usando un identificador personalizado.

Chip Bennett Chip Bennett
20 jun 2012 18:51:54

Punto a tener en cuenta sobre la priority al agregar acciones. Todo depende de cómo veas la prioridad. Si quieres que la tuya se ejecute "primero", entonces un número más bajo es mejor - una prioridad más alta en el orden de la cola de ejecución. Pero si quieres que el efecto de tu función tenga precedencia sobre otras, querrás que se ejecute más tarde - así que una prioridad más alta por "efecto". Y en este caso, probablemente querrás un número más alto. Aunque hay poco mérito en reemplazar la versión RTM de jquery, como sugiere el comentarista anterior.

Paul G. Paul G.
8 jun 2019 12:10:18
2

Aquí hay múltiples problemas que están interrelacionados.

  1. El hook de acción correcto para encolar scripts es wp_enqueue_scripts
  2. Para imprimir scripts en el footer mediante wp_enqueue_script(), establece el parámetro $footer como true
  3. Tus llamadas add_action( $hook, $callback ) no deben estar envueltas en nada; déjalas ejecutarse directamente desde functions.php
  4. Debes poner tus verificaciones condicionales is_admin() dentro de tu callback
  5. No deberías desregistrar scripts incluidos en el núcleo desde un Tema, por ninguna razón. Incluso si tu propósito es concatenación de scripts, eso es territorio de Plugins.
  6. Si debes desregistrar jquery, entonces wp_enqueue_scripts es demasiado tarde. Divide tu código de desregistro/registro en un callback enganchado a init.
  7. Llamar a algún otro script "jquery" tampoco es probablemente una buena práctica. Tu mejor opción sería simplemente desencolar jQuery, y luego cargar tu script personalizado.
  8. Asegúrate de poner una prioridad baja en tu callback, para que sobrescribas Plugins
  9. Usa get_template_directory() en lugar de TEMPLATEPATH

Juntando todo:

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

        // Desencolar jQuery
        wp_dequeue_script( 'jquery' );

        // Registrar/encolar un script personalizado, que incluye 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 realmente no es el mejor enfoque. Tu mejor opción es simplemente eliminar los callbacks add_action() de plugins que desregistran el jQuery del núcleo - o usar Plugins que no hagan algo tan imprudente como reemplazar el jQuery incluido en el núcleo.

20 jun 2012 18:50:09
Comentarios

El OP está combinando la versión de jQuery distribuida por WP con otros scripts de forma programática para que su tema realice solo una solicitud HTTP y cargue todos los archivos JS. Por lo tanto, los scripts personalizados sí contienen jQuery y no romperán nada si se cargan de esta manera. Sobrescribir el handle registrado 'jquery' es necesario para evitar cargar jQuery dos veces: una en el archivo JS combinado y otra por cualquier plugin que intente encolar jQuery por su cuenta.

EAMann EAMann
20 jun 2012 18:59:14

Es semántica y prácticamente _doing_it_wrong() llamar "jQuery" a algo que no es solo jQuery. Además: jQuery en sí puede simplemente desencolarse para asegurarse de que no se cargue dos veces. La llamada a wp_dequeue_script() solo necesita ocurrir con una prioridad suficiente para garantizar que nada lo encole después.

Chip Bennett Chip Bennett
20 jun 2012 19:09:21
0

Esta respuesta no es exactamente para tu pregunta, pero hay otro problema en tu código.

Nunca necesitas usar y no deberías usar:

wp_enqueue_script('jquery');

Si quieres usar el jQuery proporcionado por WordPress, la mejor manera de hacerlo es, cuando encolas tu propio archivo JavaScript, pasar jQuery como una dependencia. De esta manera, será manejado por WordPress mismo y no necesitarás encolarlo manualmente.

Ejemplo:

wp_enqueue_script( 'myjslib-handle', get_stylesheet_directory_uri() . '/js/myfile.js', array('jquery'), '1.0.0', true );

array('jquery') en el código anterior es el parámetro que necesitamos para cargar jQuery como una dependencia.

22 oct 2021 17:52:54