Cómo crear un plugin de funciones personalizadas

Una de las claves del éxito de WordPress es su capacidad para extenderse sobre la base que nos ofrece de serie, es decir, poder hacer cualquier cosa que nos imaginemos a partir de su estructura «de serie».

Si os fijais, un plugin que añade una nueva funcionalidad a WordPress no es más que una extensión de un fichero: functions.php. Un fichero que encontramos en la carpeta raíz de cada tema.

En este fichero encontramos las funciones básicas para que una web funcione pero ¿Qué ocurre si deseamos agregar más funcionalidades a nuestra web?

Por suerte, existen multitud de plugins y de snippets que nos permiten extender y personalizar cualquier elemento, pero siempre hay una advertencia en el caso de querer agregar un snippet y lo haces en el archivo functions.php: «Si cambias de theme, perderás esos cambios». Esto ocurre porque al cambiar de theme, el archivo functions.php activo pasa a ser el del nuevo theme.

Es por eso que es importante que las funciones personalizadas que agreguemos a través de snippets las situemos, en la mayoría de los casos, en uno o varios plugins de funcionalidades independientes, siempre que esas funciones no vayan directamente ligadas al theme que usamos.

Cómo creo mi plugin de funcionalidades

Es sencillo, basta con crear un fichero con la extensión PHP. Lo ideal es que lo empieces con la siguiente cabecera, personalizada a tu gusto, claro.

Por mi experiencia he aprendido que para no liarte, lo mejor es incluir un índice con los snippets que vas agregando, esto va a darte una idea de un vistazo de lo que tienes en tu plugin de funcionalidades. Yo lo hago de la siguiente forma:

<?php

/*****************************************************************************************************
Plugin Name: Personalizaciones carlosmdh
Description: Personalización de WordPress
Plugin URI: http://carlosmdh.es
Version: 1.0
License: GPL
Author: Carlos M. Díaz Honrado
Author URI: http://carlosmdh.es
*****************************************************************************************************/

/* Índice
- Agregar cabeceras de seguridad
- Precargar de las DNS externas
- Desactivar las etiquetas meta robots duplicadas (A partir de WordPress 5.7)
- Mostrar un aviso en el admin bar si no se está indexando el sitio
- Eliminar elementos del menú de un plugin del admin bar (barra superior)
- Ocultar de la barra lateral el acceso a Activity log para todos los usuarios excepto para el usuario con ID = XXXX (carlosmdh)
- Ocultar la opción de actualizar automáticamente los plugins menos al usuario con ID = XXXX (carlosmdh)
- Deshabilitar el email de actualizaciones automáticas de plugins
- Deshabilitar el email de actualizaciones automáticas de temas
- Definir la estructura de los permalinks por defecto a nombre del post
... */

Y ya a partir del último elemento de este índice puedes ir añadiendo los snippets que vayas a utilizar.

En mi caso hay una serie de funciones que suelo usar en la mayoría de los sitios webs y otras que uso en función de lo que quiera personalizar en esa web.

Os dejo el archivo de funcionalidades que considero básico y que suelo agregar a todas las webs con las que trabajo. Sentiros libres de borrar las funciones que no os sean necesarias o de agregar las que deseeis:

<?php

/*****************************************************************************************************
Plugin Name: Personalizaciones carlosmdh
Description: Personalización de WordPress
Plugin URI: http://carlosmdh.es
Version: 1.0
License: GPL
Author: Carlos M. Díaz Honrado
Author URI: http://carlosmdh.es
*****************************************************************************************************/

/* Índice
- Agregar cabeceras de seguridad
- Precargar de las DNS externas
- Desactivar las etiquetas meta robots duplicadas (A partir de WordPress 5.7)
- Mostrar un aviso en el admin bar si no se está indexando el sitio
- Eliminar elementos del menú de un plugin del admin bar (barra superior)
- Ocultar la opción de actualizar automáticamente los plugins menos al usuario con ID = xxxx (carlosmdh)
- Deshabilitar el email de actualizaciones automáticas de plugins
- Deshabilitar el email de actualizaciones automáticas de temas
- Definir la estructura de los permalinks por defecto a nombre del post
- Deshabilitar el JavaScript para responder comentarios
- Dar soporte a la altura de línea personalizada en el editor
- Dar soporte unidades personalizadas
- Dar de baja los patrones de bloques por defecto de WordPress (desde WordPress 5.5)
- Dar de baja las categorías de patrones de bloques por defecto de WordPress (desde WordPress 5.5)
- Registrar un patrón de bloques (es un ejemplo, para que podáis ver como hacerlo)
- Registrar el patrón de bloques «Noticias»
- Añadir una categoría personalizada a los patrones de bloques
*/

// Agregar cabeceras de seguridad
function cmdh_agregar_cabeceras_seguridad() {
header( 'X-Content-Type-Options: nosniff' );
header( 'X-Frame-Options: SAMEORIGIN' );
header( 'X-XSS-Protection: 1;mode=block' );
header( 'Strict-Transport-Security: max-age=31536000' );
// header("Content-Security-Policy upgrade-insecure-requests; base-uri https://miweb.com; default-src 'self' data: 'unsafe-inline' 'unsafe-eval'; connect-src 'self'; font-src 'self'; form-action 'self'; frame-ancestors 'self'; frame-src 'self' *.wordpress.org; img-src 'self' data: *.gravatar.com; manifest-src 'self'; media-src 'self'; object-src 'none'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; worker-src 'self';");
// header( 'Content-Security-Policy-Report-Only: script-src https://miweb.com' ); // Antes de activar, definir que dominios externos cargan Scripts (p.e. GTM; GA; Cookiebot...)header( 'Referrer-Policy: no-referrer-when-downgrade' );
header( 'Referrer-Policy: no-referrer-when-downgrade' );
}
add_action( 'send_headers', 'cmdh_agregar_cabeceras_seguridad' );

// Precargar de las DNS externas (debes personizarlo en función de tu web. En la línea que pone <link rel="dns-prefetch" href="//miweb.com" /> hay que poner el dominio de tu web sin protocolo http://)
function cmdh_dns_prefetch() {
echo '<meta http-equiv="x-dns-prefetch-control" content="on">
<link rel="dns-prefetch" href="//miweb.com" />
<link rel="dns-prefetch" href="//fonts.googleapis.com" />
<link rel="dns-prefetch" href="//fonts.gstatic.com/" />
<link rel="dns-prefetch" href="//ajax.googleapis.com" />
<link rel="dns-prefetch" href="//apis.google.com" />
<link rel="dns-prefetch" href="//www.googletagmanager.com/" />
<link rel="dns-prefetch" href="//google-analytics.com" />
<link rel="dns-prefetch" href="//www.google-analytics.com" />
<link rel="dns-prefetch" href="//ssl.google-analytics.com" />
<link rel="dns-prefetch" href="//consent.cookiebot.com" />
<link rel="dns-prefetch" href="//consentcdn.cookiebot.com/" />';
}
add_action('wp_head', 'cmdh_dns_prefetch', 0);

// Desactivar las etiquetas meta robots duplicadas (A partir de WordPress 5.7)
remove_filter( 'wp_robots', 'wp_robots_max_image_preview_large' );

// Mostrar un aviso en el admin bar si no se está indexando el sitio
add_action('admin_bar_menu', 'cmdh_site_indexation_warning', 999);
function cmdh_site_indexation_warning($bar) {
	if (get_option('blog_public') == 0) {
		$icon = '"f530"';
		$icon_color = 'red';
	}
	echo
	'<style>
	#wpadminbar #wp-admin-bar-site-indexation-warning .ab-icon:before {
	content: ' . $icon . '; color: ' . $icon_color . ';
	}
	</style>';
	$bar->add_menu(
	[
	'id' => 'site-indexation-warning',
	'title' => '<span class="ab-icon"></span>',
	'href' => '/wp-admin/options-reading.php',
	'meta' => [
		'target' => '_self',
		'title' => '¡Cuidado! la opción «Disuadir a los motores de búsqueda de indexar este sitio» está activada',
	],
	]);
}

// Eliminar elementos del menú de un plugin del admin bar (barra superior)
 add_action( 'wp_before_admin_bar_render', 'cmdh_remove_admin_bar_menu_items', 999 );
 function cmdh_remove_admin_bar_menu_items() {
     global $wp_admin_bar;
     $wp_admin_bar->remove_menu( 'updraft_admin_node' );				// Eliminar menú de UpdraftPlus
     $wp_admin_bar->remove_menu( 'gform-forms' );						// Eliminar menú de Gravity Forms
	 $wp_admin_bar->remove_menu( 'SG_CachePress_Supercacher_Purge' );	// Eliminar menú Purgar caché de SiteGround
 }

// Ocultar la opción de actualizar automáticamente los plugins menos al usuario con ID = xxx (carlosmdh)
add_action( 'init', 'cmdh_disable_plugin_auto_update_ui' );
function cmdh_disable_plugin_auto_update_ui () {
	$user_id = get_current_user_id();
    if ( ! $user_id === xxx) { // Agregar el ID del usuario al que deseas permitir gestionar las actualizaciones automáticas de plugins
		return; 
	} else {
		add_filter( 'plugins_auto_update_enabled', '__return_false' );
	}
}

// Deshabilitar el email de actualizaciones automáticas de plugins
add_filter( 'auto_plugin_update_send_email', '__return_false' );
 
// Deshabilitar el email de actualizaciones automáticas de temas
add_filter( 'auto_theme_update_send_email', '__return_false' );

// Definir la estructura de los permalinks por defecto a nombre del post
function set_permalink(){
    global $wp_rewrite;
    $wp_rewrite->set_permalink_structure('/%postname%/');
}
add_action('init', 'set_permalink');

// Deshabilitar el JavaScript para responder comentarios
function clean_header(){ wp_deregister_script( 'comment-reply' ); } add_action('init','clean_header');

// Dar soporte a la altura de línea personalizada en el editor
add_theme_support( 'custom-line-height' );

// Dar soporte unidades personalizadas
add_theme_support( 'custom-units', 'rem', 'em' );

// Dar de baja los patrones de bloques por defecto de WordPress (desde WordPress 5.5)
add_action( 'init', 'cmdh_unregister_block_patterns' );
function cmdh_unregister_block_patterns(){
	$block_patterns = array (
    'core/two-buttons',						// Patrón «Dos botones»
		'core/three-buttons',					// Patrón «Tres botones»
		'core/text-two-columns',				// Patrón «Dos columnas de texto»
		'core/text-two-columns-with-images',	// Patrón «Dos columnas de texto con imágenes»
		'core/text-three-columns-buttons',		// Patrón «Tres columnas de texto con botones»
		'core/two-images',						// Patrón «Dos imágenes contiguas»
		'core/large-header',					// Patrón «Cabecera grande con un encabezado»
		'core/large-header-button',				// Patrón «Cabecera grande con un encabezado y un botón»
		'core/heading-paragraph',				// Patrón «Encabezado y párrafo»
		'core/quote'							// Patrón «Cita»
		);
foreach ($block_patterns as $bp ):
    unregister_block_pattern( $bp );
endforeach;
}

// Dar de baja las categorías de patrones de bloques por defecto de WordPress (desde WordPress 5.5)
add_action( 'init', 'cmdh_unregister_block_patterns_categories' );
function cmdh_unregister_block_patterns_categories(){
	$block_patterns_categories = array(
		'buttons',	// Categoria «Botones» de los patrones de bloques
		'columns',	// Categoria «Columnas» de los patrones de bloques
		'gallery',	// Categoria «Galeria» de los patrones de bloques
		'header',	// Categoria «Cabeceras» de los patrones de bloques
		'text'		// Categoria «Texto» de los patrones de bloques
	);
foreach ($block_patterns_categories as $bpc ):
	unregister_block_pattern_category ( $bpc );
endforeach;
}

/* Registrar un patrón de bloques (es un ejemplo, para que podáis ver como hacerlo)
Para ver cómo crear el código del patrón de bloque que aparece tras ´content' =>, revisa el post de 
Fernando Tellado en la siguiente url: https://ayudawp.com/como-crear-patrones-de-bloques/ */
add_action( 'init', 'cmdh_register_block_patterns' );
function cmdh_register_block_patterns() {
    register_block_pattern(
        'nombre-principal',
        array(
            'title'       => __( 'Noticias', '' ),
            'description' => _x( 'Patron para poner el contenedor principal un Título H2 y un parrafo', 'Block pattern description', 'nombre-de-categoria' ),
            'categories'  => array( 'Nombre categoría personalizada AQUI' ),
            'content'     => "<!-- wp:genesis-blocks/gb-container {"containerPaddingRight":20,"containerPaddingLeft":20,"align":"full"} -->n<div style="padding-left:20%;padding-right:20%" class="wp-block-genesis-blocks-gb-container alignfull gb-block-container"><div class="gb-container-inside"><div class="gb-container-content"><!-- wp:heading -->n<h2>Encabezado</h2>n<!-- /wp:heading -->nn<!-- wp:paragraph -->n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae euismod elit. Phasellus eu justo consectetur, consectetur tortor et, sodales sem. Vivamus dapibus lorem sit amet congue finibus. Donec interdum placerat dolor, ut aliquet urna congue nec. Sed tristique arcu non dolor sodales pulvinar. Cras auctor ligula ac commodo vehicula. Ut malesuada mattis diam id faucibus. Ut non erat in ligula pharetra commodo id ut metus. Maecenas pellentesque est at neque ultrices cursus rutrum sit amet purus. Nam vitae nibh non metus sagittis porta.</p>n<!-- /wp:paragraph -->nn<!-- wp:paragraph -->n<p><br>Sed auctor, lacus at pretium pellentesque, dui orci ultricies augue, ac tincidunt sem ligula dapibus felis. Etiam in dolor sit amet ex elementum consectetur non eu arcu. Vivamus et nisi eget orci sagittis tristique vel et nulla. Duis viverra pulvinar magna, id ultricies erat molestie sit amet. Donec malesuada odio vel leo porttitor rhoncus. Sed ut libero mollis, laoreet ligula vitae, faucibus diam. Suspendisse volutpat neque vitae erat gravida, eget convallis massa porttitor. Praesent lobortis posuere sapien, a interdum nisl eleifend ut. Nunc id ornare dolor.</p>n<!-- /wp:paragraph --></div></div></div>n<!-- /wp:genesis-blocks/gb-container -->",
        )
    );
}

// Añadir una categoría personalizada a los patrones de bloques
register_block_pattern_category(
    'Nombre categoría personalizada AQUI',
    array( 'label' => __( 'Nombre categoría personalizada AQUI', 'text-domain' ) )
);

?>

¿Dónde coloco el plugin de funcionalidades?

Una vez creado tu plugin de funcionalidades tienes dos opciones;

  • Usarlo como un plugin convencional.
  • Usarlo como un plugin imprescindible.

En el primer caso, lo que deberás hacer es crear una carpeta dentro de la carpeta plugins que se encuentra en wp-content y subir ahí el fichero. Con eso en tu listado de plugins verás uno nuevo con el nombre que le hayas puesto en la cabecera (en mi caso sería «Personalizaciones carlosmdh». Atento, tendrás un plugin que hará todo lo que le añadas pero que puede ser desactivado.

Es por eso que, en mi caso, prefiero agregarlo como un plugin imprescindible. Para ello, lo que hago es subirlo mediante FTP a la carpeta mu-plugins que también se encuentra dentro de wp-content. En el caso de no existir esa carpeta, puedes crearla sin miedo.

Esto te garantiza que las funciones que agregues a este archivo se van a ejecutar si o si y que el plugin de funcionalidades no se va a desactivar por accidente. Si quieres desactivar alguna función que hayas añadido, puedes eliminar o comentar el código y si quieres desactivar por completo el plugin, deberás borrarlo o comentarlo por completo.

Un último consejo

Esto vale tanto para este caso como cualquier código (php, css o JavaScript) que agregues, AÑADE COMENTARIOS, es decir documenta que hace cada función y, si las hubiera, documenta las opciones que podría haber, por si en un futuro necesitas cambiar algo o vas a pasar ese código a otra persona. En el ejemplo de código que os he dejado veréis que hay bastantes comentarios.

Ficha Autor

CARLOS M DÍAZ

Consultor de marketing online experto en auditorias e implementación de medición con Google

Contacta conmigo Servicios

Deja un comentario

También te puede interesar