Permalink
Browse files

2.13.0: configuring an absolute "baseUrl" for your site to improve fa…

…cebook og:meta tags, newsletter generation by tasks, etc. works better.

* `req.baseUrl` is now also available as `req.data.baseUrl`.
* `req.baseUrlWithPrefix` and `req.data.baseUrlWithPrefix` have been added.
* `req.absoluteUrl` is also available as `req.data.absoluteUrl`.
* The `apostrophe-express` module correctly reads `baseUrl` from the global options of Apostrophe, not its own options; it is accepted from its own options for bc but for the full benefit you should set it globally.
* The `req` objects returned by `apos.tasks.getReq()` now include these properties, and you can pass `{ url: '/some-relative-url' }` if you want the `absoluteUrl` property to be based on a particular URL within the site. This is also used for unit testing.
* Unit tests no longer pass the meaningless `hostName` global option.
* Unit tests added for the above.
  • Loading branch information...
1 parent 3e35cc9 commit 078a389628944cf2d07bb188f3bc8c07d54e652f @boutell boutell committed Dec 21, 2016
@@ -14,13 +14,16 @@
//
// ## Options
//
-// ### `baseUrl`
+// ### `baseUrl` (GLOBAL OPTION, NOT SET FOR THIS SPECIFIC MODULE)
//
// As a convenience, `req.absoluteUrl` is set to the absolute URL of
-// the current request. If the `baseUrl` option is set to a string
+// the current request. If the `baseUrl` option **at the top level,
+// not for this specific module** is set to a string
// such as `http://mysite.com`, any site-wide prefix and `req.url` are
// appended to that. Otherwise the absolute URL is constructed based
-// on the browser's request.
+// on the browser's request. Setting the `baseUrl` global option is
+// necessary for reasonable URLs when generating markup from a
+// command line task.
//
// ### `address`
//
@@ -171,6 +174,11 @@ module.exports = {
self.optionalMiddleware();
self.addListenMethod();
self.enableCsrf();
+ if (self.options.baseUrl && (!self.apos.baseUrl)) {
+ console.error('WARNING: you have baseUrl set as an option to the `apostrophe-express` module.');
+ console.error('Set it as a global option (a property of the main object passed to apostrophe).');
+ console.error('When you do so other modules will also pick up on it and make URLs absolute.');
+ }
},
construct: function(self, options) {
@@ -471,11 +479,39 @@ module.exports = {
// Standard middleware. Sets the `req.absoluteUrl` property for all requests,
// based on the `baseUrl` option if available, otherwise based on the user's
// request headers. The global `prefix` option and `req.url` are then appended.
+ //
+ // `req.baseUrl` and `req.baseUrlWithPrefix` are also made available, and all three
+ // properties are also added to `req.data` if not already present.
+ //
+ // The `baseUrl` option should be configured at the top level, for Apostrophe itself,
+ // NOT specifically for this module, but for bc the latter is also accepted in this
+ // one case. For a satisfyingly global result, set it at the top level instead.
self.absoluteUrl = function(req, res, next) {
- req.absoluteUrl = (self.options.baseUrl || (req.protocol + '://' + req.get('Host'))) + self.apos.prefix + req.url;
+ self.addAbsoluteUrlsToReq(req);
next();
};
+
+ // Sets the `req.absoluteUrl` property for all requests,
+ // based on the `baseUrl` option if available, otherwise based on the user's
+ // request headers. The global `prefix` option and `req.url` are then appended.
+ //
+ // `req.baseUrl` and `req.baseUrlWithPrefix` are also made available, and all three
+ // properties are also added to `req.data` if not already present.
+ //
+ // The `baseUrl` option should be configured at the top level, for Apostrophe itself,
+ // NOT specifically for this module, but for bc the latter is also accepted in this
+ // one case. For a satisfyingly global result, set it at the top level instead.
+ //
+ // If you want reasonable URLs in req objects used in tasks you must
+ // set the `baseUrl` option for Apostrophe.
+
+ self.addAbsoluteUrlsToReq = function(req) {
+ req.baseUrl = (self.apos.baseUrl || self.options.baseUrl || (req.protocol + '://' + req.get('Host')));
+ req.baseUrlWithPrefix = req.baseUrl + self.apos.prefix;
+ req.absoluteUrl = req.baseUrlWithPrefix + req.url;
+ _.defaults(req.data, _.pick(req, 'baseUrl', 'baseUrlWithPrefix', 'absoluteUrl'));
+ };
// Locate modules with middleware and add it to the list
self.afterInit = function() {
@@ -143,21 +143,34 @@ module.exports = {
// Return a req object with permission to do anything.
// Useful since most APIs require one and most tasks
// should run with administrative rights.
+ //
+ // Optionally a `properties` object can be passed. If it is
+ // passed its properties are added to the req object before
+ // any initialization tasks such as computing `req.absoluteUrl`.
+ // This allows testing of that mechanism by setting `req.url`.
- self.getReq = function() {
- return {
+ self.getReq = function(properties) {
+ var req = {
user: {
_permissions: {
admin: true
}
},
- baseUrl: self.apos.modules['apostrophe-express'].baseUrl,
res: {
__: function(s) {
return s;
}
+ },
+ protocol: 'http',
+ get: function(propName) {
+ return {
+ Host: 'you-need-to-set-baseUrl-in-app-js.com'
+ }[propName];
}
};
+ _.extend(req, properties || {});
+ self.apos.modules['apostrophe-express'].addAbsoluteUrlsToReq(req);
+ return req;
};
}
};
View
@@ -1,6 +1,6 @@
{
"name": "apostrophe",
- "version": "2.12.0",
+ "version": "2.13.0",
"description": "The Apostrophe Content Management System.",
"main": "index.js",
"scripts": {
View
@@ -18,7 +18,7 @@ describe('Admin bar', function() {
apos = require('../index.js')({
root: module,
shortName: 'test',
- hostName: 'test.com',
+
modules: {
'apostrophe-express': {
secret: 'xxx',
@@ -69,7 +69,7 @@ describe('Admin bar', function() {
apos = require('../index.js')({
root: module,
shortName: 'test',
- hostName: 'test.com',
+
modules: {
'apostrophe-express': {
secret: 'xxx',
View
@@ -18,7 +18,7 @@ describe('Areas', function() {
apos = require('../index.js')({
root: module,
shortName: 'test',
- hostName: 'test.com',
+
modules: {
'apostrophe-express': {
secret: 'xxx',
View
@@ -43,7 +43,7 @@ describe('Attachment', function() {
apos = require('../index.js')({
root: module,
shortName: 'test',
- hostName: 'test.com',
+
modules: {
'apostrophe-express': {
port: 7938
View
@@ -10,7 +10,7 @@ describe('Base Module', function(){
apos = require('../index.js')({
root: module,
shortName: 'test',
- hostName: 'test.com',
+
modules: {
// will push an asset for us to look for later
'apostrophe-test-module-push': {}
View
@@ -18,7 +18,7 @@ describe('Apostrophe', function() {
root: module,
shortName: 'test',
overrideTest: 'test', // overriden by data/local.js
- hostName: 'test.com',
+
__testDefaults: {
modules: {}
},
@@ -34,7 +34,7 @@ describe('Apostrophe', function() {
root: module,
shortName: 'test',
overrideTest: 'test', // overriden by data/local_fn.js
- hostName: 'test.com',
+
__localPath: '/data/local_fn.js',
__testDefaults: {
modules: {}
@@ -51,7 +51,7 @@ describe('Apostrophe', function() {
root: module,
shortName: 'test',
overrideTest: 'test', // concated in local_fn_b.js
- hostName: 'test.com',
+
__localPath: '/data/local_fn_b.js',
__testDefaults: {
modules: {}
@@ -67,7 +67,7 @@ describe('Apostrophe', function() {
var apos = require('../index.js')({
root: module,
shortName: 'test',
- hostName: 'test.com',
+
__testDefaults: {
modules: {
'apostrophe-test-module': {},
@@ -84,7 +84,7 @@ describe('Apostrophe', function() {
var apos = require('../index.js')({
root: module,
shortName: 'test',
- hostName: 'test.com',
+
__testDefaults: {
modules: {
'apostrophe-test-module': {},
@@ -103,7 +103,7 @@ describe('Apostrophe', function() {
var apos = require('../index.js')({
root: module,
shortName: 'test',
- hostName: 'test.com',
+
afterInit: function(callback) {
// color = blue is inherited from our implicit subclass of the base module
assert(apos.assets && apos.assets.color === 'blue');
View
@@ -14,7 +14,7 @@ describe('Caches', function() {
apos = require('../index.js')({
root: module,
shortName: 'test',
- hostName: 'test.com',
+
afterInit: function(callback) {
assert(apos.caches);
return done();
@@ -21,7 +21,7 @@ describe('custom-pages', function() {
apos = require('../index.js')({
root: module,
shortName: 'test',
- hostName: 'test.com',
+
modules: {
'apostrophe-express': {
secret: 'xxx',
View
@@ -8,7 +8,7 @@ describe('Db', function(){
var apos = require('../index.js')({
root: module,
shortName: 'test',
- hostName: 'test.com',
+
afterInit: function(callback) {
assert(apos.db);
assert(apos.db.serverConfig.port === 27017)
View
@@ -21,7 +21,7 @@ describe('Docs', function() {
apos = require('../index.js')({
root: module,
shortName: 'test',
- hostName: 'test.com',
+
modules: {
'apostrophe-express': {
secret: 'xxx',
View
@@ -14,7 +14,7 @@ describe('Express', function() {
apos = require('../index.js')({
root: module,
shortName: 'test',
- hostName: 'test.com',
+
modules: {
'apostrophe-express': {
secret: 'xxx',
@@ -197,7 +197,7 @@ describe('Express', function() {
apos = require('../index.js')({
root: module,
shortName: 'test',
- hostName: 'test.com',
+
prefix: '/prefix',
modules: {
'apostrophe-express': {
@@ -242,5 +242,75 @@ describe('Express', function() {
done();
});
});
+
+ it('should provide reasonable absolute and base URLs in tasks reqs if baseUrl option is set on apos object', function(done) {
+ apos = require('../index.js')({
+ root: module,
+ shortName: 'test',
+ baseUrl: 'https://example.com',
+ modules: {
+ 'apostrophe-express': {
+ port: 7957,
+ csrf: false
+ },
+ 'express-test': {},
+ 'templates-test': {},
+ 'templates-subclass-test': {}
+ },
+ afterInit: function(callback) {
+ assert(apos.baseUrl);
+ assert(apos.baseUrl === 'https://example.com');
+ // In tests this will be the name of the test file,
+ // so override that in order to get apostrophe to
+ // listen normally and not try to run a task. -Tom
+ apos.argv._ = [];
+ return callback(null);
+ },
+ afterListen: function(err) {
+ assert(!err);
+ var req = apos.tasks.getReq({ url: '/test' });
+ assert(req.baseUrl === 'https://example.com');
+ assert(req.absoluteUrl === 'https://example.com/test');
+ done();
+ }
+ });
+ });
+
+ it('should provide reasonable absolute and base URLs in tasks reqs if baseUrl and prefix options are set on apos object', function(done) {
+
+ apos = require('../index.js')({
+ root: module,
+ shortName: 'test',
+ baseUrl: 'https://example.com',
+ prefix: '/subdir',
+ modules: {
+ 'apostrophe-express': {
+ port: 7958,
+ csrf: false
+ },
+ 'express-test': {},
+ 'templates-test': {},
+ 'templates-subclass-test': {}
+ },
+ afterInit: function(callback) {
+ assert(apos.baseUrl);
+ assert(apos.baseUrl === 'https://example.com');
+ assert(apos.prefix === '/subdir');
+ // In tests this will be the name of the test file,
+ // so override that in order to get apostrophe to
+ // listen normally and not try to run a task. -Tom
+ apos.argv._ = [];
+ return callback(null);
+ },
+ afterListen: function(err) {
+ assert(!err);
+ var req = apos.tasks.getReq({ url: '/test' });
+ assert(req.baseUrl === 'https://example.com');
+ assert(req.baseUrlWithPrefix === 'https://example.com/subdir');
+ assert(req.absoluteUrl === 'https://example.com/subdir/test');
+ done();
+ }
+ });
+ });
});
View
@@ -47,7 +47,7 @@ describe('Images', function() {
apos = require('../index.js')({
root: module,
shortName: 'test',
- hostName: 'test.com',
+
modules: {
'apostrophe-express': {
port: 7951
View
@@ -10,7 +10,7 @@ describe('Launder', function(){
apos = require('../index.js')({
root: module,
shortName: 'test',
- hostName: 'test.com',
+
afterInit: function(callback) {
assert(apos.launder);
return done();
View
@@ -16,7 +16,7 @@ describe('Locks', function() {
apos = require('../index.js')({
root: module,
shortName: 'test',
- hostName: 'test.com',
+
modules: {
'apostrophe-express': {
port: 7956
View
@@ -22,7 +22,7 @@ describe('Login', function() {
apos = require('../index.js')({
root: module,
shortName: 'test',
- hostName: 'test.com',
+
modules: {
'apostrophe-express': {
secret: 'xxx',
View
@@ -22,7 +22,7 @@ describe('Oembed', function() {
apos = require('../index.js')({
root: module,
shortName: 'test',
- hostName: 'test.com',
+
modules: {
'apostrophe-express': {
secret: 'xxx',
Oops, something went wrong.

0 comments on commit 078a389

Please sign in to comment.