¿Cuál es la forma preferida de agregar archivos javascript personalizados al sitio?

68

Ya he agregado mis scripts, pero quería saber la forma preferida.
Acabo de poner una <script>etiqueta directamente en header.phpmi plantilla.

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

naugtur
fuente
Eche un vistazo a mi pregunta de hace unos días , la respuesta a parte de su pregunta está ahí: - Cómo vincular archivos externos jQuery / Javascript con WordPress
Ben Everard
44
Gran pregunta! Es una pregunta muy común y algo que definitivamente necesitamos tener bien documentado aquí.
MikeSchinkel
Gracias. Ya vi eso, pero no cubrió mi pregunta por completo.
naugtur
Está bien, sabía que no respondería a todas sus preguntas, pero para las personas que naveguen en el futuro hay una referencia a la otra publicación :-)
Ben Everard
Consulte también wordpress.stackexchange.com/questions/575/…
naugtur el

Respuestas:

78

Úselo wp_enqueue_script()en su tema

La respuesta básica es usar wp_enqueue_script()en un wp_enqueue_scriptsgancho para front-end admin_enqueue_scriptspara el administrador. Puede verse más o menos así (lo que supone que está llamando desde el functions.phparchivo de su tema ; observe cómo hago referencia al directorio de la hoja de estilo):

<?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" );
}

Eso es lo básico.

Scripts predefinidos y dependientes múltiples

Pero supongamos que desea incluir jQuery y jQuery UI Sortable de la lista de scripts predeterminados incluidos con WordPress y desea que su script dependa de ellos. Fácil, solo incluya los dos primeros scripts utilizando los identificadores predefinidos definidos en WordPress y para su script proporcione un tercer parámetro para el wp_enqueue_script()cual es una matriz de los identificadores de script utilizados por cada script, de esta manera:

<?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 complemento

¿Qué pasa si quieres hacerlo en un complemento en su lugar? Use la plugins_url()función para especificar la URL de su 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 );
}

Versiones de sus scripts

También tenga en cuenta que anteriormente le dimos a nuestro complemento 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 emite en la fuente como argumento de consulta en la URL a la secuencia de comandos y sirve para obligar al navegador a volver a descargar el archivo posiblemente almacenado en caché si la versión cambia.

Cargue scripts solo en páginas donde sea necesario

La primera regla de rendimiento web dice minimizar las solicitudes HTTP, por lo que siempre que sea posible, debe limitar las secuencias de comandos para que se carguen solo donde sea necesario. Por ejemplo, si solo necesita su secuencia de comandos en el administrador, limítelo a las páginas de administración que usan el admin_enqueue_scriptsgancho 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 );
}

Cargue sus scripts en el pie de página

Si sus scripts son uno de los que deben cargarse en el pie de página, hay un quinto parámetro wp_enqueue_script()que le dice a WordPress que lo retrase y lo coloque en el pie de página (suponiendo que su tema no se haya comportado mal y que realmente llame al gancho wp_footer como todos 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 de grano más fino

Si necesita un control más detallado que eso, Ozh tiene un excelente artículo titulado Cómo: cargar Javascript con su complemento de WordPress que detalla más.

Deshabilitar secuencias de comandos para ganar control

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

  1. Combine varios archivos en archivos únicos (el kilometraje puede variar con JavaScript aquí).
  2. Cargue los archivos solo en las páginas que estamos usando el script o el estilo.
  3. ¡Deje 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 excelente artículo titulado Mejores prácticas para agregar código JavaScript a los complementos de WordPress, donde analiza el uso wp_localize_script()para permitirle establecer el valor de las variables en su PHP del lado del servidor para luego ser utilizado en su Javascript del lado del cliente.

Control de grano muy fino con wp_print_scripts()

Y, por último, si necesita un control muy detallado, puede consultarlo wp_print_scripts()como se describe en Beer Planet en una publicación titulada Cómo incluir CSS y JavaScript condicionalmente y solo cuando sea necesario por las publicaciones .

Epiloque

Eso es todo por las mejores prácticas de incluir archivos Javascript con WordPress. Si me perdí algo (que probablemente tengo), asegúrese de informarme en los comentarios para que pueda agregar una actualización para futuros viajeros.

MikeSchinkel
fuente
1
¡Ese es un artículo enorme! Ahora tengo mucho para elegir;)
naugtur
Ok, funcionó. Ahora la segunda parte de la pregunta: ¿cómo verifico si estoy en la página de inicio?
naugtur
Busque la respuesta aquí: wordpress.stackexchange.com/questions/575/…
naugtur el
3
Enganche en admin_initlugar de pedir is_admin(). Elimine el parámetro de versión si utiliza el CDN de Google; de ​​lo contrario, el caché del navegador tendrá dos versiones: una sin la cadena de consulta de otros sitios y la suya.
fuxia
@toscho - Buena llamada, actualizaré.
MikeSchinkel
11

Para complementar la maravillosa ilustración de Mikes sobre el uso de colas, solo deseo señalar que los scripts incluidos como dependencias no necesitan ser puestos en cola ...

Usaré el ejemplo debajo de los Scripts en un encabezado de complemento en 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 recortar para leer.

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 establezca dependencias, WordPress las encontrará y las pondrá en cola listas para su secuencia de comandos, por lo que no necesita hacer ninguna llamada independiente para estas secuencias de comandos.

Además, algunos de ustedes se estarán preguntando si establecer una dependencia múltiple puede hacer que los scripts salgan en el orden incorrecto, aquí déjenme dar un ejemplo

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

Si la secuencia de comandos dos dependiera de la secuencia de comandos tres (es decir, la secuencia de comandos tres debería cargarse primero), esto no importaría, WordPress determinará las prioridades en cola para esas secuencias de comandos y las mostrará en el orden correcto, en resumen, todo se resuelve automáticamente para ti por WordPress.

t31os
fuente
Creo que initno es el lugar adecuado para enviar la cola.
brasofilo
El código se copió originalmente de la respuesta de Mike, luego se ajustó para ilustrar un punto. Sin embargo, tienes razón, así que actualicé la respuesta para usar un gancho mejor y más correcto.
t31os
0

Para pequeñas secuencias de comandos, que quizás no desee incluir en un archivo separado, por ejemplo, porque se generan dinámicamente, WordPress 4.5 y otras ofertas wp_add_inline_script. Esta función básicamente bloquea el script con otro script.

Digamos, por ejemplo, que está desarrollando un tema y desea que su cliente pueda insertar sus propios scripts (como Google Analytics o AddThis) a través de la página de opciones. Luego, puede usar wp_add_inline_scriptpara enganchar esa secuencia de comandos a su archivo js principal (digamos mainjs) de esta manera:

$custom_script = get_option('my-script')
if (!empty($custom_script)) wp_add_inline_script ('mainjs', $custom_script);
cjbj
fuente
0

Mi forma preferida es lograr un buen rendimiento, por lo que, en lugar de usar wp_enqueue_script, uso HEREDOC con la API Fetch para cargar todo de forma asíncrona 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 insértelos en la cabeza, a veces junto con estilos como este:

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

Resultando en una cascada que se ve así, cargando todo de una vez pero controlando el orden de ejecución:

ingrese la descripción de la imagen aquí

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

Josh Habdas
fuente