用于ASP.NET网页的CKEditor文件浏览器

CKEditor是最受欢迎的丰富文本编辑之一。开箱即用,没有文件浏览器来帮助选择图像,但您可以从中购买加载项 - CKFinder。或者,您可以构建自己的文件浏览器组件。

默认情况下,如果单击CKEditor中的“图像”按钮,则会使用对话框呈现,该对话框需要您输入要插入的图像的URL。对于Web开发人员具有技术弯曲的其他用户,不应该构成太多问题,但普通用户不会有一个需要的线索。他们需要的是选择图像的方法,并让其URL自动填充对话框。 CKEditor公开了一个API,使开发人员能够插入自己的自定义文件浏览器以启用此功能。

在最简单的情况下,文件浏览器可以呈现文件列表,并提供用户可以指示他们想要使用的手段。但是,这种方法要求用户可以识别他们希望纯粹从其文件名中选择的图像。一旦任何图像文件的集合增长,除非采用某种补充索引系统,否则用户不太可能将图像与文件名相关联。更用户友好的解决方案是为用户提供一系列图像的缩略图,他们可以从中进行选择。工作流程如下:

  1. 用户单击按钮以浏览服务器上的图像
  2. 介绍用户的目录列表,其中包含可从中选择一个的图像
  3. 所选目录中的图像以缩略图形式呈现给用户
  4. 用户可以通过单击选择一个图像,并将对话框填充有其选择

因此,您需要从某些代码开始,以生成合理质量的缩略图。以下代码将添加到名为thumbnails.chtml的文件中,该文件被放置在app_code文件夹中:

@using System;
@using System.Drawing;
@using System.Drawing.Drawing2D;
@using System.IO;
@functions {
    public static byte[] GenerateTumbnail(string image, double thumbWidth) {
        try {
            using (var originalImage = Image.FromFile(image)) {
                var oWidth = originalImage.Width;
                var oHeight = originalImage.Height;
                var thumbHeight = oWidth > thumbWidth ? (thumbWidth / oWidth) * oHeight : oHeight;
                thumbWidth = oWidth > thumbWidth ? thumbWidth : oWidth;
                using (var bmp = new Bitmap((int)thumbWidth, (int)thumbHeight)) {
                    bmp.SetResolution(originalImage.HorizontalResolution, originalImage.VerticalResolution);
                    using (var graphic = Graphics.FromImage(bmp)) {
                        graphic.SmoothingMode = SmoothingMode.AntiAlias;
                        graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
                        graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;

                        var rectangle = new Rectangle(0, 0, (int)thumbWidth, (int)thumbHeight);
                        graphic.DrawImage(originalImage, rectangle, 0, 0, oWidth, oHeight, GraphicsUnit.Pixel);
                        var ms = new MemoryStream();
                        bmp.Save(ms, originalImage.RawFormat);
                        return ms.GetBuffer();
                    }
                }
            }
        }
        catch (Exception ex) {
            throw (ex);
        }
    }
}

此方法拾取将其传递给它的原始图像,并在大小将其缩小超过作为第二个参数中传递的宽度。它返回一个字节数组,因此新图像未存储在磁盘上。接下来,您需要一些在图像和缩略图宽度中传递的代码,并且可以使用返回的字节数组进行有意义的事情。此代码展示驻留在站点的根目录中的thumb.chtml:

@{
    if (Request["image"].IsEmpty()) {
        Response.End();
    }
    var image = Path.Combine(Server.MapPath("~/Media/"), Server.UrlDecode(Request["image"]));
    var thumbWidth = 128D;
    var buffer = ThumbNails.GenerateTumbnail(image, thumbWidth);
    Response.ContentType = string.Format("image/{0}", Path.GetExtension(image).Trim(new[]{'.'}));
    Response.OutputStream.Write(buffer, 0, buffer.Length);
    Response.End();
}

此文件充当处理程序。当请求时,它将从查询字符串中获取图像文件名,并使用generatethumbnail函数创建拇指映像,然后将其写入浏览器。对于这样的处理程序文件,需要设置为 SRC. 图像元素。发生在imageviewer.cshtml中:

@{
    Layout = null;
    var directory = new DirectoryInfo(Path.Combine(Server.MapPath("~/Media"), Request["directory"]));
}
@foreach (var file in directory.GetFilesByExtensions(".png", ".gif", ".jpg")) {
    <div class="thumbnail">
        <img  SRC. ="/Thumb/?image=@directory.Name\@file.Name" alt="thumb" title="@directory.Name/@file.Name" />
    </div>
}

此文件负责查找所选目录,由查询字符串中传递的值表示,然后获取具有指定扩展的所有文件,然后显示其缩略图版本。将图像的URL设置为标题属性的值。当用户将鼠标悬停在图像上时,将用户视为工具提示,并在稍后使用以填充CKEditor图像对话框。 getFileSByextensions. 是自定义扩展方法。它生存在名为fileextensions.cs中的类文件中,该文件被放置在app_code文件夹中:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

public static class FileExtensions
{
    public static IEnumerable<FileInfo> GetFilesByExtensions(this DirectoryInfo directoryInfo, params string[] extensions) {
        var allowedExtensions = new HashSet<string>(extensions, StringComparer.OrdinalIgnoreCase);
        return directoryInfo.EnumerateFiles().Where(f => allowedExtensions.Contains(f.Extension));
    } 
}

主文件称为filebrowser.cshtml。当用户单击CKEditor中的插入图像图标时,它是调用的文件。

@{
    Layout = null;
    var media = new DirectoryInfo(Server.MapPath("~/Media"));
}
<html>
    <head>
        <title>Media Browser</title>
        <link href="~/Content/StyleSheet.css" type="text/css" rel="stylesheet" />
        <script  SRC. ="/Scripts/jquery.js" type="text/javascript"></script>
        <script  SRC. ="/Scripts/ckeditor/ckeditor.js" type="text/javascript"></script>
        <script type="text/javascript">
            var funcNum = @(Request["CKEditorFuncNum"] + ";")
            $(function() {
                $('li').click(function() {
                    $('#fileExplorer').load('/ImageViewer?directory=' + encodeURIComponent($(this).text()));
                }).hover(function() {
                    $(this).css('cursor', 'pointer');
                });
                $('#fileExplorer').on('click', 'img', function () {
                    var fileUrl = '/Media/' + $(this).attr('title');
                    window.opener.CKEDITOR.tools.callFunction(funcNum, fileUrl);
                    window.close();
                }).hover(function() {
                    $(this).css('cursor', 'pointer');
                });
            });
        </script>
    </head>
    <body>
        <div id="folderExplorer">
            <ul>
            @foreach (var dir in media.EnumerateDirectories().Where(d => d.GetFilesByExtensions(".png", ".gif", ".jpg").Any())) {
                <li>@dir.Name</li>
            }
            </ul>
        </div>
       <div id="fileExplorer"></div>
    </body>
</html>

主要图像文件夹称为媒体,图像存储在子文件夹中。这些都显示在列表中。某些jQuery用于将鼠标悬停在列表项上时将光标设置为指针(手),指示它们是可点击的。当他们单击时,空了 文件管理器 div加载了imageviewer.cshtml的请求结果 - 这是调用thumb.cshtml的文件来显示所选目录的内容的缩略图版本。

下一个jQuery块将单击事件处理程序应用于出现的任何图像 文件管理器 div。它从其标题属性中提取单击映像的URL。它通过该值以及另一个最初由CKEDITOTER发送到FileBrowser文件的值回到编辑器,以便它知道您正在选择文件。文件的URL应用于相应的对话框文本框,然后关闭FileBrowser窗口。

您现在需要做的就是告诉CKEditor,您有文件浏览器,以及它在哪里。您可以在具有编辑器的文件中执行此操作。以下是仅显示编辑器并配置文件浏览器的最小文件:

@{
    
}

<!DOCTYPE html>

<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>CKEditor File Browser FOR ASP.NET Web Pages</title>
        <link href="~/Content/StyleSheet.css" type="text/css" rel="stylesheet" />
        <script type="text/javascript"  SRC. ="~/Scripts/jquery.js"></script>
        <script type="text/javascript"  SRC. ="~/Scripts/ckeditor/ckeditor.js"></script>
        <script>
            $(function () {
                CKEDITOR.replace('Content', {
                    filebrowserBrowseUrl: '/FileBrowser',
                    filebrowserWindowWidth: 800,
                    filebrowserWindowHeight: 600
                });
            });
        </script>
    </head>
    <body>
        <div id="form">
            <form method="post">
                <div>
                    @Html.TextArea("Content")
                </div>
                <div>
                    <input type="submit" />
                </div>
            </form>
        </div>
    </body>
</html>

文件浏览器配置需要将URL传递给FileBrowserBrowSuRL参数,然后可选地为窗口的高度和宽度打开以在指定的URL处显示资源。如果未指定高度或宽度,则将使用80%的可用屏幕宽度的默认值,以及将使用70%的可用高度。

这个例子, 可在github上使用 假设图像位于媒体文件夹的子文件夹中。下载还包括一个只适用于一个图像文件夹的版本。您可以通过下载和运行该站点来访问该版本并请求default2.cshtml。