đ SAISON B Semaine 4 Ăpisode 4 - Projet en autonomie Jour 2 - Structuration MVC et Dynamisation des Pages
đ Introduction
DeuxiĂšme jour de travail sur le projet oCoffee ! Aujourdâhui, jâai avancĂ© sur la structuration de lâarchitecture MVC et la dynamisation des pages. Mon objectif Ă©tait de rendre les pages du site fonctionnelles de maniĂšre statique, puis de commencer Ă les dynamiser avec des donnĂ©es JSON. Voici le bilan de la journĂ©e.
Note
Le dépÎt Github du projet est disponible ici.
Ătape 1 : Structuration de lâarchitecture MVC
Contexte
Les vues pour la page dâaccueil et le catalogue Ă©taient dĂ©jĂ fournies dans le dossier dâintĂ©gration du projet, avec leurs styles CSS respectifs. Mon travail a consistĂ© Ă :
- CrĂ©er les vues manquantes (page de dĂ©tails dâun cafĂ© et page de prĂ©sentation de la boutique).
- Configurer les routes et contrĂŽleurs pour chaque page.
Structure du Projet :
đocoffee/
â
âââ đnode_modules/ # Folder generated by npm (do not version)
â
âââ đdata/ #Database folder
â âââ create-db.sql
â âââ coffee-sample-data.json
â
âââ đdocs/ # Project specifications folder
â âââ đintegration/
â âââ đproject-brief/
â âââ đproject-design/
â
âââ đpublic/ # Static files (CSS, JS, images)
â âââ đcss/ # Style sheets
â âââ đimages/ # Images for the site (logos, cafes, etc.)
â âââ đjs/ # Client-side JavaScript scripts
â
âââ đsrc/ # Application source code
â âââ đcontrollers/ # Controllers (business logic)
â â âââ home.controller.js
â â âââ catalog.controller.js
â â âââ coffee-datails.controller.js
â â
â âââ đmodels/ # Models (interactions with the database)
â â âââ coffee.dataMapper.js
â â âââ databaseClient.js # Connection to database
â â
â âââ đrouters/ # Express routes handlers
â â âââ home.router.js
â â âââ catalog.router.js
â â âââ coffee-details.router.js
â â âââ index.router.js
â â
â âââ đviews/ # EJS views (templates)
â âââ đpartials/ # Reusable partials (header, footer)
â â âââ header.ejs
â â âââ footer.ejs
â âââ home.ejs # Home page
â âââ catalog.ejs # Coffee catalogue page
â âââ coffee-details.ejs # Coffee details page
â
âââ index.js # Express app entry point
âââ package.json # Dependencies and npm scripts
âââ package-lock.json
âââ .env # Environnement variables
âââ .env.example # Public environnement variables
âââ README.md # Project documentation
Actions réalisées
- Création des wireframes pour les pages manquantes :
- Page de dĂ©tail dâun cafĂ© : Affichage des informations spĂ©cifiques (nom, origine, prix, caractĂ©ristiques, etc.).

- Page de dĂ©tail dâun cafĂ© : Affichage des informations spĂ©cifiques (nom, origine, prix, caractĂ©ristiques, etc.).
- Développement des vues EJS de maniÚre statique :
- Récupération de la page d'intégration home.html et conversion en
home.ejs. - Récupération de la page d'intégration catalog.html et conversion en
catalog.ejs. - Création de
coffee-details.ejspour la page de dĂ©tail dâun cafĂ©. - CrĂ©ation
shop.ejspour la page de présentation de la boutique.
- Récupération de la page d'intégration home.html et conversion en
-
Création des routes et contrÎleurs :
home.router.jsethome.controller.jspour gĂ©rer la page d'accueil.catalog.router.jsetcatalog.controller.jspour gĂ©rer les requĂȘtes liĂ©es aux cafĂ©s.shop.router.jsetshop.controller.jspour la page de prĂ©sentation de la boutique.index.routerpour regrouper tous les routeurs.
Exemple sur la Home Page :
<%- include('partials/header.ejs') %> <section id="about"> <div> <h1>Votre spĂ©cialiste Haucloquois du cafĂ©</h1> <p>oCoffee est un dĂ©taillant de cafĂ© et de produits associĂ©s Ă la consommation du cafĂ© basĂ© dans la ville de Hauts-de-Cloques. Nous importons nos produits directement des producteurs, et nous les sĂ©lectionnons selon des critĂšres exigeants de qualitĂ©. oCoffee est reconnu Ă lâĂ©chelle dĂ©partementale.</p> <a class="button" href="#">DĂ©couvrir notre catalogue</a> </div> <img src="./images/about.jpg" alt="Selection de nos meilleurs cafĂ©s oCoffee"> </section> <section id="latest-products"> <h2>NouveautĂ©s</h2> <ul> <li> <article> <img src="./images/coffees/100955890.png" alt="Ethiopian Yirgacheffe"> <div> <h3>Ethiopian Yirgacheffe</h3> <a class="button-outline" href="#">Voir le dĂ©tail</a> </div> </article> </li> <li> <article> <img src="./images/coffees/100955890.png" alt="Ethiopian Yirgacheffe"> <div> <h3>Ethiopian Yirgacheffe</h3> <a class="button-outline" href="#">Voir le dĂ©tail</a> </div> </article> </li> <li> <article> <img src="./images/coffees/100955890.png" alt="Ethiopian Yirgacheffe"> <div> <h3>Ethiopian Yirgacheffe</h3> <a class="button-outline" href="#">Voir le dĂ©tail</a> </div> </article> </li> </ul> </section> <%- include('partials/footer.ejs') %>/** * Controller for handling home page logic. * @module controllers/homeController */ export default { /** * Renders the home page. * @function * @param {import('express').Request} req - Express request object * @param {import('express').Response} res - Express response object */ displayHome: (req, res) => { res.render('home'); }, }import { Router } from "express"; import homeController from "../controllers/home.controller.js"; /** * Router for handling home page related routes. * @module routers/homeRouter */ const homeRouter = Router(); /** * GET / * Route for rendering the home page. * Calls the displayHome method from homeController. */ homeRouter.get('/', homeController.displayHome); export default homeRouter;Router principal
src/routers/index.router.jsimport { Router } from 'express'; import homeRouter from './home.router.js'; /** * Main router that combines all sub-routers for the application. * @module routers/indexRouter */ const router = Router(); /** * Use the home router for home page related routes. */ router.use(homeRouter); export default router; -
Mise Ă jour du fichier
index.js:index.js/** * Main entry point for the Ocoffee application. * Sets up the Express server, view engine, static files, and routing. */ import express from "express"; import 'dotenv/config'; import router from "./src/routers/index.router.js"; // Get the port from environment variables const PORT = process.env.PORT; const app = express(); /** * Set EJS as the view engine. * Views are located in the './src/views' directory. */ app.set('view engine', 'ejs'); app.set('views', './src/views'); /** * Serve static files from the 'public' directory. */ app.use(express.static('./public')); /** * Use the main router for handling all routes. */ app.use(router); /** * Start the server and listen on the specified port. * Logs a message when the server is running. */ app.listen(PORT, () => { console.log(`Server is running on http://localhost:${PORT}`); });
Ătape 2 : Dynamisation des pages avec des donnĂ©es JSON
Objectif
Avant de me connecter Ă une base de donnĂ©es PostgreSQL, jâai dĂ©cidĂ© de simuler une base de donnĂ©es avec un fichier JSON contenant un Ă©chantillon de donnĂ©es sur les cafĂ©s. Cela me permet de tester le rendu dynamique des pages sans dĂ©pendre dâune base de donnĂ©es.
Actions réalisées
-
Création du fichier
data/coffee-sample-data.json: -
Intégration des données JSON dans les contrÎleurs :
Exemple sur la Home Page :
src/controller/home.controller.jsimport coffees from '../../data/coffee-sample-data.json' with { type: 'json' }; /** * Controller for handling home page logic. * @module controllers/homeController */ export default { /** * Renders the home page with the three latest coffees. * Sorts the coffee data by reference in descending order and selects the top three. * * @function * @param {import('express').Request} req - Express request object * @param {import('express').Response} res - Express response object * @returns {void} */ displayHome: (req, res) => { // Sort the coffees array by reference in descending order const sortedCoffees = coffees.toSorted((a, b) => b.reference - a.reference); // Select the three latest coffees const threeLatestCoffees = sortedCoffees.slice(0, 3); // Render the 'home' view, passing the three latest coffees to the template res.render('home', { coffees: threeLatestCoffees }); }, }; -
Affichage dynamique dans les vues EJS :
src/views/home.ejs<%- include('partials/header.ejs') %> <section id="about"> <div> <h1>Votre spĂ©cialiste Haucloquois du cafĂ©</h1> <p>oCoffee est un dĂ©taillant de cafĂ© et de produits associĂ©s Ă la consommation du cafĂ© basĂ© dans la ville de Hauts-de-Cloques. Nous importons nos produits directement des producteurs, et nous les sĂ©lectionnons selon des critĂšres exigeants de qualitĂ©. oCoffee est reconnu Ă lâĂ©chelle dĂ©partementale.</p> <a class="button" href="/Catalogue">DĂ©couvrir notre catalogue</a> </div> <img src="./images/about.jpg" alt="Selection de nos meilleurs cafĂ©s oCoffee"> </section> <section id="latest-products"> <h2>NouveautĂ©s</h2> <ul> <!-- Replace hard coding by a for...of loop with data from home.controller context --> <% for( const coffee of coffees ) { %> <li> <article> <img src="./images/coffees/<%= coffee.image %>" alt="<%= `image de cafĂ© ${coffee.name}` %>"> <div> <h3><%= coffee.name %></h3> <a class="button-outline" href="/Catalogue/Cafe/<%= coffee.reference %>">Voir le dĂ©tail</a> </div> </article> </li> <% } %> </ul> </section> <%- include('partials/footer.ejs') %>
Voir le code complet sur mon dépÎt Github.
Ătape 3 : RĂ©solution dâun bug dâaffichage
ProblÚme rencontré
En testant la page de dĂ©tail dâun cafĂ©, jâai rencontrĂ© une erreur dans la console :
Refused to apply style from '<URL>' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
Diagnostic
Cette erreur indiquait que le navigateur refusait dâappliquer le fichier CSS car il ne le reconnaissait pas comme une feuille de style. AprĂšs investigation, jâai rĂ©alisĂ© que le problĂšme venait des chemins des fichiers statiques dans ma vue EJS.
Solution
Dans le fichier dâintĂ©gration HTML fourni, les chemins vers les fichiers CSS Ă©taient sous la forme ../css/style.css. Or, avec EJS et Express, les fichiers statiques doivent ĂȘtre rĂ©fĂ©rencĂ©s depuis le dossier public/ avec un chemin absolu :
Une fois cette petite correction effectuĂ©e, le style sâest appliquĂ© correctement.
J'ai modifié toutes les vues ejs en faisant attention aux chemins des fichiers statiques.
Bilan de la journée
Ce qui a bien fonctionné
â
Structuration MVC : Les routes, contrÎleurs et vues sont maintenant bien organisés.
â
Dynamisation des pages : Les données JSON sont correctement intégrées et affichées.
â
RĂ©solution du bug : Jâai compris lâimportance des chemins des fichiers statiques dans un projet Express.
Difficultés rencontrées
â ïž Chemins des fichiers statiques : Une erreur simple mais qui mâa fait perdre du temps.
Objectifs pour demain
đč CrĂ©ation de la base de donnĂ©es PostgreSQL :
- Implémenter le MPD créé hier.
- Connecter lâapplication Express Ă la base de donnĂ©es.
đč Remplacer les donnĂ©es JSON par des requĂȘtes SQL :
- Utiliser
pgpour interagir avec PostgreSQL. - Mettre à jour les contrÎleurs pour récupérer les données depuis la base de données.
Conclusion
Cette deuxiĂšme journĂ©e a Ă©tĂ© intense mais trĂšs formatrice. Jâai pu appliquer les concepts MVC, dynamiser mes pages et rĂ©soudre des problĂšmes techniques. Demain, je passe Ă lâĂ©tape cruciale de la crĂ©ation et connection Ă la base de donnĂ©es !