آیا فایل منیجر در CKeditor 5 وجود دارد؟ در بک اند هر سایتی نیاز به یک مدیریت کننده فایل یا همان File Manager میباشد که در همین راستا CKeditor راه کار هایی مثل CKbox و CKfinder را ایجاد کرده اما متاسفانه رایگان نمیباشند. و از سوی دیگر قابلیت های uploadImage و imageInsert موجود در CKeditor دارای مشکلات زیر است :
از همین رو تیم تهران آی تی یک فایل منیجر قدرتمند به نام Tehran IT File Manager ایجاد کرده که دارای قابلیت های زیر است :
فایل منیجر – TIT-FileManager برای ارائه سرویس به بانک اطلاعاتی نیاز دارد و از قابلیت Code First پشتیبانی میکند. برای ایجاد بانک اطلاعاتی مورد نیاز فایل منیجر باید از مدل زیر استفاده کنید. این مدل برای ذخیره سازی اطلاعات و مسیر ذخیره سازی فایل ها میباشد.
نکته : نام مدل حتما باید FM باشد.
[Table(name: "T_FM")]
public class FM
{
[Key]
[Display(Name = "شماره همتای فایل")]
public int FileId { get; set; }
[Display(Name = "تارنمای فایل")]
[Required]
[MaxLength(100)]
public string FileUrl { get; set; }
[Display(Name = "نام فایل")]
[MaxLength(100)]
public string FileName { get; set; }
[Display(Name = "توضیحات فایل")]
[MaxLength(400)]
[DataType(DataType.MultilineText)]
public string FileDescription { get; set; }
[Display(Name = "سایز فایل")]
[Required]
public int FileSize { get; set; }
[Display(Name = "تعداد دانلود فایل")]
public int FileDownload { get; set; }
[Display(Name = "فرمت فایل")]
[Required]
[MaxLength(10)]
public string FileExeption { get; set; }
[Display(Name = "تاریخ ثبت فایل")]
[Required]
public DateTime FileRegisterDate { get; set; }
}
این گام اختیاری میباشد، و صرفا برای اینکه ما بتوانیم خروجی فایل منیجر – TIT-FileManager خود را نمایش دهیم ایجاد شده است. اما شما بنا به نیاز خود میتوانید مدلی ایجاد کنید.
[Table(name: "T-Post")]
public class Post
{
[Key]
[Required]
[Display(Name = "شناسه پست")]
public int PostID { get; set; }
[Required]
[MaxLength(500)]
[Display(Name = "تایتل")]
public string PostTitle { get; set; }
[Display(Name = "محتوا")]
[DataType(DataType.MultilineText)]
[AllowHtml]
public string PostContent { get; set; }
[Display(Name = "تصویر شاخص")]
[MaxLength(100)]
[AllowHtml]
public string PostImage { get; set; }
[Display(Name = "گالری ")]
[AllowHtml]
public string PostGallery { get; set; }
[Display(Name = "کروسل ")]
[AllowHtml]
public string PostCarousel { get; set; }
}
کلاس TIT_FileUploadAjax توسط تیم تهران آی تی برای مدیریت آپلود فایل ها به صورت Ajax نوشته شده و این پروژه به این کلاس نیاز دارد.
یک فولدر به نام Class ایجاد کنید و کلاس TIT_FileUploadAjax را در آن کپی کنید.
نیم اسپیس کلاس را ویرایش کنید namespace ProjectName به جای ProjectName نام پروژه خود را وارد کنید
برای اینکه فایل منیجر به درستی کار کند حتما باید کنترلری برای آن ایجاد کرد نام این کنترلر حتما باید FileManager باشد. کد های زیر را در کنترلر فایل منیجر کپی کنید.
نکته : نام کنترلر حتما باید FileManager باشد.
از طریق بخش هایی که در کد بالا به رنگ طلایی درآمده اند میتوانید بخش آپلود فایل ها را کانفیگ کنید
private MyDbContext db = new MyDbContext();
private string[] AllowedFormat = { "jpg", "png", "gif", "txt", "zip" };
private string FileAddress = "Images/FimeManager";
private string ImageAddressthumbnail = "Images-thumb";
private int MaxContentLength = 1;
public JsonResult Upload()
{
FM MyFile = new FM();
TIT_FileUploadAjax fu = new TIT_FileUploadAjax();
HttpFileCollectionBase files = Request.Files;
for (int i = 0; i < files.Count; i++)
{
HttpPostedFileBase file = files[i];
bool x = fu.Upload(file, MaxContentLength, AllowedFormat, FileAddress, ImageAddressthumbnail + "/" + FileAddress);
if (x)
{
MyFile.FileName = null;
MyFile.FileDescription = null;
MyFile.FileDownload = 0;
MyFile.FileRegisterDate = DateTime.Now;
MyFile.FileExeption = fu.Exeption;
MyFile.FileSize = fu.ContentLength;
MyFile.FileUrl = fu.UrlUpload;
db.FM.Add(MyFile);
db.SaveChanges();
return Json(new { uploaded = true, Message = fu.Message, file = fu.UrlUpload, JsonRequestBehavior.AllowGet });
}
else
{
return Json(new { uploaded = false, Message = fu.Message, JsonRequestBehavior.AllowGet });
}
}
return Json(new { Message = "اتمام بارگزاری", JsonRequestBehavior.AllowGet });
}
public JsonResult LoadFiles(int PageId, int Take = 30)
{
int Count = db.FM.Count();
int Skip = (PageId - 1) * Take;
int PageCount = Count / Take;
if (Count % Take != 0)
{
PageCount++;
}
var file = db.FM.OrderByDescending(t => t.FileRegisterDate).Skip(Skip).Take(Take).ToList();
return Json(new { success = true, file, PageCount = PageCount, PageId = PageId + 1, JsonRequestBehavior.AllowGet });
}
public JsonResult LoadGallery(int PageId, int Take = 30)
{
int Count = db.FM.Where(t => t.FileExeption == "jpg" || t.FileExeption == "png" || t.FileExeption == "gif").Count();
int Skip = (PageId - 1) * Take;
int PageCount = Count / Take;
if (Count % Take != 0)
{
PageCount++;
}
var file = db.FM.OrderByDescending(t => t.FileRegisterDate).
Where(t => t.FileExeption == "jpg" || t.FileExeption == "png" || t.FileExeption == "gif").
Skip(Skip).Take(Take).ToList();
return Json(new { success = true, file, PageCount = PageCount, PageId = PageId + 1, JsonRequestBehavior.AllowGet });
}
[HttpPost]
public JsonResult GetFile(int? id)
{
if (id == null)
{
return Json(new { success = false, JsonRequestBehavior.AllowGet });
}
FM myFile = db.FM.Find(id);
if (myFile == null)
{
return Json(new { success = false, JsonRequestBehavior.AllowGet });
}
return Json(new { success = true, myFile, JsonRequestBehavior.AllowGet });
}
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult RemoveFile(int id)
{
try
{
FM myFile = db.FM.Find(id);
string Address = System.Web.HttpContext.Current.Server.MapPath(myFile.FileUrl);
bool Exist = System.IO.File.Exists(Address);
if (Exist)
{
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.IO.File.Delete(Address);
}
string Address2 = System.Web.HttpContext.Current.Server.MapPath("/" + ImageAddressthumbnail + myFile.FileUrl);
bool Exist2 = System.IO.File.Exists(Address2);
if (Exist2)
{
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.IO.File.Delete(Address2);
}
db.FM.Remove(myFile);
db.SaveChanges();
return Json(new { success = true, JsonRequestBehavior.AllowGet });
}
catch (Exception ex)
{
return Json(new { success = false, message = ex, JsonRequestBehavior.AllowGet });
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult UpdateFile([Bind(Include = "FileId,FileUrl,FileName,FileDescription,FileSize,FileDownload,FileExeption")] FM myFile)
{
myFile.FileRegisterDate = DateTime.Now;
if (ModelState.IsValid)
{
db.Entry(myFile).State = EntityState.Modified;
db.SaveChanges();
return Json(new { success = true, JsonRequestBehavior.AllowGet });
}
return Json(new { success = false, JsonRequestBehavior.AllowGet });
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
<script src="~/Scripts/TIT-FileManager/FileManager.js"></script>
<link href="~/Scripts/TIT-FileManager/FileManager.css" rel="stylesheet" />
برای فراخوانی فایل منیجر کافی است کد زیر را در انتهای صفحه خود و خارج از تگ فرم اضافه کنید.
این کد را در هر صفحه فقط یک بار و خارج از تگ فرم فراخوانی کنید. و در صورتی که در صفحه تگ @Html.AntiForgeryToken() وجود ندارد آن را اضافه کنید باید حداقل یک بار تگ @Html.AntiForgeryToken() در صفحه وجود داشته باشد.
<div id="MyFileManager"></div>
@Html.EditorFor(model => model.PostContent, new { htmlAttributes = new { @class = "form-control editor" } })
با استفاده از کد زیر میتوانید فایل منیجر را به CKeditor اضافه کنید. وظیفه کانفیگ را فانکشن StartFileManager بر عهده دارد که ۴ ورودی میگیرد.
<button type="button" class="btn-save" data-bs-toggle="modal" data-bs-target="#exampleModal" onclick="StartFileManager('ckeditor', true, true, true);">
افزودن فایل چند رسانه ای
</button>
برای ایجاد تصویر شاخص در بخش اسکریپت های همان صفحه توسط کد های زیر آن را معرفی کنید.
$(document).ready(function () {
//for featured-image
window.featured_image = true;
window.featured_image_Input_id = 'PostImage';
});
توسط کد های زیر آن را فراخوانی کنید.
@*featured-image*@
<div class="col-12 col-md-3 featured-image">
<div class="featured shadow">
<div class="featured-header">
<span>تصویر شاخص</span>
</div>
<div class="featured-body">
<img id="img-featured-image" src="~/Scripts/TIT-FileManager/Images/No-Image.jpg" data-bs-toggle="modal" data-bs-target="#exampleModal" onclick="StartFileManager('featured_image', true, true, false);" />
<i class="bi bi-trash3 remove-featured-image" onclick="remove_featured_imag()"></i>
</div>
</div>
</div>
برای ایجاد گالری در بخش اسکریپت های همان صفحه توسط کد های زیر آن را معرفی کنید.
$(document).ready(function () {
//for gallery
window.External_Gallery = true;
window.External_Gallery_Input_id = 'PostGallery';
});
توسط کد های زیر آن را فراخوانی کنید.
@*External_Gallery*@
<div class="col-12 col-md-4 featured-gallery">
<div class="featured shadow">
<div class="featured-header">
<span>کالری</span>
</div>
<div class="featured-body">
<div class="repeater repeater-gallery">
<div id="sortable_gallery" data-repeater-list="group_gallery">
</div>
</div>
<button type="button" class="btn-add-gallery" data-bs-toggle="modal" data-bs-target="#exampleModal" onclick="StartFileManager('gallery', true, false, true);">
<i class="bi bi-camera-fill"></i>
</button>
</div>
</div>
</div>
جهت نمایش گالری در ویو میتوانید از کد های زیر استفاده کنید. توجه داشته باشید که مقدار MyPostGallery در اصل ID تکست باکسی است که گالری در آن ذخیره شده و شما باید با توجه به ID تکست باکسی که گالری در آن ذخیره شده این مقدار را تغییر دهید. و کلاس MyGallery مربوط به تگی است که قرار است کد های گالری در آن قرار گیرد.
$(document).ready(function () {
var x = $('#MyPostGallery').val();
if (x != '') {
var jsonArray = $.parseJSON(x);
var MyRow = '';
$.each(jsonArray, function (key, value) {
$.each(value, function (key1, val) {
MyRow += '\
<div><span>نام تصویر : </span><span>'+ val.gallery_img_name + '</span></div>\
<div><span>توضیحات تصویر : </span><span>'+ val.gallery_img_description + '</span></div>\
<div><span>آدرس تصویر : </span><span>'+ val.gallery_img_url + '</span></div>\
<div><span>آدرس تصویر بند انگشتی : </span><span>'+ val.gallery_img_thumbnail + '</span></div>\
<div>**********************************************************************************</div>';
});
});
$('.MyGallery').append(MyRow);
}
});
برای ایجاد اسلایدر در بخش اسکریپت های همان صفحه توسط کد های زیر آن را معرفی کنید.
$(document).ready(function () {
//for Carousel
window.External_Carousel = true;
window.External_Carousel_Input_id = 'PostCarousel';
});
توسط کد های زیر آن را فراخوانی کنید.
@*External_Carousel*@
<div class="col-12 col-md-5 featured-carousel">
<div class="featured shadow">
<div class="featured-header">
<span>اسلایدر</span>
</div>
<div class="featured-body">
<div class="repeater repeater-carousel">
<div id="sortable_carousel" data-repeater-list="group_Carousel">
</div>
</div>
<button type="button" class="btn-add-carousel" data-bs-toggle="modal" data-bs-target="#exampleModal" onclick="StartFileManager('carousel', true, false, true);">
<i class="bi bi-camera-fill"></i>
</button>
</div>
</div>
</div>
جهت نمایش اسلایدر در ویو میتوانید از کد های زیر استفاده کنید. توجه داشته باشید که مقدار MyPostCarousel در اصل ID تکست باکسی است که اسلایدر در آن ذخیره شده و شما باید با توجه به ID تکست باکسی که اسلایدر در آن ذخیره شده این مقدار را تغییر دهید. و کلاس MyCarousel مربوط به تگی است که قرار است کد های اسلایدر در آن قرار گیرد.
$(document).ready(function () {
var y = $('#MyPostCarousel').val();
if (y != '') {
var jsonArray = $.parseJSON(y);
var MyRowY = '';
$.each(jsonArray, function (key, value) {
$.each(value, function (key1, val) {
MyRowY += '\
<div><span>نام تصویر : </span><span>'+ val.carousel_img_name + '</span></div>\
<div><span>توضیحات تصویر : </span><span>'+ val.carousel_img_description + '</span></div>\
<div><span>آدرس تصویر : </span><span>'+ val.carousel_img_url + '</span></div>\
<div><span>آدرس تصویر بند انگشتی : </span><span>'+ val.carousel_img_thumbnail + '</span></div>\
<div><span>لینک به صفحه : </span><span>'+ val.carousel_img_link + '</span></div>\
<div>**********************************************************************************</div>';
});
});
$('.MyCarousel').append(MyRowY);
}
});
برای نمایش اسلایدر و گالری در گام نهم و دهم توضیحاتی ارائه شد که به روش Jquery بود یعنی باید اطلاعات را در یک تکست باکس هیدن قرار میدادیم و به وسیله کد های Jquery تگ های مورد نظر خود را ساخته و در مکان مناسب آن را Append میکنیم. اما این روش ممکن است به Seo سایت آسیب برساند چون کد ها در زمانی نمایش داده میشود که صفحه به صورت کامل بارگزاری شده باشد. روش مناسب برای نمایش اسلایدر و گالری در صفحات مختلف استفاده از View Model ها میباشد که به شرح ذیل است.
public class GalleryViewModel
{
public string ImageName { get; set; }
public string ImageDescription { get; set; }
public string ImageUrl { get; set; }
public string ImageThumbnailUrl { get; set; }
}
public class CarouselViewModel
{
public string ImageName { get; set; }
public string ImageDescription { get; set; }
public string ImageUrl { get; set; }
public string ImageThumbnailUrl { get; set; }
public string ImageLink { get; set; }
}
public class PostViewModel
{
[Key]
[Required]
[Display(Name = "شناسه پست")]
public int PostID { get; set; }
[Required]
[MaxLength(500)]
[Display(Name = "تایتل")]
public string PostTitle { get; set; }
[Display(Name = "محتوا")]
[DataType(DataType.MultilineText)]
[AllowHtml]
public string PostContent { get; set; }
[Display(Name = "تصویر شاخص")]
[MaxLength(100)]
[AllowHtml]
public string PostImage { get; set; }
[Display(Name = "گالری ")]
[AllowHtml]
public IEnumerable<GalleryViewModel> PostGallery { get; set; }
[Display(Name = "کروسل ")]
[AllowHtml]
public IEnumerable<CarouselViewModel> PostCarousel { get; set; }
}
در این اکشن چون با Json کار میکنیم حتما بسته Newtonsoft.Json را از ناگت به پروژه اضافه کنید.
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Post post = db.Posts.Find(id);
if (post == null)
{
return HttpNotFound();
}
PostViewModel model = new PostViewModel();
model.PostID = post.PostID;
model.PostTitle = post.PostTitle;
model.PostContent = post.PostContent;
model.PostImage = post.PostImage;
//Gallery
List<GalleryViewModel> listGallery = new List<GalleryViewModel>();
if (post.PostGallery != null)
{
JObject JsonGallery = JObject.Parse(post.PostGallery);
if (JsonGallery != null)
{
foreach (var item in JsonGallery.Values())
{
foreach (var x in item)
{
listGallery.Add(new GalleryViewModel
{
ImageName = x["gallery_img_name"].ToString(),
ImageDescription = x["gallery_img_description"].ToString(),
ImageUrl = x["gallery_img_url"].ToString(),
ImageThumbnailUrl = x["gallery_img_thumbnail"].ToString()
});
}
}
}
}
model.PostGallery = listGallery;
//End Gallery
//Carouse
List<CarouselViewModel> listCarouse = new List<CarouselViewModel>();
if (post.PostCarousel != null)
{
JObject JsonCarousel = JObject.Parse(post.PostCarousel);
if (JsonCarousel != null)
{
foreach (var item in JsonCarousel.Values())
{
foreach (var x in item)
{
listCarouse.Add(new CarouselViewModel
{
ImageName = x["carousel_img_name"].ToString(),
ImageDescription = x["carousel_img_description"].ToString(),
ImageUrl = x["carousel_img_url"].ToString(),
ImageThumbnailUrl = x["carousel_img_thumbnail"].ToString(),
ImageLink = x["carousel_img_link"].ToString()
});
}
}
}
}
model.PostCarousel = listCarouse;
//End Carouse
return View(model);
}
<div class="header-dd">
<span>اسلایدر</span>
</div>
<div class="body-dd">
@if (Model.PostCarousel != null)
{
foreach (var x in Model.PostCarousel)
{
<div>@x.ImageName</div>
<div>@x.ImageDescription</div>
<div>@x.ImageUrl</div>
<div>@x.ImageThumbnailUrl</div>
<div>@x.ImageLink</div>
<div>****************</div>
}
}
</div>
<div class="header-dd">
<span>اسلایدر</span>
</div>
<div class="body-dd">
@if (Model.PostCarousel != null)
{
int i = 0;
int y = 0;
<div id="carouselExampleCaptions" class="carousel slide" data-bs-ride="false">
<div class="carousel-indicators">
@foreach (var x in Model.PostCarousel)
{
if (i == 0)
{
<button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="@i" class="active" aria-current="true" aria-label="Slide @i"></button>
}
else
{
<button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="@i" aria-label="Slide @i"></button>
}
i++;
}
</div>
<div class="carousel-inner">
@foreach (var x in Model.PostCarousel)
{
if (y == 0)
{
<div class="carousel-item active">
<img src="@x.ImageUrl" class="d-block w-100" alt="...">
<div class="carousel-caption d-none d-md-block">
<div class="">
<h5>@x.ImageName</h5>
<p>@x.ImageDescription</p>
</div>
</div>
</div>
}
else
{
<div class="carousel-item">
<img src="@x.ImageUrl" class="d-block w-100" alt="...">
<div class="carousel-caption d-none d-md-block">
<h5>@x.ImageName</h5>
<p>@x.ImageDescription</p>
</div>
</div>
}
y++;
}
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
}
</div>
<div class="header-dd">
<span>گالری</span>
</div>
<div class="body-dd">
@if (Model.PostGallery != null)
{
foreach (var x in Model.PostGallery)
{
<div>@x.ImageName</div>
<div>@x.ImageDescription</div>
<div>@x.ImageUrl</div>
<div>@x.ImageThumbnailUrl</div>
<div>****************</div>
}
}
</div>
در صورتی که میخواهید به گالری خود قابلیت LightBox بدهید میتوانید از لینک زیر پلاگین Jquery آن را دانود کنید و به پروژه اضافه کنید.
https://www.jqueryscript.net/lightbox/Responsive-Touch-enabled-jQuery-Image-Lightbox-Plugin.html
<div class="header-dd">
<span>گالری</span>
</div>
<div class="body-dd">
@if (Model.PostGallery != null)
{
<div class="MyGallery">
@foreach (var x in Model.PostGallery)
{
<a href="@x.ImageUrl" class="big" rel="rel1">
<img src="@x.ImageThumbnailUrl" alt="@x.ImageDescription" title="@x.ImageName">
</a>
}
</div>
}
</div>
برای شخصی سازی یک ماژل جدید میتوانید از باتن زیر برای شروع کار استفاده کنید
<button type="button" class="btn-save" data-bs-toggle="modal" data-bs-target="#exampleModal" onclick="StartFileManager('Modul Name', true, true, true);">نام دلخواه</button>
در صورتی که میخواهید قابلیت فایل را برای ماژول خود فعال کنید به FileManager.JS بروید و در فانکشن FileBtnAdd از شرط زیر استفاده کنید.
else if (FileManagerType == 'Modul_Name') {
alert(id + '***' + url + '***' + exeption + '***' + $('#A_FileDescription').val() + '***' + $('#A_FileName').val() + '***' );
$("#exampleModal").modal("hide");
}
در صورتی که میخواهید قابلیت گالری را برای ماژول خود فعال کنید به FileManager.JS بروید و در فانکشن CreateGallery از شرط زیر استفاده کنید.
else if (FileManagerType == 'Modul_Name') {
RowG += '<img src="' + defaultImage + '" alt="' + itemname + '" title="' + itemdescription + '"/><img src="' + thumbnail + '" alt="' + itemname + '" title="' + itemdescription + '"/>';
}
و برای نمایش از شرط زیر استفاده کنید.
else if (FileManagerType == 'Modul_Name') {
$('#MyId').append(RowG);
ResetGallery();
$("#exampleModal").modal("hide");
}
https://github.com/ahadian2/WebApplicationFileManager
خرید از تهران آی تی به صورت آنلاین بوده لینک دانلود به صورت خودکار برای شما ایمیل میشود بدیهی است که در هنگام خرید باید از ایمیل واقعی خود استفاده کنید. چنانچه نیاز به هرگونه سوال درباره محصول و یا مشاوره و کمک در خرید آنلاین داشتید از طریق ایمیل و یا شماره های تماس ارتباط برقرار کنید 09121486770 ahadian2@gmail.com