Publicado originalmente en 2013. Revisado y actualizado para las versiones actuales de WordPress.
Para mostrar avisos o novedades en el panel de WordPress sin saturar el servidor ni depender de plugins externos, la combinación de add_meta_box o wp_add_dashboard_widget con wp_remote_get y transients es limpia, eficiente y fácil de mantener.
¿Metabox o widget de escritorio?
Depende de dónde quieras que aparezca la información. Si solo necesitas mostrarlo en la página de edición de un post o CPT concreto, usa add_meta_box. Si prefieres que sea visible en el dashboard principal para todos los usuarios con acceso, wp_add_dashboard_widget es la opción correcta. En este tutorial cubriremos ambas vías porque el código de obtención de datos es idéntico.
Preparando el JSON remoto
Supongamos que tienes un endpoint en tu servidor que devuelve algo así:
{
"items": [
{
"date": "2025-04-01",
"title": "Nueva versión del plugin",
"message": "Ya puedes actualizar a la 2.3. Se han corregido tres bugs críticos.",
"type": "info"
}
]
}El campo “type” puede ser info, warning o error para aplicar clases CSS distintas.
Cacheando con transients
Usar wp_remote_get en cada carga del panel es una pésima idea. Vamos a guardar la respuesta durante 6 horas con set_transient. Si el transient existe, lo usamos; si no, hacemos la petición y lo guardamos.
Función principal de obtención de datos
function netcodes_get_remote_news() {
$transient_key = 'netcodes_remote_news';
$data = get_transient( $transient_key );
if ( false === $data ) {
$response = wp_remote_get( 'https://tusitio.com/news.json', [
'timeout' => 8,
] );
if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {
$data = [];
} else {
$body = wp_remote_retrieve_body( $response );
$data = json_decode( $body, true );
if ( ! is_array( $data ) || empty( $data['items'] ) ) {
$data = [];
}
}
set_transient( $transient_key, $data, 6 * HOUR_IN_SECONDS );
}
return $data;
}Opción 1: Metabox en edición de post
Lo habitual es añadirlo solo en ciertos post types. Aquí lo ponemos en ‘post’ y ‘page’.
add_action( 'add_meta_boxes', 'netcodes_add_news_metabox' );
function netcodes_add_news_metabox() {
add_meta_box(
'netcodes_news_metabox',
'Novedades del equipo',
'netcodes_render_news_metabox',
[ 'post', 'page' ],
'side',
'high'
);
}Y la función de renderizado:
function netcodes_render_news_metabox() {
$news = netcodes_get_remote_news();
if ( empty( $news['items'] ) ) {
echo 'No hay novedades por ahora.
';
return;
}
echo '';
foreach ( $news['items'] as $item ) {
$class = 'notice-' . sanitize_html_class( $item['type'] ?? 'info' );
printf(
'- %s
%s (%s) ',
esc_attr( $class ),
esc_html( $item['title'] ),
esc_html( $item['message'] ),
esc_html( $item['date'] )
);
}
echo '
';
}Opción 2: Widget en el dashboard
Más visible y útil si quieres que todos los editores lo vean nada más entrar.
add_action( 'wp_dashboard_setup', 'netcodes_add_dashboard_news_widget' );
function netcodes_add_dashboard_news_widget() {
wp_add_dashboard_widget(
'netcodes_dashboard_news',
'Últimas novedades',
'netcodes_render_dashboard_news_widget'
);
}El renderizado es casi idéntico al del metabox, solo cambiamos el contenedor:
function netcodes_render_dashboard_news_widget() {
$news = netcodes_get_remote_news();
if ( empty( $news['items'] ) ) {
echo 'No hay avisos pendientes.
';
return;
}
echo '';
foreach ( $news['items'] as $item ) {
$class = 'notice notice-' . sanitize_html_class( $item['type'] ?? 'info' );
printf(
'%s
%s
%s
',
esc_attr( $class ),
esc_html( $item['title'] ),
esc_html( $item['message'] ),
esc_html( $item['date'] )
);
}
echo '';
}Añadiendo algo de CSS
Para que no quede feo, puedes encolar una hoja de estilos solo en el admin.
add_action( 'admin_enqueue_scripts', 'netcodes_news_styles' );
function netcodes_news_styles( $hook ) {
if ( 'index.php' !== $hook && ! in_array( get_current_screen()->base, [ 'post', 'page' ], true ) ) {
return;
}
wp_add_inline_style( 'wp-admin', '
.netcodes-news-list li { margin-bottom: 1em; padding: 8px; border-left: 4px solid; }
.notice-info { border-color: #0073aa; }
.notice-warning { border-color: #dba617; }
.notice-error { border-color: #d63638; }
' );
}Limpiando el transient cuando sea necesario
Si publicas una noticia urgente y quieres forzar la recarga inmediata, puedes borrar el transient desde otro endpoint o simplemente añadir un botón de “Recargar” en el propio widget.
if ( isset( $_GET['netcodes_flush_news'] ) ) {
delete_transient( 'netcodes_remote_news' );
}Con esto ya tienes un sistema ligero que no hace peticiones innecesarias, muestra la información donde quieras y es fácil de mantener. El uso de transients es clave: reduce la latencia y evita que un JSON que tarde en responder te ralentice todo el panel.
En proyectos reales este patrón se usa mucho para mostrar avisos de compatibilidad, recordatorios de actualizaciones o comunicados internos del equipo. Simple, directo y sin dependencias raras.