
Já pensei e escrevi sobre isso mais do que uma vez. Não percebo muito bem porque é que o WordPress não adiciona certas funções básicas nos seus blocos Gutenberg ou porque é que demora um século a trazê-las para as suas versões finais que incorpora no núcleo, como no caso do bloco do índice.
Desta vez, vamos adicionar algo muito útil e que sempre senti falta, que não tem o bloco de código do Gutenberg e que considero essencial. Botões de copiar e descarregar.
O botão de cópia utilizado é este daIconmonstr, que tem uma dica de ferramenta e uma confirmação visual da cópia a verde.
O botão de transferência, também do Iconmonstr, transfere tudo em formato .txt, mas para a minha utilização é suficiente.
Ambos os botões têm um efeito de flutuação suave para manter um estilo minimalista.
Em termos de desempenho, só carrega em páginas onde estão presentes blocos de código e onde o CSS e o JS estão optimizados e em linha.
Pode vê-lo a funcionar aqui mesmo, no próprio bloco, com o código necessário que só precisa de adicionar ao ficheiro functions.php do seu modelo ou tema filho.
/**
* 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');