Vous proposez des articles traitant de développement et, bien sûr, vous avez envie de partager vos codes avec votre communauté et qu'ils puissent en 1 click copier le code proposé ... mais voilà, TinyMCE ne propose pas en version gratuite une telle feature !
Ayant eu besoin de le mettre en place pour ce blog, j'ai donc décidé de développer mon propre plugin et de vous le proposer aujourd'hui !
Pour commencer, migrez sur le V5 de TinyMCE ci ce n'est pas déjà fait.
Allez ensuite sur prismJS, sélectionnez les langages que vous souhaitez prendre en charge dans vos articles et téléchargez les fichiers JS et CSS (pensez à noter les langages sélectionnés, cela va vous servir par la suite).
Installez ces fichiers dans votre projet (front et back)
Dans le dossier des plugins de TinyMCE, créez un dossier "codesnippet"
Créez ensuite un fichier "plugin.min.js" dans ce dossier et coller le code suivant :
tinymce.PluginManager.add('codesnippet', function(editor, url) {
const openDialog = () => editor.windowManager.open({
title: 'Code Snippet',
body: {
type: 'panel',
items: [
{type: 'selectbox', name: 'lang', label: 'Sélectionnez le langage', items: editor.getParam('codesnippet_languages')},
{type: 'textarea', name: 'snippet', label: 'Coller votre code ci-dessous', maximized: true}
]
},
buttons: [
{type: 'cancel', text: 'Fermer'},
{type: 'submit', text: 'Enregistrer', buttonType: 'primary'}
],
onSubmit: (api) => {
const data = api.getData();
let html = '' + data.snippet + '
';
editor.insertContent(html);
api.close();
}
});
editor.ui.registry.addButton('codesnippet', {
text: '',
onAction: () => {
openDialog();
let area = document.getElementsByClassName('tox-textarea');
area[0].setAttribute('style', 'height:400px');
}
});
return {
getMetadata: () => ({
name: 'codesnippet',
url: 'http://www.comnstay.fr/blog/de-beaux-snippet-de-code-dans-tinymce'
})
};
});
Configuration (minimale juste pour le plugin) de TinyMCE
tinymce.init({
selector: 'textarea.tinymce',
plugins: 'codesnippet',
toolbar: 'codesnippet',
codesnippet_languages: [
{ text: 'HTML/XML', value: 'markup' },
{ text: 'JavaScript', value: 'javascript' },
{ text: 'CSS', value: 'css' },
{ text: 'PHP', value: 'php' },
{ text: 'Shell', value: 'shell' }
{ text: 'Swift', value: 'swift' }
{ text: 'Ruby', value: 'ruby' },
{ text: 'Python', value: 'python' },
{ text: 'Java', value: 'java' },
{ text: 'C', value: 'c' },
{ text: 'C#', value: 'csharp' },
{ text: 'C++', value: 'cpp' }
]
});
Vous pouvez bien évidement personnaliser la liste des langages supportés en fonction de ceux que vous avez sélectionné sur prismJS !
Pour le rendu dans vos articles, un peu de JS et de CSS complémentaire à mettre dans vos fichiers front, ce JS permet d'ajouter le bouton "Copy code" sur vos snippet
/******************** copy code button ********************/
const copyButtonLabel = "Copy Code";
// use a class selector if available
let blocks = document.querySelectorAll("pre");
blocks.forEach((block) => {
// only add button if browser supports Clipboard API
if (navigator.clipboard) {
let button = document.createElement("button");
button.innerText = copyButtonLabel;
block.appendChild(button);
button.addEventListener("click", async () => {
await copyCode(block);
});
}
});
async function copyCode(block) {
let code = block.querySelector("code");
let text = code.innerText;
let button = block.querySelector("button");
await navigator.clipboard.writeText(text);
// visual feedback that task is completed
button.innerText = "Code Copied";
setTimeout(() => {
button.innerText = copyButtonLabel;
}, 1500);
}
et la CSS permet de styliser le block de code, vous pouvez bien évidement changer tout cela en fonction du design de votre site ;)
/*************** tinyMCE codesnippet module ********************/
pre[class*="language-"] {
position: relative;
margin: 5px 0 ;
padding: 1.75rem 0 1.75rem 1rem;
min-width: 95vh;
border: 1px solid #121b22;
border-radius: 9px;
overflow-x: scroll;
color: #fff;
}
pre[class*="language-"] button{
position: absolute;
top: 5px;
right: 5px;
border-radius: 7px;
background-color: #1b6d84;
color: #fff;
}
code[class*="language-"] {
white-space: pre-wrap;
word-break: break-all;
}
Mais comment ça marche ?
Une fois tout celà terminé, ouvrez un article en édition et la, surprise, un nouveau bouton </> est apparu dans la barre d'outils, cliquez dessus, une modale s'ouvre
sélectionnez le langage du snippet dans le menu déroulant, collez votre code dans la zone de texte et validez ... that's all !!!
Et le résultat est plutôt sympa, c'est ce que vous avez sur cette page !!!