NodeAtlas offers also a large set of features for development or packaging with the configuration sytem. We will see that.
Although you can configure static urls, you can also set of dynamic url!
With the following configuration:
{
"routes": {
"/list-of-members/:member/": {
"template": "members.htm"
},
"/list-of-members/": {
"template": "members.htm"
},
"/": {
"template": "index.htm"
}
}
}
you can access:
and retrieve the :member
value inchangeVariation
(common and specific).
exports.changeVariation = function (params, next) {
var variation = params.variation;
console.log(variation.params.member);
// \> 'toto', 'bob-eponge99', 'node-atlas' or 'etc'.
next(variation);
}
Dynamic url creation rules are those of Express.js.
You can also enable regular expressions to a specific path with regExp
. If it is true
, the previous profile no longer works and you pass in Regular Expression mode. If regExp
is a string, it acts as a flag (g, i, m or y).
See the following configuration:
{
"routes": {
"/list-of-members/([-a-z0-9]+)/?": {
"template": "members.htm",
"regExp": "g"
},
"/list-of-members/?": {
"template": "members.htm",
"regExp": true
},
"/": {
"template": "index.htm"
}
}
}
you can access:
and retrieve the ([-a-z0-9] +) value in the
changeVariation
(common and specific).
exports.changeVariation = function (params, next) {
var variation = params.variation;
if (variation.params && variation.params[0]) { variation.params.member = variation.params[0]; }
// variation.params[1] for second match, etc...
console.log(variation.params.member);
// \> 'toto', 'bob-eponge99', 'node-atlas' or 'etc'.
next(variation);
}
The rules for creating dynamic url with regExp
are those of RegExpJavaScript.
In order to not rewrite a long route list in webconfig.json
file to your development environment andwebconfig.prod.json
to your production environment, you can group route in a file of your choice. By convention, the name is routes.json
file.
For example:
The following set of file
├─ templates/
│ └─ index.htm
├─ webconfig.json
└─ webconfig.prod.json
with webconfig.json
{
"httpPort": 7777,
"routes": {
"/": {
"template": "index.htm"
}
}
}
and with webconfig.prod.json
{
"httpPort": 7776,
"httpHostname": "blog.lesieur.name",
"urlPort": 80,
"routes": {
"/": {
"template": "index.htm"
}
}
}
could be the following set of file
templates/
— index.htm
routes.json
webconfig.json
webconfig.prod.json
with webconfig.json
{
"httpPort": 7777,
"routes": "routes.json"
}
with webconfig.prod.json
{
"httpPort": 7776,
"httpHostname": "blog.lesieur.name",
"urlPort": 80,
"routes": "routes.json"
}
and routes.json
{
"/": {
"template": "index.htm"
}
}
Note : You can create multiple route file as routes.en.json
and routes.fr.json
and associate each of them in a set of webconfig parameterize to run a website in various languages.
assetsRelativePath
To display a custom page when a resource is not found you must:
pageNotFound
with the following value
: key
of the prepared 404 page.See the example below:
{
"pageNotFound": "/not-found-page/",
"routes": {
"/list-of-members/": {
"template": "members.htm"
},
"/": {
"template": "index.htm"
},
"/not-found-page/": {
"template": "error.htm",
"statusCode": 404
}
}
}
you can access to:
For this, just create a new route with *
at the end with the languageCode.
See below :
{
"pageNotFound": "/not-found-page/",
"languageCode": "en-gb",
"routes": {
"/list-of-members/": {
"template": "members.htm",
"variation": "members.json"
},
"/": {
"template": "index.htm",
"variation": "index.json"
},
"/not-found-page/": {
"template": "error.htm",
"variation": "error.json",
"statusCode": 404
},
"/francais/liste-des-membres/": {
"template": "members.htm",
"languageCode": "fr-fr",
"variation": "members.json"
},
"/francais/": {
"template": "index.htm",
"languageCode": "fr-fr",
"variation": "index.json"
},
"/francais/*": {
"template": "error.htm",
"languageCode": "fr-fr",
"variation": "error.json",
"statusCode": 404
}
}
}
To go to a different address (redirect 301 or 302) when you get to a url you must use the redirect
parameter.
Note : if you don't set statusCode
, no redirect will be executed. The statusCode
is mandatory for redirection.
See the example below:
{
"routes": {
"/list-of-members/": {
"template": "members.htm"
},
"/list-of-members": {
"redirect": "/list-of-members/",
"statusCode": 301
},
"/go-to-node-atlas/": {
"redirect": "https://node-atlas.js.org/",
"statusCode": 302
},
"/": {
"template": "index.htm"
}
}
}
You will be redirected:
http://localhost/list-of-members/
when you access http://localhost/list-of-members
with a header permanent redirect.https://node-atlas.js.org/
when you access http://localhost/go-to-node-atlas/
with a header temporary redirect.See the example below:
{
"routes": {
"/list-of-members/:member/": {
"template": "members.htm"
},
"/list-of-members/:member": {
"redirect": "/membres/:member/",
"statusCode": 301
},
"/": {
"template": "index.htm"
}
}
}
You will be redirected to http://localhost/list-of-members/haeresis/
when you access to http://localhost/list-of-members/haeresis
with a header permanent redirect.
See the example below:
{
"routes": {
"/membres/([-a-z0-9]+)/": {
"template": "members.htm",
"regExp": true
},
"/list-of-members/([-a-z0-9]+)/": {
"redirect": "/membres/$0/",
"statusCode": 301,
"regExp": true
},
"/list-of-members/": {
"template": "members.htm"
},
"/": {
"template": "index.htm"
}
}
}
You will be redirected to http://localhost/list-of-members/haeresis/
when you access to http://localhost/list-of-members/haeresis
with a header permanent redirect.
For the second match use $1, the third $2, etc.
By défault, sent Headers by NodeAtlas are followings: Content-Type:text/html; charset=utf-8
with a 200 statusCode
.
It's possible to modify this values for a specific route (for local API for example).
{
"routes": {
"/api/articles": {
"template": "display-json.htm",
"controller": "blog/list-of-articles.js",
"mimeType": "application/json"
"charset": "ISO-8859-1",
"statusCode": 203
}
}
}
It's also possible to modify all Headers values, this erase all shortcuts before, except the statusCode
.
{
"routes": {
"/api/articles": {
"template": "display-json.htm",
"controller": "blog/list-of-articles.js",
"statusCode": 203,
"headers": {
"Content-Type": "application/json; charset=utf-8",
"Access-Control-Allow-Origin": "*"
}
}
}
}
It is very simple to run an instance of NodeAtlas with HTTPs protocol. You just have to create such a security
folder in which to place your server.key
and server.crt
file to supply the protocol.
Just use the following configuration:
{
"httpSecure": true,
"httpSecureRelativeKeyPath": "security/server.key",
"httpSecureRelativeCertificatePath": "security/server.crt",
"routes": {
"/": {
"template": "index.htm"
}
}
}
Alternatively , if your two Key and Certificate files have the same name, use this configuration:
{
"httpSecure": "security/server",
"routes": {
"/": {
"template": "index.htm"
}
}
}
This is also possible to just set the httpSecure
value to true
for get a "https" like urlBasePath
or urlBase
in your paths variables. But the server will not running in HTTPs and you will validate certificate by your own other way (with a server proxy for example).
{
"httpSecure": true,
"routes": {
"/": {
"template": "index.htm"
}
}
}
Note : in production, if you use a proxy for redirect request/response, don't forget use urlPort: 443
instead of urlPort: 80
for HTTPs.
You can automatically generate CSS and JS files minified and obfuscated by creating Bundles by referencing the file by input and output path. Of course you can do as much as you want. The gereration files is execute every time you start NodeAtlas either as a server or via the --generate
command if a Bundle exists in the Webconfig.
With the following configuration:
{
"bundles": {
"javascript": {
"javascript/boot.min.js": [
"javascript/modernizr.js",
"javascript/yepnot.js",
"javascript/html5Shiv.js"
],
"javascript/framework.min.js": [
"javascript/jquery.js",
"javascript/jquery-ui.js",
"javascript/prettify.js",
"javascript/prettify/run_prettify.js"
],
"javascript/common.min.js": [
"javascript/components/extended-format-date.js",
"javascript/common.js"
]
},
"stylesheets": {
"stylesheets/common.min.css": [
"stylesheets/common.css",
"stylesheets/common-min780.css",
"stylesheets/common-min1160.css"
]
}
},
"routes": {
"/": {
"template": "index.htm"
}
}
}
and the following set of file:
├─ assets/
│ ├─ stylesheets/
│ │ ├─ common.css
│ │ ├─ common-min780.css
│ │ └─ common-min1160.css
│ └─ javascript/
│ ├─ modernizr.js
│ ├─ yepnot.js
│ ├─ html5Shiv.js
│ ├─ jquery.js
│ ├─ jquery-ui.js
│ ├─ prettify.js
│ ├─ prettify/
│ │ └─ run_prettify.js
│ ├─ components/
│ │ └─ extended-format-date.js
│ └─ common.js
├─ templates/
│ └─ index.htm
└─ webconfig.json
you will get the following new files:
├─ assets/
│ ├─ stylesheets/
│ │ ├─ common.css
│ │ ├─ common-min780.css
│ │ ├─ common-min1160.css
│ │ └─ common.min.css ⤆ new file
│ └─ javascript/
│ ├─ modernizr.js
│ ├─ yepnot.js
│ ├─ html5Shiv.js
│ ├─ jquery.js
│ ├─ jquery-ui.js
│ ├─ prettify.js
│ ├─ prettify/
│ │ └─ run_prettify.js
│ ├─ components/
│ │ └─ extended-format-date.js
│ ├─ common.js
│ ├─ boot.min.js ⤆ new file
│ ├─ framework.min.js ⤆ new file
│ └─ common.min.js ⤆ new file
├─ templates/
│ └─ index.htm
└─ webconfig.json
In order to not re-write a long Bundles configuration list in webconfig.json
file to your development environment andwebconfig.prod.json
to your production environment, you can group routes in a file of your choice. By convention, the name is bundles.json
file.
For example:
The following set of file
├─ assets/
│ ├─ stylesheets/
│ │ ├─ common.css
│ │ ├─ common-min780.css
│ │ └─ common-min1160.css
│ └─ javascript/
│ ├─ modernizr.js
│ ├─ yepnot.js
│ ├─ html5Shiv.js
│ ├─ jquery.js
│ ├─ jquery-ui.js
│ ├─ prettify.js
│ ├─ prettify/
│ │ └─ run_prettify.js
│ ├─ components/
│ │ └─ extended-format-date.js
│ └─ common.js
├─ templates/
│ └─ index.htm
├─ webconfig.json
└─ webconfig.prod.json
with webconfig.json
{
"httpPort": 7777,
"bundles": {
"javascript": {
"javascript/boot.min.js": [
"javascript/modernizr.js",
"javascript/yepnot.js",
"javascript/html5Shiv.js"
],
"javascript/framework.min.js": [
"javascript/jquery.js",
"javascript/jquery-ui.js",
"javascript/prettify.js",
"javascript/prettify/run_prettify.js"
],
"javascript/common.min.js": [
"javascript/components/extended-format-date.js",
"javascript/common.js"
]
},
"stylesheets": {
"stylesheets/common.min.css": [
"stylesheets/common.css",
"stylesheets/common-min780.css",
"stylesheets/common-min1160.css"
]
}
},
"routes": {
"/": {
"template": "index.htm"
}
}
}
and with webconfig.prod.json
{
"httpPort": 7776,
"httpHostname": "blog.lesieur.name",
"urlPort": 80,
"bundles": {
"javascript": {
"javascript/boot.min.js": [
"javascript/modernizr.js",
"javascript/yepnot.js",
"javascript/html5Shiv.js"
],
"javascript/framework.min.js": [
"javascript/jquery.js",
"javascript/jquery-ui.js",
"javascript/prettify.js",
"javascript/prettify/run_prettify.js"
],
"javascript/common.min.js": [
"javascript/components/extended-format-date.js",
"javascript/common.js"
]
},
"stylesheets": {
"stylesheets/common.min.css": [
"stylesheets/common.css",
"stylesheets/common-min780.css",
"stylesheets/common-min1160.css"
]
}
},
"routes": {
"/": {
"template": "index.htm"
}
}
}
could be the following set of file
├─ assets/
│ ├─ stylesheets/
│ │ ├─ common.css
│ │ ├─ common-min780.css
│ │ └─ common-min1160.css
│ └─ javascript/
│ ├─ modernizr.js
│ ├─ yepnot.js
│ ├─ html5Shiv.js
│ ├─ jquery.js
│ ├─ jquery-ui.js
│ ├─ prettify.js
│ ├─ prettify/
│ │ └─ run_prettify.js
│ ├─ components/
│ │ └─ extended-format-date.js
│ └─ common.js
├─ templates/
│ └─ index.htm
├─ bundles.json ⤆ new file
├─ webconfig.json
└─ webconfig.prod.json
with webconfig.json
{
"httpPort": 7777,
"bundles": "bundles.json",
"routes": {
"/": {
"template": "index.htm"
}
}
}
with webconfig.prod.json
{
"httpPort": 7776,
"httpHostname": "blog.lesieur.name",
"urlPort": 80,
"bundles": "bundles.json",
"routes": {
"/": {
"template": "index.htm"
}
}
}
and bundles.json
{
"javascript": {
"javascript/boot.min.js": [
"javascript/modernizr.js",
"javascript/yepnot.js",
"javascript/html5Shiv.js"
],
"javascript/framework.min.js": [
"javascript/jquery.js",
"javascript/jquery-ui.js",
"javascript/prettify.js",
"javascript/prettify/run_prettify.js"
],
"javascript/common.min.js": [
"javascript/components/extended-format-date.js",
"javascript/common.js"
]
},
"stylesheets": {
"stylesheets/common.min.css": [
"stylesheets/common.css",
"stylesheets/common-min780.css",
"stylesheets/common-min1160.css"
]
}
}
Note : it is possible to disable Bundles by not including them in the webconfig
.
It is also possible to not execute the minification when run a website with NodeAtlas with "stylesheetsBundlesEnable": false
et `"javascriptBundlesEnable": false`` for each type of Bundle.
{
"stylesheetsBundlesEnable": false,
"javascriptBundlesEnable": false,
"bundles": {
"javascript": {
"javascript/boot.min.js": [
"javascript/modernizr.js",
"javascript/yepnot.js",
"javascript/html5Shiv.js"
],
"javascript/framework.min.js": [
"javascript/jquery.js",
"javascript/jquery-ui.js",
"javascript/prettify.js",
"javascript/prettify/run_prettify.js"
],
"javascript/common.min.js": [
"javascript/components/extended-format-date.js",
"javascript/common.js"
]
},
"stylesheets": {
"stylesheets/common.min.css": [
"stylesheets/common.css",
"stylesheets/common-min780.css",
"stylesheets/common-min1160.css"
]
}
},
"routes": {
"/": {
"template": "index.htm"
}
}
}
Note : if your bundle is in shared file, you could desactivated it also without the "bundles": "bundles.json"
. Just remove it.
For test your page with minified files, you can ask it to be regenerated before each page response with "stylesheetsBundlesBeforeResponse": false
et `"javascriptBundlesBeforeResponse": false`` for each type of Bundle.
{
"stylesheetsBundlesBeforeResponse": false,
"javascriptBundlesBeforeResponse": false,
"bundles": {
"javascript": {
"javascript/boot.min.js": [
"javascript/modernizr.js",
"javascript/yepnot.js",
"javascript/html5Shiv.js"
],
"javascript/framework.min.js": [
"javascript/jquery.js",
"javascript/jquery-ui.js",
"javascript/prettify.js",
"javascript/prettify/run_prettify.js"
],
"javascript/common.min.js": [
"javascript/components/extended-format-date.js",
"javascript/common.js"
]
},
"stylesheets": {
"stylesheets/common.min.css": [
"stylesheets/common.css",
"stylesheets/common-min780.css",
"stylesheets/common-min1160.css"
]
}
},
"routes": {
"/": {
"template": "index.htm"
}
}
}
Note : this is not recommanded for production environment because it's slowed responses pages.
You can use the preprocessor Less to create your CSS. The operation is as follows: whenever a CSS request is made, if a Less equivalent exists it is read and it generates the CSS. Once done, the new CSS is responded.
With the following structure:
├─ assets/
│ └─ stylesheets
│ └─ common.less
├─ templates/
│ └─ index.htm
└─ webconfig.json
and the following webconfig:
{
"enableLess": true,
"routes": {
"/": "index.htm"
}
}
and the following content in:
templates/index.htm
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Less Test</title>
<link rel="stylesheet" href="stylesheets/common.css">
</head>
<body>
<p>This line is red.</p>
</body>
</html>
assets/stylesheets/common.less
p {
color: #f00;
}
you will build the assets/stylesheets/common.css
by calling the url http://localhost/
or http://localhost/stylesheets/common.css
.
By default, in the above example, a common.css.map
file will be generated. This allows your browser to indicated you that line in .less
file has generated the CSS property of the item you have selected in your debugger.
Disable this with enableLess.sourceMap
to false
:
"enableLess": {
"sourceMap": false
},
"routes": {
"/": "index.htm"
}
You can also generate CSS files already minify with:
"enableLess": {
"compress": true
},
"routes": {
"/": "index.htm"
}
--generate
Because of Less are compilated on the fly, when a file is requested in http(s), modification needed running website for generate CSS output. Then you can use CSS. It's possible to skip running step and directly complated Less before minify CSS with enableLess.less
.
With the following webconfig.json
:
{
"enableLess": {
"less": [
"stylesheets/common.less",
"stylesheets/component-1.less",
"stylesheets/component-2.less",
"stylesheets/component-3.less"
]
},
"routes": {
"/": "index.htm"
}
}
or with the following webconfig.json
:
{
"enableLess": {
"less": "less.json"
},
"routes": {
"/": "index.htm"
}
}
with less.json
containing :
[
"stylesheets/common.less",
"stylesheets/component-1.less",
"stylesheets/component-2.less",
"stylesheets/component-3.less"
]
The @import
used by Less will be capable to walk into subdirectories : styles
, stylesheets
or css
. It's possible to change that with :
{
"enableLess": {
"paths": [
"subdirectory/styles-files",
],
"less": "less.json"
},
"routes": {
"/": "index.htm"
}
}
You can use the preprocessor Stylus to create your CSS. The operation is as follows: whenever a CSS request is made, if a Stylus equivalent exists it is read and it generates the CSS. Once done, the new CSS is responded.
With the following structure:
├─ assets/
│ └─ stylesheets
│ └─ common.styl
├─ templates/
│ └─ index.htm
└─ webconfig.json
and the following webconfig:
{
"enableStylus": true,
"routes": {
"/": "index.htm"
}
}
and the following content in:
templates/index.htm
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Stylus Test</title>
<link rel="stylesheet" href="stylesheets/common.css">
</head>
<body>
<p>This line is red.</p>
</body>
</html>
assets/stylesheets/common.styl
p
color: #f00
you will build the assets/stylesheets/common.css
by calling the url http://localhost/
or http://localhost/stylesheets/common.css
.
By default, in the above example, a common.css.map
file will be generated. This allows your browser to indicated you that line in .styl
file has generated the CSS property of the item you have selected in your debugger.
Disable this with enableLess.sourceMap
to false
:
"enableStylus": {
"sourceMap": false
},
"routes": {
"/": "index.htm"
}
You can also generate CSS files already minify with:
"enableStylus": {
"compress": true
},
"routes": {
"/": "index.htm"
}
Note: More options on stylus documentation for module.
--generate
Because of Stylus are compilated on the fly, when a file is requested in http(s), modification needed running website for generate CSS output. Then you can use CSS. It's possible to skip running step and directly complated Stylus before minify CSS with enableLess.stylus
.
With the following webconfig.json
:
{
"enableLess": {
"stylus": [
"stylesheets/common.styl",
"stylesheets/component-1.styl",
"stylesheets/component-2.styl",
"stylesheets/component-3.styl"
]
},
"routes": {
"/": "index.htm"
}
}
or with the following webconfig.json
:
{
"enableLess": {
"stylus": "stylus.json"
},
"routes": {
"/": "index.htm"
}
}
with stylus.json
containing :
[
"stylesheets/common.styl",
"stylesheets/component-1.styl",
"stylesheets/component-2.styl",
"stylesheets/component-3.styl"
]
The @import
used by Less will be capable to walk into subdirectories : styles
, stylesheets
or css
. It's possible to change that with :
{
"enableLess": {
"paths": [
"subdirectory/styles-files",
],
"stylus": "stylus.json"
},
"routes": {
"/": "index.htm"
}
}
You can automatically generate optimized images files by creating Optimizations by referencing the file by input and output path. Of course you can do as much as you want. The optimization files is execute every time you start NodeAtlas either as a server or via the --generate
command if an Optimization exists in the Webconfig.
With the following configuration:
{
"optimizations": {
"images": {
"media/images/example.png": "media/images/optimized/",
"media/images/example.jpg": "media/images/optimized/",
"media/images/example.gif": "media/images/optimized/",
"media/images/example.svg": "media/images/optimized/"
}
},
"routes": {
"/": {
"template": "index.htm"
}
}
}
and the following set of file:
├─ assets/
│ └─ media/
│ └─ images/
│ ├─ example.png
│ ├─ example.jpg
│ ├─ example.gif
│ └─ example.svg
├─ templates/
│ └─ index.htm
└─ webconfig.json
you will get the following new files:
├─ assets/
│ └─ media/
│ └─ images/
│ ├─ example.png
│ ├─ example.jpg
│ ├─ example.gif
│ ├─ example.svg
│ └─ optimized/ ⤆ new folder
│ ├─ example.png ⤆ new file
│ ├─ example.jpg ⤆ new file
│ ├─ example.gif ⤆ new file
│ └─ example.svg ⤆ new file
├─ templates/
│ └─ index.htm
└─ webconfig.json
For example, not define file one by one, but in group:
{
"optimizations": {
"images": {
"media/images/*.{gif,jpg,png,svg}": "media/images/optimized/"
}
},
"routes": {
"/": {
"template": "index.htm"
}
}
}
It is possible to redefine default options used for optimizations via this 4 objects:
{
"optimizations": {
"jpg": { "progressive": false },
"gif": { "interlaced": false },
"png": { "optimizationLevel": 1 },
"svg": { "multipass": false },
"images": {
"media/images/*.{gif,jpg,png,svg}": "media/images/optimized/"
}
},
"routes": {
"/": {
"template": "index.htm"
}
}
}
To know all options it is here:
In order to not re-write a long Bundles configuration list in webconfig.json
file to your development environment andwebconfig.prod.json
to your production environment, you can group files in a file of your choice. By convention, the name is optimizations.json
file.
For example:
The following set of file
├─ assets/
│ └─ media/
│ └─ images/
│ ├─ example.png
│ ├─ example.jpg
│ ├─ example.gif
│ └─ example.svg
├─ templates/
│ └─ index.htm
├─ webconfig.json
└─ webconfig.prod.json
with webconfig.json
{
"httpPort": 7777,
"optimizations": {
"images": {
"media/images/example.png": "media/images/optimized/",
"media/images/example.jpg": "media/images/optimized/",
"media/images/example.gif": "media/images/optimized/",
"media/images/example.svg": "media/images/optimized/"
}
},
"routes": {
"/": {
"template": "index.htm"
}
}
}
and with webconfig.prod.json
{
"httpPort": 7776,
"httpHostname": "blog.lesieur.name",
"urlPort": 80,
"optimizations": {
"images": {
"media/images/example.png": "media/images/optimized/",
"media/images/example.jpg": "media/images/optimized/",
"media/images/example.gif": "media/images/optimized/",
"media/images/example.svg": "media/images/optimized/"
}
},
"routes": {
"/": {
"template": "index.htm"
}
}
}
could be the following set of file
├─ assets/
│ └─ media/
│ └─ images/
│ ├─ example.png
│ ├─ example.jpg
│ ├─ example.gif
│ └─ example.svg
├─ templates/
│ └─ index.htm
├─ bundles.json
├─ webconfig.json
└─ webconfig.prod.json
with webconfig.json
{
"httpPort": 7777,
"optimizations": "optimizations.json",
"routes": {
"/": {
"template": "index.htm"
}
}
}
with webconfig.prod.json
{
"httpPort": 7776,
"httpHostname": "blog.lesieur.name",
"urlPort": 80,
"optimizations": "optimizations.json",
"routes": {
"/": {
"template": "index.htm"
}
}
}
and optimizations.json
{
"images": {
"media/images/example.png": "media/images/optimized/",
"media/images/example.jpg": "media/images/optimized/",
"media/images/example.gif": "media/images/optimized/",
"media/images/example.svg": "media/images/optimized/"
}
}
Note : it is possible to disable Optimizations by not including them in the webconfig
.
It is also possible to not execute the optimization when run a website with NodeAtlas with "imagesOptimizationsEnable": false
.
{
"imagesOptimizationsEnable": false,
"optimizations": {
"images": {
"media/images/example.png": "media/images/optimized/",
"media/images/example.jpg": "media/images/optimized/",
"media/images/example.gif": "media/images/optimized/",
"media/images/example.svg": "media/images/optimized/"
}
},
"routes": {
"/": {
"template": "index.htm"
}
}
}
Note : if your optimizations is in shared file, you could desactivated it also without the "optimizations": "optimizations.json"
. Just remove it.
You can ask files to be regenerated before each page response with "stylesheetsBundlesBeforeResponse": false
et `"javascriptBundlesBeforeResponse": false`` for each type of Bundle.
{
"imagesOptimizationsBeforeResponse": false,
"optimizations": {
"images": {
"media/images/example.png": "media/images/optimized/",
"media/images/example.jpg": "media/images/optimized/",
"media/images/example.gif": "media/images/optimized/",
"media/images/example.svg": "media/images/optimized/"
}
},
"routes": {
"/": {
"template": "index.htm"
}
}
}
Note : this is not recommanded for production environment because it's slowed responses pages.
When you create templates for sending email newsletters, or even simple message, you can not attach stylesheet. The only way is to write the CSS instructions in the template within the style
markup attribute.
With injectCss
, simply design your template as usual via a stylesheet and NodeAtlas inject each rendering styles in the attribute style
. It will do more than generate templates.
With for example the following configuration:
{
"routes": {
"/": {
"template": "email.htm",
"generate": "welcome.html",
"injectCss": "stylesheets/email.css"
}
}
}
and the following set of files:
├─ generates/
├─ assets/
│ └─ stylesheets/
│ └─ email.css
├─ templates/
│ └─ email.htm
└─ webconfig.json
whose contents are :
stylesheets/common.css
body {
color: #f00;
}
templates/email.htm*
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Email</title>
</head>
<body>
<p>This is a template email.</p>
</body>
</html>
output will be, with the command node </path/to/>node-atlas/ --generate
, all following file:
├─ generates/
│ └─ bienvenue.html <= template email generate !
├─ assets/
│ └─ stylesheets/
│ └─ email.css
├─ templates/
│ └─ email.htm
└─ webconfig.json
with as content for generates/welcome.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Email</title>
</head>
<body style="color: #f00;">
<p>This is a template email.</p>
</body>
</html>
This mechanism also works if you do not intend to generate anything but a site that is running. Convenient to change your live models before generating.
Test : From
./tests/examples/css-injection
runnode "../../../" --generate
. Result are intogenerates
.
It is possible to use injectCss
as global mechanism for all pages.
{
"injectCss": "stylesheets/email.css",
"routes": {
"/welcome/": {
"template": "email-a.htm",
"generate": "welcome.html"
},
"/good-bye/": {
"template": "email-b.htm",
"generate": "good-bye.html"
}
}
}
ainsi les deux pages welcome
et good-bye
contiendront chacune <body style="color: #f00;">
.
It's possible to :
injectCss
property.{
"injectCss": ["stylesheets/reset.css", "stylesheets/email.css"],
"routes": {
"/welcome/": {
"template": "email-a.htm",
"generate": "welcome.html",
"injectCss": "/stylesheets/welcome.css"
},
"/good-bye/": {
"template": "email-b.htm",
"generate": "good-bye.html",
"injectCss": ["stylesheets/good-bye.css", "/stylesheets/others.css"]
}
}
}
Test : From
./tests/examples/css-injection
runnode "../../../" --generate --webconfig webconfig.multiple.json
. Result are intogenerates
.
You can also manager how the server will respond to requests GET/POST to a given page. For example, we will allow access to pages only GET for the whole site and allow a POST to one page only (and prohibited him GET).
{
"getSupport": true,
"postSupport": false,
"routes": {
"/": {
"template": "index.htm"
},
"/list-of-members/": {
"template": "members.htm"
},
"/write-comment/": {
"template": "write-com.htm"
},
"/save-comment/": {
"template": "save-com.htm",
"getSupport": false,
"postSupport": true
}
}
}
Note : If nothing is set, getSupport and postSupport are set to true in global webconfig and by route.
Fonctionnant exactement de la même manière que getSupport
et postSupport
, les deux actions HTTP PUT et DELETE qui part défaut ne sont pas activé peuvent être activé avec putSupport
et deleteSupport
.
{
"getSupport": false,
"postSupport": false,
"putSupport": true,
"routes": {
"/read-all-entry/": {
"template": "display-json.htm",
"variation": "all-entry.json",
"getSupport": true,
"putSupport": false
},
"/read-entry/:id/": {
"template": "display-json.htm",
"variation": "entry.json",
"getSupport": true,
"putSupport": false
},
"/create-entry/:id/": {
"template": "display-json.htm",
"variation": "entry.json",
"postSupport": true,
"putSupport": false
},
"/update-entry/:id/": {
"template": "display-json.htm",
"variation": "entry.json"
},
"/delete-entry/:id/": {
"template": "display-json.htm",
"variation": "entry.json",
"deleteSupport": true,
"putSupport": false
}
}
}
With the configuration below, only one HTTP action is possible by route, this is a great way to create APIs REST easily with NodeAtlas.
NodeAtlas itself manages sessions stored on the server as initial settings:
nodeatlas.sid
1234567890bépo
that allow customers to stay connected through the pages to a single set of personal server side variable.
It is possible to change the default settings (and even compulsory for productions sites) with the parameters of webconfig.json
following:
{
sessionKey: "personal key",
sessionSecret: "personal secret"
}
NodeAtlas also employs a memory storage object (MemoryStore) stoques that the information in the RAM of the server.
It is possible to change all the parameters of the sessions (except MemoryStore) using the configuration of next webconfig.json
:
{
"session": {
"key": "personal key",
"secret": "personal secret",
"cookie": {
"path": '/',
"httpOnly": true,
"secure": false,
"maxAge": null
},
...,
...,
...
}
}
The entirety of the possible configuration is located on the module documentation express-session.
By default, this is NodeAtlas server that stores sessions in the RAM of the server application. This does not allow users to share sessions across multiple applications NodeAtlas (or other) and erases all current sessions for an application if you restart it.
To address this concern, it should support the recording sessions via a base No SQL such as Redis
or MongoBD
.
You just have to use the setSessions
function incontrollers/common.js
of Back-end part.
Implement the following code in controllers/common.js
to store your sessions in a local Redis.
var website = {};
(function (publics) {
"use strict";
publics.loadModules = function (NA) {
var NA = this;
NA.modules.RedisStore = require('connect-redis');
};
publics.setSessions = function (next) {
var NA = this,
session = NA.modules.session,
RedisStore = NA.modules.RedisStore(session);
NA.sessionStore = new RedisStore();
next();
};
}(website));
exports.loadModules = website.loadModules;
exports.setSessions = website.setSessions;
More information to connect-redis page.
Implement the following code in controllers/common.js
to store sessions in the database sessions
of a local MongoDB.
var website = {};
(function (publics) {
"use strict";
publics.loadModules = function () {
var NA = this;
NA.modules.MongoStore = require('connect-mongo');
};
publics.setSessions = function (next) {
var NA = this,
session = NA.modules.session,
MongoStore = NA.modules.MongoStore(session);
NA.sessionStore = new MongoStore({
db: 'sessions'
});
next();
};
}(website));
exports.loadModules = website.loadModules;
exports.setSessions = website.setSessions;
More information to connect-redis page.
For example, to include part of a file instruction is used <%- include('head.htm') %>. It would be possible to do it with <?- include('head.htm') ?> with the configuration below:
{
"templateEngineDelimiter": "?",
"routes": {
"/": {
"template": "index.htm"
}
}
}
See the exemple in files below:
components/head.htm
<!DOCTYPE html>
<html lang="fr-fr">
<head>
<meta charset="utf-8" />
<title><?- specific.titlePage ?></title>
<link type="text/css" rel="stylesheet" href="stylesheets/<?= common.classCssCommon ?>.css" media="all" />
<link type="text/css" rel="stylesheet" href="stylesheets/<?= specific.classPage ?>.css" media="all" />
</head>
<body class="<?= specific.classPage ?>">
components/foot.htm
<script async type="text/javascript" src="javascript/<?= common.classJsCommon ?>.js"></script>
</body>
</html>
templates/template.htm
<?- include('head.htm') ?>
<div class="title"><?- common.titleWebsite ?></div>
<div>
<h1><?- specific.titlePage ?></h1>
<?- specific.content ?>
</div>
<?- include('foot.htm') ?>
Learn all about the possibilities of the template engine consult the documentation ejs
Note : If nothing is set, templateEngineDelimiter is set to %.
It is possible to generate a different url listening other port with urlHostname and urlPort*. For example, the local loop listens on port 80 for a script makes the Reverse Proxy from the port 7777 on the 80 with the "http-proxy" module as below:
{
"httpPort": 7777,
"httpHostname": "127.0.0.1",
"urlPort": 80,
"urlHostname": "localhost",
"routes": {
"/": {
"template": "index.htm"
}
}
}
It's also possible to avoid other enter url. Also if www.localhost
or localhost:7777
are enter into url area, it's localhost
for the user :
{
"enableForceDomain": true,
"httpPort": 7777,
"httpHostname": "127.0.0.1",
"urlPort": 80,
"urlHostname": "localhost",
"routes": {
"/": {
"template": "index.htm"
}
}
}
It is possible that the paths created from your url to be interpreted as subfolders that have actually no real existence. This has the effect the address media/images/example.jpg
initially accessible from template displayed to address http://localhost impossible to reach when the template is displayed to address http://localhost/sub-directory/ (because the path should be ../media/images/example.jpg
).
To no longer have to worry about access to resources regardless of the URL that is requested, simply turn on all the urls such as:
<link rel="stylesheet" type="text/css" href="stylesheets/common.css" />
<!-- ... -->
<img src="media/images/example.jpg" />
<!-- ... -->
<script type="text/javascript" src="javascript/common.js"></script>
in absolute urls with variable urlBasePath
as below:
<link rel="stylesheet" type="text/css" href="<%= urlBasePath %>stylesheets/common.css" />
<!-- ... -->
<img src="<%= urlBasePath %>media/images/example.jpg" />
<!-- ... -->
<script type="text/javascript" src="<%= urlBasePath %>javascript/common.js"></script>
Note that in the case of the following configuration:
{
"routes": {
"/": {
"template": "index.htm"
}
}
}
urlBasePath
return http://localhost/
while in this configuration:
{
"httpPort": 7777,
"urlRelativeSubPath": "sub/folder",
"routes": {
"/": {
"template": "index.htm"
}
}
}
urlBasePath
return http://localhost:7777/sub/folder/
.
Using the following webconfig:
{
"routes": {
"/index.html": {
"template": "index.htm"
},
"/contact.html": {
"template": "contact.htm"
}
}
}
and the corresponding template
<!-- ... -->
<a href="http://localhost/index.html">Link to home</a>
<a href="http://localhost/contact.html">Link to contact</a>
<!-- ... -->
I'd have to change my link in the template if I change the listening port or if I change the path of the url. The following configuration changes:
{
"httpPort": 7777,
"routes": {
"/home.html": {
"template": "index.htm"
},
"/contact-us.html": {
"template": "contact.htm"
}
}
}
me contraindrait à modifier le template précédent comme suit :
<!-- ... -->
<a href="http://localhost:7777/home.html">Link to home</a>
<a href="http://localhost:7777/contact-us.html">Link to contact</a>
<!-- ... -->
You can solve this problem by giving a key to a specific path and deporting are way in the url
property.
With the followinh webconfig:
{
"routes": {
"index": {
"url": "/index.html",
"template": "index.htm"
},
"contact": {
"url": "/contact.html",
"template": "contact.htm"
}
}
}
I can now write the link in the dynamic template:
as follows
<!-- ... -->
<a href="<%= urlBasePath %><%= webconfig.routes.home.url.slice(1) %>">Link to home</a>
<a href="<%= urlBasePath %><%= webconfig.routes.contact.url.slice(1) %>">Link to contact</a>
<!-- ... -->
Note : .slice(1)
makes it easy to remove the dual /
for standard url.
or as follows
<!-- ... -->
<a href="<%= urlBasePath %>.<%= webconfig.routes.home.url %>">Link to home</a>
<a href="<%= urlBasePath %>.<%= webconfig.routes.contact.url %>">Link to contact</a>
<!-- ... -->
Note : This would, for example http://localhost/./home.html
, which is a standard url.
ou comme suit
<!-- ... -->
<a href="<%= urlBasePathSlice + webconfig.routes.home.url %>">Link to home</a>
<a href="<%= urlBasePathSlice + webconfig.routes.contact.url %>">Link to contact</a>
<!-- ... -->
Note : urlBasePathSlice
return http://localhost
in place of http://localhost/
or http://localhost:7777/sub/folder
in place of http://localhost:7777/sub/folder/
.
It's maybe useful to know the key used for the current page displayed for find the equivalent page in an other language.
With the following webconfig :
{
"languageCode": "en-us",
"routes": {
"index_en-us": {
"url": "/",
"template": "/index.htm"
},
"index_fr-fr": {
"url": "/francais/",
"template": "index.htm",
"languageCode": "fr-fr"
},
"cv_en-us": {
"url": "/resume/",
"template": "cv.htm"
},
"cv_fr-fr": {
"url": "/francais/cv/",
"template": "index.htm",
"languageCode": "fr-fr"
}
}
}
and the common variation following :
{
"language": [{
"name": "English",
"code": "en-us"
}, {
"name": "French",
"code": "fr-fr"
}]
}
in fr :
{
"language": [{
"name": "Anglais",
"code": "en-us"
}, {
"name": "Français",
"code": "fr-fr"
}]
}
we could create link between each page as following :
<ul>
<% for (var i = 0; i < common.language.length; i++) { %>
<li><a href="<%= urlBasePathSlice + webconfig.routes[currentRouteName.split('_')[0] + '_' + common.language[i].code].url %>"><%- common.language[i].name %></a></li>
<% } %>
</ul>