Cómo usar jQuery UI en mi plugin de WordPress
Es un día triste cuando busco algo en Google y no obtengo resultados. Estoy intentando usar el datepicker por defecto (o CUALQUIER datepicker en este punto) y no puedo debido a mi falta de conocimiento con WordPress/PHP. En mi plugin, estoy intentando registrar jQuery y la UI y aparentemente estoy rompiendo otras partes de WordPress en el proceso. ¿Alguien puede decirme qué estoy haciendo mal? Si pueden proporcionar una solución funcional, descartaré todo mi código:
add_action('init', 'add_styles');
function add_styles(){
wp_deregister_style('simpleschoolstyles');
wp_register_style('simpleschoolstyles', SSM_STYLEFILE);
wp_deregister_script( 'jquery' );
wp_register_script( 'jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js');
wp_deregister_script( 'jquery-ui' );
wp_register_script('jquery-ui', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js');
wp_deregister_style( 'jquery-ui' );
wp_register_style( 'jquery-ui', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/themes/pepper-grinder/jquery-ui.min.css' );
wp_deregister_script('maskedinput');
wp_register_script('maskedinput', SSM_PLUGIN_URL . '/includes/js/jquery.maskedinput.min.js');
wp_deregister_script('simpleschool');
wp_register_script('simpleschool', SSM_PLUGIN_URL . '/includes/js/simpleschool.js');
}
add_action('wp_enqueue_scripts', 'load_scripts');
add_action('admin_enqueue_scripts', 'load_scripts');
function load_scripts()
{
wp_enqueue_style('jquery-ui');
wp_enqueue_style('simpleschoolstyles');
wp_enqueue_script('jquery');
wp_enqueue_script('jquery-ui');
wp_enqueue_script('maskedinput');
wp_enqueue_script('simpleschool');
}
Necesito que jQuery esté disponible tanto en el área de administración como en el front-end para la entrada de datos del usuario. Por favor, alguien ayúdeme. Estoy cerca de arrancarme las uñas de los pies ya que me he arrancado todo el pelo... Supongo que debo estar encolando en el momento equivocado, pero de nuevo, debido a mi limitado conocimiento de WordPress, me he cavado una tumba rápidamente.
ACTUALIZACIÓN: He modificado mi script y ahora solo cargo jQuery UI y he probado que tanto jQuery como la UI están cargados y tengo éxito para esos dos, pero no un objeto existente en el DOM:
add_action('init', 'init_scripts');
function init_scripts(){
wp_deregister_style('simpleschoolstyles');
wp_register_style('simpleschoolstyles', SSM_STYLEFILE);
//wp_deregister_script( 'jquery-ui' );
wp_register_script('jquery-ui', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js');
//wp_deregister_style( 'jquery-ui' );
wp_register_style( 'jquery-ui-pepper-grinder', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/themes/pepper-grinder/jquery-ui.min.css' );
//wp_deregister_script('maskedinput');
wp_register_script('maskedinput', SSM_PLUGIN_URL . '/includes/js/jquery.maskedinput.min.js');
//wp_deregister_script('simpleschool');
wp_register_script('simpleschool', SSM_PLUGIN_URL . '/includes/js/simpleschool.js');
wp_enqueue_style('jquery-ui-pepper-grinder');
wp_enqueue_style('simpleschoolstles');
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'jquery-ui' );
wp_enqueue_script('simpleschool');
}
Mi prueba:
jQuery(document).ready(function(){
//jQuery('.datepick').mask("99/99/9999");
//jQuery('.phone').mask("(999) 999-9999");
jQuery( '.datepick' ).datepicker( 'option', 'dateFormat', 'yyyy-mm-dd' ); // <-- esto falla ????
alert('jQuery DEBE ESTAR CARGADO!!!'); // <---esto funcionó
jQuery('<div>loco wordpress y su php</div>').dialog(); // <--- esto también funcionó
});

Dado que todas las librerías que necesitas para el datepicker están incluidas con WordPress y están registradas con todas las dependencias apropiadas, todo lo que realmente necesitas hacer es:
function enqueue_my_scripts_wpse_97533() {
wp_enqueue_script('jquery-ui-datepicker');
}
add_action('wp_enqueue_scripts','enqueue_my_scripts_wpse_97533');
Si luego revisas el código fuente de la página, verás que jQuery, jQuery-UI y jQuery-UI-Datepicker están todos cargados.
Por supuesto, necesitarás cargar cualquier otro script tú mismo de la misma manera en que ya lo estás haciendo, aunque deberías registrarlos con sus dependencias— tercer parámetro.
wp_register_script( $handle, $src, $deps, $ver, $in_footer );
Por ejemplo...
wp_register_script(
'maskedinput',
SSM_PLUGIN_URL.'/includes/js/jquery.maskedinput.min.js',
array('jquery')
);
De esa manera, podrías cargarlo con...
function enqueue_my_scripts_wpse_97533_v2() {
wp_enqueue_script('maskedinput');
}
add_action('wp_enqueue_scripts','enqueue_my_scripts_wpse_97533_v2');
... y estar seguro de que las dependencias— jQuery— también se cargarán.

¡gran respuesta! Una pregunta, ¿en qué evento hago todo esto? Necesito esto en la sección de administración también como en el front-end.

Lo que publiqué-- wp_enqueue_scripts
-- cargará en todas partes del front end, sin contar la página de inicio de sesión. Pero realmente quieres cargar los scripts solo en las páginas particulares que los necesitan, así que puedes modificar esa devolución de llamada para que sea más específica de la página. Para el backend usa admin_enqueue_scripts
pero de nuevo, realmente solo quieres cargarlos donde se necesiten. Hay varios hooks específicos de página en el backend. No puedo decir cuáles necesitas sin saber dónde necesitas los scripts.

Para complementar la excelente respuesta de @s_ha_dum, aquí hay un ejemplo que muestra cómo usar el selector de fechas jQuery UI integrado en la página de tu plugin.
El resultado se verá así:
Las partes más importantes:
- Usa el slug de tu página de opciones para encolar los scripts y hojas de estilo solo en tu página, no en todas las páginas de administración (contexto).
- Asegúrate de configurar
datepicker({ dateFormat: "yy-mm-dd" })
, para saber qué esperar en tu manejador de callback. - No hay un estilo incorporado para el selector de fechas en WordPress, así que debes encolar una hoja de estilo separada. Pero también hay un buen plugin de demostración de @helenhousandi con CSS que encaja perfectamente con los estilos principales.
Primero construí una clase base para tener algo que pueda usar en otras respuestas también y para mantener el código real del script del selector de fechas específico y simple.
Clase base Wpse_Plugin_Options_Page
/**
*
* No usamos la llamada API de Configuración aquí, porque es demasiado
* complicada.
* En su lugar usamos admin-post.php: simple, marcado limpio, funciona.
*/
class Wpse_Plugin_Options_Page
{
protected static $instance = NULL;
protected $slug = '';
protected $menu_slug = 'wpse_demo';
protected $option = 'wpse_option';
protected $title = 'WPSE Demo';
protected $styles = array();
protected $scripts = array();
public static function get_instance()
{
NULL === self::$instance and self::$instance = new self;
return self::$instance;
}
public function wp_loaded()
{
add_action(
"admin_post_update_$this->option",
array ( $this, 'admin_post' )
);
add_action(
'admin_menu',
array ( $this, 'admin_menu' )
);
}
public function admin_menu()
{
$slug = add_options_page(
$this->title, // título de la página
$this->title, // título del menú
'manage_options', // capacidad requerida
$this->menu_slug, // slug del menú
array ( $this, 'render_page_base' ) // función de callback
);
$this->slug = $slug;
add_action( "admin_print_styles-$slug", array ( $this, 'enqueue_style' ) );
add_action( "admin_print_scripts-$slug", array ( $this, 'enqueue_script' ) );
add_action( "page_content_$slug", array ( $this, 'render_page_content' ) );
}
public function render_page_base()
{
$this->print_message();
printf(
'<div class="wrap"><h2>%1$s</h2><form method="post" action="%2$s">',
$GLOBALS['title'],
admin_url( 'admin-post.php' )
);
printf(
'<input type="hidden" name="action" value="%s"/>',
"update_$this->option"
);
wp_nonce_field( "update_$this->option" );
do_action( 'page_content_' . $this->slug );
print '</form></div>';
}
protected function print_message()
{
if ( ! isset ( $_GET['msg'] ) )
return;
$text = $this->get_message_text( $_GET['msg'] );
if ( ! $text )
return;
print "<div id='message' class='updated fade'><p>$text</p></div>";
}
protected function get_message_text( $id )
{
$messages = $this->get_messages();
if ( isset ( $messages[ $id ] ) )
return $messages[ $id ];
return FALSE;
}
protected function get_messages()
{
return array();
}
public function render_page_content()
{
echo $this->slug;
}
public function enqueue_style()
{
foreach ( $this->styles as $style )
wp_enqueue_style( $style );
do_action( 'base_styles_loaded_' . $this->slug );
}
public function enqueue_script()
{
foreach ( $this->scripts as $script )
wp_enqueue_script( $script );
do_action( 'base_scripts_loaded_' . $this->slug );
}
public function admin_post()
{
if ( ! check_admin_referer( "update_$this->option" ) )
die( 'no' );
if ( ! isset ( $_POST[ $this->option ] ) )
die( 'falta algo' );
$msg = $this->save_option( $_POST[ $this->option ] );
$url = add_query_arg( 'msg', $msg, $_POST[ '_wp_http_referer' ] );
wp_safe_redirect( $url, 303 );
exit;
}
protected function save_option( $data )
{
return (bool) update_option( $this->option, $data );
}
}
Ahora solo tenemos que redefinir las partes más importantes. Agradable y breve.
Clase especial Wpse_Datepicker_Example
class Wpse_Datepicker_Example extends Wpse_Plugin_Options_Page
{
protected $title = 'Selector de fechas jQuery';
protected $menu_slug = 'wpse_datepicker';
protected $option = 'wpse_datepicker';
protected $scripts = array ( 'jquery-ui-datepicker' );
// no heredado
public static function get_instance()
{
NULL === self::$instance and self::$instance = new self;
return self::$instance;
}
public function render_page_content()
{
$value = esc_attr( get_option( $this->option ) );
printf(
'<p style="margin:100px auto;width:30em"><label for="%1$s">Elige una fecha
<input type="text" id="%1$s" name="%2$s" value="%3$s" />
</label> %4$s</p>',
'datepicker',
$this->option,
$value,
get_submit_button( 'Guardar', 'primary', 'submit', FALSE )
);
add_action(
"admin_footer-$this->slug",
array ( $this, 'print_footer_script' )
);
}
public function enqueue_style()
{
wp_register_style(
'jquery-ui-datepicker',
'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/themes/pepper-grinder/jquery-ui.min.css'
);
wp_enqueue_style( 'jquery-ui-datepicker' );
}
public function print_footer_script()
{
?>
<script>
jQuery( "#datepicker" ).datepicker({ dateFormat: "yy-mm-dd" });
</script>
<?php
}
protected function get_messages()
{
return array (
1 => 'Fecha guardada.'
);
}
}
Todavía hay mucho espacio para mejoras, pero como punto de partida debería ser útil.

Existen varias formas de incluir jQuery en un tema. Yo siempre uso la versión incluida en WordPress que me parece muy sencilla. Para configurarlo correctamente, debemos asegurarnos de que la página de WordPress incluya los siguientes archivos durante la carga. Para cargar los scripts y estilos mencionados, añade el siguiente código en el archivo functions.php del tema.
Script para uso en el front-end
function add_e2_date_picker(){
//Archivo del selector de fecha de jQuery UI
wp_enqueue_script('jquery-ui-datepicker');
//Archivo CSS del tema de jQuery UI
wp_enqueue_style('e2b-admin-ui-css','http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.0/themes/base/jquery-ui.css',false,"1.9.0",false);
}
add_action('wp_enqueue_scripts', 'add_e2_date_picker');
Script para uso en el back-end
function add_e2_date_picker(){
//Archivo del selector de fecha de jQuery UI
wp_enqueue_script('jquery-ui-datepicker');
//Archivo CSS del tema de jQuery UI
wp_enqueue_style('e2b-admin-ui-css','http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.0/themes/base/jquery-ui.css',false,"1.9.0",false);
}
add_action('admin_enqueue_scripts', 'add_e2_date_picker');
Podemos escribir una función para enlazarla a páginas específicas, como single.php, page o la página de un plugin. Yo lo he añadido u enlazado a 'options-general.php' para mostrarlo en Ajustes->Selector de Fecha. Simplemente coloca este código también en el archivo functions.php o debajo de esos códigos.
function register_datepiker_submenu() {
add_submenu_page( 'options-general.php', 'Selector de Fecha', 'Selector de Fecha', 'manage_options', 'date-picker', 'datepiker_submenu_callback' );
}
function datepiker_submenu_callback() { ?>
<div class="wrap">
<input type="text" class="datepicker" name="datepicker" value=""/>
</div>
<script>
jQuery(function() {
jQuery( ".datepicker" ).datepicker({
dateFormat : "dd-mm-yy"
});
});
</script>
<?php }
add_action('admin_menu', 'register_datepiker_submenu');
?>
Después de añadir este código, obtendrás un selector de fecha en Menú de Administración->Ajustes->Selector de Fecha. Si necesitas ayuda para implementar esta opción, plantea cualquier pregunta en los comentarios de Añadir un jQuery DatePicker a un Tema o Plugin de WordPress.
