Skip to content

okgrow/meteor-image-upload

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

90 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Deprecated

DISCLAIMER - Development of this package is currently on hiatus. We are currently not actively developing this package due to both resource constraints and uncertainty about how well supported it will be in the future. We are using this in our active projects, so we will continue to do bug fixes as we encounter them, but feature requests may go unanswered. PRs are still welcome.

Image Upload for Meteor

Image Upload makes it super easy for you to setup a photo input field along with all the trimmings (S3, collections, permissions, templates, etc.). Under the hood you will find ImageUpload is just a sugary wrapper around collectionFS.

To get familiar with ImageUpload take a look at the rest of this read me as well as our example:

Example app live

Example app source

One-time Setup

Prerequisites

  1. AWS S3 account for cloud file storage.

  2. GraphicsMagick or ImageMagick on your local machine and deployment server for image manipulation.

  • OS X: brew install imagemagick or brew install graphicsmagick

  • Modulus.io: supports ImageMagick no setup needed

  • Heroku, DigitalOcean, AWS EC2: requires manual ImageMagick/GraphicsMagick installation.

  • Meteor.com free hosting does not support ImageMagick/GraphicsMagick, sorry no way around it :(

Install & Configure

Install from your terminal meteor add okgrow:image-upload.

Configure in common code (server and client ).

API: ImageUpload.configure( options )

Example

ImageUpload.configure({
  accessKeyId: YOUR_ACCESS_KEY_ID,
  secretAccessKey: YOUR_SECRET_ACCESS_KEY,
  bucketName: YOUR_BUCKET_NAME,
  bucketUrl: YOUR_BUCKET_URL, //"https://your_bucket_name.s3.amazonaws.com/",
  maxUploadSize: 30 // MB
});

WARNING You should never store your keys publicly, instead use Meteor.settings. Start your app using meteor --settings settings.json. Refer to our example app settings file to see how we do it.

Note Since 0.8.0 publicRead is now set in the image collection options. ImageUpload will throw an error if you try and pass publicRead in ImageUpload.configure()

Creating Image Collections

The images you upload will be stored in separate Image Upload collections. You will probably have more than one Image Upload collection. The Image Upload collections are created differently from Meteor collections, we show you how to make these special collections below.

Each Image Upload collection will reference and index it's documents to one of your app's data collections as specified, only one app data collection can be referenced per each Image Upload collection. We show you how to query by reference ids in templating below.

API: ImageUpload.createCollection( name, reference, { [options] } )

Options:

Name Optional Description
defaultPermissions optional Enables default Allow rules on your image collection, see Security Rules to see the rules
publicRead optional set to true to server files directly from S3, bucketUrl in .configure() is also required. Also allows visitors to view images if defaultPermissions is also true.
sizes optional Let ImageMagick create multiple different sizes of each image automatically. Specify a size name as the key followed by an array for X,Y px lengths

The following creates an image collection called userImages which will be associated with the Meteor.users collection with images stored in four sizes:

  1. The original image
  2. "thumbnail": 200x200 px
  3. "normal": 800x800 px
  4. "large:": 1200x1200 px
UserImages = ImageUpload.createCollection("userImages", Meteor.users, {
  defaultPermissions: true,
  sizes: {
  thumbnail: [200, 200],
    normal: [800,800],
    large: [1200, 1200]
  }
});

Allow/Deny Security Rules

Please add your own allow/deny rules and/or enable ImageUpload's defaultPermissions when creating the ImageUpload collection.

defaultPermissions if enabled:

ImageCollection.allow({
  insert: function(userId, doc) {
    // Any authenticated user can create images
    return !!userId;
  },
  update: function(userId, doc) {
     // User can update their own image only
    return doc && doc.addedBy === userId;
  },
  remove: function(userId, doc) {
     // User can remove their own image only
    return doc && doc.addedBy === userId;
  },
  download: function (userId, fileObj) {
    // If publicRead has been set anyone can download, otherwise users
    // can only download images that they uploaded
    if (publicRead) {
      return true;
    } else {
      return fileObj.addedBy === userId;
    }
  }
});

Note: Since the image collection is based on CollectionFS, we use their allow and deny system. You can view their documentation here:

https://github.com/CollectionFS/Meteor-CollectionFS#security

Client-side Templating

Upload Image Template

You want a nice upload button with everything wired up for you? We got ya covered.

API: {{> uploadImage imageCollection=collectionName [option=option] }}

Examples:

{{> uploadImage imageCollection="userImages" size="thumbnail" doc=currentUser classImage="tiny-img round"}}

{{> uploadImage imageCollection="postImages" name="post-image" size="banner" }}

Attributes:

Name Optional Description
imageCollection required Specify the Image Upload collection images go to. hint: This was the first parameter when creating the Image Upload collection.
doc optional When adding a new image to an existing document you can pass the existing document and we will make the reference for you. We pull the reference _id from the supplied object.
size optional Specify the image size you want displayed when upload completes. By default this partial template displays the original uploaded image once complete. hint: You made these sizes when creating your Image Upload collection.
name optional Specify a custom input element name. This overwrites the default input name attribute, image
classInput optional Specify custom CSS class(es) for the input element. Included class is image-file-picker
classImage optional Specify custom CSS class(es) for the image when it displays after upload completes. Included class isuploaded-image

Display Image

To display a stored image, you can

<template name="yourTemplate">
  <img src="{{image}}"/>
</template>

Which uses a helper which loads a document from the image collection:

Template.yourTemplate.helpers({
  image: function() {
    var doc = Template.parentData(1);
    var image = yourImageCollection.findOne({associatedObjectId: doc._id});
    if (image) {
      return image.url({store: "userImages-thumbnail"});
    }
  }
});

Roadmap / TODO

In order of fuzzy priority:

  • Less configuration to setup
  • Better error handling
  • Default upload progress bar
  • In-browser image cropping/resizing with darkroom.js
  • Upload files from a URL

Contributing

Issues and Pull Requests are always welcome. Please read our contribution guidelines.

Direct Uploads to S3?

At this point we don't have plans to support uploading files directly from the browser's client to AWS's S3. We may add this in the future, but there we will probably wait until CollectionFS supports this (they have it in the works). Pull requests welcome.

Enjoy!