2015 janv. 3
Par Nicolas - Développement - Lien permanent
Depuis la version 2.7, il est possible d'utiliser CKEditor comme éditeur WYSIWYG. Ce nouvel éditeur offre les mêmes fonctionnalités que l'éditeur précédent et en propose de nouvelles avec notamment l'ajout de tableaux, la possibilité de mettre des couleurs ou le copier/coller depuis word, etc.
CKEditor est conçu de telle manière qu'il est possible de l'enrichir à l'aide d'extension (il en existe déjà de nombreuses : http://ckeditor.com/addons/plugins/all). Il est également possible d'en écrire de nouvelles. Voyons comment…
À titre d'exemple nous allons adapter le plugin externalMedia pour qu'il fonctionne de la même manière qu'avec l'ancien éditeur (dcLegacyEditor).
Pour ajouter un nouveau bouton avec CKEditor, il faut utiliser le behavior ckeditorExtraPlugins
. Cela se passe côté administration et donc dans le fichier _admin.php, nous ajoutons le code suivant :
$core->addBehavior('ckeditorExtraPlugins', array('externalMediaBehaviors', 'ckeditorExtraPlugins'));
Et dans la classe externalMediaBehaviors
nous ajoutons la méthode ckeditorExtraPlugins
qui attend en paramètres un tableau (sous forme d'objet donc de type ArrayObject) et un contexte (post, page, event, ...) qui permet de déterminer si le contexte est supporté par ce bouton, ce qui est le cas en ce qui concerne externalMedia.
public static function ckeditorExtraPlugins(ArrayObject $extraPlugins, $context) { $extraPlugins[] = array( 'name' => 'externalmedia', 'button' => 'ExternalMedia', 'url' => DC_ADMIN_URL.'index.php?pf=dcExternalMedia/cke-addon/' ); }
Il faut maintenant créer l'extension (addOn en anglais) pour CKEditor, extension qui sera incluse dans le répertoire du plugin externalMedia. Pour cela on crée un répertoire (ici cke-addon) contenant un répertoire icons et un fichier plugin.js. Le répertoire icons contient un fichier icon.png qui servira d'icône (en 16x16) pour le bouton sur la barre de l'éditeur. Le fichier plugin.js contient le code du plugin :
CKEDITOR.plugins.add('externalmedia', { init: function(editor) { editor.ui.addButton("ExternalMedia", { label: "External Media", icon: this.path+'icons/icon.png' }); } });
À ce stade, vous devriez voir apparaître un nouveau bouton dans la barre d'édition. Au survol du bouton, on verra un tooltip avec "External Media". Pour le moment le bouton ne fait rien. Nous allons ouvrir une petite fenêtre (modale) pour saisir l'URL d'un média externe. Cela se fait en utilisant le plugin dialog de CKEditor. Nous allons par ailleurs préciser du coup que notre plugin dépend de dialog, en ajoutant à la définition du plugin (dans le fichier plugin.js) :
requires: "dialog"
L'ajout d'une commande se fait avec la méthode addCommand
et la déclaration se fait dans l'init de l'extension :
editor.addCommand('externalMediaCommand', new CKEDITOR.dialogCommand('externalMediaDialog'));
On déclare la boîte de dialogue modale correspondant à la commande, dont le code se trouve dans un fichier à part :
CKEDITOR.dialog.add('externalMediaDialog', this.path+'dialogs/popup.js');
Et pour finir, on spécifie quelle commande est appelée lorsque le bouton est cliqué, avec le paramètre command :
command: 'externalMediaCommand'
Le contenu du fichier plugin.js est alors celui-ci :
CKEDITOR.plugins.add('externalmedia', { requires:"dialog", init: function(editor) { editor.addCommand('externalMediaCommand', new CKEDITOR.dialogCommand('externalMediaDialog')); CKEDITOR.dialog.add('externalMediaDialog', this.path+'dialogs/popup.js'); editor.ui.addButton("ExternalMedia", { label: "External Media", icon: this.path+'icons/icon.png', command: 'externalMediaCommand', toolbar: 'insert' }); } });
Il ne reste plus qu'à écrire (définir en fait) la boîte de dialogue modale ouverte après un clic sur le bouton (dans le fichier dialogs/popup.js) :
CKEDITOR.dialog.add('externalMediaDialog', function(editor) { return { title: 'External Media', minWidth: 400, minHeight: 150, contents: [{ id: 'tab-url', elements: [{ id: 'url', type: 'text', label: 'URL', validate: CKEDITOR.dialog.validate.notEmpty('URL cannot be empty.') }] }] onOk: function() { } }; });
Evidemment si on veut se rapprocher du comportement initial (avec l'ancien éditeur), on pourrait ouvrir une autre modale pour demander l'alignement de l'élément à insérer mais CKEditor fait plus fort et propose de faire des onglets. On va donc faire un deuxème onglet qui demandera (optionnellement) l'alignement. Le code de la modale ressemble alors à ça :
CKEDITOR.dialog.add('externalMediaDialog', function(editor) { return { title: 'External Media', minWidth: 400, minHeight: 150, contents: [ { id: 'tab-url', label: 'URL', elements: [{ id: 'url', type: 'text', label: 'URL', validate: CKEDITOR.dialog.validate.notEmpty('URL cannot be empty.') }] }, { id: 'tab-alignment', label: 'Alignment', elements: [{ type: 'radio', id: 'alignment', label: 'Position', items: [ [ 'None', 'none' ], [ 'Left', 'left' ], ['Right', 'right'],['Center', 'center'] ], 'default': 'none' }] } ], onOk: function() { var dialog = this; var url = dialog.getValueOf('tab-url', 'url'); var alignment = dialog.getValueOf('tab-alignment', 'alignment'); $.getJSON('http://oohembed.com/oohembed/?url='+url+'&callback=?', function(data) { var div = editor.document.createElement('div'); var style = ''; div.setAttribute('class', 'external-media'); if (alignment == 'left') { style = 'float: left; margin: 0 1em 1em 0;'; } else if (alignment == 'right') { style = 'float: right; margin: 0 0 1em 1em;'; } else if (alignment == 'center') { style = 'margin: 1em auto; text-align: center;'; } if (style!='') { div.setAttribute('style', style); } div.appendHtml(data.html); editor.insertElement(div); }); } }; });
Tout n'a pas été forcément détaillé mais l'idée générale est là. La documentation de CKEditor est bien faite.
Vous pouvez y trouver par exemple comment faire un plugin simple (dont je me suis largemet inspiré).
À vous de jouer !
PS : Une version à jour du plugin externalMedia sera prochainement disponible sur DotAddict.
Commentaires
Merci pour les explications. Yapuka recenser les plugins qui en ont besoin, et procéder à leur mise à jour...