Customizing CKEditor to work with clear URL in framework - javascript

I wrote a small framework with URI structure of lang/domain/controller/method/id an now that I want to use CKFinder integrated with CKEditor I cannot upload and browse server because of address structure? What should I do? To browse the server it uses:
http://localhost/public/admin/style1/plugins/ckfinder/ckfinder.html?CKEditor=abstraction&CKEditorFuncNum=1&langCode=fa
Now I have changed upload and browse address by these:
CKEDITOR.replace('article',
{
filebrowserBrowseUrl : '/browser/browse.php',
filebrowserUploadUrl : '/uploader/upload.php'
});
it shows the images but when I choose them it does not bring it to page and it uploads the file to my image folder but cannot add them or even preview them in body or upload dialogbox. How can I use ckeditor with clear URL?

CKFinder with custom paths
If you are doing URL rewrite and you expect CKFinder to return URLs with custom paths you can do the following:
You can configure how CKFinder sends URLs to CKEditor in CKFinder's config.php file in the backends section:
$config['backends'][] = array(
'name' => 'default',
'adapter' => 'local',
'baseUrl' => 'http://base/url/ckfinder/will/give/to/ckeditor',
'root' => '/path/to/files/on/disk',
'chmodFiles' => 0777,
'chmodFolders' => 0755,
'filesystemEncoding' => 'UTF-8'
);
The file path is appended to all URLs and this behavior can't be changed by configuration.
E.g. for /path/to/files/on/disk/images/picture.png the returned URL is http://base/url/ckfinder/will/give/to/ckeditor/images/picture.png
Alternatively you may add 'useProxyCommand' => true to the backend configuration.
This will change all returned URLs to the form of http://localhost/core/connector/php/connector.php?command=Proxy&lang=en&type=Files&currentFolder=%2F&hash=9fd5e9f22b8dea6a&fileName=picture.png, where http://localhost/core/connector/php/connector.php is the URL that was used to make the request to get the file's URL.
Custom integration with a file manager
If you are implementing your own integration with a file manager check your response from /uploader/upload.php. CKEditor expects something like:
<script type='text/javascript'>window.parent.CKEDITOR.tools.callFunction(1, 'http://file/url', 'message');</script>`
You can find more information in the CKEditor's documentation

Related

Can I use Laravel's File Response with AJAX calls to fetch many images?

I want to display images that users upload to storage/uploads/ folder which is outside of the website's root folder (Because I don't want other users to have access to each other's uploaded photos).
I did a test and tried to use the File Response as described in the docs: https://laravel.com/docs/9.x/responses#file-responses
This is how I did it:
In web.php:
Route::get('show_image', [ImageController::class, 'show_image']);
In ImageController:
public function show_image(Request $request)
{
$pathToFile = '../storage/uploads/460s6DLmCnvoom90S7wfk.jpg';
return response()->file($pathToFile);
}
Now when I enter the url of the route in the browser: http://mysite.dev/show_image it displays me the image in the browser inside an img tag with src=http://mysite.dev/show_image (Not a blade file or anything, I simply enter the URL in the browser and it does that automatically.
But the above example was done only with 1 file, and with simply going to the URL in the browser.
But what I really need is to fetch many images from the storage/uploads/ folder using AJAX (Or Fetch API in my case) and then append these images to a list in the browser.
Currently this is how I fetch the files with Fetch API:
const getImagesPromise = fetch('get_images');
getImages
.then((response) => {
})
.then((data) => {
});
But it doesn't seem to return anything I can work with? When I call it for the single image in the test above, I see in devtools that the response preview says Image from http://mysite.dev/show_image. (And again this is just for single file, haven't figured how to call multiple)

How to make a custom url for a file in electron

I am trying to build a mini browser using Electron.js. Is it possible to make urls like chrome://settings or about:config, so that when the user goes to that link I can show an html file? I basically want to associate a url with a file in electron.
You could use Data URIs, and base64-encode the contents of your data as a link. You can use Javascript to encode and decode binary data, then you just specify the MIME type at the start.
If you go to the following URL in a browser for example you'll see a png decoded and rendered:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==
The MDN Web doc in the first link mentions the process of base64 encoding an HTML file.
Alternatively, if you just want to force the download of a link you could add the download attribute to your anchor.
You can use did-start-navigation to detect when they go to chrome://settings/ then intercept that and tell it to go to https://stackoverflow.com/ instead.
Here's the code:
mainWin.webContents.on('did-start-navigation', function (evt, navigateUrl) {
if (navigateUrl == 'chrome://settings/') {
evt.preventDefault();
setTimeout(function () { // Without this it just crashes, no idea why.
mainWin.loadURL('https://stackoverflow.com/');
}, 0);
}
});
I tried the `will-navigate` event, but it didn't work.
Docs for: did-start-navigation
After a little searching at npm, I found a package that does exactly what I want, it's electron protocols. It's a simple way to add custom protolcs in Electron, Here's an example"
const protocols = require('electron-protocols');
const path = require('path');
protocols.register('browser', uri => {
let base = app.getAppPath();
if(uri.hostname == "newtab"){
return path.join(base,"newtab.html")
}
});
In this example, if you go to the link browser://newtab, it opens newtab.html. And if you type location.href the DevTools it shows browser://newtab there too

Trumbowyg: Django server can detect file upload but not image URL input

I'm using Trumbowyg, a WYSIWYG JavaScript editor which has a feature of rendering images from URLs pasted in. It also has an upload plugin which enables uploading local images and custom server side handling.
My python/django function upload_image() can successfully detect the uploaded image - however when I use the URL image input, my python function cannot detect it. Trumbowyg simply renders the image without going through my python backend.
Here's my code:
$('#id_content').trumbowyg({
btnsDef: {
// Create a new dropdown
image: {
dropdown: ['insertImage', 'upload'],
ico: 'insertImage'
}
},
// Redefine the button pane
btns: [
['strong', 'em', 'del'],
['link'],
['image'], // Our fresh created dropdown
],
plugins: {
// Add imagur parameters to upload plugin for demo purposes
upload: {
serverPath: '/upload_image/',
fileFieldName: 'content_image',
urlPropertyName: 'url'
}
}
});
def upload_image(request):
print('Success') #only prints when I use the upload input, not the URL input
Why can in detect the uploaded image but not the URL input?
As already pointed, Trumbowyg doesn't send the URL to backend if the user uploads the image using a URL.
But if you really want to host the images on your own server, there's a way you can do that.
When the user submits the form, you'll receive the content of the textarea in your backend. You can then read the content and look for <img src="..."> tag.
At that point, you can check if the src value doesn't start with your S3 bucket hostname, you can download that image using urllib or requests library, save it to your bucket and replace the src value.
Since the submitted data will be in HTML format, check out the excellent Beautiful Soup. It will make parsing HTML easy.

How to upload an image with CKEditor in AngularJS?

Currently I am using angular-ckeditor to add CKEditor 4.
In my template, I display it as:
<div ng-repeat="editor in editors">
<div ckeditor="options" ng-model="editor.content"></div>
</div>
I'm looking for a way to upload images to CKEditor from desktop. As far as I understand, angular-ckeditor and CKEditor libraries are separate, so I can add widgets and plugins easily.
The problem is that I can't seem to find the right plugins/widgets (that do NOT use jQuery), which will help me to upload an image from desktop. I made it work only with image links.
There is not a lot of documentation about it on the official website. They say to use PHP files that will upload and browse images, but don't really explain how, especially with angular-ckeditor. So I have several questions now:
Which plugins do I need for a simple image uploader, so that I can paste images into CKEditor?
How do I set it up with AngularJS?
What does a PHP file uploader(/browser) look like?
What I have tried so far doesn't even change the CKEditor tabs (it should change the image properties dialog by adding an "Upload" tab and some other UI). So clearly I'm missing a solid tutorial somewhere for all of this.
(I could also try to switch to ng-ckeditor, if a solution with this would be simpler)
First, let's take a look at some basics without Angular. For CKEditor version 4, we can initialize an editor with the filebrowserImageUploadUrl configuration option, which enables functionality from the File Browser API:
CKEDITOR.replace('editor', {
filebrowserImageUploadUrl: '/upload.php?type=image'
});
This just loads an editor instance onto a <textarea name="editor">. Because we set the filebrowserImageUploadUrl option, the Upload tab becomes available in the editor's image dialog. The example value, /upload.php?type=image, is the URL to the PHP script on the server that handles the uploaded image files.
When a user uploads an image, CKEditor will send the image to this URL on the server. The handler at this URL should validate the request, resize the image (if needed), and move the uploaded image to a permanent location on the server. Then, the handler sends an HTML response back to CKEditor with the image's public URL.
Of course, we can write the server-side handler in any language. Here's a basic example for PHP that we'll save as upload.php:
<?php
$tempName = $_FILES['upload']['tmp_name'];
$fileName = uniqid() . $_FILES['upload']['name'];
$uploadPath = '/path/to/uploads/' . $fileName;
$imageUrl = 'http://example.com/uploads/' . $fileName;
$success = move_uploaded_file($tempName, $uploadPath);
$html = '<script>window.parent.CKEDITOR.tools.callFunction(%s, "%s", "%s");</script>';
$message = $success ? 'Uploaded successfully.' : 'Upload failed.';
echo sprintf($html, $_GET['CKEditorFuncNum'], $imageUrl, $message);
This script places an uploaded image into the web server's uploads/ directory so the browser can fetch the image. It passes back the CKEditorFuncNum parameter from the request to identify the appropriate callback for the upload. This example provides some basic protection against duplicate filenames, but, for a real-world application, we'd need to add security, validation, and error handling (authentication, CSRF, file type checking, max size, file name sanitization, etc.).
So far, this all works with CKEditor's standard, built-in functionality (no plugins, Angular, or jQuery needed). To enable users to drag-and-drop or paste images into the editor, we can add the Upload Image plugin to our CKEditor build (or use the standard-all distribution from the CKEditor CDN).
We need to declare the plugin when initializing the editor:
CKEDITOR.replace('editor', {
extraPlugins: 'uploadimage',
filebrowserImageUploadUrl: '/upload.php?type=image'
});
...and then extend our upload.php script to return the JSON response expected by the plugin. Add this block before the last three lines of the previous example:
if (isset($_GET['responseType']) && $_GET['responseType'] === 'json') {
echo json_encode([
'uploaded' => $success,
'fileName' => $fileName,
'url' => $imageUrl,
]);
return;
}
The Upload Image plugin sends the responseType=json URL parameter that the server-side script can check for to determine which type of response to send back.
Finally, let's take a look at how to initialize an editor using the angular-ckeditor package described in the question:
<div ng-controller="EditorCtrl as editor">
<textarea ckeditor="editor.options" ng-model="editor.content"></textarea>
</div>
var myApp = angular.module('myApp', ['ckeditor'])
myApp.controller('EditorCtrl', function () {
this.options = {
extraPlugins: 'uploadimage',
filebrowserImageUploadUrl: '/image-upload.php?type=image'
};
});
As we can see, we don't need to do much to "angularize" this. Once we create our template, we declare the same configuration options that we'd pass to the plain CKEDITOR.replace() on a controller that we reference on an element with the ckeditor directive.

Node Js Meme generation error: File does not exist

Total nodejs newbie here. I am using meme-maker package to generate meme. However I want to create meme with image from url
var fileName = 'https://imgflip.com/s/meme/Futurama-Fry.jpg';
var memeMaker = require('meme-maker')
var options = {
image: fileName, // Required
outfile: 'meme.png', // Required
topText: 'top', // Required
bottomText: 'bottom', // Optional
}
memeMaker(options, function(err) {
if(err) throw new Error(err)
console.log('Image saved: ')
});
However I get error: Error: File does not exist: https://imgflip.com/s/meme/Futurama-Fry.jpg
How to read file from url and make meme?
If you go read the documentation of meme-maker you will see that it only supports local images and not URL's.
You will need to download the image first then use the local address. Go have a look at request
That library does not look like it supports URLs. The image param presumably takes a file path on the local system. If you want to use the URL to make a meme, you will have to:
Download that image from the URL using AJAX or something similar, store it to a file on the disk and get it's local path.
Pass the local file path of the file to the library
Get the generated meme path (and enable download if needed) and do clean up like deleting the old image, for example

Categories