
Я не раз думал и писал об этом. Я не совсем понимаю, почему WordPress не добавляет некоторые базовые функции в свои блоки Gutenberg или почему ему требуется столетие, чтобы довести их до финальных версий, которые он включает в ядро, как в случае с блоком оглавления.
На этот раз мы добавим кое-что очень полезное, чего мне всегда не хватало, чего нет в блоке кода Gutenberg и что я считаю необходимым. Кнопки копирования и скачивания.
В качестве кнопки копирования используется вот эта отIconmonstr, она имеет всплывающую подсказку и визуальное подтверждение копирования зеленым цветом.
Кнопка загрузки, также с Iconmonstr, загружает все в формате .txt, но для моего использования этого вполне достаточно.
Обе кнопки имеют мягкое наведение для поддержания минималистичного стиля.
С точки зрения производительности, он загружается только на тех страницах, где присутствуют блоки кода, а CSS и JS оптимизированы и встроены.
Вы можете увидеть его работу прямо здесь, в самом блоке, с необходимым кодом, который нужно просто добавить в файл functions.php вашего шаблона или дочерней темы.
/**
* 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');