Files
Portfolio-Codex/docs/stories/1.3.templates-php-base.md

273 lines
7.9 KiB
Markdown

# Story 1.3: Templates PHP de Base (Header/Footer)
## Status
Ready for Dev
## Story
**As a** développeur,
**I want** créer les templates PHP réutilisables pour le header et le footer,
**so that** je ne duplique pas le code HTML commun sur chaque page.
## Acceptance Criteria
1. `templates/header.php` contient le doctype, head, meta tags SEO de base, et lien vers le CSS
2. `templates/footer.php` contient la fermeture body, les scripts JS, et le copyright
3. Le header inclut les balises meta viewport pour le responsive
4. Le header permet de passer un titre de page dynamique via une variable PHP
5. Les templates sont inclus dans `index.php` et la page s'affiche correctement
6. Une fonction helper `include_template()` est créée pour inclure les templates avec des données
## Tasks / Subtasks
- [] **Task 1 : Créer la fonction helper include_template()** (AC: 6)
- [] Créer le fichier `includes/functions.php`
- [] Implémenter la fonction `include_template($name, $data = [])`
- [] La fonction doit utiliser `extract()` pour passer les variables au template
- [] Gérer le chemin vers le dossier templates/
- [] **Task 2 : Créer le template header.php** (AC: 1, 3, 4)
- [] Créer `templates/header.php`
- [] Ajouter le doctype HTML5
- [] Ajouter les meta tags essentiels (charset, viewport, description)
- [] Ajouter les meta tags Open Graph de base
- [] Ajouter le lien vers `output.css`
- [] Ajouter le preload des polices
- [] Permettre un titre dynamique via `$pageTitle`
- [] Permettre une description dynamique via `$pageDescription`
- [] **Task 3 : Créer le template footer.php** (AC: 2)
- [] Créer `templates/footer.php`
- [] Ajouter le copyright avec l'année dynamique
- [] Ajouter le lien vers `main.js` avec attribut `defer`
- [] Fermer les balises body et html
- [] **Task 4 : Mettre à jour index.php** (AC: 5)
- [] Inclure `includes/functions.php`
- [] Utiliser `include_template('header', ['pageTitle' => '...'])`
- [] Ajouter un contenu de test minimal
- [] Utiliser `include_template('footer')`
- [] **Task 5 : Tester l'affichage**
- [] Lancer le serveur PHP local
- [] Vérifier que la page s'affiche correctement
- [] Vérifier le titre dans l'onglet du navigateur
- [] Vérifier que le CSS est chargé
- [] Valider le HTML avec W3C Validator
## Dev Notes
### Fonction include_template()
```php
// includes/functions.php
/**
* Inclut un template avec des données
* @param string $name Nom du template (sans .php)
* @param array $data Variables à passer au template
*/
function include_template(string $name, array $data = []): void
{
extract($data);
include __DIR__ . "/../templates/{$name}.php";
}
```
### Contenu templates/header.php
```php
<?php
/**
* Template Header
* Variables disponibles :
* - $pageTitle (string) : Titre de la page
* - $pageDescription (string, optionnel) : Meta description
*/
$pageTitle = $pageTitle ?? 'Portfolio - Développeur Web';
$pageDescription = $pageDescription ?? 'Portfolio de développeur web full-stack. Découvrez mes projets, compétences et parcours.';
$siteName = 'Portfolio';
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="<?= htmlspecialchars($pageDescription, ENT_QUOTES, 'UTF-8') ?>">
<!-- Open Graph -->
<meta property="og:title" content="<?= htmlspecialchars($pageTitle, ENT_QUOTES, 'UTF-8') ?>">
<meta property="og:description" content="<?= htmlspecialchars($pageDescription, ENT_QUOTES, 'UTF-8') ?>">
<meta property="og:type" content="website">
<meta property="og:locale" content="fr_FR">
<!-- Preload fonts -->
<link rel="preload" href="/assets/fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/assets/fonts/jetbrains-mono-var.woff2" as="font" type="font/woff2" crossorigin>
<!-- Favicon -->
<link rel="icon" href="/assets/img/favicon.ico" type="image/x-icon">
<!-- CSS -->
<link rel="stylesheet" href="/assets/css/output.css">
<title><?= htmlspecialchars($pageTitle, ENT_QUOTES, 'UTF-8') ?> | <?= $siteName ?></title>
</head>
<body class="bg-background text-text-primary font-sans antialiased">
```
### Contenu templates/footer.php
```php
<?php
/**
* Template Footer
*/
$currentYear = date('Y');
?>
<!-- Footer -->
<footer class="bg-surface border-t border-border py-8 mt-auto">
<div class="container-content text-center">
<p class="text-text-muted text-sm">
&copy; <?= $currentYear ?> Portfolio. Tous droits réservés.
</p>
</div>
</footer>
<!-- Scripts -->
<script src="/assets/js/main.js" defer></script>
</body>
</html>
```
### Structure index.php mise à jour
```php
<?php
// index.php - Point d'entrée
require_once __DIR__ . '/includes/functions.php';
// Inclure le header avec le titre
include_template('header', [
'pageTitle' => 'Accueil',
'pageDescription' => 'Portfolio de développeur web. Découvrez mes projets et compétences.'
]);
?>
<main class="min-h-screen">
<div class="container-content py-20">
<h1 class="text-display text-center">Hello World</h1>
<p class="text-center text-text-secondary mt-4">
Le portfolio est en construction.
</p>
</div>
</main>
<?php include_template('footer'); ?>
```
### Conventions pour les Variables de Template
| Variable | Type | Obligatoire | Description |
|----------|------|-------------|-------------|
| `$pageTitle` | string | Oui | Titre affiché dans l'onglet |
| `$pageDescription` | string | Non | Meta description SEO |
| `$bodyClass` | string | Non | Classes additionnelles sur body |
### Meta Tags SEO Inclus
- `charset` : UTF-8
- `viewport` : responsive mobile-first
- `description` : description de la page
- `og:title` : titre Open Graph
- `og:description` : description Open Graph
- `og:type` : website
- `og:locale` : fr_FR
### Fichier main.js Minimal
Créer `assets/js/main.js` avec un contenu minimal pour éviter l'erreur 404 :
```javascript
// assets/js/main.js
// Script principal du portfolio
document.addEventListener('DOMContentLoaded', () => {
console.log('Portfolio chargé');
});
```
## Testing
### Validation Manuelle
- [ ] La page index.php s'affiche sans erreur PHP
- [ ] Le titre de l'onglet affiche "Accueil | Portfolio"
- [ ] Le fond est sombre (#17171F)
- [ ] Le texte "Hello World" est visible et stylé
- [ ] Pas d'erreur 404 dans la console (CSS, JS)
- [ ] Le HTML est valide (W3C Validator)
### Commandes de Test
```bash
# Lancer le serveur PHP
php -S localhost:8000
# Ouvrir dans le navigateur
# http://localhost:8000
# Vérifier les erreurs dans la console DevTools
```
### Checklist Accessibilité
- [ ] `lang="fr"` sur la balise html
- [ ] Meta viewport présent
- [ ] Titre de page descriptif
- [ ] Structure sémantique (main, footer)
## Change Log
| Date | Version | Description | Author |
|------|---------|-------------|--------|
| 2026-01-22 | 0.1 | Création initiale de la story | Sarah (PO) |
## Dev Agent Record
### Agent Model Used
Claude Opus 4.5 (claude-opus-4-5-20251101)
### Debug Log References
_À compléter par le dev agent_
### Completion Notes List
- Fonction include_template() créée avec extract() pour les variables
- header.php avec doctype, meta SEO, Open Graph, preload fonts, CSS link
- footer.php avec copyright dynamique et script main.js defer
- index.php mis à jour pour utiliser les templates
- main.js créé (minimal) pour éviter erreur 404
- Syntaxe PHP validée sans erreurs
- CSS regénéré avec nouvelles classes (7,7 Ko)
### File List
| Fichier | Action |
|---------|--------|
| `includes/functions.php` | Créé |
| `templates/header.php` | Créé |
| `templates/footer.php` | Créé |
| `assets/js/main.js` | Créé |
| `index.php` | Modifié |
| `assets/css/output.css` | Regénéré |
## QA Results
_À compléter par le QA agent_