
Ci ho pensato e scritto più di una volta. Non capisco perché WordPress non aggiunga alcune funzioni di base nei suoi blocchi Gutenberg o perché ci metta un secolo a portarle nelle versioni finali che incorpora nel core, come nel caso del blocco dell'indice.
Questa volta aggiungeremo qualcosa di molto utile e che mi è sempre mancato, che non ha il blocco di codice di Gutenberg e che considero essenziale. I pulsanti di copia e download.
Il pulsante di copia utilizzato è questo di Iconmonstr, dotato di tooltip e conferma visiva della copia in verde.
Il pulsante di download, sempre da Iconmonstr, scarica tutto in formato .txt, ma per il mio utilizzo è sufficiente.
Entrambi i pulsanti hanno un hover morbido per mantenere uno stile minimalista.
Dal punto di vista delle prestazioni, si carica solo sulle pagine in cui sono presenti blocchi di codice e i CSS e JS sono ottimizzati e in linea.
Lo si può vedere in funzione proprio qui, nel blocco stesso, con il codice necessario da aggiungere al file functions.php del template o del tema figlio.
/**
* Añade botones "Copiar" y "Descargar" en los bloques de código <code> de Gutenberg
*/
function botones_codigo_personalizados() {
global $post;
if (!is_a($post, 'WP_Post') || !has_block('core/code', $post)) {
return;
}
echo '<style>
.wp-block-code {
position: relative;
padding-top: 12px !important;
}
.custom-code-buttons {
position: absolute;
top: 12px;
right: 12px;
display: flex;
gap: 8px;
}
.custom-code-button {
background: none;
border: none;
padding: 4px;
cursor: pointer;
color: #6b7280;
border-radius: 4px;
transition: all 0.15s ease;
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
}
.custom-code-button:hover {
color: #374151;
background: rgba(0,0,0,0.05);
}
.custom-code-button svg {
width: 16px;
height: 16px;
}
@media (max-width: 480px) {
.custom-code-buttons {
top: 8px;
right: 8px;
}
}
</style>';
echo '<script>
document.addEventListener("DOMContentLoaded", function() {
document.querySelectorAll(".wp-block-code").forEach(block => {
const container = document.createElement("div");
container.className = "custom-code-buttons";
// Botón Copiar, icono de Iconmonstr
const copyBtn = document.createElement("button");
copyBtn.className = "custom-code-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-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-rule="nonzero"/></svg>\';
}, 2000);
});
}
});
// Botón Descargar, icono de Iconmonstr
const downloadBtn = document.createElement("button");
downloadBtn.className = "custom-code-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"/></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"/></svg>\';
}, 2000);
}
});
container.appendChild(copyBtn);
container.appendChild(downloadBtn);
block.appendChild(container);
});
});
</script>';
}
add_action('wp_footer', 'botones_codigo_personalizados');