Merge pull request #359 from terakilobyte/staging

Site speed
This commit is contained in:
Nathan
2015-04-24 19:02:16 -04:00
8 changed files with 277 additions and 190 deletions

18
app.js
View File

@ -253,12 +253,8 @@ app.use(express.static(__dirname + '/public', { maxAge: 86400000 }));
app.get('/', homeController.index); app.get('/', homeController.index);
app.get('/privacy', function(req, res) {
res.redirect(301, "/field-guide/free-code-camp's-privacy-policy");
});
app.get('/nonprofit-project-instructions', function(req, res) { app.get('/nonprofit-project-instructions', function(req, res) {
res.redirect(301, "/field-guide/free-code-camp's-privacy-policy"); res.redirect(301, '/field-guide/nonprofit-project-instructions');
}); });
app.get('/chat', resourcesController.chat); app.get('/chat', resourcesController.chat);
@ -384,17 +380,17 @@ app.post(
passportConf.isAuthenticated, passportConf.isAuthenticated,
contactController.postDoneWithFirst100Hours contactController.postDoneWithFirst100Hours
); );
//app.get(
// '/nonprofit-project-instructions',
// passportConf.isAuthenticated,
// resourcesController.nonprofitProjectInstructions
//);
app.post( app.post(
'/update-progress', '/update-progress',
passportConf.isAuthenticated, passportConf.isAuthenticated,
userController.updateProgress userController.updateProgress
); );
app.get('/privacy', function(req, res) {
res.redirect(301, '/field-guide/the-free-code-camp-privacy-policy');
});
app.get('/api/slack', function(req, res) { app.get('/api/slack', function(req, res) {
if (req.user) { if (req.user) {
if (req.user.email) { if (req.user.email) {
@ -590,7 +586,7 @@ app.post('/completed-bonfire/', bonfireController.completedBonfire);
app.get('/field-guide/:fieldGuideName', fieldGuideController.returnIndividualFieldGuide); app.get('/field-guide/:fieldGuideName', fieldGuideController.returnIndividualFieldGuide);
app.get('/field-guide', fieldGuideController.returnNextFieldGuide); app.get('/field-guide/', fieldGuideController.returnNextFieldGuide);
app.post('/completed-field-guide/', fieldGuideController.completedFieldGuide); app.post('/completed-field-guide/', fieldGuideController.completedFieldGuide);

View File

@ -63,12 +63,12 @@ exports.returnNextBonfire = function(req, res, next) {
var uncompletedBonfires = req.user.uncompletedBonfires; var uncompletedBonfires = req.user.uncompletedBonfires;
var displayedBonfires = Bonfire.find({'_id': uncompletedBonfires[0]}); var displayedBonfires = Bonfire.find({'_id': uncompletedBonfires[0]});
displayedBonfires.exec(function(err, bonfire) { displayedBonfires.exec(function(err, bonfireFromMongo) {
if (err) { if (err) {
return next(err); return next(err);
} }
bonfire = bonfire.pop(); var bonfire = bonfireFromMongo.pop();
if (bonfire === undefined) { if (typeof bonfire === 'undefined') {
req.flash('errors', { req.flash('errors', {
msg: "It looks like you've completed all the bonfires we have available. Good job!" msg: "It looks like you've completed all the bonfires we have available. Good job!"
}); });
@ -84,13 +84,13 @@ exports.returnIndividualBonfire = function(req, res, next) {
var bonfireName = dashedName.replace(/\-/g, ' '); var bonfireName = dashedName.replace(/\-/g, ' ');
Bonfire.find({'name': new RegExp(bonfireName, 'i')}, function(err, bonfire) { Bonfire.find({'name': new RegExp(bonfireName, 'i')}, function(err, bonfireFromMongo) {
if (err) { if (err) {
next(err); next(err);
} }
if (bonfire.length < 1) { if (bonfireFromMongo.length < 1) {
req.flash('errors', { req.flash('errors', {
msg: "404: We couldn't find a bonfire with that name. Please double check the name." msg: "404: We couldn't find a bonfire with that name. Please double check the name."
}); });
@ -98,9 +98,9 @@ exports.returnIndividualBonfire = function(req, res, next) {
return res.redirect('/bonfires'); return res.redirect('/bonfires');
} }
bonfire = bonfire.pop(); var bonfire = bonfireFromMongo.pop();
var dashedNameFull = bonfire.name.toLowerCase().replace(/\s/g, '-'); var dashedNameFull = bonfire.name.toLowerCase().replace(/\s/g, '-');
if (dashedNameFull != dashedName) { if (dashedNameFull !== dashedName) {
return res.redirect('../bonfires/' + dashedNameFull); return res.redirect('../bonfires/' + dashedNameFull);
} }
res.render('bonfire/show', { res.render('bonfire/show', {

View File

@ -50,14 +50,14 @@ exports.returnNextCourseware = function(req, res, next) {
} }
courseware = courseware.pop(); courseware = courseware.pop();
if (courseware === undefined) { if (typeof courseware === 'undefined') {
req.flash('errors', { req.flash('errors', {
msg: "It looks like you've completed all the courses we have " + msg: "It looks like you've completed all the courses we have " +
"available. Good job!" "available. Good job!"
}); });
return res.redirect('../challenges/learn-how-free-code-camp-works'); return res.redirect('../challenges/learn-how-free-code-camp-works');
} }
nameString = courseware.name.toLowerCase().replace(/\s/g, '-'); var nameString = courseware.name.toLowerCase().replace(/\s/g, '-');
return res.redirect('../challenges/' + nameString); return res.redirect('../challenges/' + nameString);
}); });
}; };
@ -68,23 +68,23 @@ exports.returnIndividualCourseware = function(req, res, next) {
var coursewareName = dashedName.replace(/\-/g, ' '); var coursewareName = dashedName.replace(/\-/g, ' ');
Courseware.find({'name': new RegExp(coursewareName, 'i')}, Courseware.find({'name': new RegExp(coursewareName, 'i')},
function(err, courseware) { function(err, coursewareFromMongo) {
if (err) { if (err) {
next(err); next(err);
} }
// Handle not found // Handle not found
if (courseware.length < 1) { if (coursewareFromMongo.length < 1) {
req.flash('errors', { req.flash('errors', {
msg: "404: We couldn't find a challenge with that name. " + msg: "404: We couldn't find a challenge with that name. " +
"Please double check the name." "Please double check the name."
}); });
return res.redirect('/challenges'); return res.redirect('/challenges');
} }
courseware = courseware.pop(); var courseware = coursewareFromMongo.pop();
// Redirect to full name if the user only entered a partial // Redirect to full name if the user only entered a partial
var dashedNameFull = courseware.name.toLowerCase().replace(/\s/g, '-'); var dashedNameFull = courseware.name.toLowerCase().replace(/\s/g, '-');
if (dashedNameFull != dashedName) { if (dashedNameFull !== dashedName) {
return res.redirect('../challenges/' + dashedNameFull); return res.redirect('../challenges/' + dashedNameFull);
} }
@ -292,7 +292,7 @@ exports.completedZiplineOrBasejump = function (req, res, next) {
if (isCompletedWith) { if (isCompletedWith) {
var paired = User.find({'profile.username': isCompletedWith.toLowerCase()}).limit(1); var paired = User.find({'profile.username': isCompletedWith.toLowerCase()}).limit(1);
paired.exec(function (err, pairedWith) { paired.exec(function (err, pairedWithFromMongo) {
if (err) { if (err) {
return next(err); return next(err);
} else { } else {
@ -301,7 +301,7 @@ exports.completedZiplineOrBasejump = function (req, res, next) {
req.user.progressTimestamps.push(Date.now() || 0); req.user.progressTimestamps.push(Date.now() || 0);
req.user.uncompletedCoursewares.splice(index, 1); req.user.uncompletedCoursewares.splice(index, 1);
} }
pairedWith = pairedWith.pop(); var pairedWith = pairedWithFromMongo.pop();
req.user.completedCoursewares.push({ req.user.completedCoursewares.push({
_id: coursewareHash, _id: coursewareHash,

View File

@ -9,12 +9,12 @@ exports.returnIndividualFieldGuide = function(req, res, next) {
var fieldGuideName = dashedName.replace(/\-/g, ' '); var fieldGuideName = dashedName.replace(/\-/g, ' ');
FieldGuide.find({'name': new RegExp(fieldGuideName, 'i')}, function(err, fieldGuide) { FieldGuide.find({'name': new RegExp(fieldGuideName, 'i')}, function(err, fieldGuideFromMongo) {
if (err) { if (err) {
next(err); next(err);
} }
if (fieldGuide.length < 1) { if (fieldGuideFromMongo.length < 1) {
req.flash('errors', { req.flash('errors', {
msg: "404: We couldn't find a field guide entry with that name. Please double check the name." msg: "404: We couldn't find a field guide entry with that name. Please double check the name."
}); });
@ -22,9 +22,9 @@ exports.returnIndividualFieldGuide = function(req, res, next) {
return res.redirect('/field-guide'); return res.redirect('/field-guide');
} }
fieldGuide = fieldGuide.pop(); var fieldGuide = fieldGuideFromMongo.pop();
var dashedNameFull = fieldGuide.name.toLowerCase().replace(/\s/g, '-').replace(/\?/g, ''); var dashedNameFull = fieldGuide.name.toLowerCase().replace(/\s/g, '-').replace(/\?/g, '');
if (dashedNameFull != dashedName) { if (dashedNameFull !== dashedName) {
return res.redirect('../field-guide/' + dashedNameFull); return res.redirect('../field-guide/' + dashedNameFull);
} }
res.render('field-guide/show', { res.render('field-guide/show', {
@ -42,7 +42,7 @@ exports.showAllFieldGuides = function(req, res) {
if (req.user && req.user.completedFieldGuides) { if (req.user && req.user.completedFieldGuides) {
data.completedFieldGuides = req.user.completedFieldGuides; data.completedFieldGuides = req.user.completedFieldGuides;
} else { } else {
data.completedFieldGuides = [] data.completedFieldGuides = [];
} }
res.send(data); res.send(data);
}; };
@ -69,7 +69,7 @@ exports.returnNextFieldGuide = function(req, res, next) {
return next(err); return next(err);
} }
fieldGuide = fieldGuide.pop(); fieldGuide = fieldGuide.pop();
if (fieldGuide === undefined) { if (typeof fieldGuide === 'undefined') {
req.flash('success', { req.flash('success', {
msg: "You've read all our current Field Guide entries. You can contribute to our Field Guide <a href='https://github.com/FreeCodeCamp/freecodecamp/blob/master/seed_data/field-guides.json'>here</a>." msg: "You've read all our current Field Guide entries. You can contribute to our Field Guide <a href='https://github.com/FreeCodeCamp/freecodecamp/blob/master/seed_data/field-guides.json'>here</a>."
}); });

View File

@ -8,7 +8,6 @@ var async = require('async'),
Nonprofit = require('./../models/Nonprofit'), Nonprofit = require('./../models/Nonprofit'),
Comment = require('./../models/Comment'), Comment = require('./../models/Comment'),
resources = require('./resources.json'), resources = require('./resources.json'),
steps = resources.steps,
secrets = require('./../config/secrets'), secrets = require('./../config/secrets'),
bonfires = require('../seed_data/bonfires.json'), bonfires = require('../seed_data/bonfires.json'),
nonprofits = require('../seed_data/nonprofits.json'), nonprofits = require('../seed_data/nonprofits.json'),
@ -21,6 +20,12 @@ var async = require('async'),
request = require('request'), request = require('request'),
R = require('ramda'); R = require('ramda');
/**
* Cached values
*/
var allBonfireIds, allBonfireNames, allCoursewareIds, allCoursewareNames,
allFieldGuideIds, allFieldGuideNames, allNonprofitNames;
/** /**
* GET / * GET /
* Resources. * Resources.
@ -38,63 +43,106 @@ Array.zip = function(left, right, combinerFunction) {
}; };
module.exports = { module.exports = {
privacy: function privacy(req, res) {
res.render('resources/privacy', {
title: 'Privacy'
});
},
sitemap: function sitemap(req, res, next) { sitemap: function sitemap(req, res, next) {
var appUrl = 'http://www.freecodecamp.com'; var appUrl = 'http://www.freecodecamp.com';
var now = moment(new Date()).format('YYYY-MM-DD'); var now = moment(new Date()).format('YYYY-MM-DD');
User.find({'profile.username': {'$ne': '' }}, function(err, users) {
if (err) { async.parallel({
debug('User err: ', err); users: function(callback) {
return next(err); User.aggregate()
} .group({_id: 1, usernames: { $addToSet: '$profile.username'}})
Courseware.find({}, function (err, challenges) { .match({'profile.username': { $ne: ''}})
if (err) { .exec(function(err, users) {
debug('User err: ', err);
return next(err);
}
Bonfire.find({}, function (err, bonfires) {
if (err) {
debug('User err: ', err);
return next(err);
}
Story.find({}, function (err, stories) {
if (err) {
debug('User err: ', err);
return next(err);
}
Nonprofit.find({}, function (err, nonprofits) {
if (err) { if (err) {
debug('User err: ', err); debug('User err: ', err);
return next(err); callback(err);
} else {
callback(null, users[0].usernames);
} }
FieldGuide.find({}, function (err, fieldGuides) {
if (err) {
debug('User err: ', err);
return next(err);
}
res.header('Content-Type', 'application/xml');
res.render('resources/sitemap', {
appUrl: appUrl,
now: now,
users: users,
challenges: challenges,
bonfires: bonfires,
stories: stories,
nonprofits: nonprofits,
fieldGuides: fieldGuides
});
});
}); });
},
challenges: function (callback) {
Courseware.aggregate()
.group({_id: 1, names: { $addToSet: '$name'}})
.exec(function (err, challenges) {
if (err) {
debug('Courseware err: ', err);
callback(err);
} else {
callback(null, challenges[0].names);
}
});
},
bonfires: function (callback) {
Bonfire.aggregate()
.group({_id: 1, names: { $addToSet: '$name'}})
.exec(function (err, bonfires) {
if (err) {
debug('Bonfire err: ', err);
callback(err);
} else {
callback(null, bonfires[0].names);
}
}); });
}); },
}); stories: function (callback) {
}); Story.aggregate()
.group({_id: 1, links: {$addToSet: '$link'}})
.exec(function (err, stories) {
if (err) {
debug('Story err: ', err);
callback(err);
} else {
callback(null, stories[0].links);
}
});
},
nonprofits: function (callback) {
Nonprofit.aggregate()
.group({_id: 1, names: { $addToSet: '$name'}})
.exec(function (err, nonprofits) {
if (err) {
debug('User err: ', err);
callback(err);
} else {
callback(null, nonprofits[0].names);
}
});
},
fieldGuides: function (callback) {
FieldGuide.aggregate()
.group({_id: 1, names: { $addToSet: '$name'}})
.exec(function (err, fieldGuides) {
if (err) {
debug('User err: ', err);
callback(err);
} else {
callback(null, fieldGuides[0].names);
}
});
}
}, function (err, results) {
if (err) {
return next(err);
} else {
setTimeout(function() {
res.header('Content-Type', 'application/xml');
res.render('resources/sitemap', {
appUrl: appUrl,
now: now,
users: results.users,
challenges: results.challenges,
bonfires: results.bonfires,
stories: results.stories,
nonprofits: results.nonprofits,
fieldGuides: results.fieldGuides
});
}, 0);
}
}
);
}, },
chat: function chat(req, res) { chat: function chat(req, res) {
@ -161,132 +209,165 @@ module.exports = {
debug('User err: ', err); debug('User err: ', err);
return next(err); return next(err);
} }
User.count({'points': {'$gt': 53}}, function (err, all) {
if (err) {
debug('User err: ', err);
return next(err);
}
res.render('resources/learn-to-code', { res.render('resources/learn-to-code', {
title: 'About Free Code Camp', title: 'About Free Code Camp',
daysRunning: daysRunning, daysRunning: daysRunning,
c3: numberWithCommas(c3), c3: numberWithCommas(c3),
announcements: announcements announcements: announcements
});
}); });
}); });
}, },
randomPhrase: function() { randomPhrase: function() {
var phrases = resources.phrases; return resources.phrases[Math.floor(
return phrases[Math.floor(Math.random() * phrases.length)]; Math.random() * resources.phrases.length)];
}, },
randomVerb: function() { randomVerb: function() {
var verbs = resources.verbs; return resources.verbs[Math.floor(
return verbs[Math.floor(Math.random() * verbs.length)]; Math.random() * resources.verbs.length)];
}, },
randomCompliment: function() { randomCompliment: function() {
var compliments = resources.compliments; return resources.compliments[Math.floor(
return compliments[Math.floor(Math.random() * compliments.length)]; Math.random() * resources.compliments.length)];
}, },
allBonfireIds: function() { allBonfireIds: function() {
return bonfires.map(function(elem) { if (allBonfireIds) {
return { return allBonfireIds;
_id: elem._id, } else {
difficulty: elem.difficulty allBonfireIds = bonfires.
} map(function (elem) {
}) return {
.sort(function(a, b) { _id: elem._id,
return a.difficulty - b.difficulty; difficulty: elem.difficulty
}) };
.map(function(elem) { }).
return elem._id; sort(function (a, b) {
}); return a.difficulty - b.difficulty;
}).
map(function (elem) {
return elem._id;
});
return allBonfireIds;
}
}, },
allFieldGuideIds: function() { allFieldGuideIds: function() {
return fieldGuides.map(function(elem) { if (allFieldGuideIds) {
return { return allFieldGuideIds;
_id: elem._id, } else {
} allFieldGuideIds = fieldGuides.
}) map(function (elem) {
.map(function(elem) { return {
return elem._id; _id: elem._id
}); };
});
return allFieldGuideIds;
}
}, },
allBonfireNames: function() { allBonfireNames: function() {
return bonfires.map(function(elem) { if (allBonfireNames) {
return { return allBonfireNames;
name: elem.name, } else {
difficulty: elem.difficulty, allBonfireNames = bonfires.
_id: elem._id map(function (elem) {
} return {
}) name: elem.name,
.sort(function(a, b) { difficulty: elem.difficulty,
return a.difficulty - b.difficulty; _id: elem._id
}) };
.map (function(elem) { }).
return { sort(function (a, b) {
name : elem.name, return a.difficulty - b.difficulty;
_id: elem._id }).
} map(function (elem) {
}); return {
name: elem.name,
_id: elem._id
};
});
return allBonfireNames;
}
}, },
allFieldGuideNames: function() { allFieldGuideNames: function() {
return fieldGuides.map(function(elem) { if (allFieldGuideNames) {
return { return allFieldGuideNames;
name: elem.name } else {
} allFieldGuideNames = fieldGuides.
}) map(function (elem) {
return {
name: elem.name
};
});
return allFieldGuideNames;
}
}, },
allNonprofitNames: function() { allNonprofitNames: function() {
return nonprofits.map(function(elem) { if (allNonprofitNames) {
return { return allNonprofitNames;
name: elem.name } else {
} allNonprofitNames = nonprofits.
}) map(function (elem) {
return {
name: elem.name
};
});
return allNonprofitNames;
}
}, },
allCoursewareIds: function() { allCoursewareIds: function() {
return coursewares.map(function(elem) { if (allCoursewareIds) {
return { return allCoursewareIds;
_id: elem._id, } else {
difficulty: elem.difficulty allCoursewareIds = coursewares.
}; map(function (elem) {
}) return {
.sort(function(a, b) { _id: elem._id,
return a.difficulty - b.difficulty; difficulty: elem.difficulty
}) };
.map(function(elem) { }).
return elem._id; sort(function (a, b) {
}); return a.difficulty - b.difficulty;
}).
map(function (elem) {
return elem._id;
});
return allCoursewareIds;
}
}, },
allCoursewareNames: function() { allCoursewareNames: function() {
return coursewares.map(function(elem) { if (allCoursewareNames) {
return { return allCoursewareNames;
name: elem.name, } else {
difficulty: elem.difficulty, allCoursewareNames = coursewares.
challengeType: elem.challengeType, map(function (elem) {
_id: elem._id return {
}; name: elem.name,
}) difficulty: elem.difficulty,
.sort(function(a, b) { challengeType: elem.challengeType,
return a.difficulty - b.difficulty; _id: elem._id
}) };
.map (function(elem) { }).
return { sort(function (a, b) {
name: elem.name, return a.difficulty - b.difficulty;
challengeType: elem.challengeType, }).
_id: elem._id map(function (elem) {
}; return {
}); name: elem.name,
challengeType: elem.challengeType,
_id: elem._id
};
});
return allCoursewareNames;
}
}, },
whichEnvironment: function() { whichEnvironment: function() {
@ -302,8 +383,9 @@ module.exports = {
var metaDescription = $("meta[name='description']"); var metaDescription = $("meta[name='description']");
var metaImage = $("meta[property='og:image']"); var metaImage = $("meta[property='og:image']");
var urlImage = metaImage.attr('content') ? metaImage.attr('content') : ''; var urlImage = metaImage.attr('content') ? metaImage.attr('content') : '';
var metaTitle = $('title');
var description = metaDescription.attr('content') ? metaDescription.attr('content') : ''; var description = metaDescription.attr('content') ? metaDescription.attr('content') : '';
result.title = $('title').text().length < 141 ? $('title').text() : $('title').text().slice(0, 137) + " ..."; result.title = metaTitle.text().length < 141 ? metaTitle.text() : metaTitle.text().slice(0, 137) + " ...";
result.image = urlImage; result.image = urlImage;
result.description = description; result.description = description;
callback(null, result); callback(null, result);
@ -360,7 +442,9 @@ module.exports = {
}); });
}, foundStories); }, foundStories);
async.parallel(tasks, function(err) { async.parallel(tasks, function(err) {
if (err) { return cb(err); } if (err) {
return cb(err);
}
cb(); cb();
}); });
} }

View File

@ -253,7 +253,7 @@ exports.checkExistingUsername = function(req, res, next) {
exports.checkUniqueEmail = function(req, res, next) { exports.checkUniqueEmail = function(req, res, next) {
User.count({'email': decodeURIComponent(req.params.email).toLowerCase()}, function (err, data) { User.count({'email': decodeURIComponent(req.params.email).toLowerCase()}, function (err, data) {
if (err) { return next(err); } if (err) { return next(err); }
if (data == 1) { if (data === 1) {
return res.send(true); return res.send(true);
} else { } else {
return res.send(false); return res.send(false);
@ -271,7 +271,7 @@ exports.returnUser = function(req, res, next) {
User.find({'profile.username': req.params.username.toLowerCase()}, function(err, user) { User.find({'profile.username': req.params.username.toLowerCase()}, function(err, user) {
if (err) { debug('Username err: ', err); next(err); } if (err) { debug('Username err: ', err); next(err); }
if (user[0]) { if (user[0]) {
var user = user[0]; user = user[0];
user.progressTimestamps = user.progressTimestamps.sort(function(a, b) { user.progressTimestamps = user.progressTimestamps.sort(function(a, b) {
return a - b; return a - b;
@ -284,6 +284,7 @@ exports.returnUser = function(req, res, next) {
var tmpLongest = 1; var tmpLongest = 1;
var timeKeys = R.keys(timeObject); var timeKeys = R.keys(timeObject);
for (var i = 1; i <= timeKeys.length; i++) { for (var i = 1; i <= timeKeys.length; i++) {
if (moment(timeKeys[i - 1]).add(1, 'd').toString() if (moment(timeKeys[i - 1]).add(1, 'd').toString()
=== moment(timeKeys[i]).toString()) { === moment(timeKeys[i]).toString()) {
@ -305,13 +306,17 @@ exports.returnUser = function(req, res, next) {
var data = {}; var data = {};
var progressTimestamps = user.progressTimestamps; var progressTimestamps = user.progressTimestamps;
for (var i = 0; i < progressTimestamps.length; i++) { progressTimestamps.forEach(function(timeStamp) {
data[(progressTimestamps[i] / 1000).toString()] = 1; data[(timeStamp / 1000)] = 1;
} });
//for (var i = 0; i < progressTimestamps.length; i++) {
// data[(progressTimestamps[i] / 1000).toString()] = 1;
//}
user.currentStreak = user.currentStreak || 1; user.currentStreak = user.currentStreak || 1;
user.longestStreak = user.longestStreak || 1; user.longestStreak = user.longestStreak || 1;
challenges = user.completedCoursewares.filter(function ( obj ) { var challenges = user.completedCoursewares.filter(function ( obj ) {
return !!obj.solution; return !!obj.solution;
}); });
res.render('account/show', { res.render('account/show', {

View File

@ -644,7 +644,8 @@
"difficulty": "3.12", "difficulty": "3.12",
"description": [ "description": [
"Fill in the object constructor with the methods specified in the tests.", "Fill in the object constructor with the methods specified in the tests.",
"Those methods are getFirstName(), getLastName(), getFullName(), setFirstName(), setLastName(), and setFullName().", "Those methods are getFirstName(), getLastName(), getFullName(), setFirstName(first), setLastName(last), and setFullName(firstAndLast).",
"All functions that take an argument have an arity of 1, and the argument will be a string.",
"These methods must be the only available means for interacting with the object." "These methods must be the only available means for interacting with the object."
], ],
"challengeSeed": "var Person = function(firstAndLast) {\n return firstAndLast;\r\n};\n\nvar bob = new Person('Bob Ross');\nbob.getFullName();", "challengeSeed": "var Person = function(firstAndLast) {\n return firstAndLast;\r\n};\n\nvar bob = new Person('Bob Ross');\nbob.getFullName();",

View File

@ -32,18 +32,19 @@ urlset(xmlns="http://www.sitemaps.org/schemas/sitemap/0.9")
changefreq daily changefreq daily
priority= 0.8 priority= 0.8
//- Users //- User
each user in users each user in users
url url
loc #{appUrl}/#{user.profile.username} loc #{appUrl}/#{user}
lastmod= now lastmod= now
changefreq daily changefreq daily
priority= 0.9 priority= 0.9
//- Products //- Products
each bonfire in bonfires each bonfire in bonfires
url url
loc #{appUrl}/bonfires/#{bonfire.name.replace(/\s/g, '-')} loc #{appUrl}/bonfires/#{bonfire.replace(/\s/g, '-')}
lastmod= now lastmod= now
changefreq weekly changefreq weekly
priority= 0.5 priority= 0.5
@ -51,7 +52,7 @@ urlset(xmlns="http://www.sitemaps.org/schemas/sitemap/0.9")
//- Challenges //- Challenges
each challenge in challenges each challenge in challenges
url url
loc #{appUrl}/challenges/#{challenge.name.replace(/\s/g, '-')} loc #{appUrl}/challenges/#{challenge.replace(/\s/g, '-')}
lastmod= now lastmod= now
changefreq weekly changefreq weekly
priority= 0.5 priority= 0.5
@ -59,7 +60,7 @@ urlset(xmlns="http://www.sitemaps.org/schemas/sitemap/0.9")
//- Stories //- Stories
each story in stories each story in stories
url url
loc #{appUrl}/stories/#{story.storyLink.replace(/\s/g, '-')} loc #{appUrl}/stories/#{story.replace(/\s/g, '-')}
lastmod= now lastmod= now
changefreq daily changefreq daily
priority= 0.9 priority= 0.9
@ -67,7 +68,7 @@ urlset(xmlns="http://www.sitemaps.org/schemas/sitemap/0.9")
//- Nonprofit //- Nonprofit
each nonprofit in nonprofits each nonprofit in nonprofits
url url
loc #{appUrl}/nonprofits/#{nonprofit.name.replace(/\s/g, '-')} loc #{appUrl}/nonprofits/#{nonprofit.replace(/\s/g, '-')}
lastmod= now lastmod= now
changefreq daily changefreq daily
priority= 0.9 priority= 0.9
@ -75,7 +76,7 @@ urlset(xmlns="http://www.sitemaps.org/schemas/sitemap/0.9")
//- Nonprofit //- Nonprofit
each fieldGuide in fieldGuides each fieldGuide in fieldGuides
url url
loc #{appUrl}/field-guide/#{fieldGuide.name.replace(/\s/g, '-')} loc #{appUrl}/field-guide/#{fieldGuide.replace(/\s/g, '-')}
lastmod= now lastmod= now
changefreq daily changefreq daily
priority= 0.9 priority= 0.9