Compare commits
10 commits
50612b1a83
...
dc8639c5ef
Author | SHA1 | Date | |
---|---|---|---|
dc8639c5ef | |||
f952d44841 | |||
634bddc093 | |||
03e691ed2e | |||
1c9c8b1a5a | |||
062cc251ba | |||
11fd6d9aa2 | |||
23265dce80 | |||
b9b4a68b11 | |||
c7465cc151 |
31 changed files with 707 additions and 334 deletions
96
app.js
96
app.js
|
@ -5,7 +5,6 @@ var passport = require('passport');
|
|||
var Strategy = require('passport-local').Strategy;
|
||||
var async = require('async');
|
||||
var fs = require('fs');
|
||||
var markdown = require( "markdown" ).markdown;
|
||||
var moment = require("moment");
|
||||
|
||||
// Make ourselves a nice little express app.
|
||||
|
@ -16,6 +15,7 @@ var MongoClient = require('mongodb').MongoClient;
|
|||
|
||||
// Include some other JS
|
||||
Post = require('./post.js');
|
||||
Photo = require('./photo.js');
|
||||
User = require('./user.js');
|
||||
Category = require('./category.js');
|
||||
Static = require('./static.js');
|
||||
|
@ -104,11 +104,12 @@ app.get('/admin/view/uploads',
|
|||
function(req, res, next) {
|
||||
Post.getNeedsUpload(function (err, posts) {
|
||||
if (err) console.log(err);
|
||||
res.render('admin-view-uploads', {
|
||||
successNotice: req.flash('successNotice'),
|
||||
failureNotice: req.flash('failureNotice'),
|
||||
posts: posts,
|
||||
user: req.user
|
||||
Photo.getNeedsUpload(function (err, photos) {
|
||||
res.render('admin-view-uploads', {
|
||||
successNotice: req.flash('successNotice'),
|
||||
failureNotice: req.flash('failureNotice'),
|
||||
user: req.user
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -119,38 +120,77 @@ app.get('/admin/view/builds',
|
|||
function(req, res, next) {
|
||||
Post.getNeedsBuild(function (err, posts) {
|
||||
if (err) console.log(err);
|
||||
res.render('admin-view-builds', {
|
||||
successNotice: req.flash('successNotice'),
|
||||
failureNotice: req.flash('failureNotice'),
|
||||
posts: posts,
|
||||
user: req.user
|
||||
Photo.getNeedsBuild(function (err, photos) {
|
||||
res.render('admin-view-builds', {
|
||||
successNotice: req.flash('successNotice'),
|
||||
failureNotice: req.flash('failureNotice'),
|
||||
user: req.user
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Admin page to build all unbuilt items
|
||||
app.get('/admin/build',
|
||||
function(req, res, next) {
|
||||
Post.getNeedsBuild(function (err, posts) {
|
||||
if (!err) {
|
||||
for (i=0; i<posts.length; i++) {
|
||||
posts[i].build(function (err) {
|
||||
if (err) console.log(err);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
console.log(err);
|
||||
}
|
||||
});
|
||||
Photo.getNeedsBuild(function(err, photos) {
|
||||
if (!err) {
|
||||
for (i=0; i<photos.length; i++) {
|
||||
photos[i].build(function (err) {
|
||||
if (err) console.log(err);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
console.log(err);
|
||||
}
|
||||
});
|
||||
req.flash('successNotice', 'All items built.');
|
||||
res.redirect(req.header('Referer') || '/admin');
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// Admin dashboard page.
|
||||
app.get('/admin',
|
||||
function(req, res, next) {
|
||||
Post.countPosts(function (err, postCount) {
|
||||
Category.countCategories(function (err, categoryCount) {
|
||||
Post.getLastBuildDate(function (err, lastBuildDate) {
|
||||
Post.getLastUploadDate( function (err, lastUploadDate) {
|
||||
res.render('admin-dashboard', {
|
||||
successNotice: req.flash('successNotice'),
|
||||
failureNotice: req.flash('failureNotice'),
|
||||
categories: categoryCount,
|
||||
posts: postCount,
|
||||
galleries: "###",
|
||||
photos: "###",
|
||||
tags: "###",
|
||||
regenerateDate: moment(lastBuildDate).format("YYYY-MM-DD HH:mm"),
|
||||
uploadDate: moment(lastUploadDate).format("YYYY-MM-DD HH:mm"),
|
||||
user: req.user});
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
Photo.countPhotos(function (err, photoCount) {
|
||||
Post.getNeedsBuild(function (err, buildPosts) {
|
||||
Photo.getNeedsBuild(function (err, buildPhotos) {
|
||||
Post.getNeedsUpload(function (err, uploadPosts) {
|
||||
Photo.getNeedsUpload(function (err, uploadPhotos) {
|
||||
res.render('admin-dashboard', {
|
||||
successNotice: req.flash('successNotice'),
|
||||
failureNotice: req.flash('failureNotice'),
|
||||
categories: categoryCount,
|
||||
posts: postCount,
|
||||
galleries: "###",
|
||||
photos: photoCount,
|
||||
tags: "TBD",
|
||||
buildCount: buildPosts.length + buildPhotos.length,
|
||||
uploadCount: uploadPosts.length + uploadPhotos.length,
|
||||
user: req.user
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
function changeImg(e) {
|
||||
if (e.getAttribute('load') == 'lazy') {
|
||||
path = '/photos/'+e.getAttribute('slug');
|
||||
path = e.getAttribute('slug');
|
||||
if (window.devicePixelRatio && window.devicePixelRatio > 1) {
|
||||
console.log('Loading retina version of '+e.getAttribute('slug'));
|
||||
e.setAttribute('load', 'loaded');
|
||||
e.src = path+'/'+e.getAttribute('size')+'2x.'+e.getAttribute('ext');
|
||||
e.src = path+e.getAttribute('size')+'2x.'+e.getAttribute('ext');
|
||||
}
|
||||
else {
|
||||
console.log('Loading non-retina version of '+e.getAttribute('slug'));
|
||||
e.setAttribute('load', 'loaded');
|
||||
e.src = path+'/'+e.getAttribute('size')+'.'+e.getAttribute('ext');
|
||||
e.src = path+e.getAttribute('size')+'.'+e.getAttribute('ext');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,4 @@
|
|||
@media (min-width: 768px) {
|
||||
div.nav-title-block {
|
||||
height:240px;
|
||||
bottom:20px;
|
||||
position:fixed;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
div.nav-title-block img.img-responsive {
|
||||
max-width: 200px;
|
||||
}
|
||||
article {
|
||||
border-bottom: 1px rgb(119, 119, 119) solid;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
|
|
@ -9,13 +9,13 @@
|
|||
"connect-redis": "^3.0.2",
|
||||
"cookie-parser": "^1.3.5",
|
||||
"debug": "^2.2.0",
|
||||
"exif": "^0.5.1",
|
||||
"express": "^4.13.1",
|
||||
"express-flash": "^0.0.2",
|
||||
"express-session": "^1.13.0",
|
||||
"gm": "^1.21.1",
|
||||
"jade": "^1.11.0",
|
||||
"lodash": "^4.0.0",
|
||||
"markdown": "^0.5.0",
|
||||
"marked": "^0.3.5",
|
||||
"moment": "^2.11.1",
|
||||
"mongodb": "^2.1.4",
|
||||
"morgan": "^1.6.1",
|
||||
|
@ -25,6 +25,7 @@
|
|||
"passport": "^0.3.0",
|
||||
"passport-local": "^1.0.0",
|
||||
"redis": "^2.4.2",
|
||||
"serve-favicon": "^2.3.0"
|
||||
"serve-favicon": "^2.3.0",
|
||||
"sharp": "^0.12.2"
|
||||
}
|
||||
}
|
||||
|
|
93
photo.js
93
photo.js
|
@ -3,11 +3,11 @@ var _ = require("lodash");
|
|||
var fs = require('fs');
|
||||
var mkdirp = require('mkdirp');
|
||||
var jade = require('jade');
|
||||
var markdown = require( "markdown" ).markdown;
|
||||
var marked = require('marked');
|
||||
var path = require('path');
|
||||
var schemas = require('./schemas.js');
|
||||
var gm = require('gm');
|
||||
var config = require("./config.js").config;
|
||||
var sharp = require('sharp');
|
||||
|
||||
var Photo = function(data) {
|
||||
this.data = this.sanitize(data);
|
||||
|
@ -52,7 +52,7 @@ Photo.prototype.save = function (date, callback) {
|
|||
|
||||
// Parse a string of tags
|
||||
// Returns a list of tags
|
||||
Post.prototype.tagPhoto = function(str) {
|
||||
Photo.prototype.tagPhoto = function(str) {
|
||||
this.set("tags", []);
|
||||
|
||||
// we don't need no stinking commas
|
||||
|
@ -97,14 +97,14 @@ Photo.prototype.getShortDate = function () {
|
|||
// Arguments: None
|
||||
// Returns: Content as String
|
||||
Photo.prototype.renderMarkdown = function () {
|
||||
return markdown.toHTML(this.get("markdown"));
|
||||
return marked(this.get("markdown"));
|
||||
}
|
||||
|
||||
// Function to get the relative url of a photo, this sets the permalink structure
|
||||
// Arguments: None
|
||||
// Returns: URL as String
|
||||
Photo.prototype.getURL = function () {
|
||||
var url = "/photo/";
|
||||
var url = "/photos/";
|
||||
url += moment(this.get("photoDate")).format("YYYY/MM/");
|
||||
url += this.get("slug") + '/';
|
||||
return url;
|
||||
|
@ -153,13 +153,11 @@ Photo.prototype.makeSlug = function () {
|
|||
// Arguments: Callback function
|
||||
// Returns: err
|
||||
Photo.prototype.build = function (callback) {
|
||||
var options = {
|
||||
console.log('Rendering photo: '+this.get("title"));
|
||||
var jadeOut = jade.renderFile('views/render-photo.jade', {
|
||||
pretty: true,
|
||||
photo: this
|
||||
};
|
||||
|
||||
console.log('Rendering photo: '+this.get("title"));
|
||||
var jadeOut = jade.renderFile('views/render-photo.jade', options);
|
||||
});
|
||||
|
||||
console.log('Creating directory: '+ this.getDirectory());
|
||||
|
||||
|
@ -169,20 +167,20 @@ Photo.prototype.build = function (callback) {
|
|||
if (err) console.log(err);
|
||||
for (var size in config.imageSizes) {
|
||||
console.log('Generating '+size+' for '+self.get("slug"));
|
||||
(function(size){
|
||||
gm(photo.path)
|
||||
.autoOrient()
|
||||
.resize(config.imageSizes[size], config.imageSizes[size])
|
||||
.write(path.join(self.getDirectory(),size+'.'+self.get("extension")),
|
||||
function(err) {
|
||||
if (err) {
|
||||
(function (size) {
|
||||
var outFile = path.join(self.getDirectory(),size+'.'+self.get("extension"));
|
||||
sharp(self.get('masterPath'))
|
||||
.resize(config.imageSizes[size], config.imageSizes[size])
|
||||
.max()
|
||||
.quality(95)
|
||||
.withoutEnlargement()
|
||||
.toFile(outFile, function(err) {
|
||||
if (!err) {
|
||||
console.log(self.get("slug")+' '+size+' generated.');
|
||||
} else {
|
||||
console.log(self.get("slug")+' resize failed.');
|
||||
}
|
||||
else {
|
||||
console.log(self.get("slug")+' '+size+' generated.');
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
})(size);
|
||||
}
|
||||
|
||||
|
@ -229,7 +227,7 @@ Photo.getLastUploadDate = function (callback) {
|
|||
// Inputs: UUID as String
|
||||
// Returns: Photo object
|
||||
Photo.getByUUID = function (uuid, callback) {
|
||||
db.collection("posts").findOne({uuid: uuid}, function(err, doc) {
|
||||
db.collection("photos").findOne({uuid: uuid}, function(err, doc) {
|
||||
callback(err, new Photo(doc));
|
||||
});
|
||||
}
|
||||
|
@ -247,7 +245,7 @@ Photo.countPhotos = function (callback) {
|
|||
// Function to get a list of posts of a certain count and starting at an offset
|
||||
// Count and start are optional, when start is specified count must be specified.
|
||||
// Returns a list of post objects
|
||||
Photos.getPhotos = function (count, start, callback) {
|
||||
Photo.getPhotos = function (count, start, callback) {
|
||||
if (typeof callback === undefined) {
|
||||
if (typeof start === undefined) {
|
||||
callback = count;
|
||||
|
@ -275,5 +273,50 @@ Photos.getPhotos = function (count, start, callback) {
|
|||
});
|
||||
}
|
||||
|
||||
// Export the Post object for external use.
|
||||
// Function to find photos that need to be built
|
||||
// Inputs: Callback function
|
||||
// Returns: list of Photo objects
|
||||
Photo.getNeedsBuild = function (callback) {
|
||||
db.collection("photos").find({
|
||||
$where: "(this.lastBuildDate < this.updatedDate) && this.published"
|
||||
}).toArray(
|
||||
function (err, docs) {
|
||||
if (err) console.log(err);
|
||||
photos = [];
|
||||
if (docs) {
|
||||
for (i=0; i<docs.length; i++) {
|
||||
photos.push(new Photo(docs[i]));
|
||||
}
|
||||
callback(null, photos);
|
||||
} else {
|
||||
callback('No photos need to be built.', null);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Function to find photos that need to be uploaded
|
||||
// Inputs: Callback function
|
||||
// Returns: List of Photo objects
|
||||
Photo.getNeedsUpload = function (callback) {
|
||||
db.collection("photos").find({
|
||||
$where: '(this.lastUploadDate < this.updatedDate) && \
|
||||
(this.lastBuildDate >= this.updatedDate) && \
|
||||
this.published'
|
||||
}).toArray( function (err, docs) {
|
||||
if (err) console.log(err);
|
||||
photos = [];
|
||||
if (docs) {
|
||||
for (i=0; i<docs.length; i++) {
|
||||
photos.push(new Photo(docs[i]));
|
||||
}
|
||||
callback(null, photos);
|
||||
} else {
|
||||
callback("No photos require upload.", null);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Export the Photo object for external use.
|
||||
module.exports = Photo;
|
||||
|
|
229
post.js
229
post.js
|
@ -3,7 +3,7 @@ var _ = require("lodash");
|
|||
var fs = require('fs');
|
||||
var mkdirp = require('mkdirp');
|
||||
var jade = require('jade');
|
||||
var markdown = require( "markdown" ).markdown;
|
||||
var marked = require('marked');
|
||||
var path = require('path');
|
||||
var schemas = require('./schemas.js');
|
||||
var config = require("./config.js").config;
|
||||
|
@ -26,6 +26,10 @@ Post.prototype.set = function (name, value) {
|
|||
this.data[name] = value;
|
||||
}
|
||||
|
||||
Post.prototype.toString = function () {
|
||||
return 'Post: ' + this.get('title') + ' - ' + this.getShortDate();
|
||||
}
|
||||
|
||||
Post.prototype.sanitize = function (data) {
|
||||
data = data || {};
|
||||
schema = schemas.post;
|
||||
|
@ -45,6 +49,7 @@ Post.prototype.save = function (date, callback) {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Prototype Functions
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -96,7 +101,7 @@ Post.prototype.getShortDate = function () {
|
|||
// Arguments: None
|
||||
// Returns: Content as String
|
||||
Post.prototype.renderMarkdown = function () {
|
||||
return markdown.toHTML(this.get("markdown"));
|
||||
return marked(this.get("markdown"));
|
||||
}
|
||||
|
||||
// Function to get the relative url of a post, this sets the permalink structure
|
||||
|
@ -152,23 +157,43 @@ Post.prototype.makeSlug = function () {
|
|||
// Arguments: Callback function
|
||||
// Returns: err
|
||||
Post.prototype.build = function (callback) {
|
||||
console.log('Rendering ' + this);
|
||||
|
||||
year = moment(this.get("postDate")).format("YYYY");
|
||||
month = moment(this.get("postDate")).format("MM");
|
||||
|
||||
Post.buildYearIndex(year, function (err) {
|
||||
if (err) console.log(err);
|
||||
});
|
||||
Post.buildMonthIndex(year, month, function (err) {
|
||||
if (err) console.log(err);
|
||||
});
|
||||
Post.buildIndex();
|
||||
|
||||
var options = {
|
||||
pretty: true,
|
||||
post: this
|
||||
};
|
||||
|
||||
console.log('Rendering post: '+this.get("title"));
|
||||
var jadeOut = jade.renderFile('views/render-post.jade', options);
|
||||
|
||||
self = this;
|
||||
|
||||
mkdirp(self.getDirectory(), function (err) {
|
||||
fs.writeFile(self.getFilePath(), jadeOut, 'utf-8', function (err) {
|
||||
self.set('lastBuildDate', new Date());
|
||||
self.save(self.get('lastBuildDate'), function (err) {
|
||||
callback(err);
|
||||
if (!err) {
|
||||
fs.writeFile(self.getFilePath(), jadeOut, 'utf-8', function (err) {
|
||||
if (!err) {
|
||||
self.set('lastBuildDate', new Date());
|
||||
self.save(self.get('lastBuildDate'), function (err) {
|
||||
callback(err);
|
||||
});
|
||||
} else {
|
||||
callback(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
callback(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -190,7 +215,7 @@ Post.getLastBuildDate = function (callback) {
|
|||
};
|
||||
|
||||
// Function to find the most recent post upload date.
|
||||
// Returns a date object
|
||||
// Returns: err, date object
|
||||
Post.getLastUploadDate = function (callback) {
|
||||
db.collection("posts").findOne({}, {lastUploadDate: 1}, {sort: {lastUploadDate: -1}},
|
||||
function (err, doc) {
|
||||
|
@ -201,15 +226,17 @@ Post.getLastUploadDate = function (callback) {
|
|||
|
||||
|
||||
// Get a specific post by it's UUID
|
||||
// Returns post object
|
||||
// Returns: err, post object
|
||||
Post.getByUUID = function (uuid, callback) {
|
||||
db.collection("posts").findOne({uuid: uuid}, function(err, doc) {
|
||||
callback(err, new Post(doc));
|
||||
post = new Post(doc);
|
||||
console.log('Retrieved ' + post);
|
||||
callback(err, post);
|
||||
});
|
||||
}
|
||||
|
||||
// Function to get a count of current posts
|
||||
// Returns count of posts
|
||||
// Returns: err, count of posts
|
||||
Post.countPosts = function(callback) {
|
||||
db.collection("posts").find({}).count(function (err, count) {
|
||||
if (err) console.log(err);
|
||||
|
@ -219,7 +246,7 @@ Post.countPosts = function(callback) {
|
|||
|
||||
// Function to get a list of posts of a certain count and starting at an offset
|
||||
// Count and start are optional, when start is specified count must be specified.
|
||||
// Returns a list of post objects
|
||||
// Returns: err, list of post objects
|
||||
Post.getPosts = function(count, start, callback) {
|
||||
if (typeof callback === undefined) {
|
||||
if (typeof start === undefined) {
|
||||
|
@ -239,18 +266,22 @@ Post.getPosts = function(count, start, callback) {
|
|||
options.sort = [['postDate', 'desc'],['title', 'asc']];
|
||||
|
||||
db.collection("posts").find({},options).toArray( function(err, docs) {
|
||||
console.log(err);
|
||||
posts = [];
|
||||
for (i=0; i<docs.length; i++) {
|
||||
posts.push(new Post(docs[i]));
|
||||
if (!err) {
|
||||
posts = [];
|
||||
for (i=0; i<docs.length; i++) {
|
||||
posts.push(new Post(docs[i]));
|
||||
}
|
||||
callback(null, posts);
|
||||
} else {
|
||||
console.log(err);
|
||||
callback(err, null);
|
||||
}
|
||||
callback(null, posts);
|
||||
});
|
||||
}
|
||||
|
||||
// Function to find posts that need to be built
|
||||
// Inputs: Callback function
|
||||
// Returns: list of Post objects
|
||||
// Returns: err, list of Post objects
|
||||
Post.getNeedsBuild = function (callback) {
|
||||
db.collection("posts").find({
|
||||
$where: "(this.lastBuildDate < this.updatedDate) && this.published"
|
||||
|
@ -268,7 +299,7 @@ Post.getNeedsBuild = function (callback) {
|
|||
|
||||
// Function to find posts that need to be uploaded
|
||||
// Inputs: Callback function
|
||||
// Returns: List of Post objects
|
||||
// Returns: err, List of Post objects
|
||||
Post.getNeedsUpload = function (callback) {
|
||||
db.collection("posts").find({
|
||||
$where: '(this.lastUploadDate < this.updatedDate) && \
|
||||
|
@ -289,5 +320,163 @@ Post.getNeedsUpload = function (callback) {
|
|||
);
|
||||
}
|
||||
|
||||
// Function to build an index for a specific month
|
||||
// Inputs: Year, Month, callback
|
||||
// Returns: err
|
||||
Post.buildMonthIndex = function (year, month, callback) {
|
||||
console.log('Rendering month index: '+year+'/'+month);
|
||||
|
||||
var directory = config.buildDir
|
||||
directory += "/blog/";
|
||||
directory += year + '/' + month + '/';
|
||||
|
||||
console.log('Finding posts from '+year+'/'+month);
|
||||
mkdirp(directory, function (err) {
|
||||
if (!err) {
|
||||
db.collection('posts').find({
|
||||
$where: '(this.postDate >= new Date('+year+', '+month+'-1, 1, 0, 0, 0)) \
|
||||
&& (this.postDate <= new Date('+year+', '+month+', 0, 23, 59, 59)) \
|
||||
&& this.published'
|
||||
}, {sort: [['postDate', 'desc'],['title', 'asc']]}
|
||||
).toArray(function (err, docs) {
|
||||
if (!err) {
|
||||
console.log('Found '+docs.length+' posts from '+year+'/'+month);
|
||||
posts = []
|
||||
for (i=0; i<docs.length; i++) {
|
||||
posts.push(new Post(docs[i]));
|
||||
}
|
||||
|
||||
var jadeOut = jade.renderFile('views/render-post-index.jade', {
|
||||
pretty: true,
|
||||
posts: posts,
|
||||
pageTitle: 'Posts from '+year+'/'+month,
|
||||
title: 'Posts from '+year+'/'+month
|
||||
});
|
||||
|
||||
file = path.join(directory, 'index.html');
|
||||
|
||||
fs.writeFile(file, jadeOut, 'utf-8', function (err) {
|
||||
callback(err);
|
||||
});
|
||||
} else {
|
||||
callback(err)
|
||||
}
|
||||
});
|
||||
} else {
|
||||
callback(err);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// Function to build an index for a specific year
|
||||
// Inputs: Year, callback
|
||||
// Returns: err
|
||||
Post.buildYearIndex = function (year, callback) {
|
||||
console.log('Rendering year index: '+year);
|
||||
|
||||
var directory = config.buildDir
|
||||
directory += "/blog/";
|
||||
directory += year + '/';
|
||||
|
||||
console.log('Finding posts from '+year);
|
||||
|
||||
mkdirp(directory, function (err) {
|
||||
if (!err) {
|
||||
db.collection('posts').find({
|
||||
$where: '(this.postDate >= new Date('+year+', 0, 1, 0, 0, 0)) \
|
||||
&& (this.postDate <= new Date('+year+'+1, 0, 0, 23, 59, 59)) \
|
||||
&& this.published'
|
||||
}, {sort: [['postDate', 'desc'],['title', 'asc']]}
|
||||
).toArray(function (err, docs) {
|
||||
if (!err) {
|
||||
console.log('Found '+docs.length+' posts from '+year);
|
||||
posts = []
|
||||
for (i=0; i<docs.length; i++) {
|
||||
posts.push(new Post(docs[i]));
|
||||
}
|
||||
|
||||
var jadeOut = jade.renderFile('views/render-post-index.jade', {
|
||||
pretty: true,
|
||||
posts: posts,
|
||||
pageTitle: 'Posts from '+year,
|
||||
title: 'Posts from '+year
|
||||
});
|
||||
|
||||
file = path.join(directory, 'index.html');
|
||||
console.log(file);
|
||||
fs.writeFile(file, jadeOut, 'utf-8', function (err) {
|
||||
callback(err);
|
||||
});
|
||||
} else {
|
||||
callback(err)
|
||||
}
|
||||
});
|
||||
} else {
|
||||
callback(err);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// Function to build the main index
|
||||
// Inputs: none
|
||||
// Returns: none
|
||||
Post.buildIndex = function () {
|
||||
console.log("Building home index");
|
||||
Post.getPosts(null, null, function (err, posts) {
|
||||
pages = posts.length / 10;
|
||||
for ( p = 0; p < pages ; p++) {
|
||||
(function (p) {
|
||||
console.log("Building page "+p+" of index.");
|
||||
var start = p*10;
|
||||
var end = (p+1)*10-1;
|
||||
if ( p > 0 ) {
|
||||
var title = 'Page 2';
|
||||
var pageTitle = 'Page 2';
|
||||
}
|
||||
if ( p === 0 ) {
|
||||
var prev = -1;
|
||||
} else {
|
||||
var prev = p-1;
|
||||
}
|
||||
if ( p + 1 < pages ) {
|
||||
var next = p+2;
|
||||
} else {
|
||||
var next = false;
|
||||
}
|
||||
var jadeOut = jade.renderFile('views/render-post-index.jade', {
|
||||
pretty: true,
|
||||
title: title,
|
||||
pageTitle: pageTitle,
|
||||
next: next,
|
||||
prev: prev,
|
||||
posts: posts.slice(start, end)
|
||||
});
|
||||
|
||||
if (p === 0) {
|
||||
var directory = path.join(config.buildDir, 'blog');
|
||||
var file = path.join(directory, 'index.html');
|
||||
} else {
|
||||
var directory = path.join(config.buildDir, 'blog', (p+1).toString());
|
||||
var file = path.join(directory, 'index.html');
|
||||
}
|
||||
mkdirp(directory, function (err) {
|
||||
console.log('Made directory: '+directory);
|
||||
if (!err) {
|
||||
fs.writeFile(file, jadeOut, 'utf-8', function (err) {
|
||||
console.log('Wrote out: '+file);
|
||||
if (err) console.log(err);
|
||||
});
|
||||
} else {
|
||||
console.log('Failed to build '+file, err)
|
||||
}
|
||||
});
|
||||
})(p);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Export the Post object for external use.
|
||||
module.exports = Post;
|
||||
|
|
233
routes-photo.js
233
routes-photo.js
|
@ -1,10 +1,13 @@
|
|||
// Routes for photo administration.
|
||||
var config = require('./config.js').config;
|
||||
var multer = require('multer');
|
||||
var ExifImage = require('exif').ExifImage;
|
||||
var jade = require('jade');
|
||||
var upload = multer({ dest: config.uploadDir });
|
||||
var uuid = require('node-uuid');
|
||||
|
||||
module.exports = function(app) {
|
||||
// Photo management Routing
|
||||
|
||||
app.get('/admin/photo/list/:start?',
|
||||
function(req, res, next) {
|
||||
var count = 25;
|
||||
|
@ -13,156 +16,180 @@ module.exports = function(app) {
|
|||
} else {
|
||||
var start = 0;
|
||||
}
|
||||
database.listPhotos(count, start, function(photos){
|
||||
for (photo in photos) {
|
||||
var date = new Date(photos[photo].photoDate);
|
||||
photos[photo].dateString = date.getFullYear() + '-' +
|
||||
("0" + (date.getMonth()+1)).slice(-2) + '-' +
|
||||
("0" + date.getDate()).slice(-2);
|
||||
}
|
||||
res.render('admin-photo-list', {photos, user: req.user});
|
||||
|
||||
Photo.getPhotos(count, start, function(err, photos) {
|
||||
res.render('admin-photo-list', {
|
||||
successNotice: req.flash('successNotice'),
|
||||
failureNotice: req.flash('failureNotice'),
|
||||
photos,
|
||||
user: req.user
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
app.get('/admin/photo/view/:id?',
|
||||
app.get('/admin/photo/view/:uuid?',
|
||||
function (req, res, next) {
|
||||
if (req.params.id) {
|
||||
database.getPhotoById(req.params.id, function(row) {
|
||||
if (req.params.uuid) {
|
||||
Photo.getByUUID(req.params.uuid, function(err, photo) {
|
||||
var jadeOut = jade.renderFile('views/partial-photo.jade', {
|
||||
pretty: true,
|
||||
photo: photo
|
||||
});
|
||||
res.render('admin-photo-view', {
|
||||
successNotice: req.flash('successNotice'),
|
||||
failureNotice: req.flash('failureNotice'),
|
||||
photo: row,
|
||||
srcPath: '/'+row.path,
|
||||
photo,
|
||||
htmlSnippet: jadeOut,
|
||||
user: req.user
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
res.redirect('/admin/photo/list');
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
app.get('/admin/photo/new',
|
||||
function(req, res, next) {
|
||||
res.render('admin-photo-new', { user: req.user });
|
||||
}
|
||||
res.render('admin-photo-new', {
|
||||
successNotice: req.flash('successNotice'),
|
||||
failureNotice: req.flash('failureNotice'),
|
||||
user: req.user
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
app.post('/admin/photo/new',
|
||||
upload.single('photo'),
|
||||
function(req, res, next) {
|
||||
console.log(req.file);
|
||||
if ( req.body.title != "") {
|
||||
var title = req.body.title;
|
||||
var photo = new Photo({'uuid': uuid.v1()});
|
||||
if (req.body.title != '') {
|
||||
photo.set('title', req.body.title);
|
||||
} else {
|
||||
photo.set('title', req.file.originalname.split('.').slice(0,-1).join(' '));
|
||||
}
|
||||
else {
|
||||
var title = req.file.originalname.split('.').slice(0,-1).join(' ');
|
||||
}
|
||||
var extension = req.file.originalname.split('.').slice(-1);
|
||||
photo.set('extension', req.file.originalname.split('.').slice(-1));
|
||||
if (req.body.photoDate != "") {
|
||||
var photoDate = helper.dateToEpoch(new Date(req.body.photoDate));
|
||||
}
|
||||
else {
|
||||
var photoDate = helper.dateToEpoch(new Date());
|
||||
photo.set('photoDate', new Date(req.body.photoDate));
|
||||
} else {
|
||||
photo.set('photoDate', new Date());
|
||||
}
|
||||
if (req.body.slug != "") {
|
||||
var slug = req.body.slug;
|
||||
photo.set('slug', req.body.slug);
|
||||
} else {
|
||||
photo.set('slug', photo.makeSlug());
|
||||
}
|
||||
else if ( req.body.title != "" ){
|
||||
var slug = helper.makeSlug(title+'-'+photoDate);
|
||||
photo.set('mimetype', req.file.mimetype);
|
||||
photo.set('markdown', req.body.markdown);
|
||||
photo.set('createdDate', new Date());
|
||||
photo.set('masterPath', req.file.path);
|
||||
photo.tagPhoto(req.body.tags);
|
||||
if (req.body.published) {
|
||||
photo.set("published", true);
|
||||
} else {
|
||||
photo.set("published", false);
|
||||
}
|
||||
else {
|
||||
var cleanFileName = req.file.originalname.split('.').slice(0,-1).join('-');
|
||||
var slug = helper.makeSlug(cleanFileName+'-'+photoDate);
|
||||
}
|
||||
var mimetype = req.file.mimetype;
|
||||
var tags = helper.parseTags(req.body.tags);
|
||||
var markdown = req.body.markdown;
|
||||
var updatedDate = photoDate;
|
||||
var createDate = helper.dateToEpoch(new Date());
|
||||
var categoryName = req.body.category;
|
||||
var path = req.file.path;
|
||||
|
||||
database.createPhoto(title, slug, markdown, extension, mimetype, photoDate, updatedDate, createDate, path, function(err, row) {
|
||||
if (err) console.log(err);
|
||||
console.log(row);
|
||||
database.tagPhoto(row.id, tags);
|
||||
req.flash('successNotice', 'Photo created.');
|
||||
res.redirect('/admin/photo/view/'+row.id);
|
||||
ExifImage({image: photo.get('masterPath')}, function (err, exifData) {
|
||||
if (!err) {
|
||||
photo.set('exif', exifData.exif || {});
|
||||
photo.set('gps', exifData.gps || {});
|
||||
photo.save(null, function (err) {
|
||||
if (!err) {
|
||||
req.flash('successNotice', 'Photo created.');
|
||||
res.redirect('/admin/photo/view/'+photo.get('uuid'));
|
||||
} else {
|
||||
console.log(err);
|
||||
req.flash('failureNotice', 'Photo failed to be created');
|
||||
res.redirect(req.header('Referer') || '/admin');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.log(err);
|
||||
req.flash('failureNotice', 'Photo failed to be created');
|
||||
res.redirect(req.header('Referer') || '/admin');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
app.get('/admin/photo/edit/:id',
|
||||
app.get('/admin/photo/edit/:uuid',
|
||||
function(req, res, next) {
|
||||
var id = req.params.id;
|
||||
async.parallel({
|
||||
photoTags: function(callback) {
|
||||
database.getPhotoTagsAsString(id, function(tagString) {
|
||||
callback(null, tagString);
|
||||
})
|
||||
},
|
||||
photo: function(callback) {
|
||||
database.getPhotoById(id, function(photo) {
|
||||
callback(null, photo);
|
||||
})
|
||||
Photo.getByUUID(req.params.uuid, function (err, photo) {
|
||||
var tags = ""
|
||||
for (i=0; i<photo.get("tags").length; i++) {
|
||||
tags += photo.get("tags")[i].name + " ";
|
||||
}
|
||||
},
|
||||
function(err, results) {
|
||||
res.render('admin-photo-edit', {
|
||||
successNotice: req.flash('successNotice'),
|
||||
failureNotice: req.flash('failureNotice'),
|
||||
photo: results.photo,
|
||||
srcPath: '/'+results.photo.path,
|
||||
photoTags: results.photoTags,
|
||||
formattedDate: helper.epochToDateString(results.photo.photoDate),
|
||||
photo: photo,
|
||||
tags: tags,
|
||||
user: req.user
|
||||
});
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
app.post('/admin/photo/edit/:id',
|
||||
app.post('/admin/photo/edit/:uuid',
|
||||
function(req, res, next) {
|
||||
var id = req.params.id;
|
||||
var title = req.body.title;
|
||||
var slug = req.body.slug;
|
||||
var markdown = req.body.markdown;
|
||||
var photoDate = helper.dateToEpoch(new Date(req.body.photoDate));
|
||||
var tags = helper.parseTags(req.body.tags);
|
||||
console.log('Post '+id+' update request received');
|
||||
database.tagPhoto(id, tags);
|
||||
database.updatePhoto(id, title, slug, markdown, photoDate, function(err, row) {
|
||||
req.flash('successNotice', 'Photo updated.');
|
||||
res.redirect('/admin/photo/view/'+id);
|
||||
Photo.getByUUID(req.params.uuid, function (err, photo) {
|
||||
photo.set('title', req.body.title);
|
||||
if (req.body.slug != '') {
|
||||
photo.set('slug', req.body.slug);
|
||||
} else {
|
||||
photo.set('slug', photo.makeSlug());
|
||||
}
|
||||
photo.set('markdown', req.body.markdown);
|
||||
photo.set('photoDate', new Date(req.body.photoDate));
|
||||
photo.tagPhoto(req.body.tags);
|
||||
if (req.body.published) {
|
||||
photo.set("published", true);
|
||||
} else {
|
||||
photo.set("published", false);
|
||||
}
|
||||
console.log('Updating photo: '+photo.get('title'));
|
||||
photo.save(null, function (err) {
|
||||
if (!err) {
|
||||
console.log('Photo updated.');
|
||||
req.flash('successNotice', 'Photo updated.');
|
||||
res.redirect('/admin/photo/edit/'+photo.get('uuid'));
|
||||
} else {
|
||||
console.log(err);
|
||||
req.flash('failureNotice', 'Photo failed to update.');
|
||||
res.redirect('/admin/photo/edit/'+photo.get('uuid'));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
app.get('/admin/photo/regenerate/:id',
|
||||
app.get('/admin/photo/build/:uuid',
|
||||
function(req, res, next) {
|
||||
console.log('Generating resized images for: '+req.params.id);
|
||||
genStatic.generateStatic(function(err){ if (err) console.log(err) });
|
||||
genPhotos.generatePhotoSizesById(req.params.id, function(err) {
|
||||
if (!err) {
|
||||
genPhotos.generatePhotoPage(req.params.id, function(err) {
|
||||
if (req.params.uuid) {
|
||||
Static.updateBuildFolder(function (err) {
|
||||
if (err) console.log(err);
|
||||
});
|
||||
Photo.getByUUID(req.params.uuid, function (err, photo) {
|
||||
console.log('Building '+photo.get('title'));
|
||||
photo.build(function (err) {
|
||||
if (!err) {
|
||||
req.flash("successNotice", "Photo regenerated");
|
||||
res.redirect('/admin/photo/view/'+req.params.id);
|
||||
console.log(photo.get('title') + ' built.');
|
||||
req.flash("successNotice", 'Photo "'+photo.get('title')+'" built');
|
||||
res.redirect(req.header('Referer') || '/admin');
|
||||
}
|
||||
else {
|
||||
req.flash('failureNotice', 'Photo was unable to be resized.');
|
||||
res.redirect('/admin/photo/view/'+req.params.id);
|
||||
console.log(err);
|
||||
req.flash('failureNotice', 'Unable to build photo.');
|
||||
res.redirect(req.header('Referer') || '/admin');
|
||||
}
|
||||
})
|
||||
}
|
||||
else {
|
||||
req.flash('failureNotice', 'Photo was unable to be resized.');
|
||||
res.redirect('/admin/photo/view/'+req.params.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
res.redirect('/admin/photos/list');
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
var config = require('./config.js').config;
|
||||
var markdown = require( "markdown" ).markdown;
|
||||
var uuid = require('node-uuid');
|
||||
|
||||
// Post management routing
|
||||
|
||||
|
@ -34,7 +34,6 @@ module.exports = function(app) {
|
|||
successNotice: req.flash('successNotice'),
|
||||
failureNotice: req.flash('failureNotice'),
|
||||
post: post,
|
||||
content: markdown.toHTML(post.get("markdown")),
|
||||
user: req.user
|
||||
});
|
||||
});
|
||||
|
@ -57,7 +56,7 @@ module.exports = function(app) {
|
|||
// POST /admin/post/new
|
||||
app.post('/admin/post/new',
|
||||
function(req, res, next) {
|
||||
var post = new Post();
|
||||
var post = new Post({'uuid': uuid.v1()});
|
||||
post.set("title", req.body.title);
|
||||
if (req.body.slug != "") {
|
||||
post.set("slug", req.body.slug);
|
||||
|
@ -77,7 +76,6 @@ module.exports = function(app) {
|
|||
}
|
||||
Category.getByName(req.body.category, function (err, category) {
|
||||
post.set("category", category.get("uuid"));
|
||||
//console.log(post);
|
||||
post.save(null, function (err) {
|
||||
if (!err) {
|
||||
req.flash('successNotice', 'Post created.');
|
||||
|
@ -148,27 +146,31 @@ module.exports = function(app) {
|
|||
}
|
||||
);
|
||||
|
||||
// GET /admin/post/rebuild
|
||||
app.get('/admin/post/rebuild/:uuid?',
|
||||
// GET /admin/post/build
|
||||
app.get('/admin/post/build/:uuid?',
|
||||
function(req, res, next) {
|
||||
if (req.params.uuid) {
|
||||
Static.updateBuildFolder(function (err) {
|
||||
if (err) console.log(err);
|
||||
});
|
||||
post = Post.getByUUID(req.params.uuid, function (err, post) {
|
||||
console.log("Got post: "+post.get("title"));
|
||||
if (err) console.log(err);
|
||||
post.build(function (err) {
|
||||
if (!err) {
|
||||
req.flash('successNotice', 'Post rebuilt successfully.');
|
||||
res.redirect(req.header('Referer') || '/admin');
|
||||
}
|
||||
else {
|
||||
console.log(err);
|
||||
req.flash('failureNotice', 'Post regeneration failed, check logs.');
|
||||
res.redirect(req.header('Referer') || '/admin');
|
||||
}
|
||||
});
|
||||
if (!err && post) {
|
||||
post.build(function (err) {
|
||||
if (!err) {
|
||||
req.flash('successNotice', 'Post rebuilt successfully.');
|
||||
res.redirect(req.header('Referer') || '/admin');
|
||||
}
|
||||
else {
|
||||
console.log(err);
|
||||
req.flash('failureNotice', 'Post regeneration failed, check logs.');
|
||||
res.redirect(req.header('Referer') || '/admin');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.log(err);
|
||||
req.flash('failureNotice', 'Post regeneration failed, check logs.');
|
||||
res.redirect(req.header('Referer') || '/admin');
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
var config = require('./config.js').config;
|
||||
|
||||
var fs = require('fs');
|
||||
|
||||
module.exports = function (app) {
|
||||
|
||||
|
@ -9,27 +9,29 @@ module.exports = function (app) {
|
|||
function(req, res, next) {
|
||||
if (req.params[0] != '') {
|
||||
var path = __dirname + '/' + config.buildDir + '/blog/' + req.params[0];
|
||||
console.log('Trying to serve: ' + path);
|
||||
fs.exists(path, function(exists) {
|
||||
if (exists) {
|
||||
console.log(path + ' exists serving...');
|
||||
res.sendFile(path);
|
||||
}
|
||||
else {
|
||||
console.log(path + ' does not exist...');
|
||||
if (path.slice(-1) != '/') path += '/';
|
||||
path += 'index.html'
|
||||
console.log('Trying to serve: ' + path);
|
||||
fs.exists(path, function(exists) {
|
||||
if (exists) {
|
||||
console.log(path + ' exists serving...');
|
||||
res.sendFile(path);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
var path = __dirname + '/' + config.buildDir + '/blog/';
|
||||
}
|
||||
}
|
||||
console.log('Trying to serve: ' + path);
|
||||
fs.exists(path, function(exists) {
|
||||
if (exists) {
|
||||
console.log(path + ' exists serving...');
|
||||
res.sendFile(path);
|
||||
}
|
||||
else {
|
||||
console.log(path + ' does not exist...');
|
||||
if (path.slice(-1) != '/') path += '/';
|
||||
path += 'index.html'
|
||||
console.log('Trying to serve: ' + path);
|
||||
fs.exists(path, function(exists) {
|
||||
if (exists) {
|
||||
console.log(path + ' exists serving...');
|
||||
res.sendFile(path);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
app.get('/photos/*',
|
||||
|
|
2
run.sh
2
run.sh
|
@ -2,5 +2,5 @@
|
|||
|
||||
supervisor \
|
||||
-e 'jade|js' \
|
||||
-i './generated' \
|
||||
-i './build' \
|
||||
node app.js
|
||||
|
|
10
schemas.js
10
schemas.js
|
@ -36,15 +36,19 @@ schemas = {
|
|||
title: null,
|
||||
slug: null,
|
||||
markdown: null,
|
||||
masterPath: null,
|
||||
extension: null,
|
||||
mimetype: null,
|
||||
createdDate: new Date(),
|
||||
photoDate: new Date(),
|
||||
updatedDate: new Date(),
|
||||
deleted: false,
|
||||
published: false,
|
||||
category: null,
|
||||
aspect: null,
|
||||
tags: [],
|
||||
metadata: {},
|
||||
lastGenerateDate: new Date("Mon Jan 1 1900 00:00:00 GMT-0500"),
|
||||
gps: {},
|
||||
exif: {},
|
||||
lastBuildDate: new Date("Mon Jan 1 1900 00:00:00 GMT-0500"),
|
||||
lastUploadDate: new Date("Mon Jan 1 1900 00:00:00 GMT-0500")
|
||||
}
|
||||
}
|
||||
|
|
21
static.js
21
static.js
|
@ -19,18 +19,15 @@ Post.prototype.set = function (name, value) {
|
|||
}
|
||||
|
||||
Static.updateBuildFolder = function (callback) {
|
||||
console.log("Removing "+config.staticDest);
|
||||
fs.unlink(config.staticDest, function(err) {
|
||||
console.log(config.staticDest+' deleted.');
|
||||
ncp(config.staticSource, config.staticDest, function(err) {
|
||||
if (!err) {
|
||||
console.log(config.staticSource+' copied to '+config.staticDest);
|
||||
callback(null);
|
||||
}
|
||||
else {
|
||||
callback(err);
|
||||
}
|
||||
});
|
||||
console.log("Copying "+config.staticDest);
|
||||
ncp(config.staticSource, config.staticDest, function(err) {
|
||||
if (!err) {
|
||||
console.log(config.staticSource+' copied to '+config.staticDest);
|
||||
callback(null);
|
||||
}
|
||||
else {
|
||||
callback(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -13,18 +13,18 @@ block content
|
|||
div(class="col-md-6")
|
||||
div(class="panel panel-success")
|
||||
div(class="panel-heading")
|
||||
h3(class="panel-title") Last Upload (UTC)
|
||||
h3(class="panel-title") Pending Uploads
|
||||
|
||||
div(class="panel-body")
|
||||
h3 #{uploadDate}
|
||||
h3 #{uploadCount}
|
||||
|
||||
div(class="col-md-6")
|
||||
div(class="panel panel-danger")
|
||||
div(class="panel-heading")
|
||||
h3(class="panel-title") Last Rebuild (UTC)
|
||||
h3(class="panel-title") Pending Builds
|
||||
|
||||
div(class="panel-body")
|
||||
h3 #{rebuildDate}
|
||||
h3 #{buildCount}
|
||||
|
||||
div(class="row")
|
||||
div(class="col-md-4")
|
||||
|
|
|
@ -11,23 +11,28 @@ block content
|
|||
|
||||
div(class='page-header row')
|
||||
div(class="col-sm-6 col-sm-offset-3")
|
||||
img(class="img-responsive", src='#{srcPath}')
|
||||
img(class="img-responsive", src="/#{photo.get('masterPath')}")
|
||||
|
||||
form(method="post", action="/admin/photo/edit/#{photo.id}")
|
||||
form(method="post", action="/admin/photo/edit/#{photo.get('uuid')}")
|
||||
div(class="row page-header")
|
||||
div(class="input-group input-group-lg col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
input(class="form-control", type="text", name="title", placeholder="Enter title", value="#{photo.title}")
|
||||
input(class="form-control", type="text", name="title", placeholder="Enter title", value="#{photo.get('title')}")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
input(class="form-control", type="text", name="slug", placeholder="Enter slug (optional)", value="#{photo.slug}")
|
||||
input(class="form-control", type="text", name="slug", placeholder="Enter slug (optional)", value="#{photo.get('slug')}")
|
||||
div(class="row page-header")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
input(type="text", class="form-control", placeholder="Publish Date", name="photoDate", value="#{formattedDate}")
|
||||
input(type="text", class="form-control", placeholder="Publish Date", name="photoDate", value="#{photo.get('photoDate')}")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
input(type="text", class="form-control", placeholder="Tags", name="tags" value="#{photoTags}")
|
||||
input(type="text", class="form-control", placeholder="Tags", name="tags" value="#{tags}")
|
||||
div(class="row page-header")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
span(class="input-group-addon")
|
||||
input(type="checkbox", name="published", checked=(photo.get('published')))
|
||||
input(type="text", class="form-control" placeholder="Published")
|
||||
div(class="row page-header")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
textarea(class="form-control", rows="12", name="markdown", placeholder="Markdown formatted description")
|
||||
| #{photo.description}
|
||||
| #{photo.get('markdown')}
|
||||
div(class="row")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
div(class="pull-left")
|
||||
|
|
|
@ -12,14 +12,14 @@ block content
|
|||
table(class="table table-striped")
|
||||
each photo in photos
|
||||
tr
|
||||
td #{photo.id}
|
||||
td: a(href="/admin/photo/view/#{photo.id}") #{photo.title}
|
||||
td #{photo.dateString}
|
||||
td: a(href="/admin/photo/view/#{photo.get('uuid')}") #{photo.get('title')}
|
||||
td #{photo.getShortDate()}
|
||||
td #{photo.get('uuid')}
|
||||
td
|
||||
a(href="/admin/photo/edit/#{photo.id}") Edit
|
||||
| -
|
||||
a(href="/admin/photo/delete/#{photo.id}") Delete
|
||||
| -
|
||||
a(href="/admin/photo/rebuild/#{photo.id}") Rebuild
|
||||
| -
|
||||
a(href="/admin/photo/publish/#{photo.id}") Publish
|
||||
a(href="/admin/photo/edit/#{photo.get('uuid')}") Edit
|
||||
| -
|
||||
a(href="/admin/photo/delete/#{photo.get('uuid')}") Delete
|
||||
| -
|
||||
a(href="/admin/photo/build/#{photo.get('uuid')}") Build
|
||||
| -
|
||||
a(href="/admin/photo/upload/#{photo.get('uuid')}") Upload
|
||||
|
|
|
@ -3,7 +3,7 @@ extends admin-layout
|
|||
block content
|
||||
div(class="row")
|
||||
include ./admin-sidebar.jade
|
||||
|
||||
|
||||
div(class="col-sm-10 col-sm-offset-2 main")
|
||||
h1(class="page-header") New Photo
|
||||
|
||||
|
@ -22,6 +22,11 @@ block content
|
|||
input(type="text", class="form-control", placeholder="Publish Date", name="photoDate")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
input(type="text", class="form-control", placeholder="Tags", name="tags")
|
||||
div(class="row page-header")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
span(class="input-group-addon")
|
||||
input(type="checkbox", name="published", checked, value='true')
|
||||
input(type="text", class="form-control" placeholder="Published")
|
||||
div(class="row page-header")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
textarea(class="form-control", rows="12", name="markdown", placeholder="Markdown formatted description")
|
||||
|
|
|
@ -3,16 +3,28 @@ extends admin-layout
|
|||
block content
|
||||
div(class="row")
|
||||
include ./admin-sidebar.jade
|
||||
|
||||
|
||||
div(class="col-sm-10 col-sm-offset-2 main")
|
||||
|
||||
include ./admin-messages.jade
|
||||
|
||||
div(class='page-header row')
|
||||
div(class="col-sm-6 col-sm-offset-3")
|
||||
img(class="img-responsive", src='#{srcPath}')
|
||||
|
||||
div
|
||||
h3 #{photo.title}
|
||||
p #{photo.date}
|
||||
p #{photo.description}
|
||||
div(class="col-sm-10 col-sm-offset-1")
|
||||
img(class="img-responsive", src="/#{photo.get('masterPath')}")
|
||||
|
||||
div(class='row')
|
||||
h3 #{photo.get('title')}
|
||||
|
||||
div(class='row')
|
||||
| #{photo.getShortDate()} --
|
||||
a(href="/admin/photo/edit/#{photo.get('uuid')}") Edit
|
||||
| -
|
||||
a(href="/admin/photo/build/#{photo.get('uuid')}") Build
|
||||
|
||||
div(class='row')
|
||||
p #{photo.get('markdown')}
|
||||
|
||||
div(class="row")
|
||||
h4 Snippet for Use in Posts
|
||||
div #{htmlSnippet}
|
||||
|
||||
|
|
|
@ -17,12 +17,12 @@ block content
|
|||
td #{post.getShortDate()}
|
||||
td #{post.get("uuid")}
|
||||
td
|
||||
a(href="/admin/post/edit/#{post.get('uuid')}") Edit
|
||||
| -
|
||||
a(href="/admin/post/delete/#{post.get('uuid')}") Delete
|
||||
| -
|
||||
a(href="/admin/post/rebuild/#{post.get('uuid')}") Rebuild
|
||||
| -
|
||||
a(href="/admin/post/upload/#{post.get('uuid')}") Upload
|
||||
a(href="/admin/post/edit/#{post.get('uuid')}") Edit
|
||||
| -
|
||||
a(href="/admin/post/delete/#{post.get('uuid')}") Delete
|
||||
| -
|
||||
a(href="/admin/post/build/#{post.get('uuid')}") Build
|
||||
| -
|
||||
a(href="/admin/post/upload/#{post.get('uuid')}") Upload
|
||||
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ block content
|
|||
div(class="row page-header")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
span(class="input-group-addon")
|
||||
input(type="checkbox", name="published", checked=false, value='true')
|
||||
input(type="checkbox", name="published", checked, value='true')
|
||||
input(type="text", class="form-control" placeholder="Published")
|
||||
div(class="row page-header")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
|
|
|
@ -12,9 +12,9 @@ block content
|
|||
h3 #{post.get('title')}
|
||||
|
||||
div(class='row')
|
||||
| #{post.getShortDate()} --
|
||||
| #{post.getShortDate()} --
|
||||
a(href="/admin/post/edit/#{post.get('uuid')}") Edit
|
||||
| -
|
||||
a(href="/admin/post/rebuild/#{post.get('uuid')}") Rebuild
|
||||
| -
|
||||
a(href="/admin/post/build/#{post.get('uuid')}") Build
|
||||
|
||||
div(class='row') !{content}
|
||||
div(class='row') !{post.renderMarkdown()}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
div(class="col-sm-2 sidebar")
|
||||
ul(class="nav nav-sidebar")
|
||||
li: a #{user.get("username")}
|
||||
li: a(href="/admin/") Dashboard
|
||||
li: a(href='/admin/view/uploads') Pending Uploads
|
||||
li: a(href='/admin/view/builds') Pending Builds
|
||||
|
@ -18,11 +17,11 @@ div(class="col-sm-2 sidebar")
|
|||
li: a(href="/admin/gallery/list") All Galleries
|
||||
|
||||
ul(class="nav nav-sidebar")
|
||||
form(action="/admin/rebuild/", method="get")
|
||||
form(action="/admin/build/", method="get")
|
||||
button(class="btn btn-lg btn-success")
|
||||
span(class="glyphicon glyphicon-repeat") Build
|
||||
|
||||
ul(class="nav nav-sidebar")
|
||||
form(action="/admin/publish/", method="get")
|
||||
form(action="/admin/upload/", method="get")
|
||||
button(class="btn btn-lg btn-warning")
|
||||
span(class="glyphicon glyphicon-upload") Upload
|
||||
|
|
|
@ -9,7 +9,7 @@ block content
|
|||
|
||||
include ./admin-messages.jade
|
||||
|
||||
if Posts
|
||||
if posts.length > 0
|
||||
h2 Posts
|
||||
table(class="table table-striped")
|
||||
each post in posts
|
||||
|
@ -18,6 +18,19 @@ block content
|
|||
td #{post.getShortDate()}
|
||||
td #{post.get("uuid")}
|
||||
td
|
||||
a(href="/admin/post/edit/#{post.get('uuid')}") Edit
|
||||
| -
|
||||
a(href="/admin/post/rebuild/#{post.get('uuid')}") Rebuild
|
||||
a(href="/admin/post/edit/#{post.get('uuid')}") Edit
|
||||
| -
|
||||
a(href="/admin/post/build/#{post.get('uuid')}") Build
|
||||
|
||||
if photos.length > 0
|
||||
h2 Photos
|
||||
table(class="table table-striped")
|
||||
each photo in photos
|
||||
tr
|
||||
td: a(href="/admin/photo/view/#{photo.get('uuid')}") #{photo.get("title")}
|
||||
td #{photo.getShortDate()}
|
||||
td #{photo.get("uuid")}
|
||||
td
|
||||
a(href="/admin/photo/edit/#{photo.get('uuid')}") Edit
|
||||
| -
|
||||
a(href="/admin/photo/build/#{photo.get('uuid')}") Build
|
||||
|
|
|
@ -9,7 +9,7 @@ block content
|
|||
|
||||
include ./admin-messages.jade
|
||||
|
||||
if posts
|
||||
if posts.length > 0
|
||||
h2 Posts
|
||||
table(class="table table-striped")
|
||||
each post in posts
|
||||
|
@ -18,4 +18,15 @@ block content
|
|||
td #{post.getShortDate()}
|
||||
td #{post.get("uuid")}
|
||||
td
|
||||
a(href="/admin/post/edit/#{post.get('uuid')}") Edit
|
||||
a(href="/admin/post/edit/#{post.get('uuid')}") Edit
|
||||
|
||||
if photos.length > 0
|
||||
h2 Photos
|
||||
table(class="table table-striped")
|
||||
each photo in photos
|
||||
tr
|
||||
td: a(href="/admin/photo/view/#{photo.get('uuid')}") #{photo.get('title')}
|
||||
td #{photo.getShortDate()}
|
||||
td #{photo.get('uuid')}
|
||||
td
|
||||
a(href="/admin/photo/edit/#{photo.get('uuid')}") Edit
|
||||
|
|
3
views/partial-photo.jade
Normal file
3
views/partial-photo.jade
Normal file
|
@ -0,0 +1,3 @@
|
|||
img(slug="#{photo.getURL()}", size='post',
|
||||
src="/static/images/loading.gif", ext="#{photo.get('extension')}", load='lazy',
|
||||
onload='changeImg(this);').img-responsive
|
5
views/partial-post.jade
Normal file
5
views/partial-post.jade
Normal file
|
@ -0,0 +1,5 @@
|
|||
article
|
||||
header
|
||||
h3: a(href="#{post.getURL()}") #{post.get("title")}
|
||||
p #{post.getShortDate()}
|
||||
| !{post.renderMarkdown()}
|
|
@ -1 +1,2 @@
|
|||
script(type="text/javascript", src="/static/scripts/crunch.js")
|
||||
script(src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js")
|
||||
script(src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js" integrity="sha256-Sk3nkD6mLTMOF0EOpNtsIry+s1CsaqQC1rVLTAy+0yc= sha512-K1qjQ+NcF2TYO/eI3M6v8EiNYZfA95pQumfvcVrTHtwQVDG+aHRqLi/ETn2uB+1JqwYqVG3LIvdm9lj6imS/pQ==" crossorigin="anonymous")
|
||||
|
|
|
@ -1,23 +1,28 @@
|
|||
doctype html
|
||||
html
|
||||
head
|
||||
title #{title}
|
||||
meta(charset="utf-8")
|
||||
meta(http-equiv="X-UA-Compatible", content="IE=edge")
|
||||
meta(name="viewport", content="width=device-width, initial-scale=1")
|
||||
link(href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css", rel="stylesheet" integrity="sha256-MfvZlkHCEqatNoGiOXveE8FIwMzZg4W85qfrfIFBfYc= sha512-dTfge/zgoMYpP7QbHy4gWMEGsbsdZeCXz7irItjcC3sPUFtf0kuFbDz/ixG7ArTxmDjLXDmezHubeNikyKGVyQ==" crossorigin="anonymous")
|
||||
link(rel='stylesheet', href='/static/stylesheets/style.css')
|
||||
block head-addition
|
||||
body(role="document")
|
||||
div(role="main").container-fluid
|
||||
div.col-sm-3
|
||||
div.title-block
|
||||
img(src="/static/images/logo.png").img-responsive
|
||||
div.col-sm-8.col-sm-offset-4
|
||||
block content
|
||||
div.col-sm-3.title-block-nav
|
||||
ul.nav.nav-pills.nav-justified
|
||||
li: a(href="/") Home
|
||||
li: a(href="/blog") Blog
|
||||
li: a(href="/photos") Photos
|
||||
head
|
||||
title #{title}
|
||||
meta(charset="utf-8")
|
||||
meta(http-equiv="X-UA-Compatible", content="IE=edge")
|
||||
meta(name="viewport", content="width=device-width, initial-scale=1")
|
||||
link(href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/simplex/bootstrap.min.css", rel="stylesheet", integrity="sha256-rgHoMgF45/9e2kvxfvR0KarwQNw5CRqgxbrthGpeUuc= sha512-CGGV53FSdrXrjyGCNk04p+xuna3CbE33n773A0EEmqtcN8W3NaFsR0vSQcbll5dpSS90d3i2Zh3jFX/j46hzJA==", crossorigin="anonymous")
|
||||
link(rel='stylesheet', href='/static/stylesheets/style.css')
|
||||
script(type="text/javascript", src="/static/scripts/crunch.js")
|
||||
block head-addition
|
||||
body(role="document")
|
||||
div(class="container-fluid", role="main", style="padding-bottom: 20px;")
|
||||
div.row
|
||||
div(class="col-sm-3 sidebar")
|
||||
div.row.visible-xs-block.col-xs-6.col-xs-offset-3
|
||||
img(src="/static/images/logo.png").img-responsive
|
||||
img(src="/static/images/logo.png").img-responsive.center-block.hidden-xs
|
||||
div.hidden-xs
|
||||
include ./render-sidebar.jade
|
||||
|
||||
div(class="col-sm-7 col-sm-offset-1 col-xs-12 main")
|
||||
block content
|
||||
|
||||
div(style="text-align:center;").visible-xs-block.col-xs-12
|
||||
include ./render-sidebar.jade
|
||||
|
||||
include ./render-footer.jade
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
extends render-layout
|
||||
|
||||
block head-addition
|
||||
script(type="text/javascript", src="/static/scripts/crunch.js")
|
||||
|
||||
block content
|
||||
div: img(slug='#{slug}', size='md',
|
||||
src="/static/images/loading.gif", ext='#{extension}', load='lazy',
|
||||
onload='changeImg(this);')
|
||||
|
||||
h3: a(href="#{url}") #{title}
|
||||
div !{content}
|
||||
article
|
||||
header
|
||||
div(style="padding-top: 30px;")
|
||||
include ./partial-photo.jade
|
||||
h3: a(href="#{photo.getURL()}") #{photo.get('title')}
|
||||
!{photo.renderMarkdown()}
|
||||
|
||||
|
|
19
views/render-post-index.jade
Normal file
19
views/render-post-index.jade
Normal file
|
@ -0,0 +1,19 @@
|
|||
extends render-layout
|
||||
|
||||
block content
|
||||
h1 #{pageTitle}
|
||||
|
||||
each post in posts
|
||||
include ./partial-post.jade
|
||||
|
||||
div
|
||||
if prev == 0
|
||||
a(href="/blog/") Newer
|
||||
if prev > 0
|
||||
a(href="/blog/#{prev}/") Newer
|
||||
|
||||
if prev >= 0 && next > 0
|
||||
| —
|
||||
|
||||
if next > 0
|
||||
a(href="/blog/#{next}/") Older
|
|
@ -1,6 +1,5 @@
|
|||
extends render-layout
|
||||
|
||||
block content
|
||||
h3: a(href="#{post.getURL()}") #{post.get("title")}
|
||||
p #{post.getShortDate()}
|
||||
div #{post.renderMarkdown()}
|
||||
include ./partial-post.jade
|
||||
|
||||
|
|
3
views/render-sidebar.jade
Normal file
3
views/render-sidebar.jade
Normal file
|
@ -0,0 +1,3 @@
|
|||
ul.nav.nav-sidebar
|
||||
li: a(href="/blog/") Blog
|
||||
li: a(href='/photos/') Photos
|
Loading…
Reference in a new issue