├── .npm
└── package
│ ├── .gitignore
│ ├── npm-shrinkwrap.json
│ └── README
├── autoform-cloudinary.css
├── package.js
├── README.md
├── autoform-cloudinary.html
├── autoform-cloudinary-server.js
└── autoform-cloudinary.js
/.npm/package/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/autoform-cloudinary.css:
--------------------------------------------------------------------------------
1 | .afCloudinary-thumbnail img {
2 | width: 200px;
3 | }
4 |
--------------------------------------------------------------------------------
/.npm/package/npm-shrinkwrap.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "cloudinary": {
4 | "version": "1.2.1",
5 | "dependencies": {
6 | "q": {
7 | "version": "1.4.1"
8 | },
9 | "lodash": {
10 | "version": "3.6.0"
11 | }
12 | }
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/.npm/package/README:
--------------------------------------------------------------------------------
1 | This directory and the files immediately inside it are automatically generated
2 | when you change this package's NPM dependencies. Commit the files in this
3 | directory (npm-shrinkwrap.json, .gitignore, and this README) to source control
4 | so that others run the same versions of sub-dependencies.
5 |
6 | You should NOT check in the node_modules directory that Meteor automatically
7 | creates; if you are using git, the .gitignore file tells git to ignore it.
8 |
--------------------------------------------------------------------------------
/package.js:
--------------------------------------------------------------------------------
1 | Package.describe({
2 | name: 'cosio55:autoform-cloudinary',
3 | git: 'https://github.com/cosio55/autoform-cloudinary.git',
4 | summary: 'Use Cloudinary with autoform/simpleschema to upload an image, and save the url on the collection.',
5 | version: '0.0.2'
6 | });
7 |
8 | Package.onUse(function (api) {
9 | Npm.depends({
10 | cloudinary: '1.2.1'
11 | });
12 |
13 | api.versionsFrom('1.1.0.2');
14 |
15 | api.use([
16 | 'templating',
17 | 'reactive-var',
18 | 'underscore',
19 | 'check',
20 | 'nekojira:cloudinary-jquery-upload@0.1.0',
21 | 'aldeed:autoform@5.3.0'
22 | ], 'client');
23 |
24 | api.addFiles([
25 | 'autoform-cloudinary.html',
26 | 'autoform-cloudinary.css',
27 | 'autoform-cloudinary.js'
28 | ], 'client');
29 |
30 | api.addFiles([
31 | 'autoform-cloudinary-server.js'
32 | ], 'server');
33 | });
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | About
2 | =====
3 |
4 | This package lets you use Cloudinary with autoform/simpleschema to easily upload an image to your Cloudinary account, and it automatically saves the url for the image using autoform.
5 |
6 | Usage
7 | =====
8 |
9 | 1. `meteor add cosio55:autoform-cloudinary`
10 |
11 | 2. Set up settings.json file
12 |
13 | ```json
14 | {
15 | "public": {
16 | "CLOUDINARY_API_KEY": "[YOUR API KEY]",
17 | "CLOUDINARY_CLOUD_NAME": "[YOUR CLOUD NAME]"
18 | },
19 |
20 | "CLOUDINARY_API_SECRET": "[YOUR API SECRET]"
21 | }
22 | ```
23 |
24 | 3. Create collection and attach simple schema
25 |
26 | ```javascript
27 | Images = new Mongo.Collection('images');
28 |
29 | Images.attachSchema(new SimpleSchema({
30 | image: {
31 | type: String,
32 | autoform: {
33 | afFieldInput: {
34 | type: 'cloudinary'
35 | }
36 | }
37 | }
38 | }));
39 | ```
40 |
41 | 4. Create quick form
42 |
43 | ```html
44 |
45 | {{> quickForm collection="Images" type="insert" id="add-image"}}
46 |
47 | ```
48 |
49 | 5. Run meteor
50 |
51 | `meteor --settings settings.json`
52 |
--------------------------------------------------------------------------------
/autoform-cloudinary.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{#if url}}
4 |
5 |

6 |
7 |
Remove
8 | {{else}}
9 |
13 | {{/if}}
14 |
21 |
25 |
26 |
27 |
28 |
29 |
30 | {{#if url}}
31 |
32 |

33 |
34 |
Remove
35 | {{else}}
36 |
41 | {{/if}}
42 |
49 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/autoform-cloudinary-server.js:
--------------------------------------------------------------------------------
1 | var cloudinary = Npm.require('cloudinary');
2 |
3 | if (process.env.CLOUDINARY_URL) {
4 | var cloudinaryURL = new URI(process.env.CLOUDINARY_URL);
5 | }
6 |
7 | Meteor.methods({
8 | afCloudinarySign: function (params) {
9 | check(params, Match.Optional(Object));
10 |
11 | params = params || {};
12 | params.timestamp = (new Date).getTime();
13 |
14 | return cloudinary.utils.sign_request(params, {
15 | api_key: apiKey(),
16 | api_secret: apiSecret()
17 | });
18 | },
19 | publicCredentials: function() {
20 | if (cloudinaryURL) {
21 | return {
22 | cloudName: apiHost(),
23 | apiKey: apiKey()
24 | }
25 | }
26 | }
27 | });
28 |
29 | apiHost = function() {
30 | if (cloudinaryURL) {
31 | return cloudinaryURL.hostname();
32 | }
33 | };
34 |
35 | apiKey = function () {
36 | if (cloudinaryURL) {
37 | return cloudinaryURL.username();
38 | }
39 |
40 | if (! Meteor.settings ||
41 | ! Meteor.settings.public ||
42 | ! Meteor.settings.public.CLOUDINARY_API_KEY) {
43 | throw new Error('Meteor.settings.public.CLOUDINARY_API_KEY is undefined');
44 | }
45 |
46 | return Meteor.settings.public.CLOUDINARY_API_KEY;
47 | };
48 |
49 | apiSecret = function () {
50 | if (cloudinaryURL) {
51 | return cloudinaryURL.password();
52 | }
53 |
54 | if (! Meteor.settings ||
55 | ! Meteor.settings.CLOUDINARY_API_SECRET) {
56 | throw new Error('Meteor.settings.CLOUDINARY_API_SECRET is undefined');
57 | }
58 |
59 | return Meteor.settings.CLOUDINARY_API_SECRET;
60 | };
61 |
--------------------------------------------------------------------------------
/autoform-cloudinary.js:
--------------------------------------------------------------------------------
1 | AutoForm.addInputType('cloudinary', {
2 | template: 'afCloudinary',
3 |
4 | valueOut: function () {
5 | return this.val();
6 | }
7 | });
8 |
9 | Meteor.startup(function () {
10 | Meteor.call('publicCredentials', function(err, res) {
11 | if (res) {
12 | $.cloudinary.config({
13 | cloud_name: res.cloudName,
14 | api_key: res.apiKey
15 | });
16 | } else {
17 | $.cloudinary.config({
18 | cloud_name: Meteor.settings.public.CLOUDINARY_CLOUD_NAME,
19 | api_key: Meteor.settings.public.CLOUDINARY_API_KEY
20 | });
21 | }
22 | });
23 | });
24 |
25 | var templates = ['afCloudinary', 'afCloudinary_bootstrap3'];
26 |
27 | _.each(templates, function (tmpl) {
28 | Template[tmpl].onCreated(function () {
29 | var self = this;
30 |
31 | self.url = new ReactiveVar();
32 |
33 | self.initialValueChecked = false;
34 | self.checkInitialValue = function () {
35 | Tracker.nonreactive(function () {
36 | if (! self.initialValueChecked && ! self.url.get() && self.data.value) {
37 | self.url.set(self.data.value);
38 | self.initialValueChecked = true;
39 | }
40 | });
41 | };
42 | });
43 |
44 | Template[tmpl].onRendered(function () {
45 | var self = this;
46 |
47 | Meteor.call('afCloudinarySign', function (err, res) {
48 | if (err) {
49 | return console.log(err);
50 | }
51 |
52 | self.$('input[name=file]').cloudinary_fileupload({
53 | formData: res
54 | });
55 | });
56 |
57 | self.$('input[name=file]').on('fileuploaddone', function (e, data) {
58 | self.url.set(data.result.secure_url);
59 | Tracker.flush();
60 | });
61 |
62 | self.$(self.firstNode).closest('form').on('reset', function () {
63 | self.url.set(null);
64 | });
65 | });
66 |
67 | Template[tmpl].helpers({
68 | url: function () {
69 | var t = Template.instance();
70 |
71 | t.checkInitialValue();
72 | return t.url.get();
73 | },
74 |
75 | accept: function () {
76 | return this.atts.accept || 'image/*';
77 | }
78 | });
79 |
80 | Template[tmpl].events({
81 | 'click button': function (e, t) {
82 | t.$('input[name=file]').click();
83 | },
84 |
85 | 'click .js-remove': function (e, t) {
86 | e.preventDefault();
87 | t.url.set(null);
88 | }
89 | });
90 | });
91 |
--------------------------------------------------------------------------------