Table des matières:
- Étape 1: Structure de l'application
- Étape 2: mettez en page votre modèle
- {{Titre}}
- Étape 3: Formulaire de contact
- Étape 4: page de connexion
- Étape 5: compteur de trafic
- Étape 6: Bloguer
- Étape 7: Terminé
Vidéo: Page Web Node.js Partie 2 : 7 étapes
2024 Auteur: John Day | [email protected]. Dernière modifié: 2024-01-30 09:08
Bienvenue à la PARTIE 2 !!
Ceci est la partie 2 de mon didacticiel d'application de site Web Node.js. J'ai divisé ce tutoriel en deux parties car il sépare ceux qui ont juste besoin d'une brève introduction et ceux qui veulent un tutoriel complet sur une page Web.
Je vais passer par la création de mon site. Le vôtre peut être différent, alors suivez le mien et apprenez les techniques utilisées. Une fois que vous avez choisi un modèle HTML différent, le flux sera légèrement différent. Garde ça en tête.
Étape 1: Structure de l'application
Donc mon site suit le générateur express, cependant j'ai utilisé des guidons plutôt que du jade. Si vous aimez le jade, foncez ! Jade est un code HTML abrégé sans tous les crochets et div. Si vous ne comprenez pas cela, vous voudrez peut-être visiter youtube et regarder des didacticiels HTML.
Je préfère et suis plus à l'aise avec le HTML et le guidon, c'est donc ce que j'ai utilisé. Pour créer un projet express avec des guidons, exécutez la commande express.
express --hbs nameofmyapp
Continuez ensuite à suivre l'étape de la partie 1 pour installer tous les middleware.
Express crée une structure d'application très spécifique et très utile. La plupart des applications node.js suivent cette forme avec quelques variations.
Sur la photo ci-jointe, vous pouvez voir différents dossiers et fichiers, ci-dessous j'essaie d'expliquer tout cela.
poubelle
C'est le dossier qui est exécuté en premier lorsque node.js démarre votre serveur. Il regarde le fichier www et suit ce fichier pour l'exécution. Le fichier www indique à node.js de démarrer un serveur sur le port 3000 (cela peut changer à peu près n'importe quoi) et de faire d'autres choses telles que l'écouteur d'événements et autres. La chose la plus importante est le port sur lequel votre application est configurée.
node_modules
Dans ce dossier se trouve ce qu'on appelle un middleware. Middleware que j'aime expliquer en tant que logiciel supplémentaire pour vous faciliter la tâche à coder. Ce sont essentiellement d'autres bibliothèques avec des fonctions prédéfinies que vous pouvez utiliser. Certains middleware supplémentaires que j'ai utilisés pour ce projet étaient Nodemailer, Passport, Nodemon, bycrypt et autres.
Publique
C'est là qu'iraient toutes vos images, CSS et javascript pour votre site Web. Ceux-ci sont directement utilisés par les pages Web.
itinéraires
Ce sont des itinéraires définis pour votre site. Tels qu'une page d'accueil, une page de connexion et autres.
vues
Comme vous pouvez le voir, les vues sont des fichiers.hbs ou.handlebars, l'un ou l'autre fonctionnera, il suffit de manipuler le fichier app.js. Ce sont les pages html de votre guidon qui s'afficheront sur le navigateur. La mise en page est votre fichier de mise en page principal et se trouve parfois dans son propre sous-dossier de mise en page. Le fichier de mise en page principal appelle vos autres fichiers de guidon et les affiche, cela aura plus de sens lorsque nous plongerons dans le code.
app.js
Il s'agit de votre fichier d'application principal, parfois appelé serveur, cela dépend simplement de la configuration. Ce fichier contient toute la configuration du serveur et même certaines fonctions spéciales. Ce sera également un gestionnaire d'erreurs.
package.json
Ce fichier est créé par express et indique à npm tous les middleware que vous souhaitez utiliser dans votre projet. Une fois que vous avez exécuté npm install, tous les middleware appelés dans ce fichier seront installés dans le dossier node_modules.
Étape 2: mettez en page votre modèle
Vous pouvez créer tout votre code HTML à partir de zéro ou vous pouvez utiliser un modèle. J'ai utilisé un modèle pour ce site. D'autres sites que j'ai aidé à développer, j'ai codé à partir de zéro. Le choix vous appartient, cette étape explique la mise en page du modèle.
Mon application Web utilise un modèle d'amorçage qui est idéal pour créer des CSS incroyables. Pour trouver des modèles, visitez ce site. Comme indiqué précédemment à l'étape précédente, tous les fichiers css, js et img nécessaires se trouvent dans le dossier public. Ces fichiers rendent le site plus beau que le texte brut et la façon dont les images sont utilisées sur le site.
Afin de faire fonctionner le style de gabarit du guidon avec un modèle, les pages sont divisées en deux parties. Le premier est ce que l'on appelle la « mise en page ». La mise en page correspond aux propriétés que vous voudriez voir apparaître sur chaque page Web de votre site. Dans mon cas, il s'agit de l'en-tête, qui contient la barre de navigation, et du pied de page, qui contient des éléments de navigation et d'affichage supplémentaires.
Le fichier de mise en page et les autres fichiers de guidon se trouvent dans le dossier views. Je vais passer en revue une mise en page plus simple du générateur express que vous avez utilisé plus tôt pour afficher le fonctionnement du concept, puis vous pouvez voir mon code et les comparer.
Fichier layout.handlebars généré par express
{{title}} {{{body}}}
La vraie magie du guidon réside dans les guidons {{title}} et {{{body}}}. Donc, ces deux-là agissent différemment {{title}} est une variable qui est passée du fichier index.js dans les routes, une fois passée au modèle, elle est affichée. La balise {{{body}}} prend tout ce qui est appelé dans la fonction de rendu de votre fichier route js. Dans notre cas, index.js a cette ligne:
res.render('index', { titre: 'Express', count: userCount});
Cela appelle le fichier « index » de votre moteur d'utilisation, jade, guidon, etc., donc dans notre cas index.handlebars.
Index généré par express.handlebars
{{Titre}}
Bienvenue à {{title}}
Le fichier index.handlebars est passé comme une variable à la balise {{{body}}} et affiché sur votre page Web.
Cela vous permet d'avoir une partie statique de votre site Web et une partie variable. Cela rend les en-têtes et les pieds de page agréables car vous n'avez pas besoin de reconstituer la page entière, lors du chargement d'une nouvelle page, seules certaines informations sont modifiées.
Étape 3: Formulaire de contact
J'ai incorporé un formulaire de contact dans ma page Web afin que n'importe qui puisse envoyer un courriel à mon site, avec des questions ou des commentaires.
Ce formulaire de contact utilisait un middleware npm appelé Node Mailer.
Configuration de Node Mailer
Pour installer node-mailer, il vous suffit d'exécuter le code ci-dessous dans votre fichier de niveau supérieur, dans notre cas, myapp.
sudo npm installer nodemailer
Une fois installé, vous devrez configurer quelques éléments dans votre fichier app.js.
Le premier est juste la dépendance, cela indique au nœud que nous prévoyons d'utiliser ce middleware.
var nodemailer = require('nodemailer');
Le deuxième est notre transporteur, le transporteur est utilisé pour se connecter à votre serveur de messagerie, dans mon cas gmail.
// Transporteur utilisé pour obtenir le compte gmail
var transporter = nodemailer.createTransport({ service: 'gmail', auth: { type: 'OAuth2', utilisateur: '[email protected]', clientId: '139955258255-a3c6ilqu6rtocigde7cbrusicg7j00eh.apps.googleusercontent.com', clientSecret: 'Q775xefdHA_BGu3ZnY9-6sP-', refreshToken: '1 / 0HfdzyzW3FmnDPqeYkv19_py6zWgMCOqI9DSZ9kQWfc', accessToken: 'ya29. GlvDBGA2Z_coEKjQOnXAnBLbTB0wQmS-sARqNGC3V2UATiywNb34IhFq4d7UQvhTobE6pi83-FB2-OvMWjC-mk-EKPMYmwxFe9AOZ7mY6kurYyQ7e1Mu8m8INxg7'}})
si vous utilisez nodemailer avec un autre serveur de messagerie, veuillez consulter ici la documentation et l'aide.
Quelques éléments changeront d'une personne à l'autre: user, clientId, clientSecret. refreshToken et accessToken.
Votre userId est l'email dans lequel vous souhaitez l'utiliser, j'en ai créé un nouveau du même nom que mon site.
Le clientId, clientSecret, refreshToken et accessToken doivent être trouvés via votre compte Google.
Si vous avez besoin de plus d'aide, vous pouvez suivre cette vidéo ici.
Une fois tous ces champs remplis, nous ajouterons les détails de notre message.
Ensuite, nous devons valider que tous les champs de notre formulaire ont été saisis et sont des réponses valides.
// Express Validatorapp.use(expressValidator({ errorFormatter: function(param, msg, value) { var namespace = param.split('.'), root = namespace.shift(), formParam = root; while(namespace.length) { formParam += '[' + namespace.shift() + ']'; } return { param: formParam, msg: msg, value: value }; } }));
Nous devons maintenant obtenir des informations à partir de notre formulaire de contact sur notre page Web et envoyer un message.
// Publier à partir du bouton d'envoi du contact, besoin de créer une page d'accueil avec un message de réussite pour les formulaires soumis = req.body.name; var email = req.body.email; var phone = req.body.phone; var message = req.body.message; var mailOptions = { //crée les informations utilisées lors de l'envoi d'un message à partir de: ' Email automatique', à: '[email protected]', sujet: 'Formulaire de contact du site Web: ' + nom, texte: 'Vous avez reçu un nouveau message du formulaire de contact de votre site Web.\n\n' + 'Ici sont les détails:\n\nNom: ' + nom + '\n\nEmail: ' + email + '\n\nTéléphone: ' + téléphone + '\n\nMessage:\n' + message } transporter.sendMail(mailOptions, function (err, res) { if(err){ console.log('Error'); }else { console.log('Email Sent'); } }) res.render('index'); //rendre nouvelle page d'accueil, découvrez comment procéder avec un message de réussite, comme la page de déconnexion })
Éclat
Flash est utilisé pour afficher les messages une fois les actions effectuées. Vous pouvez le voir lorsque vous soumettez un formulaire ou que vous ne saisissez pas correctement un champ.
Installez flash comme les autres middleware npm.
sudo npm installer connect-flash
var flash = require('connect-flash'); // avait une fonctionnalité flash pour afficher les messages à l'écran
// Connecter Flashapp.use(flash());
Activez le flash qui envoie et met à jour les messages sur la page Web. Ce sont les messages qui disent des choses comme le succès, ou des informations ont été saisies de manière incorrecte.
// Variables globales
app.use(function (req, res, next) { res.locals.success_msg = req.flash('success_msg'); res.locals.error_msg = req.flash('error_msg'); res.locals.error = req.flash('error'); res.locals.user = req.user || null; next(); });
Certains ont besoin de variables associées au flash.
Voilà un formulaire de contact créé.
Étape 4: page de connexion
C'était juste quelque chose que je voulais voir si je pouvais le faire et peut-être que je l'utiliserai à l'avenir. Je voulais juste expliquer le code tel qu'il se trouve dans mon référentiel git.
Cette partie utilise donc un peu plus de middleware npm. Installez les éléments suivants à l'aide des commandes ci-dessous.
npm installer le passeport && npm installer le passeport-local && npm installer bcryptjs
Le && vous permet d'exécuter plusieurs commandes avec une seule ligne.
Connexion et utilisateurs
Vous devrez créer un fichier login.js et user.js dans votre dossier routes. Cela sera utilisé pour permettre la création d'un utilisateur, qui sera stocké dans notre base de données, et permettre à l'utilisateur de se connecter en vérifiant la base de données.
user.js
var express = require('express');var router = express. Router(); var passeport = require('passeport'); var LocalStrategy = require('passport-local'). Strategy; var Utilisateur = require('../models/user'); // Enregistrer router.get('/register', function(req, res){ res.render('register'); }); //Enregistrer l'utilisateur router.post('/register', function(req, res){ var name = req.body.name; var email = req.body.email; var username = req.body.username; var password = req.body.password; var password2 = req.body.password2; // Validation req.checkBody('name', 'Name is required').notEmpty(); req.checkBody('email', 'Email is required').notEmpty(); req.checkBody('email', 'Email n'est pas valide').isEmail(); req.checkBody('username', 'Username is required').notEmpty(); req.checkBody(' mot de passe', 'Le mot de passe est requis').notEmpty(); req.checkBody('password2', 'Les mots de passe ne correspondent pas').equals(req.body.password); var error = req.validationErrors(); if(erreurs){ res.render('register', { error:errors }); } else { var newUser = new User({ name: name, email:email, username: username, password: password }); User.createUser(newUser, function(err, user){ if(err) throw err; console.log(user); }); req.flash('success_msg', 'Vous êtes enregistré et pouvez maintenant vous connecter'); res.redirect(' /connexion'); } });
Décomposer ça morceau par morceau
Nous incluons d'abord tous les middleware nécessaires, puis nous incluons notre fichier modèle qui est expliqué ci-dessous. Nous acheminons à partir de la balise de registre et affichons le texte de notre guidon de registre. Vient ensuite la fonction importante. Ceux-ci nous permettent d'enregistrer un nouvel utilisateur dans notre base de données. La fonction vérifie que tous les champs sont valides et inclus dans le formulaire, sinon elle les demandera. Ensuite, il vérifie les erreurs et, si aucune erreur ne se produit, il crée un nouvel utilisateur avec les informations fournies. Il redirige ensuite vers la page de connexion, vous permettant de vous connecter.
login.js
var express = require('express');
var router = express. Router();var passeport = require('passport'); var LocalStrategy = require('passport-local'). Strategy; var Utilisateur = require('../models/user'); /* GET liste des utilisateurs. */ //Page d'accueil router.get('/', function(req, res){ res.render('login'); }); passeport.use(new LocalStrategy(function(username, password, done) { User.getUserByUsername(username, function(err, user){ if(err) throw err; if(!user){ return done(null, false, { message: 'Utilisateur inconnu'}); } User.comparePassword(password, user.password, function(err, isMatch){ if(err) throw err; if(isMatch){ return done(null, user); } else { return done(null, false, {message: 'Mot de passe invalide'}); } }); }); })); passeport.serializeUser(function(user, done) { done(null, user.id); }); passeport.deserializeUser(function(id, done) { User.getUserById(id, function(err, user) { done(err, user); }); }); router.post('/login', passeport.authenticate('local', {successRedirect:'/', failureRedirect:'/login', failureFlash: true}), function(req, res) { res.redirect('/ tableau de bord'); }); router.get('/logout', function(req, res){ req.logout(); req.flash('success_msg', 'Vous êtes déconnecté'); res.redirect('/homepage'); });
module.exports = routeur;
Nous incluons d'abord tous les middleware nécessaires, puis nous incluons notre fichier modèle qui est expliqué ci-dessous. Nous routons à partir de la balise de connexion et affichons le texte de notre guidon de connexion. Nous utilisons ensuite certaines fonctions de passeport pour prendre le nom d'utilisateur et le mot de passe saisis et les comparer à notre base de données. Nous utiliserons également un mot de passe crypté, ce qui peut ralentir un peu la connexion sur un Raspberry Pi. J'explique cela plus loin. Après avoir validé le nom d'utilisateur et le mot de passe, vous êtes redirigé vers la page d'accueil qui affichera le tableau de bord tel que nous l'avons configuré dans notre fichier d'index. Nous ajoutons également ici la possibilité de se déconnecter.
Comme je l'ai mentionné précédemment, nous devrons également créer un modèle pour vérifier la base de données.
Cela se fait en créant un dossier sous votre dossier d'application principal appelé models. Dans ce dossier, un fichier user.js est également nécessaire.
modèle/utilisateur.js
var mangouste = require('mangouste');
var bcrypt = require('bcryptjs'); // Schéma utilisateur var UserSchema = mongoose. Schema({ nom d'utilisateur: { type: chaîne, index: true }, mot de passe: { type: chaîne }, email: { type: chaîne }, nom: { type: chaîne } }); var User = module.exports = mongoose.model('User', UserSchema);
module.exports.createUser = function(newUser, callback){
bcrypt.genSalt(10, function(err, salt) { bcrypt.hash(newUser.password, salt, function(err, hash) { newUser.password = hash; newUser.save(callback); }); }); } module.exports.getUserByUsername = function(nom d'utilisateur, rappel){ var query = {nom d'utilisateur: nom d'utilisateur}; User.findOne(requête, rappel); } module.exports.getUserById = function(id, callback){ User.findById(id, callback); } module.exports.comparePassword = function(candidatePassword, hash, callback){ bcrypt.compare(candidatePassword, hash, function(err, isMatch) { if(err) throw err; callback(null, isMatch); }); }
Ce modèle décrit à quoi ressembleront nos paramètres utilisateur ainsi que la manière dont nous y accéderons. J'ai déjà mentionné que nous crypterons nos mots de passe. ceci afin qu'aucun mot de passe ne soit stocké dans la base de données en cas de violation. Les mots de passe sont hachés à l'aide du middleware bcrypt.
Étape 5: compteur de trafic
Je voulais voir combien d'utilisateurs uniques ont visité ma page Web et compter le nombre de "coups". Il y a plusieurs façons de le faire, je vais vous expliquer comment je m'y suis pris.
Cela utilise une collection mongodb pour suivre combien d'utilisateurs ont visité ma page et combien de fois chaque visiteur unique a visité.
Puisque nous avons déjà parlé de la mise en place d'un mongoDB, je ne le reverrai plus.
Vous devrez peut-être ajouter deux collections à votre base de données afin de compiler. Pour ce faire, vous pouvez soit installer RoboMongo si vous utilisez une interface utilisateur, mais si vous utilisez un raspberry pi sans tête comme je le suis, vous vous amuserez avec les commandes suivantes.
Coquille de mongo
Pour éditer une base de données, obtenir des informations ou créer une collection, vous aurez besoin du shell mongo sur une unité sans tête.
Courir
mongo
Cela ouvrira le shell.
Ajouter une collection
Dans mon cas, la base de données s'appelle loginapp, vous pouvez la nommer comme vous le souhaitez.
utiliser nomdevotreb
Nous avons besoin d'une collection pour contenir toutes nos adresses IP des utilisateurs qui visitent notre site.
db.creatCollection("ip")
Ensuite, nous créons une collection pour compter les visites uniques sur notre site. Ceci est initialisé avec un identifiant et un compte commençant à 0.
db.createCollection("count", {id: "hit counter", count:0})
Suivre les adresses IP
Pour ce faire, nous allons extraire l'adresse IP des utilisateurs lorsqu'ils visitent notre page d'accueil, incrémenter notre nombre et les stocker pour les comparer plus tard.
Nous devons créer des modèles pour stocker nos schémas de mangouste et ajouter du code à notre fichier homepage.js.
Nous créons count.js et ip.js et les stockons dans notre dossier models.
Le fichier ip.js n'est qu'un schéma de notre adresse IP
var mangouste = require('mangouste'); //gestionnaire de paquets pour mongo
//Count Schema var IpSchema = mongoose. Schema({ ip: { type: String, }, count: { type: Number, } }); var Ip = module.exports = mongoose.model('Ip', IpSchema);
count.js sera appelé par notre page d'accueil pour lancer le suivi des hits. Ceci est fait comme ci-dessous.
//Homepagerouter.get('/', function(req, res){ publicIp.v4().then(ip => { Public_ip = ip; console.log("ipv4: "+ Public_ip); //=> ' 46.5.21.123' }); publicIp.v6().then(ip => { console.log("ipv6" + ip); Public_ip=ip; //=> 'fe80::200:f8ff:fe21:67cf' });
Count.getCount(collection, ipc, Public_ip, function(count){
}); count = db.collection('count').findOne({id: "hit counter"}, function(err, count){ userCount = count.count; res.render('homepage', {count: userCount}); }); });
Cela se produit chaque fois que quelqu'un se rend sur notre page d'accueil, dans ce cas theinternet.onthewifi.com/homepage.
Il vérifie l'adresse IP de l'utilisateur, ip4 ou ip6, puis stocke cette valeur où il l'envoie à count.get.collection qui est une fonction stockée dans notre fichier count.js.
Après avoir vérifié l'unicité de l'utilisateur, il renvoie et publie la valeur de comptage sur la page d'accueil en tant que variable de guidon.
Le fichier count.js est le suivant.
//count.jsvar mongo = require('mongodb'); //prend en charge la base de données var mongoose = require('mongoose'); //gestionnaire de packages pour mongo mongoose.connect('mongodb://localhost/loginapp'); var db = mangouste.connexion; var Ip = require('../models/ip'); //Count Schema var CountSchema = mongoose. Schema({ id: { type: String, }, count: { type: Number, } }); var Count = module.exports = mongoose.model('Count', CountSchema); module.exports.getCount = function(count, ipc, Public_ip, callback){ //count is test, callback isfunction ipc.findOne({ip: Public_ip}, function(err, iptest){ if(!iptest)//add une nouvelle ip si elle n'est pas dans la base de données, et mettez à jour le compteur { var new_ip = new Ip({ ip: Public_ip, count: 1 }); db.collection('ip').save(new_ip);//add new ip to database count.update(//mettre à jour le compteur d'accès { id: "hit counter"}, { $inc: {count: 1} }) } else//mettre à jour le compteur IP spécifique, pour voir qui visite le plus { ipc.update({ ip: Public_ip }, { $inc: {count: 1} }) } }); }
Cela crée le schéma de comptage et notre fonction.getCount. La fonction.getCount vérifie la base de données pour l'adresse IP de l'utilisateur et si elle la trouve, la fonction incrémente le nombre de cet utilisateur, pas le compteur d'accès. Cependant, si l'adresse IP de l'utilisateur n'est pas trouvée, un nouvel objet de collection sera créé avec l'adresse IP de l'utilisateur et incrémentera le compteur d'accès de 1.
Celui-ci est ensuite renvoyé et affiché sur la page Web.
Là, vous l'avez un compteur de succès de suivi ip.
Étape 6: Bloguer
J'essaie actuellement de développer un blog centralisé sur mes intérêts concernant les logiciels, les maisons intelligentes et les Polaroids. J'ai donc créé une section blog. Le blog utilise des pages html statiques et le framework de guidon. Après avoir recherché de meilleures technologies pour rendre les blogs plus faciles, j'ai depuis repensé mon site Web à l'aide d'Hugo. Hugo est un générateur html statique. J'en parle plus dans le tutoriel mentionné ci-dessous.
Étape 7: Terminé
Voilà un tutoriel détaillé sur mon site Web node.js hébergé localement sur mon raspberry pi. Si vous avez des questions ou des commentaires, veuillez les laisser ci-dessous.
J'espère que cela aidera d'autres personnes.
Pour une approche différente de ce site utilisant hugo, un générateur de page web statique voir mon autre tutoriel (à venir).
Conseillé:
Contrôle de la luminosité des LED par Raspberry Pi et page Web personnalisée : 5 étapes
Contrôle de la luminosité de la LED par Raspberry Pi et page Web personnalisée : en utilisant un serveur Apache sur mon pi avec php, j'ai trouvé un moyen de contrôler la luminosité d'une LED à l'aide d'un curseur avec une page Web personnalisée accessible sur n'importe quel appareil connecté au même réseau que votre pi .Il y a beaucoup de façons dont cela peut être ac
Ventilateur ESP8266 POV avec horloge et mise à jour du texte de la page Web : 8 étapes (avec images)
Ventilateur POV ESP8266 avec horloge et mise à jour du texte de la page Web : il s'agit d'un ventilateur POV (Persistance de la vision) à vitesse variable qui affiche l'heure par intermittence et deux messages texte pouvant être mis à jour "à la volée". Le ventilateur POV est également un serveur Web à page unique qui vous permet de modifier les deux textes moi
Comment créer une page Web simple à l'aide de crochets pour les débutants : 14 étapes
Comment créer une page Web simple à l'aide de crochets pour les débutants : IntroductionLes instructions suivantes fournissent des instructions étape par étape pour créer une page Web à l'aide de crochets. Brackets est un éditeur de code source axé principalement sur le développement Web. Créé par Adobe Systems, il s'agit d'un logiciel gratuit et open source sous licence
Comment créer un site Web sur un Raspberry Pi, avec Node.js, Express et MongoDB Partie 1 : 6 étapes
Comment créer un site Web sur un Raspberry Pi, avec Node.js, Express et MongoDB… Partie 1 : Bienvenue dans la PARTIE 1 de mon didacticiel sur l'application Web node.js. La partie 1 passera en revue le logiciel nécessaire utilisé pour le développement d'applications node.js, comment utiliser la redirection de port, comment créer une application à l'aide d'Express et comment exécuter votre application. La deuxième partie de ce
Fusionner votre page Web (Google Page Creator) avec Picasa on Line Album : 5 étapes
Fusionnez votre page Web (créateur de page Google) avec Picasa sur l'album en ligne : Bonjour, voici mon premier Instructable, profitez-en ! continuer avec cette instructable Configuration d'un site Web avec le créateur de page de Google