diff options
| -rw-r--r-- | app/index.js | 50 | ||||
| -rw-r--r-- | app/node_modules/okserver/index.js | 11 | ||||
| -rw-r--r-- | app/node_modules/okservices/oks3/index.js | 139 | ||||
| -rw-r--r-- | app/node_modules/okservices/oks3/package.json | 5 | ||||
| -rw-r--r-- | app/node_modules/okservices/oks3/upload.js | 79 | ||||
| -rw-r--r-- | app/node_modules/okservices/okwebhook/index.js | 83 | ||||
| -rw-r--r-- | app/node_modules/okservices/okwebhook/package.json | 11 | ||||
| -rw-r--r-- | examples/db.json | 24 | ||||
| -rw-r--r-- | examples/index.js | 33 | ||||
| -rw-r--r-- | examples/lib/okdumpfm/index.js | 39 | ||||
| -rw-r--r-- | examples/lib/okdumpfm/package.json | 14 | ||||
| -rw-r--r-- | examples/lib/okexample/index.js | 49 | ||||
| -rw-r--r-- | examples/lib/okexample/package.json | 11 | ||||
| -rw-r--r-- | package.json | 7 | ||||
| -rw-r--r-- | themes/okadmin/public/css/main.css | 4 | ||||
| -rw-r--r-- | themes/okadmin/public/js/app.js | 26 | ||||
| -rw-r--r-- | themes/okadmin/public/js/upload.js | 5 | ||||
| -rw-r--r-- | themes/okadmin/templates/index.liquid | 59 | ||||
| -rw-r--r-- | themes/okadmin/templates/partials/inputs.liquid | 22 |
19 files changed, 528 insertions, 143 deletions
diff --git a/app/index.js b/app/index.js index 1a8f97e..48e713a 100644 --- a/app/index.js +++ b/app/index.js @@ -15,6 +15,7 @@ var OKServer = require('okserver'); var OKSchema = require('okschema'); var OKS3Service = require('okservices/oks3'); var OKTwitterService = require('okservices/oktwitter') +var OKWebhookService = require('okservices/okwebhook') require('dotenv').load(); @@ -94,19 +95,37 @@ function OKCMS(options) { errorHandler); // Create services - if (serviceConfig.s3) { - var s3Service = OKS3Service({ - express: express, - s3: serviceConfig.s3, - }); - } - - if (serviceConfig.twitter) { - var twitterService = OKTwitterService({ - express: express, - credentials: serviceConfig.twitter, - }) - } + var services = {} + Object.keys(serviceConfig).forEach(function(key){ + var config = serviceConfig[key] + switch (key) { + case 's3': + services.s3 = OKS3Service({ + express: express, + s3: config, + }); + break + case 'twitter': + services.twitter = OKTwitterService({ + express: express, + credentials: config, + }); + break + case 'webhook': + services.webhook = OKWebhookService({ + express: express, + config: config, + }); + break + default: + services[key] = config.lib({ + db: resourceCache, + express: express, + config: config, + }); + break + } + }); var server = this._server = new OKServer({ express: express, @@ -117,10 +136,7 @@ function OKCMS(options) { root: root, adminRoot: adminRoot, adminPath: adminPath, - services: { - s3: s3Service, - twitter: twitterService, - }, + services: services, errorHandler: errorHandler }); } diff --git a/app/node_modules/okserver/index.js b/app/node_modules/okserver/index.js index 3428565..a89676f 100644 --- a/app/node_modules/okserver/index.js +++ b/app/node_modules/okserver/index.js @@ -52,6 +52,8 @@ function OKServer(options) { * other middleware. */ + // Disable x-powered-by express header + app.disable('x-powered-by') // Serve user static files app.use(express.static(root)); // Serve admin interface static files @@ -59,12 +61,9 @@ function OKServer(options) { // Application router app.use(router); // Add services - if (services.s3) { - app.use('/_services/s3', services.s3.middleware()); - } - if (services.twitter) { - app.use('/_services/twitter', services.twitter.middleware()) - } + Object.keys(services).forEach(function(key){ + app.use('/_services/' + key, services[key].middleware()); + }) // Make sure this lady is last. Checks whether the desired // route has a trailing-slash counterpart and redirects there app.use(slash()); diff --git a/app/node_modules/okservices/oks3/index.js b/app/node_modules/okservices/oks3/index.js index 34c5840..cc40b71 100644 --- a/app/node_modules/okservices/oks3/index.js +++ b/app/node_modules/okservices/oks3/index.js @@ -1,5 +1,5 @@ -var skipper = require('skipper'); -var skipperS3 = require('skipper-s3') +var upload = require("./upload") +var multer = require('multer') // Hack to prevent this god-forsaken module from crashing our shit var d = require('domain').create() @@ -20,10 +20,6 @@ function OKS3(options) { if (!options.s3.audio) options.s3.audio = {} if (!options.s3.video) options.s3.video = {} -/* - // TODO: maxBytes property doesn't work - if you upload a large file, - // it will just hang until you reload the browser, and then CRASH. - // Make sure maxbytes property is there - it can be a number, // or zero/undefined (for no maximum upload size) if (options.s3.maxbytes) { @@ -34,85 +30,104 @@ function OKS3(options) { if (! ('maxbytes' in options.s3.audio)) options.s3.audio.maxbytes = options.s3.maxbytes } -*/ - if (options.s3.image.preserveFilename) - options.s3.image.preserveFilename = preserveFilename - if (options.s3.video.preserveFilename) - options.s3.video.preserveFilename = preserveFilename - if (options.s3.audio.preserveFilename) - options.s3.audio.preserveFilename = preserveFilename + if (typeof options.s3.image.allowed !== "boolean") + options.s3.image.allowed = true + if (typeof options.s3.video.allowed !== "boolean") + options.s3.video.allowed = false + if (typeof options.s3.audio.allowed !== "boolean") + options.s3.audio.allowed = false + + upload.init({ + key: options.s3.key, + secret: options.s3.secret, + bucket: options.s3.bucket, + }) var express = options.express; var router = express.Router(); - router.use(skipper()); + var mult = multer() - // req should have a method `file` on it which is - // provided by skipper. Use that to do AWS stuff - router.post('/image', function(req, res) { + router.post('/image', mult.single('image'), function(req, res) { d.run(function () { - var skip = req.file('image').upload({ - adapter: skipperS3, - key: options.s3.key, - secret: options.s3.secret, - bucket: options.s3.bucket, + + if (! options.s3.image.allowed) { + return res.status(500).json({ error: "Image uploading not permitted" }) + } + + upload.put({ + file: req.file, + preserveFilename: options.s3.image.preserveFilename, dirname: options.s3.dirname, - // maxBytes: options.s3.image.maxbytes, - saveAs: options.s3.image.preserveFilename, - headers: { - 'x-amz-acl': 'public-read' + types: { + 'image/gif': 'gif', + 'image/jpeg': 'jpg', + 'image/jpg': 'jpg', + 'image/png': 'png', + }, + unacceptable: function(err){ + res.json({ error: err }) + }, + success: function(url){ + res.json({ url: url }) } - }, function (err, uploadedFiles) { - if (err) return res.status(500).send(err) - res.json(uploadedFiles); - }); + }) + }); }); - router.post('/audio', function(req, res) { + router.post('/audio', mult.single('audio'), function(req, res) { d.run(function () { - if (! options.s3.allowAudioUploads) { - return res.status(500).json({ error: "audio uploading not permitted" }) + + if (! options.s3.image.allowed) { + return res.status(500).json({ error: "Audio uploading not permitted" }) } - req.file('audio').upload({ - adapter: skipperS3, - key: options.s3.key, - secret: options.s3.secret, - bucket: options.s3.bucket, + + upload.put({ + file: req.file, + preserveFilename: options.s3.audio.preserveFilename, dirname: options.s3.dirname, - // maxBytes: options.s3.audio.maxbytes, - saveAs: options.s3.audio.preserveFilename, - headers: { - 'x-amz-acl': 'public-read' + types: { + 'audio/mp3': 'mp3', + 'audio/mpeg': 'mp3', + 'audio/wav': 'wav', + 'audio/flac': 'flac', + }, + unacceptable: function(err){ + res.json({ error: err }) + }, + success: function(url){ + res.json({ url: url }) } - }, function (err, uploadedFiles) { - if (err) res.status(500).send(err) - res.json(uploadedFiles); - }); + }) + }); }); - router.post('/video', function(req, res) { + router.post('/video', mult.single('video'), function(req, res) { d.run(function () { - if (! options.s3.allowVideoUploads) { - return res.status(500).json({ error: "video uploading not permitted" }) + + if (! options.s3.image.allowed) { + return res.status(500).json({ error: "Video uploading not permitted" }) } - req.file('video').upload({ - adapter: skipperS3, - key: options.s3.key, - secret: options.s3.secret, - bucket: options.s3.bucket, + + upload.put({ + file: req.file, + preserveFilename: options.s3.video.preserveFilename, dirname: options.s3.dirname, - // maxBytes: options.s3.video.maxbytes, - saveAs: options.s3.video.preserveFilename, - headers: { - 'x-amz-acl': 'public-read' + types: { + 'video/mp4': 'mp4', + 'video/webm': 'webm', + }, + unacceptable: function(err){ + res.json({ error: err }) + }, + success: function(url){ + res.json({ url: url }) } - }, function (err, uploadedFiles) { - if (err) res.status(500).send(err) - res.json(uploadedFiles); - }); + }) + }); }); diff --git a/app/node_modules/okservices/oks3/package.json b/app/node_modules/okservices/oks3/package.json index 19a2d2a..61da414 100644 --- a/app/node_modules/okservices/oks3/package.json +++ b/app/node_modules/okservices/oks3/package.json @@ -9,7 +9,8 @@ "author": "OKFocus", "license": "None", "dependencies": { - "skipper": "^0.5.9", - "skipper-s3": "^0.5.6" + "knox": "^0.9.2", + "multer": "^1.1.0", + "node-uuid": "^1.4.7" } } diff --git a/app/node_modules/okservices/oks3/upload.js b/app/node_modules/okservices/oks3/upload.js new file mode 100644 index 0000000..517d5f7 --- /dev/null +++ b/app/node_modules/okservices/oks3/upload.js @@ -0,0 +1,79 @@ + +var knox = require('knox') +var uuid = require('node-uuid') + +var s3 + +var acceptableuploadTypes = { + 'image/gif': 'gif', + 'image/jpeg': 'jpg', + 'image/jpg': 'jpg', + 'image/png': 'png', +} + +module.exports = {} + +module.exports.init = function (opt){ + s3 = knox.createClient({ + key: opt.key, + secret: opt.secret, + bucket: opt.bucket, + }) +} + +module.exports.put = function (opt) { + var filename + var err + var now = new Date() + + var file = opt.file + + var types = opt.types || acceptableuploadTypes + var extension = types[file.mimetype] + + if (opt.preserveFilename) { + filename = file.originalname + } + else { + filename = uuid.v1() + "." + extension; + } + + var remote_path = "/" + opt.dirname + "/" + filename + + if (! extension) { + err = "Unacceptable filetype." + } + else if (opt.maxSize && file.size > opt.maxSize) { + err = "File too large. Uploads can be a maximum of " + opt.maxSize + " bytes." + } + + if (err) { + console.error(">>>", err) + opt.unacceptable && opt.unacceptable(err) + return + } + + opt.acceptable && opt.acceptable(err) + + // console.log("upload >", remote_path) + s3.putBuffer(file.buffer, remote_path, { + 'Content-Length': file.size, + 'Content-Type': file.mimetype, + 'x-amz-acl': 'public-read' + }, function(err, s3res) { + if (err || s3res.statusCode !== 200) { + console.error(err); + if (s3res && s3res.resume) { + s3res.resume() + } + return; + } + + var file_url = s3res.url || s3res.req.url + + opt.success && opt.success(file_url) + }).on('error', function(err, s3res){ + console.error(err) + s3res && s3res.resume && s3res.resume() + }) +} diff --git a/app/node_modules/okservices/okwebhook/index.js b/app/node_modules/okservices/okwebhook/index.js new file mode 100644 index 0000000..d04e662 --- /dev/null +++ b/app/node_modules/okservices/okwebhook/index.js @@ -0,0 +1,83 @@ + +/** + * Service which will listen for a Github webhook, fired on push. + * This service can be used to rebuild / restart the app automatically + * when new code is pushed. + */ + +var crypto = require('crypto') +var exec = require('child_process').exec +var path = require('path') + +function OKWebhook (options) { + if (!(this instanceof OKWebhook)) return new OKWebhook(options) + options = options || {} + if (!options.express) + throw new Error('Express not provided to OKWebhook'); + if (!options.config) + throw new Error('Configuration not provided to OKWebhook'); + if (options.config.active && !options.config.secret) + throw new Error('Github secret not provided to OKWebhook'); + if (options.config.active && !options.config.command) + throw new Error('Build command not provided to OKWebhook'); + + var express = options.express + var router = express.Router() + var config = options.config + + var secret = config.secret + var command = config.command + + router.get('/', function (req, res) { + res.send('GET not supported') + }) + + router.post('/', getBody, function (req, res) { + if (!config.active) + return + console.log("OKWebhook received push") + var event = req.headers['x-github-event'] + if (event !== "push") { + return res.sendStatus(500) + } + var sig = req.headers['x-hub-signature'].split('=')[1] + var text = req.rawBody + var hash = crypto.createHmac('sha1', secret).update(text).digest('hex') + if (hash !== sig) { + return res.sendStatus(500) + } + res.sendStatus(200) + var cwd = path.dirname(command) + exec(command, { cwd: cwd }, function(err, stdout, stderr){ + // may not fire if process was restarted.. + console.log(process.env) + console.log(stdout) + }) + }) + + function getBody (req, res, next) { + req.rawBody = '' + // req.setEncoding('utf8') + + req.on('data', function(chunk) { + req.rawBody += chunk + }) + + req.on('end', function() { + try { + req.body = JSON.parse(req.rawBody) + } catch (e) { + return res.sendStatus(500) + } + next() + }) + } + + this._router = router +} + +OKWebhook.prototype.middleware = function () { + return this._router +} + +module.exports = OKWebhook diff --git a/app/node_modules/okservices/okwebhook/package.json b/app/node_modules/okservices/okwebhook/package.json new file mode 100644 index 0000000..0436f01 --- /dev/null +++ b/app/node_modules/okservices/okwebhook/package.json @@ -0,0 +1,11 @@ +{ + "name": "okwebhook", + "version": "1.0.0", + "description": "webhook to receive pushes from github", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "okfocus <frontdesk@okfoc.us>", + "license": "LNT" +} diff --git a/examples/db.json b/examples/db.json index 8805342..401bf26 100644 --- a/examples/db.json +++ b/examples/db.json @@ -154,13 +154,21 @@ "title": "Red", "media": [ { + "uri": "https://ltho.s3.amazonaws.com/okcms-example/a91c4210-080c-11e6-8a7d-f30231d4ec26.png", + "width": "800", + "height": "800", + "caption": "", + "type": "image" + }, + { "uri": "http://asdf.us/", "caption": "ASDF", "type": "link" } ], "__index": 0, - "dateCreated": "Mon, 28 Mar 2016 23:02:45 GMT" + "dateCreated": "Mon, 28 Mar 2016 23:02:45 GMT", + "flagged": false }, { "id": "blue", @@ -210,5 +218,19 @@ ], "flagged": true } + ], + "flour": [ + { + "id": "test", + "title": "TEST", + "image": { + "uri": "https://ltho.s3.amazonaws.com/okcms-example/7be163d0-080b-11e6-8a7d-f30231d4ec26.png", + "caption": "", + "width": "800", + "height": "800" + }, + "__index": 0, + "dateCreated": "Thu, 21 Apr 2016 21:52:44 GMT" + } ] }
\ No newline at end of file diff --git a/examples/index.js b/examples/index.js index fe37954..341a50b 100644 --- a/examples/index.js +++ b/examples/index.js @@ -1,10 +1,13 @@ var okcms = require('..'); +var isProduction = process.env.OK_PRODUCTION === 'true' + var app = okcms.createApp({ root: 'public', - debug: true, + debug: !isProduction, + production: isProduction, schemas: { page: { @@ -26,6 +29,11 @@ var app = okcms.createApp({ title: {type: 'string'}, flagged: {type: 'flag'}, media: {type: 'media-list'}, + }, + flour: { + id: {type: 'string', hidden: true}, + title: {type: 'string'}, + image: {type: 'image'}, } }, @@ -34,6 +42,7 @@ var app = okcms.createApp({ { type: 'page', static: {id: 'contact'}}, { type: 'bread' }, { type: 'test' }, + { type: 'flour' }, ], services: { @@ -42,10 +51,24 @@ var app = okcms.createApp({ secret: process.env.S3_SECRET, bucket: process.env.S3_BUCKET, dirname: "okcms-example", - // TODO: maxbytes stuff isn't working, need to change underlying module - image: { preserveFilename: false, maxbytes: 20000 }, - video: { preserveFilename: true, maxbytes: 0 }, - audio: { preserveFilename: true, maxbytes: 150000000 }, + image: { allowed: true, preserveFilename: false, maxbytes: 2*1024*1024 }, + video: { allowed: true, preserveFilename: true, maxbytes: 200*1024*1024 }, + audio: { allowed: true, preserveFilename: true, maxbytes: 100*1024*1024 }, + }, + + webhook: { + active: false, + secret: 'test', + command: '/path/to/build.sh', + }, + + example: { + lib: require("./lib/okexample"), + stuff: "things", + }, + + dumpfm: { + lib: require("./lib/okdumpfm"), } }, diff --git a/examples/lib/okdumpfm/index.js b/examples/lib/okdumpfm/index.js new file mode 100644 index 0000000..4dc5461 --- /dev/null +++ b/examples/lib/okdumpfm/index.js @@ -0,0 +1,39 @@ +var request = require('request') + +/** + * Example service which queries the Dump search. + */ +function OKDumpfm (options) { + if (!(this instanceof OKDumpfm)) return new OKDumpfm(options) + options = options || {} + if (!options.express) + throw new Error('Express not provided to OKDumpfm'); + + var express = options.express + var router = express.Router() + + router.get('*', function (req, res) { + var query = req.query.q + request('http://dump.fm/cmd/search/' + query, function (err, response, body) { + if (err || response.statusCode !== 200) { + res.status(response.statusCode) + res.send(err) + } else { + res.set('Content-Type', 'application/json; charset=utf-8') + res.send(body) + } + }) + }) + + router.post('*', function (req, res) { + throw new Error('OKDumpfm POST requests not implemented') + }) + + this._router = router +} + +OKDumpfm.prototype.middleware = function () { + return this._router +} + +module.exports = OKDumpfm diff --git a/examples/lib/okdumpfm/package.json b/examples/lib/okdumpfm/package.json new file mode 100644 index 0000000..17bcba2 --- /dev/null +++ b/examples/lib/okdumpfm/package.json @@ -0,0 +1,14 @@ +{ + "name": "okdumpfm", + "version": "1.0.0", + "description": "service to query the dump search API", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "okfocus <frontdesk@okfoc.us>", + "license": "LNT", + "dependencies": { + "request": "^2.71.0" + } +} diff --git a/examples/lib/okexample/index.js b/examples/lib/okexample/index.js new file mode 100644 index 0000000..04c5984 --- /dev/null +++ b/examples/lib/okexample/index.js @@ -0,0 +1,49 @@ + +/** + * Example service to show how these things should be set up. + * + * Services should be added to index.js in the proper area, + * with any configuration parameters that you want passed in: + * + * services: { + * example: { + * lib: require("./lib/okexample"), + * stuff: "things", + * } + * }, + * + * The service will be mounted on /_services/example + * + * This binds to route '*' but you can specify e.g. "/thing", + * and it will be mounted on /_services/example/thing + */ + +function OKExample (options) { + if (!(this instanceof OKExample)) return new OKExample(options) + options = options || {} + if (!options.express) + throw new Error('Express not provided to OKExample'); + if (!options.config) + throw new Error('Configuration not provided to OKExample'); + + var express = options.express + var router = express.Router() + var config = options.config + var db = options.db + + router.get('*', function (req, res) { + res.send(config.stuff) + }) + + router.post('*', function (req, res) { + throw new Error('OKExample POST requests not implemented') + }) + + this._router = router +} + +OKExample.prototype.middleware = function () { + return this._router +} + +module.exports = OKExample diff --git a/examples/lib/okexample/package.json b/examples/lib/okexample/package.json new file mode 100644 index 0000000..2b2a47c --- /dev/null +++ b/examples/lib/okexample/package.json @@ -0,0 +1,11 @@ +{ + "name": "okexample", + "version": "1.0.0", + "description": "example service", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "okfocus <frontdesk@okfoc.us>", + "license": "LNT" +} diff --git a/package.json b/package.json index 2d5df49..c78669a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "okcms", - "version": "0.1.27", - "description": "great", + "version": "0.1.35", + "description": "The dopest CMS on the planet.", "main": "app/index.js", "scripts": { "postinstall": "./install.sh", @@ -13,7 +13,8 @@ "dotenv": "^1.1.0", "express": "^4.12.3", "object-assign": "^2.0.0", - "q": "^1.2.0" + "q": "^1.2.0", + "request": "^2.71.0" }, "devDependencies": { "grunt": "^0.4.5", diff --git a/themes/okadmin/public/css/main.css b/themes/okadmin/public/css/main.css index 9e0c26f..5fbb624 100644 --- a/themes/okadmin/public/css/main.css +++ b/themes/okadmin/public/css/main.css @@ -297,7 +297,9 @@ button, input[type=submit] { height: 7em; } .main.resource form img { - width: 10em; + width: auto; + height: auto; + max-width: 10em; max-height: 6em; border: 0; } diff --git a/themes/okadmin/public/js/app.js b/themes/okadmin/public/js/app.js index 59fc6ae..578d99f 100644 --- a/themes/okadmin/public/js/app.js +++ b/themes/okadmin/public/js/app.js @@ -9,8 +9,10 @@ var OKAdmin = function(){ var url = media.url var imageTemplate = $(".image-template", parent).html() var $el = $(imageTemplate) - $el.find(".uri").val(url) - $el.find("img").attr("src", url) + $el.find(".uri").val(media.url) + $el.find(".image-width").val(media.width) + $el.find(".image-height").val(media.height) + $el.find("img").attr("src", media.url) $("ol", parent).prepend($el) } }) @@ -44,8 +46,10 @@ var OKAdmin = function(){ var url = media.url var imageTemplate = $(".image-template", parent).html() var $el = $(imageTemplate) - $el.find(".uri").val(url) - $el.find("img").attr("src", url) + $el.find(".uri").val(media.url) + $el.find(".image-width").val(media.width) + $el.find(".image-height").val(media.height) + $el.find("img").attr("src", media.url) $("ol", parent).prepend($el) } uploader.addMedia = function(media){ @@ -103,11 +107,13 @@ var OKAdmin = function(){ var $el = $(this) var uploader = new OKUpload () uploader.bind( this ) - uploader.add = function(url){ - console.log(url) - $el.find(".uri").val(url) + uploader.add = function(media){ + console.log(media) + $el.find(".uri").val(media.url) $el.find(".caption").val("") - $el.find("img").attr("src", url).show() + $el.find(".image-width").val(media.width) + $el.find(".image-height").val(media.height) + $el.find("img").attr("src", media.url).show() $el.addClass("loaded") } }) @@ -117,6 +123,8 @@ var OKAdmin = function(){ var $el = $(this).closest(".image") $el.removeClass('loaded') $el.find(".uri").val("") + $el.find(".image-width").val("") + $el.find(".image-height").val("") $el.find(".caption").val("") $el.find("img").attr("src", "") } @@ -141,7 +149,7 @@ var OKAdmin = function(){ $el.parent().addClass("loaded") $el.parent().find(".video-type").val( media.type ) $el.parent().find(".video-token").val( media.token ) - $el.parent().find(".video-uri").val( media.uri ) + $el.parent().find(".video-uri").val( media.url ) $el.parent().find(".video-title").val( media.title ) $el.parent().find(".video-thumb").val( media.thumbnail ) $el.parent().find(".video-width").val( media.width ) diff --git a/themes/okadmin/public/js/upload.js b/themes/okadmin/public/js/upload.js index 44a34b5..6ff7ac9 100644 --- a/themes/okadmin/public/js/upload.js +++ b/themes/okadmin/public/js/upload.js @@ -167,7 +167,7 @@ OKUpload.prototype.success = function(data){ console.log(data.error) return } - var url = data[0].extra.Location.replace(/%2F/, '\/') + var url = data.url console.log(url) this.parse(url) } @@ -177,9 +177,6 @@ OKUpload.prototype.add = function(media){ OKUpload.prototype.addMedia = function(media){ console.log(media) } -OKUpload.prototype.addAudio = function(media){ - console.log(media) -} OKUpload.prototype.error = function(error){ throw error } diff --git a/themes/okadmin/templates/index.liquid b/themes/okadmin/templates/index.liquid index 8255d99..c8c4aa5 100644 --- a/themes/okadmin/templates/index.liquid +++ b/themes/okadmin/templates/index.liquid @@ -17,35 +17,36 @@ <input type="hidden" name="_method" value="PUT"> {% if resource.groupBy %} {% assign i = 0 %} - {% for pair in resource.data[resource.groupBy] %} - {% assign group = pair[0] %} - {% assign members = pair[1] %} - <section class="resource-category {{group}}"> - <header> - <h2>{{group | capitalize}}</h2> - </header> - <ol class="resource-list"> - {% for data in members %} - <li> - {% if data.disabled %} <del> {% endif %} - <a href="{{resource.type}}/{{data.id}}/">{{data.title}}</a> - {% if data.disabled %} </del> {% endif %} - <input class="resource-input" type="hidden" name="{{resource.type}}[{{i}}]" - value='{{data | stringify | escape_once}}'> - </li> - {% assign i = i | plus: 1 %} - {% endfor %} - </ol> - <footer> - <nav> - <a class="btn cancel-btn" href="#">cancel</a> - <button type="submit" - class="btn save-btn" href="#">save</button> - <a class="btn edit-btn active" href="#">sort</a> - <a class="btn add-btn active" href="{{resource.type}}/__new__/">+</a> - </nav> - </footer> - </section> + {% for item in resource.data %} + {% for pair in item[resource.groupBy] %} + {% assign group = pair[0] %} + {% assign members = pair[1] %} + <section class="resource-category {{group}}"> + <header> + <h2>{{group | capitalize}}</h2> + </header> + <ol class="resource-list"> + {% for data in members %} + <li> + {% if data.disabled %} <del> {% endif %} + <a href="{{resource.type}}/{{data.id}}/">{{data.title}}</a> + {% if data.disabled %} </del> {% endif %} + <input class="resource-input" type="hidden" name="{{resource.type}}[{{increment i}}]" + value='{{data | stringify | escape_once}}'> + </li> + {% endfor %} + </ol> + <footer> + <nav> + <a class="btn cancel-btn" href="#">cancel</a> + <button type="submit" + class="btn save-btn" href="#">save</button> + <a class="btn edit-btn active" href="#">sort</a> + <a class="btn add-btn active" href="{{resource.type}}/__new__/">+</a> + </nav> + </footer> + </section> + {% endfor %} {% endfor %} {% else %} <ol class="resource-list"> diff --git a/themes/okadmin/templates/partials/inputs.liquid b/themes/okadmin/templates/partials/inputs.liquid index 28b422e..e83bec0 100644 --- a/themes/okadmin/templates/partials/inputs.liquid +++ b/themes/okadmin/templates/partials/inputs.liquid @@ -48,6 +48,8 @@ <div class="image-element"> <input class="uri" type="hidden" name="{{name}}[uri]" value="{{spec.value.uri}}"> <textarea class="caption" name="{{name}}[caption]">{{spec.value.caption | escape}}</textarea> + <input type="hidden" name="{{name}}[width]" value="{{spec.value.width}}" class="image-width"> + <input type="hidden" name="{{name}}[height]" value="{{spec.value.height}}" class="image-height"> <img src="{{spec.value.uri}}" alt="{{spec.value.caption | escape}}"> <button class="remove">x</button> </div> @@ -69,7 +71,7 @@ <div class="flag"> <input name="{{name}}" type="checkbox" - {% if spec.value == 'true' %} + {% if spec.value %} checked="true" {% endif %} value="true"> @@ -153,7 +155,9 @@ <label>Caption</label> <input class="uri" type="hidden" name="{{name}}[][uri]" value=""> <textarea class="caption" name="{{name}}[][caption]"></textarea> - <input type="hidden" name="media[][type]" value="image"> + <input type="hidden" name="{{name}}[][type]" value="image"> + <input type="hidden" name="{{name}}[][width]" class="image-width" hidden> + <input type="hidden" name="{{name}}[][height]" class="image-height" hidden> <img> <button class="remove">x</button> </li> @@ -165,8 +169,8 @@ <input name="{{name}}[][type]" type="hidden" class="video-type" hidden> <input name="{{name}}[][token]" type="hidden" class="video-token" hidden> <input name="{{name}}[][uri]" type="hidden" class="video-uri" hidden> - <input name="{{name}}[][width]" value="{{image.width}}" type="hidden" class="video-width" hidden> - <input name="{{name}}[][height]" value="{{image.height}}" type="hidden" class="video-height" hidden> + <input name="{{name}}[][width]" type="hidden" class="video-width" hidden> + <input name="{{name}}[][height]" type="hidden" class="video-height" hidden> <label>Caption</label> <input name="{{name}}[][title]" type="text" class="video-title"> <label>Thumbnail</label> @@ -259,6 +263,8 @@ <li class="image-element"> <label>Caption</label> <input type="hidden" name="{{name}}[][uri]" value="{{image.uri}}"> + <input name="{{name}}[{{forloop.index0}}][width]" value="{{image.width}}" type="hidden" class="image-width" hidden> + <input name="{{name}}[{{forloop.index0}}][height]" value="{{image.height}}" type="hidden" class="image-height" hidden> <textarea class="caption" name="{{name}}[][caption]">{{image.caption | escape}}</textarea> <input type="hidden" name="{{name}}[][type]" value="image"> <img src="{{image.uri}}" alt="{{image.caption | strip_html}}"> @@ -281,6 +287,8 @@ <script type="text/html" class="image-template"> <li class="image-element"> <input class="uri" type="hidden" name="{{name}}[][uri]" value=""> + <input type="hidden" name="{{name}}[][width]" class="image-width" hidden> + <input type="hidden" name="{{name}}[][height]" class="image-height" hidden> <textarea class="caption" name="{{name}}[][caption]"></textarea> <img> <button class="remove">x</button> @@ -291,6 +299,8 @@ {% for image in spec.value %} <li class="image-element"> <input type="hidden" name="{{name}}[{{forloop.index0}}][uri]" value="{{image.uri}}"> + <input type="hidden" name="{{name}}[{{forloop.index0}}][width]" value="{{image.width}}" class="image-width"> + <input type="hidden" name="{{name}}[{{forloop.index0}}][height]" value="{{image.height}}" class="image-height"> <textarea class="caption" name="{{name}}[{{forloop.index0}}][caption]">{{image.caption | escape}}</textarea> <img src="{{image.uri}}" alt="{{image.caption | strip_html}}"> <button class="remove">x</button> @@ -313,6 +323,8 @@ <img> <button class="remove">x</button> <input class="uri" type="hidden" name="{{name}}[][uri]" value=""> + <input type="hidden" name="{{name}}[][width]" class="image-width"> + <input type="hidden" name="{{name}}[][height]" class="image-height"> <input class="caption" name="{{name}}[][label]" placeholder="Name"> <input class="caption" name="{{name}}[][caption]" placeholder="Email"> </li> @@ -324,6 +336,8 @@ <img src="{{image.uri}}" alt="{{image.caption | strip_html}}"> <button class="remove">x</button> <input type="hidden" name="{{name}}[{{forloop.index0}}][uri]" value="{{image.uri}}"> + <input type="hidden" name="{{name}}[{{forloop.index0}}][width]" value="{{image.width}}" class="image-width"> + <input type="hidden" name="{{name}}[{{forloop.index0}}][height]" value="{{image.height}}" class="image-height"> <input class="caption" name="{{name}}[{{forloop.index0}}][label]" value="{{image.label | escape}}" placeholder="Name"> <input class="caption" name="{{name}}[{{forloop.index0}}][caption]" value="{{image.caption | escape}}" placeholder="Email"> </li> |
