1

I want to allow registered users to insert (i.e. upload) images into a Redactor rich text field in a front-end form.

I dowloaded the Image Manager plugin from Imperavi (https://imperavi.com/redactor/plugins/imagemanager/) and set up my Redactor config as follows:

{% includeJsResource "lib/redactor/redactor.js" %}
{% includeJsResource "lib/redactor/plugins/source.js" %}
{% includeJsResource "lib/redactor/plugins/fullscreen.js" %}
{% includeJsResource "lib/redactor/plugins/imagemanager.js" %}
{% includeCssResource "lib/redactor/redactor.css" %}

{% set redactorJS %}
    $('#{{ elId }}').redactor({
        buttons: ['format', 'bold', 'italic', 'deleted', 'lists', 'link', 'html', 'image'],
        formatting: ['p', 'blockquote', 'h2', 'h3'],
        plugins: ['source','fullscreen', 'imagemanager'],
        minHeight: 300,
        imageUpload: '/upload.php',
    });
{% endset %}
{% includeJs redactorJS %}

I can see the image button in the toolbar and the browse files modal when I click the image button. However, it doesn’t upload anything because imageUpload: '/upload.php', is obviously incorrect. What, if anything, can I replace upload.php with? If this isn’t possible, what else could I do to achieve this functionality? Thanks!

UPDATE:

I have the following code in craft/plugins/imagesuploaderscript/controllers/ImagesUploaderScriptController.php from CloudApp share link in comment below:

namespace Craft;

class ImagesUploaderScriptController extends BaseController {

protected $valid_extensions = array('jpg', 'jpeg', 'png');
protected $assetSourceId = 1;
protected $assetFolderId = 1;

public function actionUpload()
{
    $this->requireAjaxRequest();

    $errors = array();
    $success = array();

    if (!$_FILES['file']['error'])
    {
        $filename = $_FILES['file']['name'];
        $file = $_FILES['file']['tmp_name'];
        $extension = pathinfo($filename, PATHINFO_EXTENSION);

        if (!in_array($extension, $this->valid_extensions))
        {
            $errors[] = "$filename has an invalid extension.";
        } else {
            $uploadDir = craft()->assetSources->getSourceById($this->assetSourceId)->settings['path'];

            if (move_uploaded_file($file, $uploadDir . $filename))
            {
                IOHelper::deleteFile($file);

                $file = $uploadDir . $filename;

                $fileModel = new AssetFileModel();
                $fileModel->sourceId = $this->assetSourceId;
                $fileModel->folderId = $this->assetFolderId;
                $fileModel->filename = IOHelper::getFileName($filename);
                $fileModel->kind = IOHelper::getFileKind(IOHelper::getExtension($filename));
                $fileModel->size = filesize($file);
                $fileModel->dateModified = IOHelper::getLastTimeModified($file);

                craft()->assets->storeFile($fileModel);

                // print_r($fileModel);

                // displaying file
                $image = array(
                    'url' => 'images/'.$filename,
                    'id' => 1
                );
                $this->returnJSON($image);
                exit;
            }
            else
            {
                $errors[] = "$filename was unable to be saved.";
            }
        }
    }

    $this->returnJSON(compact('errors'));
    exit;
}

}

How do I get my form to talk to it? Also, what else do I need to do to get it to work?

2
  • I'm not sure if there is a really quick and dirty solution without messing things up in some way or another. The best way would be creating a custom redactor plugin. Craft made it's own for that craft/app/resources/js/craft/redactor.js::10511 you could search for an existing one or create your own. All in all you have to send a request to the AssetController with the file and the parent folder and return the img tag. I've done it with quilljs.com but not with the redactor. If you want I can show you the default code Commented Nov 30, 2017 at 15:58
  • Hi Robin, Thanks! Quill looks quite nice. I would be very interested in seeing the code. Commented Dec 1, 2017 at 15:30

1 Answer 1

3

It doesn't seems possible natively, you should write a custom upload script.

Example #1

Example #2

If it doesn't matter to add the images inside your rich text field, one more simple workaround could be to allow image upload to your assets using a separate upload field.

Uploading Files from Front-end Entry Forms

5
  • Hi Romain, Thanks. The front-end form is to publish blog posts. I already have a separate upload field for the posts' featured image. However, I want users to be able to insert images between paragraphs. Ideally, I'd do this with a Matrix field, but my JS skills are insufficient to add new blocks on the front-end. I saw example #1. However, example #2 looks more interesting since I would also like to rename files on upload. I would basically be creating a plugin, correct? Could I use pluginfactory.io and select Controllers comp. & put content of ex. #2 in it? Commented Nov 30, 2017 at 19:09
  • Yes, you should write a plugin with a controller. Content of example #2 is a good start, but it needs some adaptations to works with Redactor. I made a first draft, which starts to work ; I could send it to you later.
    – Romain P.
    Commented Dec 1, 2017 at 12:28
  • Hi Romain, that would be most helpful. I don't have any experience with plugin development yet, so any help is greatly appreciated. Commented Dec 1, 2017 at 15:28
  • Sorry for the late reply, I'm still very busy since my previous message. Here is perhaps something to start: cl.ly/2p0C3q1g2q0p. Please note that this will not work as it is currently, it's just a quick first draft. Hope you can start something with this. I don't have so experience in plugin development, but don't be afraid, your request is a very good opportunity to learn!
    – Romain P.
    Commented Jan 5, 2018 at 10:54
  • Many thanks, Romain, I'll give it a go and when I get it working, I'll share it with Craft community. Commented Jan 5, 2018 at 14:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.