yannstatic/static/2019/04/25/Node.js_Stack_Virtual_Machine(VirtualBox).html

2730 lines
264 KiB
HTML
Raw Normal View History

2024-10-31 20:18:37 +01:00
<!DOCTYPE html><html lang="fr">
<head><meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"><title>Node.js Stack "bitnami-node" (VirtualBox/PC1) - YannStatic</title>
<meta name="description" content="NodeJS">
<link rel="canonical" href="https://static.rnmkcy.eu/2019/04/25/Node.js_Stack_Virtual_Machine(VirtualBox).html"><link rel="alternate" type="application/rss+xml" title="YannStatic" href="/feed.xml">
<!-- - include head/favicon.html - -->
<link rel="shortcut icon" type="image/png" href="/assets/favicon/favicon.png"><link rel="stylesheet" href="/assets/css/main.css"><link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" ><!-- start custom head snippets --><link rel="stylesheet" href="/assets/css/expand.css">
<!-- end custom head snippets --><script>(function() {
window.isArray = function(val) {
return Object.prototype.toString.call(val) === '[object Array]';
};
window.isString = function(val) {
return typeof val === 'string';
};
window.hasEvent = function(event) {
return 'on'.concat(event) in window.document;
};
window.isOverallScroller = function(node) {
return node === document.documentElement || node === document.body || node === window;
};
window.isFormElement = function(node) {
var tagName = node.tagName;
return tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA';
};
window.pageLoad = (function () {
var loaded = false, cbs = [];
window.addEventListener('load', function () {
var i;
loaded = true;
if (cbs.length > 0) {
for (i = 0; i < cbs.length; i++) {
cbs[i]();
}
}
});
return {
then: function(cb) {
cb && (loaded ? cb() : (cbs.push(cb)));
}
};
})();
})();
(function() {
window.throttle = function(func, wait) {
var args, result, thisArg, timeoutId, lastCalled = 0;
function trailingCall() {
lastCalled = new Date;
timeoutId = null;
result = func.apply(thisArg, args);
}
return function() {
var now = new Date,
remaining = wait - (now - lastCalled);
args = arguments;
thisArg = this;
if (remaining <= 0) {
clearTimeout(timeoutId);
timeoutId = null;
lastCalled = now;
result = func.apply(thisArg, args);
} else if (!timeoutId) {
timeoutId = setTimeout(trailingCall, remaining);
}
return result;
};
};
})();
(function() {
var Set = (function() {
var add = function(item) {
var i, data = this._data;
for (i = 0; i < data.length; i++) {
if (data[i] === item) {
return;
}
}
this.size ++;
data.push(item);
return data;
};
var Set = function(data) {
this.size = 0;
this._data = [];
var i;
if (data.length > 0) {
for (i = 0; i < data.length; i++) {
add.call(this, data[i]);
}
}
};
Set.prototype.add = add;
Set.prototype.get = function(index) { return this._data[index]; };
Set.prototype.has = function(item) {
var i, data = this._data;
for (i = 0; i < data.length; i++) {
if (this.get(i) === item) {
return true;
}
}
return false;
};
Set.prototype.is = function(map) {
if (map._data.length !== this._data.length) { return false; }
var i, j, flag, tData = this._data, mData = map._data;
for (i = 0; i < tData.length; i++) {
for (flag = false, j = 0; j < mData.length; j++) {
if (tData[i] === mData[j]) {
flag = true;
break;
}
}
if (!flag) { return false; }
}
return true;
};
Set.prototype.values = function() {
return this._data;
};
return Set;
})();
window.Lazyload = (function(doc) {
var queue = {js: [], css: []}, sources = {js: {}, css: {}}, context = this;
var createNode = function(name, attrs) {
var node = doc.createElement(name), attr;
for (attr in attrs) {
if (attrs.hasOwnProperty(attr)) {
node.setAttribute(attr, attrs[attr]);
}
}
return node;
};
var end = function(type, url) {
var s, q, qi, cbs, i, j, cur, val, flag;
if (type === 'js' || type ==='css') {
s = sources[type], q = queue[type];
s[url] = true;
for (i = 0; i < q.length; i++) {
cur = q[i];
if (cur.urls.has(url)) {
qi = cur, val = qi.urls.values();
qi && (cbs = qi.callbacks);
for (flag = true, j = 0; j < val.length; j++) {
cur = val[j];
if (!s[cur]) {
flag = false;
}
}
if (flag && cbs && cbs.length > 0) {
for (j = 0; j < cbs.length; j++) {
cbs[j].call(context);
}
qi.load = true;
}
}
}
}
};
var load = function(type, urls, callback) {
var s, q, qi, node, i, cur,
_urls = typeof urls === 'string' ? new Set([urls]) : new Set(urls), val, url;
if (type === 'js' || type ==='css') {
s = sources[type], q = queue[type];
for (i = 0; i < q.length; i++) {
cur = q[i];
if (_urls.is(cur.urls)) {
qi = cur;
break;
}
}
val = _urls.values();
if (qi) {
callback && (qi.load || qi.callbacks.push(callback));
callback && (qi.load && callback());
} else {
q.push({
urls: _urls,
callbacks: callback ? [callback] : [],
load: false
});
for (i = 0; i < val.length; i++) {
node = null, url = val[i];
if (s[url] === undefined) {
(type === 'js' ) && (node = createNode('script', { src: url }));
(type === 'css') && (node = createNode('link', { rel: 'stylesheet', href: url }));
if (node) {
node.onload = (function(type, url) {
return function() {
end(type, url);
};
})(type, url);
(doc.head || doc.body).appendChild(node);
s[url] = false;
}
}
}
}
}
};
return {
js: function(url, callback) {
load('js', url, callback);
},
css: function(url, callback) {
load('css', url, callback);
}
};
})(this.document);
})();
</script><script>
(function() {
var TEXT_VARIABLES = {
version: '2.2.6',
sources: {
font_awesome: 'https://use.fontawesome.com/releases/v5.0.13/css/all.css',
jquery: '/assets/js/jquery.min.js',
leancloud_js_sdk: '//cdn.jsdelivr.net/npm/leancloud-storage@3.13.2/dist/av-min.js',
chart: 'https://cdn.bootcss.com/Chart.js/2.7.2/Chart.bundle.min.js',
gitalk: {
js: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.js',
css: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.css'
},
valine: 'https://unpkg.com/valine/dist/Valine.min.js'
},
site: {
toc: {
selectors: 'h1,h2,h3'
}
},
paths: {
search_js: '/assets/search.js'
}
};
window.TEXT_VARIABLES = TEXT_VARIABLES;
})();
</script>
</head>
<body>
<div class="root" data-is-touch="false">
<div class="layout--page js-page-root"><!----><div class="page__main js-page-main page__viewport hide-footer has-aside has-aside cell cell--auto">
<div class="page__main-inner"><div class="page__header d-print-none"><header class="header"><div class="main">
<div class="header__title">
<div class="header__brand"><svg id="svg" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="478.9473684210526" viewBox="0, 0, 400,478.9473684210526"><g id="svgg"><path id="path0" d="M308.400 56.805 C 306.970 56.966,303.280 57.385,300.200 57.738 C 290.906 58.803,278.299 59.676,269.200 59.887 L 260.600 60.085 259.400 61.171 C 258.010 62.428,256.198 63.600,255.645 63.600 C 255.070 63.600,252.887 65.897,252.598 66.806 C 252.460 67.243,252.206 67.600,252.034 67.600 C 251.397 67.600,247.206 71.509,247.202 72.107 C 247.201 72.275,246.390 73.190,245.400 74.138 C 243.961 75.517,243.598 76.137,243.592 77.231 C 243.579 79.293,241.785 83.966,240.470 85.364 C 239.176 86.740,238.522 88.365,237.991 91.521 C 237.631 93.665,236.114 97.200,235.554 97.200 C 234.938 97.200,232.737 102.354,232.450 104.472 C 232.158 106.625,230.879 109.226,229.535 110.400 C 228.933 110.926,228.171 113.162,226.434 119.500 C 226.178 120.435,225.795 121.200,225.584 121.200 C 225.373 121.200,225.200 121.476,225.200 121.813 C 225.200 122.149,224.885 122.541,224.500 122.683 C 223.606 123.013,223.214 123.593,223.204 124.600 C 223.183 126.555,220.763 132.911,219.410 134.562 C 218.443 135.742,217.876 136.956,217.599 138.440 C 217.041 141.424,215.177 146.434,214.532 146.681 C 214.240 146.794,214.000 147.055,214.000 147.261 C 214.000 147.467,213.550 148.086,213.000 148.636 C 212.450 149.186,212.000 149.893,212.000 150.208 C 212.000 151.386,208.441 154.450,207.597 153.998 C 206.319 153.315,204.913 150.379,204.633 147.811 C 204.365 145.357,202.848 142.147,201.759 141.729 C 200.967 141.425,199.200 137.451,199.200 135.974 C 199.200 134.629,198.435 133.224,196.660 131.311 C 195.363 129.913,194.572 128.123,193.870 125.000 C 193.623 123.900,193.236 122.793,193.010 122.540 C 190.863 120.133,190.147 118.880,188.978 115.481 C 188.100 112.928,187.151 111.003,186.254 109.955 C 185.358 108.908,184.518 107.204,183.847 105.073 C 183.280 103.273,182.497 101.329,182.108 100.753 C 181.719 100.177,180.904 98.997,180.298 98.131 C 179.693 97.265,178.939 95.576,178.624 94.378 C 178.041 92.159,177.125 90.326,175.023 87.168 C 174.375 86.196,173.619 84.539,173.342 83.486 C 172.800 81.429,171.529 79.567,170.131 78.785 C 169.654 78.517,168.697 77.511,168.006 76.549 C 167.316 75.587,166.594 74.800,166.402 74.800 C 166.210 74.800,164.869 73.633,163.421 72.206 C 160.103 68.936,161.107 69.109,146.550 69.301 C 133.437 69.474,128.581 70.162,126.618 72.124 C 126.248 72.495,125.462 72.904,124.872 73.033 C 124.282 73.163,123.088 73.536,122.219 73.863 C 121.349 74.191,119.028 74.638,117.061 74.858 C 113.514 75.254,109.970 76.350,108.782 77.419 C 107.652 78.436,100.146 80.400,97.388 80.400 C 95.775 80.400,93.167 81.360,91.200 82.679 C 90.430 83.195,89.113 83.804,88.274 84.031 C 85.875 84.681,78.799 90.910,74.400 96.243 L 73.400 97.456 73.455 106.028 C 73.526 117.055,74.527 121.238,77.820 124.263 C 78.919 125.273,80.400 127.902,80.400 128.842 C 80.400 129.202,81.075 130.256,81.900 131.186 C 83.563 133.059,85.497 136.346,86.039 138.216 C 86.233 138.886,87.203 140.207,88.196 141.153 C 89.188 142.098,90.000 143.104,90.000 143.388 C 90.000 144.337,92.129 148.594,92.869 149.123 C 93.271 149.410,93.600 149.831,93.600 150.059 C 93.600 150.286,93.932 150.771,94.337 151.136 C 94.743 151.501,95.598 153.004,96.237 154.475 C 96.877 155.947,97.760 157.351,98.200 157.596 C 98.640 157.841,99.900 159.943,101.000 162.267 C 102.207 164.817,103.327 166.644,103.825 166.876 C 104.278 167.087,105.065 168.101,105.573 169.130 C 107.658 173.348,108.097 174.093,110.006 176.647 C 111.103 178.114,112.000 179.725,112.000 180.227 C 112.000 181.048,113.425 183.163,114.678 184.200 C 115.295 184.711,117.396 188.733,117.720 190.022 C 117.855 190.562,118.603 191.633,119.381 192.402 C 120.160 193.171,121.496 195.258,122.351 197.039 C 123.206 198.820,124.167 200.378,124.487 200.501 C 124.807 200.624,125.953 202.496,127.034 204.662 C 128.114 206.828,129.676 209.299,130.505 210.153 C 131.333 211.007,132.124 212.177,132.262 212.753 C 132.618 214.239,134.291 217.048,136.288 219.5
" href="/">YannStatic</a></div><!--<button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button>--><!-- <li><button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button></li> -->
<!-- Champ de recherche -->
<div id="searchbox" class="search search--dark" style="visibility: visible">
<div class="main">
<div class="search__header"></div>
<div class="search-bar">
<div class="search-box js-search-box">
<div class="search-box__icon-search"><i class="fas fa-search"></i></div>
<input id="search-input" type="text" />
<!-- <div class="search-box__icon-clear js-icon-clear">
<a><i class="fas fa-times"></i></a>
</div> -->
</div>
</div>
</div>
</div>
<!-- Script pointing to search-script.js -->
<script>/*!
* Simple-Jekyll-Search
* Copyright 2015-2020, Christian Fei
* Licensed under the MIT License.
*/
(function(){
'use strict'
var _$Templater_7 = {
compile: compile,
setOptions: setOptions
}
const options = {}
options.pattern = /\{(.*?)\}/g
options.template = ''
options.middleware = function () {}
function setOptions (_options) {
options.pattern = _options.pattern || options.pattern
options.template = _options.template || options.template
if (typeof _options.middleware === 'function') {
options.middleware = _options.middleware
}
}
function compile (data) {
return options.template.replace(options.pattern, function (match, prop) {
const value = options.middleware(prop, data[prop], options.template)
if (typeof value !== 'undefined') {
return value
}
return data[prop] || match
})
}
'use strict';
function fuzzysearch (needle, haystack) {
var tlen = haystack.length;
var qlen = needle.length;
if (qlen > tlen) {
return false;
}
if (qlen === tlen) {
return needle === haystack;
}
outer: for (var i = 0, j = 0; i < qlen; i++) {
var nch = needle.charCodeAt(i);
while (j < tlen) {
if (haystack.charCodeAt(j++) === nch) {
continue outer;
}
}
return false;
}
return true;
}
var _$fuzzysearch_1 = fuzzysearch;
'use strict'
/* removed: const _$fuzzysearch_1 = require('fuzzysearch') */;
var _$FuzzySearchStrategy_5 = new FuzzySearchStrategy()
function FuzzySearchStrategy () {
this.matches = function (string, crit) {
return _$fuzzysearch_1(crit.toLowerCase(), string.toLowerCase())
}
}
'use strict'
var _$LiteralSearchStrategy_6 = new LiteralSearchStrategy()
function LiteralSearchStrategy () {
this.matches = function (str, crit) {
if (!str) return false
str = str.trim().toLowerCase()
crit = crit.trim().toLowerCase()
return crit.split(' ').filter(function (word) {
return str.indexOf(word) >= 0
}).length === crit.split(' ').length
}
}
'use strict'
var _$Repository_4 = {
put: put,
clear: clear,
search: search,
setOptions: __setOptions_4
}
/* removed: const _$FuzzySearchStrategy_5 = require('./SearchStrategies/FuzzySearchStrategy') */;
/* removed: const _$LiteralSearchStrategy_6 = require('./SearchStrategies/LiteralSearchStrategy') */;
function NoSort () {
return 0
}
const data = []
let opt = {}
opt.fuzzy = false
opt.limit = 10
opt.searchStrategy = opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = NoSort
opt.exclude = []
function put (data) {
if (isObject(data)) {
return addObject(data)
}
if (isArray(data)) {
return addArray(data)
}
return undefined
}
function clear () {
data.length = 0
return data
}
function isObject (obj) {
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Object]'
}
function isArray (obj) {
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Array]'
}
function addObject (_data) {
data.push(_data)
return data
}
function addArray (_data) {
const added = []
clear()
for (let i = 0, len = _data.length; i < len; i++) {
if (isObject(_data[i])) {
added.push(addObject(_data[i]))
}
}
return added
}
function search (crit) {
if (!crit) {
return []
}
return findMatches(data, crit, opt.searchStrategy, opt).sort(opt.sort)
}
function __setOptions_4 (_opt) {
opt = _opt || {}
opt.fuzzy = _opt.fuzzy || false
opt.limit = _opt.limit || 10
opt.searchStrategy = _opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = _opt.sort || NoSort
opt.exclude = _opt.exclude || []
}
function findMatches (data, crit, strategy, opt) {
const matches = []
for (let i = 0; i < data.length && matches.length < opt.limit; i++) {
const match = findMatchesInObject(data[i], crit, strategy, opt)
if (match) {
matches.push(match)
}
}
return matches
}
function findMatchesInObject (obj, crit, strategy, opt) {
for (const key in obj) {
if (!isExcluded(obj[key], opt.exclude) && strategy.matches(obj[key], crit)) {
return obj
}
}
}
function isExcluded (term, excludedTerms) {
for (let i = 0, len = excludedTerms.length; i < len; i++) {
const excludedTerm = excludedTerms[i]
if (new RegExp(excludedTerm).test(term)) {
return true
}
}
return false
}
/* globals ActiveXObject:false */
'use strict'
var _$JSONLoader_2 = {
load: load
}
function load (location, callback) {
const xhr = getXHR()
xhr.open('GET', location, true)
xhr.onreadystatechange = createStateChangeListener(xhr, callback)
xhr.send()
}
function createStateChangeListener (xhr, callback) {
return function () {
if (xhr.readyState === 4 && xhr.status === 200) {
try {
callback(null, JSON.parse(xhr.responseText))
} catch (err) {
callback(err, null)
}
}
}
}
function getXHR () {
return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
}
'use strict'
var _$OptionsValidator_3 = function OptionsValidator (params) {
if (!validateParams(params)) {
throw new Error('-- OptionsValidator: required options missing')
}
if (!(this instanceof OptionsValidator)) {
return new OptionsValidator(params)
}
const requiredOptions = params.required
this.getRequiredOptions = function () {
return requiredOptions
}
this.validate = function (parameters) {
const errors = []
requiredOptions.forEach(function (requiredOptionName) {
if (typeof parameters[requiredOptionName] === 'undefined') {
errors.push(requiredOptionName)
}
})
return errors
}
function validateParams (params) {
if (!params) {
return false
}
return typeof params.required !== 'undefined' && params.required instanceof Array
}
}
'use strict'
var _$utils_9 = {
merge: merge,
isJSON: isJSON
}
function merge (defaultParams, mergeParams) {
const mergedOptions = {}
for (const option in defaultParams) {
mergedOptions[option] = defaultParams[option]
if (typeof mergeParams[option] !== 'undefined') {
mergedOptions[option] = mergeParams[option]
}
}
return mergedOptions
}
function isJSON (json) {
try {
if (json instanceof Object && JSON.parse(JSON.stringify(json))) {
return true
}
return false
} catch (err) {
return false
}
}
var _$src_8 = {};
(function (window) {
'use strict'
let options = {
searchInput: null,
resultsContainer: null,
json: [],
success: Function.prototype,
searchResultTemplate: '<li><a href="{url}" title="{desc}">{title}</a></li>',
templateMiddleware: Function.prototype,
sortMiddleware: function () {
return 0
},
noResultsText: 'No results found',
limit: 10,
fuzzy: false,
debounceTime: null,
exclude: []
}
let debounceTimerHandle
const debounce = function (func, delayMillis) {
if (delayMillis) {
clearTimeout(debounceTimerHandle)
debounceTimerHandle = setTimeout(func, delayMillis)
} else {
func.call()
}
}
const requiredOptions = ['searchInput', 'resultsContainer', 'json']
/* removed: const _$Templater_7 = require('./Templater') */;
/* removed: const _$Repository_4 = require('./Repository') */;
/* removed: const _$JSONLoader_2 = require('./JSONLoader') */;
const optionsValidator = _$OptionsValidator_3({
required: requiredOptions
})
/* removed: const _$utils_9 = require('./utils') */;
window.SimpleJekyllSearch = function (_options) {
const errors = optionsValidator.validate(_options)
if (errors.length > 0) {
throwError('You must specify the following required options: ' + requiredOptions)
}
options = _$utils_9.merge(options, _options)
_$Templater_7.setOptions({
template: options.searchResultTemplate,
middleware: options.templateMiddleware
})
_$Repository_4.setOptions({
fuzzy: options.fuzzy,
limit: options.limit,
sort: options.sortMiddleware,
exclude: options.exclude
})
if (_$utils_9.isJSON(options.json)) {
initWithJSON(options.json)
} else {
initWithURL(options.json)
}
const rv = {
search: search
}
typeof options.success === 'function' && options.success.call(rv)
return rv
}
function initWithJSON (json) {
_$Repository_4.put(json)
registerInput()
}
function initWithURL (url) {
_$JSONLoader_2.load(url, function (err, json) {
if (err) {
throwError('failed to get JSON (' + url + ')')
}
initWithJSON(json)
})
}
function emptyResultsContainer () {
options.resultsContainer.innerHTML = ''
}
function appendToResultsContainer (text) {
options.resultsContainer.innerHTML += text
}
function registerInput () {
options.searchInput.addEventListener('input', function (e) {
if (isWhitelistedKey(e.which)) {
emptyResultsContainer()
debounce(function () { search(e.target.value) }, options.debounceTime)
}
})
}
function search (query) {
if (isValidQuery(query)) {
emptyResultsContainer()
render(_$Repository_4.search(query), query)
}
}
function render (results, query) {
const len = results.length
if (len === 0) {
return appendToResultsContainer(options.noResultsText)
}
for (let i = 0; i < len; i++) {
results[i].query = query
appendToResultsContainer(_$Templater_7.compile(results[i]))
}
}
function isValidQuery (query) {
return query && query.length > 0
}
function isWhitelistedKey (key) {
return [13, 16, 20, 37, 38, 39, 40, 91].indexOf(key) === -1
}
function throwError (message) {
throw new Error('SimpleJekyllSearch --- ' + message)
}
})(window)
}());
</script>
<!-- Configuration -->
<script>
SimpleJekyllSearch({
searchInput: document.getElementById('search-input'),
resultsContainer: document.getElementById('results-container'),
json: '/search.json',
//searchResultTemplate: '<li><a href="https://static.rnmkcy.eu{url}">{date}&nbsp;{title}</a></li>'
searchResultTemplate: '<li><a href="{url}">{date}&nbsp;{title}</a></li>'
})
</script>
<!-- Fin déclaration champ de recherche --></div><nav class="navigation">
2024-11-28 11:42:23 +01:00
<ul><li class="navigation__item"><a href="/archive.html">Etiquettes</a></li><li class="navigation__item"><a href="/htmldoc.html">Documents</a></li><li class="navigation__item"><a href="/liens_ttrss.html">Liens</a></li><li class="navigation__item"><a href="/syntaxe-markdown.html">Aide</a></li></ul>
2024-10-31 20:18:37 +01:00
</nav></div>
</header>
</div><div class="page__content"><div class ="main"><div class="grid grid--reverse">
<div class="col-main cell cell--auto"><!-- start custom main top snippet --><div id="results-container" class="search-result js-search-result"></div><!-- end custom main top snippet -->
<article itemscope itemtype="http://schema.org/Article"><div class="article__header"><header><h1 style="color:Tomato;">Node.js Stack "bitnami-node" (VirtualBox/PC1)</h1></header></div><meta itemprop="headline" content="Node.js Stack "bitnami-node" (VirtualBox/PC1)"><div class="article__info clearfix"><ul class="left-col menu"><li>
2024-11-08 14:10:33 +01:00
<a class="button button--secondary button--pill button--sm" style="color:#00FFFF" href="/archive.html?tag=virtuel">virtuel</a>
2024-10-31 20:18:37 +01:00
</li></ul><ul class="right-col menu"><li>
<i class="far fa-calendar-alt"></i>&nbsp;<span title="Création" style="color:#FF00FF">25&nbsp;avr.&nbsp;&nbsp;2019</span>
<span title="Modification" style="color:#00FF7F">23&nbsp;mai&nbsp;&nbsp;&nbsp;2019</span></li></ul></div><meta itemprop="datePublished" content="2019-05-23T00:00:00+02:00">
<meta itemprop="keywords" content="virtuel"><div class="js-article-content">
<div class="layout--article"><!-- start custom article top snippet -->
<style>
#myBtn {
display: none;
position: fixed;
bottom: 10px;
right: 10px;
z-index: 99;
font-size: 12px;
font-weight: bold;
border: none;
outline: none;
background-color: white;
color: black;
cursor: pointer;
padding: 5px;
border-radius: 4px;
}
#myBtn:hover {
background-color: #555;
}
</style>
<button onclick="topFunction()" id="myBtn" title="Haut de page">&#8679;</button>
<script>
//Get the button
var mybutton = document.getElementById("myBtn");
// When the user scrolls down 20px from the top of the document, show the button
window.onscroll = function() {scrollFunction()};
function scrollFunction() {
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
mybutton.style.display = "block";
} else {
mybutton.style.display = "none";
}
}
// When the user clicks on the button, scroll to the top of the document
function topFunction() {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
}
</script>
<!-- end custom article top snippet -->
<div class="article__content" itemprop="articleBody"><details>
<summary><b>Afficher/cacher Sommaire</b></summary>
<!-- affichage sommaire -->
<div class="toc-aside js-toc-root"></div>
</details><h1 id="nodejs">NodeJS</h1>
<p><img src="/images/Node_logo.png" alt="" /></p>
<ul>
<li><a href="https://bitnami.com/stack/nodejs/virtual-machine">Bitnami Node.js Stack Virtual Machines</a></li>
<li><a href="https://buzut.net/configurer-node-js-pour-le-serveur/">Configurer Node.js pour le serveur</a></li>
</ul>
<p>Nom du fichier information : <strong>2019-04-25-Node.js_Stack_Virtual_Machine(VirtualBox).md</strong><br />
Machine virtuelle (VirtualBox) : <strong>bitnami-node</strong><br />
Utilisateur : <strong>bitnami</strong><br />
Mot de passe : <strong>bitnami49450</strong><br />
Accès SSH : <strong>ssh bitnami@192.168.0.29</strong><br />
Accès par <a href="http://192.168.0.29">http://192.168.0.29</a> ou <a href="http://nodejs">http://nodejs</a></p>
<h2 id="machine-virtuelle-nodejs-virtualbox">Machine virtuelle (node.js VirtualBox)</h2>
<p><a href="https://bitnami.com/redirect/to/525308/bitnami-node-12.0.0-0-linux-debian-9-x86_64.ova">Télécharger la machine virtuelle Node.js Stack (ova)</a></p>
<p>Vérifier le ckecksum :<br />
MD5 → ff51f348e18893ab04f4dc1e737290f9<br />
SHA1 → 94ca4d4c52d6bb65a77616bac9bbb69b942e40f6<br />
SHA256 → dea3ba9fba328ca68938d925c157a4f58dca07ea3d10a40bb28a5df5d47eb269</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sha1sum bitnami-node-12.0.0-0-linux-debian-9-x86_64.ova
94ca4d4c52d6bb65a77616bac9bbb69b942e40f6 bitnami-node-12.0.0-0-linux-debian-9-x86_64.ova
</code></pre></div></div>
<p>Ouvrir “Oracle VM VirtualBox” → Fichier → Importer un appareil virtuel…</p>
<p><img src="/images/nodejs01.png" alt="" width="600" /></p>
<p><img src="/images/nodejs02.png" alt="" width="600" /></p>
<p><img src="/images/nodejs03.png" alt="" width="600" /></p>
<p>Cliquer sur “Démarrer”</p>
<p><img src="/images/nodejs04.png" alt="" width="600" /></p>
<blockquote>
<p><strong>ATTENTION!!! Clavier en qwerty</strong></p>
</blockquote>
<p>Changer le mot de passe de <strong>bitnami</strong><strong>bitnami49450</strong><br />
Passer em mode su : <code class="language-plaintext highlighter-rouge">sudo -s</code><br />
Installer nano comme éditeur de texte : <code class="language-plaintext highlighter-rouge">apt install nano</code><br />
Installer le paquet pour configurer le clavier fr :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt-get install console-data
</code></pre></div></div>
<p><img src="/images/nodejs05.png" alt="" width="600" /></p>
<p><img src="/images/nodejs06.png" alt="" width="600" /></p>
<p><img src="/images/nodejs07.png" alt="" width="600" /></p>
<p>Relever ladresse ip : <code class="language-plaintext highlighter-rouge">ip a</code> → 192.168.0.29<br />
Effacer le fichier : <code class="language-plaintext highlighter-rouge">rm /etc/ssh/sshd_not_to_be_run</code> pour autoriser laccès par ssh<br />
Activer et lancer ssh</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>systemctl enable ssh
systemctl start ssh
</code></pre></div></div>
<p>Connexion par ssh : <code class="language-plaintext highlighter-rouge">ssh bitnami@192.168.0.29</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
___ _ _ _
| _ |_<span class="o">)</span> |_ _ _ __ _ _ __ <span class="o">(</span>_<span class="o">)</span>
| _ <span class="se">\ </span>| _| <span class="s1">' \/ _` | '</span> <span class="se">\|</span> |
|___/_|<span class="se">\_</span>_|_|_|<span class="se">\_</span>_,_|_|_|_|_|
<span class="k">***</span> Welcome to the Bitnami Node.js 12.0.0-0 <span class="k">***</span>
<span class="k">***</span> Documentation: https://docs.bitnami.com/virtual-machine/infrastructure/nodejs/ <span class="k">***</span>
<span class="k">***</span> https://docs.bitnami.com/virtual-machine/ <span class="k">***</span>
<span class="k">***</span> Bitnami Forums: https://community.bitnami.com/ <span class="k">***</span>
Last login: Thu Apr 25 11:08:14 2019
</code></pre></div></div>
<h3 id="tester-nodejs-avec-un-programme-minimal">Tester Node.js avec un programme minimal</h3>
<p>Pour commencer, ouvrez votre éditeur de texte favori (vim, Emacs, Sublime Text, Notepad++…) et rentrez le code JavaScript suivant :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>console.log('Bienvenue dans Node.js !');
</code></pre></div></div>
<p>Enregistrez votre fichier sous lextension .js. Par exemple test.js.</p>
<p>Ensuite, ouvrez une console dans le dossier où se trouve votre fichier test.js et entrez la commande node test.js. Vous devriez avoir le résultat suivant dans la console :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ node test.js
Bienvenue dans Node.js !
</code></pre></div></div>
<h2 id="application-météo-simple-avec-nodejs">Application météo simple avec Node.js</h2>
<p>Appeler l API OpenWeatherMap.org et à afficher le résultat sur la console. Voici ce dont vous aurez besoin:</p>
<ul>
<li>Compte <strong>OpenWeatherMap.org</strong></li>
<li><strong>Node.js</strong>: Visitez le <a href="https://nodejs.org/en/">site web officiel de Node.js</a> pour télécharger et installer Node.</li>
</ul>
<h3 id="étape-1-openweathermap">Étape 1: OpenWeatherMap</h3>
<p><strong><a href="https://openweathermap.org/api">OpenWeatherMap</a></strong> utilise les API (11 API différentes toutes liées à la météo) auxquelles vous pouvez accéder.<br />
Pour ce projet, nous utiliserons lAPI gratuite «Météo actuelle». Rendez-vous sur <a href="https://openweathermap.org/appid">ce lien</a> et créez un compte. Tout ce dont vous avez besoin est une adresse email et un mot de passe.<br />
Une fois connecté, sélectionnez longlet <strong>API keys</strong> (Clés API) . À partir de là, vous pouvez créer une clé sur le côté droit de la page. Entrez un nom (tout fonctionne) et sélectionnez générer. Votre clé API apparaîtra à gauche. Copiez cette clé pour plus tard.</p>
<h3 id="étape-2-configuration-du-projet">Étape 2: Configuration du projet</h3>
<p>1-Créez un répertoire vide nommé “node-weather” et exécutez:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir node-weather
cd node-weather
npm init
</code></pre></div></div>
<p>2-Remplissez les informations requises pour initialiser le projet.<br />
Le fichier package.json après linitialisation du projet.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{
"name": "nodejs-weather-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \\\" Erreur: aucun test spécifié \\ \"&amp;&amp; exit 1"
},
"author": "yann",
"license": "ISC"
}
</code></pre></div></div>
<p>3-Créez un fichier nommé <strong>index.js</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>touch index.js
</code></pre></div></div>
<p>ce fichier hébergera le code de notre application.</p>
<p>Maintenant que nous avons toutes les pièces, on commence à construire!</p>
<h3 id="faire-lappel-api">Faire lappel API</h3>
<p>Pour faire notre appel API, nous utiliserons un module npm populaire appelé request . request a des millions de téléchargements et est un module qui simplifie le code nécessaire pour effectuer une requête http dans un nœud.</p>
<p>Demande dinstallation en exécutant:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm install request --save
</code></pre></div></div>
<p>Comme je lai dit, la demande est assez facile à utiliser. Nous avons juste besoin de transmettre notre URL cible, et request renvoie une fonction de rappel. Notre code de démarrage ressemble à ceci:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">request</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">request</span><span class="dl">'</span><span class="p">);</span>
<span class="nf">request</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">response</span><span class="p">,</span> <span class="nx">body</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nx">err</span><span class="p">){</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">error:</span><span class="dl">'</span><span class="p">,</span> <span class="nx">error</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">body:</span><span class="dl">'</span><span class="p">,</span> <span class="nx">body</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
</code></pre></div></div>
<p>Permet de décomposer ce code:</p>
<ol>
<li>Nous avons besoin du paquet de demande</li>
<li>Nous passons dans une URL et request renvoie une fonction de rappel avec trois arguments: <em>err</em> , <em>response</em> et <em>body</em></li>
<li>Nous vérifions sil y a une erreur dans notre demande. Sil y en a une, nous enregistrons lerreur et nous avons terminé.</li>
<li>Sil ny a pas derreur, nous enregistrons tout le contenu du corps de la réponse.</li>
</ol>
<p><strong>Alors quelle est lURL à laquelle nous faisons la demande?</strong></p>
<p>En lisant la documentation OpenWeatherMap, nous sommes en mesure de déterminer lURL à laquelle nous devons adresser nos demandes: <a href="http://api.openweathermap.org/data/2.5/weather">http://api.openweathermap.org/data/2.5/weather</a><br />
LURL contient également deux paramètres de requête obligatoires.<br />
Les paramètres de requête sont des paires clé/valeur qui nous permettent de transmettre des données à une URL<br />
Dans ce cas, nous devons inclure la ville que nous recherchons et notre clé API.</p>
<p>Voici à quoi ressemblera le code:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">apiKey</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">****************************</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">city</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">portland</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">url</span> <span class="o">=</span> <span class="s2">`http://api.openweathermap.org/data/2.5/weather?q=</span><span class="p">${</span><span class="nx">city</span><span class="p">}</span><span class="s2">&amp;appid=</span><span class="p">${</span><span class="nx">apiKey</span><span class="p">}</span><span class="s2">`</span>
</code></pre></div></div>
<p>Nous avons fait 3 choses ci-dessus:</p>
<ol>
<li>Créez une variable nommée <strong>apiKey</strong> et lui assignez la clé API OpenWeatherMap</li>
<li>Créez une variable <strong>city</strong> et lui attribuez une valeur chaîne de la ville à tester</li>
<li>Créez une variable nommée <strong>url</strong> et attribuez-lui lurl OpenWeatherMap avec nos deux paramètres de requête requis. Notez que les paramètres de requête commencent par un ? point dinterrogation. Ils sont ensuite indiqués avec des paires clé / valeur séparées par un signe = égal. Différentes paires clé / valeur sont séparées par un &amp; esperluette.</li>
</ol>
<p>Voici le code:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano index.js
</code></pre></div></div>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">request</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">request</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">let</span> <span class="nx">apiKey</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">*****************************</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">city</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">portland</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">url</span> <span class="o">=</span> <span class="s2">`http://api.openweathermap.org/data/2.5/weather?q=</span><span class="p">${</span><span class="nx">city</span><span class="p">}</span><span class="s2">&amp;appid=</span><span class="p">${</span><span class="nx">apiKey</span><span class="p">}</span><span class="s2">`</span>
<span class="nf">request</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">response</span><span class="p">,</span> <span class="nx">body</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nx">err</span><span class="p">){</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">error:</span><span class="dl">'</span><span class="p">,</span> <span class="nx">error</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">body:</span><span class="dl">'</span><span class="p">,</span> <span class="nx">body</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
</code></pre></div></div>
<p>Nous pouvons maintenant exécuter notre code dans la console en tapant:</p>
<p>noeud index.js</p>
<p>est renvoyé le texte suivant:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>body: {"coord":{"lon":-122.67,"lat":45.52},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"base":"stations","main":{"temp":278.95,"pressure":1021,"humidity":66,"temp_min":275.93,"temp_max":282.15},"visibility":16093,"wind":{"speed":2.1,"deg":340},"clouds":{"all":1},"dt":1556196456,"sys":{"type":1,"id":5321,"message":0.0096,"country":"US","sunrise":1556197688,"sunset":1556248130},"id":5746545,"name":"Portland","cod":200}
</code></pre></div></div>
<p>Ça marche! Comme vous pouvez le constater, nous avons envoyé avec succès une demande à lAPI dOpenWeatherMap et récupéré les données suivantes. Il y a beaucoup de bonnes informations éparpillées: je vois la température, lhumidité et la vitesse du vent pour nen nommer que quelques-unes.</p>
<blockquote>
<p>IMPORTANT: Dans les prochains tutoriels, je vous montrerai comment masquer votre clé API à laide de variables denvironnement . Pour linstant, sachez quil nest pas standard que votre clé API soit exposée de la sorte.</p>
</blockquote>
<h3 id="améliorer-la-réponse">Améliorer la réponse</h3>
<p>La première chose à faire est de convertir le texte renvoyé (appelé JSON) en un objet JavaScript. (JavaScript Object Notation) est un moyen de stocker des informations de manière organisée et facile daccès - cela ressemble à un objet JavaScript avec des guillemets supplémentaires.</p>
<p>Nous pouvons effectuer cette conversion avec une seule ligne de code:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>let weather = JSON.parse(body)
</code></pre></div></div>
<p>Maintenant que nous avons un objet JavaScript, nous pouvons accéder aux données de cet objet avec une notation par points ou par crochets. Ci-dessous, nous construisons une chaîne de message en accédant aux données de notre objet météo:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">message</span> <span class="o">=</span> <span class="s2">`It's </span><span class="p">${</span><span class="nx">weather</span><span class="p">.</span><span class="nx">main</span><span class="p">.</span><span class="nx">temp</span><span class="p">}</span><span class="s2"> degrees in
</span><span class="p">${</span><span class="nx">weather</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2">!`</span><span class="p">;</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">message</span><span class="p">);</span>
</code></pre></div></div>
<p>Si nous devions exécuter notre application à ce stade, nous aurions:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>node index.js
</code></pre></div></div>
<p>→ Its 300.4 degrees in Portland</p>
<p>OpenWeatherMap modifie sa température par défaut à Kelvin. Nous devons donc ajouter un autre paramètre de requête.</p>
<ul>
<li><strong>Celsius</strong>, vous ajouterez: <strong>units=metric</strong></li>
<li><strong>Fahrenheit</strong>, vous utiliserez <strong>units=imperial</strong> .</li>
</ul>
<p>Maintenant si nous exécutons:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nodeindex.js
</code></pre></div></div>
<p>→ Its 23.39 degrees in Portland!</p>
<p>Voici le code à ce stade:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">request</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">request</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">let</span> <span class="nx">apiKey</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">***********************************</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">city</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">portland</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">url</span> <span class="o">=</span> <span class="s2">`http://api.openweathermap.org/data/2.5/weather?q=</span><span class="p">${</span><span class="nx">city</span><span class="p">}</span><span class="s2">&amp;units=metric&amp;appid=</span><span class="p">${</span><span class="nx">apiKey</span><span class="p">}</span><span class="s2">`</span>
<span class="nf">request</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">response</span><span class="p">,</span> <span class="nx">body</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nx">err</span><span class="p">){</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">error:</span><span class="dl">'</span><span class="p">,</span> <span class="nx">error</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">weather</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="nx">body</span><span class="p">)</span>
<span class="kd">let</span> <span class="nx">message</span> <span class="o">=</span> <span class="s2">`It's </span><span class="p">${</span><span class="nx">weather</span><span class="p">.</span><span class="nx">main</span><span class="p">.</span><span class="nx">temp</span><span class="p">}</span><span class="s2"> degrees in </span><span class="p">${</span><span class="nx">weather</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2">!`</span><span class="p">;</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">message</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
</code></pre></div></div>
<h3 id="ajouter-de-linteractivité">Ajouter de linteractivité</h3>
<p>Nous avons uniquement accès au climat à Portland, Oregon.Pour ajouter une interactivité nous utiliserons des <a href="https://www.npmjs.com/package/yargs">“yargs”</a> . Yargs est un outil dinterface interactif qui permet de définir des variables à partir de la ligne de commande.</p>
<p>Installez yargs avec:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm install yargs --save
</code></pre></div></div>
<p>Yargs fonctionne en exposant toutes les variables que nous utilisons dans la console sur lobjet argv . Nous configurons et accédons à cet objet comme suit:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>const argv = require('yargs').argv;
</code></pre></div></div>
<p>Nous utiliserons le drapeau “c” comme ville:<br />
<em>Si notre variable <strong>city</strong> est égale à <strong>argv.c</strong> OU si aucune variable nest entrée, nous aurons une valeur de ville par défaut de Portland</em></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>let city = argv.c || 'portland';
</code></pre></div></div>
<p>Maintenant, pour exécuter lapplication, au lieu de simplement dire:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>node index.js
</code></pre></div></div>
<p>Nous devons passer une variable nommée <strong>“c”</strong> comme ceci:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>node index.js -c Boston
</code></pre></div></div>
<p>→ Its 30.39 degrees in Boston!</p>
<p>Nous utilisons un drapeau pour indiquer que nous passons dans la variable. Puisque nous configurons notre variable comme étant la lettre <strong>“c”</strong> nous passons dans notre variable avec <strong>“-c”</strong> . Après un espace, nous pouvons utiliser nimporte quel nom de ville!</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>node index.js -c Anchorage
</code></pre></div></div>
<p>Voici le code à ce stade:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">request</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">request</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">argv</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">yargs</span><span class="dl">'</span><span class="p">).</span><span class="nx">argv</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">apiKey</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">*****************************</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">city</span> <span class="o">=</span> <span class="nx">argv</span><span class="p">.</span><span class="nx">c</span> <span class="o">||</span> <span class="dl">'</span><span class="s1">portland</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">url</span> <span class="o">=</span> <span class="s2">`http://api.openweathermap.org/data/2.5/weather?q=</span><span class="p">${</span><span class="nx">city</span><span class="p">}</span><span class="s2">&amp;units=metric&amp;appid=</span><span class="p">${</span><span class="nx">apiKey</span><span class="p">}</span><span class="s2">`</span>
<span class="nf">request</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">response</span><span class="p">,</span> <span class="nx">body</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nx">err</span><span class="p">){</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">error:</span><span class="dl">'</span><span class="p">,</span> <span class="nx">error</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">weather</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="nx">body</span><span class="p">)</span>
<span class="kd">let</span> <span class="nx">message</span> <span class="o">=</span> <span class="s2">`It's </span><span class="p">${</span><span class="nx">weather</span><span class="p">.</span><span class="nx">main</span><span class="p">.</span><span class="nx">temp</span><span class="p">}</span><span class="s2"> degrees in </span><span class="p">${</span><span class="nx">weather</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2">!`</span><span class="p">;</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">message</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
</code></pre></div></div>
<h2 id="site-web-météo-nodejs--express--openweather">Site Web météo (Node.js + Express + OpenWeather)</h2>
<h3 id="nécessité-dun-proxy-nginx">Nécessité dun proxy nginx</h3>
<p>Pour un accès web extérieur ,il faut utiliser un proxy <br />
Installer nginx et loutil tree</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install nginx tree
</code></pre></div></div>
<p>Configurer le proxy</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /etc/nginx/sites-enabled/default
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
location / {
proxy_pass http://localhost:3000;
}
}
</code></pre></div></div>
<p>Vérifier et relancer nginx</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nginx -t
sudo systemctl restart nginx
</code></pre></div></div>
<p>Accès par http://192.168.0.29<br />
Si vous ajoutez à /etc/hosts du PC1 la ligne suivante<br />
<code class="language-plaintext highlighter-rouge">192.168.0.29 nodejs</code><br />
Laccès se fera via http://nodejs</p>
<h3 id="configuration-du-projet">Configuration du projet</h3>
<p>Le code de ce projet se trouve dans le <a href="https://github.com/bmorelli25/simple-nodejs-weather-app">Repo GitHub</a></p>
<ol>
<li>Créez un répertoire vide nommé <strong>weather-app</strong> , <code class="language-plaintext highlighter-rouge">mkdir ~/weather-app</code></li>
<li>Ouvrez votre console, accédez à notre nouveau répertoire et exécutez <code class="language-plaintext highlighter-rouge">npm init</code> .</li>
<li>Remplissez les informations requises pour initialiser le projet.</li>
<li>Dans notre répertoire weather-app , créez un fichier nommé server.js : <code class="language-plaintext highlighter-rouge">touch server.js</code><br />
Ce fichier hébergera le code de notre application.</li>
</ol>
<p>le fichier /home/bitnami/weather-app/package.json:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{
"name": "web-weather-app",
"version": "1.0.0",
"description": "application web météo",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" &amp;&amp; exit 1"
},
"author": "yann",
"license": "ISC"
}
</code></pre></div></div>
<h3 id="création-du-serveur-express-js">Création du serveur (Express JS)</h3>
<p>Express est un framework Web minimaliste pour Node.js. Express facilite grandement la création et lexécution dun serveur Web avec Node.</p>
<p>Pour utiliser express, installez-le dans la console:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm install --save express
</code></pre></div></div>
<p>Une fois installé, nous allons copier lapplication de démarrage boilerplate Express à partir de la <a href="https://expressjs.com/en/starter/hello-world.html">documentation Express</a> :</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">express</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">express</span><span class="dl">'</span><span class="p">)</span>
<span class="kd">const</span> <span class="nx">app</span> <span class="o">=</span> <span class="nf">express</span><span class="p">()</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">res</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="dl">'</span><span class="s1">Hello World!</span><span class="dl">'</span><span class="p">)</span>
<span class="p">})</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">listen</span><span class="p">(</span><span class="mi">3000</span><span class="p">,</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Example app listening on port 3000!</span><span class="dl">'</span><span class="p">)</span>
<span class="p">})</span>
</code></pre></div></div>
<p>Vous trouverez ci-dessus un exemple dapplication la plus simple que nous puissions créer avec Express. Nous avons dabord besoin du paquet express qui vient dêtre installé. Ensuite, nous créons une instance nommée app en appelant Express.</p>
<p><strong>app.get(/’…</strong> signifie que nous nous concentrons spécifiquement sur lURL racine ( / ). Si nous visitons lURL racine, Express répondra par «Hello World!».<br />
<strong>app.listen(…</strong> indique que nous créons un serveur qui écoute sur le port 3000 pour les connexions.</p>
<p>Nous pouvons tester notre serveur en exécutant:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>node server.js
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Example app listening on port 3000!
</code></pre></div></div>
<p>Maintenant, ouvrez votre navigateur et visitez: localhost:3000 et vous devriez voir Hello World!<br />
Si proxy , http://192.168.0.29 ou http://nodejs</p>
<p>Impressionnant! Vous venez de créer un serveur avec Node.js et Express!
Configuration de la vue dindex</p>
<p>Au lieu de répondre avec du texte lorsque quelquun visite notre route racine, nous aimerions répondre avec un fichier HTML. Pour cela, nous utiliserons EJS ( <a href="http://www.embeddedjs.com/">Embedded Javascript [JavaScript incorporé] </a>). EJS est un langage de template.</p>
<p>Pour utiliser EJS dans Express, nous devons configurer notre <strong>template engine</strong> (moteur de modèle):</p>
<blockquote>
<p><em>Un <strong>template engine</strong> (moteur de modèle) vous permet dutiliser des fichiers de modèle statiques dans votre application. Au moment de lexécution, le moteur de modèle remplace les variables dun fichier de modèle par les valeurs réelles et transforme le modèle en un fichier HTML envoyé au client. Cette approche facilite la conception dune page HTML.</em></p>
</blockquote>
<p>EJS nous permet dinteragir avec des variables et de créer dynamiquement notre code HTML à partir de ces variables!</p>
<p>Tout dabord, nous allons installer ejs dans le terminal:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm install ejs --save
</code></pre></div></div>
<p>Nous pouvons ensuite configurer notre moteur de template avec cette ligne de code (juste en dessous de nos instructions require) dans notre fichier server.js :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>app.set('view engine', 'ejs')
</code></pre></div></div>
<p>EJS est accessible par défaut dans le répertoire <strong>views</strong> . Créez donc un nouveau dossier nommé views dans votre répertoire. Dans ce dossier de views , ajoutez un fichier nommé index.ejs . Considérez notre fichier index.ejs comme un fichier HTML pour le moment.</p>
<p>notre structure de fichiers jusquà présent:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>weather-app/
├── package.json
├── server.js
└── views
└── index.ejs
</code></pre></div></div>
<p>Le fichier index.ejs devrait être assez simple ,cest juste un formulaire avec une entrée pour une ville et un bouton denvoi:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano views/index.ejs
</code></pre></div></div>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;!DOCTYPE html&gt;</span>
<span class="nt">&lt;html&gt;</span>
<span class="nt">&lt;head&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">charset=</span><span class="s">"utf-8"</span><span class="nt">&gt;</span>
<span class="nt">&lt;title&gt;</span>Test<span class="nt">&lt;/title&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">type=</span><span class="s">"text/css"</span> <span class="na">href=</span><span class="s">"/css/style.css"</span><span class="nt">&gt;</span>
<span class="nt">&lt;link</span> <span class="na">href=</span><span class="s">'https://fonts.googleapis.com/css?family=Open+Sans:300'</span> <span class="na">rel=</span><span class="s">'stylesheet'</span> <span class="na">type=</span><span class="s">'text/css'</span><span class="nt">&gt;</span>
<span class="nt">&lt;/head&gt;</span>
<span class="nt">&lt;body&gt;</span>
<span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"container"</span><span class="nt">&gt;</span>
<span class="nt">&lt;fieldset&gt;</span>
<span class="nt">&lt;form</span> <span class="na">action=</span><span class="s">"/"</span> <span class="na">method=</span><span class="s">"post"</span><span class="nt">&gt;</span>
<span class="nt">&lt;input</span> <span class="na">name=</span><span class="s">"city"</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">class=</span><span class="s">"ghost-input"</span> <span class="na">placeholder=</span><span class="s">"Enter a City"</span> <span class="na">required</span><span class="nt">&gt;</span>
<span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"submit"</span> <span class="na">class=</span><span class="s">"ghost-button"</span> <span class="na">value=</span><span class="s">"Get Weather"</span><span class="nt">&gt;</span>
<span class="nt">&lt;/form&gt;</span>
<span class="nt">&lt;/fieldset&gt;</span>
<span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;/body&gt;</span>
<span class="nt">&lt;/html&gt;</span>
</code></pre></div></div>
<p>Une fois que le code ci-dessus est copié dans votre fichier <strong>index.ejs</strong> , vous avez presque terminé!<br />
La dernière chose à faire est de remplacer notre code <em>app.get</em> dans le fichier <strong>server.js</strong> :</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">app</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// OLD CODE</span>
<span class="nx">res</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="dl">'</span><span class="s1">Hello World!</span><span class="dl">'</span><span class="p">)</span>
<span class="p">})</span>
</code></pre></div></div>
<p>Ci-dessus lancien code où nous envoyons le texte “Hello World!” au client. Au lieu de cela, nous voulons envoyer notre fichier <strong>index.ejs</strong> :</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">app</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">res</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span><span class="dl">'</span><span class="s1">index</span><span class="dl">'</span><span class="p">);</span>
<span class="p">})</span>
</code></pre></div></div>
<p>Au lieu dutiliser <em>res.send</em> , nous utilisons <em>res.render</em> lorsque nous travaillons avec un langage de template.<br />
<em>res.render</em> rendra notre vue, puis enverra le code HTML équivalent au client.</p>
<p>Le fichier server.js</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">express</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">express</span><span class="dl">'</span><span class="p">)</span>
<span class="kd">const</span> <span class="nx">app</span> <span class="o">=</span> <span class="nf">express</span><span class="p">()</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">set</span><span class="p">(</span><span class="dl">'</span><span class="s1">view engine</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">ejs</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">res</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span><span class="dl">'</span><span class="s1">index</span><span class="dl">'</span><span class="p">);</span>
<span class="p">})</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">listen</span><span class="p">(</span><span class="mi">3000</span><span class="p">,</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Example app listening on port 3000!</span><span class="dl">'</span><span class="p">)</span>
<span class="p">})</span>
</code></pre></div></div>
<p>tester à nouveau en exécutant:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>node server.js
</code></pre></div></div>
<p>// Example app listening on port 3000!</p>
<p>Ouvrez maintenant votre navigateur et visitez: localhost:3000 (http://nodejs) et vous devriez voir notre fichier index.ejs être affiché!</p>
<p><img src="/images/nodejs08.png" alt="" /></p>
<h3 id="ajouter-fichier-css">Ajouter fichier CSS</h3>
<p>Le vôtre sera un peu moins “joli” que le mien. Cest parce que je me sers dun fichier CSS pour styliser mon HTML. Voici comment nous faisons fonctionner notre CSS:</p>
<p>Vous devrez ajouter un nouveau dossier à notre projet appelé public . Dans ce dossier, créez un dossier css , puis un fichier nommé style.css .</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir -p ~/weather-app/public/css
touch ~/weather-app/public/css/style.css
</code></pre></div></div>
<p>nouvelle structure de fichier:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>weather-app/
├── package.json
├── public
│   └── css
├── server.js
└── views
└── index.ejs
</code></pre></div></div>
<p>Express nautorisera pas laccès à ce fichier par défaut. Nous devons donc lattribuer avec la ligne de code suivante:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>app.use(express.static('public'));
</code></pre></div></div>
<p>Ce code nous permet daccéder à tous les fichiers statiques du dossier “public”.</p>
<p>Le fichier CSS <strong>~/weather-app/public/css/style.css</strong></p>
<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">/*
Styles from this codepen:
https://codepen.io/official_naveen/pen/rgknI
*/</span>
<span class="nt">body</span> <span class="p">{</span>
<span class="nl">width</span><span class="p">:</span> <span class="m">800px</span><span class="p">;</span>
<span class="nl">margin</span><span class="p">:</span> <span class="m">0</span> <span class="nb">auto</span><span class="p">;</span>
<span class="nl">font-family</span><span class="p">:</span> <span class="s2">'Open Sans'</span><span class="p">,</span> <span class="nb">sans-serif</span><span class="p">;</span>
<span class="p">}</span>
<span class="nc">.container</span> <span class="p">{</span>
<span class="nl">width</span><span class="p">:</span> <span class="m">600px</span><span class="p">;</span>
<span class="nl">margin</span><span class="p">:</span> <span class="m">0</span> <span class="nb">auto</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">fieldset</span> <span class="p">{</span>
<span class="nl">display</span><span class="p">:</span> <span class="nb">block</span><span class="p">;</span>
<span class="nl">-webkit-margin-start</span><span class="p">:</span> <span class="m">0px</span><span class="p">;</span>
<span class="nl">-webkit-margin-end</span><span class="p">:</span> <span class="m">0px</span><span class="p">;</span>
<span class="nl">-webkit-padding-before</span><span class="p">:</span> <span class="m">0em</span><span class="p">;</span>
<span class="nl">-webkit-padding-start</span><span class="p">:</span> <span class="m">0em</span><span class="p">;</span>
<span class="nl">-webkit-padding-end</span><span class="p">:</span> <span class="m">0em</span><span class="p">;</span>
<span class="nl">-webkit-padding-after</span><span class="p">:</span> <span class="m">0em</span><span class="p">;</span>
<span class="nl">border</span><span class="p">:</span> <span class="m">0px</span><span class="p">;</span>
<span class="nl">border-image-source</span><span class="p">:</span> <span class="n">initial</span><span class="p">;</span>
<span class="nl">border-image-slice</span><span class="p">:</span> <span class="n">initial</span><span class="p">;</span>
<span class="nl">border-image-width</span><span class="p">:</span> <span class="n">initial</span><span class="p">;</span>
<span class="nl">border-image-outset</span><span class="p">:</span> <span class="n">initial</span><span class="p">;</span>
<span class="nl">border-image-repeat</span><span class="p">:</span> <span class="n">initial</span><span class="p">;</span>
<span class="nl">min-width</span><span class="p">:</span> <span class="n">-webkit-min-content</span><span class="p">;</span>
<span class="nl">padding</span><span class="p">:</span> <span class="m">30px</span><span class="p">;</span>
<span class="p">}</span>
<span class="nc">.ghost-input</span><span class="o">,</span> <span class="nt">p</span> <span class="p">{</span>
<span class="nl">display</span><span class="p">:</span> <span class="nb">block</span><span class="p">;</span>
<span class="nl">font-weight</span><span class="p">:</span><span class="m">300</span><span class="p">;</span>
<span class="nl">width</span><span class="p">:</span> <span class="m">100%</span><span class="p">;</span>
<span class="nl">font-size</span><span class="p">:</span> <span class="m">25px</span><span class="p">;</span>
<span class="nl">border</span><span class="p">:</span><span class="m">0px</span><span class="p">;</span>
<span class="nl">outline</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
<span class="nl">width</span><span class="p">:</span> <span class="m">100%</span><span class="p">;</span>
<span class="nl">-webkit-box-sizing</span><span class="p">:</span> <span class="n">border-box</span><span class="p">;</span>
<span class="nl">-moz-box-sizing</span><span class="p">:</span> <span class="n">border-box</span><span class="p">;</span>
<span class="nl">box-sizing</span><span class="p">:</span> <span class="n">border-box</span><span class="p">;</span>
<span class="nl">color</span><span class="p">:</span> <span class="m">#4b545f</span><span class="p">;</span>
<span class="nl">background</span><span class="p">:</span> <span class="m">#fff</span><span class="p">;</span>
<span class="nl">font-family</span><span class="p">:</span> <span class="n">Open</span> <span class="n">Sans</span><span class="p">,</span><span class="n">Verdana</span><span class="p">;</span>
<span class="nl">padding</span><span class="p">:</span> <span class="m">10px</span> <span class="m">15px</span><span class="p">;</span>
<span class="nl">margin</span><span class="p">:</span> <span class="m">30px</span> <span class="m">0px</span><span class="p">;</span>
<span class="nl">-webkit-transition</span><span class="p">:</span> <span class="n">all</span> <span class="m">0.1s</span> <span class="n">ease-in-out</span><span class="p">;</span>
<span class="nl">-moz-transition</span><span class="p">:</span> <span class="n">all</span> <span class="m">0.1s</span> <span class="n">ease-in-out</span><span class="p">;</span>
<span class="nl">-ms-transition</span><span class="p">:</span> <span class="n">all</span> <span class="m">0.1s</span> <span class="n">ease-in-out</span><span class="p">;</span>
<span class="nl">-o-transition</span><span class="p">:</span> <span class="n">all</span> <span class="m">0.1s</span> <span class="n">ease-in-out</span><span class="p">;</span>
<span class="nl">transition</span><span class="p">:</span> <span class="n">all</span> <span class="m">0.1s</span> <span class="n">ease-in-out</span><span class="p">;</span>
<span class="p">}</span>
<span class="nc">.ghost-input</span><span class="nd">:focus</span> <span class="p">{</span>
<span class="nl">border-bottom</span><span class="p">:</span><span class="m">1px</span> <span class="nb">solid</span> <span class="m">#ddd</span><span class="p">;</span>
<span class="p">}</span>
<span class="nc">.ghost-button</span> <span class="p">{</span>
<span class="nl">background-color</span><span class="p">:</span> <span class="nb">transparent</span><span class="p">;</span>
<span class="nl">border</span><span class="p">:</span><span class="m">2px</span> <span class="nb">solid</span> <span class="m">#ddd</span><span class="p">;</span>
<span class="nl">padding</span><span class="p">:</span><span class="m">10px</span> <span class="m">30px</span><span class="p">;</span>
<span class="nl">width</span><span class="p">:</span> <span class="m">100%</span><span class="p">;</span>
<span class="nl">min-width</span><span class="p">:</span> <span class="m">350px</span><span class="p">;</span>
<span class="nl">-webkit-transition</span><span class="p">:</span> <span class="n">all</span> <span class="m">0.1s</span> <span class="n">ease-in-out</span><span class="p">;</span>
<span class="nl">-moz-transition</span><span class="p">:</span> <span class="n">all</span> <span class="m">0.1s</span> <span class="n">ease-in-out</span><span class="p">;</span>
<span class="nl">-ms-transition</span><span class="p">:</span> <span class="n">all</span> <span class="m">0.1s</span> <span class="n">ease-in-out</span><span class="p">;</span>
<span class="nl">-o-transition</span><span class="p">:</span> <span class="n">all</span> <span class="m">0.1s</span> <span class="n">ease-in-out</span><span class="p">;</span>
<span class="nl">transition</span><span class="p">:</span> <span class="n">all</span> <span class="m">0.1s</span> <span class="n">ease-in-out</span><span class="p">;</span>
<span class="p">}</span>
<span class="nc">.ghost-button</span><span class="nd">:hover</span> <span class="p">{</span>
<span class="nl">border</span><span class="p">:</span><span class="m">2px</span> <span class="nb">solid</span> <span class="m">#515151</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">p</span> <span class="p">{</span>
<span class="nl">color</span><span class="p">:</span> <span class="m">#E64A19</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Mise en place de notre route POST</p>
<p>Le fichier <strong>~/weather-app/server.js</strong> :</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">express</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">express</span><span class="dl">'</span><span class="p">)</span>
<span class="kd">const</span> <span class="nx">app</span> <span class="o">=</span> <span class="nf">express</span><span class="p">()</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">use</span><span class="p">(</span><span class="nx">express</span><span class="p">.</span><span class="nf">static</span><span class="p">(</span><span class="dl">'</span><span class="s1">public</span><span class="dl">'</span><span class="p">));</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">set</span><span class="p">(</span><span class="dl">'</span><span class="s1">view engine</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">ejs</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">res</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span><span class="dl">'</span><span class="s1">index</span><span class="dl">'</span><span class="p">);</span>
<span class="p">})</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">listen</span><span class="p">(</span><span class="mi">3000</span><span class="p">,</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Example app listening on port 3000!</span><span class="dl">'</span><span class="p">)</span>
<span class="p">})</span>
</code></pre></div></div>
<p>Nous avons un itinéraire “get” sur la racine <em>app.get(/’…</em> , puis nous créons notre serveur<em>app.listen(3000…</em>.<br />
Cependant, pour que notre application fonctionne, nous avons également besoin dun itinéraire “post”.<br />
Dans le fichier <strong>index.ejs</strong> , vous pouvez voir que notre formulaire envoie une demande de publication (post request) à la racine ( / ):</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;form</span> <span class="na">action=</span><span class="s">"/"</span> <span class="na">method=</span><span class="s">"post"</span><span class="nt">&gt;</span>
</code></pre></div></div>
<p>Maintenant que nous savons où notre formulaire est affiché, nous pouvons configurer litinéraire! Une demande de publication (post request) ressemble à une demande dobtention (get request), avec une modification mineure:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">app</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">res</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span><span class="dl">'</span><span class="s1">index</span><span class="dl">'</span><span class="p">);</span>
<span class="p">})</span>
</code></pre></div></div>
<p>Mais au lieu de simplement répondre avec le même modèle html, il faut accéder également au nom de la ville saisie par lutilisateur. Pour cela, nous devons utiliser un <em>Express Middleware</em> .</p>
<p>Express est un cadre minimaliste. Cependant, nous pouvons utiliser un Middleware (fonctions qui ont accès aux corps de req et de res ) afin de réaliser des tâches plus avancées.</p>
<p>Nous allons utiliser le middleware <em>body-parser</em> . <em>body-parser</em> nous permet dutiliser les paires clé-valeur stockées sur lobjet <em>req-body</em> . Dans ce cas, nous pourrons accéder au nom de la ville saisie par lutilisateur du côté client.</p>
<p>Pour utiliser <em>body-parser</em> , il faut dabord linstaller:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm install body-parser --save
</code></pre></div></div>
<p>Une fois installé, pour utiliser notre middleware ajoutez les 2 lignes de code au fichier <strong>server.js</strong></p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">bodyParser</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">body-parser</span><span class="dl">'</span><span class="p">);</span>
<span class="c1">// ...</span>
<span class="c1">// ...</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">use</span><span class="p">(</span><span class="nx">bodyParser</span><span class="p">.</span><span class="nf">urlencoded</span><span class="p">({</span> <span class="na">extended</span><span class="p">:</span> <span class="kc">true</span> <span class="p">}));</span>
</code></pre></div></div>
<p>Sachez simplement quen utilisant <em>body-parser</em> nous pouvons utiliser lobjet <em>req.body</em></p>
<p>Enfin, nous pouvons maintenant mettre à jour notre demande de publication pour consigner la valeur de <strong>city</strong> (ville) dans la console.</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">app</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">res</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span><span class="dl">'</span><span class="s1">index</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">city</span><span class="p">);</span>
<span class="p">})</span>
</code></pre></div></div>
<p>test !</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>node server.js
Example app listening on port 3000!
</code></pre></div></div>
<p>Ouvrez maintenant votre navigateur et visitez: localhost:3000 , tapez un nom de ville dans le champ et appuyez sur Entrée!</p>
<p>Si vous revenez à votre invite de commande, vous devriez voir le nom de la ville affiché dans linvite!</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>node server.js
Example app listening on port 3000!
paris
</code></pre></div></div>
<p>Vous avez maintenant passé avec succès les données du client au serveur!</p>
<p>Le fichier server.js :</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">express</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">express</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">bodyParser</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">body-parser</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">app</span> <span class="o">=</span> <span class="nf">express</span><span class="p">()</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">use</span><span class="p">(</span><span class="nx">express</span><span class="p">.</span><span class="nf">static</span><span class="p">(</span><span class="dl">'</span><span class="s1">public</span><span class="dl">'</span><span class="p">));</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">use</span><span class="p">(</span><span class="nx">bodyParser</span><span class="p">.</span><span class="nf">urlencoded</span><span class="p">({</span> <span class="na">extended</span><span class="p">:</span> <span class="kc">true</span> <span class="p">}));</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">set</span><span class="p">(</span><span class="dl">'</span><span class="s1">view engine</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">ejs</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">res</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span><span class="dl">'</span><span class="s1">index</span><span class="dl">'</span><span class="p">);</span>
<span class="p">})</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">city</span><span class="p">);</span>
<span class="nx">res</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span><span class="dl">'</span><span class="s1">index</span><span class="dl">'</span><span class="p">);</span>
<span class="p">})</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">listen</span><span class="p">(</span><span class="mi">3000</span><span class="p">,</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Example app listening on port 3000!</span><span class="dl">'</span><span class="p">)</span>
<span class="p">})</span>
</code></pre></div></div>
<h3 id="finition-apppost">Finition app.post</h3>
<p>Pour terminer le projet,on utilise le code de <a href="#application-météo-simple-avec-nodejs">Application météo simple avec Node.js</a><br />
Ce que nous allions faire, cest faire une demande à lAPI OpenWeatherMap dans notre demande <strong>app.post</strong><br />
Voici à quoi ressemble le code:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">request</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">request</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">apiKey</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">*****************</span><span class="dl">'</span><span class="p">;</span>
<span class="c1">//...</span>
<span class="c1">//...</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">city</span> <span class="o">=</span> <span class="nx">req</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">city</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">url</span> <span class="o">=</span> <span class="s2">`http://api.openweathermap.org/data/2.5/weather?q=</span><span class="p">${</span><span class="nx">city</span><span class="p">}</span><span class="s2">&amp;units=imperial&amp;appid=</span><span class="p">${</span><span class="nx">apiKey</span><span class="p">}</span><span class="s2">`</span>
<span class="nf">request</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">response</span><span class="p">,</span> <span class="nx">body</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nx">err</span><span class="p">){</span>
<span class="nx">res</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span><span class="dl">'</span><span class="s1">index</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span><span class="na">weather</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span> <span class="na">error</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Error, please try again</span><span class="dl">'</span><span class="p">});</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">weather</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="nx">body</span><span class="p">)</span>
<span class="k">if</span><span class="p">(</span><span class="nx">weather</span><span class="p">.</span><span class="nx">main</span> <span class="o">==</span> <span class="kc">undefined</span><span class="p">){</span>
<span class="nx">res</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span><span class="dl">'</span><span class="s1">index</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span><span class="na">weather</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span> <span class="na">error</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Error, please try again</span><span class="dl">'</span><span class="p">});</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">weatherText</span> <span class="o">=</span> <span class="s2">`It's </span><span class="p">${</span><span class="nx">weather</span><span class="p">.</span><span class="nx">main</span><span class="p">.</span><span class="nx">temp</span><span class="p">}</span><span class="s2"> degrees in </span><span class="p">${</span><span class="nx">weather</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2">!`</span><span class="p">;</span>
<span class="nx">res</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span><span class="dl">'</span><span class="s1">index</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span><span class="na">weather</span><span class="p">:</span> <span class="nx">weatherText</span><span class="p">,</span> <span class="na">error</span><span class="p">:</span> <span class="kc">null</span><span class="p">});</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="p">})</span>
</code></pre></div></div>
<p><strong>1. Configurer notre URL:</strong><br />
La première chose que nous faisons lorsque nous recevons le post request est de “req.body”” city <br />
Ensuite, nous créons une chaîne d url que nous utiliserons pour accéder à lAPI OpenWeatherMap</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">app</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">city</span> <span class="o">=</span> <span class="nx">req</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">city</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">url</span> <span class="o">=</span> <span class="s2">`http://api.openweathermap.org/data/2.5/weather?q=</span><span class="p">${</span><span class="nx">city</span><span class="p">}</span><span class="s2">&amp;units=imperial&amp;appid=</span><span class="p">${</span><span class="nx">apiKey</span><span class="p">}</span><span class="s2">`</span>
</code></pre></div></div>
<p><strong>2. Faites notre appel API:</strong><br />
Maintenant que nous avons notre URL, nous pouvons faire notre appel API. Lorsque nous recevons notre rappel, la première chose à faire est de rechercher une erreur. Si nous avons une erreur, nous allons rendre notre page dindex. Mais remarquez que jai aussi ajouté dans un deuxième argument. res.render a un second argument optionnel - un objet où nous pouvons spécifier les propriétés à gérer par notre vue ( index.ejs ).</p>
<p>Dans ce cas, jai ajouté une chaîne derreur:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">request</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">response</span><span class="p">,</span> <span class="nx">body</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nx">err</span><span class="p">){</span>
<span class="nx">res</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span><span class="dl">'</span><span class="s1">index</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span><span class="na">weather</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span> <span class="na">error</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Error, please try again</span><span class="dl">'</span><span class="p">});</span>
</code></pre></div></div>
<p><strong>3. Afficher le temps météo:</strong><br />
Maintenant que nous savons que nous navons aucune erreur dAPI, nous pouvons analyser notre code JSON dans un objet JavaScript utilisable.</p>
<p>La première chose à faire est de vérifier si <em>weather.main == undefined</em><br />
La seule raison pour laquelle ce ne serait pas défini, cest si notre utilisateur saisit une chaîne qui nest pas une ville (3, afefaefefe, etc.).<br />
Dans ce cas, nous allons rendre la vue dindex et nous renverrons également une erreur.</p>
<p>Si <em>weather.main != undefined</em> , nous pouvons enfin renvoyer la météo au client!<br />
Nous allons créer une chaîne qui clarifie la météo et la renvoyer avec la vue index.</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">weather</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="nx">body</span><span class="p">)</span>
<span class="k">if</span><span class="p">(</span><span class="nx">weather</span><span class="p">.</span><span class="nx">main</span> <span class="o">==</span> <span class="kc">undefined</span><span class="p">){</span>
<span class="nx">res</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span><span class="dl">'</span><span class="s1">index</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span><span class="na">weather</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span> <span class="na">error</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Error, please try again</span><span class="dl">'</span><span class="p">});</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">weatherText</span> <span class="o">=</span> <span class="s2">`It's </span><span class="p">${</span><span class="nx">weather</span><span class="p">.</span><span class="nx">main</span><span class="p">.</span><span class="nx">temp</span><span class="p">}</span><span class="s2"> degrees in </span><span class="p">${</span><span class="nx">weather</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2">!`</span><span class="p">;</span>
<span class="nx">res</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span><span class="dl">'</span><span class="s1">index</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span><span class="na">weather</span><span class="p">:</span> <span class="nx">weatherText</span><span class="p">,</span> <span class="na">error</span><span class="p">:</span> <span class="kc">null</span><span class="p">});</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<h3 id="utiliser-ejs">Utiliser EJS</h3>
<p>Il ne reste plus quune chose à faire à ce stade…<br />
Utiliser toutes les variables que nous avons renvoyées avec notre appel r<em>es.render</em><br />
Ces variables ne sont pas disponibles sur le client, cest ici que nous finissons par utiliser EJS.<br />
Il existe trois scénarios possibles dans notre code:</p>
<ol>
<li><code class="language-plaintext highlighter-rouge">{weather: null, error: null}</code></li>
<li><code class="language-plaintext highlighter-rouge">{weather: null, error: 'Error, please try again'}</code></li>
<li><code class="language-plaintext highlighter-rouge">{weather: weatherText, error: null}</code></li>
</ol>
<p>Nous devons apporter deux modifications simples à notre <strong>index.ejs</strong> pour gérer ces trois scénarios. Voici le code:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;% if(weather !== null){ %&gt;
&lt;p&gt;&lt;%= weather %&gt;&lt;/p&gt;
&lt;% } %&gt;
&lt;% if(error !== null){ %&gt;
&lt;p&gt;&lt;%= error %&gt;&lt;/p&gt;
&lt;% } %&gt;
</code></pre></div></div>
<p>Il est utile de se rappeler que EJS signifie Embedded JavaScript.<br />
Dans cet esprit, EJS a des crochets douverture et de fermeture:</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">&lt;% CODE HERE %&gt;</code> Tout ce qui est entre les crochets est exécuté.</li>
</ul>
<p>Si le crochet douverture inclut également un signe égal:</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">&lt;%= CODE HERE ADDS HTML %&gt;</code> , ce code ajoutera du code HTML au résultat.</li>
</ul>
<p>Si vous regardez notre EJS que nous avons ajouté, nous testons pour voir si nos variables <strong>weather</strong> ou <strong>error</strong> sont nulles. Si elles sont toutes deux nulles , rien ne se passe.<br />
Cependant, si lune nest pas nulle (cest-à-dire quelle a une valeur), nous ajouterons un paragraphe à lécran avec la valeur de la variable respective.</p>
<h3 id="indexejs">index.ejs</h3>
<p>Voici à quoi devrait ressembler votre index.ejs :</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;!DOCTYPE html&gt;</span>
<span class="nt">&lt;html&gt;</span>
<span class="nt">&lt;head&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">charset=</span><span class="s">"utf-8"</span><span class="nt">&gt;</span>
<span class="nt">&lt;title&gt;</span>Test<span class="nt">&lt;/title&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">type=</span><span class="s">"text/css"</span> <span class="na">href=</span><span class="s">"/css/style.css"</span><span class="nt">&gt;</span>
<span class="nt">&lt;link</span> <span class="na">href=</span><span class="s">'https://fonts.googleapis.com/css?family=Open+Sans:300'</span> <span class="na">rel=</span><span class="s">'stylesheet'</span> <span class="na">type=</span><span class="s">'text/css'</span><span class="nt">&gt;</span>
<span class="nt">&lt;/head&gt;</span>
<span class="nt">&lt;body&gt;</span>
<span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"container"</span><span class="nt">&gt;</span>
<span class="nt">&lt;fieldset&gt;</span>
<span class="nt">&lt;form</span> <span class="na">action=</span><span class="s">"/"</span> <span class="na">method=</span><span class="s">"post"</span><span class="nt">&gt;</span>
<span class="nt">&lt;input</span> <span class="na">name=</span><span class="s">"city"</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">class=</span><span class="s">"ghost-input"</span> <span class="na">placeholder=</span><span class="s">"Enter a City"</span> <span class="na">required</span><span class="nt">&gt;</span>
<span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"submit"</span> <span class="na">class=</span><span class="s">"ghost-button"</span> <span class="na">value=</span><span class="s">"Get Weather"</span><span class="nt">&gt;</span>
<span class="nt">&lt;/form&gt;</span>
<span class="nt">&lt;</span><span class="err">%</span> <span class="na">if</span><span class="err">(</span><span class="na">weather</span> <span class="err">!==</span> <span class="na">null</span><span class="err">){</span> <span class="err">%</span><span class="nt">&gt;</span>
<span class="nt">&lt;p&gt;&lt;</span><span class="err">%=</span> <span class="na">weather</span> <span class="err">%</span><span class="nt">&gt;&lt;/p&gt;</span>
<span class="nt">&lt;</span><span class="err">%</span> <span class="err">}</span> <span class="err">%</span><span class="nt">&gt;</span>
<span class="nt">&lt;</span><span class="err">%</span> <span class="na">if</span><span class="err">(</span><span class="na">error</span> <span class="err">!==</span> <span class="na">null</span><span class="err">){</span> <span class="err">%</span><span class="nt">&gt;</span>
<span class="nt">&lt;p&gt;&lt;</span><span class="err">%=</span> <span class="na">error</span> <span class="err">%</span><span class="nt">&gt;&lt;/p&gt;</span>
<span class="nt">&lt;</span><span class="err">%</span> <span class="err">}</span> <span class="err">%</span><span class="nt">&gt;</span>
<span class="nt">&lt;/fieldset&gt;</span>
<span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;/body&gt;</span>
<span class="nt">&lt;/html&gt;</span>
</code></pre></div></div>
<h3 id="serverjs">server.js</h3>
<p>Voici à quoi devrait ressembler votre server.js :</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">express</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">express</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">bodyParser</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">body-parser</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">request</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">request</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">app</span> <span class="o">=</span> <span class="nf">express</span><span class="p">()</span>
<span class="kd">const</span> <span class="nx">apiKey</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">*****************</span><span class="dl">'</span><span class="p">;</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">use</span><span class="p">(</span><span class="nx">express</span><span class="p">.</span><span class="nf">static</span><span class="p">(</span><span class="dl">'</span><span class="s1">public</span><span class="dl">'</span><span class="p">));</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">use</span><span class="p">(</span><span class="nx">bodyParser</span><span class="p">.</span><span class="nf">urlencoded</span><span class="p">({</span> <span class="na">extended</span><span class="p">:</span> <span class="kc">true</span> <span class="p">}));</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">set</span><span class="p">(</span><span class="dl">'</span><span class="s1">view engine</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">ejs</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">res</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span><span class="dl">'</span><span class="s1">index</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span><span class="na">weather</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span> <span class="na">error</span><span class="p">:</span> <span class="kc">null</span><span class="p">});</span>
<span class="p">})</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">city</span> <span class="o">=</span> <span class="nx">req</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">city</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">url</span> <span class="o">=</span> <span class="s2">`http://api.openweathermap.org/data/2.5/weather?q=</span><span class="p">${</span><span class="nx">city</span><span class="p">}</span><span class="s2">&amp;units=metric&amp;appid=</span><span class="p">${</span><span class="nx">apiKey</span><span class="p">}</span><span class="s2">`</span>
<span class="nf">request</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">response</span><span class="p">,</span> <span class="nx">body</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nx">err</span><span class="p">){</span>
<span class="nx">res</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span><span class="dl">'</span><span class="s1">index</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span><span class="na">weather</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span> <span class="na">error</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Error, please try again</span><span class="dl">'</span><span class="p">});</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">weather</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="nx">body</span><span class="p">)</span>
<span class="k">if</span><span class="p">(</span><span class="nx">weather</span><span class="p">.</span><span class="nx">main</span> <span class="o">==</span> <span class="kc">undefined</span><span class="p">){</span>
<span class="nx">res</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span><span class="dl">'</span><span class="s1">index</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span><span class="na">weather</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span> <span class="na">error</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Error, please try again</span><span class="dl">'</span><span class="p">});</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">weatherText</span> <span class="o">=</span> <span class="s2">`It's </span><span class="p">${</span><span class="nx">weather</span><span class="p">.</span><span class="nx">main</span><span class="p">.</span><span class="nx">temp</span><span class="p">}</span><span class="s2"> degrees in </span><span class="p">${</span><span class="nx">weather</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2">!`</span><span class="p">;</span>
<span class="nx">res</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span><span class="dl">'</span><span class="s1">index</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span><span class="na">weather</span><span class="p">:</span> <span class="nx">weatherText</span><span class="p">,</span> <span class="na">error</span><span class="p">:</span> <span class="kc">null</span><span class="p">});</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="p">})</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">listen</span><span class="p">(</span><span class="mi">3000</span><span class="p">,</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Example app listening on port 3000!</span><span class="dl">'</span><span class="p">)</span>
<span class="p">})</span>
</code></pre></div></div>
<h3 id="exécutez-votre-code">Exécutez votre code</h3>
<p>Exécution</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bitnami@debian:~$ cd ~/weather-app/
bitnami@debian:~/weather-app$ node server.js
Example app listening on port 3000!
</code></pre></div></div>
<p>Ouvrez maintenant votre navigateur et visitez: localhost:3000 , tapez un nom de ville dans le champ et appuyez sur Entrée! Vous devriez voir la météo apparaître sur votre écran!</p>
<p><img src="/images/nodejs09.png" alt="" width="400" /></p>
<p>Vous venez de créer un site Web permettant de passer des appels API et de répondre au client en temps réel!</p>
</div>
<div class="d-print-none"><footer class="article__footer"><meta itemprop="dateModified" content="2019-04-25T00:00:00+02:00"><!-- start custom article footer snippet -->
<!-- end custom article footer snippet -->
<!--
<div align="right"><a type="application/rss+xml" href="/feed.xml" title="S'abonner"><i class="fa fa-rss fa-2x"></i></a>
&emsp;</div>
-->
</footer>
<div class="article__section-navigator clearfix"><div class="previous"><span>PRÉCÉDENT</span><a href="/2019/04/03/Installer-Python-PIP-sur-Debian-Stretch.html">Installer Python PIP sur Debian Stretch</a></div><div class="next"><span>SUIVANT</span><a href="/2019/04/30/Android-Pie-LineageOS_16.html">nouveautés de LineageOS 16 (android 9)</a></div></div></div>
</div>
<script>(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
$(function() {
var $this ,$scroll;
var $articleContent = $('.js-article-content');
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
var scroll = hasSidebar ? '.js-page-main' : 'html, body';
$scroll = $(scroll);
$articleContent.find('.highlight').each(function() {
$this = $(this);
$this.attr('data-lang', $this.find('code').attr('data-lang'));
});
$articleContent.find('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]').each(function() {
$this = $(this);
$this.append($('<a class="anchor d-print-none" aria-hidden="true"></a>').html('<i class="fas fa-anchor"></i>'));
});
$articleContent.on('click', '.anchor', function() {
$scroll.scrollToAnchor('#' + $(this).parent().attr('id'), 400);
});
});
});
})();
</script>
</div><section class="page__comments d-print-none"></section></article><!-- start custom main bottom snippet -->
<!-- end custom main bottom snippet -->
</div>
</div></div></div></div>
</div><script>(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
var $body = $('body'), $window = $(window);
var $pageRoot = $('.js-page-root'), $pageMain = $('.js-page-main');
var activeCount = 0;
function modal(options) {
var $root = this, visible, onChange, hideWhenWindowScroll = false;
var scrollTop;
function setOptions(options) {
var _options = options || {};
visible = _options.initialVisible === undefined ? false : show;
onChange = _options.onChange;
hideWhenWindowScroll = _options.hideWhenWindowScroll;
}
function init() {
setState(visible);
}
function setState(isShow) {
if (isShow === visible) {
return;
}
visible = isShow;
if (visible) {
activeCount++;
scrollTop = $(window).scrollTop() || $pageMain.scrollTop();
$root.addClass('modal--show');
$pageMain.scrollTop(scrollTop);
activeCount === 1 && ($pageRoot.addClass('show-modal'), $body.addClass('of-hidden'));
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.on('scroll', hide);
$window.on('keyup', handleKeyup);
} else {
activeCount > 0 && activeCount--;
$root.removeClass('modal--show');
$window.scrollTop(scrollTop);
activeCount === 0 && ($pageRoot.removeClass('show-modal'), $body.removeClass('of-hidden'));
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.off('scroll', hide);
$window.off('keyup', handleKeyup);
}
onChange && onChange(visible);
}
function show() {
setState(true);
}
function hide() {
setState(false);
}
function handleKeyup(e) {
// Char Code: 27 ESC
if (e.which === 27) {
hide();
}
}
setOptions(options);
init();
return {
show: show,
hide: hide,
$el: $root
};
}
$.fn.modal = modal;
});
})();
</script><div class="modal modal--overflow page__search-modal d-print-none js-page-search-modal"><script>
(function () {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
// search panel
var search = (window.search || (window.search = {}));
var useDefaultSearchBox = window.useDefaultSearchBox === undefined ?
true : window.useDefaultSearchBox ;
var $searchModal = $('.js-page-search-modal');
var $searchToggle = $('.js-search-toggle');
var searchModal = $searchModal.modal({ onChange: handleModalChange, hideWhenWindowScroll: true });
var modalVisible = false;
search.searchModal = searchModal;
var $searchBox = null;
var $searchInput = null;
var $searchClear = null;
function getModalVisible() {
return modalVisible;
}
search.getModalVisible = getModalVisible;
function handleModalChange(visible) {
modalVisible = visible;
if (visible) {
search.onShow && search.onShow();
useDefaultSearchBox && $searchInput[0] && $searchInput[0].focus();
} else {
search.onShow && search.onHide();
useDefaultSearchBox && $searchInput[0] && $searchInput[0].blur();
setTimeout(function() {
useDefaultSearchBox && ($searchInput.val(''), $searchBox.removeClass('not-empty'));
search.clear && search.clear();
window.pageAsideAffix && window.pageAsideAffix.refresh();
}, 400);
}
}
$searchToggle.on('click', function() {
modalVisible ? searchModal.hide() : searchModal.show();
});
// Char Code: 83 S, 191 /
$(window).on('keyup', function(e) {
if (!modalVisible && !window.isFormElement(e.target || e.srcElement) && (e.which === 83 || e.which === 191)) {
modalVisible || searchModal.show();
}
});
if (useDefaultSearchBox) {
$searchBox = $('.js-search-box');
$searchInput = $searchBox.children('input');
$searchClear = $searchBox.children('.js-icon-clear');
search.getSearchInput = function() {
return $searchInput.get(0);
};
search.getVal = function() {
return $searchInput.val();
};
search.setVal = function(val) {
$searchInput.val(val);
};
$searchInput.on('focus', function() {
$(this).addClass('focus');
});
$searchInput.on('blur', function() {
$(this).removeClass('focus');
});
$searchInput.on('input', window.throttle(function() {
var val = $(this).val();
if (val === '' || typeof val !== 'string') {
search.clear && search.clear();
} else {
$searchBox.addClass('not-empty');
search.onInputNotEmpty && search.onInputNotEmpty(val);
}
}, 400));
$searchClear.on('click', function() {
$searchInput.val(''); $searchBox.removeClass('not-empty');
search.clear && search.clear();
});
}
});
})();
</script><div class="search search--dark">
<div class="main">
<div class="search__header">Recherche</div>
<div class="search-bar">
<div class="search-box js-search-box">
<div class="search-box__icon-search"><i class="fas fa-search"></i></div>
<input id="search-input" type="text" />
<div class="search-box__icon-clear js-icon-clear">
<a><i class="fas fa-times"></i></a>
</div>
</div>
<button class="button button--theme-dark button--pill search__cancel js-search-toggle">
Annuler</button>
</div>
<div id="results-container" class="search-result js-search-result"></div>
</div>
</div>
<!-- Script pointing to search-script.js -->
<script>/*!
* Simple-Jekyll-Search
* Copyright 2015-2020, Christian Fei
* Licensed under the MIT License.
*/
(function(){
'use strict'
var _$Templater_7 = {
compile: compile,
setOptions: setOptions
}
const options = {}
options.pattern = /\{(.*?)\}/g
options.template = ''
options.middleware = function () {}
function setOptions (_options) {
options.pattern = _options.pattern || options.pattern
options.template = _options.template || options.template
if (typeof _options.middleware === 'function') {
options.middleware = _options.middleware
}
}
function compile (data) {
return options.template.replace(options.pattern, function (match, prop) {
const value = options.middleware(prop, data[prop], options.template)
if (typeof value !== 'undefined') {
return value
}
return data[prop] || match
})
}
'use strict';
function fuzzysearch (needle, haystack) {
var tlen = haystack.length;
var qlen = needle.length;
if (qlen > tlen) {
return false;
}
if (qlen === tlen) {
return needle === haystack;
}
outer: for (var i = 0, j = 0; i < qlen; i++) {
var nch = needle.charCodeAt(i);
while (j < tlen) {
if (haystack.charCodeAt(j++) === nch) {
continue outer;
}
}
return false;
}
return true;
}
var _$fuzzysearch_1 = fuzzysearch;
'use strict'
/* removed: const _$fuzzysearch_1 = require('fuzzysearch') */;
var _$FuzzySearchStrategy_5 = new FuzzySearchStrategy()
function FuzzySearchStrategy () {
this.matches = function (string, crit) {
return _$fuzzysearch_1(crit.toLowerCase(), string.toLowerCase())
}
}
'use strict'
var _$LiteralSearchStrategy_6 = new LiteralSearchStrategy()
function LiteralSearchStrategy () {
this.matches = function (str, crit) {
if (!str) return false
str = str.trim().toLowerCase()
crit = crit.trim().toLowerCase()
return crit.split(' ').filter(function (word) {
return str.indexOf(word) >= 0
}).length === crit.split(' ').length
}
}
'use strict'
var _$Repository_4 = {
put: put,
clear: clear,
search: search,
setOptions: __setOptions_4
}
/* removed: const _$FuzzySearchStrategy_5 = require('./SearchStrategies/FuzzySearchStrategy') */;
/* removed: const _$LiteralSearchStrategy_6 = require('./SearchStrategies/LiteralSearchStrategy') */;
function NoSort () {
return 0
}
const data = []
let opt = {}
opt.fuzzy = false
opt.limit = 10
opt.searchStrategy = opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = NoSort
opt.exclude = []
function put (data) {
if (isObject(data)) {
return addObject(data)
}
if (isArray(data)) {
return addArray(data)
}
return undefined
}
function clear () {
data.length = 0
return data
}
function isObject (obj) {
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Object]'
}
function isArray (obj) {
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Array]'
}
function addObject (_data) {
data.push(_data)
return data
}
function addArray (_data) {
const added = []
clear()
for (let i = 0, len = _data.length; i < len; i++) {
if (isObject(_data[i])) {
added.push(addObject(_data[i]))
}
}
return added
}
function search (crit) {
if (!crit) {
return []
}
return findMatches(data, crit, opt.searchStrategy, opt).sort(opt.sort)
}
function __setOptions_4 (_opt) {
opt = _opt || {}
opt.fuzzy = _opt.fuzzy || false
opt.limit = _opt.limit || 10
opt.searchStrategy = _opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = _opt.sort || NoSort
opt.exclude = _opt.exclude || []
}
function findMatches (data, crit, strategy, opt) {
const matches = []
for (let i = 0; i < data.length && matches.length < opt.limit; i++) {
const match = findMatchesInObject(data[i], crit, strategy, opt)
if (match) {
matches.push(match)
}
}
return matches
}
function findMatchesInObject (obj, crit, strategy, opt) {
for (const key in obj) {
if (!isExcluded(obj[key], opt.exclude) && strategy.matches(obj[key], crit)) {
return obj
}
}
}
function isExcluded (term, excludedTerms) {
for (let i = 0, len = excludedTerms.length; i < len; i++) {
const excludedTerm = excludedTerms[i]
if (new RegExp(excludedTerm).test(term)) {
return true
}
}
return false
}
/* globals ActiveXObject:false */
'use strict'
var _$JSONLoader_2 = {
load: load
}
function load (location, callback) {
const xhr = getXHR()
xhr.open('GET', location, true)
xhr.onreadystatechange = createStateChangeListener(xhr, callback)
xhr.send()
}
function createStateChangeListener (xhr, callback) {
return function () {
if (xhr.readyState === 4 && xhr.status === 200) {
try {
callback(null, JSON.parse(xhr.responseText))
} catch (err) {
callback(err, null)
}
}
}
}
function getXHR () {
return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
}
'use strict'
var _$OptionsValidator_3 = function OptionsValidator (params) {
if (!validateParams(params)) {
throw new Error('-- OptionsValidator: required options missing')
}
if (!(this instanceof OptionsValidator)) {
return new OptionsValidator(params)
}
const requiredOptions = params.required
this.getRequiredOptions = function () {
return requiredOptions
}
this.validate = function (parameters) {
const errors = []
requiredOptions.forEach(function (requiredOptionName) {
if (typeof parameters[requiredOptionName] === 'undefined') {
errors.push(requiredOptionName)
}
})
return errors
}
function validateParams (params) {
if (!params) {
return false
}
return typeof params.required !== 'undefined' && params.required instanceof Array
}
}
'use strict'
var _$utils_9 = {
merge: merge,
isJSON: isJSON
}
function merge (defaultParams, mergeParams) {
const mergedOptions = {}
for (const option in defaultParams) {
mergedOptions[option] = defaultParams[option]
if (typeof mergeParams[option] !== 'undefined') {
mergedOptions[option] = mergeParams[option]
}
}
return mergedOptions
}
function isJSON (json) {
try {
if (json instanceof Object && JSON.parse(JSON.stringify(json))) {
return true
}
return false
} catch (err) {
return false
}
}
var _$src_8 = {};
(function (window) {
'use strict'
let options = {
searchInput: null,
resultsContainer: null,
json: [],
success: Function.prototype,
searchResultTemplate: '<li><a href="{url}" title="{desc}">{title}</a></li>',
templateMiddleware: Function.prototype,
sortMiddleware: function () {
return 0
},
noResultsText: 'No results found',
limit: 10,
fuzzy: false,
debounceTime: null,
exclude: []
}
let debounceTimerHandle
const debounce = function (func, delayMillis) {
if (delayMillis) {
clearTimeout(debounceTimerHandle)
debounceTimerHandle = setTimeout(func, delayMillis)
} else {
func.call()
}
}
const requiredOptions = ['searchInput', 'resultsContainer', 'json']
/* removed: const _$Templater_7 = require('./Templater') */;
/* removed: const _$Repository_4 = require('./Repository') */;
/* removed: const _$JSONLoader_2 = require('./JSONLoader') */;
const optionsValidator = _$OptionsValidator_3({
required: requiredOptions
})
/* removed: const _$utils_9 = require('./utils') */;
window.SimpleJekyllSearch = function (_options) {
const errors = optionsValidator.validate(_options)
if (errors.length > 0) {
throwError('You must specify the following required options: ' + requiredOptions)
}
options = _$utils_9.merge(options, _options)
_$Templater_7.setOptions({
template: options.searchResultTemplate,
middleware: options.templateMiddleware
})
_$Repository_4.setOptions({
fuzzy: options.fuzzy,
limit: options.limit,
sort: options.sortMiddleware,
exclude: options.exclude
})
if (_$utils_9.isJSON(options.json)) {
initWithJSON(options.json)
} else {
initWithURL(options.json)
}
const rv = {
search: search
}
typeof options.success === 'function' && options.success.call(rv)
return rv
}
function initWithJSON (json) {
_$Repository_4.put(json)
registerInput()
}
function initWithURL (url) {
_$JSONLoader_2.load(url, function (err, json) {
if (err) {
throwError('failed to get JSON (' + url + ')')
}
initWithJSON(json)
})
}
function emptyResultsContainer () {
options.resultsContainer.innerHTML = ''
}
function appendToResultsContainer (text) {
options.resultsContainer.innerHTML += text
}
function registerInput () {
options.searchInput.addEventListener('input', function (e) {
if (isWhitelistedKey(e.which)) {
emptyResultsContainer()
debounce(function () { search(e.target.value) }, options.debounceTime)
}
})
}
function search (query) {
if (isValidQuery(query)) {
emptyResultsContainer()
render(_$Repository_4.search(query), query)
}
}
function render (results, query) {
const len = results.length
if (len === 0) {
return appendToResultsContainer(options.noResultsText)
}
for (let i = 0; i < len; i++) {
results[i].query = query
appendToResultsContainer(_$Templater_7.compile(results[i]))
}
}
function isValidQuery (query) {
return query && query.length > 0
}
function isWhitelistedKey (key) {
return [13, 16, 20, 37, 38, 39, 40, 91].indexOf(key) === -1
}
function throwError (message) {
throw new Error('SimpleJekyllSearch --- ' + message)
}
})(window)
}());
</script>
<!-- Configuration -->
<script>
SimpleJekyllSearch({
searchInput: document.getElementById('search-input'),
resultsContainer: document.getElementById('results-container'),
noResultsText: '<p>Aucun résultat!</p>',
json: '/search.json',
searchResultTemplate: '<li><a href="{url}">{date}&nbsp;{title}</a>&nbsp;(Création {create})</li>'
})
</script>
</div></div>
<script>(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
function scrollToAnchor(anchor, duration, callback) {
var $root = this;
$root.animate({ scrollTop: $(anchor).position().top }, duration, function() {
window.history.replaceState(null, '', window.location.href.split('#')[0] + anchor);
callback && callback();
});
}
$.fn.scrollToAnchor = scrollToAnchor;
});
})();
(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
function affix(options) {
var $root = this, $window = $(window), $scrollTarget, $scroll,
offsetBottom = 0, scrollTarget = window, scroll = window.document, disabled = false, isOverallScroller = true,
rootTop, rootLeft, rootHeight, scrollBottom, rootBottomTop,
hasInit = false, curState;
function setOptions(options) {
var _options = options || {};
_options.offsetBottom && (offsetBottom = _options.offsetBottom);
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
_options.scroll && (scroll = _options.scroll);
_options.disabled !== undefined && (disabled = _options.disabled);
$scrollTarget = $(scrollTarget);
isOverallScroller = window.isOverallScroller($scrollTarget[0]);
$scroll = $(scroll);
}
function preCalc() {
top();
rootHeight = $root.outerHeight();
rootTop = $root.offset().top + (isOverallScroller ? 0 : $scrollTarget.scrollTop());
rootLeft = $root.offset().left;
}
function calc(needPreCalc) {
needPreCalc && preCalc();
scrollBottom = $scroll.outerHeight() - offsetBottom - rootHeight;
rootBottomTop = scrollBottom - rootTop;
}
function top() {
if (curState !== 'top') {
$root.removeClass('fixed').css({
left: 0,
top: 0
});
curState = 'top';
}
}
function fixed() {
if (curState !== 'fixed') {
$root.addClass('fixed').css({
left: rootLeft + 'px',
top: 0
});
curState = 'fixed';
}
}
function bottom() {
if (curState !== 'bottom') {
$root.removeClass('fixed').css({
left: 0,
top: rootBottomTop + 'px'
});
curState = 'bottom';
}
}
function setState() {
var scrollTop = $scrollTarget.scrollTop();
if (scrollTop >= rootTop && scrollTop <= scrollBottom) {
fixed();
} else if (scrollTop < rootTop) {
top();
} else {
bottom();
}
}
function init() {
if(!hasInit) {
var interval, timeout;
calc(true); setState();
// run calc every 100 millisecond
interval = setInterval(function() {
calc();
}, 100);
timeout = setTimeout(function() {
clearInterval(interval);
}, 45000);
window.pageLoad.then(function() {
setTimeout(function() {
clearInterval(interval);
clearTimeout(timeout);
}, 3000);
});
$scrollTarget.on('scroll', function() {
disabled || setState();
});
$window.on('resize', function() {
disabled || (calc(true), setState());
});
hasInit = true;
}
}
setOptions(options);
if (!disabled) {
init();
}
$window.on('resize', window.throttle(function() {
init();
}, 200));
return {
setOptions: setOptions,
refresh: function() {
calc(true, { animation: false }); setState();
}
};
}
$.fn.affix = affix;
});
})();
(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
function toc(options) {
var $root = this, $window = $(window), $scrollTarget, $scroller, $tocUl = $('<ul class="toc toc--ellipsis"></ul>'), $tocLi, $headings, $activeLast, $activeCur,
selectors = 'h1,h2,h3', container = 'body', scrollTarget = window, scroller = 'html, body', disabled = false,
headingsPos, scrolling = false, hasRendered = false, hasInit = false;
function setOptions(options) {
var _options = options || {};
_options.selectors && (selectors = _options.selectors);
_options.container && (container = _options.container);
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
_options.scroller && (scroller = _options.scroller);
_options.disabled !== undefined && (disabled = _options.disabled);
$headings = $(container).find(selectors).filter('[id]');
$scrollTarget = $(scrollTarget);
$scroller = $(scroller);
}
function calc() {
headingsPos = [];
$headings.each(function() {
headingsPos.push(Math.floor($(this).position().top));
});
}
function setState(element, disabled) {
var scrollTop = $scrollTarget.scrollTop(), i;
if (disabled || !headingsPos || headingsPos.length < 1) { return; }
if (element) {
$activeCur = element;
} else {
for (i = 0; i < headingsPos.length; i++) {
if (scrollTop >= headingsPos[i]) {
$activeCur = $tocLi.eq(i);
} else {
$activeCur || ($activeCur = $tocLi.eq(i));
break;
}
}
}
$activeLast && $activeLast.removeClass('active');
($activeLast = $activeCur).addClass('active');
}
function render() {
if(!hasRendered) {
$root.append($tocUl);
$headings.each(function() {
var $this = $(this);
$tocUl.append($('<li></li>').addClass('toc-' + $this.prop('tagName').toLowerCase())
.append($('<a></a>').text($this.text()).attr('href', '#' + $this.prop('id'))));
});
$tocLi = $tocUl.children('li');
$tocUl.on('click', 'a', function(e) {
e.preventDefault();
var $this = $(this);
scrolling = true;
setState($this.parent());
$scroller.scrollToAnchor($this.attr('href'), 400, function() {
scrolling = false;
});
});
}
hasRendered = true;
}
function init() {
var interval, timeout;
if(!hasInit) {
render(); calc(); setState(null, scrolling);
// run calc every 100 millisecond
interval = setInterval(function() {
calc();
}, 100);
timeout = setTimeout(function() {
clearInterval(interval);
}, 45000);
window.pageLoad.then(function() {
setTimeout(function() {
clearInterval(interval);
clearTimeout(timeout);
}, 3000);
});
$scrollTarget.on('scroll', function() {
disabled || setState(null, scrolling);
});
$window.on('resize', window.throttle(function() {
if (!disabled) {
render(); calc(); setState(null, scrolling);
}
}, 100));
}
hasInit = true;
}
setOptions(options);
if (!disabled) {
init();
}
$window.on('resize', window.throttle(function() {
init();
}, 200));
return {
setOptions: setOptions
};
}
$.fn.toc = toc;
});
})();
/*(function () {
})();*/
</script><script>
/* toc must before affix, since affix need to konw toc' height. */(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
var TOC_SELECTOR = window.TEXT_VARIABLES.site.toc.selectors;
window.Lazyload.js(SOURCES.jquery, function() {
var $window = $(window);
var $articleContent = $('.js-article-content');
var $tocRoot = $('.js-toc-root'), $col2 = $('.js-col-aside');
var toc;
var tocDisabled = false;
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
var hasToc = $articleContent.find(TOC_SELECTOR).length > 0;
function disabled() {
return $col2.css('display') === 'none' || !hasToc;
}
tocDisabled = disabled();
toc = $tocRoot.toc({
selectors: TOC_SELECTOR,
container: $articleContent,
scrollTarget: hasSidebar ? '.js-page-main' : null,
scroller: hasSidebar ? '.js-page-main' : null,
disabled: tocDisabled
});
$window.on('resize', window.throttle(function() {
tocDisabled = disabled();
toc && toc.setOptions({
disabled: tocDisabled
});
}, 100));
});
})();
(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
var $window = $(window), $pageFooter = $('.js-page-footer');
var $pageAside = $('.js-page-aside');
var affix;
var tocDisabled = false;
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
affix = $pageAside.affix({
offsetBottom: $pageFooter.outerHeight(),
scrollTarget: hasSidebar ? '.js-page-main' : null,
scroller: hasSidebar ? '.js-page-main' : null,
scroll: hasSidebar ? $('.js-page-main').children() : null,
disabled: tocDisabled
});
$window.on('resize', window.throttle(function() {
affix && affix.setOptions({
disabled: tocDisabled
});
}, 100));
window.pageAsideAffix = affix;
});
})();
</script><!---->
</div>
<script>(function () {
var $root = document.getElementsByClassName('root')[0];
if (window.hasEvent('touchstart')) {
$root.dataset.isTouch = true;
document.addEventListener('touchstart', function(){}, false);
}
})();
</script>
</body>
</html>