
Lo he pensado y escrito más de una vez. No termino de entender porqué WordPress no añade determinadas funciones básicas en sus bloques de Gutenberg o tarda un siglo en llevarlas a sus versiones finales que incorpora al core, como es el caso del bloque de tablas de contenido.
En esta ocasión vamos a añadir algo muy útil y que siempre he echado de menos, que no tiene el bloque de código de Gutenberg y que considero imprescindible. Botones de copiar y descargar.
El botón de copiar usado es este deIconmonstr, tiene tooltip y confirmación visual de copiado en color verde.
El botón de descargar, también de Iconmonstr, descarga todo en formato .txt, pero para el uso que le doy, para mí es suficiente.
Ambos botones tienen un hover suave para mantener un estilo minimalista.
En cuanto al rendimiento, solo se carga en aquellas páginas donde hay bloques de código presentes y el CSS y el JS están optimizados e inline.
Puedes verlo funcionando aquí mismo en el propio bloque con el código necesario que basta añadir al archivo functions.php de tu plantilla o tema hijo.
Actualización 29/08/2026. Se añade una flecha para plegar y desplegar el bloque de código, por defecto aparece plegado y las palabras "Plegar" y "Desplegar" solo aparecen en los post en español, para el resto de idiomas solo muestra la flecha.
* Añade botones "Copiar", "DEdescargar" y "Desplegar/Plegar" a los bloques de código (PHP + JS + CSS)
* Inyecta CSS y JS solo si el post actual contiene bloques de código.
* Muestra texto + icono en español y solo icono en otros idiomas. */
if (!function_exists('botones_codigo_personalizados')) {
function botones_codigo_personalizados() {
global $post;
// Optimización: salir si no es un post o no tiene el bloque 'core/code'
if (!is_a($post, 'WP_Post') || !has_block('core/code', $post)) {
return;
}
// Detección de idioma español (Polylang o nativo de WP)
$es_espanol = false;
if (function_exists('pll_current_language')) {
$es_espanol = (pll_current_language() === 'es');
} else {
$es_espanol = (strpos(get_locale(), 'es') === 0);
}
// --- INYECCIÓN DE ESTILOS CSS ---
echo '<style>
.wp-block-code {
position: relative;
padding-top: 40px !important;
max-height: 120px;
overflow: hidden;
transition: max-height 0.25s ease-in-out;
}
.wp-block-code.is-expanded {
max-height: none;
overflow: visible;
}
.custom-code-buttons {
position: absolute;
top: 8px;
right: 12px;
display: flex;
align-items: center;
gap: 6px;
z-index: 2;
}
.custom-code-button {
background: none;
border: none;
padding: 4px;
cursor: pointer;
color: #bc080e;
border-radius: 4px;
transition: all 0.15s ease;
width: 28px;
height: 28px;
display: flex;
align-items: center;
justify-content: center;
}
.custom-code-button:hover {
color: #8f060b;
background: rgba(188, 8, 14, 0.08);
}
.custom-code-button svg {
width: 18px;
height: 18px;
}
.custom-code-toggle {
background: none;
border: none;
padding: 4px 8px;
cursor: pointer;
color: #bc080e;
border-radius: 4px;
transition: all 0.15s ease;
font-size: 13px;
font-weight: 600;
display: flex;
align-items: center;
gap: 4px;
line-height: 1;
height: 28px;
}
.custom-code-toggle:hover {
color: #8f060b;
background: rgba(188, 8, 14, 0.08);
}
.custom-code-toggle svg {
width: 16px;
height: 16px;
transition: transform 0.2s ease;
}
.wp-block-code.is-expanded .custom-code-toggle svg,
.wp-block-code.is-expanded .custom-code-toggle-icon svg {
transform: rotate(180deg);
}
@media (max-width: 480px) {
.custom-code-buttons {
top: 6px;
right: 8px;
}
}
</style>';
// --- INYECCIÓN DE JAVASCRIPT ---
echo '<script>
document.addEventListener("DOMContentLoaded", function() {
const esEspanol = ' . ($es_espanol ? 'true' : 'false') . ';
document.querySelectorAll(".wp-block-code").forEach(block => {
const container = document.createElement("div");
container.className = "custom-code-buttons";
// Botón Desplegar / Plegar
const toggleBtn = document.createElement("button");
toggleBtn.type = "button";
toggleBtn.setAttribute("notranslate", "true");
if (esEspanol) {
toggleBtn.className = "custom-code-toggle";
toggleBtn.innerHTML = \'<span>Desplegar</span><svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6z" fill="currentColor"/></svg>\';
} else {
toggleBtn.className = "custom-code-button custom-code-toggle-icon";
toggleBtn.ariaLabel = "Expand / Collapse";
toggleBtn.innerHTML = \'<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6z" fill="currentColor"/></svg>\';
}
toggleBtn.addEventListener("click", function() {
const isExpanded = block.classList.toggle("is-expanded");
if (esEspanol) {
const label = toggleBtn.querySelector("span");
if (label) {
label.textContent = isExpanded ? "Plegar" : "Desplegar";
}
}
});
// Botón Copiar
const copyBtn = document.createElement("button");
copyBtn.className = "custom-code-button";
copyBtn.type = "button";
copyBtn.title = "Copiar código";
copyBtn.innerHTML = \'<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m6 18h-3c-.48 0-1-.379-1-1v-14c0-.481.38-1 1-1h14c.621 0 1 .522 1 1v3h3c.621 0 1 .522 1 1v14c0 .621-.522 1-1 1h-14c-.48 0-1-.379-1-1zm1.5-10.5v13h13v-13zm9-1.5v-2.5h-13v13h2.5v-9.5c0-.481.38-1 1-1z" fill="currentColor" fill-rule="nonzero"/></svg>\';
copyBtn.addEventListener("click", function() {
const code = block.querySelector("code");
if (code) {
navigator.clipboard.writeText(code.textContent)
.then(() => {
copyBtn.innerHTML = \'<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m6 18h-3c-.48 0-1-.379-1-1v-14c0-.481.38-1 1-1h14c.621 0 1 .522 1 1v3h3c.621 0 1 .522 1 1v14c0 .621-.522 1-1 1h-14c-.48 0-1-.379-1-1zm1.5-10.5v13h13v-13zm9-1.5v-2.5h-13v13h2.5v-9.5c0-.481.38-1 1-1z" fill="#10b981" fill-rule="nonzero"/></svg>\';
setTimeout(() => {
copyBtn.innerHTML = \'<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m6 18h-3c-.48 0-1-.379-1-1v-14c0-.481.38-1 1-1h14c.621 0 1 .522 1 1v3h3c.621 0 1 .522 1 1v14c0 .621-.522 1-1 1h-14c-.48 0-1-.379-1-1zm1.5-10.5v13h13v-13zm9-1.5v-2.5h-13v13h2.5v-9.5c0-.481.38-1 1-1z" fill="currentColor" fill-rule="nonzero"/></svg>\';
}, 2000);
});
}
});
// Botón Descargar
const downloadBtn = document.createElement("button");
downloadBtn.className = "custom-code-button";
downloadBtn.type = "button";
downloadBtn.title = "Descargar código";
downloadBtn.innerHTML = \'<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 21l-8-9h6v-12h4v12h6l-8 9zm9-1v2h-18v-2h-2v4h22v-4h-2z" fill="currentColor"/></svg>\';
downloadBtn.addEventListener("click", function() {
const code = block.querySelector("code");
if (code) {
const blob = new Blob([code.textContent], { type: "text/plain" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "codigo.txt";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
downloadBtn.innerHTML = \'<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 21l-8-9h6v-12h4v12h6l-8 9zm9-1v2h-18v-2h-2v4h22v-4h-2z" fill="#10b981"/></svg>\';
setTimeout(() => {
downloadBtn.innerHTML = \'<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 21l-8-9h6v-12h4v12h6l-8 9zm9-1v2h-18v-2h-2v4h22v-4h-2z" fill="currentColor"/></svg>\';
}, 2000);
}
});
container.appendChild(toggleBtn);
container.appendChild(copyBtn);
container.appendChild(downloadBtn);
block.appendChild(container);
});
});
</script>';
}
add_action('wp_footer', 'botones_codigo_personalizados');
}Y si quieren solo un botón con el texto "Copiar código", sin imagen, por aquí pueden encontrar el código.














