¿Cuál es la forma recomendada de añadir archivos javascript personalizados al sitio?

19 ago 2010, 11:18:46
Vistas: 33.5K
Votos: 73

Ya he añadido mis scripts, pero quería saber cuál es la forma recomendada.
Simplemente coloqué una etiqueta <script> directamente en el header.php de mi plantilla.

¿Existe un método preferido para insertar archivos js externos o personalizados?
¿Cómo puedo vincular un archivo js a una sola página? (Tengo en mente la página de inicio)

La forma recomendada es usar wp_enqueue_script() en el archivo functions.php:


// Para agregar globalmente
function my_custom_scripts() {
    wp_enqueue_script( 'custom-js', get_template_directory_uri() . '/js/custom.js', array(), '1.0.0', true );
}
add_action( 'wp_enqueue_scripts', 'my_custom_scripts' );

// Para agregar solo en la página de inicio
function my_homepage_scripts() {
    if ( is_front_page() ) {
        wp_enqueue_script( 'homepage-js', get_template_directory_uri() . '/js/homepage.js', array(), '1.0.0', true );
    }
}
add_action( 'wp_enqueue_scripts', 'my_homepage_scripts' );
5
Comentarios

¡Excelente pregunta! Es algo muy común que la gente pregunta y definitivamente necesitamos tenerlo bien documentado aquí.

MikeSchinkel MikeSchinkel
19 ago 2010 13:03:57

Echa un vistazo a mi pregunta de hace unos días, la respuesta a parte de tu pregunta está ahí: - Cómo vincular archivos externos jQuery/JavaScript con WordPress

Ben Everard Ben Everard
19 ago 2010 12:09:50

Gracias. Ya lo había visto, pero no cubría completamente mi pregunta.

naugtur naugtur
19 ago 2010 15:18:03

Está bien, sabía que no respondería toda tu pregunta, pero para las personas que naveguen en el futuro, hay una referencia a la otra publicación :-)

Ben Everard Ben Everard
19 ago 2010 15:20:30
Todas las respuestas a la pregunta 4
10
82

Usar wp_enqueue_script() en tu tema

La respuesta básica es usar wp_enqueue_script() en el hook wp_enqueue_scripts para el front-end y admin_enqueue_scripts para el administrador. Podría verse algo así (asumiendo que lo llamas desde el archivo functions.php de tu tema; nota cómo hago referencia al directorio de la hoja de estilos):

<?php
add_action( 'wp_enqueue_scripts', 'mysite_enqueue' );

function mysite_enqueue() {
  $ss_url = get_stylesheet_directory_uri();
  wp_enqueue_script( 'mysite-scripts', "{$ss_url}/js/mysite-scripts.js" );
}

Esos son los fundamentos.

Scripts predefinidos y múltiples dependencias

Pero digamos que quieres incluir tanto jQuery como jQuery UI Sortable de la lista de scripts predeterminados incluidos con WordPress y que tu script dependa de ellos. Fácil, solo incluye los primeros dos scripts usando los handles predefinidos en WordPress y para tu script proporciona un tercer parámetro a wp_enqueue_script() que es un array de los handles de los scripts usados por cada script, así:

<?php
add_action( 'wp_enqueue_scripts', 'mysite_enqueue' );

function mysite_enqueue() {
  $ss_url = get_stylesheet_directory_uri();
  wp_enqueue_script( 'mysite-scripts', "{$ss_url}/js/mysite-scripts.js", array( 'jquery', 'jquery-ui-sortable' ) );
}

Scripts en un plugin

¿Qué pasa si quieres hacerlo en un plugin? Usa la función plugins_url() para especificar la URL de tu archivo Javascript:

<?php
define( 'MY_PLUGIN_VERSION', '2.0.1' );
add_action( 'wp_enqueue_scripts', 'my_plugin_enqueue' );

function my_plugin_enqueue() {
  wp_enqueue_script( 'my-script', plugins_url('/js/my-script.js',__FILE__), array('jquery','jquery-ui-sortable'), MY_PLUGIN_VERSION );
}

Versionado de tus scripts

También nota que arriba dimos a nuestro plugin un número de versión y lo pasamos como un 4to parámetro a wp_enqueue_script(). El número de versión se muestra en el código fuente como un argumento de consulta en la URL del script y sirve para forzar al navegador a volver a descargar un archivo posiblemente en caché si la versión cambió.

Cargar scripts solo en las páginas donde se necesitan

La primera regla del Rendimiento Web dice Minimizar las Solicitudes HTTP, así que siempre que sea posible deberías limitar los scripts para que se carguen solo donde se necesitan. Por ejemplo, si solo necesitas tu script en el administrador, limítalo a las páginas de administración usando el hook admin_enqueue_scripts en su lugar:

<?php
define( 'MY_PLUGIN_VERSION', '2.0.1' );
add_action( 'admin_enqueue_scripts', 'my_plugin_admin_enqueue' );

function my_plugin_admin_enqueue() {
  wp_enqueue_script( 'my-script', plugins_url( '/js/my-script.js', __FILE__ ), array( 'jquery', 'jquery-ui-sortable' ), MY_PLUGIN_VERSION );
}

Cargar tus scripts en el pie de página

Si tu script es uno de esos que necesita cargarse en el pie de página, hay un 5to parámetro de wp_enqueue_script() que le dice a WordPress que lo retrase y lo coloque en el pie de página (asumiendo que tu tema no se comportó mal y que efectivamente llama al hook wp_footer como todos los buenos temas de WordPress deberían):

<?php
define( 'MY_PLUGIN_VERSION', '2.0.1' );
add_action( 'admin_enqueue_scripts', 'my_plugin_admin_enqueue' );

function my_plugin_admin_enqueue() {
  wp_enqueue_script( 'my-script', plugins_url( '/js/my-script.js', __FILE__ ), array( 'jquery', 'jquery-ui-sortable' ), MY_PLUGIN_VERSION, true );
}

Control más granular

Si necesitas un control más granular que eso, Ozh tiene un gran artículo titulado Cómo: Cargar Javascript con tu Plugin de WordPress que detalla más.

Deshabilitar scripts para ganar control

Justin Tadlock tiene un buen artículo titulado Cómo deshabilitar scripts y estilos en caso de que quieras:

  1. Combinar múltiples archivos en archivos únicos (el kilometraje puede variar con JavaScript aquí).
  2. Cargar los archivos solo en las páginas donde usamos el script o estilo.
  3. Dejar de tener que usar !important en nuestro archivo style.css para hacer ajustes simples de CSS.

Pasar valores de PHP a JS con wp_localize_script()

En su blog, Vladimir Prelovac tiene un gran artículo titulado Mejor práctica para agregar código JavaScript a plugins de WordPress donde discute el uso de wp_localize_script() para permitirte establecer el valor de variables en tu PHP del lado del servidor para ser usadas posteriormente en tu Javascript del lado del cliente.

Control realmente granular con wp_print_scripts()

Y finalmente, si necesitas un control realmente granular, puedes investigar wp_print_scripts() como se discute en Beer Planet en una publicación titulada Cómo Incluir CSS y JavaScript Condicionalmente Y Solo Cuando Lo Necesiten Las Publicaciones.

Epílogo

Eso es todo sobre las Mejores Prácticas para incluir archivos Javascript con WordPress. Si me faltó algo (lo cual probablemente haya hecho), asegúrate de decírmelo en los comentarios para que pueda agregar una actualización para futuros viajeros.

19 ago 2010 13:03:06
Comentarios

¡Ese es un artículo enorme! Ahora tengo mucho para elegir ;)

naugtur naugtur
19 ago 2010 15:19:40

Ok, funcionó. Ahora la segunda parte de la pregunta - ¿cómo verifico si estoy en la página de inicio?

naugtur naugtur
19 ago 2010 16:39:58

Busca la respuesta aquí: http://wordpress.stackexchange.com/questions/575/why-isnt-is-home-working-correctly

naugtur naugtur
23 ago 2010 13:23:18

Utiliza el hook admin_init en lugar de verificar con is_admin(). Elimina el parámetro de versión si usas la CDN de Google, de lo contrario la caché del navegador mantendrá dos versiones: una sin la cadena de consulta de otros sitios y la tuya.

fuxia fuxia
10 nov 2010 01:02:40

@toscho - Buen punto, lo actualizaré.

MikeSchinkel MikeSchinkel
10 nov 2010 03:11:25

@toscho Creo que es mejor eliminar ver de forma selectiva en lugar de toda la cadena de consulta (no importa para Google pero puede ser relevante para URLs más complejos), mira mi versión en la colección de functions.php @MikeSchinkel revisa lo mismo para un truco con URLs bonitas que siempre obtendrá la versión más reciente del script desde la CDN de Google, lo aprendí recientemente

Rarst Rarst
10 nov 2010 09:14:12

@Rarst, sí, mi función afecta solo a las URIs de la CDN de Google. En otros casos puede ser útil mantener el parámetro.

fuxia fuxia
10 nov 2010 16:39:24

Mike, quizás quieras tener en cuenta que cuando declaras un array de dependencias, no necesitas encolar esos scripts individualmente. Con la mayoría de los ejemplos publicados, en realidad no necesitas un par de los encolamientos (se cargarán de todos modos, simplemente porque se han llamado como dependencias).

t31os t31os
11 nov 2010 16:28:25

@t31os - Estoy un poco saturado en este momento; ¿por qué no añades otra respuesta aquí para aprovechar la mía detallando esa sugerencia?

MikeSchinkel MikeSchinkel
11 nov 2010 18:27:59
Mostrar los 5 comentarios restantes
2
11

Para complementar la maravillosa ilustración de Mike sobre el uso de enqueues, solo deseo señalar que los scripts incluidos como dependencias no necesitan ser encolados...

Usaré el ejemplo bajo el encabezado Scripts en un Plugin de la respuesta de Mike.

define('MY_PLUGIN_VERSION','2.0.1');

add_action( 'wp_enqueue_scripts', 'my_plugin_enqueue_scripts' );
function my_plugin_enqueue_scripts() {
    wp_enqueue_script('jquery');
    wp_enqueue_script('jquery-ui-sortable');
    wp_enqueue_script('my-script',plugins_url('/js/my-script.js',__FILE__),array('jquery','jquery-ui-sortable'),MY_PLUGIN_VERSION);
}

Esto se puede reducir a...

define('MY_PLUGIN_VERSION','2.0.1');

add_action( 'wp_enqueue_scripts', 'my_plugin_enqueue_scripts' );
function my_plugin_enqueue_scripts() {
    wp_enqueue_script('my-script', plugins_url( '/js/my-script.js', __FILE__ ), array('jquery','jquery-ui-sortable'), MY_PLUGIN_VERSION);
}

Cuando estableces dependencias, WordPress las encontrará y las encolará listas para tu script, por lo que no necesitas hacer llamadas independientes para estos scripts.

Además, algunos podrían preguntarse si establecer múltiples dependencias podría causar que los scripts se carguen en el orden incorrecto. Permíteme dar un ejemplo:

wp_enqueue_script( 'first-script', 'example/path/example_script_1.js', array('second-script','third-script') );

Si el script dos dependiera del script tres (es decir, el script tres debería cargarse primero), esto no importaría, WordPress determinará las prioridades de encolado para esos scripts y los cargará en el orden correcto. En resumen, WordPress lo resuelve todo mágicamente por ti.

13 nov 2010 14:04:45
Comentarios

Creo que init no es el lugar adecuado para despachar el enqueue.

brasofilo brasofilo
22 sept 2013 02:14:01

El código fue copiado originalmente de la respuesta de Mike, luego ajustado para ilustrar un punto. Sin embargo tienes razón, así que he actualizado la respuesta para usar un hook mejor y más correcto.

t31os t31os
28 ene 2014 16:42:20
0

Para pequeños fragmentos de scripts, que quizás no quieras incluir en un archivo separado, por ejemplo porque se generan dinámicamente, WordPress 4.5 y versiones posteriores ofrece la función wp_add_inline_script. Básicamente, esta función adjunta el script a otro script.

Digamos, por ejemplo, que estás desarrollando un tema y quieres que tu cliente pueda insertar sus propios scripts (como Google Analytics o AddThis) a través de la página de opciones. Entonces podrías usar wp_add_inline_script para adjuntar ese script a tu archivo js principal (digamos mainjs) de la siguiente manera:

$custom_script = get_option('my-script')
if (!empty($custom_script)) wp_add_inline_script ('mainjs', $custom_script);
31 oct 2016 10:51:05
0

Mi forma preferida para lograr un buen rendimiento es, en lugar de usar wp_enqueue_script, utilizar HEREDOC con la Fetch API para cargar todo de manera asíncrona y en paralelo:

$jquery_script_path = '/wp-includes/js/jquery/jquery.js?ver=1.12.4';
$jquery_dependent_script_paths = [
  get_theme_file_uri( '/assets/js/global.js' ),
  get_theme_file_uri( '/assets/js/jquery.scrollTo.js' ),
  get_theme_file_uri( '/assets/js/skip-link-focus-fix.js' ),
  get_theme_file_uri( '/assets/js/navigation.js' )
];
$jquery_dependent_script_paths_json = json_encode($jquery_dependent_script_paths);
$inline_scripts = <<<EOD
<script>
(function () {
  'use strict';
  if (!window.fetch) return;
  /**
   * Fetch Inject v1.6.8
   * Copyright (c) 2017 Josh Habdas
   * @licence ISC
   */
  var fetchInject=function(){"use strict";const e=function(e,t,n,r,o,i,c){i=t.createElement(n),c=t.getElementsByTagName(n)[0],i.type=r.blob.type,i.appendChild(t.createTextNode(r.text)),i.onload=o(r),c?c.parentNode.insertBefore(i,c):t.head.appendChild(i)},t=function(t,n){if(!t||!Array.isArray(t))return Promise.reject(new Error("`inputs` must be an array"));if(n&&!(n instanceof Promise))return Promise.reject(new Error("`promise` must be a promise"));const r=[],o=n?[].concat(n):[],i=[];return t.forEach(e=>o.push(window.fetch(e).then(e=>{return[e.clone().text(),e.blob()]}).then(e=>{return Promise.all(e).then(e=>{r.push({text:e[0],blob:e[1]})})}))),Promise.all(o).then(()=>{return r.forEach(t=>{i.push({then:n=>{"text/css"===t.blob.type?e(window,document,"style",t,n):e(window,document,"script",t,n)}})}),Promise.all(i)})};return t}();
  fetchInject(
    $jquery_dependent_script_paths_json
  , fetchInject([
    "{$jquery_script_path}"
  ]));
})();
</script>
EOD;

Y luego insertarlos en el head, a veces junto con estilos de esta manera:

function wc_inline_head() {
  global $inline_scripts;
  echo "{$inline_scripts}";
  global $inline_styles;
  echo "{$inline_styles}";
}

Lo que resulta en una cascada de carga que se ve así, cargando todo a la vez pero controlando el orden de ejecución:

Cascada de carga de scripts y estilos en paralelo

Nota: Esto requiere el uso de la Fetch API, que no está disponible en todos los navegadores.

17 abr 2017 23:22:54