La documentation officielle n’est pas claire: quelle est la bonne façon d’intégrer un navigateur/uploader de fichiers personnalisé à CKEditor? (v3 - pas FCKEditor)
Commencez par enregistrer votre navigateur/uploader personnalisé lorsque vous instanciez CKEditor. Vous pouvez désigner différentes URL pour un navigateur d'images par rapport à un navigateur de fichiers général.
<script type="text/javascript">
CKEDITOR.replace('content', {
filebrowserBrowseUrl : '/browser/browse/type/all',
filebrowserUploadUrl : '/browser/upload/type/all',
filebrowserImageBrowseUrl : '/browser/browse/type/image',
filebrowserImageUploadUrl : '/browser/upload/type/image',
filebrowserWindowWidth : 800,
filebrowserWindowHeight : 500
});
</script>
Votre code personnalisé recevra un paramètre GET appelé CKEditorFuncNum. Enregistrez-le - c'est votre fonction de rappel. Disons que vous le mettez dans $callback
.
Quand quelqu'un sélectionne un fichier, lancez ce JavaScript pour informer CKEditor du fichier sélectionné:
window.opener.CKEDITOR.tools.callFunction(<?php echo $callback; ?>,url)
Où "url" est l'URL du fichier qu'ils ont choisi. Un troisième paramètre facultatif peut être le texte que vous souhaitez afficher dans une boîte de dialogue d'alerte standard, tel que "fichier illégal" ou quelque chose du genre. Définissez url sur une chaîne vide si le troisième paramètre est un message d'erreur.
L'onglet "upload" de CKEditor soumettra un fichier dans le champ "upload" - en PHP, qui passe à $ _FILES ['upload']. Ce que CKEditor veut que votre serveur produise est un bloc JavaScript complet:
$output = '<html><body><script type="text/javascript">window.parent.CKEDITOR.tools.callFunction('.$callback.', "'.$url.'","'.$msg.'");</script></body></html>';
echo $output;
Encore une fois, vous devez lui donner le paramètre de rappel, l’URL du fichier et éventuellement un message. Si le message est une chaîne vide, rien ne s'affichera. si le message est une erreur, url devrait alors être une chaîne vide.
La documentation officielle de CKEditor est incomplète sur tout cela, mais si vous suivez ce qui précède, cela fonctionnera comme un champion.
J'ai posté un petit tutoriel sur l'intégration du FileBrowser disponible dans l'ancien FCKEditor à CKEditor.
http://www.mixedwaves.com/2010/02/integrating-fckeditor-filemanager-in-ckeditor/
Il contient des instructions détaillées pour le faire et c’est très simple. J'espère que quiconque à la recherche de ce tutoriel trouvera ce tutoriel utile.
Je viens de suivre le processus d'apprentissage moi-même. Je l'ai compris, mais je suis d'accord pour dire que la documentation est rédigée de manière intimidante pour moi. Le grand moment "aha" pour moi a été de comprendre que pour la navigation, tout ce que CKeditor fait, c'est ouvrir une nouvelle fenêtre et fournir quelques paramètres dans l'URL. Il vous permet d’ajouter des paramètres supplémentaires, mais sachez que vous devrez utiliser encodeURIComponent () sur vos valeurs.
J'appelle le navigateur et le téléchargeur avec
CKEDITOR.replace( 'body',
{
filebrowserBrowseUrl: 'browse.php?type=Images&dir=' +
encodeURIComponent('content/images'),
filebrowserUploadUrl: 'upload.php?type=Files&dir=' +
encodeURIComponent('content/images')
}
Pour le browser, dans la fenêtre ouverte (browse.php), vous utilisez php & js pour fournir une liste de choix, puis sur votre gestionnaire onclick fourni, vous appelez une fonction CKeditor avec deux arguments, l'url/path vers l'image sélectionnée et CKEditorFuncNum fourni par CKeditor dans l'URL:
function myOnclickHandler(){
//..
window.opener.CKEDITOR.tools.callFunction(<?php echo $_GET['CKEditorFuncNum']; ?>, pathToImage);
window.close();
}
De même, le ploader appelle simplement l'url que vous fournissez, par exemple upload.php , et fournit à nouveau $ _GET ['CKEditorFuncNum ']. La cible est un iframe. Après avoir sauvegardé le fichier à partir de $ _FILES, vous transmettez vos commentaires à CKeditor comme suit:
$funcNum = $_GET['CKEditorFuncNum'];
exit("<script>window.parent.CKEDITOR.tools.callFunction($funcNum, '$filePath', '$errorMessage');</script>");
Vous trouverez ci-dessous un script de navigateur personnalisé simple à comprendre. Bien qu'il n'autorise pas les utilisateurs à naviguer sur le serveur, il vous permet d'indiquer le répertoire dans lequel extraire les fichiers image lorsque vous appelez le navigateur.
Il s’agit plutôt d’un codage de base, il devrait donc fonctionner dans tous les navigateurs relativement modernes.
CKeditor ouvre simplement une nouvelle fenêtre avec l'URL fournie
/*
in CKeditor **use encodeURIComponent()** to add dir param to the filebrowserBrowseUrl property
Replace content/images with directory where your images are housed.
*/
CKEDITOR.replace( 'editor1', {
filebrowserBrowseUrl: '**browse.php**?type=Images&dir=' + encodeURIComponent('content/images'),
filebrowserUploadUrl: 'upload.php?type=Files&dir=' + encodeURIComponent('content/images')
});
<?php
header("Content-Type: text/html; charset=utf-8\n");
header("Cache-Control: no-cache, must-revalidate\n");
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
// e-z params
$dim = 150; /* image displays proportionally within this square dimension ) */
$cols = 4; /* thumbnails per row */
$thumIndicator = '_th'; /* e.g., *image123_th.jpg*) -> if not using thumbNails then use empty string */
?>
<!DOCTYPE html>
<html>
<head>
<title>browse file</title>
<meta charset="utf-8">
<style>
html,
body {padding:0; margin:0; background:black; }
table {width:100%; border-spacing:15px; }
td {text-align:center; padding:5px; background:#181818; }
img {border:5px solid #303030; padding:0; verticle-align: middle;}
img:hover { border-color:blue; cursor:pointer; }
</style>
</head>
<body>
<table>
<?php
$dir = $_GET['dir'];
$dir = rtrim($dir, '/'); // the script will add the ending slash when appropriate
$files = scandir($dir);
$images = array();
foreach($files as $file){
// filter for thumbNail image files (use an empty string for $thumIndicator if not using thumbnails )
if( !preg_match('/'. $thumIndicator .'\.(jpg|jpeg|png|gif)$/i', $file) )
continue;
$thumbSrc = $dir . '/' . $file;
$fileBaseName = str_replace('_th.','.',$file);
$image_info = getimagesize($thumbSrc);
$_w = $image_info[0];
$_h = $image_info[1];
if( $_w > $_h ) { // $a is the longer side and $b is the shorter side
$a = $_w;
$b = $_h;
} else {
$a = $_h;
$b = $_w;
}
$pct = $b / $a; // the shorter sides relationship to the longer side
if( $a > $dim )
$a = $dim; // limit the longer side to the dimension specified
$b = (int)($a * $pct); // calculate the shorter side
$width = $_w > $_h ? $a : $b;
$height = $_w > $_h ? $b : $a;
// produce an image tag
$str = sprintf('<img src="%s" width="%d" height="%d" title="%s" alt="">',
$thumbSrc,
$width,
$height,
$fileBaseName
);
// save image tags in an array
$images[] = str_replace("'", "\\'", $str); // an unescaped apostrophe would break js
}
$numRows = floor( count($images) / $cols );
// if there are any images left over then add another row
if( count($images) % $cols != 0 )
$numRows++;
// produce the correct number of table rows with empty cells
for($i=0; $i<$numRows; $i++)
echo "\t<tr>" . implode('', array_fill(0, $cols, '<td></td>')) . "</tr>\n\n";
?>
</table>
<script>
// make a js array from the php array
images = [
<?php
foreach( $images as $v)
echo sprintf("\t'%s',\n", $v);
?>];
tbl = document.getElementsByTagName('table')[0];
td = tbl.getElementsByTagName('td');
// fill the empty table cells with data
for(var i=0; i < images.length; i++)
td[i].innerHTML = images[i];
// event handler to place clicked image into CKeditor
tbl.onclick =
function(e) {
var tgt = e.target || event.srcElement,
url;
if( tgt.nodeName != 'IMG' )
return;
url = '<?php echo $dir;?>' + '/' + tgt.title;
this.onclick = null;
window.opener.CKEDITOR.tools.callFunction(<?php echo $_GET['CKEditorFuncNum']; ?>, url);
window.close();
}
</script>
</body>
</html>
J'ai passé un moment à essayer de comprendre celui-ci et voici ce que j'ai fait. Je l'ai décomposé très simplement car c'est ce dont j'avais besoin.
Directement sous la zone de texte de ckeditor, entrez le fichier de téléchargement comme ceci >>>>
<form action="welcomeeditupload.asp" method="post" name="deletechecked">
<div align="center">
<br />
<br />
<label></label>
<textarea class="ckeditor" cols="80" id="editor1" name="editor1" rows="10"><%=(rslegschedule.Fields.Item("welcomevar").Value)%></textarea>
<script type="text/javascript">
//<![CDATA[
CKEDITOR.replace( 'editor1',
{
filebrowserUploadUrl : 'updateimagedone.asp'
});
//]]>
</script>
<br />
<br />
<br />
<input type="submit" value="Update">
</div>
</form>
'et ajoutez ensuite votre fichier de téléchargement, voici le mien qui est écrit en ASP. Si vous utilisez PHP, etc., remplacez simplement le ASP par votre script de téléchargement, mais assurez-vous que la page affiche la même chose.
<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<%
if Request("CKEditorFuncNum")=1 then
Set Upload = Server.CreateObject("Persits.Upload")
Upload.OverwriteFiles = False
Upload.SetMaxSize 5000000, True
Upload.CodePage = 65001
On Error Resume Next
Upload.Save "d:\hosting\belaullach\senate\legislation"
Dim picture
For Each File in Upload.Files
Ext = UCase(Right(File.Path, 3))
If Ext <> "JPG" Then
If Ext <> "BMP" Then
Response.Write "File " & File.Path & " is not a .jpg or .bmp file." & "<BR>"
Response.write "You can only upload .jpg or .bmp files." & "<BR>" & "<BR>"
End if
Else
File.SaveAs Server.MapPath(("/senate/legislation") & "/" & File.fileName)
f1=File.fileName
End If
Next
End if
fnm="/senate/legislation/"&f1
imgop = "<html><body><script type=""text/javascript"">window.parent.CKEDITOR.tools.callFunction('1','"&fnm&"');</script></body></html>;"
'imgop="callFunction('1','"&fnm&"',"");"
Response.write imgop
%>
C'est l'approche que j'ai utilisée. C'est assez simple et fonctionne très bien.
Le répertoire racine de l'éditeur CK contient un fichier nommé config.js
J'ai ajouté ceci (vous n'avez pas besoin de la chaîne de requête, c'est juste pour notre gestionnaire de fichiers). J'ai également inclus un peu de skinning et de changement des boutons par défaut affichés:
CKEDITOR.editorConfig = function(config) {
config.skin = 'v2';
config.startupFocus = false;
config.filebrowserBrowseUrl = '/admin/content/filemanager.aspx?path=Userfiles/File&editor=FCK';
config.filebrowserImageBrowseUrl = '/admin/content/filemanager.aspx?type=Image&path=Userfiles/Image&editor=FCK';
config.toolbar_Full =
[
['Source', '-', 'Preview', '-'],
['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Print', 'SpellChecker'], //, 'Scayt'
['Undo', 'Redo', '-', 'Find', 'Replace', '-', 'SelectAll', 'RemoveFormat'],
'/',
['Bold', 'Italic', 'Underline', 'Strike', '-', 'Subscript', 'Superscript'],
['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', 'Blockquote'],
['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
['Link', 'Unlink', 'Anchor'],
['Image', 'Flash', 'Table', 'HorizontalRule', 'SpecialChar'],
'/',
['Styles', 'Format', 'Templates'],
['Maximize', 'ShowBlocks']
];
};
Ensuite, notre gestionnaire de fichiers appelle ceci:
opener.SetUrl('somefilename');
Un article sur zerokspot intitulé callbacks de Filebrowser personnalisés dans CKEditor 3. gère cela. La section la plus pertinente est citée ci-dessous:
Donc, tout ce que vous avez à faire à partir du navigateur de fichiers quand vous avez un fichier sélectionné est d'appeler ce code avec le bon numéro de rappel (normalement 1) et l'URL du fichier sélectionné:
window.opener.CKEDITOR.tools.callFunction(CKEditorFuncNum,url);
Pour le téléchargeur rapide, le processus est assez similaire. Au début, je pensais que l'éditeur pouvait écouter un code de retour 200 HTTP et peut-être regarder dans un champ d'en-tête ou quelque chose du genre pour déterminer l'emplacement du fichier téléchargé, mais ensuite - grâce à une surveillance Firebug - j'ai remarqué que tout ce qui se passait après un téléchargement est le code suivant:
<script type="text/javascript">
window.parent.CKEDITOR.tools.callFunction(CKEditorFuncNum,url, errorMessage);
</script>
Si le téléchargement échoue, définissez
errorMessage
sur une chaîne de longueur non nulle et videz l'URL, et inversement en cas de succès.
Commencez par enregistrer votre navigateur/uploader personnalisé lorsque vous instanciez CKEditor.
<script type="text/javascript">
CKEDITOR.replace('content', {
filebrowserUploadUrl: "Upload File Url",//http://localhost/phpwork/test/ckFileUpload.php
filebrowserWindowWidth : 800,
filebrowserWindowHeight : 500
});
</script>
Code pour le fichier de téléchargement (ckFileUpload.php) & placez le fichier de téléchargement dans le répertoire racine de votre projet.
// HERE SET THE PATH TO THE FOLDERS FOR IMAGES AND AUDIO ON YOUR SERVER (RELATIVE TO THE ROOT OF YOUR WEBSITE ON SERVER)
$upload_dir = array(
'img'=> '/phpwork/test/uploads/editor-images/',
'audio'=> '/phpwork/ezcore_v1/uploads/editor-images/'
);
// HERE PERMISSIONS FOR IMAGE
$imgset = array(
'maxsize' => 2000, // maximum file size, in KiloBytes (2 MB)
'maxwidth' => 900, // maximum allowed width, in pixels
'maxheight' => 800, // maximum allowed height, in pixels
'minwidth' => 10, // minimum allowed width, in pixels
'minheight' => 10, // minimum allowed height, in pixels
'type' => array('bmp', 'gif', 'jpg', 'jpeg', 'png'), // allowed extensions
);
// HERE PERMISSIONS FOR AUDIO
$audioset = array(
'maxsize' => 20000, // maximum file size, in KiloBytes (20 MB)
'type' => array('mp3', 'ogg', 'wav'), // allowed extensions
);
// If 1 and filename exists, RENAME file, adding "_NR" to the end of filename (name_1.ext, name_2.ext, ..)
// If 0, will OVERWRITE the existing file
define('RENAME_F', 1);
$re = '';
if(isset($_FILES['upload']) && strlen($_FILES['upload']['name']) >1) {
define('F_NAME', preg_replace('/\.(.+?)$/i', '', basename($_FILES['upload']['name']))); //get filename without extension
// get protocol and Host name to send the absolute image path to CKEditor
$protocol = !empty($_SERVER['HTTPS']) ? 'https://' : 'http://';
$site = $protocol. $_SERVER['SERVER_NAME'] .'/';
$sepext = explode('.', strtolower($_FILES['upload']['name']));
$type = end($sepext); // gets extension
$upload_dir = in_array($type, $imgset['type']) ? $upload_dir['img'] : $upload_dir['audio'];
$upload_dir = trim($upload_dir, '/') .'/';
//checkings for image or audio
if(in_array($type, $imgset['type'])){
list($width, $height) = getimagesize($_FILES['upload']['tmp_name']); // image width and height
if(isset($width) && isset($height)) {
if($width > $imgset['maxwidth'] || $height > $imgset['maxheight']) $re .= '\\n Width x Height = '. $width .' x '. $height .' \\n The maximum Width x Height must be: '. $imgset['maxwidth']. ' x '. $imgset['maxheight'];
if($width < $imgset['minwidth'] || $height < $imgset['minheight']) $re .= '\\n Width x Height = '. $width .' x '. $height .'\\n The minimum Width x Height must be: '. $imgset['minwidth']. ' x '. $imgset['minheight'];
if($_FILES['upload']['size'] > $imgset['maxsize']*1000) $re .= '\\n Maximum file size must be: '. $imgset['maxsize']. ' KB.';
}
}
else if(in_array($type, $audioset['type'])){
if($_FILES['upload']['size'] > $audioset['maxsize']*1000) $re .= '\\n Maximum file size must be: '. $audioset['maxsize']. ' KB.';
}
else $re .= 'The file: '. $_FILES['upload']['name']. ' has not the allowed extension type.';
//set filename; if file exists, and RENAME_F is 1, set "img_name_I"
// $p = dir-path, $fn=filename to check, $ex=extension $i=index to rename
function setFName($p, $fn, $ex, $i){
if(RENAME_F ==1 && file_exists($p .$fn .$ex)) return setFName($p, F_NAME .'_'. ($i +1), $ex, ($i +1));
else return $fn .$ex;
}
$f_name = setFName($_SERVER['DOCUMENT_ROOT'] .'/'. $upload_dir, F_NAME, ".$type", 0);
$uploadpath = $_SERVER['DOCUMENT_ROOT'] .'/'. $upload_dir . $f_name; // full file path
// If no errors, upload the image, else, output the errors
if($re == '') {
if(move_uploaded_file($_FILES['upload']['tmp_name'], $uploadpath)) {
$CKEditorFuncNum = $_GET['CKEditorFuncNum'];
$url = $site. $upload_dir . $f_name;
$msg = F_NAME .'.'. $type .' successfully uploaded: \\n- Size: '. number_format($_FILES['upload']['size']/1024, 2, '.', '') .' KB';
$re = in_array($type, $imgset['type']) ? "window.parent.CKEDITOR.tools.callFunction($CKEditorFuncNum, '$url', '$msg')" //for img
: 'var cke_ob = window.parent.CKEDITOR; for(var ckid in cke_ob.instances) { if(cke_ob.instances[ckid].focusManager.hasFocus) break;} cke_ob.instances[ckid].insertHtml(\'<audio src="'. $url .'" controls></audio>\', \'unfiltered_html\'); alert("'. $msg .'"); var dialog = cke_ob.dialog.getCurrent(); dialog.hide();';
}
else $re = 'alert("Unable to upload the file")';
}
else $re = 'alert("'. $re .'")';
}
@header('Content-type: text/html; charset=utf-8');
echo '<script>'. $re .';</script>';
La documentation de Ck-editor n'est pas claire après avoir fait beaucoup de R & D pour le téléchargement de fichiers personnalisés. Finalement, j'ai trouvé cette solution. Cela fonctionne pour moi et j'espère que cela aidera également les autres.
Pour les personnes qui s’interrogent sur une implémentation Servlet/JSP, voici comment procéder: j’expliquerai également uploadimage ci-dessous.
1) Assurez-vous d’abord d’avoir ajouté la variable filebrowser et ploadimage à votre fichier config.js. Assurez-vous que vous avez aussi le dossier ploadimage et filebrowser à l'intérieur du dossier plugins.
2) Cette partie est où il m'a fait trébucher:
La documentation du site Web Ckeditor indique que vous devez utiliser ces deux méthodes:
function getUrlParam( paramName ) {
var reParam = new RegExp( '(?:[\?&]|&)' + paramName + '=([^&]+)', 'i' );
var match = window.location.search.match( reParam );
return ( match && match.length > 1 ) ? match[1] : null;
}
function returnFileUrl() {
var funcNum = getUrlParam( 'CKEditorFuncNum' );
var fileUrl = 'https://patiliyo.com/wp-content/uploads/2017/07/ruyada-kedi-gormek.jpg';
window.opener.CKEDITOR.tools.callFunction( funcNum, fileUrl );
window.close();
}
Ce qu'ils ne mentionnent pas, c'est que ces méthodes doivent figurer sur une page différente et non sur la page sur laquelle vous cliquez sur le bouton parcourir le serveur.
Donc, si vous avez ckeditor initialisé dans page editor.jsp, vous devez alors créer un navigateur de fichiers (avec html/css/javascript basique) dans page filebrowser.jsp.
editor.jsp (tout ce dont vous avez besoin, c’est dans votre balise script) Cette page ouvrira filebrowser.jsp dans une mini-fenêtre lorsque vous cliquez sur le bouton Parcourir le serveur.
CKEDITOR.replace( 'editor', {
filebrowserBrowseUrl: '../filebrowser.jsp', //jsp page with jquery to call servlet and get image files to view
filebrowserUploadUrl: '../UploadImage', //servlet
});
filebrowser.jsp (est le navigateur de fichiers personnalisé que vous avez construit et qui contiendra les méthodes mentionnées ci-dessus)
<head>
<script src="../../ckeditor/ckeditor.js"></script>
</head>
<body>
<script>
function getUrlParam( paramName ) {
var reParam = new RegExp( '(?:[\?&]|&)' + paramName + '=([^&]+)', 'i' );
var match = window.location.search.match( reParam );
return ( match && match.length > 1 ) ? match[1] : null;
}
function returnFileUrl() {
var funcNum = getUrlParam( 'CKEditorFuncNum' );
var fileUrl = 'https://patiliyo.com/wp-content/uploads/2017/07/ruyada-kedi-gormek.jpg';
window.opener.CKEDITOR.tools.callFunction( funcNum, fileUrl );
window.close();
}
//when this window opens it will load all the images which you send from the FileBrowser Servlet.
getImages();
function getImages(){
$.get("../FileBrowser", function(responseJson) {
//do something with responseJson (like create <img> tags and update the src attributes)
});
}
//you call this function and pass 'fileUrl' when user clicks on an image that you loaded into this window from a servlet
returnFileUrl();
</script>
</body>
3) la servlet FileBrowser
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Images i = new Images();
List<ImageObject> images = i.getImages(); //get images from your database or some cloud service or whatever (easier if they are in a url ready format)
String json = new Gson().toJson(images);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(json);
}
4) Servlet UploadImage
Retournez à votre fichier config.js pour ckeditor et ajoutez la ligne suivante:
//https://docs.ckeditor.com/ckeditor4/latest/guide/dev_file_upload.html
config.uploadUrl = '/UploadImage';
Ensuite, vous pouvez glisser et déposer des fichiers aussi:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Images i = new Images();
//do whatever you usually do to upload your image to your server (in my case i uploaded to google cloud storage and saved the url in a database.
//Now this part is important. You need to return the response in json format. And it has to look like this:
// https://docs.ckeditor.com/ckeditor4/latest/guide/dev_file_upload.html
// response must be in this format:
// {
// "uploaded": 1,
// "fileName": "example.png",
// "url": "https://www.cats.com/example.png"
// }
String image = "https://www.cats.com/example.png";
ImageObject objResponse = i.getCkEditorObjectResponse(image);
String json = new Gson().toJson(objResponse);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(json);
}
}
Et c'est tous les gens. J'espère que ça aide quelqu'un.