Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In with Google Sign In with OpenID

Image Handling

edited April 2013 in Framework

Is it possible to make elefant delete associate images when removing a page or listing from an app such as events for instance? Also make the images be renamed on upload.

WordPress does this with both posts/pages. Just a thought. I see that becoming a concerned for use with my people down the road. Most people won't think about going to the file browser to delete images/files. It would eat up space after time as well.

Another question does or can Elefant resize images on upload or can it at least? One thing nice about WP again is it does resize images but one thing that is annoying is it doesn't remove the larger image. Typically I only use the large resized image that WP creates. I think this would be a huge benefit to turning designers/developers more onto the CMS.

Last question is it as well possible for Elefant to create a folder for each page added or say a listing from an app like Events. This would make it much easier when trouble shooting images.

Comments

  • Just reread my post. Excuse my horrible and broken grammar today. I'm a bit under the weather and typing faster than I'm actually processing the output of my grammar.

  • My app does delete images when the listing is deleted, and it does resize on upload, and it does create/delete the folders as appropriate.

  • I was more so speaking on incorporating into the core of the cms. I haven't tested that feature on your app as you know from our discussions.

  • It would be nice, I agree. (Wasn't sure if you'd tested.) The image resizing uses an elefant function; the creating/deleting is something I added.

  • This kind of thing can be done with hooks. A script would parse the blog post body for embedded images, resize them via Image::resize(), update the image tags in the post body and save the changes.

    Image::resize() returns the path to the resized file (stored in the cache folder), which you could then move into a folder like files/posts/123/ where 123 is the blog post ID. Of course, you can always use the value returned by Image::resize() directly, which makes it handy as a filter in templates (e.g., <img src="/{{image_path|Image::resize}}">).

    From there, it's a matter of replacing the <img> tags in the blog post body with the new images and saving the post again, then erasing the old files if needed via unlink().

    Another hook would be needed to remove the files/posts/123/ folder and its contents when that post is deleted, as well as when a post is edited to resize any new images (but not existing ones that were already moved into the files/posts/123/ folder).

    As for being a core CMS behaviour, I think that would be a bit risky. Multiple pages/posts can use the same image, so moving or erasing it automatically could result in a broken image on another page. I guess if it's just being used as a blogging tool that wouldn't be as much of a risk, but as a general purpose CMS that would be better as add-on option.

    Here's an outline of what a hook like this would look like (at least the one for new posts):

    <?php // apps/myapp/handlers/hook/add_post.php
    
    /**
     * Resize/move images in blog posts. Add to conf/config.php's
     * [Hooks] section as:
     *
     *     blog/add[] = myapp/hook/add_post
     */
    
    if (! $this->internal) {
        die ('Must be called by another handler');
    }
    
    // resize dimensions
    $width = 500;
    $height = 300;
    
    // get the post id
    $parts = explode ('/', $this->data['page']);
    array_pop ($parts); // lose the title
    $post_id = array_pop ($parts); // get the ID
    
    // create the folders if they don't exist
    if (! file_exists ('files/posts')) {
        mkdir ('files/posts');
    }
    if (! file_exists ('files/posts/' . $post_id)) {
        mkdir ('files/posts/' . $post_id);
    }
    
    if (preg_match ('/<img src="\/(.+)"/', $this->data['body'], $matches)) {
        foreach ($matches as $image) {
            // resize the image
            $resized = Image::resize ($image, $width, $height);
    
            // move it into the posts folder
            $new_image = 'files/posts/' . $post_id . '/' . basename ($resized);
            rename ($resized, $new_image);
    
            // update the body
            $this->data['body'] = str_replace (
                '<img src="/' . $image . '"',
                '<img src="/' . $new_image . '"',
                $this->data['body']
            );
        }
    }
    
    // update the blog post
    $p = new blog\Post ($post_id);
    $p->body = $this->data['body'];
    $p->put ();
    
    ?>
    
  • Perhaps maybe turning it into an app down the road then. Or incorporating as an option within the CMS. Thanks for the reply.

  • Just a note about my example, in the case of an app that needs an image upload field (photo of a listing, or member profile pic) like @twheel's does, it's definitely a good idea to rename the file in a standardized way after processing it (or even moving it off-disk to S3 or another cloud store).

    In that case though it should happen within the app itself, and not plugged in like my example. And for scalability, when uploads are exposed to public site members (e.g., profile photos), it's often best done in a queue outside of the original web request too.

    An app (or an option in the filemanager app) that offers "plug in" easier upload post-processing capabilities to other apps would be pretty cool too :)

  • Been thinking about image uploads some more and came up with a bit of a proposal:

    https://github.com/jbroadway/elefant/issues/176

    Let me know what you guys think!

  • It seems sophisticated, but I don't think I completely understand the need or the benefits.

  • The purpose is to standardize how to handle file upload processing for images, so apps all do it consistently, but with enough flexibility for the individual app developer.

    Basically, I'd like to use the $.filebrowser helper on the client-side, then pass $_FILES['image_field'] to $model_obj->image_field () and have it take care of the rest automatically based on the info in the $fields array in the model definition.

    Take a look at Paperclip for Rails as an example of what this could do to ease file uploading and processing when building new apps.

Sign In or Register to comment.