Sommaire

BONJOUR
Musique "Invention BWV988" J.S. BACH 1685-1750

Tutoriel et Help

- WEBSite -


ASM Mode Reel

Nous veillons aux respects des droits d'auteur : si par erreur un contenu protégé
est disponible sans indication sur ce site, merci de contacter l'administrateur,
il sera retiré ou mis à jour dans les plus brefs délais.


Prgm du WEB

Programmation web

tchats

Un article de Wikipédia,l'encyclopédie libre.

La programmation web peut prendre différentes formes : de la simple page statique à la page dynamique avec connexion à une base de données. Nous allons tracer ici un bref aperçu de différentes technologies possibles dans la programmation côté client ou côté serveur.

  • 1 Bases de la page web - Les langages de balisage
  • 2 Insertion d'objets
  • 3 Programmation web côté client
  • 4 Programmation web côté serveur
  • 5 Voir aussi

Bases de la page web - Les langages de balisage

Langage HTML ou XHTML

Toute page web comprend une base de langage HTML ou XHTML. Il s'agit d'un langage de balisage qui définit essentiellement la structure de la page web (titres, tableaux, paragraphes, etc.).

C'est un langage qui permet de créer des hyperliens, à savoir des liens d'un document à un autre ou d'un endroit d'un document à un autre endroit du même document (identificateur de fragment).

Au départ ce langage ne définissait que la structure de la page mais très vite se sont rajoutées des balises (ou tags) qui s'occupaient de mettre en forme le document (mise en gras, en italique, choix d'une police de caractère, ...).

Depuis sa version 4, le langage HTML s'accompagne des CSS (Cascading Style Sheets - Feuilles de style en cascade) qui sont des styles qui se chargent de la mise en forme de la page.

Le XHTML est une évolution du HTML basée sur XML.

Limites du HTML

Une page web créée en HTML est totalement statique et n'offre qu'une faible possibilité d'interaction avec le visiteur. Chaque page doit être créée au préalable et doit être manuellement mise à jour.

Concernant l'aspect dynamique, seules existent deux balises HTML (<marquee> et <blink>), mais sont propriétaires à Microsoft et ne sont pas reconnues par le W3C.

Quelques fonctionnalités des CSS permettaient de créer un peu de dynamisme dans la page (ex. changement de couleur lors d'un survol). Le CSS 3.0 est en train de changer la donne.

À propos de l'interactivité, le langage HTML permet uniquement de créer le fond d'un formulaire d'interaction avec le visiteur. Il permet de définir les paramètres d'une action, et de renvoyer les données du formulaire vers un 'système' qui gèrera celles-ci, mais ne permet pas de définir l'action elle-même.

Portabilité

Le langage HTML est multiplateformes. Tous les navigateurs web reconnaissent le langage HTML de base, seuls certaines balises sont propres à certains navigateurs (comme la balise <marquee> qui n'est interprété comme défilement de texte que dans Internet Explorer et Google Chrome. Les CSS, même s'ils sont standardisés par le W3C, ne sont pas toujours reconnus de la même manière par les différents navigateurs web.

Mise en place

Le langage HTML a l'avantage d'être facile à mettre en place, et ne demande pas de compétences techniques très poussées. Ses pages sont d'un traitement très léger et rapide par le serveur.

Il faut donc autre chose pour ajouter de l'animation ou de l'interactivité dans la page web.

XML (eXtended Markup Language)

Le langage de balisage XML peut également servir de base à une page web. Le fichier XML contiendra le contenu de la page web. Ce fichier sera lié à un fichier XSL (Feuilles de style XML) qui mettra en forme les données du fichier XML.

La plupart du temps, la page web ne sera pas basée sur un fichier XML natif mais celui-ci sera généré dynamiquement par un des langages de programmation web ci-dessous.

Insertion d'objets

Une première technique pour rendre une page web plus dynamique, est d'y insérer des objets. Les objets seront insérés dans la page HTML grâce aux tags <object>, <img>, <applet> ou <script>.

Images

Un premier type d'objet sont les images qu'on intègre dans la page web. Les images sont généralement statiques sauf les gifs animés.

Portabilité

Pour autant qu'on se limite aux formats de fichiers standards pour le web (.gif, .jpg ou . jpeg et .png), les images sont sans doute un des objets les plus multi-plateforme du web : la majorité des navigateurs web savent afficher les images.

Mise en place

Les images numériques deviennent un média très "grand public" et sont assez aisées à implémenter dans un site web.

Multimédia

L'intégration de documents multimédia (son ou vidéo) va également permettre de 'dynamiser' un site mais ce genre de fichier est souvent très lourd au téléchargement.

Portabilité

Les fichiers multimédia de type son et vidéo ne sont pas lus en standard par les navigateurs web et donc, ils exigeront l'installation d'un "plugin" pour être lus.

Mise en place

Une fois le fichier son ou vidéo produit, le placement dans la page HTML n'est pas complexe.

Performance

Comme nous l'avons signalé, les fichiers multimédia sont souvent lourds et donc longs à télécharger. Ils vont donc fortement réduire les performances (temps de chargement) de la page web. Cependant il existe des technologies permettant la lecture en flux (streaming).

Dans le futur

la norme HTML5 devrait faciliter les points cités précédemment.

Animation Flash

Flash (de Adobe Systems - Macromedia) est un programme qui permet de créer des animations dans un format vectoriel propriétaire relativement léger. Le programme génère un fichier avec l'extension .fla qui est le fichier de travail et qui sera 'compilé' en un fichier avec l'extension .swf. Swift est un autre programme générant des fichiers swf hors de la sphère Macromedia.

Dans une page web, une animation Flash (fichier avec extension .swf) peut être intégrée comme partie de la page (une publicité, un menu, ...) ou l'ensemble de la page peut être en flash mais il y aura toujours un squelette HTML.

Flash permet de créer des animations de qualité, permet une certaine interaction avec l'utilisateur grâce au langage de programmation ActionScript (dérivé de ECMAScript comme JavaScript). Les dernières versions de Flash permettent également l'interfaçage avec une base de données.

Portabilité

L'utilisation de Flash dans une page web nécessite l'installation du plug-in "Flash player" qui n'est pas disponible pour tous les systèmes.

Mise en place

La création d'une animation Flash est une technologie complète en soi. La complexité dépendra du résultat attendu mais un beau résultat peut déjà être obtenu sans trop de difficultés. Une fois le fichier .swf créé, l'intégration dans une page HTML ne pose pas trop de problèmes.

Performance

Une page en Flash est plus lourde qu'une page HTML qui ne contiendrait que du code HTML mais reste beaucoup plus légère que la plupart des fichiers multimédia.

Utilisation

Avec Flash, il est possible de créer n'importe quoi. Mais on privilégiera des interfaces dynamiques (déplacements d'images, petites animations). En tant que partie d'une page, Flash se retrouvera fréquemment dans la création de bannières publicitaires et de petits jeux.

Applet Java (appliquette)

Il est également possible de créer des petits programmes avec interface dans un langage de programmation comme Java. Ces petits programme sont appelés Applets ou appliquettes. Ils sont complètement autonomes mais éventuellement paramétrables et s'intègrent dans une page web. Ils sont téléchargés avec la page web et exécutés par l'ordinateur client.

Portabilité

Le code est indépendant de la plate forme grâce à la machine virtuelle Java (un petit plug-in Java).

Mise en place

La programmation en Java est complexe et nécessite de bonnes connaissances en programmation. De nombreux outils de développement existent.

Performance

Les performances sont limitées par le téléchargement et l'implantation de la machine virtuelle.

Utilisation

Sur le web, on trouvera un grand nombre d'application aux applets : des jeux, des tchats , des menus, ...

Les applets gèrent bien le multi-utilisateur. Les fonctionnalités des applets sont strictement limitées au niveau sécurité (par exemple, un applet ne pourra jamais lancer une application sur la machine du client).

Attention, tous les niveaux de sécurité de tous les navigateurs n'acceptent pas le lancement d'applets.

Par ailleurs la machine virtuelle Java gère elle-même les allocations de mémoire (en langage C, la mémoire est gérée manuellement), ainsi les applications Java prennent plus de ressources.

ActiveX

Les ActiveX sont une solution de création d'applications développée par Microsoft. Les principes de fonctionnement sont très semblables au fonctionnement des applets. Voir aussi Component Object Model

Portabilité

Le code est dépendant de la plateforme le plus souvent (généralement système Windows et navigateur Internet Explorer)

Mise en place

La programmation peut se faire avec plusieurs langages (C++, Visual Basic, Java) mais nécessite de bonnes connaissances en programmation. De nombreux outils de développement existent.

Performance

Les performances sont bonnes grâce à la possibilité de compilation et la possibilité de mémorisation du programme chez le client.

Utilisation

Les possibilités d'utilisation des ActiveX sont énormes et il y a peu de limitations sécuritaires. À cause de cela et du lien avec une plate-forme, les ActiveX seront souvent réservés aux Intranets.

Programmation web côté client

Les objets ne fournissent pas toutes les solutions aux besoins d'interactivité et de dynamisme des sites ou sont parfois lourds à mettre en place. Il est possible alors de passer à de la programmation permettant une meilleure interaction avec la page HTML.

Principe

Lorsque le visiteur demande une simple page HTML (avec ou sans objets) en tapant une adresse ou URL, le serveur web lui renvoie simplement le contenu de la page demandée, c'est le navigateur web qui interprète le contenu HTML et les plug-ins qui interprètent les objets, en demandant à leur tour le contenu des objets au serveur web.

Si du code, côté client, est inséré dans la page, le serveur web renverra également la page au client, y compris le code. C'est donc, à nouveau le navigateur web qui doit interpréter le code et faire ce que le code demande.

Utilisation

La programmation côté client sera utilisée essentiellement dans le cas de validation de formulaires (champs obligatoires, petits calculs, ...) et dans la création de petites animations (menus déroulants...).

Langages de Script

La programmation côté client utilise des langages de scripts. À la différence d'autres langages de programmation, ces langages ne sont pas compilés. Ils sont interprétés par le navigateur web du visiteur, et leur syntaxe est moins stricte que celle des langages de développeurs (variables non-typées a priori, le point-virgule à la fin des instructions est optionnel...).

  • JavaScript est le plus utilisé des langages de programmation web côté client. Il est reconnu par tous les navigateurs (dans les versions actuelles). Il se base sur le langage normalisé ECMAScript.
  • JScript, fort proche du JavaScript est simplement une adaptation de celui-ci par Microsoft.
  • VBScript est le langage de script développé par Microsoft sur base du Visual Basic. Ce langage n'est interprété que par les navigateurs basés sur ceux développés par Microsoft (soit Internet Explorer et Maxthon). Il est donc peu utilisé sur l'Internet (mais utilisé parfois sur des intranets).
  • DHTML n'est PAS un langage de script mais simplement la combinaison, dans une page web, de JavaScript, de HTML 4 ou de XHTML et de CSS.

Avantages et inconvénients

  • Avantages :

La programmation côté client est légère et relativement simple à implémenter (syntaxe pas trop complexe).

  • Inconvénients :

Le code est envoyé tel quel au client, et donc visible par celui-ci (s'il regarde les sources de sa page) et donc peu sécurisé. Le bon déroulement du programme dépend entièrement du navigateur du client, de sa configuration et de son niveau de sécurité.

Il n'est donc pas question ici de lier le site web à une base de données.

Programmation web côté serveur

Principe

Lors de l'insertion de programmation côté serveur dans une page, lorsque le visiteur demande la page, le serveur va d'abord lire celle-ci, il va interpréter le code serveur et encapsuler le résultat dans la page HTML. Cette dernière sera expédiée au visiteur sans plus aucune trace du code serveur. Le visiteur reçoit donc une pure page html (avec éventuellement encore du code client).

De ce processus, on gagne énormément en sécurisation du code. On a aussi un grand nombre de possibilité d'interactions avec d'autres systèmes ou applications comme les bases de données.

Les fichiers des pages "côté serveur" ont généralement une extension autre que .htm ou .html. L'extension dépendra de la technologie utilisée.

Différentes technologies

Technologies Microsoft

  • ASP (Active Server Pages) : Technologie développée par Microsoft à partir de 1996 dans le but de créer des pages dynamiques. ASP permet d'ajouter du code dans la page HTML qui sera interprété par le serveur. La partie ADO (ActiveX Data Object) de ASP permet de se connecter à une base de données.
    • Langages utilisés : VBScript (langage par défaut) ou JScript.
    • Portabilité : La technologie est implémentée sur les serveurs web de Microsoft (IIS et PWS).
    • Mise en place : Utilisation de langage de Script donc d'accès relativement aisé (mais se complexifie vite).
    • Performance : Bonne performance surtout si l'on utilise du code compilé (dll).
    • Utilisation : Tout site web dynamique peut être créé en ASP.
    • Dernière version : ASP 3.0.
  • ASP.NET : Technologie développée par Microsoft sur base du Framework.Net. L'évolution est importante par rapport à ASP et les possibilités deviennent quasi infinies. ASP.NET a le gros avantage, par rapport à d'autres technologies, de bien séparer le contenu de la page web, sa mise en forme et la programmation des aspects dynamiques (travail en Code Behind).
    • Langages utilisés : C#, VB.Net, JavaScript.Net... et de nombreux autres langages partageant le Common Runtime Language du Framework.Net.
    • Portabilité : La technologie est implémentée sur les serveurs web de Microsoft (IIS 2003).
    • Mise en place : Utilisation de langage de programmation et nécessite donc de bonnes bases en programmation mais le langage importe peu (plusieurs langages possibles). Avec la version 2 (ASP.NET 2.0) et un outil de développement comme Visual Studio, le développement d'applications peut déjà aller très loin sans programmation : beaucoup de contrôles sont gérés par leurs propriétés.
    • Performance : Excellentes performances car tout le code est compilé (soit précompilé, soit compilé à la volée).
    • Utilisation : Tout type d'application web peut être créé avec ASP.NET.

PHP

PHP (PHP: Hypertext Preprocessor) est un langage de script interprété côté serveur. Le code PHP est lu par le serveur et interprété pour produire une page HTML (ou d'autres types de fichier comme des images ou des documents PDF) à chaque fois que la page sera demandée. Ce langage a été créé initialement dans le cadre des logiciels Open Source. De nombreux développeurs ont ensuite profité de l'Open Source pour développer de nombreux modules prêts à l'usage et paramétrables à volonté.

  • Portabilité : Les modules serveurs de PHP sont implémentés sur les serveurs Apache et Unix mais PHP peut être implémenté sur d'autres plates-formes via des CGI. PHP travaille généralement avec une base de données MySQL.
  • Mise en place : PHP est un langage de script, donc relativement facile à apprendre. La syntaxe est simplifiée, mais part d'une base de C.
  • Performance : Très bonnes performances. La seule limite serait l'évolution rapide des modules et donc parfois le besoin de "rafraîchir" la programmation.[précision nécessaire]
  • Utilisation : Tout type d'application web peut être créé avec PHP.
  • Dernière version : PHP 5.5.

Technologies Java

  • JSP (Java Server Pages) : Technologie développée par Sun Microsystems dans le but de créer des pages dynamiques avec le langage Java. Les JSP permettent d'ajouter du code Java dans la page HTML qui sera interprété par le serveur. On peut distinguer trois ensembles d'instructions JSP :
    • Les instructions de programmation permettent d’insérer des bouts de code Java directement dans la page web, et donnent accès à une grande partie de la bibliothèque de programmation de la version standard de Java (composants JavaBeans, accès aux bases de données via JDBC etc.)
    • Les directives qui permettent de spécifier certaines propriétés de la page, l’inclusion du contenu d’autres fichiers et l’utilisation d’autres classes et bibliothèques de balises personnalisées.
    • Les actions permettent essentiellement d’utiliser des composants JavaBeans existants.
    • Portabilité : Très grande portabilité grâce à Java : serveurs Apache mais aussi IIS, etc.
    • Mise en place : Utilisation de Java comme langage de programmation.
    • Performance : Très variable en fonction de l'implémentation utilisée.
    • Utilisation : Tout type de fonctionnalités.
  • Servlets : Le nom vient d'une analogie possible à faire avec les applets. Il s'agit donc de programmes créés en Java et tournant sur le serveur web. L'exécution du programme génère les pages web renvoyées au client.
    • Langages utilisés : Java.
    • Portabilité : Très grande portabilité grâce à Java : serveurs Apache mais aussi IIS, etc.
    • Mise en place : Utilisation de Java comme langage de programmation.
    • Performance : Très variable en fonction de l'implémentation utilisée.
    • Utilisation : Tout type de fonctionnalités.

ColdFusion

ColdFusion est une technologie de création de pages dynamiques développée par Macromedia. Les pages d’application sont des pages web contenant des instructions de programmation écrite à l’aide d’un langage propriétaire, le CFML (ColdFusion Markup Language). Le CFML est un langage simple basé sur des balises dont la syntaxe est similaire à celles du langage HTML mais interprétées par le serveur.

Ajax (Asynchronous JavaScript And XML)

Ajax est une technologie, avec ses avantages et inconvénients, qui combine plusieurs éléments :

  • du XHTML pour la structure de la page,
  • les CSS pour la mise en forme de la page,
  • du JavaScript et le DOM pour la partie dynamique,
  • XML, XSLT et XMLHttpRequest pour la manipulation des données (ou d'autres formats de fichiers de données).

À la base, cette technologie permet d'effectuer une requête HTTP asynchrone (en parallèle) au serveur web (effectuer une action, mettre à jour une information...). Le serveur renvoie la ressource demandée, celle-ci pouvant contenir des informations ou du code pour mettre à jour la page HTML.

Voir aussi

Sur les autres projets Wikimedia :

· Programmation web, sur Wikibooks

Articles connexes

  • Site web
  • Conception de site Web


ASM Mode Reel

Conception de site web

Un article de Wikipédia, l'encyclopédie libre.

La création et la conception d'un site web ou web design est la conception de l'interface web : l’architecture interactionnelle, l’organisation des pages, l’arborescence et la navigation dans un site web. La conception d'un design web tient compte des contraintes spécifiques du support Internet, notamment en termes d’ergonomie, d’utilisabilité

et d’accessibilité.

Le web design réclame donc des compétences variées : en programmation, en ergonomie et en interactivité, ainsi qu'une bonne connaissance des contraintes techniques liées à ce domaine : diversité des terminaux web et de leurs affichages, accessibilité, spécificités des différents langages et processus, portabilité, respect des recommandations du W3C.

Le webdesign d'un site se présente en premier temps sous forme de maquette fonctionnelle avec des spécifications techniques : ergonomie, charte graphique, identité visuelle, marketing, interactivité.

Un site web peut être une simple page au format HTML et CSS, des services programmés en Java, PHP ou autre langage serveur, des formulaires supposant un traitement en JavaScript, ou AJAX. Il peut reposer sur des technologies de bases de données, par exemple MySQL.

Sommaire

  • 1 Histoire
  • 2 Étapes de la création
  • 3 Constituants des pages
  • 4 Programmation des services
  • 5 Web design d'entreprise
  • 6 Formation
  • 7 Festivals
  • 8 Notes et références

Histoire

Tim Berners-Lee, l'inventeur du World Wide Web, a mis en ligne le tout premier site internet en août 1991, faisant de lui le tout premier concepteur de site (Web designer). Le site utilisait pour la première fois un lien hypertexte et un lien vers une adresse électronique.

Au début, les sites internet étaient écrits en HTML basique, un langage qui donne aux sites internet une structure de base (titres et paragraphes), ainsi que la possibilité d'utiliser des liens hypertextes. C'était une nouveauté et c'était fondamentalement différent des formes de communications préalables, les utilisateurs pouvaient facilement ouvrir d'autres pages.

Au fur et à mesure que l'Internet et la conception de site progressèrent, le langage qui formait les pages, le "Hypertext Mark-up Language" ou HTML, devint plus fourni et flexible. Un nouvel élément, les tableaux, dans lesquels on peut afficher des données, furent vite détournés de leur objectif initial et furent utilisés comme moyen de mise en page. Avec l'apparition du CSS et des feuilles de styles, la mise en page avec les tableaux fut vite considérée comme obsolète. Les technologies modernes qui utilisaient des bases de données, ou le codage côté serveur (voir CGI, PHP, ASP.NET, ASP, JSP, et ColdFusion), ainsi que les normes de conception comme le CSS se sont encore davantage améliorées et ont diversifié les outils de conception de site.

L'apparition de Flash, développé par Macromedia, qui permet de réaliser des animations ainsi que de diffuser du son et de la vidéo, a également changé l'apparence d'Internet, en offrant de nouvelles cartes aux concepteurs de sites. Toutefois, Flash est beaucoup plus restrictif que le HTML car c'est un format protégé par Macromedia, et il nécessite un plug-in pour être affiché.

Une technique assez récente appelée le codage à distance a permis une utilisation d'Internet de façon plus dynamique, sans nécessiter de plug-in ou d'applications spécialisées. Le chef de file de ces technologies est AJAX, mais ce n'est pas la seule technologie existante. Par ailleurs, AJAX n'a pas encore accédé au statut de norme.

Étapes de la création

En fonction du type de site, du contexte et des moyens disponibles pour le mettre en œuvre, certaines de ces étapes sont optionnelles voire inutiles. À chacune de ces étapes correspondent des compétences spécialisées (ergonomie, architecture de l'information, référencement, rédaction Web, etc.).

  1. Projet :
    • Réflexion sur l'objectif du site, sa cible, sa rentabilité, les moyens financiers à engager...
    • Réflexion sur l'autonomie souhaitée et le type de moyens humains pour faire la mise à jour.
    • Réflexion sur le contenu : pages, services attendus, principes de navigation
  2. Mise en œuvre :
    • Dépôt d'un nom de domaine.
    • Choix d'un hébergeur.
    • Choix et installation d'un Système de gestion de contenu (exemples : SPIP, TYPO3, Drupal, Joomla, Wiki, Wordpress,...) ou d'un éditeur de site Web de type WYSIWYG (exemples : Adobe Dreamweaver, phpDesigner, Microsoft FrontPage, NVU, KompoZer, Webself, iziSpot) ou texte (exemples : Bluefish, Emacs, Notepad++...).
  3. Conception :
    • Établissement d'une structure de pages HTML ou XHTML.
    • Définition d'une arborescence
    • Mise au point d'une charte graphique
    • Mise au point d'une charte éditoriale.
  4. Réalisation :
    • Création de pages via le Système de gestion de contenu ou l'éditeur. Les pages peuvent être créées individuellement ou reposer sur un système de gabarits.
    • Mise en place de la charte graphique. Pour bien séparer la structure de la présentation, les feuilles de styles CSS sont utilisées.
    • Éventuels développements dynamiques (formulaire, services, etc.)
  5. Suivi :
    • Recette du site une fois prêt.
    • Lancement du site : mise en ligne.
    • Annonce. Faire connaître le site peut se faire par plusieurs leviers : annonce, publicité, inscription dans des annuaires...
    • La mise à jour : la mise à jour est une action fondamentale de la vie d’un site web. Elle consiste à actualiser, à modifier et à faire évoluer le contenu graphique, textuel, visuel et même la structure et les fonctionnalités du site web.
    • La sauvegarde : quel que soit le type de votre site web, statique ou dynamique, il est exposé à plusieurs menaces : crache de serveur web, piratage, les virus, les bugs…, alors pour des mesures de sécurité, il est très important de faire des sauvegardes régulières pour les données du site web (Base de données, contenus (documents, images, textes…) et tous les paramétrages de votre hébergement, après chaque mise à jour afin d’éviter la perte des données et de garantir la continuité de vos services sur le web.
    • Maintenance : la maintenance d’un site web consiste en général à s’assurer de son bon fonctionnement ; on peut distinguer quatre types de maintenances : La maintenance corrective, La maintenance préventive, La maintenance évolutive, La maintenance adaptative

L'accessibilité du site est une donnée à prendre en compte à chaque étape à partir de la mise au point de la structure des pages. Il en est de même du référencement dont la stratégie peut être mise en place dès la conception. Des principes du référencement sont également à prendre en compte lors de la création des gabarits, l'intégration des pages, la rédaction des contenus, le lancement du site, la maintenance. L'ergonomie intervient également à toutes les étapes : conception, recette et audits, amélioration continue.

Constituants des pages

  • La structure et le contenu, en HTML ou en XHTML
  • La présentation avec les feuilles de style CSS.
  • Le graphisme par découpage et intégration des images GIF, JPG, PNG, MNG.
  • Le comportement en Javascript qui sera géré coté client par le navigateur.
  • La navigation et l'échange de données par l'intermédiaire du protocole HTTP et l'utilisation de Web Service ou d'AJAX.
  • L'animation en Flash ou en SVG, et depuis peu, avec certains attributs du CSS3 (pas encore officialisé, ce qui peut poser des problèmes de compatibilité avec les vieux navigateurs, ou des différences notables d'interprétation graphique entre navigateurs).
  • L'incorporation de multimédias.

Le dynamisme au niveau de la gestion de contenu se fera coté serveur avec des langages de développement de type PHP, Java, ASP,... fonctionnant avec un serveur Web.

Programmation des services

Article détaillé : Programmation web.

Web design d'entreprise

Dans le cadre d'un site web d'entreprise, le web design est défini selon les objectifs qui lui sont fixés :

  • Site web corporate : l'objectif premier est de développer la visibilité de l'offre et de la marque. Les sous-objectifs fixés au web design sont la validation de la lisibilité de l'identité de la société, l'amélioration de la qualité du trafic (plus profond), la facilitation de création d'un capital relationnel[1] entre les visiteurs et le site web (donc l'entreprise, optimiser les temps de réponses des pages.
  • Site web e-commerce : l'objectif premier est de transformer les visites en ventes. Le premier KPI affecté au web design est la réduction du taux d'abandon du panier (63 % en moyenne[2].
  • Landing page : l'objectif d'une atterripage est de capter un visiteur pour des sous objectifs diverses : alimenter une base de donnée mail de suspects, de prospects, de demande de contact pré-qualifiées... trois tâches sont affectées au web design : temps d'accès, cohérence du message entre celui qui capte le visiteur et celui de la landing page dans un objectif d'avoir un maximum de trafic intéressé, adaptation du formulaire de saisie à la cible visée pour avoir un nombre minimal d'abandon de formulaires.

Formation

Le Web Design s'enseigne dans de nombreuses écoles de design, publiques (Ex: Estienne) et privées (Esam Design, Créapole),MJM),MJM),CIFACOM,EEMI,IESA)) dans un cursus dédié au graphisme et à la communication visuelle, généralement en 3 ou 5 ans.

Festivals

Les festivals dédiés au web design sont appelés WebJam dont les plus connus sont les Vector Lounge qui se déroulent dans plusieurs villes du monde chaque année à Limoges avec le Webdesign International Festival, Chattanooga, Rouyn-Noranda, Paris avec le Web Flash festival, Annecy, Amsterdam. Ainsi Cre824, est une manifestation américaine de création de site web en 24 h 00 non-stop organisée un peu partout aux États-Unis.

De plus en plus de petits événements apparaissent et se développent à l'image de MYB "Move-Your-<body>" le concours Troyen du Web Design depuis deux ans ou de Paris Web (cycle de conférences sur le Design, Qualité, Accessibilité).

Notes et références

  1. ↑ http://www.weesifi.com/Pourquoi-investir-dans-la-E-reputation-de-son-entreprise-BtoB_a32.html
  2. ↑ Étude Keyrus-Hybris 2012
  • Cet article est partiellement ou en totalité issu de l'article intitulé « Web design » (voir la liste des auteurs).

Voir aussi

Sur les autres projets Wikimedia :

· Conception de site web, sur Wikiversity

· Conception de site web, sur Wikibooks

Bibliographie

  • Deborah Mayhew, The usability engineering lifecycle: a practitioner’s handbook for user interface design, Morgan Kaufmann Publishers, San Francisco, 1999.
  • Jakob Nielsen Usability Engineering, AP Professional, Cambridge, 1994.
  • Jean-François Nogier (2008), du logiciel et design web : Le manuel des interfaces utilisateur, 4ème édition, Dunod.
  • ISO 20282, Ease of operation of everyday products
  • (en) Philippe de Baeck (dir.), Web Design Handbook, Mul,‎ 2009 (ISBN 978-9460650048)
  • Rob Ford, Julius Wiedemann (dir.), The Internet Case Study Book, Cologne, Tashen,‎ 2010 (ISBN 978-3-8365-1999-1)
  • Jennifer Niederst Robbins (trad. Nathalie Nicoletis), Introduction au Design Web, O'Reilly Editions,‎ 2007, 3e éd. (ISBN 978-2841774388)


Exemple de conception d'un site dynamique

Vu dans ... https://pbnaigeon.developpez.com/tutoriel/PHP/conception-site-dynamique/

I. Définition de la structure du site

I-A. Arborescence

Voici l'arborescence que nous souhaitons créer :

  • Accueil

    • Mon corps de rêve

      • Mes abdos Kro
      • Mes mains
      • Mon profil Grec

    • Mes vacances

      • Au ski

      • A la mer

        • Mer du Nord
        • Mer Morte
    • Mes loisirs
    • Me contacter

Bien entendu, ce n'est qu'un exemple, vous pouvez adapter à volonté.

I-B. Les contraintes

Dans le cadre de cet exemple, nous allons définir notre besoin.

  • Présentation identique des différentes pages (un seul template).
  • Menus générés à la volée.
  • Chaque page aura un identifiant unique
  • Chaque page aura un titre
  • Chaque page aura des mots-clés
  • Chaque page aura une description
  • Chaque page aura un contenu
  • Chaque page aura un et un seul parent

II. Base de données

Passons maintenant à la création de la base de données.

II-A. Structure de la base

Commencez par créer une base nomée BASE_TEST.
Nous allons ensuite créer la table `pages`, en fonction des besoins ennoncés ci-dessus :

  • Id_page : int auto_increment (clé primaire): identifiant unique
  • Titre : varchar(255) : titre
  • Mots_cles : varchar(255) : mots-clés
  • Description : varchar(255) : description
  • Contenu : text : contenu
  • Id_parent : int : Identifiant de la page parent

Afin de définir la page 'racine' du site, nous allons déclarer que son Id_parent vaudra 0. Il n'y aura donc qu'une seule page à posséder cet Id_parent.

Code SQL correspondant
Sélectionnez

CREATE TABLE `pages` (
    `Id_page` INT NOT NULL AUTO_INCREMENT ,
    `Titre` VARCHAR( 255 ) NOT NULL ,
    `Mots_cles` VARCHAR( 255 ) NOT NULL ,
    `Description` VARCHAR( 255 ) NOT NULL ,
    `Contenu` TEXT NOT NULL ,
    `Id_parent` INT DEFAULT '1' NOT NULL ,
    PRIMARY KEY ( `Id_page` )
);

Pour le champ Id_parent, j'ai choisi 1 comme valeur par défaut, afin d'éviter que par mégarde plusieurs pages ne se retrouvent avec soit une valeur nulle soit 0 comme parent.
Au pire donc, pout toutes les pages dont l'Id_parent ne sera pas spécifié, elles seront considérées comme enfant de l'accueil.

Bon, un peu plus d'explications concernant l'Id_parent. Comme un dessin vaut souvent mieux qu'une longue explication, voici notre arborescence représentée avec les Id de chaque page :

Nous allons insérer dans la base les pages par 'niveau' (et de gauche à droite) dans l'arborescence.

Arborescence du site
Arborescence du site

Comme vous pouvez le constater, chaque page n'a qu'un et un seul parent (exception faite de la page d'accueil), et 0 à n enfants.

Prenons maintenant un exemple pour bien comprendre le système de parenté : "Mer Morte" a pour Id 12, et comme parent "A la mer" qui elle a pour Id 10. L'Id_parent de "Mer Morte" sera donc l'Id de "A la mer" soit 10. En remontant encore d'un cran, "A la mer" a pour parent "Mes vacances" (Id=3). L'Id_parent de "A la mer" est donc 3. Et faisons de même pour le dernier niveau : "Mes vacances" a pour parent "Accueil" (Id=1). L'Id_parent de "Mes vacances" est donc 1.

La page d'accueil est la seule en orange, car elle subira un traitement particulier, du fait qu'elle est la seule à ne pas avoir de parent.
Les pages en vert sont les pages 'feuilles', n'ayant pas d'enfant. Les pages en bleu et en rose représentent les différents niveau de profondeur.

Pour le champ Contenu, Deux solutions s'offrent à nous pour le remplissage :

  • Définir ce champ en varchar, et stoquer uniquement l'adresse physique sur le serveur de la page à inclure. A ce moment là, il faudra remplacer l'affichage du contenu en provenance de la base de données par un include du chemin extrait du contenu de la DB.
  • Laisser ce champ en text (comme c'est le cas ici), et inclure directement le code HTML dans la base de données.

Quelle que soit la solution choisie, il ne sera pas utile de remettre les entêtes HTML dans le contenu. Le seul contenu de la balise BODY nous interesse ici (en effet, les entêtes sont déjà définies dans index.php).

Dans le second cas, il va falloir faire très attention à la manière dont les données seront insérées dans la base. Les apostrophes et les guillement dans notre contenu risquent de nous poser problème, il faudra donc les échaper à l'aide de la fonction mysql_real_escape_string.

II-B. Remplissage de la base

Pour le remplissage de la base, je ne me suis pas embêté : le titre, les mots clés, la description et le contenu seront identiques.
Voici le SQL généré par l'ajout de notre arborescence :

SQL de remplissage de la table
Sélectionnez

INSERT INTO `pages` VALUES (1, 'Accueil', 'Accueil', 'Accueil', 'Accueil', 0);
INSERT INTO `pages` VALUES (2, 'Mon corps de rêve', 'Mon corps de rêve', 'Mon corps de rêve', 'Mon corps de rêve', 1);
INSERT INTO `pages` VALUES (3, 'Mes vacances', 'Mes vacances', 'Mes vacances', 'Mes vacances', 1);
INSERT INTO `pages` VALUES (4, 'Mes loisirs', 'Mes loisirs', 'Mes loisirs', 'Mes loisirs', 1);
INSERT INTO `pages` VALUES (5, 'Me contacter', 'Me contacter', 'Me contacter', 'Me contacter', 1);
INSERT INTO `pages` VALUES (6, 'Mes abdos Kro', 'Mes abdos Kro', 'Mes abdos Kro', 'Mes abdos Kro', 2);
INSERT INTO `pages` VALUES (7, 'Mes mains', 'Mes mains', 'Mes mains', 'Mes mains', 2);
INSERT INTO `pages` VALUES (8, 'Mon profil Grec', 'Mon profil Grec', 'Mon profil Grec', 'Mon profil Grec', 2);
INSERT INTO `pages` VALUES (9, 'Au ski', 'Au ski', 'Au ski', 'Au ski', 3);
INSERT INTO `pages` VALUES (10, 'A la mer', 'A la mer', 'A la mer', 'A la mer', 3);
INSERT INTO `pages` VALUES (11, 'Mer du Nord', 'Mer du Nord', 'Mer du Nord', 'Mer du Nord', 10);
INSERT INTO `pages` VALUES (12, 'Mer Morte', 'Mer Morte', 'Mer Morte', 'Mer Morte', 10);

Remarquez bien ici que seul l'accueil à comme Id_parent 0.

III. PHP

III-A. Fonctions de connexion à la base

Créons tout d'abord un fichier nommé mes_fonctions.php. Ce fichier contiendra les différentes fonctions permettant de se connecter et d'interroger la base (et d'autres par la suite) :

mes_fonctions.php
Sélectionnez

<?php

// Se connecte à la DB
// Paramètres : nom de la base -> $name_DB
function connexion_DB($name_DB) {
// Déclaration des paramètres de connexion
    $host = "localhost";
    $user = "root";
    $bdd = $name_DB;
    $passwd  = "";
// Connexion au serveur
    mysql_connect($host, $user,$passwd) or die("erreur de connexion au serveur");
    mysql_select_db($bdd) or die("erreur de connexion a la base de donnees");
}

// --------------------------------------------------------------------------------------------------------------------------
// Deconnection de la DB
function deconnexion_DB() {
    mysql_close();
}

// --------------------------------------------------------------------------------------------------------------------------
// Exécute une requète SQL. Si la requête ne passe pas, renvoir le message d'erreur MySQL
// Paramètres : chaine SQL -> $strSQL
// Renvoie : enregistrements correspondants -> $result
function requete_SQL($strSQL) {
    $result = mysql_query($strSQL);
    if (!$result) {
        $message  = 'Erreur SQL : ' . mysql_error() . "<br>\n";
        $message .= 'SQL string : ' . $strSQL . "<br>\n";
        $message .= "Merci d'envoyer ce message au webmaster";
        die($message);
    }
    return $result;
}

?>

Pas besoin de plus de détails sur ces fonctions, contentons-nous de les utiliser.

Juste une petite explication sur l'utilité de ce fichier 'mes_fonctions.php'. Ce fichier va être inclus dans notre page 'index.php'. Celà revient au même que si vous aviez codé directement dans le fichier 'index.php'.

J'ai choisi de séparer les fonctions du reste pour plusieurs raisons :

  • Fonctions plus faciles à maintenir. On voit clairement où elles sont (et rien n'empêche de créer un fichier par 'type' de fonctions... connexion_DB.php, affichage_header.php, ...).
  • Certaines fonctions peuvent être nécessaires dans plusieurs pages du site. Les inclure dans un fichier spécifique permet donc de ne pas avoir à les recopier dans chaque page (et donc une seule fonction à maintenir, CQFD).

Les fonctions définies dans ce fichier seront donc appelées depuis notre page principale, sans que celà ne pose le moindre problème.

III-B. Création du template

L'intérêt de ce tutorial étant tout autre, nous n'allons pas nous étaler sur la création du template.
Définissons ici simplement nos besoins en terme d'affichage :

  • Un menu 'racine' horizontal en permanence accessible en haut de la page
  • Un 'chemin de fer', permettant de savoir en permanence l'endroit où l'on se situe dans le site
  • Un menu vertical à gauche correspondant à la position actuelle
  • Le contenu de la page.
  • Un pied de page commun à l'ensemble des pages du site

L'idée va simplement être de créer une seule et unique page PHP qui chargera dynamiquement les différents éléments dont elle a besoin pour son affichage.
Nommons cette page index.php :

index.php
Sélectionnez

<?php
    // Active tout les warning. Utile en phase de développement
    // En phase de production, remplacer E_ALL par 0
    error_reporting(E_ALL);

    // Inclus le fichier contenant les fonctions personalisées
    include_once 'mes_fonctions.php';

    // Fonction de connexion à la base de données
    connexion_DB('BASE_TEST');

    // Définit l'Id de la page d'accueil (1 dans cet exemple)
    // Pensez à le modifier si ce n'est pas le cas chez vous.
    $id_page_accueil = 1;

    // Récupère l'id de la page courante passée par l'URL
    // Si non défini, on considère que la page est la page d'accueil
    if (isset($_GET['id_page'])) {
        $_ENV['id_page'] = intval($_GET['id_page']);
    } else {
        $_ENV['id_page'] = $id_page_accueil;
    }

    // Extrait les informations correspondantes à la page en cours de la DB
    extraction_infos_DB();
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<!-- Insère les mots-clés extraits de la DB dans les meta -->
<META NAME="keywords" lang="fr" CONTENT="<?php echo $_ENV['mots_cles']; ?>">
<!-- Insère la description extraite de la DB dans les meta -->
<META NAME="Description" CONTENT="<?php echo $_ENV['description']; ?>">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<!-- Insère le titre extrait de la DB dans la balise correspondante -->
<title><?php echo $_ENV['titre']; ?></title>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
    <div id="menu_horizontal">
        <?php
            // Affiche le menu 'racine' => id de la page = id de la page d'accueil = 1
            echo affiche_menu($id_page_accueil);
        ?>
    </div>
    <div id="chemin_fer">
        <?php
            // Affiche le chemin de fer
            echo 'Vous êtes ici : '.affiche_chemin_fer($_ENV['id_page']);
        ?>
    </div>
    <div id="bloc_central">
        <div id="menu_vertical">
            <?php
                // Affiche le menu en cours => id de la page = id de la page en cours.
                echo affiche_menu($_ENV['id_page']);
            ?>
        </div>
        <div id="contenu">
            <?php
                // Affiche le contenu de la page en cours
                echo $_ENV['contenu'];
            ?>
        </div>
    </div>
    <div id="pied_page">
        <?php include("pied_page.html"); ?>
    </div>
    <?php deconnexion_DB(); ?>
</body>
</html>

Et voici le CSS lié :

styles.css
Sélectionnez

/* propriétés générales de la page */
body {
    background-color:#DDE3EF;
    }
/* propriétés du menu horizontal */
#menu_horizontal {
    text-align:center;
    }
/* propriétés du chemin de fer */
#chemin_fer {
     }
 /* bloc central uniquement crée pour uniformiser les hauteurs des deux blocs contenus (menu_vertical et contenu) */
 #bloc_central {
     }
 /* propriétés du menu vertical */
 #menu_vertical {
     float:left;
     width:20%;
     height:300px;
     }
 /* propriétés du contenu */
 #contenu {
     float:left;
     width:80%;
     height:300px;
     font-size:28px;
     text-align:center;
     }
 /* propriétés du pied de page */
 #pied_page {
     clear:both;
     text-align:center;
     }

Et enfin le fichier pied_page.html

pied_page.html
Sélectionnez

 <hr>
 Ceci est le pied de page...

Le CSS sera ammené à évoluer au fil du temps, le PHP restera en l'état, toutes les fonctions appelées seront ajoutées dans mes_fonctions.php.

Nous avons défini ici trois fonctions : extraction_infos_DB(), affiche_menu(), et affiche_chemin_fer(). En les construisant bien, rien de plus ne sera necessaire.

III-C. Détail des fonctions de récupération et d'affichage des données

Nous allons détailler ici les différentes fonctions auxquelles nous faisons appel dans notre index.php.
Ces fonctions seront à ajouter dans le fichier "mes_fonctions.php"
Commençons par la première, extraction_infos_DB() :

extraction_infos_DB()
Sélectionnez

// Récupère les informations de la page concernée
function extraction_infos_DB() {
    $strSQL = 'SELECT * FROM `pages` WHERE `Id_page` = '.$_ENV['id_page'];
    $resultat = requete_SQL($strSQL);
    $tabl_result = mysql_fetch_array($resultat);
    $_ENV['mots_cles'] = $tabl_result['Mots_cles'];
    $_ENV['description'] = $tabl_result['Description'];
    $_ENV['titre'] = $tabl_result['Titre'];
    $_ENV['contenu'] = $tabl_result['Contenu'];
    $_ENV['id_parent'] = $tabl_result['Id_parent'];
}

Nous nous contentons simplement ici de récupérer les différentes informations de la base de données pour la page en cours.
On colle toutes ces informations dans des variables d'environnement histoire d'être tranquilles, et hop !
Rien de bien sorcier quoi ;)

Mais pourquoi ce intval lors de la récupération de la valeur passée par l'URL ? Tout simplement pour s'assurer que la valeur récupérée est bien un nombre, et ne risque pas de détourner la requête de son but initial.
Dans cet exemple, ce n'est pas flagrant, mais documentez-vous sur l'injection SQL pour vous rendre compte des risques.

Pensez systématiquement à contrôler toutes les saisies de l'utilisateur (ou valeurs qu'il pourrait modifier, telles les variables passéer pas l'URL). Par défaut, ne JAMAIS faire confiance à l'utilisateur.

Passons maintenant à un peu plus difficile... L'affichage du chemin de fer. Commençons par le code, l'explication viendra après :

affiche_chemin_fer($idpage)
Sélectionnez

// Affiche le chemin de fer.
// Paramètres : id de la page en cours -> $idpage
// Renvoie : chemin complet -> $chemin_complet
function affiche_chemin_fer($idpage) {
    // on définit la variable pour éviter le warning
    $chemin_complet = "";
    // Si l'id de la page en cours est différent de 0
    // (0 = page parente de la page racine = inexistante)
    if ($idpage != 0) {
        // on récupère les informations de la page en cours dans la DB
        $strSQL = 'SELECT `Titre`, `Id_parent` FROM `pages` WHERE `Id_page` = '.$idpage;
        $resultat = requete_SQL($strSQL);
        $tabl_result = mysql_fetch_array($resultat);

        $titrepage = $tabl_result['Titre'];
        $idparent = $tabl_result['Id_parent'];

        // création du lien vers la page en cours
        $chemin_page_en_cours = ' -> <a href="index.php?id_page='.$idpage.'">'.$titrepage.'</a>';

        // Concaténation du lien de la page N-1 et
        // du lien de la page en cours
        $chemin_complet = affiche_chemin_fer($idparent).$chemin_page_en_cours;
    }
    // renvoie le chemin complet
    return $chemin_complet;
}

N'ayez pas peur, ce n'est pas si compliqué que ca y paraît ...
Il s'agit simplement d'une fonction récursive (qui se rappelle elle-même). Elle récupère les informations de la page en cours, puis elle crée le lien correspondant et se rappelle elle même. Elle prend en paramètre l'ID de la page parent, tant que cet ID n'est pas égal à 0 (id_parent = 0 -> page racine du site).

Reste la dernière fonction, celle chargée d'afficher le menu...
L'idée est la suivante :

  • La page en cours a des filles, auquel cas, le menu sera composé de liens vers ces filles.
  • La page en cours est une page feuille, auquel cas le menu sera composé de liens vers ses soeurs.
affiche_menu($idpage)
Sélectionnez

// Affiche les menus.
// Paramètres : id de la page -> $idpage
// (id de la page en cours pour le menu vertical, id de la page racine (1) pour le menu horizontal)
// Renvoie : le menu sous forme de liste -> $menu_retour
function affiche_menu($idpage) {
    // Sélectionne toutes les pages filles de la page en cours
    $strSQL = 'SELECT `Id_page`, `Titre` FROM `pages` WHERE `Id_parent` = '.$idpage;
    $resultat = requete_SQL($strSQL);
    // Si la page n'a pas de page fille, alors on modifie la requète pour obtenir ses pages soeurs.
    if (mysql_num_rows($resultat) == 0) {
        $strSQL = 'SELECT `Id_page`, `Titre` FROM `pages` WHERE `Id_parent` = '.$_ENV['id_parent'];
        $resultat = requete_SQL($strSQL);
    }
    $menu_retour = '<ul>';
    while ($tabl_result = mysql_fetch_array($resultat)) {
        $menu_retour .= '<li>';
        $menu_retour .= '<a href="index.php?id_page='.$tabl_result['Id_page'].'">';
        $menu_retour .= $tabl_result['Titre'];
        $menu_retour .= '</a>';
        $menu_retour .= '</li>';
    }
    $menu_retour .= '</ul>';
    return $menu_retour;
}

Rien de bien compliqué ici.
On sélectionne toutes les pages filles de la page passée en paramètre. Si il n'y en a pas, on sélectionne toutes les pages filles de la page parent.
Il ne reste plus ensuite qu'à générer notre liste, laissons les CSS gérer l'affichage :)

III-D. Gestion de la feuille de style

Le plus important d'abord... Afficher notre liste 'en ligne'. Rien de bien compliqué, rassurez-vous.
Rajoutons le code suivant à notre fichier "styles.css" :

affichage en ligne d'une liste
Sélectionnez

/* comportement de la liste dans le bloc menu_horizontal */
#menu_horizontal li {
    margin-right:40px;
    list-style-type: none;
    display: inline;
    }

Ce simple petit bout de code suffit à préciser l'écartement entre nos différents éléments, l'affichage ou non d'une puce, ainsi que l'affichage en ligne.
Le #menu_horizontal li signifie que ce style s'appliquera à tout les éléments de type liste contenus dans le bloc ayant pour id menu_horizontal.

Rajoutons encore quelques styles pour rendre notre affichage plus agréable :

styles complémentaires
Sélectionnez

/* propriétés des liens (de base et déjà visités) contenus dans le bloc menu_horizontal */
#menu_horizontal a:link, #menu_horizontal a:visited {
    color:#339999;
    font-weight:bold;
    text-decoration:none;
    }
/* propriétés des liens (au dessus et actifs) contenus dans le bloc menu_horizontal */
#menu_horizontal a:hover, #menu_horizontal a:active {
    text-decoration:underline overline;
    }
/* propriétés des liens (de base et déjà visités) contenus dans le bloc chemin_fer */
#chemin_fer a:link, #chemin_fer a:visited {
    color:#FF9933;
    font-weight:bold;
    text-decoration:none;
    }
/* propriétés des liens (au dessus et actifs) contenus dans le bloc chemin_fer */
#chemin_fer a:hover, #chemin_fer a:active {
    text-decoration:underline overline;
    }
/* propriétés des liens (de base et déjà visités) contenus dans le bloc menu_vertical */
#menu_vertical a:link, #menu_vertical a:visited {
    color:#CC66CC;
    font-size:16px;
    text-decoration:none;
    }
/* propriétés des liens (au dessus et actifs) contenus dans le bloc menu_gauche */
#menu_vertical a:hover, #menu_vertical a:active {
    text-decoration:underline;
    }

Voici le résultat que vous devriez obtenir :

Résultat final

IV. Conclusion

Et voilà, vous disposez à présent d'un site entièrement dynamique. Vous pouvez rajouter autant de pages que vous le souhaitez, en supprimer à la volée, les menus seront toujours à jour, de même que les liens.
Finalement, avec un tout petit effort de conception à la base, il est facile d'être fainéant après. Plus besoin désormais de modifier 42 pages, si vous souhaitez déplacer le menu, une simple édition du fichier index.html suffira.

Si vous souhaitez aller plus avant dans la conception de ce site (classes d'abstractions, système de template), je vous conseille la lecture du tutoriel de Guillaume RossoliniProfil de Guillaume Rossolini : Tutoriel de site dynamique - Classes d'abstractionTutoriel de site dynamique - Classes d'abstraction.

Un très gros merci à l'équipe web de developpez.com, ainsi qu'à mon bêta testeur qui a bien voulu se dévouer pour éponger les plâtres : SpaceFrog.


Google WEEB

Depuis un moment, on vous bassine avec le même mot : cloud. Vous entendez des choses comme : « Utilise le cloud, et tous tes problèmes seront réglés ! ». Et vous, vous vous demandez ce qui leur prend à parler de cloud à tout va… Le pire, c’est que vous ne savez même pas vraiment ce que c’est !

Je vous propose de découvrir le fonctionnement du cloud avec Google App Engine. Vous n'avez jamais rêvé d'utiliser les serveurs de Google ? De stocker des informations dans leurs gigantesques bases de données ? D'utiliser des centaines de processeurs pour faire vos calculs les plus gourmands ?

Google App Engine vous permet d'héberger votre site sur les serveurs de Google et de bénéficier d'une puissance qui peut s'adapter au trafic de votre site. Besoin de plus de serveurs ? Il suffit de demander, ça se met en place tout seul ! Et le mieux dans tout ça, c'est qu'on peut s'en servir gratuitement tant que le trafic ne dépasse pas 5 millions de pages vues par mois, ce qui laisse de la marge !

Alors inscrivez-vous à ce cours, et direction les nuages !

Un souci technique avec ce cours, pour accéder aux exercices ou corriger les activités ? Écrivez -nous ! Pour le reste, rendez-vous sur le forum ! :)

    Partie 1 - Débutez avec Google App Engine

    1. Qu’est-ce que Google App Engine ?

    2. Installer Google App Engine avec Eclipse

    3. Créer et déployer sa première application

    Partie 2 - Stockez toutes vos données

    1. Comment stocker des données dans le Cloud ?

    2. Google Cloud SQL

    3. Le Datastore

    4. Manipuler le DataStore avec Objectify

    5. Stocker des fichiers sur Google Cloud Storage

    6. TP : et voici le... Cloud Uploader

    Partie 3 - Les services de Google App Engine

    1. Google Accounts API : authentifiez vos visiteurs

    2. Mail API : envoyez et réceptionnez des e-mails

    3. Image API : transformez des images

    4. Crons : exécutez des tâches à intervalles réguliers

    5. Cloud Endpoints : créez des APIs et générez des apps Android & iPhone

    6. Aller plus loin avec App Engine


Google WEEB

Qu’est-ce que Google App Engine ?

Cloud, cloud, cloud... Les gens n'ont que ce mot-là à la bouche en ce moment ? Qu'est-ce que c'est ? A quoi ça sert ?

Google App Engine est justement une de ces solutions cloud. C'est un service qui vous permet d’utiliser les mécanismes du "cloud computing" et de bénéficier de leurs avantages pour votre prochain site web.

Comme vous devez avoir une bonne compréhension globale des principes du cloud avant toute chose, je vais justement vous expliquer dans ce premier chapitre ce qu’est le cloud et comment ça fonctionne. Puis, je vous parlerai plus précisément de Google App Engine, le cloud « façon Google », pour que vous puissiez décider si vous ferez votre prochain site avec ces nouvelles technologies. :)

Comment est né le cloud ?

Mettons les choses au clair : « cloud » est d’abord un terme marketing. Voilà pourquoi vous l’entendez souvent. On aimerait que vous disiez « je veux utiliser le cloud pour mon site web »… Bien qu’il s’agisse d’un tutoriel sur le cloud (et donc quelque part à la gloire du cloud !), j’aimerais aiguiser votre esprit critique avant d’aller plus loin.

Comment est né le mot cloud ? Comment a-t-on découvert et mis en place ces nouvelles techniques ? Laissez-moi vous raconter la petite histoire du cloud à travers l'histoire d'Amazon Web Services, qui a précédé le lancement de Google App Engine.

Remontons quelques années en arrière. Juillet 2002. Amazon est un site de vente en ligne qui cartonne. Simple site de vente de livres à l’origine, on peut aujourd’hui tout acheter : jeux vidéo, matériel hi-fi, vêtements, chaussures… Pour évoluer et gérer de plus en plus de clients, Amazon a dû construire lui-même une très grosse infrastructure technique. Eh oui, il faut des serveurs, beaucoup de serveurs.

Des datacenters et des serveurs par milliers

Un site comme Amazon est donc hébergé sur d’innombrables serveurs, eux-mêmes regroupés dans des grands entrepôts appelés datacenters. Tous les très gros sites ont leurs propres datacenters, et Google ne fait évidemment pas exception à la règle.

Un datacenter avec des baies de serveurs
Un datacenter avec des baies de serveurs

On se croirait dans un décor de science-fiction, et pourtant c'est bien dans des endroits comme celui-ci que tous les plus gros sites web du monde sont hébergés (bon ok la photo a peut-être légèrement été retouchée sur Photoshop :-° ).

Google a diffusé une vidéo de l'un de ses datacenters, c'est assez impressionnant et ça mérite vraiment le coup d'oeil. On peut aussi y naviguer avec Google Street View !

Vidéo d'un datacenter de Google Vidéo d'un datacenter de Google

Chaque colonne que vous voyez est appelée une baie de serveurs. A l'intérieur, on peut trouver facilement 15, 20, 30 serveurs. Zoomons un peu sur eux:

Zoom sur les serveurs
Zoom sur les serveurs

Les serveurs sont des ordinateurs comme les autres. Ils ont des ports USB, des ports Ethernet, et évidemment un bouton Power. ;)

Que faire des serveurs inutilisés ?

Pour faire face à la demande qui grandissait de jour en jour, Amazon a dû installer des dizaines de milliers de serveurs dans le monde, eux-mêmes répartis dans de multiples datacenters qui lui appartiennent : aux Etats-Unis, en Irlande, en Asie… Ces datacenters ont poussé comme des champignons ces dernières années.

Tous ces serveurs ne sont pas utilisés en même temps. Certains sont prêts pour faire face à la demande lors des pics de vente (comme Noël). Mais alors, que faire de ces serveurs qui dorment ?

Les ingénieurs d’Amazon ont alors eu l’idée de les louer à d’autres développeurs web. Mais pas comme n’importe quel hébergeur web qui louerait des serveurs dédiés, attention : Amazon s’est dit « on ne va pas louer la machine physique elle-même mais la puissance de nos machines ». Ainsi, les entreprises n'auront plus besoin d'acheter des tonnes de serveurs comme eux juste pour être prêt en cas de pic de trafic : ils devront simplement demander d'utiliser temporairement plus de serveurs les jours où ils ont plus de visiteurs.

Quelle est la différence avec un hébergeur qui loue des serveurs ? :euh:

Dans le cas d'un hébergement traditionnel, vous achetez ou louez vos propres serveurs. Vous pouvez dire, si vous allez dans le datacenter : « ces serveurs-là, ce sont les miens ! » (et si vous les avez achetés, vous pouvez même graver votre nom dessus :p ).

Les ingénieurs d’Amazon ont eu l’idée de « cacher » le fonctionnement de leurs serveurs et de vendre uniquement de la puissance de calcul et du stockage. Bien sûr, au final, c’est toujours un vrai serveur qui répond à vos requêtes (un serveur branché sur une prise électrique avec un disque dur et tout !). Mais la différence est que vous ne savez pas quel est le serveur qui répond aux requêtes. Parfois, le serveur change dans la journée et vous n’êtes pas au courant, mais ça n’est pas grave : ce qui compte, c’est que votre site fonctionne toujours !

L’intérêt de ce fonctionnement, c’est que vous n’avez plus à vous préoccuper des problèmes physiques des machines. Si un disque dur tombe en panne, ce n'est pas à vous d'aller le remplacer. Vous avez juste besoin de demander à votre site de démarrer sur une autre machine.

Voilà comment le cloud (ou cloud computing) est né. Ca n’a rien de magique : il y a toujours des serveurs, des processeurs et des disques durs. Sauf qu’au lieu de vous louer un serveur précis avec son numéro de série, on vous loue « la puissance d’un serveur ».

Le cloud est généralement matérialisé par un nuage qui dit « vous ne voyez pas ce qu’il y a à l’intérieur mais ne vous inquiétez pas ça fonctionne ». Soyons un peu critiques toutefois : les problèmes, même s’ils sont rares, peuvent toujours survenir. Amazon, Google et Microsoft ont tous les trois connu des ennuis avec leur infrastructure de cloud, qui parfois n’a pas fonctionné pendant plusieurs heures à cause d’un gros bug technique.
Heureusement, cela reste rare, mais il faut quand même le savoir !

Encore un disque grillé... j'aurais dû passer au cloud !
Encore un disque grillé... j'aurais dû passer au cloud !

Comment fonctionne le cloud ?

Bon, c'est bien beau tout ça, mais si on rentrait un peu dans le vif du sujet ? Par exemple, comment fonctionne le cloud ? Ah... Ca, c'est une question délicate, parce qu'il existe plusieurs types de cloud !

Les différents types de cloud

Si le cloud est difficile à saisir pour beaucoup de gens, c’est parce que c’est un terme très large qui englobe beaucoup de concepts. Je vous propose pour commencer de retenir les termes suivants, qui font tous partie de la grande famille du cloud :

  • IaaS (Infrastructure as a Service) : un prestataire vous fournit un accès à tout ou partie de son infrastructure technique, c’est-à-dire à ses serveurs. C’est ce que faisait Amazon à ses débuts dans l'histoire que je viens de vous raconter (ils font d'autres services cloud aussi maintenant).

    Analogie : imaginez que vous faites un voyage à travers les Etats-Unis avec 3 amis. Vous avez besoin d’une voiture ; vous faites donc appel à un service de location de voitures. Si la voiture a un problème technique, vous devrez juste la ramener chez le loueur et on vous en donnera une autre. Ce n'est pas à vous de régler les problèmes de moteur de la voiture.
    Avec un IaaS, vous déléguez donc la gestion de ces problèmes matériels. En revanche, si d’autres amis décident de se joindre à votre voyage en cours de route, il faudra demander vous-mêmes d’autres voitures pour transporter tout ce petit monde.

  • PaaS (Platform as a Service) : on vous fournit non seulement un accès à l’infrastructure, mais on s’occupe aussi de gérer le nombre de machines nécessaires pour que votre application fonctionne bien quelle que soit la charge de trafic. On vous donne aussi accès à des fonctionnalités comme par exemple des bases de données, des serveurs de cache, des serveurs d’e-mail… C’est le cas de Google App Engine : vous bénéficiez des serveurs de Google pour stocker votre site, mais aussi des fonctionnalités très puissantes de gestion de la charge, un accès aux bases de données Google, aux serveurs d’envoi d’e-mails, etc.

    Analogie : reprenons notre voyage à travers les Etats-Unis avec un groupe d’amis. Avec un PaaS, vous ne louez plus directement les voitures : vous embauchez les services d’une personne responsable de vérifier si le voyage se déroule toujours dans les meilleures conditions (appelons cette personne le “concierge”).
    Si 3 nouveaux amis vous rejoignent en cours de route, le concierge s’en apercevra et louera une seconde voiture sans que vous ayez besoin de le demander. Si d’un coup 20 nouveaux amis se joignent à votre voyage, il remplacera les voitures par un bus qu’il affrêtera spécialement pour vous.
    C’est exactement ce que fait un PaaS comme Google App Engine : il vérifie que les visiteurs qui vont sur votre site le font dans les meilleures conditions. Il rajoute ou retire des serveurs en fonction du trafic. Vous pourriez presque lui demander des rafraîchissements quand vous avez soif ! ;)

  • SaaS (Software as a Service) : on vous fournit l’accès à un logiciel sous forme de service. Avant, vous deviez installer le logiciel sur votre machine (ex : Microsoft Office). Aujourd’hui, le logiciel se présente sous la forme d’une application web (qui n’est rien d’autre qu’une sorte de super site web !). Vous devez juste vous rendre à une adresse et vous pouvez l’utiliser (ex : Microsoft Office 360, Google Apps…).

La différence entre un IaaS et un PaaS est ce qu'il y a de plus difficile à comprendre. Je me suis permis de résumer mon analogie de la location de voiture dans un schéma pour vous aider à retenir le principe :

La différence entre un IaaS et un PaaS imagée avec un exemple
La différence entre un IaaS et un PaaS imagée avec un exemple

Toutes ces offres de Cloud fournissent des services à différents niveaux. Comme les langages de programmation, certains services sont "bas niveau" (proche de la machine) et d'autres sont "haut niveau" (grosse abstraction, éloignée du fonctionnement de la machine) :

Les différents types de cloud
Les différents types de cloud

Le calcul du coût

Une des grandes innovations du cloud computing, c’est qu’on vous facture uniquement la puissance dont vous avez besoin. Avant, vous deviez prendre et payer 50 serveurs au cas où il y ait un pic de trafic sur votre site. Aujourd’hui, le nombre de serveurs que vous utilisez peut changer d’une minute à l’autre. On vous facture les serveurs à l’heure, et parfois même à la minute ou à la seconde !

Si vous avez un pic de trafic sur votre site, vous paierez un petit peu plus pendant quelques heures mais vous n’aurez pas besoin d’acheter et de monter des serveurs dont vous n’aurez peut-être plus besoin ensuite.

La plupart des services de cloud peuvent être utilisés gratuitement pour commencer. Si vous avez besoin d’un tout petit peu de puissance, c’est donc gratuit !

Comment ?! Mais il faut bien payer à un moment non ?

Oui, mais seulement si votre site grossit et commence à accueillir beaucoup de visiteurs. Dans ce cas, vous aurez besoin de plus de puissance et il faudra commencer à payer.

Chez Google App Engine, vous pouvez par exemple utiliser gratuitement le service avec 1 Go de stockage et l’équivalent de 5 millions de pages vues par mois.

A vous de surveiller votre consommation ensuite car les services de cloud peuvent finir par être coûteux si votre site commence à grossir beaucoup !

Google App Engine vous permet d'indiquer combien vous êtes prêts à payer par jour pour héberger votre site. Si vous dépassez cette limite, vous ne serez pas facturé plus, mais votre site refusera des visiteurs. A vous ensuite de décider si vous êtes prêts à augmenter cette limite, mais au moins vous ne risquez pas de surprise avec une grosse facture en fin de mois. :)

Cloud or no cloud ?

Faut-il partir sur une infrastructure cloud pour votre prochain site ? Il n’y a que vous qui puissiez le décider. Voici quelques éléments vous permettant de faire votre choix en toute objectivité si vous hésitez à vous lancer dans une plateforme PaaS comme Google App engine :

  • Le cloud vous permet de commencer gratuitement dans la plupart des cas.

  • Vous n’avez rien à faire si le trafic de votre site grossit : vous utiliserez automatiquement plus de serveurs (et ferez chauffer votre CB :-° ).

  • Vous n’avez pas à gérer les problèmes techniques « bas niveau » comme la perte d’un disque dur ou même d’un serveur entier. Tout cela est transparent pour vous.

  • Dans le cas d’un PaaS comme Google App Engine, vous bénéficiez de fonctionnalités très pratiques qui vous évitent d’avoir à installer et maintenir un serveur de base de données, d’e-mails, etc.

En revanche :

  • Vous devez adapter votre site pour qu’il fonctionne avec les limitations et fonctionnalités offertes par votre PaaS. Il y a des règles à suivre quand vous développez : vous n'avez en général pas accès au système d'exploitation du serveur et vous ne pouvez pas y stocker des fichiers. Il faut les stocker sur d'autres serveurs en faisant appel à un service de stockage.

  • Si vous voulez changer de prestataire, c’est compliqué. Il faut parfois recoder tout ou partie de votre site pour qu’il fonctionne sur un autre PaaS.

  • Les bugs techniques sont rares mais peuvent toujours survenir, quoique le service marketing veuille bien tenter de vous faire croire. Ne faites pas une confiance aveugle dans votre cloud et demandez des SLA (Service Level Agreement) pour garantir financièrement le bon fonctionnement du site si vous êtes une entreprise et que le site est critique pour vous. Avec des SLA, le fournisseur aura des pénalités si votre site ne fonctionne pas pendant plusieurs heures par sa faute.

Google App Engine, le cloud selon Google

Rentrons un peu plus dans le détail du fonctionnement de Google App Engine. Pour commencer, il faut savoir que Google propose plusieurs services cloud :

  • App Engine : le service PaaS de Google, la star de la maison. De gros sites comme Khan Academy ou Pulse l’utilisent. C'est ce service que nous étudierons dans ce tutoriel.

  • Compute Engine : le service IaaS de Google. Si vous avez besoin de puissance de calcul brute (pour calculer des modèles mathématiques par exemple), c’est ce qu’il faut utiliser.

  • Cloud Storage : un service potentiellement « illimité » de stockage de fichiers dans le cloud. C'est donc un... DaaS. C'est bien, je vois que vous suivez. :p

  • Big Query : des fonctionnalités permettant d’analyser de grosses quantités de données en peu de temps (on parle de Big Data). Très utile pour les entreprises qui veulent faire de la Business Intelligence (BI) pour avoir des indicateurs de tendance basés parfois sur plusieurs Tera Octets de données.

  • Cloud SQL : une base de données MySQL distribuée dans le cloud. Vous n’avez pas besoin d’installer ni de mettre à jour MySQL. Pas même besoin de le configurer. Vous pouvez créer des serveurs SQL répliqués en quelques clics si vous avez besoin de plus de puissance.

Les services de Cloud de Google
Les services de Cloud de Google

Comment fonctionne App Engine ?

Le rôle d'App Engine est de "masquer" le fonctionnement et la complexité des serveurs de Google. Lorsqu'un visiteur se connecte à votre site, il arrive sur le load balancer (répartiteur de charge) de Google, qui va chercher un serveur disponible et pas trop chargé pour gérer la demande de votre visiteur. Si votre site a besoin d'accéder à des données, ce qui est fréquent, il fera appel à une autre zone de serveurs appelée DataStore (c'est en quelque sorte la base de données).

Tout ceci est résumé dans ce schéma fourni par Google :

L'architecture de Google App Engine L'architecture de Google App Engine

Pas besoin de le comprendre et de le retenir par coeur. :p
Retenez simplement ce que je viens de vous expliquer, ce sera déjà pas mal !

Quels langages sont supportés par App Engine ?

Les plateformes PaaS comme Google App Engine supportent un nombre limité de langages de programmation. En effet, elles fournissent des fonctionnalités supplémentaires sous la forme de bibliothèques, il faut donc que Google ait développé les fonctionnalités correspondantes pour ces langages.

Voici les langages supportés par Google à l’heure actuelle (cette liste est susceptible de s'agrandir à l'avenir) :

  • Java

  • Python

  • Go (en bêta-test)

  • PHP (en bêta-test)

En réalité, tout langage pouvant utiliser la machine virtuelle Java peut aussi fonctionner : c’est le cas de Ruby et de Scala par exemple. Dans la pratique, la plupart des gens utilisent soit Java, soit Python. Go est un langage créé par Google assez spécifique et encore expérimental, nous n’en parlerons pas ici.

Dans ce cours, je supposerai que vous savez déjà créer des sites web avec un de ces langages. Mes exemples seront basés sur un site Java EE développé en Java. Allez donc lire les cours sur Java et Java EE (ou sur Python et Django) pour apprendre la création de sites web dynamiques avec ces langages.

Lorsque vous saurez créer des sites en Java ou Python, vous pourrez ensuite découvrir avec moi comment on fait des sites dans le cloud avec Google App Engine !

Allez, vous en savez assez sur le cloud. :)
Dans le prochain chapitre, nous allons voir comment mettre en place les outils de développement pour créer un site web en Java en utilisant Google App Engine. Nous allons en fait simuler le fonctionnement des serveurs de Google sur notre propre machine pour créer notre site !


Google WEEB

Installer Google App Engine avec Eclipse

Maintenant que nous savons un peu mieux ce qu'est le Cloud et en quoi consiste Google App Engine, si nous passions un peu à la pratique ? Avant de commencer à développer notre premier site utilisant App Engine, il va nous falloir transformer notre ordinateur en "mini-serveur Google" pour pouvoir faire plus facilement nos tests par la suite.

Heureusement, Google nous fournit tous les outils dont nous avons besoin pour développer. Ces outils varient en fonction du langage que vous utilisez : Java, Python ou Go. Comme je vous l'ai dit, je ne peux pas présenter tous les langages à la fois, j'ai donc choisi de faire mes exemples en Java.
(insérez ici le traditionnel troll sur Java une bonne fois pour toutes, qu'on puisse continuer tranquillement ensuite :-° )

La plupart des développeurs Java saints de corps et d'esprit (oui ça existe) utilisent un IDE comme Eclipse. Google y a pensé et nous fournit justement un kit de développement App Engine sous la forme d'un plugin Eclipse !

Pour information, Google fournit aussi le support de Maven pour les projets App Engine. Cela intéressera ceux qui ont l'habitude de l'utiliser pour générer leurs projets Java EE.

Installer Eclipse

Si vous avez l'habitude de développer en Java et de faire du Java EE, vous devriez déjà utiliser Eclipse régulièrement. Vous pouvez donc sauter cette étape qui ne vous apprendra rien de nouveau.

Cependant, si vous n'avez pas déjà Eclipse, et puisqu'un rappel ne fait jamais de mal, voici ce qu'il faut faire : il faut télécharger Eclipse (nooon ?). Allez sur la section téléchargement d'Eclipse et sélectionnez la version d'Eclipse de votre choix.

La version la plus téléchargée est "Eclipse for Java EE developers", c'est celle qui convient le mieux dans notre cas. Si vous utilisez une autre version vous ne devriez pas rencontrer de problème rassurez-vous.

Lors du premier lancement, Eclipse vous demandera de choisir un "workspace", un dossier dans lequel il déposera vos projets de développement Java. Vous pouvez laisser la valeur proposée par défaut et continuer.

Eclipse étant lui-même un programme Java, vous devez avoir installé Java auparavant. Vous aurez besoin du JDK (Java Development Kit) pour l'utiliser. Téléchargez le JDK sur le site d'Oracle si vous ne l'avez pas déjà.

Vous m'excuserez, je passe volontairement un peu vite sur tout ça, car ce ne sont normalement que des rappels pour vous. Si vous êtes perdus, c'est que vous ne connaissez probablement pas Java et Java EE. Lisez les tutoriels correspondants avant d'utiliser Google App Engine. :)

Installer le plugin Google App Engine

Installer le plugin Google App Engine dans Eclipse est vraiment très simple. Allez dans le menu Help > Install New Software.

Une fenêtre apparaît, où l'on vous demande où trouver de nouveaux plugins. Rentrez l'adresse suivante (si vous avez la version 4.2 d'Eclipse comme moi, sinon changez l'URL) :

http://dl.google.com/eclipse/plugin/4.2

Appuyez sur Entrée. La liste des plugins disponibles se charge. Je vous invite à cocher ceux-ci :

  • Google Plugin for Eclipse

  • SDK > Google App Engine Java SDK

  • SDK > Google Web Toolkit SDK (facultatif)

Votre fenêtre devrait alors ressembler à ceci :

Sélection des plugins à installer
Sélection des plugins à installer

Vous pouvez installer d'autres plugins si vous le voulez mais ça ne nous sera pas nécessaire ici. Cliquez ensuite sur Next.

Validation des éléments à installer
Validation des éléments à installer

On vous demande de vérifier ce que vous allez installer. Cliquez encore sur Next.

Validation de la licence
Validation de la licence

Vous devez valider la licence d'utilisation. Cliquez sur "I accept the terms of the license agreements" et continuez. L'installation devrait commencer.

Au bout d'un moment, vous verrez le message suivant :

Validation de la signature
Validation de la signature

Pas de panique. Eclipse avertit qu'il y a du contenu non signé (qui pourrait ne pas provenir de Google) dans ce que vous téléchargez. En réalité il n'y a pas de problème, cliquez sur OK pour continuer l'installation.

A la fin, on vous demandera de redémarrer Eclipse pour finaliser l'installation :

Redémarrage d'Eclipse

Une fois Eclipse redémarré, c'est fini ! Si vous lancez un nouveau projet ou que vous fermez simplement l'écran de bienvenue, vous devriez voir une icône Google (représentée par un "g") qui vous donne accès aux fonctionnalités de Google App Engine que nous avons installé :

Le menu Google dans Eclipse
Le menu Google dans Eclipse

Voilà, vous avez installé Google App Engine sur votre ordinateur et vous êtes maintenant prêts à programmer ! :)


Google WEEB

Créer et déployer sa première application

Maintenant que nous avons installé Eclipse et le plugin Google App Engine, tout est prêt pour que nous commencions à créer notre première application App Engine !

Dans ce chapitre, nous allons nous familiariser avec les outils que nous donne le plugin App Engine. Vous allez voir que créer une première application est vraiment très très simple. Nous irons même jusqu'à la déployer (c'est-à-dire la mettre en ligne) sur les serveurs de Google !

Je vous rappelle que vous devez déjà avoir des connaissances sur Java EE pour suivre ce tutoriel (je voudrais bien tout vous réexpliquer mais ce serait vraiment trop long, et puis on a un super cours sur Java EE sur le site !). Je montrerai rapidement certains concepts, comme les servlets et les JSP, sans trop m'attarder dessus. Je vous montrerai surtout ce qui change par rapport à une application Java EE classique.

Création de l'application

Pour créer une nouvelle application App Engine, utilisez le bouton "g" de Google qui a été ajouté lorsque vous avez installé le plugin. Sélectionnez "New Web Application Project".

Nouvelle application App Engine
Nouvelle application App Engine

Un assistant de création de projet s'ouvre. A l'intérieur :

  • Donnez un nom à votre premier projet (par exemple "MaPremiereApplication")

  • Donnez un nom au Package que vous allez créer (par exemple "maPremiereApplication")

  • Vérifiez que les cases "Use Google App Engine" et "Generate project sample code" sont cochées.

  • En revanche, décochez "Use Google Web Toolkit" si vous l'avez installé, il ne nous sera pas utile ici et alourdira inutilement le projet.

Préparation de l'application
Préparation de l'application

Cliquez sur Finish. Le plugin App Engine se charge de créer et d'organiser les fichiers de votre application tout seul !

Et si on regardait un peu comment ces fichiers sont organisés maintenant ? :)

Structure des fichiers d'un projet App Engine

En générant notre premier projet, le plugin App Engine a créé toute une architecture de fichiers et de dossiers. Elle ne devrait pas trop vous dépayser si vous avez l'habitude de développer en Java EE.

Structure des fichiers d'un projet App Engine
Structure des fichiers d'un projet App Engine

J'ai surligné les fichiers qui méritent qu'on y jette un oeil. Je vous propose qu'on en parle un petit peu. :)

MaPremiereAppServelet.java

C'est un fichier de code source Java. On l'appelle servlet quand on développe des applications web Java EE.

Ce fichier contient une classe qui peut interagir avec le serveur web. Elle peut récupérer les données envoyées par le visiteur depuis un formulaire et les traiter par exemple.

Le code généré par le plugin ressemble à ceci :

package maPremiereApp;

import java.io.IOException;
import javax.servlet.http.*;

@SuppressWarnings("serial")
public class MaPremiereAppServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {
        resp.setContentType("text/plain");
        resp.getWriter().println("Hello, world");
    }
}

Tout se passe dans la méthode doGet() qui est appelée quand le visiteur demande la page. Ici, la servlet ne fait rien de particulier : elle affiche "Hello, world" sur la page sous forme de texte brut. Elle pourrait néanmoins faire beaucoup d'autres choses, comme récupérer les données envoyées par un formulaire, demander à les stocker dans une base de données de Google, envoyer des emails à l'aide des serveurs utilisés par GMail et bien d'autres choses. Nous verrons comment faire tout cela dans les prochains chapitres !

Cette servlet ressemble en tous points à une servlet d'application Java EE classique, si ce n'est qu'on peut accéder à tous les services offerts par les bibliothèques d'App Engine.

appengine-web.xml

C'est un fichier de configuration propre à App Engine. C'est en fait le seul de la liste que je vous présente qui diffère d'un projet Java EE classique (si on ne tient pas compte des nombreuses bibliothèques d'App Engine qui ont été chargées mais que nous n'avons aucun besoin d'ouvrir).

Eclipse a la fâcheuse tendance à afficher ce fichier dans une interface spécifique, alors que ce n'est en fait qu'un simple fichier XML :

Eclipse affiche les XML dans une interface spécifique
Eclipse affiche les XML dans une interface spécifique

Pour changer de mode de visualisation, cliquez sur l'onglet "Source" en bas à gauche. Vous devriez alors voir le vrai code XML :

<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
  <application></application>
  <version>1</version>

  <!--
    Allows App Engine to send multiple requests to one instance in parallel:
  -->
  <threadsafe>true</threadsafe>

  <!-- Configure java.util.logging -->
  <system-properties>
    <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
  </system-properties>

  <!--
    HTTP Sessions are disabled by default. To enable HTTP sessions specify:

      <sessions-enabled>true</sessions-enabled>

    It's possible to reduce request latency by configuring your application to
    asynchronously write HTTP session data to the datastore:

      <async-session-persistence enabled="true" />

    With this feature enabled, there is a very small chance your app will see
    stale session data. For details, see
    http://code.google.com/appengine/docs/java/config/appconfig.html#Enabling_Sessions
  -->

</appengine-web-app>

Le fichier est assez simple en fait. Google a laissé quelques commentaires pour nous aiguiller si on veut compléter le fichier.

A quoi sert ce fichier en fait ?

Il donne des informations générales sur votre application App Engine : son nom, sa version... Il permet d'activer certaines fonctionnalités comme les sessions, des services de Google, etc.

Le nom et la version

Pour le moment, l'application n'a pas de nom. On devrait d'ailleurs plus exactement parler d'identifiant, car l'application doit avoir un nom unique sur les serveurs de Google, nous verrons cela un peu plus tard.

Le numéro de version permet, lui, d'identifier la version de votre application. Vous pouvez tester une nouvelle version de votre application en ligne pendant que vos visiteurs sont sur une ancienne version. Et lorsque vous trouvez que votre nouvelle version fonctionne bien, il ne vous faudra que quelques clics dans l'interface d'administration de Google pour rediriger vos visiteurs vers la nouvelle version !

Par exemple, si votre site a pour nom "monsupersite", il sera accessible par défaut à cette adresse :

http://monsupersite.appspot.com/

Et si vous voulez tester spécifiquement la version 57 de votre application, il vous suffira d'aller à l'adresse :

http://57.monsupersite.appspot.com/

La déclaration des fichiers statiques

Le fichier appengine-web.xml permet aussi d'indiquer où se trouvent les fichiers statiques de votre site, c'est-à-dire les images (PNG, JPEG...), les CSS, les Javascript, etc. En gros, tout ce qui n'est pas du code Java.

Tous les fichiers de votre site n'ont pas besoin de subir de traitement particulier par les serveurs de Google. Un PNG est un PNG, il n'est (normalement) pas modifié par le serveur avant envoi au visiteur, alors qu'une servlet requiert une exécution par un processeur. On vous demande donc d'indiquer où sont ces fichiers statiques pour que Google puisse les mettre à part sur des serveurs spécifiques qui n'ont pas besoin d'autant de puissance processeur.

Les fichiers statiques sont stockés sur des serveurs différents des servlets et JSPs
Les fichiers statiques sont stockés sur des serveurs différents des servlets et JSPs

L'avantage de mettre les fichiers statiques sur des serveurs spécifiques, c'est que Google peut ainsi les dupliquer sur plusieurs serveurs via un CDN (Content Delivery Network). Ainsi, chaque visiteur ira récupérer les fichiers statiques sur le serveur le plus proche de lui, ce qui rendra leur téléchargement plus rapide. :)

Avec un CDN, le visiteur télécharge les fichiers depuis le serveur le plus proche
Avec un CDN, le visiteur télécharge les fichiers depuis le serveur le plus proche

Pour indiquer à Google quels sont les fichiers statiques, vous devrez ajouter des balises XML incluant ou excluant des fichiers. Par exemple :

<static-files>
    <include path="/**.png" />
    <include path="/javascript/*.js" />
    <exclude path="/generator/**.png" />
</static-files>

On a 2 règles d'inclusion et 1 règle d'exclusion dans cet exemple :

  • Tous les fichiers .png seront considérés comme statiques et entreposés dans des serveurs de stockage (à une exception près que je vous indiquerai juste après). Les deux étoiles ** signifient que Google peut aller chercher les .png dans tous les sous-dossiers.

  • Tous les fichiers .js dans le dossier /javascript uniquement seront considérés statiques.

  • En revanche, les fichiers .png du dossier "generator" seront exclus des fichiers statiques (ils seront bien placés sur les serveurs d'exécution). C'est utile si, par exemple, le dossier generator contient en réalité du code Java qui génère des PNG et qui les présente sous la forme de fichiers PNG pour le navigateur.

web.xml

C'est le fichier de configuration "classique" de votre application Java EE. Il ne faut pas le confondre avec appengine-web.xml :

  • appengine-web.xml contient la configuration de votre application Java EE App Engine, c'est-à-dire de tout ce qui est spécifique à App Engine dans votre application (comme la définition de fichiers statiques pour que Google sache sur quels serveurs les placer).

  • web.xml contient la configuration générale de votre application Java EE, comme par exemple la liste des servlets et l'adresse correspondant à chacune d'elle sur votre site.

Ce fichier est couramment modifié quand on développe une application Java EE. Il devrait vous être familier. Ici, pour le moment, le fichier contient ceci :

<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
    <servlet>
        <servlet-name>MaPremiereApp</servlet-name>
        <servlet-class>maPremiereApp.MaPremiereAppServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>MaPremiereApp</servlet-name>
        <url-pattern>/mapremiereapp</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
</web-app>

On voit par exemple que la servlet MaPremiereApp (dont on a vu le code Java tout à l'heure) est appelée quand le visiteur essaie d'accéder à la page /mapremiereapp de votre site.
Le fichier index.html est appelé par défaut à la racine de votre site. C'est donc lui qui sera chargé comme page d'accueil.

index.html

C'est la page qui sera affichée à votre visiteur à l'accueil de votre site. Il s'agit d'une page HTML tout ce qu'il y a de plus basique.

Nous pouvons bien entendu la modifier ou même demander au fichier web.xml d'appeler une servlet à la place de cette page statique pour l'accueil de notre site.

Exécuter l'application App Engine

Pour tester votre site, il suffit de cliquer sur le bouton "Debug" (ou "Run") de la barre d'outils, et de sélectionner : "Debug as" > "Web Application" :

Exécution de l'application depuis Eclipse
Exécution de l'application depuis Eclipse

La console en bas d'Eclipse devrait afficher des messages pendant quelques secondes avant d'indiquer : "INFO: Dev App Server is now running". Cela signifie que le mini-serveur Google tourne maintenant sur votre machine et que vous pouvez tester votre site !

Si vous regardez bien, on vous indique à quelle adresse locale vous pouvez tester votre site :

INFO: Server default is running at http://localhost:8888/

Allez donc à l'adresse http://localhost:8888 dans votre navigateur, vous devriez voir la page d'accueil s'afficher :

Ouverture du site dans le navigateur (sur localhost:8888)
Ouverture du site dans le navigateur (sur localhost:8888)

Il s'agit là du fichier index.html que nous avons vu tout à l'heure dans le projet sous Eclipse. Si vous cliquez sur le lien "MaPremiereApp", la servlet MaPremiereApp sera chargée et s'exécutera. Comme je vous l'ai dit, cette servlet ne fait rien de bien excitant pour le moment : elle affiche juste "Hello, world" !

Affichage de la servlet dans le navigateur
Affichage de la servlet dans le navigateur

Il faut aussi savoir que Google génère automatiquement une administration pour contrôler et surveiller votre site. Vous pouvez y accéder en allant à l'adresse http://localhost:8888/_ah/admin :

L'administration automatiquement générée par Google pour gérer votre application
L'administration automatiquement générée par Google pour gérer votre application

D'ici, vous pourrez surveiller votre application : voir les données stockées dans le Datastore (la "base de données Google", que nous étudierons plus tard), simuler des emails entrants, désactiver des fonctionnalités pour voir le comportement de l'application en mode dégradé, etc.

Bon, nous avons exécuté l'application qui a été générée par Google, ce n'était pas bien difficile. Je vous propose de la déployer maintenant sur les serveurs de Google. :D

Déployer l'application App Engine sur les serveurs de Google

Pour pouvoir envoyer notre application App Engine sur les serveurs de Google, nous devons d'abord réserver un identifiant d'application. Nous pourrons ensuite dans un second temps déployer l'application directement depuis Eclipse !

Déclarer l'application auprès de Google

Commencez par vous rendre à l'adresse suivante : https://appengine.google.com/
C'est ici que vous pourrez créer et gérer vos applications App Engine.

Si vous n'avez pas déjà de compte Google (un compte GMail par exemple) il vous faudra en créer un et vous connecter. Une fois que c'est fait, vous devriez voir l'écran suivant :

L'interface d'administration de vos projets App Engine chez Google
L'interface d'administration de vos projets App Engine chez Google

Cliquez sur "Create Application" pour commencer la déclaration de votre application chez Google. La première fois, on vous demandera sûrement une authentification supplémentaire, pour "éviter les abus" vous dit-on. Il suffit d'indiquer votre numéro de téléphone portable, d'attendre de recevoir un SMS contenant un code secret et de l'écrire sur la page.

Une fois que c'est fait, un simple formulaire vous demande de créer l'identifiant de votre application et de lui donner un nom :

Création de l'application
Création de l'application

Vous devrez utiliser un identifiant d'application libre. Cliquez sur "Check Availability" pour vérifier si celui que vous voulez prendre est disponible.

Le formulaire vous demande si vous voulez restreindre les utilisateurs qui se connecteront sur votre site à des comptes Google spécifiques à un domaine (par exemple le domaine d'une entreprise si vous faites une application pour votre entreprise). N'y touchez pas, ça ne nous sert à rien ici.

Validez la licence... et voilà !

On vous propose un lien vers le dashboard (tableau de bord) de votre application. D'ici, vous pouvez voir tout ce qui se passe sur votre site et contrôler toute votre application !

Administration de l'application
Administration de l'application

Quelle est la différence entre cette zone admin et celle que nous avons vue un peu plus tôt après avoir testé le site en local ?

L'admin du site local permet de faire des tests précis pour débugger temporairement votre application. En revanche, l'admin que vous avez maintenant sous les yeux est beaucoup plus complète : elle vous donne des indications sur l'application qui est en ligne et disponible à tous. Vous pouvez voir le trafic, mettre en maintenance votre site, augmenter la puissance des serveurs, et bien d'autres choses ! :)

Déploiement : direction les serveurs de Google !

Maintenant que Google nous connaît et que nous avons réservé un identifiant, nous pouvons retourner dans Eclipse et envoyer notre site !

Il faut d'abord indiquer l'identifiant de l'application dans le fichier appengine-web.xml dans la balise <application></application> :

<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
  <application>sdz-mapremiereapp</application>
  <version>1</version>

Ne copiez pas le même nom d'application que moi ! Je l'ai réservé en rédigeant ce tutoriel, vous ne pouvez donc pas avoir créé une application ayant le même nom que moi.
Indiquez le nom que vous avez réservé à la place.

Vous pouvez maintenant déployer ! Allez dans le menu Google et cliquez sur "Deploy to App Engine" :

Demandez le déploiement depuis le menu Google
Demandez le déploiement depuis le menu Google

La première fois, on vous demandera de vous connecter à votre compte Google pour qu'on puisse vous identifier. Rentrez votre login et votre mot de passe. Une fois connecté, on vous demande de valider avant de déployer :

Validation avant déploiement
Validation avant déploiement

Cliquez tout simplement sur "Deploy" : votre site part alors sur les serveurs de Google comme un grand !

Le déploiement est en cours, vous n'avez rien à faire !
Le déploiement est en cours, vous n'avez rien à faire !

Le déploiement d'une application App Engine est une sorte de FTP amélioré. Vous n'avez pas besoin d'indiquer les fichiers qui ont changé, Google se charge de tout !

Voilà, votre site est maintenant disponible à une adresse de la forme : http://applicationid.appspot.com (remplacez applicationid par l'identifiant de votre application).

Dans mon cas, l'application est disponible à cette adresse :

http://sdz-mapremiereapp.appspot.com/

Allez-y, je l'ai envoyée au moment où j'ai écrit ce tutoriel et elle tourne toujours à l'heure où vous lisez ces lignes ! Google se charge de gérer les serveurs et de faire en sorte que les sites web soient toujours en ligne, c'est l'intérêt justement d'utiliser une solution de cloud PaaS (Platform as a Service) comme Google App Engine. :)

Mais... Mon site est dans un sous-domaine de appspot.com, je n'aime pas l'adresse que ça lui donne ! Il n'y a pas moyen de changer ça ? :o

Bien sûr que si ! :D

Vous pouvez tout à fait faire en sorte que votre site soit disponible depuis http://www.monsupersite.com/ (si vous avez acheté le nom de domaine), pour ne pas que vos visiteurs voient un "appspot.com" qui n'a rien à faire là pour eux.

Il faut aller dans l'administration de l'application, section "Administration" > "Application Settings" et cliquer sur le bouton "Add Domain" dans "Domain Setup". Il faudra associer au préalable le domaine avec Google Apps et modifier les entrées DNS auprès du registrar chez qui vous avez acheté le nom de domaine. Toutes les instructions sont données dans la documentation de Google. Allez, ne faites pas cette tête, un peu de lecture de documentation ne peut pas vous faire de mal !

Et maintenant

Bravo, vous avez réussi à déployer votre première application Google App Engine !

Dans la suite de ce cours, nous allons découvrir dans le détail toutes les fonctionnalités offertes par Google App Engine : comment stocker des données dans le Datastore, comment authentifier les utilisateurs depuis leur compte Google, envoyer des e-mails, gérer le cache et bien d'autres choses !

N'oubliez pas de faire vos exercices avant de passer à la partie suivante ! Vous trouverez les liens des exercices (1 quiz et 1 activité) dans le plan principal du cours. À vous de jouer !


Google WEEB

Comment stocker des données dans le Cloud ?

Le stockage de données est le point le plus important, que dis-je, le plus fondamental, le plus crucial d'une application web ! Où stocker la liste de vos membres ? Les messages qu'ils postent ? Les commandes qu'ils effectuent ? Les fichiers qu'ils envoient ?

Ce n'est pas un hasard si, après avoir découvert les bases d'App Engine, nous enchaînons tout de suite sur le stockage des données. C'est vraiment le vif du sujet.

Bien sûr, App Engine nous offre beaucoup d'autres services (et je vous les présenterai dans une prochaine partie). Mais votre site web ne sert à rien si vous ne savez pas comment y stocker des données. Nous allons donc passer du temps à découvrir les choix qui s'offrent à nous dans ce chapitre, puis à apprendre à nous servir des différents moyens de stockage à notre disposition dans les prochains chapitres.

Vous allez voir, avec une architecture Cloud comme Google App Engine il y a des choses qu'on avait pris l'habitude de faire qui ne sont plus possibles. Ecrire un fichier sur le disque du serveur est par exemple interdit ! Pourquoi ? Ah ah, il y a une vraie raison à ça, je vais vous l'expliquer. :)

Une affaire d'architecture de serveurs

Avant d'aller plus loin, il faut qu'on parle ensemble de l'architecture des serveurs d'un site web. C'est une notion indispensable pour comprendre la suite.

Comme vous le savez peut-être, les serveurs peuvent fournir différents services :

  • Le serveur web : c'est lui qui répond directement aux requêtes des clients et qui exécute les instructions de la page en Java, Python, PHP... Son rôle revient grosso modo le plus souvent à renvoyer une page HTML au client.

  • Le serveur de stockage de fichiers : il se contente de stocker des fichiers statiques (donc pas de Java, Python ou PHP là-dedans!). Ca concerne aussi bien les images de votre site, les images uploadées par vos visiteurs, les fichiers CSS, les fichiers JS, etc. Ces fichiers peuvent être efficacement servis via un CDN (un ensemble de serveurs répartis sur la planète).

  • Le serveur de base de données : il enregistre les informations de façon structurée. Il stocke la liste des membres, la liste des messages, la liste des commandes, etc.

Ces serveurs peuvent être tous regroupés au sein d'une même machine physique. Une seule machine peut en théorie faire toutes ces choses-là à la fois. C'est l'architecture serveur la plus simple :

L'architecture la plus simple : un seul serveur fait tous les services
L'architecture la plus simple : un seul serveur fait tous les services

Cette architecture est la plus facile à mettre en place. Mais elle a un gros défaut : si la machine rend l'âme, votre site web ne fonctionnera plus du tout ! Pire, si le disque dur est grillé et que vous n'avez pas de sauvegardes, non seulement vous perdez toutes les données de la base, mais aussi tous les fichiers stockés !

Pour remédier à ce problème, on commence par séparer les services sur différentes machines physiques :

Les services sont répartis sur des serveurs différents
Les services sont répartis sur des serveurs différents

Cette architecture est déjà bien meilleure. On évite de surcharger le serveur web (souvent appelé le "frontal web") car on répartit le reste des activités sur d'autres serveurs : un serveur de stockage de fichiers, un serveur de base de données...

Comme vous le voyez, les clients accèdent directement au frontal web (pour lui demander la page HTML) et au serveur de fichiers (pour lui demander les autres fichiers statiques, comme les CSS, JS, images...). En revanche ils n'ont pas à accéder au serveur de base de données directement. C'est le frontal web qui y fait appel pour récupérer des informations stockées et construire la page HTML.

Mais il y a toujours un défaut : si le disque du serveur de base de données rend l'âme, il n'y a plus de base de données ! Si le frontal web devient surchargé, il ne peut plus traiter les demandes et n'a plus assez de puissance pour exécuter les fichiers Java / Python / PHP / etc. Du coup, on commence à redonder chaque serveur pour chaque service. On en met plusieurs :

On redonde les serveurs pour éviter les pannes et avoir plus de puissance
On redonde les serveurs pour éviter les pannes et avoir plus de puissance

Et là ça devient vraiment compliqué : comment indiquer au client quel serveur il doit appeler ? Comment gérer la charge de chaque machine ? Comment empêcher que des clients appellent une machine qui ne répond plus ? Il faut faire du load balancing, c'est-à-dire de la répartition de charge, et ça devient vite complexe.

C'est là qu'un service de Cloud en PaaS comme Google App Engine fait des merveilles : il simplifie toute la gestion des serveurs pour que vous n'ayez plus à vous en préoccuper. Vous n'avez plus besoin de savoir ce qui se passe au niveau des serveurs.

En général, on représente ce principe de façon très simple : sous la forme d'un nuage qui masque la complexité (d'où le nom "cloud").

Le Cloud masque la gestion des serveurs pour vous simplifier la vie
Le Cloud masque la gestion des serveurs pour vous simplifier la vie

Cette simplicité apparente ne doit pas vous tromper. Si vous ne manipulez plus les serveurs directement, vous allez quand même devoir utiliser les services fournis par Google dans votre application pour qu'elle fonctionne. Quels sont ces services ? C'est ce que nous allons voir maintenant !

Stocker, oui mais où ?

Nous venons de voir que l'architecture des serveurs du Cloud était... nébuleuse. On ne sait pas combien de serveurs sont utilisés par Google App Engine : ce nombre augmente ou diminue tout seul au fil du temps. Il ne faut plus penser en serveurs mais en services. App Engine nous fournit une flopée de services pour résoudre nos problèmes les plus courants. Dans cette partie du cours, nous nous intéressons aux services de stockage.

Les services de stockage d'App Engine

Réfléchissez un instant. Qu'avez-vous l'habitude de stocker d'habitude ?
On pourrait distinguer deux types de besoins :

  • Stocker des informations : on a très régulièrement besoin d'enregistrer des informations. Ca peut être le nom d'un nouveau membre, un message qu'il laisse, une commande qu'il effectue sur le site...

  • Stocker des fichiers : on a parfois besoin de stocker de nouveaux fichiers, que ce soient des images, des .zip, etc. Ces fichiers sont le plus souvent uploadés par les utilisateurs du site web.

Pour répondre à ces besoins, Google App Engine fournit différents services :

  • Pour le stockage d'informations, on a en général besoin d'une base de données. C'est en effet le moyen le plus sûr et le plus structuré pour "ranger" les informations. Google App Engine propose 2 types de bases de données :

    • Une base de données relationnelle SQL : c'est le service Google Cloud SQL. Il s'agit en fait d'une base de données MySQL gérée en Cloud.

    • Une base de données non relationnelle NoSQL : c'est le service Datastore. Il est basé sur Big Table, le système de stockage créé par Google pour ses propres services pour des besoins de performance (qui a d'ailleurs lui-même inspiré en bonne partie le mouvement NoSQL).

  • Pour le stockage de fichiers, on utilisera le service Google Cloud Storage. A noter qu'il existe aussi le Blobstore qui fait globalement la même chose mais avec moins de fonctionnalités (et comme il tend à être remplacé par Google Cloud Storage nous n'en parlerons pas ici).

Résumons dans un schéma les différents choix qui s'offrent à nous :

Les services de stockage Cloud de Google
Les services de stockage Cloud de Google

Ok, je sais faire la différence entre des fichiers et des données. Par contre, comment je sais moi si mes données sont "fortement structurées" ? :euh:

C'est clairement la question la plus délicate. Tout dépend de votre modèle de données, de l'importance des données que va traiter votre site et de bien d'autres choses. Voici d'autres façons de le voir pour vous aider à choisir :

  • Si vous adaptez un site déjà existant sur Google App Engine et que vous utilisez une base de données relationnelle comme MySQL, il est inutile de tout changer. Utilisez la base de données relationnelle Google Cloud SQL. Elle sera compatible.

  • Si vous êtes curieux de découvrir une nouvelle façon de stocker les données, que vous avez toujours entendu parler de NoSQL mais que vous n'avez jamais eu l'occasion de vous y mettre, essayez-vous au Datastore.

  • Si vous préférez opter pour la prudence et que vous avez vos habitudes pour créer une base de données, ne changez pas tout et utilisez Google Cloud SQL. Vous saurez vous y retrouver rapidement.

  • Si vous créez un nouveau site et que vous anticipez un très fort trafic, beaucoup de lectures et d'écritures simultanées, utilisez le Datastore. Le fait qu'il soit basé sur Big Table, le système de stockage utilisé par Google lui-même, vous indique à quel point il peut être performant. En contrepartie, vous ne pourrez cependant plus utiliser certaines fonctionnalités non essentielles des bases de données SQL.

Vous voulez plus de détails techniques ? Très bien très bien, alors voici un petit tableau comparatif SQL vs NoSQL :

Fonctionnalité | SQL (ex : MySQL) | NoSQL (ex : Datastore) | Avantage
Scalabilité multi-serveurs | Limité à un serveur principal pour les écritures. Pour avoir plus de puissance en écriture il faut un plus gros serveur. | Multi-serveurs par défaut, pas de limitations. La charge est aisément répartie sur plusieurs serveurs. | NoSQL
Structuration des données | Les données sont toujours très structurées dans des tables. Pratique quand on a besoin d'une structure précise. | Adapté pour les données en structure arborescente (ex : XML, JSON...) dont la forme peut varier. | Dépend des besoins
Puissance du langage SQL | Permet d'effectuer des requêtes complexes et précises (parfois assez lentes). | Permet d'effectuer seulement des requêtes simples, mais rapides. | SQL
Schéma des données | Le schéma est contraignant : vous devez absolument faire "rentrer" les données dans les cases prévues. Avantage : tout est toujours proprement rangé. | Le schéma n'est pas contraignant : vous pouvez faire ce que vous voulez, stocker comme vous le voulez. Défaut : il faut vérifier manuellement si tout est bien rangé. | Dépend des besoins
Transactions | Les transactions sont strictes : les données sont immédiatement enregistrées et à jour. | Les transactions sont possibles mais cela demande plus de travail. Les données peuvent être enregistrées avec un léger retard. | SQL

Ne cherchez pas un gagnant là-dedans : tout dépend en réalité de vos besoins.

Retenez surtout que les bases de données SQL comme MySQL structurent les informations sous forme de tableaux (appelés les tables). Vous connaissez certainement déjà ça.
En revanche, les bases NoSQL comme le Datastore sont beaucoup plus basiques : elles stockent des paires de données clé-valeur. Par exemple : pseudo = "Mateo21". Les données sont assemblées entre elles mais de façon beaucoup moins forte et structurée que dans une base SQL. En fait, il faut imaginer que le Datastore ressemble plus à un système de stockage XML qu'à des tableaux.

Différences entre les structures SQL et NoSQL
Différences entre les structures SQL et NoSQL

Nous y reviendrons bien plus en détail quand nous parlerons du Datastore. ;)

Pas de configuration à faire, mais de nouvelles règles

L'intérêt de tous ces services de stockage Cloud est que vous n'avez pas à gérer le nombre de serveurs nécessaires pour que votre application fonctionne. Vous n'avez pas besoin non plus d'installer les logiciels, de les configurer et de faire les mises à jour. Par exemple, Google Cloud SQL, qui est basé sur MySQL, vous épargne toute l'installation et la configuration de MySQL. S'il y a une mise à jour de sécurité à faire, c'est Google qui s'en charge de façon transparente pour vous.

Pour information, Google Cloud Storage et Google Cloud SQL peuvent être utilisés de façon totalement indépendante à Google App Engine. Si vous avez besoin de stocker des fichiers ou de monter une base de données MySQL, vous pouvez le faire sans avoir à créer un site web sur App Engine. Rendez-vous sur Google API console et activez le service dont vous avez besoin !

Cette simplicité s'accompagne cependant de nouvelles règles. Avec l'architecture cloud de Google App Engine, vous ne savez pas combien de frontaux web sont utilisés pour faire tourner votre site. Ce nombre augmente ou diminue tout seul au fil du temps en fonction des besoins. Potentiellement, plusieurs frontaux web peuvent tourner en même temps. Tôt ou tard, vous allez vous poser une question anodine et pourtant très importante : si un visiteur envoie un fichier via un formulaire, où doit-on le stocker ?

Si vous aviez une architecture simple avec un seul serveur, vous pourriez stocker le fichier quelque part sur votre serveur et ça fonctionnerait. Mais ce n'est plus possible avec de multiples serveurs sur App Engine : s'il y a à un moment donné 3 frontaux A, B et C et qu'un visiteur uploade sur le frontal A, les frontaux B et C ne posséderont pas le fichier !

Les frontaux web de Google App Engine ne sont pas faits pour stocker les données
Les frontaux web de Google App Engine ne sont pas faits pour stocker les données

La même chose est valable pour les fichiers comme pour les données d'une base. Impensable de stocker ça sur les frontaux web vu qu'ils sont nombreux et peuvent naître comme mourir à chaque instant en fonction du trafic ! Voilà pourquoi Google nous interdit d'écrire des fichiers sur les frontaux web. Cela fait partie des nouvelles règles que nous allons devoir respecter.

La solution est d'utiliser les services de Google, comme Google Cloud Storage pour le stockage de fichiers uploadés.

Utiliser des serveurs spéciaux permet à tout le monde de retrouver les données
Utiliser des serveurs spéciaux permet à tout le monde de retrouver les données

Les frontaux web d'App Engine sont dits stateless. Cela veut dire qu'ils ne fournissent que de la puissance de calcul pour créer vos pages web. Ils ne stockent aucune donnée, ils n'ont pas d'état, c'est pour ça qu'on dit qu'ils sont stateless.
Cela permet à App Engine de tuer à tout moment une machine si le trafic est faible ou si elle ne répond plus (pour ne pas bloquer tout le reste des serveurs). Oui je sais, c'est terrible, le monde des serveurs est sans pitié. :diable:

Google Cloud Storage, Google Cloud SQL, le Datastore... Ca fait quand même beaucoup de services qu'il va falloir apprendre à utiliser. Va-t-on tous les passer en revue ? :o

Mais bien sûr ! Qu'alliez-vous croire, je ne comptais pas vous abandonner en chemin ! ;)

En vérité, je ne vous expliquerai pas le langage SQL ici. Il y a déjà un très bon tutoriel sur MySQL si vous avez besoin d'apprendre ce langage. Je vous expliquerai en revanche comme mettre en place Google Cloud SQL et comment l'utiliser dans votre application App Engine.
Je vous présenterai aussi Google Cloud Storage, mais il n'est pas non plus très complexe à prendre en main.

En revanche, le Datastore méritera qu'on y passe plus de temps. Plusieurs chapitres complets y seront consacrés, car nous devons nous mettre dans la philosophie NoSQL, comprendre les spécificités du Datastore, construire et optimiser notre application App Engine. Bref, nous allons avoir du pain sur la planche !


Google WEEB

Google Cloud SQL

Nous venons de faire un tour d'horizon des différentes méthodes de stockage dans le Cloud de Google. Comme vous avez dû le constater, ce ne sont pas les services qui manquent, mais encore faut-il savoir les utiliser !

Le premier service que j'aimerais vous présenter ici est Google Cloud SQL. Je commence par lui, et non par le Datastore, pour différentes raisons :

  • Les bases de données SQL sont en général connues des développeurs web. Je ne prends pas beaucoup de risques en affirmant que vous avez déjà dû en manipuler une, alors que le Datastore vous est encore complètement inconnu.

  • Google Cloud SQL est en fait d'une base de données MySQL dans le Cloud. Si vous avez un dump (une sauvegarde) d'une base MySQL, vous pourrez le stocker dans Google Cloud SQL et commencer à l'utiliser tout de suite.

Google Cloud SQL est donc un bon moyen pour nous de découvrir un service de stockage Cloud sans être trop dépaysés. :)

Nous allons ici associer une base de données Google Cloud SQL à une application App Engine... mais ce n'est absolument pas obligatoire. Sachez qu'on peut aussi utiliser Google Cloud SQL de façon totalement indépendante. Si vous avez "juste" besoin d'une base de données gérée dans le Cloud (pour ne pas avoir à vous occuper de l'installation, de la configuration et de la maintenance), Google Cloud SQL est peut-être la réponse que vous cherchez.

Nous allons commencer par voir comment créer une instance Google Cloud SQL. Nous verrons ensuite comment la connecter à notre application Java EE sous App Engine. Enfin, pour que vous ayez un exemple complet sous les yeux, je vous montrerai comment réaliser un mini livre d'or sous App Engine en utilisant Google Cloud SQL pour le stockage ! :)

Contrairement au Datastore, Google Cloud SQL ne peut pas être utilisé gratuitement même si on a un petit trafic. Il faut payer (un peu) pour pouvoir l'utiliser. Le prix dépend de la puissance nécessaire et du temps que vous souhaitez l'utiliser (ça démarre à 0,025$ de l'heure environ).

Activer Google Cloud SQL dans l'API Console

Google Cloud SQL étant un service indépendant, on l'active dans l'interface Google APIs Console. C'est l'interface qui regroupe progressivement tous les accès aux API de Google, de l'API Google Maps à l'API Google+, en passant par Google Calendar et bien d'autres.

Commencez donc par vous rendre sur l'interface API Console à l'adresse suivante :
https://code.google.com/apis/console

La première fois, Google API Console vous accueille en vous demandant de créer un nouveau "projet API console". Cela permet de regrouper vos différents projets qui utilisent les APIs de Google.

Google API Console vous demande de créer un nouveau projet
Google API Console vous demande de créer un nouveau projet

Cliquez sur le bouton pour créer un nouveau projet. La liste de toutes les APIs de Google utilisables apparaît. Oui, il y en a beaucoup !

La liste de toutes les APIs utilisables
La liste de toutes les APIs utilisables

Repérez "Google Cloud SQL" dans la liste et cliquez sur le bouton pour l'activer.

Activez Google Cloud SQL
Activez Google Cloud SQL

On vous demande de donner un nom à votre projet Google Cloud SQL. Indiquez le nom que vous voulez :

Donnez un nom à votre projet Cloud SQL
Donnez un nom à votre projet Cloud SQL

... puis validez les conditions d'utilisation :

Validez les conditions d'utilisation
Validez les conditions d'utilisation

Ouf, vous y êtes ! Vous devriez voir un lien "Google Cloud SQL" apparaître dans le menu de gauche :

Un lien Google Cloud SQL est apparu dans le menu
Un lien Google Cloud SQL est apparu dans le menu

Euh... Qu'est-ce que c'est le point d'exclamation à côté de "Billing" ? :euh:

Ca, c'est le signal que Google vous demande de sortir la carte bancaire. :p
Rendez-vous dans la section Billing pour rentrer les informations de paiement. Elles seront utilisées uniquement pendant le temps que vous utiliserez des instances Google Cloud SQL. Comme je le disais en introduction, une utilisation courte de quelques heures coûte autour de 1$ (pour vous donner une idée).

Créer un projet Google Cloud SQL

Maintenant que nous avons activé Google Cloud SQL (et que nous avons entré les informations de paiement dans la section "Billing") nous pouvons créer une instance Google Cloud SQL. Cela consiste à demander à Google de lancer des serveurs MySQL dans le Cloud. Google démarrera alors des machines en fonction de vos besoins.

Je rappelle que notre but est au final de créer des tables dans la base de données. Courage, sur l'ensemble du processus, nous venons de faire la moitié. :)

Nous sommes à la moitié du chemin !
Nous sommes à la moitié du chemin !

Créer un projet App Engine (facultatif)

Avant ça, je vous invite à créer d'abord un nouveau projet App Engine pour nos tests. En effet, en créant un projet Google Cloud SQL, on vous demandera le nom de votre projet App Engine (si vous voulez utiliser Cloud SQL avec App Engine). Autant commencer par là donc. :)

Vous savez déjà créer un projet App Engine. Il suffit de vous rendre sur https://appengine.google.com/ et de cliquer sur "Create Application". Pour mémoire, nous en avons parlé dans un chapitre précédent.

Pour ma part, je vais appeler le projet sdz-guestbook-cloudsql, car nous allons faire un petit livre d'or (guestbook) par la suite.

Créer le projet Cloud SQL

Retour à l'API Console. Cliquez dans le menu sur "Google Cloud SQL" que vous avez activé. Vérifiez qu'il n'y a pas de point d'exclamation devant la section "Billing" (sinon vous ne pourrez pas créer d'instance !).

Cliquez sur "New instance". Une fenêtre apparaît. Elle vous demande les informations nécessaires pour créer votre instance Cloud SQL :

Configuration de Google Cloud SQL dans Eclipse
Configuration de Google Cloud SQL dans Eclipse

Il y a plusieurs champs à saisir et il faut bien comprendre ce que vous faites :

  • Name : c'est le nom de l'instance. Il doit être unique et ne pas avoir déjà été utilisé par quelqu'un d'autre. Utilisez des caractères simples (pas de caractères spéciaux ni d'espaces).

  • Location Options : vous permet d'indiquer si vous voulez utiliser les datacenters de Google aux Etats-Unis ou en Europe. Idéalement, je choisirais l'Europe pour des questions de performance pour ma part... cependant, il faut que l'instance App Engine avec laquelle vous vous connectez soit sur le même continent pour que ça fonctionne. Or, les instances App Engine gratuites sont forcément situées aux Etats-Unis. On se contentera donc des Etats-Unis.

    Notez que le choix du lieu de stockage n'est pas qu'une question de performances... Si on vous offre ce choix, c'est aussi pour des raisons juridiques.
    En effet, toute donnée stockée aux Etats-Unis (que ce soit chez Google ou n'importe qui d'autre) peut potentiellement être lue par le gouvernement américain en-dehors d'une procédure judiciaire. Il y a une loi qui permet cela : le "Patriot Act".
    De façon générale, je constate que le lieu où sont stockées les données prend de plus en plus d'importance juridique et politique. Si vous vous sentez concerné par le sujet, parlez-en avec un juriste qui connaîtra mieux le sujet que moi.

  • Size : la puissance de la machine qui hébergera MySQL. Les machines les plus puissantes disposent de plus de mémoire (voir les prix).

  • Replication mode : choisissez entre Synchronous (synchrone) et Asynchronous (asynchrone). C'est le mode de copie des données d'un serveur à un autre (pour éviter la perte de données si le serveur tombe). Avec Synchronous, vous avez la garantie de ne perdre aucune donnée, mais les écritures dans la base seront plus longues. Avec Asynchronous, vous pouvez perdre les dernières millisecondes (voire les dernières secondes) d'écriture quand un serveur tombe, mais l'ensemble des écritures sera plus rapide. Je vous conseille de choisir Asynchronous sauf si les données que vous comptez héberger sont vraiment critiques et que perdre la moindre information serait une catastrophe (donc si vous êtes une banque, cochez Synchronous :p ).

  • Pricing plan : c'est le mode de calcul du paiement. Vous avez le choix entre "Per use" et "Package". Le mode "Per use" est le plus flexible : Google compte le nombre d'heures que vous utilisez l'instance et vous les facture. Le mode "Package" vous permet de payer à la journée et vous permet d'avoir des réductions. Sélectionnez "Per use" si vous hésitez pour commencer, c'est le plus flexible.

  • Authorized applications : ce sont les noms des applications App Engine qui utiliseront votre instance Cloud SQL. Si vous ne voulez pas utiliser Cloud SQL avec App Engine (je vous rappelle que ce n'est pas obligatoire), vous pouvez laisser cette section vide. Pour ma part, je vais indiquer le nom de l'application App Engine que j'ai créée tout à l'heure : sdz-guestbook-cloudsql.

Ouf ! Au bout de quelques secondes, l'instance Google Cloud SQL est créée et le tableau de bord s'affiche :

Le tableau de bord de l'instance Google Cloud SQL
Le tableau de bord de l'instance Google Cloud SQL

De là, vous avez plusieurs onglets que vous pouvez consulter :

  • Logs : vous permet d'avoir les logs d'utilisation de l'instance.

  • SQL Prompt : vous permet de saisir des commandes SQL (pour tester, pour faire des modifications "à chaud"...).

  • Backups : vous permet de configurer les heures des sauvegardes. Les sauvegardes sont automatiques et incluses dans le prix des instances Cloud SQL.

Il faut bien comprendre que nous venons de créer une instance Cloud SQL. En gros, nous venons de monter un serveur.
Sur une instance, vous pouvez créer plusieurs bases de données, qui elles-mêmes peuvent contenir plusieurs tables.

Exemple : Cloud SQL dans une application

Résumons :

  1. Nous avons activé l'utilisation de Google Cloud SQL dans l'API Console de Google

  2. Nous avons créé une application App Engine pour nos tests (j'ai appelé la mienne sdz-guestbook-cloudsql)

  3. Nous avons créé une instance Google Cloud SQL qui est prête à recevoir des instructions

Il ne reste plus que l'essentiel... Découvrir comment utiliser Google Cloud SQL dans notre application App Engine ! :D

Je vous propose de découvrir tout cela à travers un exemple. Nous allons créer un mini livre d'or : les visiteurs du site pourront poster leur nom et un message pour nous dire combien ils aiment notre site.

L'application de livre d'or que nous allons créer sur Cloud SQL et App Engine
L'application de livre d'or que nous allons créer sur Cloud SQL et App Engine

Création du schéma SQL

Pour commencer, il faut créer la base de données. L'API Console nous donne justement accès à un formulaire permettant de saisir des requêtes SQL. Vous vous souvenez de la commande SQL qui permet de créer une base ?

CREATE DATABASE guestbook;

On ne l'exécute pas tous les jours, c'est vrai. ;)

Rentrez-la dans le formulaire de l'API Console :

Création d'une base avec une commande SQL
Création d'une base avec une commande SQL

Cliquez sur "Execute". Vous venez de créer une nouvelle base ! Sélectionnez-la dans le menu déroulant pour pouvoir exécuter vos prochaines requêtes au sein de cette base :

Choisissez la base que vous venez de créer pour la prochaine commande
Choisissez la base que vous venez de créer pour la prochaine commande

Parfait. Il ne nous reste plus qu'à créer notre table qui va stocker les messages du livre d'or. Pour notre exemple on va faire très simple : une table qui stocke le nom et le message du visiteur.

La commande SQL suivante permet de créer notre table :

CREATE TABLE messages (name VARCHAR(255), message TEXT, id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(id))

Voilà qui est fait ! :D Si vous voulez vérifier que tout s'est bien passé, vous pouvez exécuter la commande suivante pour afficher la structure de votre table :

DESCRIBE messages;

Résultat :

La structure de la table que nous venons de créer
La structure de la table que nous venons de créer

Mais au fait, il n'existe pas des logiciels bien faits pour administrer visuellement une base de données MySQL ? Du genre MySQL Admin ou phpMyAdmin ?

Si si. Vous pouvez utiliser un logiciel qui supporte les connexions via JDBC comme Squirrel Sql. Google donne dans sa doc des instructions pour vous connecter à une base Cloud SQL depuis Squirrel sql. Cela vous permettra d'administrer un peu plus visuellement votre base de données. :)

Initialement, on ne pouvait pas utiliser d'outil comme phpMyAdmin qui ne supporte pas les connexions via JDBC. Mais à présent, des moyens existent pour utiliser Google Cloud SQL avec PHPmyadmin, comme vous pouvez le voir dans la documentation de Google Cloud et dans ce tutoriel.

Création de l'application App Engine

Retournons sur Eclipse où nous allons écrire le code du livre d'or utilisant Cloud SQL. On va créer une nouvelle application App Engine comme on a appris à le faire. Allez dans File / New / Web Application Project.

Le plugin Eclipse de Google App Engine est capable de travailler avec un MySQL installé sur votre machine pour simuler le fonctionnement de Google Cloud SQL en local. En clair, même si vous n'avez pas créé d'instance en ligne tout à l'heure, vous allez pouvoir tester sur votre machine les codes qui vont suivre sans problème !

Je vais appeler le projet "guestbookCloudSql". Je laisse coché "Generate sample code" pour avoir un peu de code sur lequel me baser et je décoche "Use Google Web Toolkit" qui ne nous sert pas ici.

Activation de Google Cloud SQL dans Eclipse

Par défaut, Google Cloud SQL n'est pas activé. Faites un clic droit sur le nom du projet (GuestbookCloudSql) dans l'arborescence et sélectionnez Properties. Dans la fenêtre qui s'ouvre, rendez-vous dans la section Google / App Engine et cochez la case "Enable Google Cloud SQL".

Configuration de Google Cloud SQL dans Eclipse
Configuration de Google Cloud SQL dans Eclipse

On y distingue 2 types d'instance :

  • L'instance de développement : vous pouvez utiliser soit une instance MySQL locale quand vous développez, soit une instance Google Cloud SQL en ligne.

  • L'instance de production : c'est l'instance qui sera utilisée lorsque votre application sera déployée en ligne.

Si vous voulez utiliser une instance MySQL locale, il vous faudra installer MySQL vous-mêmes sur votre machine. Cliquez ensuite sur "Configure" dans la fenêtre pour indiquer à Eclipse comment s'y connecter.

Pour ma part je vais faire très simple ici : je vais utiliser la même instance Google Cloud SQL en ligne pour développer que pour la production. C'est très mal, je sais, mais j'ai la flême d'installer MySQL sur ma machine et je n'ai pas envie de payer 2 instances Cloud SQL juste pour faire ce tutoriel, j'espère que vous ne m'en voudrez pas. :D

Je vais donc cliquer sur les liens "Configure" à droite de "Use Google Cloud SQL instance" et de "App Engine SQL instance". Je vais y rentrer les informations pour me connecter à la base :

Connexion aux instances Cloud SQL
Connexion aux instances Cloud SQL

Le nom de l'instance (instance name) est affiché sur le tableau de bord sur l'API Console. C'est un nom unique qui représente votre instance Cloud SQL chez Google.

Notez que par défaut seul le compte root (sans mot de passe) est créé. J'utilise celui-ci pour mes exemples. Dans la pratique, vous devriez créer des utilisateurs et leur donner des droits plus limités (parce que root bon, hein, il peut tout faire :-° ). Lisez la doc de MySQL sur la création d'utilisateurs pour en savoir plus.

Utiliser Cloud SQL depuis l'application App Engine

Allez, il est temps de coder. :)
Vous allez voir, il n'y a rien de bien particulier par rapport à une application Java EE classique... si ce n'est la façon de se connecter à la base.

Je vous ai fait créer une Web Application basique avec un peu de code de base. Je vous propose de faire une application qui fonctionne sur une seule page (la page d'accueil "/"). On agira différemment sur cette page en fonction de la méthode d'appel du client :

  • Avec la méthode HTTP GET, on affichera un formulaire pour remplir le livre d'or et la liste des derniers messages postés.

  • Si le visiteur envoie des données avec la méthode HTTP POST sur la même URL, nous enregistrerons les informations en base et nous le redirigerons vers la même page en GET.

Nous allons travailler sur 3 fichiers pour faire très simple :

  • src/guestbook/GuestbookServlet.java : c'est notre servlet qui contiendra les instructions pour manipuler la base de données Cloud SQL. On y implémentera les méthodes doGet et doPost.

  • war/WEB-INF/guestbook.jsp : c'est notre JSP qui affichera le formulaire et les messages.

  • war/WEB-INF/web.xml : le fichier de configuration qui permet d'indiquer les routes (URLs) de notre application.

Commençons par le fichier web.xml de configuration, c'est le plus simple :

<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
    <servlet>
        <servlet-name>Guestbook</servlet-name>
        <servlet-class>guestbook.GuestbookServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Guestbook</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>guestbook.jsp</welcome-file>
    </welcome-file-list>
</web-app>

On indique que notre servlet Guestbook correspond à l'URL "/" (la page d'accueil). On affiche par défaut au visiteur la page guestbook.jsp.

La JSP est très simple, c'est pratiquement du HTML. On va y récupérer une variable messages qui contiendra les résultats de la base de données. On fait une boucle dessus pour afficher les messages après avoir créé le formulaire :

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.sql.*"%>

<!DOCTYPE html>

<html>
    <head>
        <title>Livre d'or</title>
        <meta charset="utf-8" />
    </head>

    <body>
        <h1>Vous avez aimé mon site ? Dites-le dans Cloud SQL !</h1>
        <form action="/post" method="post">
            <p>
                <label>Votre nom : <input type="text" name="name" /></label>
            </p>
            <p>
                <label>Votre message :<br />
                <textarea name="message" style="width: 200px; height: 100px;"></textarea></label>
            </p>
            <p>
                <input type="submit" />
            </p>
        </form>

        <h1>Ils ont aimé :</h1>
        <%
            ResultSet messages = (ResultSet) request.getAttribute("messages");
            while (messages.next()) {
        %>
        <p>
            <strong><%= messages.getString("name") %></strong> a écrit :<br />
            <%= messages.getString("message") %>
        </p>
        <%
            }
        %>
    </body>
</html>

Reste maintenant le coeur, le plus "dur" si on peut l'appeler comme ça, c'est-à-dire la servlet. C'est là que ça se passe :

package guestbook;

import java.io.IOException;
import java.sql.*;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import com.google.appengine.api.rdbms.AppEngineDriver;

@SuppressWarnings("serial")
public class GuestbookServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse resp) {
        try {
            Connection c = null;
            DriverManager.registerDriver(new AppEngineDriver());
            c = DriverManager.getConnection("jdbc:google:rdbms://simple-it.fr:testcloudsql:test-cloud-sql/guestbook");

            ResultSet resultats = c.createStatement().executeQuery("SELECT name, message FROM messages ORDER BY id DESC LIMIT 20");
            req.setAttribute("messages", resultats);
            this.getServletContext().getRequestDispatcher("/WEB-INF/guestbook.jsp").forward(req, resp);
        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void doPost(HttpServletRequest req, HttpServletResponse resp) {
        try {
            Connection c = null;
            DriverManager.registerDriver(new AppEngineDriver());
            c = DriverManager.getConnection("jdbc:google:rdbms://simple-it.fr:testcloudsql:test-cloud-sql/guestbook");

            PreparedStatement stmt = c.prepareStatement("INSERT INTO messages (name, message) VALUES( ? , ? )");
            stmt.setString(1, req.getParameter("name"));
            stmt.setString(2, req.getParameter("message"));
            stmt.executeUpdate();
            resp.sendRedirect("/");
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Bon tout ça c'est beaucoup de blabla, c'est du Java EE classique. Qu'est-ce qu'il faut retenir, qu'est-ce qui est spécifique à App Engine ?

Eh bien tout d'abord on charge le package qui contient le driver Google pour manipuler la base de données :

import com.google.appengine.api.rdbms.AppEngineDriver;

Ensuite, on charge le driver et on se connecte à notre base :

DriverManager.registerDriver(new AppEngineDriver());
c = DriverManager.getConnection("jdbc:google:rdbms://simple-it.fr:testcloudsql:test-cloud-sql/guestbook");

Remplacez simple-it.fr:testcloudsql:test-cloud-sql par le nom de votre instance Cloud SQL. Remplacez le "/guestbook" qui suit par le nom de votre base de données.
En résumé, la syntaxe est jdbc:google:rdbms://<NOM_INSTANCE>/<NOM_BASE>

Voilà ce qu'il faut savoir. :)
Tout le reste n'est en effet que du Java EE classique : exécution de requêtes SQL et requêtes préparées, comme vous devez avoir l'habitude d'en faire !

Si vous voulez tester l'application, je l'ai mise en ligne ici : http://sdz-guestbook-cloudsql.appspot.com/

Pour ceux qui connaissent, sachez que vous pouvez utiliser JPA au lieu de JDBC. JPA vous permet de faire du mapping objet-relationnel et donc de développer à plus haut niveau, sans avoir à écrire manuellement les requêtes SQL.
Si vous ne connaissez pas JPA, je connais un cours sur un certain site qui traite du sujet. ;)

Voilà l'essentiel de ce qu'il faut savoir sur Google Cloud SQL ! Vous avez appris à créer une instance et à vous y connecter depuis votre application App Engine.


Google WEEB

Le Datastore

Le Datastore est la voie royale pour stocker des données sur Google App Engine. C'est clairement l'outil que Google nous conseille d'utiliser. Vous pouvez vous en servir gratuitement (jusqu'à une certaine limite de trafic) et on ne vous en dit que du bien : il serait rapide, capable de gérer de fortes charges, réparti sur de multiples datacenters... On dit même qu'il serait basé sur Big Table, la technologie qu'utilise Google pour stocker toutes ses données, notamment les résultats d'indexation des milliards de pages web par le GoogleBot. Allons bon, rien que ça !

Le Datastore fonctionne en mode High Replication Datastore (HRD). Ce système est très résilient aux erreurs : il fait en sorte que vos données soient copiées sur de multiples datacenters ! L'objectif est que votre application puisse continuer à fonctionner même en cas d'évènement catastrophique (du genre si un datacenter prend feu... :-° ).

Les données stockées dans le Datastore sont répliquées dans de multiples datacenters
Les données stockées dans le Datastore sont répliquées dans de multiples datacenters

Si le Datastore est alléchant, il est néanmoins très différent d'une base de données SQL comme MySQL... Pour vous et moi qui sommes habitués aux bases SQL, c'est un changement très important : le Datastore est ce qu'on appelle une base de données NoSQL.

Une base de données NoSQL ? Ce sont des réactionnaires qui disent "Non au SQL !" c'est ça ?

Non, pas vraiment. :D
En fait beaucoup de gens croient que "NoSQL" est une opposition au SQL, alors que c'est en fait l'acronyme de "Not Only SQL" (pas seulement du SQL). On y reprend des principes de SQL mais pas tous. L'objectif est de se débarrasser de tout ce qui empêche habituellement les sites basés sur SQL de croître avec un fort trafic. Cela implique une philosophie assez différente au final !

Dans ce chapitre, je vais commencer par vous expliquer comment fonctionne le Datastore dans les grandes lignes avant de vous montrer comment vous en servir dans votre application.

Ne sautez pas ce chapitre ! Utiliser Google App Engine sans utiliser le Datastore ce serait comme... eh bien, ce serait comme... Enfin, vous voyez ce que je veux dire. :p

Comprendre le Datastore

Ouvrez grands vos yeux et vos oreilles, c'est le moment d'être attentifs ! Pour utiliser le Datastore, il faut comprendre comment il fonctionne. Et là, vous ne pourrez pas vous baser sur votre expérience dans une base de données comme MySQL, Oracle ou PostgreSQL car le Datastore fonctionne très différemment !

Si vous avez déjà utilisé une base de données NoSQL comme MongoDB ou Redis, certains principes vous seront déjà connus. Néanmoins, je vous recommande aussi la lecture de cette section car le Datastore a ses propres spécificités.

Le Datastore n'est PAS une base de données relationnelle

C'est la première chose à vous mettre dans la tête. Oubliez ce que vous croyez savoir sur les bases de données relationnelles comme MySQL ou PostgreSQL.

Le Datastore est à plusieurs égards beaucoup plus basique et bas niveau qu'une base de données classique. Imaginez le Datastore comme un espace géant prêt à accepter des données. N'importe quelles données. Vous lui envoyez du contenu et il vous le stocke. Quand vous en avez à nouveau besoin, il vous suffit de le lui demander.

Mais... On ne doit pas commencer par créer une base ? Des tables ?

Non ! Le Datastore n'utilise pas de tables. Il n'y a pas de schéma SQL : on dit que le Datastore est schemaless (sans schéma).

On n'a pas besoin de décrire comment sont formées les données avant de les stocker. Le Datastore vous dit tout simplement : "Envoie-moi ce que tu veux stocker, ne te prends pas la tête à créer des tables ou à m'indiquer les relations entre les données. Donne-moi, je stocke, c'est tout."

A la base : une clé et une valeur

Le Datastore peut être utilisé de façon massive, avec beaucoup de données et de requêtes simultanées. Pourtant, à son plus bas niveau, il fonctionne de façon très simple : il accepte des clés et des valeurs. Exactement comme une HashMap (table de hachage).

A son niveau le plus basique, le Datastore ressemble donc à ça :

Le Datastore stocke des paires clé-valeur
Le Datastore stocke des paires clé-valeur

Le Datastore est capable de stocker beaucoup, beaucoup, beaucoup de paires clé-valeur :

Le Datastore est capable de stocker un grand nombre de paires clé-valeur
Le Datastore est capable de stocker un grand nombre de paires clé-valeur

Mais... ce n'est pas structuré ! Ca fait juste un grand bazar ! On ne va quand même pas mélanger des noms de membres, des messages, des commandes...

En fait, le Datastore est un peu plus malin que ça. Il vous permet de regrouper les données dans des entités.

Les entités organisent (un peu) les données

Le Datastore a un concept d'entités. C'est ce qui nous aide à structurer les informations.

Les entités sont des regroupements d'une ou plusieurs paires clé-valeur. Elles ressemblent à ceci :

Le Datastore stocke des entités qui regroupent les paires clé-valeur
Le Datastore stocke des entités qui regroupent les paires clé-valeur

Le Datastore est aussi capable d'associer les entités entre elles. Une entité peut avoir une entité parente, qui peut elle-même avoir une entité parente, etc.
On peut aussi stocker des entités sans parent.

Les entités peuvent avoir une relation de parenté
Les entités peuvent avoir une relation de parenté

Cela m'a l'air quand même sacrément désorganisé ! Les deux enfants de l'entité rouge ont chacun un nombre de paires clé-valeur différentes !

Oui, mais c'est comme ça. Le Datastore est très flexible et ne vous impose pas grand chose. Si vous voulez stocker 2 informations dans une entité, vous pouvez le faire. Si vous voulez en ajouter, faites-le, on ne vous dira rien.

Imaginez que les entités sont comme des objets

Un élément m'a aidé à bien comprendre le Datastore. Je me suis mis à imaginer que les entités sont comme des objets en Java. Un objet possède plusieurs attributs : ce sont les paires clé-valeur. La clé correspond au nom de l'attribut, et la valeur... à sa valeur.

Pour reprendre un exemple que j'aime bien, imaginez un Personnage d'un jeu vidéo. Il possède des attributs : un nom, un niveau de vie... Il possède aussi une Arme qui a ses propres caractéristiques. Les entités dans le Datastore pourraient être représentées comme ceci :

Les entités sont comme des objets
Les entités sont comme des objets

Les entités d'un même groupe (celles qui sont reliées par un lien de parenté) sont stockées sur un même groupe de serveurs par Google pour assurer l'intégrité des données. C'est pratique mais ça n'aide pas à répartir la charge entre de multiples serveurs, car vous ne pouvez mettre à jour les données d'un même groupe d'entités qu'entre 1 et 5 fois par seconde. Oui, c'est très restrictif, donc il faut bien faire attention à ça.
Retenez donc qu'il faut utiliser les relations entre entités avec parcimonie. C'est puissant mais, si on l'utilise de façon trop massive à une grande échelle, cela empêchera votre application de monter en charge avec plus de trafic et de données.

Comment identifier une entité ?

Résumons. Les entités sont des groupes de données qui vivent dans l'espace intersidéral du Datastore. Il peut y en avoir une très grande quantité. Parfois, certaines entités sont reliées entre elles : elles ont une relation de parenté.

Les données (paires clé-valeur) au sein des entités sont appelées des propriétés. Celles-ci stockent obligatoirement des données basiques, comme du texte ou des nombres. La doc de Google nous donne tous les types autorisés pour les propriétés d'une entité. Vous constaterez qu'il y a les types de base de Java mais aussi quelques types un peu plus riches, comme des coordonnées géographiques, mais en gros on ne peut rien y stocker de bien plus complexe (si vous avez besoin de stocker un objet, il faut créer une autre entité).

Nous voulons maintenant savoir comment repérer une entité. Vu qu'il y en a des milliers (que dis-je, des millions voire des milliards !) qui vivent au sein du Datastore, il va falloir leur donner un nom unique pour les repérer ! Une fois qu'on aura l'entité, on saura alors facilement lire et modifier toutes ses propriétés.

Pour identifier une entité, Google utilise la combinaison de 3 informations :

  • Un type (kind) : c'est le type de données de votre entité. Par exemple, on peut dire que le type de données de mon personnage est... "Personnage". C'est ma classe "Personnage".

  • Un identifiant (identifier) : il peut s'agir soit d'une chaîne de caractères soit d'un nombre. Vous pouvez le définir vous-mêmes ou bien laisser Google générer un nombre pour vous.

  • Un parent (ancestor path) : si l'entité possède un parent, celui-ci aidera à identifier l'entité de façon unique. Si l'entité ne possède pas de parent, on dit que c'est une entité racine (root). Dans ce cas l'ancestor path vaut null.

Une fois l'identifiant défini, il n'est plus possible de le changer !

En résumé :

Structure d'un identificateur d'entité
Structure d'un identificateur d'entité

Si on le rapportait à notre exemple précédent avec des personnages et des armes, ça donnerait quelque chose de ce genre :

Exemples d'identificateurs

Les opérations

Maintenant que nous savons comment le Datastore de Google stocke les entités, il ne nous reste plus qu'une chose à voir avant de commencer à coder : quelles actions peut-on faire sur une telle base ?

Il y a 4 opérations de base disponibles dans une base de données NoSQL comme le Datastore :

  • get() : récupère une entité en fonction de son identifiant

  • put() : écrit une entité (ou en écrase une)

  • delete() : supprime une entité via son identifiant

  • query() : retrouve des entités en fonction de certains critères de recherche

Voilà, vous en savez assez sur les concepts du Datastore. Place au code maintenant ! :D

Manipuler le Datastore à bas niveau

Google nous propose plusieurs moyens d'accéder au Datastore. Je vais vous montrer ici la méthode de base, c'est-à-dire la méthode la plus bas niveau. Cela vous permettra de bien comprendre comment fonctionne le Datastore dans ses entrailles et de faire le lien avec ce que je viens de vous expliquer précédemment.

De l'aveu même de Google, manipuler le Datastore à bas niveau n'est pas le plus pratique. On recommande d'utiliser une couche d'abstraction comme la bibliothèque Objectify qui mappe vos objets au Datastore (c'est une sorte d'ORM pour le Datastore). Je vous en parlerai dans un prochain chapitre car c'est certainement avec Objectify que vous réaliserez la plupart de vos vraies applications. En attendant, un peu de pratique à bas niveau ne peut pas vous faire de mal !

Contrairement à Google Cloud SQL, vous n'avez rien à activer pour utiliser le Datastore. En fait, une instance locale du Datastore tourne déjà sur votre machine si vous avez installé le plugin Eclipse ! En somme, il est beaucoup plus facile de se lancer dans une application utilisant le Datastore. :)

Notez que le Datastore peut aussi être utilisé depuis une application externe avec le service Cloud Datastore. Celui-ci est activable depuis l'API Console mais nous ne le ferons pas ici car ce n'est pas nécessaire pour s'en servir depuis une application App Engine.

Récupération du service Datastore

Avant toute chose, vous devez importer les APIs du Datastore dans votre application :

import com.google.appengine.api.datastore.*;

Ensuite, vous devez récupérer un objet représentant le service du Datastore. On fait appel à une factory qui nous renvoie l'objet dont nous allons avoir besoin. Cela se fait en une ligne :

DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

Vous êtes prêts à utiliser le Datastore !

Créer une entité

Pour créer une entité, 3 opérations sont nécessaires :

  • Créez l'objet représentant l'entité, de type Entity

  • Assignez-lui une ou plusieurs propriétés (ce sont les paires clé-valeur)

  • Demandez l'écriture de l'entité au Datastore avec la méthode put()

Essayons de recréer l'entité Personnage que j'avais inventée pour vous expliquer le fonctionnement du Datastore :

Les entités que nous allons créer
Les entités que nous allons créer
// Crée l'entité de type (kind) "Personnage"
Entity personnage = new Entity("Personnage");

// Assigne des propriétés à l'entité
personnage.setProperty("nom", "Groknan le Barbare");
personnage.setProperty("niveau", 25);
personnage.setProperty("vie", 100);

// Enregistre l'entité dans le Datastore
datastore.put(personnage);

Ici, Google a assigné un identifiant numérique automatiquement à l'entité. Si vous voulez lui donner votre propre identifiant, il suffit d'ajouter un second paramètre lorsque vous créez l'entité :

// Crée l'entité de type (kind) "Personnage" avec l'ID "groknan"
Entity personnage = new Entity("Personnage", "groknan");

Si vous exécutez ce code sur votre machine, le Datastore installé localement va stocker les données. Vous pouvez voir les données enregistrées en vous rendant dans la console d'administration intégrée à l'application. Pour mémoire, vous devriez la trouver à l'adresse :

http://localhost:8888/_ah/admin

On y voit l'entité qu'on vient de créer :

Le Datastore viewer intégré à votre application permet de voir les entités
Le Datastore viewer intégré à votre application permet de voir les entités

Le Datastore viewer vous permet de filtrer les données par entité. Vous pouvez les supprimer manuellement à partir d'ici : cliquez sur les cases correspondant aux entités à supprimer et cliquez sur "Delete".

La clé (key) de l'entité que vous voyez ici est la combinaison du type (ici "Personnage"), de la clé (ici "groknan") et des ancêtres (ici, il n'y a aucun ancêtre). C'est elle qui permet à Google de retrouver rapidement l'entité au sein du Datastore, sur le même principe de fonctionnement qu'une HashMap (table de hachage).

Notez que les données ne sont pas supprimées lorsque vous arrêtez le serveur local. Si vous voulez supprimer toute la base locale, il vous suffit de supprimer le fichier war/WEB-INF/appengine-generated/local_db.bin qui a été généré.

Si nous voulons aussi créer l'arme du personnage, il faut spécifier la clé de son parent dans un troisième paramètre en créant l'entité :

Entity arme = new Entity("Arme", "pourfendeur", personnage.getKey());

On récupère comme vous le voyez la clé du parent en faisant appel à personnage.getKey().

Résumons tout ceci dans un code qui crée le personnage et l'arme comme entité fille :

DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

Entity personnage = new Entity("Personnage", "groknan");

personnage.setProperty("nom", "Groknan le Barbare");
personnage.setProperty("niveau", 25);
personnage.setProperty("vie", 100);

Entity arme = new Entity("Arme", "pourfendeur", personnage.getKey());

arme.setProperty("nom", "Pourfendeur des faibles");
arme.setProperty("degats", 250);

datastore.put(personnage);
datastore.put(arme);

Effectuer deux put() d'affilée comme ceci n'est pas très performant car cela provoque 2 appels au Datastore. Si vous avez plusieurs entités à enregistrer d'un coup, regroupez-les au sein d'une liste d'entités (List<Entity> entites = ...) puis faites un put(entites);

Mettre à jour une entité

Surprise ! :D
Le Datastore ne fait pas la différence entre la création et la mise à jour d'une entité. Si vous voulez modifier une entité existante, appelez simplement put() : vous écraserez l'ancienne entité par la nouvelle.

Récupérer une entité grâce à sa clé

La méthode get() permet de récupérer une entité en se basant sur sa clé. Elle attend un objet de type Key qui représente la clé de l'entité.

Il faut commencer par créer la clé qui correspond à l'entité que l'on recherche :

Key clePersonnage = KeyFactory.createKey("Personnage", "groknan");

L'objet clePersonnage représente la clé de l'entité de type "Personnage" et d'ID "groknan".

Si on souhaite créer une clé correspondant à une entité fille, il faut impérativement indiquer la clé du parent en premier paramètre. Pour l'arme, ça donnerait :

Key cleArme = KeyFactory.createKey(clePersonnage, "Arme", "pourfendeur");

On peut ensuite appeler la méthode get() en lui transmettant la clé :

Entity personnageTrouve = datastore.get(clePersonnage);

Maintenant qu'on possède l'entité, si on souhaite récupérer une de ses propriétés, on peut appeler getProperty() :

String nomPersonnage = (String) personnageTrouve.getProperty("nom");

Notez qu'il existe aussi la méthode getProperties() qui renvoie une Map de toutes les propriétés contenues dans l'entité.

Et si je ne connais pas la clé ? Disons, si je veux récupérer tous les personnages qui ont 100 de vie, comment je fais ?

Alors là, il faut effectuer une requête (query). Nous allons en parler juste après, c'est là que les choses vont se corser...

Supprimer une entité

Pour supprimer une entité, il suffit de connaître sa clé et d'appeler delete() :

Key clePersonnage = KeyFactory.createKey("Personnage", "groknan");

datastore.delete(clePersonnage);

Il n'y a pas de suppression automatique en cascade dans le Datastore. Si vous supprimez le personnage, les entités filles (comme l'arme) ne seront pas supprimées. Elles auront toujours le personnage pour parent, même si celui-ci n'existe plus.
C'est à vous de gérer la suppression en cascade au sein du code de votre application si vous ne voulez pas vous retrouver dans ce genre de situation. ;)

Retrouver une entité avec une requête

Pour retrouver une entité si vous ne connaissez pas sa clé, il faut construire une requête (query). Comme je vous le disais, c'est à partir de là que les choses se corsent...

En effet, la création d'une requête à bas niveau dans le Datastore est particulièrement complexe. Je vais vous montrer quelques exemples simples pour que vous ayez une idée de la façon dont ça fonctionne, mais je ne vais pas essayer d'être aussi exhaustif que la documentation de Google sur les requêtes. En fait, je préfère qu'on passe plus de temps ensemble à voir comment construire des requêtes avec la bibliothèque Objectify dans un prochain chapitre, car celle-ci nous simplifie pas mal la vie. En attendant, pour notre culture générale, voyons comment faire une requête bas niveau dans l'API. :)

Pour faire une requête dans la base du Datastore, on crée un objet de type Query. Une requête est constituée :

  • D'un type d'entité

  • De filtres (optionnel)

  • De demandes d'ordonnancement (optionnel)

Le type d'entité

Dans sa forme la plus simple, la requête demande toutes les entités d'un même type :

Query q = new Query("Personnage");
List<Entity> results = datastore.prepare(q).asList(FetchOptions.Builder.withDefaults());

Dans la première ligne, je construis la requête. Ici, je demande tout ce que le Datastore possède comme entités de type Personnage.
Dans la seconde ligne, je prépare la requête et demande son exécution au Datastore. Je lui demande ici de me retourner une liste d'entités.

Je peux ensuite parcourir la liste qui m'a été retournée et effectuer des actions :

for (Entity result : results) {
    // Effectuer des actions sur l'entité result
}
Les filtres

Le Datastore nous permet de filtrer les entités en fonction de leurs propriétés. On peut ainsi demander : "Donne-moi toutes les entités (de type Personnage) dont le niveau de vie est à 100.".

Query q = new Query("Personnage").setFilter(new Query.FilterPredicate("vie", Query.FilterOperator.EQUAL, 100));

Ici, on a créé une requête sur les entités de type Personnage avec un filtre qui indique qu'on souhaite uniquement les entités dont la propriété vie vaut 100. On peut aussi utiliser d'autres opérateurs comme "supérieur ou égal", "inférieur à", "différent de", etc. On peut aussi combiner plusieurs filtres avec des opérateurs logiques comme "OU" ou "ET". Vous trouverez plus d'informations sur les filtres dans la doc.

Enfin, il faut savoir qu'on peut filtrer en fonction des ancêtres d'une entité. Je peux demander toutes les armes d'un ancêtre précis en fonction de sa clé. Par exemple, si je veux toutes les armes dans le même groupe d'entités que mon personnage "groknan" (c'est-à-dire toutes les armes qui appartiennent à groknan), j'écrirai :

Query q = new Query("Arme").setAncestor(KeyFactory.createKey("Personnage", "groknan"));
Les ordonnancements

Pour récupérer les résultats dans un ordre particulier en fonction de leurs propriétés, on fera appel à la méthode addSort() :

Query q = new Query("Personnage").addSort("vie", SortDirection.ASCENDING);

On peut combiner et chaîner les appels à addSort() si on veut faire plusieurs tris d'affilée.

Query q = new Query("Personnage").addSort("vie", SortDirection.ASCENDING).addSort("niveau", SortDirection.DESCENDING);
Limiter le nombre de résultats

Il est possible (et même recommandé) de limiter le nombre de résultats pour ne pas récupérer un trop grand nombre d'entités. Cela se fait au moment de la demande d'exécution de la requête comme ceci :

List<Entity> results = datastore.prepare(q).asList(FetchOptions.Builder.withLimit(5));
Aller plus loin

Je ne vous ai fait qu'une très brève introduction au système de requêtes bas niveau de l'API du Datastore. Il y a beaucoup d'autres options et d'autres choses à savoir mais, comme je vous l'ai dit, je ne souhaite pas rentrer trop dans le détail ici. Si vous voulez en savoir plus, consultez la doc sur les requêtes.

Manipuler la bibliothèque bas niveau est, comme vous le voyez, assez complexe. Il faut appeler les bonnes méthodes, passer les bons objets... Il n'y a pas de "langage de requête" comme c'est le cas en SQL.
Heureusement, la plupart des développeurs App Engine ne sont pas fous et utilisent une bibliothèque comme Objectify qui est plébiscitée car elle nous simplifie grandement le travail. Je vous la présenterai dans un prochain chapitre. :)

Exemple : le Datastore dans une application

Création d'un livre d'or utilisant le Datastore

Je vous propose d'adapter le petit livre d'or que nous avions fait pour expérimenter Cloud SQL dans le chapitre précédent. Créez une nouvelle application "GuestbookDatastore" avec un peu de code de base.

On y reprend le même fichier web.xml de configuration :

<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
    <servlet>
        <servlet-name>Guestbook</servlet-name>
        <servlet-class>guestbook.GuestbookServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Guestbook</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>guestbook.jsp</welcome-file>
    </welcome-file-list>
</web-app>

L'application fonctionne sur une seule URL, la racine "/". Avec la méthode HTTP GET, on affiche le formulaire et les derniers messages. Avec la méthode HTTP POST, on enregistre le message et on redirige vers la même page en GET pour lister les résultats.

Voici à quoi ressemble notre servlet :

package guestbook;

import java.io.IOException;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.*;
import com.google.appengine.api.datastore.*;
import com.google.appengine.api.datastore.Query.SortDirection;

@SuppressWarnings("serial")
public class GuestbookServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse resp) {
        try {
            DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

            // Demande tous les 5 derniers messages triés par date décroissante
            Query q = new Query("Message").addSort("date", SortDirection.DESCENDING);
            List<Entity> results = datastore.prepare(q).asList(FetchOptions.Builder.withLimit(5));

            req.setAttribute("messages", results);
            this.getServletContext().getRequestDispatcher("/WEB-INF/guestbook.jsp").forward(req, resp);
        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void doPost(HttpServletRequest req, HttpServletResponse resp) {
        try {
            DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

            // Stocke le message posté
            Entity message = new Entity("Message");

            message.setProperty("name", req.getParameter("name"));
            message.setProperty("message", req.getParameter("message"));
            message.setProperty("date", new Date());

            datastore.put(message);

            resp.sendRedirect("/");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Il n'y a absolument rien de compliqué dans ce code : on crée un seul type d'entité ("Message") et on le stocke avec 3 propriétés. A l'affichage, la requête récupère les derniers messages et les transmet à la JSP. Celle-ci n'a ensuite plus qu'à itérer sur cette liste d'entités :

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="com.google.appengine.api.datastore.*" %>
<%@ page import="java.util.List" %>

<!DOCTYPE html>

<html>
    <head>
        <title>Livre d'or</title>
        <meta charset="utf-8" />
    </head>

    <body>
        <h1>Vous avez aimé mon site ? Dites-le !</h1>
        <form action="/post" method="post">
            <p>
                <label>Votre nom : <input type="text" name="name" /></label>
            </p>
            <p>
                <label>Votre message :

                <textarea name="message" style="width: 200px; height: 100px;"></textarea></label>
            </p>
            <p>
                <input type="submit" />
            </p>
        </form>

        <h1>Ils ont aimé :</h1>
        <p><em>(et c'est stocké dans le Datastore !)</em></p>
        <%
            List<Entity> messages = (List<Entity>) request.getAttribute("messages");
            for (Entity message : messages) {
        %>
        <p>
            <strong><%= message.getProperty("name") %></strong> a écrit :

            <%= message.getProperty("message") %>
        </p>
        <%
            }
        %>
    </body>
</html>

Et voilà notre livre d'or utilisant le Datastore ! :)

Le livre d'or utilisant le Datastore
Le livre d'or utilisant le Datastore

Des requêtes qui retournent des résultats à jour

Euh, je viens de tester mais ça n'a pas l'air de marcher très bien. Mes nouveaux messages ne s'affichent pas tout de suite après avoir été postés. :euh:

Fichtre ! Le Datastore serait-il lent ?!

En fait, le Datastore est asynchrone. Lorsque vous demandez à enregistrer une entité, il rend la main à votre application en lui disant "C'est noté, je vais stocker ça."... mais contrairement à ce qu'on a l'habitude avec SQL, les données ne sont pas forcément stockées tout de suite.

On peut régler le problème en changeant un peu notre requête. Il faut savoir qu'on distingue 2 types de requêtes dans le Datastore :

  • Celles qui recherchent des objets sans parent : elles sont eventually consistent. Il est possible que vous n'obteniez pas des données complètement à jour. Ce type de requête est le plus rapide.

  • Celles qui recherchent des objets qui ont un parent commun : elles sont strongly consistent. Vous êtes sûr d'obtenir les données les plus à jour. En revanche, ce type de requête est plus long.

Comme vous l'avez vu, nous avons fait des requêtes sans parent, ce qui explique pourquoi elles retournent parfois des résultats qui ne sont pas encore à jour.

Nos entités Message n'ont pas d'ancêtre : il y a un risque que nous récupérions des données pas encore à jour
Nos entités Message n'ont pas d'ancêtre : il y a un risque que nous récupérions des données pas encore à jour

Si on veut avoir des résultats à jour, il faut indiquer un parent commun. Contrairement à ce que vous pourriez penser, on n'est pas obligé de créer une entité parente. Il suffit d'indiquer une clé parente commune pour chacun des messages, même si cette clé ne correspond à aucune entité réelle.

Nos entités Message ont un ancêtre : les données récupérées seront forcément à jour
Nos entités Message ont un ancêtre : les données récupérées seront forcément à jour

En clair, il nous suffit de définir une clé correspond à un ancêtre (même s'il est fictif) quand on crée les messages :

Entity message = new Entity("Message", KeyFactory.createKey("LivreOr", "livre"));

... et de demander les messages dépendant de cet ancêtre pour être sûr d'avoir des données toujours à jour :

Query q = new Query("Message").setAncestor(KeyFactory.createKey("LivreOr", "livre")).addSort("date", SortDirection.DESCENDING);

Et voilà ! Testez le code, vous verrez que cette fois les données récupérées seront toujours à jour !

Comme toutes les bonnes choses, il ne faut pas en abuser. Les données dépendant d'un ancêtre commun sont forcément stockées sur le même serveur chez Google comme je vous l'avais expliqué. C'est pratique mais ça a ses limites.
Si on manipule mal trop de données dépendant d'un ancêtre commun, on risque de congestionner son application et celle-ci risque de ralentir. Ce serait un peu dommage alors que la promesse du Datastore est quand même de nous permettre de passer à l'échelle !

Tester l'application

Si vous voulez tester l'application, je l'ai uploadée sur les serveurs d'App Engine à l'adresse suivante : http://sdz-guestbook-datastore.appspot.com/

Voilà, nous nous sommes suffisamment amusés avec l'API bas niveau du Datastore comme ça, il est temps de découvrir l'incontournable bibliothèque Objectify !


Google WEEB

Manipuler le DataStore avec Objectify

On vient de le voir : le Datastore est un système puissant mais son API bas niveau est assez délicate à utiliser, notamment son système de requêtes. De l'avis de plusieurs développeurs que j'ai rencontrés (y compris des gens de chez Google !), il est recommandé d'utiliser la bibliothèque Objectify pour travailler avec le Datastore aujourd'hui.

Contrairement au Datastore lui-même, la lib Objectify n'est pas maintenue par Google lui-même mais par un développeur externe. Objectify est particulièrement suivi et maintenu, c'est donc un excellent choix pour développer avec le Datastore.

Objectify se veut être une API "ni trop bas niveau, ni trop haut niveau". Elle est (heureusement) plus haut niveau que l'API de base que nous venons de découvrir, mais elle ne nous empêche pas d'effectuer des actions basiques si nécessaire.

Objectify est un peu comme un ORM pour le Datastore : son rôle est de persister (stocker) vos objets dans le Datastore.

Objectify permet de stocker des objets dans le Datastore et de les ressortir
Objectify permet de stocker des objets dans le Datastore et de les ressortir

Objectify s'occupe de la création d'entités et de clés et de la relation entre ces éléments. Mieux : il utilise automatiquement le service Memcache de Google qui permet de mettre en cache des données pour aller encore plus vite et vous éviter d'appeler systématiquement le Datastore.

Objectify est suffisamment simple à comprendre et pourtant très puissant. La plupart des vraies applications sur App Engine l'utilisent aujourd'hui. Bref, c'est à se demander ce qu'on attend pour commencer ! :D

Configurer Objectify

Objectify est une bibliothèque créée par un développeur tiers. Elle n'est pas installée automatiquement avec le plugin App Engine pour Eclipse. Heureusement, son installation et sa configuration sont simples. :)

Le projet Objectify est hébergé sur Google Code à l'adresse suivante : https://code.google.com/p/objectify-appengine/

Le site d'Objectify possède un excellent wiki qui documente le projet, que je vous recommanderai de lire en complément de ce tutoriel. Le wiki décrit par ailleurs très bien le fonctionnement du Datastore lui-même.

Pour utiliser Objectify, il faut télécharger 2 bibliothèques sous la forme de fichiers .jar :

  • Objectify : on peut télécharger Objectify sur Maven Central. Si vous voulez le télécharger manuellement, vous le trouverez dans ce répertoire. Prenez le fichier .jar correspondant à la dernière version (par exemple 4.0b3/objectify-4.0b3.jar)

  • Guava : c'est une bibliothèque offrant des fonctionnalités de base de Java, créée par Google et utilisée notamment par Objectify. Vous en aurez besoin pour faire fonctionner Objectify. Vous pouvez télécharger le .jar sur le site de Guava.

Placez ces fichiers dans le dossier WEB-INF/lib de votre projet.

Objectify et Guava sont installés dans le dossier WEB-INF/lib
Objectify et Guava sont installés dans le dossier WEB-INF/lib

Ajoutez-les ensuite au build path : clic droit sur le projet / Properties / Java Build Path / Onglet "Libraries" puis cliquez sur "Add JARs" et sélectionnez les .jar que vous venez d'ajouter à votre projet.

Ensuite, vous devez modifier le fichier web.xml et y ajouter les lignes suivantes qui permettront à Objectify de fonctionner correctement :

<filter>
        <filter-name>ObjectifyFilter</filter-name>
        <filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
        <filter-name>ObjectifyFilter</filter-name>
        <url-pattern>/*</url-pattern>
</filter-mapping>

Objectify est maintenant prêt à être utilisé dans votre projet !

Créer des objets persistables

Objectify se charge de stocker vos objets Java dans le Datastore et, inversement, d'extraire du Datastore des données pour reformer des objets Java. On dit qu'Objectify travaille sur des POJO (Plain Old Java Object, ou "Bons vieux objets Java"), ce qui signifie qu'on travaille sur des objets Java de base (par opposition à des objets plus complexes comme les Enterprise Java Beans).

Pour travailler avec Objectify, il va falloir créer des objets et leur ajouter des annotations spécifiques. Je vous propose encore une fois de reprendre mon super exemple du Personnage et de son Arme (décidément je l'aime bien ce Groknan le Barbare) :

Les entités que nous allons créer
Les entités que nous allons créer

Allez, on se motive et on crée notre objet Personnage pour commencer !

public class Personnage {
    String nom;
    int niveau;
    int vie;

    public Personnage (String nom, int niveau) {
        this.nom = nom;
        this.niveau = niveau;
        this.vie = 100;
    }
}

Ahhh, créer à nouveau des bons vieux objets Java à la main, y'a pas à dire ça dérouille. :D

Bon pour le moment notre objet est tout ce qu'il y a de plus classique. Des attributs, un constructeur... On pourrait y ajouter des getters et setters aussi mais je ne le fais pas là pour garder un code court et lisible.

Alors, comment faire pour expliquer à Objectify comment cet objet fonctionne ? On va lui ajouter des annotations ! Pour commencer on doit importer les annotations d'Objectify :

import com.googlecode.objectify.annotation.*;

Les principales annotations

@Entity : l'entité

On va rajouter une annotation @Entity devant la définition de la classe pour qu'Objectify sache qu'il s'agit d'une classe qu'il peut persister.

@Entity
public class Personnage {
    // ...
}

Ensuite, nous devons annoter les attributs de la classe (Objectify ne s'intéresse pas aux méthodes). Il faut dire à Objectify quel est l'attribut qui tient lieu d'ID, quels attributs doivent être ignorés pour ne pas être persistés, quels attributs doivent être indexés, quelles sont les relations avec d'autres classes...

@Id : l'ID

Si on crée un attribut ID annoté @Id de type Long, Google génèrera un numéro automatiquement :

@Id Long id; // Google génèrera un ID automatiquement (car type Long)

Si on crée un attribut ID annoté @Id de type String, ce sera à nous de définir une chaîne de caractères unique :

@Id String id; // Ce sera à nous de générer des ID uniques (car type String)

Toute classe-entité doit avoir un attribut annoté @Id. C'est la seule annotation réellement obligatoire.

@Ignore : les attributs ignorés

Par défaut, Objectify va persister tous les attributs dans le Datastore. Si certains n'ont pas besoin d'être enregistrés (parce qu'ils ne servent que temporairement par exemple), on peut leur rajouter l'annotation @Ignore : Objectify ne les enregistrera pas.

@Ignore boolean tempInfo; // Ne sera pas stocké dans le Datastore
@Index : les index

Par défaut, les attributs ne seront pas indexés dans le Datastore. Objectify préfère ne pas les indexer à moins que vous ne le demandiez car ils consomment des ressources et "coûtent" dans votre quota d'usage du Datastore.
Pourtant, les index sont obligatoires si vous voulez faire des requêtes sur ces attributs par la suite. Si vous savez que vous ferez une recherche sur un champ, ajoutez-lui l'annotation @Index :

@Index int niveau; // Cet attribut sera indexé

A l'inverse, si vous voulez indexer tous les attributs par défaut sur une classe, vous pouvez ajouter l'annotation @Index avant la définition de la classe et utiliser @Unindex si vous ne voulez pas indexer certains attributs :

@Entity
@Index // Active l'indexation par défaut
public class Personnage {
    @Id String id; // Sera indexé (les ID sont toujours indexés)
    @Unindex String nom; // Ne sera pas indexé
    int niveau; // Sera indexé
    int vie; // Sera indexé
}

Le Datastore permet aussi de créer des index sur plusieurs champs à la fois. Par exemple, vous pouvez créer un index sur le niveau ET la vie du personnage à la fois. C'est utile si vos requêtes font des recherches sur ces deux informations à la fois.
Le plugin Eclipse génère un fichier WEB-INF/appengine-generated/datastore-indexes-auto.xml en fonction des index multiples dont il voit que vous avez besoin. Copiez ces index dans le fichier datastore-indexes.xml si vous voulez que le Datastore gère ces index multiples.
Attention à ne pas trop créer d'index non plus : leur gestion a un coût pour le Datastore ! En résumé : bien utiliser les index va accélérer les performances de votre application, mais mal les utiliser risque au contraire de diminuer les performances !

@parent : l'entité parente

Vous pouvez définir l'entité parente avec l'annotation @Parent. Pour faire référence à l'entité parente, Objectify nous fournit la classe Key<?> (mais vous pouvez aussi utiliser la simple classe Key fournie par l'API bas niveau). Exemple :

@Parent Key<AutreClasse> parent;

L'entité fera alors partie du même groupe d'entités que le parent. Cela nous serait utile par exemple pour définir qui est le parent de l'Arme dans nos exemples.

Le parent fait partie de l'identifiant (souvenez-vous : identifiant = type + ID + parent). Or, vous ne pouvez pas changer l'identifiant d'une entité dans le Datastore.
Par conséquent, si vous modifiez l'attribut parent, le Datastore considèrera qu'il s'agit d'une nouvelle entité et la stockera en plus de l'ancienne.

D'autres annotations

Objectify fournit plusieurs autres annotations qui peuvent vous êtres utiles dans des cas plus précis. Je ne vous les présente pas toutes ici mais je vous invite :

  • A lire la doc sur les entités, très complète (heureusement, car c'est la doc officielle :D )

  • A lire la référence sur les annotations qui résume toutes les annotations disponibles

Définition d'un constructeur sans paramètres

Pour qu'Objectify puisse fonctionner, vous devez obligatoirement définir un constructeur sans paramètres (même s'il ne fait rien) dans une classe-entité :

@Entity
public class Personnage {
    // Attributs

    private Personnage() {} // Obligatoire pour Objectify

    public Personnage (String nom, int niveau) {
        // ...
    }
}

Enregistrement des entités auprès d'Objectify

En plus des annotations, vous devez indiquer à Objectify quelles sont vos classes-entités au chargement de l'application. Pour cela, le mieux est d'effectuer une définition static dans votre servlet comme ceci :

import com.googlecode.objectify.ObjectifyService;

@SuppressWarnings("serial")
public class ObjectifyTestsServlet extends HttpServlet {
    static {
        ObjectifyService.register(Personnage.class); // Fait connaître votre classe-entité à Objectify
    }

    public void doGet(HttpServletRequest req, HttpServletResponse resp) {
        // ...
    }
}

Exemple complet avec le Personnage et l'Arme

Pour résumer, voici le code que je vous propose d'utiliser pour nos classes Personnage et Arme :

import com.googlecode.objectify.annotation.*;

@Entity
@Index
public class Personnage {
    @Id String id;
    @Unindex String nom;
    int niveau;
    int vie;

    private Personnage() {}

    public Personnage (String nom, int niveau) {
        this.id = nom;
        this.nom = nom;
        this.niveau = niveau;
        this.vie = 100;
    }
}

import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.*;

@Entity
public class Arme {
    @Id Long id;
    @Parent Key<Personnage> parent;
    String nom;
    int degats;

    private Arme() {}
    public Arme(String nom, int degats, Key<Personnage> parent) {
        this.nom = nom;
        this.degats = degats;
        this.parent = parent;
    }
}

Dans notre servlet, il ne faut pas oublier d'enregistrer les classes auprès d'Objectify au chargement de l'application via une définition static :

import com.googlecode.objectify.ObjectifyService;

@SuppressWarnings("serial")
public class ObjectifyTestsServlet extends HttpServlet {
    static {
        ObjectifyService.register(Personnage.class);
        ObjectifyService.register(Arme.class);
    }

    public void doGet(HttpServletRequest req, HttpServletResponse resp) {
        // ...
    }
}

Voilà à quoi pourrait ressembler la définition de nos objets POJO pour Objectify. Voyons voir maintenant combien il est simple de les manipuler. :)

Opérations sur les clés

Comme l'API bas niveau du Datastore, Objectify nous permet d'effectuer des opérations basiques sur les entités via leurs clés :

  • Ecrire une entité

  • Récupérer une entité grâce à sa clé

  • Supprimer une entité grâce à sa clé

Nous nous intéressons ici à ces opérations simples. Nous verrons juste après comment effectuer des requêtes, ce qui est un poil plus complexe mais quand même bien plus lisible que l'API bas niveau. ;)

Charger l'instance Objectify

Pour travailler avec Objectify, on doit d'abord récupérer son instance. Cela se fait comme ceci :

ObjectifyService.ofy()

Le principe d'Objectify est que vous pouvez enchaîner plusieurs appels sur cette instance. Par exemple, pour charger un objet en fonction de sa clé on ferait :

Objet monObjet = ObjectifyService.ofy().load().key(cle).now();

Comme vous allez devoir écrire ObjectifyService.ofy() de nombreuses fois, il est recommandé d'effectuer une définition statique au début du fichier :

import static com.googlecode.objectify.ObjectifyService.ofy;

Vous pouvez alors écrire simplement ofy() au lieu de ObjectifyService.ofy() :

Objet monObjet = ofy().load().key(cle).now();

Ecrire une entité

Objectify travaille sur des objets. La première chose à faire est donc, dans votre servlet, de créer des objets comme vous avez l'habitude de le faire en Java :

Personnage p = new Personnage("groknan", 25);

Notre Personnage p peut ensuite être persisté dans le Datastore avec cette simple commande :

ofy().save().entity(p); // Asynchrone (pas enregistré immédiatement)

Par défaut, les sauvegardes sont asynchrones. Cela signifie que le Datastore rend la main à votre programme avant d'avoir enregistré les données. C'est la méthode la plus rapide mais, si vous avez besoin des données que vous venez d'enregistrer immédiatement après, vous voudrez peut-être forcer l'enregistrement de façon synchrone comme c'est le cas en SQL. Pour ça, rajoutez juste un appel à now() à la chaîne :

ofy().save().entity(p).now(); // Synchrone (enregistré immédiatement)

Il n'y a rien de plus compliqué que ça : vous savez sauvegarder des objets dans le Datastore avec Objectify ! Magique non ? :D

Récupérer une entité

Pour récupérer une entité, vous devez connaître sa clé. Je vous rappelle qu'une clé est simplement un identifiant constitué du type + de l'ID + du parent.

Les clés avec Objectify

Le Datastore nous fournissait déjà la classe Key qui représente une clé. Cette classe s'utilise comme ceci pour rappel :

Key clePersonnage = KeyFactory.createKey("Personnage", "groknan"); // API bas niveau

Mais Objectify fournit une légère variante : la classe Key<?> (qui indique en plus le type d'objet stocké). On peut l'utiliser comme ceci :

Key<Personnage> clePersonnage = Key.create(Personnage.class, "groknan");

Les deux types de clés sont utilisables dans Objectify. A noter qu'il existe aussi le type Ref<?> qui fonctionne comme Key<?> mais qui permet de manipuler les sous-objets plus facilement.

Charger un objet grâce à sa clé

Pour charger un objet, je crée d'abord sa clé (soit avec la classe Key bas niveau du Datastore, soit avec la classe Key<?> d'Objectify) puis je demande son chargement :

Key<Personnage> cleGroknan = Key.create(Personnage.class, "groknan");
Personnage r = ofy().load().key(cleGroknan).now();
Charger un objet sans créer de clé

Plus fort que le Roquefort, Objectify nous permet de charger un objet sans passer par l'étape préalable de création d'une clé :

Personnage r = ofy().load().type(Personnage.class).id("groknan").now();

Il s'agit juste d'une syntaxe plus pratique créée par Objectify, elle a le même effet que si vous étiez passés par la création d'une clé.

Si on veut récupérer une entité qui a un parent, il faudra ajouter un appel à parent() dans la chaîne comme ceci :

Arme a = ofy().load().type(Arme.class).parent(personnage).id("pourfendeur").now();

Supprimer une entité

En tant que roi du Datastore, vous avez droit de vie et de mort sur vos entités. Il n'y a rien de plus simple : indiquez en paramètre l'objet que vous voulez supprimer du Datastore.

ofy().delete().entity(objetASupprimer).now();

Si vous voulez varier les plaisirs, vous pouvez aussi supprimer l'entité via sa clé :

ofy().delete().key(cleObjetASupprimer).now();

Ou utiliser la syntaxe offerte par Objectify qui vous évite d'avoir à créer une clé :

ofy().delete().type(Personnage.class).id("groknan").now();

Les requêtes

Filtrer et récupérer une liste d'entités

Exécuter des requêtes avec Objectify est beaucoup beaucoup beaucoup (beaucoup) plus pratique que l'API bas niveau du Datastore. En fait, la syntaxe de base est la même que le chargement via une clé. Il vous suffit de rajouter des filtres via filter() et d'indiquer que vous voulez qu'on vous retourne une liste avec list() :

// Retourne tous les personnages dont la vie est supérieure à 50
List<Personnage> personnages = ofy().load().type(Personnage.class).filter("vie >", 50).list();

Comme vous le voyez, l'opérateur est indiqué dans le filtre avec un symbole. Les opérateurs supportés sont : >, >=, <, <=, in, !=, <>, =, ==. Il y a de quoi faire. :)

Notez que si vous ne mettez pas d'opérateur, cela correspond à une égalité :

// Pas d'opérateur : retourne tous les personnages dont la vie est égale à 50
List<Personnage> personnages = ofy().load().type(Personnage.class).filter("vie", 50).list();

Vous ne pouvez effectuer des requêtes que sur des propriétés indexées par le Datastore. Je vous rappelle que par défaut Objectify n'indexe pas les attributs des classes, sauf si vous utilisez l'annotation @Index. Vérifiez donc que vous avez correctement défini vos index avant d'effectuer des requêtes !

Filtrer par ancêtre

Si les entités sur lesquelles vous effectuez une requête ont un parent (aussi appelé "ancêtre"), vous devez rajouter .ancestor() à votre requête :

// Récupère toutes les armes qui ont pour ancêtre mon objet personnage
List<Arme> armes = ofy().load().type(Arme.class).ancestor(personnage).list();

Vous pouvez aussi rechercher parmi les ancêtres via leur clé avec la même méthode :

List<Arme> armes = ofy().load().type(Arme.class).ancestor(KeyFactory.createKey("Personnage", "groknan")).list();

Ordonner les résultats

Pour ordonner les résultats, rajoutez des appels à order() dans votre chaîne d'appels :

// Triera les personnages par niveau de vie croissant
List<Personnage> personnages = ofy().load().type(Personnage.class).filter("niveau >", 30).order("vie").list();

Vous pouvez aussi trier par niveau de vie décroissant avec un symbole moins : .order("-vie") // Décroissant
Et bien entendu vous pouvez effectuer plusieurs tris d'affilée si nécessaire !

Limiter le nombre de résultats

Il est toujours conseillé de limiter le nombre de résultats, surtout quand vous risquez d'en récupérer un très grand nombre. Pour cela, faites un appel à limit() à la fin de votre chaîne, juste avant de demander la list() :

// Récupère maximum 10 personnages
List<Personnage> personnages = ofy().load().type(Personnage.class).filter("niveau >", 30).limit(10).list();

Récupérer le premier résultat

Si vous savez que la requête ne va vous retourner qu'un seul résultat, vous pouvez demander le premier résultat de la liste avec first() à la place de list() :

// Retourne le premier personnage dont la vie est supérieure à 50
Personnage personnages = ofy().load().type(Personnage.class).filter("vie >", 50).first().now();

Récupérer les clés

Objectify peut aussi vous retourner uniquement les clés des entités plutôt que les entités elles-mêmes. C'est plus rapide à charger et cela vous permet d'effectuer une suppression de masse. Que diriez-vous de supprimer tous les personnages trop faibles de la surface de votre application ? :D

Iterable<Key<Personnage>> clesPersonnagesFaibles = ofy().load().type(Personnage.class).filter("vie <", 30).keys();

// Supprime tous les personnages faibles
ofy().delete().keys(clesPersonnagesFaibles);

Bref, l'exécution de requêtes dans le Datastore avec Objectify est un vrai plaisir. :)

Mise en cache avec Memcache

App Engine offre un service de Memcache. Pour ceux qui ne connaissent pas Memcache, il s'agit d'un logiciel qui tourne uniquement en mémoire vive (RAM) sur des serveurs et qui stocke des paires clé-valeur.

Euh... c'est ce que fait le Datastore ça non ?

Non, pour le coup ça c'est vraiment très basique. Il n'y a pas de notion d'entités : juste des clés et des valeurs. Par ailleurs, les données sont stockées en RAM et peuvent disparaître à tout moment. Il n'y a pas de garantie que les données seront toujours disponibles.

Memcache se révèle en fait un excellent complément au Datastore. Puisqu'il ne nécessite pas d'accéder à des disques, il est beaucoup plus performant que le Datastore (en gros, une requête Memcache va 10 fois plus vite qu'une requête dans le Datastore). On serait tenté de tout mettre dans Memcache mais il ne faut pas oublier que les données peuvent vraiment être perdues à tout moment : si le serveur redémarre tout est perdu et s'il n'y a plus de place en mémoire Memcache supprime arbitrairement de vieilles données en cache.

Il faut savoir que le service Memcache chez Google est gratuit. Google veut nous encourager à utiliser intensivement Memcache pour alléger la charge des serveurs du Datastore. Nous n'allons donc pas nous en priver. :D

En pratique, l'utilisation combinée de Memcache et du Datastore se fait comme ceci :

  1. On s'apprête à faire une requête dans le Datastore pour récupérer des données

  2. On demande d'abord à Memcache s'il possède déjà ces données

  3. Si Memcache les possède, on aura récupéré les données 10x plus rapidement et sans passer par le Datastore

  4. Si Memcache ne les possède pas, on fait une requête classique au Datastore et on stocke le résultat dans Memcache pour que la prochaine requête aille plus vite.

La mise en cache avec Memcache
La mise en cache avec Memcache

Google propose des APIs bas niveau pour accéder à Memcache. Vous pouvez vraiment y stocker tout ce que vous voulez (vous n'êtes pas obligés de l'utiliser en conjonction avec le Datastore), le tout est de retenir que la donnée peut disparaître à tout moment et qu'il faut que vous soyez capables de la récupérer ailleurs pour la remettre dans Memcache si nécessaire.

Objectify est capable de faire une utilisation intelligente de Memcache. Pour activer le système de cache, il suffit de rajouter l'annotation @Cache devant vos classes persistables :

@Entity
@Cache
public class Message {

}

Et... c'est tout ! :D
Objectify se charge de tout le travail : lorsque vous faites une requête, il ira vérifier si la donnée est déjà en cache. Il ira la mettre en cache si elle ne l'est pas pour être capable de récupérer les données beaucoup plus rapidement la seconde fois.

Il n'y a que des avantages à cette méthode :

  • Les appels au Datastore pour la même requête sont de l'ordre de 10x plus rapides à partir de la seconde requête

  • Vous n'appelez plus le Datastore et donc vous utilisez moins de quota de lecture/écriture (donc vous payez moins au final)

  • Tout l'usage de Memcache étant gratuit, vous ne payez rien de plus !

Dans de rares cas néanmoins, vous ne voudrez probablement pas mettre les données en cache. Mais à mon sens cela concerne vraiment une minorité de cas. Je vous recommande vivement d'activer le cache autant que possible.

Par défaut, il faut savoir que les données restent en cache aussi longtemps que possible (jusqu'à ce que Memcache décide qu'il veut supprimer vos données). Vous pouvez demander à ce que les données soient supprimées au bout d'un certain temps pour forcer le rafraîchissement du cache :

@Entity
@Cache(expirationSeconds=600) // Le cache expirera au bout de 10 minutes
public class Message {

}

Les transactions

Les transactions sont indispensables dans un grand nombre d'applications. Elles vous permettent d'exécuter plusieurs requêtes d'affilée et de vous assurer qu'elles ont bien fonctionné avant de réellement enregistrer les données.

Dans le Datastore, les transactions ne fonctionnent qu'au sein d'un même groupe d'entités. Si vos entités sont "séparées", vous ne pouvez pas effectuer de transaction dessus.

Pourquoi des transactions ?

Imaginez une application qui effectuerait les opérations suivantes :

  1. Lecture de données depuis le Datastore

  2. Calculs

  3. Ecriture de données

  4. Ecriture d'autres données

  5. Lecture d'autres données

  6. Ecriture d'autres données

Si une écriture échoue au milieu et que vous voudriez tout annuler (pour faire "comme si rien ne s'était passé"), il faut placer l'ensemble de ces instructions au sein d'une même transaction.
Si toutes les requêtes de la transaction réussissent, on dit qu'on commit la transaction. S'il y a un échec, on dit qu'on rollback (annule) la transaction.

J'aime bien illustrer les transactions avec le bon vieil exemple de la banque. Imaginez : vous êtes une banque. Vous gérez beaucoup de sous, d'accord, mais vous avez aussi la responsabilité de la gestion de cet argent. Si un client A fait un virement de 100€ vers le client B, vous devez faire 2 requêtes :

  1. Retirer 100€ du compte du client A

  2. Ajouter 100€ au compte du client B

C'est typiquement le cas où une transaction est indispensable. Imaginez que quelque chose échoue entre les deux (votre application est arrêtée par exemple). Sans transaction, le client A aura perdu de l'argent mais le client B ne l'aura pas récupéré !
(certes, on pourrait en profiter pour faire glisser discrètement l'argent dans un paradis fiscal mais ce n'est pas le sujet :-° )

Les transactions avec Objectify

Objectify fournit un système très pratique pour effectuer des transactions. On pourrait aussi le faire avec l'API bas niveau mais je préfère vous montrer directement la méthode Objectify.

Il y a 2 cas :

  • Soit votre transaction doit retourner des données (sous forme d'un objet)

  • Soit votre transaction ne doit pas retourner de données

Une transaction qui ne retourne pas de données

Si votre transaction ne doit pas retourner de données, voici comment on l'écrirait avec Objectify :

import com.googlecode.objectify.VoidWork;

ofy().transact(new VoidWork() {
    public void vrun() { // Tout ce qui est exécuté dans cette méthode appartient à la même transaction
        Objet objet = ofy().load().key(cle).now();
        /* Modification de l'objet... */
        ofy().save().entity(objet);
    }
}

On fait un appel à la méthode transact() dans laquelle on crée un objet de type VoidWork qui possède une méthode vrun(). Toute la transaction doit être codée dans la méthode vrun() : les lectures dans la base, les modifications, les calculs, les enregistrements...

S'il y a un échec, Objectify demandera l'annulation de tout ce qui a été fait au sein de la méthode.

Une transaction qui retourne des données

Voici un exemple de transaction qui retourne cette fois des données :

import com.googlecode.objectify.Work;

Objet monObjet = ofy().transact(new Work<Objet>() {
    public Objet run() {
        Objet objet = ofy().load().key(cle).now();
        /* Modification de l'objet... */
        ofy().save().entity(objet);
        return objet;
    }
});

La seule différence est qu'on fait ici appel à un objet de type Work qui possède une méthode run() retournant un objet.

Exemple : Objectify dans une application

Rien de tel pour s'assurer qu'on a bien compris que de reprendre notre bon vieil exemple du livre d'or et de l'adapter à Objectify !

Je rappelle à quoi ressemble le livre d'or (sur une seule page) que nous allons créer :

Le livre d'or que nous allons créer avec Objectify
Le livre d'or que nous allons créer avec Objectify

Commençons par définir la classe Message. Elle représentera les objets que nous allons persister dans le Datastore.
La classe doit définir la structure de nos objets persistables. On doit y écrire des annotations qui indiquent à Objectify où est l'ID, les champs qui doivent être indexés...

import java.util.Date;
import com.googlecode.objectify.annotation.*;

@Entity
@Cache
public class Message {
    @Id Long id; // Sera généré automatiquement
    @Index Date date;
    String name;
    String message;

    private Message() {}
    public Message(String name, String message) {
        this.name = name;
        this.message = message;
        this.date = new Date();
    }

    public Date getDate() {
        return date;
    }
    public void setDate(Date date) {
        this.date = date;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
}

Hormis les annotations, cette classe est vraiment très basique ! On y active le cache Memcache avec l'annotation @Cache pour réduire automatiquement la charge sur le Datastore.

Avec Objectify, le code de la servlet devient de son côté vraiment concis :

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.*;

import com.googlecode.objectify.ObjectifyService;
import static com.googlecode.objectify.ObjectifyService.ofy;

@SuppressWarnings("serial")
public class GuestbookServlet extends HttpServlet {
    // Enregistrement de la classe persistable auprès d'Objectify
    static {
        ObjectifyService.register(Message.class);
    }

    public void doGet(HttpServletRequest req, HttpServletResponse resp) {
        try {
            // Requête Objectify
            List<Message> messages = ofy().load().type(Message.class).order("-date").limit(5).list();

            req.setAttribute("messages", messages);
            this.getServletContext().getRequestDispatcher("/WEB-INF/guestbook.jsp").forward(req, resp);
        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void doPost(HttpServletRequest req, HttpServletResponse resp) {
        try {
            // Création de l'objet
            Message message = new Message(req.getParameter("name"), req.getParameter("message"));
            // Enregistrement de l'objet dans le Datastore avec Objectify
            ofy().save().entity(message).now();

            resp.sendRedirect("/");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

La requête trie par date, donc il faut un index sur la date pour que le Datastore puisse effectuer la requête. C'est pour cela que j'ai ajouté une annotation @Index devant l'attribut date de la classe Message.

La JSP récupère simplement une liste de messages et fait une boucle pour les afficher, rien de bien particulier :

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.List" %>
<%@ page import="guestbook.Message" %>

<!DOCTYPE html>

<html>
    <head>
        <title>Livre d'or</title>
        <meta charset="utf-8" />
    </head>

    <body>
        <h1>Vous avez aimé mon site ? Dites-le dans le Datastore !</h1>
        <form action="/post" method="post">
            <p>
                <label>Votre nom : <input type="text" name="name" /></label>
            </p>
            <p>
                <label>Votre message :<br />
                <textarea name="message" style="width: 200px; height: 100px;"></textarea></label>
            </p>
            <p>
                <input type="submit" />
            </p>
        </form>

        <h1>Ils ont aimé :</h1>
        <%
            List<Message> messages = (List<Message>) request.getAttribute("messages");
            for (Message message : messages) {
        %>
        <p>
            <strong><%= message.getName() %></strong> a écrit :<br />
            <%= message.getMessage() %>
        </p>
        <%
            }
        %>
    </body>
</html>

Enfin, n'oublions pas le fichier web.xml qui doit comporter les lignes spécifiques à Objectify pour que notre application puisse fonctionner correctement :

<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">
    <servlet>
        <servlet-name>Guestbook</servlet-name>
        <servlet-class>guestbook.GuestbookServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Guestbook</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>guestbook.jsp</welcome-file>
    </welcome-file-list>
    <filter>
        <filter-name>ObjectifyFilter</filter-name>
        <filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>ObjectifyFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

Euh... j'ai à nouveau parfois le problème : je poste un message et il ne s'affiche pas immédiatement après...

Oui, Objectify se base sur le Datastore et il y a un principe de base du Datastore qui dit : "les données que vous récupérez ne sont pas forcément immédiatement à jour, si vous voulez des données à jour regroupez-les au sein d'un même groupe d'entités".

Pour faire ça avec Objectify, il faut que je rajoute un attribut qui représente le parent dans la classe Message, avec l'annotation @Parent :

public class Message {
    // ...
    @Parent Key parent;

    private Message() {}
    public Message(String name, String message) {
        // ...
        this.parent = KeyFactory.createKey("LivreOr", "livreOr");
    }

Je ne crée pas d'entité parente mais ce n'est pas obligatoire comme je vous l'avais expliqué : il me suffit de donner un même ancêtre à tous les messages du livre d'or pour les regrouper dans un même groupe d'entités.

Ma requête Objectify dans la servlet doit maintenant indiquer qui est l'ancêtre :

List<Message> messages = ofy().load().type(Message.class).ancestor(KeyFactory.createKey("LivreOr", "livreOr")).order("-date").limit(5).list();

Voilà c'est tout, vous avez maintenant l'assurance d'avoir des données toujours à jour. :)

Encore une fois, je le répète car c'est important : n'abusez pas de cette technique. Si vous regroupez aveuglément toutes les entités de votre application au sein d'un même groupe, vous aurez rapidement des problèmes de performance, ce qui serait le comble !
Vos visiteurs n'ont pas forcément toujours besoin de voir des données à jour à la milliseconde près. Faites des regroupements uniquement lorsque c'est nécessaire.


Google WEEB

Stocker des fichiers sur Google Cloud Storage

Nous avons vu de long en large comment nous pouvions stocker des données sur Google App Engine : via Cloud SQL, dans le Datastore, dans le Datastore via Objectify... Mais nous ne savons toujours pas stocker des fichiers sur le Cloud de Google !

Je vous avais dit qu'App Engine nous interdisait de stocker les données sur leurs serveurs web pour une raison simple : ceux-ci ne communiquent pas entre eux et chaque serveur peut être arrêté à tout instant.

Les frontaux web de Google App Engine ne sont pas faits pour stocker les fichiers
Les frontaux web de Google App Engine ne sont pas faits pour stocker les fichiers

La solution passe par l'utilisation d'un service externe comme Google Cloud Storage qui est fait pour stocker ces fichiers :

Utiliser des serveurs spéciaux permet à tout le monde de retrouver les fichiers
Utiliser des serveurs spéciaux permet à tout le monde de retrouver les fichiers

Il faut savoir que Google propose 2 méthodes de stockage de fichiers :

  • Le Blobstore : c'est un système de stockage de fichiers intégré à App Engine. Pratique et stable, il est intégré à votre application et rapidement utilisable, tout comme le Datastore. Vous pouvez stocker des fichiers d'une taille de 2 Go chacun maximum. Vous disposez de 5 Go de stockage gratuit avec votre application App Engine.

  • Google Cloud Storage : c'est un autre système de stockage de fichiers qui utilise une autre architecture de serveurs. Il possède plus de barrières à l'entrée : il s'agit d'un autre service qu'il faut activer (via API Console), il ne propose pas de stockage gratuit et il est encore assez jeune. Malgré ces éléments qui peuvent être rebutants au début, il possède de nombreux avantages : vous pourrez uploader de très gros fichiers (jusqu'à plusieurs To), gérer plus finement les droits d'accès et vous disposerez d'une API REST complète pour l'utiliser depuis des applications externes.

Google Cloud Storage est clairement la solution la plus complète. Elle constitue le futur du stockage de fichiers pour les applications App Engine. Néanmoins, le Blobstore ne manque pas d'intérêt lui aussi, parce qu'on peut l'utiliser gratuitement (jusqu'à une certaine limite) et qu'il est plus simple à configurer au sein d'une application App Engine.

Je vous présenterai donc les deux solutions au sein de ce chapitre, en commençant par le Blobstore qui vous permettra de gérer vos premiers uploads rapidement. Si vous voulez aller plus loin, lisez les sections sur Cloud Storage mais préparez-vous à un peu plus de configuration avant de pouvoir l'utiliser.

Uploader sur le Blobstore

Le Blobstore est un système de stockage déjà intégré à votre application. De la même façon que le Datastore stocke des données, le Blobstore stocke des fichiers.

Principe du Blobstore

On utilise typiquement le Blobstore en combinaison avec des formulaires d'upload de fichiers. Dans ce cas, on crée un formulaire qu'on redirige vers une URL qui nous est fournie par le Blobstore :

<form action="<%= blobstoreService.createUploadUrl("/upload") %>" method="post" enctype="multipart/form-data">

</form>

C'est le Blobstore qui récupère le formulaire et non votre application directement. Le Blobstore se charge de stocker les fichiers soumis avec le formulaire.

Et si mon formulaire contient d'autres champs comme des champs texte, comment je récupère les données ?

C'est là que le Blobstore est malin. Une fois qu'il a fini de stocker les fichiers uploadés par le visiteur, il renvoie le reste du formulaire à votre application... sans les fichiers mais avec des informations sur l'emplacement où les fichiers ont été sauvegardés. Votre application peut ensuite effectuer le reste du traitement, comme sauvegarder les données du formulaire dans le Datastore.

Résumons :

Le Blobstore stocke les fichiers transmis et renvoie le formulaire à traiter à votre application
Le Blobstore stocke les fichiers transmis et renvoie le formulaire à traiter à votre application

Utilisation du Blobstore dans une application App Engine

Commençons pour cette fois par la JSP. Nous devons simplement récupérer le service du Blobstore dans la JSP et renvoyer le formulaire vers l'adresse fournie par le Blobstore :

<%@ page import="com.google.appengine.api.blobstore.*" %>

<%
    BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
%>

<!DOCTYPE html>

<html>
    <head>
        <title>Envoi de fichiers dans le Cloud</title>
        <meta charset="utf-8" />
    </head>

    <body>
        <h1>Envoyez un fichier dans le Cloud !</h1>
        <form action="<%= blobstoreService.createUploadUrl("/upload") %>" method="post" enctype="multipart/form-data">
            <p>
                <label>Fichier à envoyer : <input type="file" name="uploadedFile" /></label>
            </p>
            <p>
                <label>Description du fichier : <input type="text" name="description" /></label>
            </p>
            <p>
                <input type="submit" />
            </p>
        </form>
        </body>
</html>

L'appel à <%= blobstoreService.createUploadUrl("/upload") %> renvoie vers une URL générée par le Blobstore (typiquement une URL un peu longue comme /_ah/upload/aglub19hcHBfaWRyGwsScV8fQmxvYlVwbG9hZFNlc3Npb05fXxgWDA). En paramètre, nous indiquons à quelle adresse le Blobstore doit rediriger le reste du formulaire (ici "/upload").

Nous devons donc créer une Servlet qui répond à l'adresse /upload :

// Répond sur /upload

import com.google.appengine.api.blobstore.*;

@SuppressWarnings("serial")
public class UploadServlet extends HttpServlet {
    public void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {
            BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();

            // Récupère une Map de tous les champs d'upload de fichiers
            Map<String, List<BlobKey>> blobs = blobstoreService.getUploads(req);

            // Récupère la liste des fichiers uploadés dans le champ "uploadedFile"
            // (il peut y en avoir plusieurs si c'est un champ d'upload multiple, d'où la List)
            List<BlobKey> blobKeys = blobs.get("uploadedFile");

            // Récupère la clé identifiant du fichier uploadé dans le Blobstore (à sauvegarder)
            String cleFichierUploade = blobKeys.get(0).getKeyString();

            // On peut récupérer les autres champs du formulaire comme d'habitude
            String autreChamp = req.getParameter("description");
            // ...
    }
}

Cette servlet est appelée par le Blobstore après qu'il ait stocké les fichiers envoyés dans le formulaire.

La première étape, simple, consiste à récupérer le service du Blobstore. A partir de là, on obtient une Map associant les champs d'uploads du formulaire à une liste de fichiers uploadés. En général, un champ = un fichier mais il est possible aussi d'uploader plusieurs fichiers par champ avec l'attribut multiple de HTML5 (voilà pourquoi on manipule une Map contenant une List).

On peut obtenir à chaque fois une chaîne représentant le fichier dans le Blobstore, qu'on stockera en général dans le Datastore pour y accéder à nouveau par la suite. C'est une clé de type BlobKey.
On peut aussi récupérer le reste des champs du formulaire comme on le ferait d'habitude.

Et comment je fais ensuite pour afficher le fichier uploadé moi ?

Il vous faut la clé du fichier. Imaginez une autre servlet, qui répond par exemple sur l'adresse /image?blob-key=xxx. Dans la servlet, il vous suffit de récupérer cette clé et de faire appel à la méthode serve() pour que la servlet réponde par le fichier. Par exemple :

// Répond sur /image

import com.google.appengine.api.blobstore.*;

public class ImageServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws IOException, ServletException {
        BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();

        if (req.getParameter("blob-key") != null) {
            BlobKey blobKey = new BlobKey(req.getParameter("blob-key"));
            blobstoreService.serve(blobKey, resp);
        }
}

Donc on fait une servlet juste pour fournir un fichier ?

Oui. C'est pratique si on veut faire du traitement mais coûteux en ressources serveurs s'il s'agit juste de fournir un fichier statique comme une image (ce qui est souvent le cas). Dans ce cas, il y a une autre méthode qui consiste à récupérer l'URL du fichier directement. Il faut passer pour cela par un autre service de Google : ImageService.

On doit charger le service d'images :

import com.google.appengine.api.images.*;

public void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws IOException {
        BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
        ImagesService imagesService = ImagesServiceFactory.getImagesService(); // Récupération du service d'images

        Map<String, List<BlobKey>> blobs = blobstoreService.getUploads(req);
        List<BlobKey> blobKeys = blobs.get("uploadedFile");

        // Récupération de l'URL de l'image
        String urlImage = imagesService.getServingUrl(ServingUrlOptions.Builder.withBlobKey(blobKeys.get(0)));
}

Vous pouvez ensuite stocker l'url de l'image où vous le souhaitez pour l'inclure directement dans vos pages web. Attention cependant à ne pas perdre la BlobKey qui vous sera indispensable si vous voulez effectuer d'autres opérations (comme supprimer l'image par la suite).

Principes de Google Cloud Storage

Nous venons de voir comment utiliser le Blobstore, qui est un moyen pratique et rapide de stocker des fichiers avec App Engine. Je vous propose que l'on s'intéresse maintenant à un autre service de stockage, Google Cloud Storage, qui est plus récent et plus complet (mais aussi plus complexe à prendre en main).

Google Cloud Storage vous permet de stocker sur les serveurs de Google toutes sortes de fichiers d'une taille pouvant aller jusqu'à plusieurs Teraoctets. Les fichiers peuvent être stockés soit aux Etats-Unis soit en Europe, ce qui peut être pratique pour optimiser les temps d'accès et pour la confidentialité des données. Les fichiers sont eux-mêmes répartis sur plusieurs datacenters pour éviter les pertes accidentelles de données.
Cloud Storage est un peu l'équivalent du service Amazon S3 chez Google.

Il y a 3 types d'éléments sur Cloud Storage :

  • Les projets : vous pouvez gérer plusieurs projets Cloud Storage. En général, un projet correspond à un site web. On crée ces projets dans l'API Console de Google.

  • Les buckets : chaque projet peut gérer plusieurs buckets, qui sont des espaces de stockage différents. On peut les voir comme des dossiers mais les buckets ne peuvent pas être imbriqués contrairement aux dossiers. Chaque bucket définit des droits d'accès différents.

  • Les objets : ce sont les fichiers et dossiers que vous stockez. Les fichiers peuvent peser jusqu'à plusieurs Teraoctets. Un fichier se trouve dans un et un seul bucket à la fois.

Structure de Cloud Storage
Structure de Cloud Storage

Chaque objet possède un contenu (le contenu du fichier lui-même) et des métadonnées. Ces métadonnées sont des paires clé-valeur qui stockent des informations sur l'objet.

Pour manipuler Cloud Storage, Google vous propose plusieurs méthodes :

  • Une interface graphique web : accessible depuis l'API Console, elle vous donne une vue d'ensemble de ce qui est stocké sur Cloud Storage. Elle est accessible depuis un lien dans l'API Console ou directement à l'adresse https://storage.cloud.google.com/NOM_BUCKET (remplacez NOM_BUCKET par le nom de votre bucket lorsque vous en aurez créé un). On va voir dans un instant comment l'utiliser et comment y créer des buckets.

  • Un outil en ligne de commande : Google propose le programme Python gsutil utilisable en ligne de commande qui vous permet d'effectuer toutes les opérations que vous souhaitez sur Cloud Storage. Vous trouverez des instructions pour l'installer dans la doc.

  • Des APIs : Google propose des APIs XML et JSON que vous pouvez manipuler de façon externe en Java, Python, JavaScript... Vous pouvez aussi manipuler Cloud Storage directement depuis une application App Engine, et ça tombe bien car c'est justement ce que nous allons faire !

Activer Google Cloud Storage

Google Cloud Storage est un service qui peut être utilisé indépendamment d'App Engine. Le principe est le même que pour Google Cloud SQL : vous devez l'activer dans l'API Console. Rendez-vous donc sur :

https://code.google.com/apis/console

Là, dans la section "Services", repérez "Google Cloud Storage" et activez-le :

Activation de Google Cloud Storage
Activation de Google Cloud Storage

Vous devriez voir le service apparaître dans le menu :

Google Cloud Storage est activé et apparaît dans le menu
Google Cloud Storage est activé et apparaît dans le menu

Cloud Storage requiert que vous ayez entré les informations de paiement (billing) pour l'utiliser.

Le lien dans le menu ouvre une page vous donnant des informations sur les différentes possibilités d'utilisation de Cloud Storage. Un lien vous mène à une interface web qui vous permet de voir l'état de votre projet Cloud Storage :

L'interface web de Cloud Storage
L'interface web de Cloud Storage

La première étape est de créer un bucket. Cliquez sur le bouton correspondant dans l'interface et entrez un nom de bucket :

Un bucket a été créé
Un bucket a été créé

Le nom du bucket doit être unique parmi tous ceux déjà créés sur Cloud Storage. Vous ne pourrez donc pas l'appeler "test" par exemple car quelqu'un en a déjà créé un avec ce nom avant vous.

A l'intérieur d'un bucket, vous pouvez stocker tous les fichiers et dossiers que vous voulez. L'interface web vous fournit un bouton pour uploader et vous pouvez même faire un glisser-déposer :

Des fichiers et dossiers stockés dans un bucket
Des fichiers et dossiers stockés dans un bucket

Les fichiers que vous stockez sont disponibles à une adresse de la forme suivante :

https://storage.cloud.google.com/BUCKET/FICHIER

Par défaut, le contenu des buckets est protégé et n'est pas accessible de l'extérieur (seul vous qui êtes connecté pouvez le voir). Nous verrons plus loin comment changer les droits d'accès aux buckets.

Tout ça ressemble à un bête FTP en ligne ! Quel est l'intérêt ?

L'interface web est simple et ne propose rien d'extraordinaire. Tout l'intérêt de Cloud Storage est qu'on peut y accéder depuis des applications externes avec les APIs fournies par Google.

En ce qui nous concerne, nous allons nous concentrer sur l'utilisation de Cloud Storage dans une application App Engine !

Relier Cloud Storage à son application

Nous devons maintenant indiquer à Cloud Storage que notre application a le droit de modifier notre bucket, c'est-à-dire d'y lire et d'y écrire des fichiers. C'est la partie que j'ai trouvée la plus délicate pour ma part, alors suivez bien mes instructions dans l'ordre. ;)

Le Service Account Name

Pour commencer, vous devez récupérer le Service Account Name de votre application App Engine. Il faut que vous ayez déjà créé votre application sur l'interface en ligne pour en avoir un. Une fois que c'est fait, allez dans la console d'administration App Engine du projet, section Administration / Application settings :

Le Service Account Name nous permettra d'autoriser notre application sur Cloud Storage
Le Service Account Name nous permettra d'autoriser notre application sur Cloud Storage

Dans le cas de mon projet, le service account name est l'email : sdz-guestbook-datastore@appspot.gserviceaccount.com

Les ACL

Vous devez autoriser le service account name dans les ACL (Access Control List) du bucket Cloud Storage. L'avantage de Cloud Storage est justement qu'on peut définir de façon très précise qui a le droit de faire quoi dans un bucket, mais les ACL sont un petit peu complexes à manipuler.

Pour commencer, vous aurez besoin du programme en ligne de commande gsutil. Je vous rappelle que vous pouvez trouver les instructions pour l'installer dans la doc.

Configurer l'application gsutil

Ouvrez ensuite votre console et exécutez pour commencer la commande :

gsutil config

Suivez les instructions qu'on vous donne. Il vous faudra charger votre navigateur à une URL précise et retourner un identifiant pour que le programme gsutil reconnaisse que vous êtes bien le propriétaire du bucket.

Autoriser votre application App Engine à écrire dans le bucket

Ensuite, ajoutez à votre application le droit de lecture et d'écriture sur le bucket comme ceci :

gsutil chacl -u ID_APPLICATION@appspot.gserviceaccount.com:W gs://NOM_BUCKET

Pensez à remplacer ID_APPLICATION par le nom de votre application et NOM_BUCKET par le nom du bucket concerné.

Ouf ! Votre application a maintenant le droit d'accéder au bucket. :)

Autoriser tout le monde à voir les fichiers

Par défaut, vous êtes le seul à pouvoir lire les fichiers stockées dans le bucket. Le plus simple pour autoriser tout le monde à voir les fichiers dans le bucket est de lancer la commande qui change les ACL par défaut pour les nouveaux objets uploadés :

gsutil chdefacl -g AllUsers:R gs://NOM_BUCKET

Tous les nouveaux fichiers uploadés seront alors lisibles par tout le monde à une URL de la forme : http://storage.googleapis.com/NOM_BUCKET/NOM_FICHIER

Utiliser Cloud Storage dans son application

Maintenant que notre application a accès à notre bucket Google Cloud Storage, il ne nous reste plus qu'à écrire le code qui uploade sur Google Cloud Storage. Et là, surprise ! Le fonctionnement est basé sur le Blobstore que nous venons de voir il y a peu. Nous aurons donc très peu de choses à adapter.

Vous allez devoir créer une JSP avec un formulaire qui redirige encore une fois vers une URL fournie par le BlobstoreService :

<form action="<%= blobstoreService.createUploadUrl("/upload", UploadOptions.Builder.withGoogleStorageBucketName("NOM_BUCKET")) %>" method="post" enctype="multipart/form-data">

</form>

Cette fois, la différence est qu'on ajoute un second paramètre qui indique au BlobstoreService qu'on veut en fait stocker sur Google Cloud Storage et non dans le BlobStore. Pensez à remplacer "NOM_BUCKET" par le nom de votre bucket bien entendu. ;)

Reste à créer une servlet qui répond sur l'URL indiquée dans la JSP (ici "/upload"), qui peut récupérer les informations sur les fichiers uploadés ainsi que les autres champs de formulaire :

// Répond sur /upload

public void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws IOException {
        BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
        ImagesService imagesService = ImagesServiceFactory.getImagesService();

        Map<String, List<BlobKey>> blobs = blobstoreService.getUploads(req);
        List<BlobKey> blobKeys = blobs.get("uploadedFile");

        // Clé à stocker pour effectuer des opérations sur le fichier
        String cleFichierUploade = blobKeys.get(0).getKeyString();

        // URL du fichier pour afficher directement le fichier
        String urlImage = imagesService.getServingUrl(ServingUrlOptions.Builder.withBlobKey(blobKeys.get(0)));

        // ...
}

Le fonctionnement est strictement le même dans la servlet que pour le Blobstore. Avec les mêmes méthodes, on récupère une BlobKey (qui représente cette fois le fichier dans Cloud Storage) et l'URL du fichier. A vous maintenant de stocker ces informations (par exemple dans le Datastore) pour manipuler le fichier par la suite. :)


Google WEEB

TP : et voici le... Cloud Uploader

Assez de théorie, il est temps de pratiquer ! J'aimerais que vous vous exerciez dans un TP assez simple en jouant vraiment le jeu : essayez de répondre du mieux possible à l'exercice avec les connaissances que vous avez acquises dans les derniers chapitres. Vous avez le droit de relire autant que vous le voulez les chapitres précédents, mais ne regardez pas la solution... sauf si vous êtes désespérés. ;)

Dans ce TP, je vous propose de réunir vos connaissances sur le Datastore, Objectify, le Blobstore et Cloud Storage au sein d'une même application App Engine. Son nom : le... Cloud Uploader (c'est vraiment un nom de mon invention mais à l'allure où avancent les projets chez Google je ne serais pas étonné que ce soit bientôt le nom d'un nouveau service :p ).

Votre mission, si vous l'acceptez : créer une page où des milliers de visiteurs vont pouvoir uploader des images de leur choix et voter pour celle qu'ils préfèrent. Vous utiliserez évidemment l'infrastructure Cloud de Google App Engine pour faire en sorte que votre application supporte un grand nombre de visiteurs !

Consignes

Vous allez devoir réaliser un système d'upload d'icônes dans le Cloud en vous basant sur l'infrastructure App Engine. L'application sera capable de :

  • Lister les 9 dernières icônes uploadées par date décroissante, ainsi que leur description

  • Uploader de nouvelles icônes avec une description

Pour rester simple, je vous propose de tout faire sur une page. Voici à quoi ressemble l'application que je vous propose de créer (notez que je me suis basé sur Bootstrap pour mettre en place rapidement un petit design) :

L'application que vous allez devoir réaliser
L'application que vous allez devoir réaliser

La structure est très simple : l'application liste les dernières icônes uploadées, permet leur suppression et propose un formulaire en bas de page pour en ajouter de nouvelles.

Quelques instructions :

  • Vous devrez stocker les fichiers dans le Blobstore. Vous pourrez aussi les stocker dans Cloud Storage dans un second temps, la syntaxe étant quasiment la même, mais je me concentrerai sur le Blobstore ici.

  • Vous devrez stocker les informations concernant les icônes dans le Datastore en utilisant la bibliothèque Objectify.

A vous de bien construire votre POJO (objet de base Java) qui représente les uploads dans le Blobstore ! Pour le reste vous êtes libre de faire comme vous voulez. :)

Si cela peut vous être utile, voici le canevas de la page web que j'ai créée en utilisant Bootstrap :

<!DOCTYPE html>
<html>
<head>
<title>Cloud Uploader</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/bootstrap.min.css" rel="stylesheet" media="screen">
<link href="css/style.css" rel="stylesheet" media="screen">
</head>
<body>

    <div class="container-narrow">

        <div class="masthead">
            <ul class="nav nav-pills pull-right">
                <li class="active"><a href="/">Accueil</a></li>
                <li><a href="#list">Liste des icônes</a></li>
                <li><a href="#upload">Upload</a></li>
            </ul>
            <h3 class="muted">Cloud Uploader</h3>
        </div>

        <hr />

        <div class="jumbotron">
            <h1>
                Vos icônes<br />dans le Cloud
            </h1>
            <p class="lead">En un clic, uploadez vos icônes dans le Cloud de
                Google et votez pour votre icône préférée !</p>
            <a class="btn btn-large btn-success" href="#upload">Uploader une
                icône</a>
        </div>

        <hr />

        <div class="row-fluid iconlist" id="list">

            <h2>Liste des icônes</h2>

            <p>
                <span class="label">Note</span> Seules les 9 dernières icônes
                uploadées sont présentées ici.
            </p>

            <!-- Liste des icônes -->

        </div>

        <hr />

        <div class="row-fluid iconlist" id="upload">

            <h2>Uploader une icône</h2>

            <!-- Formulaire -->

        </div>

    </div>
    <script src="http://code.jquery.com/jquery.js"></script>
    <script src="js/bootstrap.min.js"></script>
</body>
</html>

Bon courage ! :)

Correction

Allez hop, je corrige les copies ! :D

Ca n'a pas été trop dur ? Le plus gros du travail consistait à créer correctement sa classe d'entité pour Objectify, le reste suit normalement assez bien tout seul. ;)

L'entité

Commençons justement par notre entité. J'ai créé une classe Upload qui représente chaque upload :

import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.images.ImagesService;
import com.google.appengine.api.images.ImagesServiceFactory;
import com.google.appengine.api.images.ServingUrlOptions;

import java.util.Date;
import com.googlecode.objectify.annotation.*;

@Entity
@Cache
public class Upload {
    @Id Long id;
    @Index Date date;
    String url;
    @Index BlobKey key;
    String description;

    private Upload() {}
    public Upload(BlobKey key, String description) {
        ImagesService imagesService = ImagesServiceFactory.getImagesService();

        this.date = new Date();
        this.key = key;
        this.url = imagesService.getServingUrl(ServingUrlOptions.Builder.withBlobKey(key));
        this.description = description;
    }

    public String getUrl() {
        return url;
    }
    public BlobKey getKey() {
        return key;
    }
    public String getKeyString() {
        return key.getKeyString();
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }

}

J'y stocke la BlobKey représentant l'upload mais aussi directement l'URL (pour des raisons de performance), la description, la date d'upload, etc. J'ai généré quelques getters et setters pour l'utiliser facilement depuis l'extérieur de la classe.

J'ai choisi d'activer 2 index :

  • La date, car mes icônes seront triées par date décroissante

  • La BlobKey car je dois pouvoir retrouver facilement une icône précise et la supprimer

La JSP

J'ai ensuite créé la JSP. Je suppose que j'y reçois une liste d'uploads et j'y génère aussi un formulaire d'upload :

<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<%@ page import="java.util.List"%>
<%@ page import="com.google.appengine.api.blobstore.*"%>
<%@ page import="cloudupload.Upload"%>

<%
    BlobstoreService blobstoreService = BlobstoreServiceFactory
            .getBlobstoreService();
%>

<!DOCTYPE html>
<html>
<head>
<title>Cloud Uploader</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/bootstrap.min.css" rel="stylesheet" media="screen">
<link href="css/style.css" rel="stylesheet" media="screen">
</head>
<body>

    <div class="container-narrow">

        <div class="masthead">
            <ul class="nav nav-pills pull-right">
                <li class="active"><a href="/">Accueil</a></li>
                <li><a href="#list">Liste des icônes</a></li>
                <li><a href="#upload">Upload</a></li>
            </ul>
            <h3 class="muted">Cloud Uploader</h3>
        </div>

        <hr />

        <div class="jumbotron">
            <h1>
                Vos icônes<br />dans le Cloud
            </h1>
            <p class="lead">En un clic, uploadez vos icônes dans le Cloud de
                Google et votez pour votre icône préférée !</p>
            <a class="btn btn-large btn-success" href="#upload">Uploader une
                icône</a>
        </div>

        <hr />

        <div class="row-fluid iconlist" id="list">

            <h2>Liste des icônes</h2>

            <p>
                <span class="label">Note</span> Seules les 9 dernières icônes
                uploadées sont présentées ici.
            </p>

            <%
                List<Upload> uploads = (List<Upload>) request.getAttribute("uploads");
                if (uploads.size() == 0) {
                    %>

            <p>
                <em>Aucune icône uploadée</em>
            </p>

            <%
                }
                else {
                int i = 0;
                for (Upload upload : uploads) {
                    if ((i % 3) == 0) {
            %>
            <div class="row">
                <% } %>

                <div class="span4">
                    <figure>
                        <img src="<%=upload.getUrl()%>" alt="Image utilisateur"
                            class="img-polaroid" style="max-width: 100px;" />
                        <figcaption><a class="close" href="/?delete=<%=upload.getKeyString() %>">&times;</a> <%=upload.getDescription()%></figcaption>
                    </figure>
                </div>

                <%
            if ((i % 3) == 2 || i == uploads.size() - 1) {
                %>
            </div>
            <%			}
                        i++;
                    }
                }%>

        </div>

        <hr />

        <div class="row-fluid iconlist" id="upload">

            <h2>Uploader une icône</h2>

            <form
                action="<%= blobstoreService.createUploadUrl("/") %>"
                method="post" enctype="multipart/form-data">
                <p>
                    <label>Fichier à envoyer : <input type="file"
                        name="uploadedFile" /></label>
                </p>
                <p>
                    <label>Description du fichier : <input type="text"
                        name="description" /></label>
                </p>
                <div class="form-actions">
                    <input type="submit" class="btn" />
                </div>
            </form>
        </div>

    </div>
    <script src="http://code.jquery.com/jquery.js"></script>
    <script src="js/bootstrap.min.js"></script>
</body>
</html>

Le code n'a rien de bien compliqué, si ce n'est mes petits calculs pour afficher correctement 3 icônes par ligne mais c'est juste pour le design. ;)
Je récupère toutes les infos sur les icônes via les getters que j'ai générés dans la classe Upload.

La servlet

Il reste maintenant à écrire le coeur de l'application : la servlet !

package cloudupload;

import static com.googlecode.objectify.ObjectifyService.ofy;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.*;

import com.google.appengine.api.blobstore.*;
import com.googlecode.objectify.ObjectifyService;

@SuppressWarnings("serial")
public class CloudUploadServlet extends HttpServlet {
    static {
        ObjectifyService.register(Upload.class);
    }

    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws IOException, ServletException {
        BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();

        // Récupère les derniers uploads
        List<Upload> uploads = ofy().load().type(Upload.class).order("-date").limit(9).list();
        req.setAttribute("uploads", uploads);

        // Supprime un upload si on l'a demandé
        if (req.getParameter("delete") != null) {
            BlobKey deleteUploadData = new BlobKey(req.getParameter("delete"));
            Upload deleteUploadInfos = ofy().load().type(Upload.class).filter("key", deleteUploadData).first().now();
            if (deleteUploadInfos != null) {
                blobstoreService.delete(deleteUploadData);
                ofy().delete().entity(deleteUploadInfos).now();
            }
        }

        this.getServletContext().getRequestDispatcher("/WEB-INF/formUpload.jsp").forward(req, resp);
    }

    public void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {
        BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();

        Map<String, List<BlobKey>> blobs = blobstoreService.getUploads(req);
        List<BlobKey> blobKeys = blobs.get("uploadedFile");

        Upload upload = new Upload(blobKeys.get(0), req.getParameter("description"));

        ofy().save().entity(upload).now();

        resp.sendRedirect("/");

    }
}

La servlet gère le listing des icônes, la suppression des icônes (avec la méthode GET) et l'envoi d'icônes (avec la méthode POST) au sein de la seule page de l'application.

Dans la méthode doPost() on récupère le fichier uploadé et on crée un objet de type Upload avec la BlobKey et la description. La classe se charge de générer le reste : l'URL, la date d'upload...

Dans la méthode doGet(), on récupère les 9 derniers uploads triés par date, d'où la nécessité d'un index sur le champ date. On vérifie si on a demandé une suppression (avec le paramètre delete) et, si c'est le cas, on récupère l'objet à supprimer avec une requête Objectify et on demande la suppression de l'image dans le Blobstore ainsi que de ses infos dans le Datastore.

Lors du développement de l'application, j'ai constaté que si le champ description contient des accents, le blobstoreService s'emmêle les pinceaux et renvoie un charset ISO au lieu de UTF-8. C'est manifestement un bug du serveur local : le problème n'apparaît pas une fois l'application déployée en ligne.

Tester l'application

J'ai déployé mon application en ligne à l'adresse suivante si vous voulez la tester :

http://sdz-cloudupload.appspot.com/

Vous pouvez aussi télécharger l'archive complète de l'application (attention c'est un peu gros) :

http://www.sdz-files.com/cours/appengine/cloudupload.zip (18 Mo)

Aller plus loin

L'application que nous venons de faire est minimale et ne propose pas beaucoup de fonctionnalités. Elle ne fait pas non plus beaucoup de tests : vous devriez en ajouter.

Voici quelques idées en vrac de ce que vous pourriez faire pour l'améliorer et pour vous entraîner :

  • Utilisez Google Cloud Storage au lieu du Blobstore pour stocker les fichiers

  • Vérifiez que les fichiers uploadés sont bien des PNG avant de les autoriser. Normalement, le blobstoreService transmet à votre application des infos sur un fichier déjà uploadé. Il vous faudra demander sa suppression dans la méthode doPost() pour annuler l'upload.

  • Redimensionnez l'image à une taille de 100x100. Le service d'images d'App Engine fournit des fonctionnalités pour manipuler l'image directement stockée sur le Blobstore !

  • Proposez de renommer les images après upload

  • Proposez de retourner les images après upload, là encore en utilisant le service d'images

  • Ajoutez une page qui liste toutes les icônes et pas seulement les dernières

  • Proposez à vos visiteurs de voter pour l'icône qu'ils préfèrent et triez les icônes en fonction des votes !

Voilà qui devrait vous donner de quoi vous occuper un moment. Amusez-vous bien ! :)

Cette partie est maintenant terminée. N'oubliez pas de faire vos exercices avant de passer à la partie suivante ! Vous trouverez les liens des exercices (1 quiz et 1 activité) dans le plan principal du cours. À vous de jouer !


Google WEEB

Google Accounts API : authentifiez vos visiteurs

Nous avons passé suffisamment de temps sur des choses un peu compliquées : Cloud SQL, Datastore, Blobstore, Cloud Storage, Objectify... Je vous propose de souffler un peu et de découvrir par la même occasion d'autres services qui sont fournis par l'API de Google App Engine.

Parce que oui, les services d'App Engine ne se limitent pas au stockage ! On peut aussi télécharger des fichiers, manipuler des images, planifier des tâches, générer des APIs... et authentifier ses utilisateurs facilement. C'est justement ce dernier point que nous allons voir ici.

Google App Engine nous permet en un rien d'effort de créer une section membres sur notre site. Vos membres pourront se connecter avec leur compte Google ou même avec un OpenID, et vous n'avez presque rien à coder pour ça !

Authentifier les utilisateurs

Google App Engine nous permet d'authentifier nos utilisateurs par 3 méthodes différentes :

  • Google Accounts : vous pouvez autoriser toute personne possédant un compte Google à se connecter à votre application. Les comptes Google sont généralement des adresses e-mail @gmail.com mais il peut parfois s'agir d'autres e-mails dans certains cas.

  • Google Accounts d'un domaine : si vous réalisez une application pour les besoins d'un groupe ou d'une entreprise qui possède un compte Google Apps, c'est la méthode idéale. Seules les personnes appartenant à votre domaine (par ex. *@entreprise.com) pourront se connecter à votre application.

  • OpenID : toute personne possédant un compte OpenID pourra se connecter à votre application. Il n'est pas nécessaire dans ce cas de posséder un compte Google mais il faut que la personne ait déjà créé un compte chez un fournisseur OpenID comme myOpenID. Ce fournisseur joue le rôle de tiers de confiance pour authentifier les utilisateurs.

Vous devez choisir l'une de ces méthodes au moment de la création de l'application en ligne sur https://appengine.google.com/. Souvenez-vous, vous avez déjà vu ces options :

Options d'authentification à la création de l'application
Options d'authentification à la création de l'application

Dans la plupart des cas, vous laisserez l'option par défaut qui est la plus simple. Elle permet à toute personne possédant un compte Google de se connecter facilement à votre application.

Dans votre code, vous avez juste besoin de générer :

  • Une URL pour se connecter

  • Une URL pour se déconnecter

Google se charge du reste. :)

On peut faire tout ça directement dans la JSP.

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%@ page import="com.google.appengine.api.users.*" %>

<% UserService userService = UserServiceFactory.getUserService(); %>

<!DOCTYPE html>

<html>
    <head>
        <title>Application App Engine</title>
        <meta charset="utf-8" />
    </head>

    <body>
        <h1>Bienvenue dans mon application</h1>

        <% if (userService.getCurrentUser() == null) { %>
            <p><a href="<%= userService.createLoginURL("/") %>">Se connecter</a></p>
        <% }
        else { %>
            <p>Bonjour <%= userService.getCurrentUser().getNickname() %></p>
            <p><a href="<%= userService.createLogoutURL("/") %>">Se déconnecter</a></p>
        <% } %>
    </body>
</html>

Ce code est très simple : on récupère le service UserService de Google et on vérifie si l'utilisateur est déjà connecté avec userService.getCurrentUser(). Cette méthode renvoie null si l'utilisateur n'est pas connecté, et elle renvoie un objet de type User s'il est connecté.

Notez que le Datastore est capable de stocker des propriétés de type User directement (en plus des types standard int, Long, Date...). Vous pouvez donc vous en servir pour établir une liste de vos membres.

Selon si l'utilisateur est connecté ou non, vous pouvez générer une URL de connexion ou de déconnexion avec userService.createLoginURL("/") et userService.createLogoutURL("/"). La valeur en paramètre indique où l'utilisateur doit ensuite être redirigé sur votre site (ici, "/" correspond à l'accueil).

On peut ensuite récupérer le pseudonyme de l'utilisateur avec userService.getCurrentUser().getNickname() (qui peut être aussi son e-mail) ou bien directement l'e-mail avec userService.getCurrentUser().getEmail().

Si vous testez ce code en local, vous verrez que le serveur "simule" une mini-page de connexion qui ressemble à ceci :

La fausse page de connexion en local
La fausse page de connexion en local

Vous pouvez rentrer n'importe quelle adresse, vous serez immédiatement connecté.

Bien sûr, une fois votre application en ligne, vos utilisateurs passeront par le vrai processus de connexion d'un compte Google :

La vraie page de connexion une fois l'application en ligne
La vraie page de connexion une fois l'application en ligne

Et voilà, vous venez de mettre en place un super système de connexion sur votre site en quelques minutes à peine ! :)

Protéger des URLs

Google App Engine nous fournit un moyen basique et très simple de protéger rapidement tout un groupe d'URLs.

Il suffit d'éditer le fichier web.xml et d'y ajouter les lignes suivantes :

<security-constraint>
    <web-resource-collection>
        <url-pattern>/admin/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>admin</role-name>
    </auth-constraint>
</security-constraint>

Ici, je protège toutes les URLs commençant par /admin/ et je les réserve uniquement aux admins.

Les admins de l'application sont ceux qui ont un rôle de viewer, developer ou owner au sein de l'application. On les ajoute dans le menu Administration / Permissions du dashboard App Engine :

Ajout de rôles dans le dashboard d'App Engine
Ajout de rôles dans le dashboard d'App Engine

En développement local, vous pouvez simuler une connexion administrateur en cliquant sur "Sign in as administrator" dans la fausse page de connexion qui est générée.

Ce moyen d'authentification est vraiment très basique. Si vous avez besoin d'un moyen plus fin d'authentifier les utilisateurs (et si vous ne voulez pas avoir à rajouter à la main des admins dans le dashboard), vous devrez coder vous-mêmes un système d'authentification dans vos servlets.

De la même façon, vous pouvez réserver des pages à tous vos membres connectés avec un compte Google. Il vous suffit d'indiquer le rôle "*" :

<security-constraint>
    <web-resource-collection>
        <url-pattern>/membres/*</url-pattern>
        <url-pattern>/upload/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>*</role-name>
    </auth-constraint>
</security-constraint>

Ici, tout le contenu des dossiers /membres/ et /upload/ sera réservé aux membres connectés.


Google WEEB

Mail API : envoyez et réceptionnez des e-mails

Parmi les services fournis par App Engine, l'un d'eux devrait éveiller votre intérêt : la Mail API. Ce service permet :

  • D'envoyer des e-mails : votre application peut envoyer des e-mails en bénéficiant de l'architecture de serveurs mail de Google (la même que GMail !).

  • De recevoir des e-mails : votre application peut recevoir et traiter automatiquement des e-mails qu'on lui envoie.

Les deux fonctionnalités sont réellement puissantes et vous permettent d'imaginer de nouvelles interactions avec vos visiteurs. Nous allons découvrir comment nous en servir ! :)

Envoyer des e-mails

Sur App Engine, vous pouvez envoyer des e-mails à un ou plusieurs destinataires à la fois. En revanche, il y a une restriction sur l'expéditeur. Celui-ci doit être :

  • Soit un administrateur de l'application, du type admin@monapplication.com. Ces e-mails sont définis dans le dashboard d'App Engine.

  • Soit l'e-mail de l'utilisateur actuellement connecté à l'application, s'il utilise un compte Google.

App Engine implémente les interfaces de JavaMail, ce qui fait que le code ne devrait pas vous surprendre si vous avez déjà envoyé des e-mails en Java. Seules particularités : l'expéditeur est restreint (comme je viens de vous l'expliquer) et il n'est pas nécessaire de définir de serveur SMTP étant donné que Google sait déjà qu'il doit utiliser les siens.

Je vous propose ce code que je recopie sans honte ni vergogne depuis la documentation :

import java.io.IOException;
import java.util.Properties;
import javax.servlet.http.*;
import javax.mail.*;
import javax.mail.internet.*;

@SuppressWarnings("serial")
public class TestsServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {
        try {
            Properties props = new Properties();
            Session session = Session.getDefaultInstance(props, null);

            String message = "Corps du message";

            Message msg = new MimeMessage(session);
            msg.setFrom(new InternetAddress("admin@monapplication.com", "Administrateur"));
            msg.addRecipient(Message.RecipientType.TO,
                             new InternetAddress("robert@isp.com", "Robert"));
            msg.setSubject("Bienvenue sur mon application !");
            msg.setText(message);
            Transport.send(msg);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}

Vous pouvez vous baser dessus pour définir le corps du message, l'expéditeur, le destinataire et le sujet de l'e-mail.

Si vous testez le code en local, aucun e-mail ne sera envoyé. Les informations sur l'e-mail seront en revanche loggées dans la console :

17 mai 2013 15:45:35 com.google.appengine.api.mail.dev.LocalMailService log
INFO: MailService.send
17 mai 2013 15:45:35 com.google.appengine.api.mail.dev.LocalMailService log
INFO:   From: Administrateur <admin@monapplication.com>
17 mai 2013 15:45:35 com.google.appengine.api.mail.dev.LocalMailService log
INFO:   To: Robert <robert@isp.com>
17 mai 2013 15:45:35 com.google.appengine.api.mail.dev.LocalMailService log
INFO:   Reply-to: Administrateur <admin@monapplication.com>
17 mai 2013 15:45:35 com.google.appengine.api.mail.dev.LocalMailService log
INFO:   Subject: Bienvenue sur mon application !
17 mai 2013 15:45:35 com.google.appengine.api.mail.dev.LocalMailService log
INFO:   Body:
17 mai 2013 15:45:35 com.google.appengine.api.mail.dev.LocalMailService log
INFO:     Content-type: text/plain
17 mai 2013 15:45:35 com.google.appengine.api.mail.dev.LocalMailService log
INFO:     Data length: 16

Evidemment une fois votre application en ligne l'e-mail sera bel et bien envoyé par les serveurs e-mail de Google !

En cas d'échec de l'envoi de l'e-mail (par exemple si le destinataire n'existe pas), l'expéditeur recevra une erreur par e-mail. En revanche votre application ne recevra pas d'information sur l'échec de l'envoi.

Sachez qu'il y a des quotas pour l'envoi d'e-mails. Inutile de vous amuser à envoyer du spam depuis App Engine donc. ;)

Recevoir des e-mails

Les applications App Engine peuvent aussi recevoir des e-mails ! C'est un moyen très pratique d'établir une interface avec les utilisateurs (ce qui devrait vous intéresser si vous développez un outil de support client par exemple).

Le principe est le suivant :

  • L'utilisateur envoie un e-mail à une adresse du type adresse@appid.appspotmail.com

  • App Engine reçoit l'e-mail et retransmet à votre application son contenu sous la forme d'un paramètre POST

App Engine récupère les e-mails et les reposte à votre application
App Engine récupère les e-mails et les reposte à votre application

Pour activer la réception d'e-mails, ajoutez ces lignes dans votre fichier appengine-web.xml :

<inbound-services>
    <service>mail</service>
</inbound-services>

A partir de maintenant, tout le monde peut vous envoyer des e-mails à n'importe quelle adresse de la forme *@appid.appspotmail.com (où appid est l'ID de votre application sur App Engine). Par exemple, si un visiteur envoie un e-mail à aide@appid.appspotmail.com, App Engine provoquera un appel POST vers l'URL /_ah/mail/aide. A vous ensuite de créer la servlet correspondante.

Notez qu'il n'est malheureusement pas possible de changer la forme de l'adresse e-mail de réception (en appspotmail.com), même si vous possédez votre propre nom de domaine. :(

Pour faire simple et gérer tous les e-mails au même endroit, je vous proposer de mapper les appels à /_ah/mail/* vers une servlet. Ajoutez dans le fichier web.xml le code suivant par exemple :

<servlet>
    <servlet-name>mailhandler</servlet-name>
    <servlet-class>MailHandlerServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>mailhandler</servlet-name>
    <url-pattern>/_ah/mail/*</url-pattern>
</servlet-mapping>
<security-constraint>
    <web-resource-collection>
        <url-pattern>/_ah/mail/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>admin</role-name>
    </auth-constraint>
</security-constraint>

Si un visiteur envoie un e-mail à aide@appid.appspotmail.com, App Engine provoquera un appel vers /_ah/mail/aide. Vous pouvez donc créer plusieurs servlets qui réceptionnent différentes adresses e-mails.
Dans mes exemples, je fais simple et je réceptionne tous les e-mails au même endroit.

Il ne vous reste plus qu'à créer la servlet MailHandlerServlet et d'y implémenter une méthode doPost() pour réceptionner le contenu de l'e-mail !

public class MailHandlerServlet extends HttpServlet {
    public void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {

        try {
            // On extrait le message de la requête POST
            Properties props = new Properties();
            Session session = Session.getDefaultInstance(props, null);
            MimeMessage message = new MimeMessage(session, req.getInputStream());

            // On peut ensuite récupérer toutes les informations que l'on veut
            message.getSubject();
            message.getFrom();
            message.getContent();

        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}

Vous pouvez utiliser toutes les méthodes de la classe MimeMessage pour récupérer le contenu du message et effectuer tous les traitements que vous voulez ! :)

Si vous voulez tester localement comment votre application se comporte quand elle reçoit un e-mail, rendez-vous dans le backend local, section "Inbound Mail" (typiquement http://localhost:8888/_ah/admin/inboundmail). Vous pourrez simuler l'envoi d'un e-mail vers votre application.

Vous pouvez simuler la réception d'un e-mail dans le backend en local
Vous pouvez simuler la réception d'un e-mail dans le backend en local

Bref, vous avez tout ce qu'il faut pour développer de belles fonctionnalités pour votre application ! :)


Google WEEB

Image API : transformez des images

Google propose les services de ses serveurs pour effectuer des manipulations simples sur des images. Ces manipulations ne nécessitent pas d'utiliser la puissance de calcul de vos frontaux App Engine : elles sont effectuées sur des serveurs spéciaux de traitement des images.

Cette Image API se révèle très pratique car elle est capable de travailler directement sur des images stockées dans le Blobstore (mais pas dans Google Cloud Storage malheureusement). Nous pouvons donc manipuler des images après leur envoi dans le Blobstore, voire même générer dynamiquement des versions transformées des images directement en changeant l'URL !

Transformer des images depuis le Blobstore

Traitement d'images par le service d'images

Pour transformer des images, on fait appel à un ImageService. On le récupère grâce à la factory qui nous est fournie par l'API d'App Engine.

J'aime bien travailler à partir de codes d'exemple, donc commençons par un exemple. Voici un code qui récupère une image depuis le Blobstore (grâce à sa BlobKey) et qui la retourne horizontalement :

// Récupère le service d'images
ImagesService imagesService = ImagesServiceFactory.getImagesService();

// Récupère une image dans le Blobstore, représentée par sa blobKey
Image oldImage = ImagesServiceFactory.makeImageFromBlob(blobKey);

// Effectue une transformation (ici un retournement horizontal)
Transform transform = ImagesServiceFactory.makeHorizontalFlip();
Image newImage = imagesService.applyTransform(transform, oldImage);

// Récupère le contenu de l'image transformée
byte[] newImageData = newImage.getImageData();

// Vous pouvez ensuite sauvegarder l'image où bon vous semble !

Il faut savoir que l'API est capable de travailler avec les formats d'images suivants :

  • JPEG

  • PNG

  • WEBP

  • GIF

  • BMP

  • TIFF

  • ICO

Elle peut enregistrer en revanche uniquement en JPEG, WEBP et PNG.

Le format WEBP a été inventé par Google. C'est un format public qui se présente comme le futur du JPEG, car il est capable de mieux compresser les images.

Les transformations

L'Image API propose un certain nombre de transformations basiques.

Redimensionnement

Vous pouvez redimensionner une image avec la transformation makeResize() :

Transform resize = ImagesServiceFactory.makeResize(200, 300);
Redimensionnement d'une image
Redimensionnement d'une image
Rotation

Pour faire une rotation de l'image, appelez makeRotate() et indiquez une valeur en degrés :

Transform resize = ImagesServiceFactory.makeRotate(90);
Rotation d'une image
Rotation d'une image
Retournement horizontal

Vous pouvez retourner horizontalement une image avec makeHorizontalFlip() :

Transform resize = ImagesServiceFactory.makeHorizontalFlip();
Retournement horizontal d'une image
Retournement horizontal d'une image
Retournement vertical

Vous pouvez retourner verticalement une image avec makeVerticalFlip() :

Transform resize = ImagesServiceFactory.makeVerticalFlip();
Retournement vertical d'une image
Retournement vertical d'une image
Découpage

Vous pouvez effectuer un découpage (crop) d'une image avec makeCrop(). Indiquez les coordonnées (X,Y) du point en haut à gauche suivies des coordonnées (X,Y) du point en bas à droite de la zone que vous voulez récupérer dans l'image :

Transform resize = ImagesServiceFactory.makeCrop(20, 20, 60, 60);
Découpage d'une image
Découpage d'une image
Amélioration automatique

Google propose une fonctionnalité qui améliore automatiquement le contraste et les couleurs d'une image, sous le nom "I'm feeling lucky" (on aura reconnu le clin d'oeil !). Le nom de cette fonction magique est makeImFeelingLucky() :

Transform resize = ImagesServiceFactory.makeImFeelingLucky();
Amélioration d'une image I'm feeling lucky
Amélioration d'une image I'm feeling lucky

Bon cette transformation est en général plus pertinente sur une photo que sur une image PNG je vous l'accorde. ;)

Transformer des images depuis leur URL

Si vous ne voulez pas avoir à enregistrer une nouvelle image, Google propose un service très pratique qui permet de transformer des images dynamiquement simplement en changeant la forme de l'URL !

Vous vous souvenez de la méthode getServingUrl() ?

String urlImage = imagesService.getServingUrl(ServingUrlOptions.Builder.withBlobKey(blobKey));

Cette méthode renvoie une URL qui fournit directement l'image de façon efficace (c'est-à-dire sans avoir à passer par une servlet).

On peut ajouter un suffixe à l'URL pour effectuer des transformations très facilement ! Imaginons par exemple que votre URL ressemble à ceci :

http://appid.appspot.com/identifiantimage

Vous pouvez ajouter 2 suffixes :

  • =sXX : où XX est la nouvelle taille de l'image (au niveau de son côté le plus large). Cela vous permet d'effectuer un redimensionnement à la volée !

  • =sXX-c : où XX indique où l'image doit être coupée.

Par exemple :

http://appid.appspot.com/identifiantimage=s100

... vous retournera automatiquement une image redimensionnée à 100px de large et de haut maximum. :)

Pour obtenir l'URL de la "version 100px" de l'image, il nous suffit donc d'adapter notre code comme ceci :

String urlMiniImage = imagesService.getServingUrl(ServingUrlOptions.Builder.withBlobKey(blobKey) + "=s100");


Google WEEB

Crons : exécutez des tâches à intervalles réguliers

Vous connaissez les crons ? Sous Linux, c'est le système qui permet d'exécuter des tâches à intervalles réguliers sur une machine. Cela peut être très utile dans tout un tas d'occasions : si vous voulez régénérer les caches de votre application à intervalles réguliers, envoyer un e-mail quotidien à vos membres qui fêtent leur anniversaire, etc.

Avec App Engine, on n'a pas accès au serveur pour y configurer des crons comme on le ferait d'habitude, mais on dispose d'une autre technique : il suffit d'éditer un fichier XML de crons et Google planifiera automatiquement l'exécution de vos tâches !

Le système de crons est d'ailleurs très complet et vous permet de planifier des tâches de façon beaucoup plus simple que sous Linux je trouve. :)

Configurer des tâches cron

Google peut appeler automatiquement certaines URLs de votre application à intervalles réguliers. Il exécute de simples appels GET sur les URLs que vous spécifiez.

Vous devez créer un fichier cron.xml dans le dossier WEB-INF de votre application. Ce fichier peut avoir la forme suivante :

<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
    <cron>
        <url>/recache</url>
        <description>Met à jour le cache régulièrement</description>
        <schedule>every 2 minutes</schedule>
    </cron>
    <cron>
        <url>/rapport</url>
        <description>Envoie un rapport hebdomadaire</description>
        <schedule>every monday 09:00</schedule>
        <timezone>Europe/Paris</timezone>
    </cron>
</cronentries>

Dans cet exemple, le fichier contient 2 tâches cron. Pour chaque tâche cron, vous devez indiquer :

  • Une URL : c'est l'URL qui sera appelée par le planificateur cron de Google. Cette URL de votre application sera appelée avec la méthode GET.

  • Une description : pour vous souvenir de ce que fait la tâche cron.

  • Un horaire ou une récurrence : c'est le rôle de la balise <schedule>. Elle accepte une syntaxe assez riche qui vous permet de faire un peu tout ce que vous voulez (pour peu que vous l'écriviez en anglais :p ).

  • Une zone horaire : si, comme moi, vous n'habitez pas à côté du datacenter de Google, il est préférable d'indiquer une zone horaire dans le format standard. Sinon vous risquez de subir un sérieux décalage horaire !

Le plus important est de bien définir la balise <schedule>. Elle accepte une syntaxe riche qui est plutôt bien décrite dans la documentation.

Voici quelques exemples pour vous inspirer :

// Toutes les 12 heures
every 12 hours

// Toutes les 10 minutes
every 10 minutes

// Toutes les 5 minutes entre 10h et 14h
every 5 minutes from 10:00 to 14:00

// Les seconds et troisièmes mardis, mercredis et jeudis du mois de mars à 17h
2nd,third mon,wed,thu of march 17:00

// Chaque lundi à 9h
every monday 09:00

// Les premiers lundis de septembre, octobre et novembre à 17h
1st monday of sep,oct,nov 17:00

// Chaque jour à minuit
every day 00:00

Voilà qui devrait vous permettre de créer toutes les récurrences dont vous rêvez et même plus ! ;)

Protéger les URLs des crons

En général, vous ne voulez pas que vos visiteurs puissent se rendre aux URLs normalement exécutées par des crons... sinon ils risqueraient de lancer des tâches potentiellement lourdes n'importe quand !

Heureusement, les tâches cron s'exécutent en mode administrateur. Cela signifie que vous pouvez protéger vos crons en les réservant uniquement aux administrateurs. Pour cela, il suffit d'éditer le fichier web.xml et d'y ajouter les règles de sécurité suivantes :

<security-constraint>
    <web-resource-collection>
        <url-pattern>/cron/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>admin</role-name>
    </auth-constraint>
</security-constraint>

Ainsi, toutes vos tâches cron seront protégées des utilisateurs, pour peu que vous les placiez dans le cas présent dans un dossier /cron/.

Attention : si vous protégez les URLs des crons en les réservant à tous les utilisateurs connectés (avec le rôle *) au lieu de cibler les administrateurs, le planificateur cron ne pourra pas y accéder !


Google WEEB

Cloud Endpoints : créez des APIs et générez des apps Android & iPhone

Le but de Cloud Endpoints est de relier l'ensemble de vos applications (web, mobile...) en générant une API. C'est une fonctionnalité récente de Google App Engine déjà promise à un bel avenir. Google résume de façon très synthétique le principe dans un seul schéma :

Cloud Endpoints connecte votre application backend avec vos applications frontend
Cloud Endpoints connecte votre application backend avec vos applications frontend

  • Sur la droite, vous avez le backend. C'est votre application qui tourne sur App Engine. C'est elle qui effectue tous les calculs et tout le stockage (sur le Datastore par exemple).

  • Sur la gauche, vous avez vos frontends. Ce sont les interfaces de votre application dont se servent vos utilisateurs. Ces dernières années, les interfaces se sont multipliées : Web (navigateur), application Android, application iOS...

Vous pourriez réécrire autant de fois que nécessaire votre application : une fois en version web, une fois en version Android, une fois en version iOS (et demain en version Blackberry, Windows Phone... ?). Mais ce serait long, fastidieux et lourd à maintenir.

La bonne pratique de programmation est de séparer son application en deux parties logiques : le backend (en gros le modèle et le contrôleur) et le frontend (en gros la vue). Comme les interfaces changent en fonction des appareils (sur le Web on a du HTML5, sur Android des widgets Java, sur iOS des composants Objective-C...), on est obligé de multiplier les frontends. En revanche, on peut ne créer qu'un seul backend qui fait les calculs et le stockage... sur App Engine par exemple. ;)

En résumé, dans ce modèle les calculs et le stockage sont sur App Engine, tandis que les interfaces sont dans des applis mobiles et des sites web séparés.

L'ensemble des appareils communique avec une API. Celle-ci est le plus souvent une API REST qui échange des informations dans un format JSON.

Sans rentrer dans le détail, le principe de REST est de créer des interfaces respectant le fonctionnement de HTTP, avec les méthodes GET, POST, PUT, DELETE... L'API répond sur des URLs qui ont une forme particulière. Par exemple : une requête GET sur /membre/mateo21 renverra toutes les informations sur le membre mateo21. Une requête HTTP DELETE sur /membre/mateo21 supprimera le membre mateo21, etc.

Cloud Endpoints se charge de construire et de gérer l'API de votre application pour vous. Cela vous évite d'avoir à écrire du code parfois complexe pour faire fonctionner l'API. En plus, Cloud Endpoints se charge de gérer la sécurité et l'authentification OAuth 2.0 de votre API (et vu qu'on a dû le faire à la main pour le Site du Zéro récemment je peux vous dire que c'est pas de la tarte :p ).

Enfin, et c'est là que ça devient particulièrement intéressant : Cloud Endpoints peut générer des applications Web (JavaScript), Android (Java) et iPhone (Objective-C) à partir de votre API ! Pour être exact, il crée un code bootstrap, c'est-à-dire un code prêt à être rempli, dans lequel vous n'avez plus qu'à écrire la vue de votre application Android par exemple. Un sacré gain de temps !

Premiers pas avec Cloud Endpoints

Cloud Endpoints peut être délicat à prendre en main quand on ne sait pas par où commencer. Aussi, avant de rentrer dans les détails du fonctionnement de Cloud Endpoints, je vous propose de découvrir par la pratique une micro-application basique utilisant Endpoints, que nous complèterons progressivement. :)

Le code

La classe TestEndpoint

Créez un nouveau projet "Web Application Project" que vous appellerez par exemple "Test" et décochez "Google Web Toolkit" car nous n'en aurons pas besoin ici. L'assistant va générer un fichier de servlet : ignorez-le, il ne nous est pas utile ici. Créez plutôt un nouveau fichier contenant une nouvelle classe appelée "TestEndpoint". Placez-y avec le code suivant :

package tests;

import com.google.api.server.spi.config.Api;

@Api(name = "monapi")
public class TestEndpoint {

    // Méthode de l'API
    public Membre getMembre() {
        Membre membre = new Membre("Mateo21");
        return membre;
    }

    // Classe représentant les données à transmettre
    public class Membre {
        public String nom;

        public Membre(String nom) {
            this.nom = nom;
        }
    }
}

Vous constaterez que la classe TestEndpoint contient une autre classe Membre représentant un membre. Il n'est pas obligatoire de les imbriquer (on aurait pu faire 2 fichiers) mais par contre nous avons bien besoin de 2 classes :

  • Une classe représentant l'API (ici TestEndpoint) dans laquelle chaque méthode est une fonctionnalité différente de l'API.

  • Une classe représentant les données (ici Membre) dans laquelle Cloud Endpoint va récupérer les attributs pour connaître les données transmettre.

La classe représentant l'API (TestEndpoint) est précédée d'une annotation :

@Api(name = "monapi")
public class TestEndpoint {
    // ...
}

Celle-ci indique que la classe qui suit fournit les fonctionnalités d'une API. Elle contient un paramètre : le nom de l'API (qu'on retrouvera dans l'URL). On peut y ajouter d'autres paramètres, j'y reviendrai plus tard.

Alerte ! Je viens de voir que les attributs de la classe Membre étaient publics ! Ça ne se fait pas !

Oui je sais, mais je l'ai fait quand même pour rester simple ici. :D
En fait, Cloud Endpoints va analyser la classe Membre et extraire toutes les données publiques. Heureusement, vous n'êtes pas obligés de rendre les attributs publics : vous pouvez aussi passer par des getters et setters qui vérifient que l'utilisateur ne rentre pas n'importe quoi. Cloud Endpoints saura reconnaître les getters et setters : si vous rendez votre attribut "nom" privé et que vous créez une méthode publique getNom(), cela marche aussi. :)

Adapter le fichier web.xml

Dans le fichier web.xml, ajoutez les lignes suivantes pour associer votre classe à l'API :

<servlet>
    <servlet-name>SystemServiceServlet</servlet-name>
    <servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class>
    <init-param>
        <param-name>services</param-name>
        <param-value>tests.TestEndpoint</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>SystemServiceServlet</servlet-name>
    <url-pattern>/_ah/spi/*</url-pattern>
</servlet-mapping>

Si vous avez plusieurs classes fournissant une API, vous pouvez les ajouter à la suite séparées par des virgules dans <param-value> :

<param-value>tests.TestEndpoint,tests.OtherEndpoint,tests.SuperEndpoint</param-value>
Tester l'API

Il ne vous reste plus qu'à lancer votre application. Rendez-vous ensuite à l'adresse suivante :

http://localhost:8888/_ah/api/monapi/v1/membre/

Si tout va bien, la page devrait afficher des données en format JSON :

{
  "nom" : "Mateo21"
}

Et si vous avez un message "Error 404"... c'est que tout va mal. :D Vérifiez que vous n'avez pas fait d'erreur dans les codes que je viens de vous donner, en particulier que vous n'avez pas oublié de mettre à jour le fichier web.xml. Vérifiez aussi que vous avez une version récente du plugin Google pour Eclipse, car Cloud Endpoints est une fonctionnalité récente qui ne marche pas avec les vieilles versions du plugin.

Les explications

Peut-on m'expliquer ce qui vient de se passer ? J'ai suivi les instructions, ça marche, mais je ne comprends pas ce que je fais ! :(

Pas de panique ! Je voulais qu'on travaille ensemble sur un premier code basique qui marche pour qu'on ait une base sur laquelle discuter. C'est le moment des explications.

Quand vous annotez une classe avec @Api, Google App Engine sait qu'il doit utiliser des fonctionnalités de Cloud Endpoints. Celui-ci prend le relai et analyse comment votre classe (ici TestEndpoint) est constituée. Il repère les méthodes qu'elle contient et, en fonction de leur nom et du type de données qu'elles retournent, génère des URLs (routes) pour votre API.

Dans notre test, il n'y a qu'une seule méthode :

public Membre getMembre() {
    Membre membre = new Membre("Mateo21");
    return membre;
}

Cette méthode commençant par "get" et retournant un objet de type Membre, Endpoints sait qu'il doit générer une route /membre/ qui doit renvoyer en JSON le contenu de l'objet Membre (c'est-à-dire tous ses attributs publics). La classe Membre est constituée des attributs suivants :

public class Membre {
    public String nom;

    // ...
}

Elle possède un seul attribut (auquel on peut accéder parce qu'il est public, mais on aurait aussi pu créer un getter), donc Endpoints renvoie cet attribut dans le JSON :

{
  "nom" : "Mateo21"
}

Essayez d'ajouter un second attribut et de lui donner une valeur pour voir ! Par exemple, essayez d'obtenir le résultat suivant pour vous entraîner :

{
  "nom" : "Mateo21",
  "pays" : "France"
}

Et à quoi sert ce JSON au juste ?

Si vous avez déjà développé avec des APIs, vous ne devriez pas vous poser la question. Si c'est votre première fois avec une API en revanche, je comprends votre interrogation. :p

En fait, ce JSON correspond au code qui transitera entre votre backend (sur App Engine) et votre frontend (l'application web, l'application Android, iOS...). C'est comme ça que les différentes parties de votre application vont pouvoir communiquer.

Par exemple, si vous avez une application Android, elle devra effectuer une requête HTTP GET sur http://www.votresite.com/_ah/api/monapi/v1/membre/ pour récupérer le JSON et en extraire les informations. Voilà comment on peut faire communiquer 2 applications entre elles !

Et pourquoi l'URL a-t-elle cette forme ? Je n'aurais jamais pu la deviner !

C'est vrai. L'URL a une forme bien précise :

http://localhost:8888/_ah/api/monapi/v1/membre/

On peut décomposer l'URL comme ceci :

http://localhost:8888/<prefixe>/<nom_api>/<version_api>/<objet>/

Chacun de ces éléments peut être modifié en ajoutant des options aux annotations. C'est justement ce que nous allons voir maintenant : on peut largement personnaliser notre API avec les annotations !

Les annotations Cloud Endpoints

Cloud Endpoints nous permet de créer 2 types d'annotations :

  • Des annotations globales, qui définissent le comportement global de l'API

  • Des annotations par méthode, qui définissent le comportement de chaque méthode / route de l'API

Les annotations globales @Api

Commençons par les annotations globales. Comme vous l'avez vu, on a ajouté une annotation @Api devant la classe qui contient les méthodes de l'API :

@Api(name = "monapi")
public class TestEndpoint {
    // ...
}

Vous pouvez ajouter un certain nombre de paramètres à cette annotation comme nous l'indique la doc. En voici quelques-unes intéressantes :

Paramètre | Description
root | L'adresse racine de l'URL de l'API
name | Le nom de l'API
version | Le numéro de version de l'API
description | Une courte description de l'API

Il y a d'autres paramètres comme l'indique la doc, utilisés notamment pour l'authentification des applications Android, iOS... Je ne traiterai pas ce sujet plus complexe ici pour le moment.

En somme, on peut écrire l'annotation avec des paramètres comme ceci :

@Api(
        name = "monapi",
        version = "v2",
        description = "Une API de test qui manipule des membres"
    )
public class TestEndpoint {
    // ...
}

Dans ce cas, l'API sera accessible à l'adresse : http://localhost:8888/_ah/api/monapi/v2/

Les annotations par méthode @ApiMethod

Endpoints est capable de générer automatiquement une API en fonction du nom des méthodes, en se basant sur leur préfixe, leurs paramètres et leur type de retour. C'est pratique mais dans la réalité assez complexe car il faut respecter scrupuleusement certaines règles pour que ça fonctionne. Ainsi, Endpoints sait qu'une méthode getMembre() doit renvoyer un objet de type Membre, qu'une méthode listMembre va renvoyer une liste de membres, que deleteMembre va supprimer un membre, etc.

Plutôt que de vous baser sur les noms (ce qui est un peu complexe, la documentation n'étant pas très claire à ce sujet je trouve), vous pouvez ajouter une annotation @ApiMethod à vos méthodes. Ainsi, vous pouvez définir clairement le chemin de l'API, la méthode à utiliser (GET, POST, DELETE...), etc.

Voici quelques-uns des paramètres que vous pouvez utiliser :

Paramètre | Description
name | Un nom unique pour cette fonctionnalité de l'API.
path | Le chemin permettant d'accéder à cette fonctionnalité.
httpMethod | La méthode HTTP permettant d'y accéder (GET, POST, PUT, DELETE...).

Il existe d'autres paramètres pour l'authentification OAuth 2 mais je ne les détaille pas ici pour rester simple.

Annotations sans paramètres

Prenons un exemple pour tester. Par exemple, nous voulons créer une route /membres/liste qui renvoie la liste des membres :

@ApiMethod(
        path = "membres/liste",
        httpMethod = HttpMethod.GET
    )
public Membre[] listeMembres() {

    // Récupère la liste des membres...

    return listeMembres;
}

Si on se rend sur http://localhost:8888/_ah/api/monapi/v1/membres/liste avec la méthode GET, on obtient une liste de membres :

{
    "items": [
        {
            "nom": "robert"
        },
        {
            "nom": "francis"
        }
    ]
}
Les paramètres

Si votre méthode doit prendre des paramètres, vous devez les lier à la requête du client. Pour cela, il faut faire précéder les paramètres de la méthode d'une annotation @Named et réutiliser le nom du paramètre dans le chemin.

Imaginez par exemple qu'on souhaite changer le nom d'un membre. On pourra procéder comme ceci :

@ApiMethod(
        path = "membre/{anciennom}/{nvnom}",
        httpMethod = HttpMethod.PUT
    )
public Membre updateName(@Named("anciennom") String ancienNom, @Named("nvnom") String nouveauNom) {

    // Modifie le nom du membre...

    return membre;
}

Le chemin sera par exemple http://localhost:8888/_ah/api/monapi/v1/membre/francis/rob pour renommer le membre "francis" en "rob". Comme c'est la coutume dans ce genre d'API, on renvoie l'objet qu'on vient de modifier (le membre avec son nouveau nom).

Dans mon code je n'ai pas mis les appels à la base de données, mais normalement on est censé modifier le nom du membre dans la base !

Attention, cette fois j'utilise la méthode HTTP PUT (et non pas GET). Vous ne pourrez pas tester cette route facilement avec votre navigateur... sauf si vous utilisez un outil spécialisé comme Postman (plugin Google Chrome).

Vous pouvez y insérer l'URL de votre API et modifier la méthode HTTP dans la liste déroulante. Vous y voyez le résultat de votre requête en JSON !

Le plugin Postman pour Google Chrome permet de tester son API
Le plugin Postman pour Google Chrome permet de tester son API

Sachez aussi qu'un outil permettant de tester votre API est directement intégré à App Engine : l'API Explorer ! Vous pouvez y accéder à l'adresse http://localhost:8888/_ah/api/explorer :

L'API Explorer intégré à App Engine
L'API Explorer intégré à App Engine

Maintenant que vous savez générer votre API, jetez un oeil à la doc du côté de la génération d'applications clientes ! Cloud Endpoints vous facilite aussi la vie du côté de l'interface frontend notamment si vous développez une application Android (en Java), iOS (en Objective C) ou Web (en JavaScript).
Cela vous évite d'avoir à écrire tout le code qui récupère et traite le JSON de l'API, ainsi que toute la gestion de l'authentification OAuth 2 !


Google WEEB

Aller plus loin avec App Engine

App Engine est un service en constante évolution. Et quand je dis constante, c'est constante. Vous verrez des services apparaître régulièrement (et parfois certains disparaître ou évoluer, changer de nom...).

Les fonctionnalités que je vous ai présentées dans ce cours sont stables, mais il en existe beaucoup d'autres, parfois stables, parfois nouvelles, qui méritent très souvent le détour. Je voudrais vous les présenter brièvement dans ce chapitre pour que vous ayez une vue d'ensemble de tout ce que peut proposer App Engine. :)

D'autres fonctionnalités d'App Engine à découvrir

Si vous parcourez un peu la doc d'App Engine, vous verrez rapidement qu'elle est très riche en fonctionnalités. Et bien sûr, moi, je n'ai pas le temps de vous détailler chacune d'entre elles (ça prend du temps et elles évoluent régulièrement !).

Je veux au moins que vous ayez une vue d'ensemble. Cette liste est non exhaustive. J'essaierai cependant de la mettre à jour de temps en temps. ;)

Alors, qu'est-ce qu'App Engine a d'autre dans le ventre ?

  • Task Queues : vous permet de gérer une liste de tâches à faire exécuter à App Engine en toile de fond (c'est-à-dire en dehors d'une requête de page de la part du client). Cela vous évite d'avoir à exécuter toutes les requêtes avant de retourner la page à l'utilisateur. Certaines peuvent être effectuées avec un peu de délai, parce qu'elles sont longues et lourdes et il n'est pas toujours indispensable de les exécuter tout de suite. Un exemple ? Si un utilisateur poste sur des forums, vous voudrez peut-être informer les autres lecteurs des forums qu'il y a un nouveau message. Si vous le faites en même temps (de façon synchrone), l'utilisateur ne verra son message posté que quand tout le monde aura été averti. Si vous le faites avec Task Queues (de façon asynchrone), vous pouvez poster le message immédiatement et déléguer la tâche qui consiste à avertir les autres utilisateurs à Task Queues.

  • Backends (sera renommé en "Modules" prochainement) : vous donne accès à des instances de machine plus puissantes pour exécuter des requêtes particulièrement gourmandes (pratique en combinaison de Task Queues !). Les instances peuvent avoir jusqu'à 1 Go de RAM (normalement assez pour traiter une requête utilisateur !) et un CPU de 4,8 Ghz.

  • Search API : vous permet d'effectuer des recherches précises en utilisant la puissance du moteur de recherche de Google au sein de votre Datastore. L'API est capable de chercher du texte, du HTML, des nombres, des dates, des positions géographiques...

  • Prospective Search API : un moteur de recherche temps réel. Par exemple, vous pouvez faire une recherche sur des flux Twitter, sur des sessions de tchat, etc. Le moteur vous retourne les résultats dès qu'ils apparaissent. Pratique pour faire du monitoring global, de la recherche big data, etc.

  • Sockets API : permet une communication temps réel bas niveau via les sockets. Cela vous permet d'envoyer des paquets TCP et UDP pour, par exemple, gérer un tchat en ligne ou un jeu en réseau qui évolue en temps réel.

  • Channel API : permet de gérer une connexion persistante entre le navigateur du client et les serveurs de Google, pour faire des mise à jour en temps réel sans avoir à recourir à une technique de polling (qui consiste à demander toutes les quelques secondes si le serveur a du nouveau, ce qui n'est pas très efficace). Peut être combiné avec la sockets API.

  • URL Fetch : API très simple qui permet de récupérer un document sur Internet en HTTP ou HTTPS. Oui oui, c'est aussi bête que ça, mais il y en a besoin.

  • Namespace API : permet de compartimenter les données de votre site dans différents namespaces (espaces de nom). L'API peut compartimenter les données du Datastore, du Memcache et des Task Queues.

Au-delà des APIs, il y a des fonctionnalités globales à App Engine que vous devriez regarder. Par exemple :

  • Vous pouvez ajuster la performance de l'application en modifiant la puissance des machines utilisées pour traiter les requêtes. Vous pouvez notamment ajuster le nombre d'instances "dormantes" que vous utilisez : ces instances vous coûtent de l'argent en continu mais permettent à votre site d'être plus réactif dès qu'il y a un pic de visiteurs.

  • Vous pouvez utiliser le service PageSpeed qui optimise automatiquement la performance frontend de vos applications. Il réduit le poids des fichiers .css, .js et des images à la volée, et fait tout un tas d'optimisations globalement pour que le site se charge plus vite.

  • Vous pouvez tester de nouvelles fonctionnalités sur votre site de façon progressive avec du traffic splitting (découpage de votre trafic qui permet de faire de l'A/B Testing). Vous pouvez par exemple décider que 10% des visiteurs voient la nouvelle version de votre site, pour avoir des retours et améliorer rapidement votre site.

Comme vous le voyez, App Engine en a encore sous le capot. :soleil:

Google Cloud Platform

N'oubliez pas que Google App Engine est un sous-élément de... Google Cloud Platform. Nous venons de voir un des services de cloud de Google (pas un des moins importants je vous l'accorde ;) ).

Google Cloud Platform
Google Cloud Platform

Vous connaissez déjà une bonne partie de ces services car ils sont intégrés à App Engine, mais il faut savoir qu'il est aussi possible de les utiliser de façon indépendante (sans avoir besoin de développer sur App Engine). Voici une liste des produits actuellement disponibles sur Google Cloud Platform :

  • Compute Engine : permet de commander des serveurs que l'on peut entièrement gérer (comparable à Amazon EC2). Contrairement à App Engine, cette fois vous avez un accès SSH root sur les machines.

  • Cloud Storage : permet le stockage de grandes quantité de fichiers en ligne.

  • BigQuery : permet d'effectuer des requêtes sur de très grands ensembles de données.

  • Cloud SQL : permet de disposer d'un serveur SQL entièrement configuré.

  • Prediction API : utilise les fonctionnalités d'apprentissage des machines à partir de grandes quantités de données pour... prédire le futur. Brrr...

  • Translate API : permet d'obtenir des traductions automatiques.

Amusez-vous bien ! :D

Il vous reste un dernier quiz à faire pour conclure cette partie ! Rendez-vous dans le plan principal du cours :-).


Accueil

Accueil CHM


Tutoriel WEB

Développement Web : "Zone Grand Débutant"

  • I. Introduction
    • I-A. Remerciements
    • I-B. Préambule
    • I-C. Analogies
      • I-C-1. Tableur (pour feuilles de calcul)
      • I-C-2. Traitement de texte
      • I-C-3. Conclusion

I. Introduction

I-A. Remerciements

Mes plus sincères remerciements vont à toute l'équipe Web/PHP, en particulier aux rédacteurs des tutoriels et des tests dont je parle ici.

I-B. Préambule

Lorsque l'on souhaite créer des pages Web, il y a de très nombreuses manières d'arriver au but. Nous allons voir ici comment utiliser les technologies de manière simple et efficace.

Il s'agit ici d'un cours pour débutants. Nous n'aborderons pas de techniques complexes dans les tutoriels.

Cette introduction peut sembler courte mais je préfère y aller pas à pas : je vous donnerai une introduction spécifique dans chaque partie.

I-C. Analogies

Une page Web est un document. Elle est enregistrée sur le disque du serveur, et affichée par le navigateur Web. Le navigateur Web affiche le contenu du fichier enregistré sur le serveur après l'avoir interprété, il offre donc une interprétation du fichier. J'aimerais mettre ici en avant une terminologie que j'affectionne : le fichier est sur le disque dur, tandis que le document est affiché par le navigateur. Les termes "fichier" et "document" font référence au même élément, mais ils ne désignent pas la même vision de cet élément. Voyons deux exemples qui nous sont familiers : un tableur et un traitement de texte.

I-C-1. Tableur (pour feuilles de calcul)

Peut-être connaissez-vous le format CSV très souvent utilisé avec les tableurs comme Excel ? Il s'agit de fichiers de texte contenant des données respectant un format particulier : elles sont séparées par des points virgules ou par des tabulations. Un outil comme Microsoft Office Excel ou bien OpenOffice.org Calc vous permettent d'ouvrir un fichier CSV en découpant les lignes en cases.

Dans ce fichier CSV, les règles sont :
  • Les colonnes sont séparées par des point virgules ;
  • Les lignes sont délimitées par des sauts de ligne.

Aperçu dans Notepad :

Image non disponible

Aperçu dans MS Office Excel :

Image non disponible

Aperçu dans OpenOffice Calc :

Image non disponible

Nous pouvons remarquer un détail intéressant : Notepad, qui n'est pas prévu pour comprendre la syntaxe (le format) des documents CSV, nous affiche le contenu brut du fichier. En revanche, Excel et Calc connaissent la syntaxe CSV et permettent de voir le document en tant que tel plutôt que le code source du fichier.

I-C-2. Traitement de texte

Prenons maintenant un fichier .rtf (Rich Text File), un format de document texte formaté compatible avec tous les processeurs de texte.

Le format RTF étant bien plus complexe que le format CSV, je ne vais pas le détailler ici.

Aperçu dans Notepad :

Image non disponible

Aperçu dans MS Office Word :

Image non disponible

Aperçu dans OpenOffice Writer :

Image non disponible

La conclusion est ici encore plus évidente que pour le format CSV : Notepad affiche le contenu du fichier, tandis que Word et Writer affichent le document. De plus, RTF étant un format standard, la mise en forme est la même dans les deux outils de traitement de texte. Ici, le titre est centré dans la page, coloré en bleu et d'une taille plus grosse que le texte ; le texte normal est en noir, aligné à gauche.

Retenez cette notion importante : le respect des standards permet d'afficher le même document de la même manière, quel que soit l'outil utilisé pour le consulter. Je terminerai donc chaque partie de ce tutoriel par un lien vers l'organisme de référence ayant défini le format de fichier de la technologie.

I-C-3. Conclusion

De très nombreux documents sont enregistrés en tant que fichiers et selon un format bien défini. Les fichiers ne sont pas toujours lisibles dans leur format brut, c'est pourquoi nous utilisons des outils comme Microsoft Office ou OpenOffice.org pour nous faciliter la tâche.

Le développement Web est fondamentalement le même principe : proposer à l'internaute des documents qui sont en fait des fichiers au format HTML. Le navigateur Web (Internet Explorer, Firefox, Opera...) est l'outil qui sert à l'internaute pour visualiser ces documents, car le code source des documents n'est pas prévu pour être lu par un humain. Le code source des documents est prévu simplement pour définir ce que contient le document et comment ce contenu doit être affiché dans le navigateur. Nous verrons que, tout comme pour les formats CSV et RTF il existe des standards qu'il faut respecter pour que tous les navigateurs affichent vos documents de la même manière.

Trois notions fondamentales :
  • Le format décrit la syntaxe du code source (= le fichier) ;
  • Le document est le fichier affiché (= traduit) et lisible par l'utilisateur ;
  • L'outil permet d'interpréter le fichier en fonction de son format afin de l'afficher à l'utilisateur.


Tutoriel WEB

Développement Web : "Zone Grand Débutant"

  • II. HTML : Structurer le document
    • II-A. Introduction
      • II-A-1. Vue d'ensemble
      • II-A-2. Organisation d'un fichier HTML
    • II-B. Terminologie
      • II-B-1. Balise
      • II-B-2. Attribut
    • II-C. Outils nécessaires
    • II-D. Votre premier document HTML
    • II-E. Formation
      • II-E-1. Organisme de référence en HTML
      • II-E-2. Nos ressources habituelles
      • II-E-3. Notre sélection de cours :
        • Cours sur les formulaires en HTML
        • Div et CSS : une mise en page rapide et facile
        • Écrire du bon code HTML
        • Introduction à l'XHTML
    • II-F. Les limites du HTML

II. HTML : Structurer le document

II-A. Introduction

Les trois notions fondamentales :
  • Le fichier est au format HTML ;
  • Le document est à destination de l'internaute ;
  • L'outil est un navigateur Web.

II-A-1. Vue d'ensemble

Le HTML (HyperText Markup Language) est le "langage" qui permet à un navigateur Web d'afficher un document Web selon une certaine structure. Il ne s'agit pas d'un langage à proprement parler (dans le sens "interprété" ou "compilé") mais plutôt d'un format de document.

Une page Web est généralement écrite dans un fichier en HTML (ou assimilé). Ce fichier est en fait du texte, formaté en suivant certaines règles. Ainsi, lorsqu'un fichier HTML est ouvert avec Notepad, on voit du code HTML pur ; en revanche, lorsque l'on utilise un navigateur Web, on voit au contraire un document correctement présenté : le navigateur Web interprète le code HTML pour présenter le document Web à l'internaute.

Exemple de code source HTML :
Sélectionnez
<!DOCTYPE HTML PUBLIC
    "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>Hello World!</title>
</head>
<body>
    <h1>Hello World!</h1>
    <p>Un bonjour de Yogui ;)</p>
</body>
</html>

Aperçu dans Internet Explorer 7 :

Image non disponible

Aperçu dans Firefox 2 :

Image non disponible

L'on peut remarquer ici la même chose qu'avec mes exemples précédents : le format HTML de mon fichier permet d'afficher le document de la même manière dans les deux navigateurs. C'est rendu possible par le langage HTML, un standard au même titre que RTF.

II-A-2. Organisation d'un fichier HTML

Un fichier HTML contient principalement deux parties : l'en-tête et le corps.

Sélectionnez
<html>
    <head></head>
    <body></body>
</html>

L'en-tête (head) est une succession de balises (tags) permttant au navigateur Web de savoir de quoi il s'agit. On peut y trouver un résumé de la page, les mots clefs principaux, le titre pour la fenêtre, la fréquence de mise à jour, etc.

Le corps (body) est constitué du contenu du document. On y trouve habituellement des divisions (div), des paragraphes (p), des images (img), etc.

Le HTML est un format structuré. Chaque balise peut en contenir d'autres, de manière hiérarchique. Dans le document vu plus haut, l'en-tête contient un titre principal tandis que le corps contient un titre de niveau 1 et un paragraphe.

Il est primordial de comprendre que chaque balise a une signification particulière. Utiliser les bonnes balises au bon moment permet d'obtenir des documents affichés sans surprises dans tous les navigateurs du marché. En revanche, utiliser incorrectement les balises peut donner des résultats imprévisibles... Reportez-vous toujours à la documentation officielle pour savoir comment utiliser les balises ; les tutoriels sont là pour vous aider à comprendre la documentation officielle (qui est malheureusement souvent indigeste).

Lorsque vous souhaitez ajouter un élément à votre document, pensez à sa signification. Chaque type de contenu dispose d'une balise en HTML : si c'est du texte, il s'agit probablement d'un paragraphe ; si vous commencez un chapitre composé d'un titre et de paragraphes, alors vous êtes en train de diviser votre document ; un titre est de niveau 1, 2, 3, etc. suivant sa hiérarchie. Je vous recommande de construire votre document de la même manière que vous construisez un document avec un traitement de texte : pensez au type de contenu que vous souhaitez mettre et utilisez les balises en fonction de cela.

II-B. Terminologie

II-B-1. Balise

En HTML, les informations sont organisées à l'aide de "balises". Une balise permet de contenir quelque chose, par exemple "un lien", "un paragraphe", etc. La balise se caractérise par un mot encadré des signes inférieur < et supérieur > comme par exemple <b>, <body>, etc. Les balises HTML vont généralement par paire : l'une ouvre, l'autre referme et ce qui est situé entre les deux balises est affecté. Toutes les balises de la page sont organisées de manière hiérarchique.

Il faut penser à cette hiérarchie car c'est très important. Par exemple, il est fondamental de refermer les balises dans l'ordre inverse de leur ouverture. La première balise ouverte englobe toutes les autres, elle est la dernière à être refermée. La dernière balise ouverte a une durée de vie plus courte car elle est refermée avant toutes les autres.

La balise ouvrante est la balise permettant de délimiter le début, et la balise fermante délimite la fin. Dans le cas d'un titre, "<h1>" est une balise ouvrante et "</h1>" est la balise fermante correspondante.

Ordre de fermeture non respecté :
Sélectionnez
<b><i>du texte en gras italique...</b></i>
Ordre correct :
Sélectionnez
<b><i>du texte en gras italique...</i></b>

Une balise HTML est très simple : le signe "inférieur" < suivi de quelques lettres et enfin du signe "supérieur" >. Si la balise est double (c'est souvent le cas) car elle doit contenir quelque chose, alors la balise fermante est très similaire à la balise ouvrante : < suivi d'une barre oblique / puis des quelques lettres (les mêmes que pour la balise ouvrante) et enfin >.

Le corps du document est une balise double :
Sélectionnez
<body>
...
...
...
</body>
Un titre est une balise double :
Sélectionnez
<h1>...</h1>

Les balises ayant du contenu doivent être hiérarchisées car elles vont par paires. En revanche, les balises simples n'ont pas cette contrainte.

Un passage à la ligne est une balise simple (sans contenu) :
Sélectionnez
<br/>
Une ligne de séparation est une balise simple (sans contenu) :
Sélectionnez
<hr/>

L'identifiant d'une balise ("body" ou bien "h1" par exemple) peut être écrit en minuscules, majuscules ou un mélange des deux mais il est fortement recommandé d'utiliser systématiquement les minuscules.

II-B-2. Attribut

En grammaire, le sens d'un nom commun peut être précisé par des compléments. En HTML, une balise peut être complétée par des attributs. Une "balise" correspond à un "nom commun" dont le sens peut être précisé par des "attributs" (ses "compléments").

Toutes les balises HTML peuvent contenir un ou plusieurs attributs. Ce sont comme des paramètres, des éléments qui nous permettent de préciser le comportement des balises. Par exemple, la balise "lien" peut être précisée au moyen des attributs "destination" et "titre".

Certaines balises ont des attributs obligatoires. Certains attributs sont spécifiques à certaines balises, tandis que d'autres peuvent être mis dans n'importe quelle balise HTML.

Simplement à titre d'exemple, voici quelques attributs que nous verrons très souvent :
  • href : Principalement dans les liens ;
  • title : Principalement dans les liens ;
  • src : Principalement dans les images ;
  • id : Pour n'importe quelle balise, il est utile pour CSS et JavaScript (cf. plus loin) ;
  • name : Dans les contrôles des formulaires.
Un lien appelé 'Description' et renvoyant vers 'page.html' :
Sélectionnez
<a href="page.html" title="Description">lien</a>
Une image appelée 'Nom du logo' ayant comme source 'images/logo.jpg' :
Sélectionnez
<img src="images/logo.jpg" alt="Nom du logo"/>

La valeur d'un attribut s'écrit entre guillemets ou bien entre apostrophes. Je vous recommande les guillemets car cela pose moins de problèmes.

II-C. Outils nécessaires

Tout comme pour les fichiers CSV que j'évoquais plus haut, n'importe quel éditeur de texte peut être utilisé pour créer des pages en HTML. Notepad est suffisant si vous êtes sous Windows mais je vous recommande l'un des outils décrits dans notre page Outils (X)HTMLLes meilleurs outils pour développer en (X)HTML.

Pour visualiser un document HTML, n'importe quel navigateur Web fait l'affaire : Internet Explorer, Firefox, Opera, etc.

II-D. Votre premier document HTML

Créez le fichier suivant, puis ouvrez-le avec votre navigateur Web (double clic sur le nom du fichier) :

index.html
Sélectionnez
<html>
<head>
    <title>Hello world</title>
</head>
<body>Hello World, I am Yogui!</body>
</html>

Le navigateur Web vous affiche une page contenant les mots "Hello World, I am Yogui!" et dont la barre de titre contient simplement "Hello World".

Je ne vous présente ici que le strict minimum afin d'obtenir du HTML reconnu à peu près correctement par votre navigateur Web. En situation réelle, il vous faudra respecter les standards tels que le W3C (World Wide Web Consortium) les a définis. Pour faire du véritable code HTML ou XHTML, je vous recommande la lecture de tutoriels plus complets (cf. la liste ci-dessous).

Tout le contenu d'un document HTML se trouve à l'intérieur de la balise <body>.

Ainsi, je vous ai indiqué la structure d'une page Web. En effet, le HTML sert principalement à une chose : structurer un document. Bien que ce soit possible, il est préférable d'éviter de mettre en forme le document au moyen de HTML : ce sera le travail de CSS (cf. plus loin).

Pour faire une page bien présentée, vous pouvez utiliser les balises suivantes :
  • <center> : Le texte est centré dans la page (balise double) ;
  • <font color=""> : Changement de la couleur du texte (balise double) ;
  • <font size=""> : Changement de la taille du texte (balise double) ;
  • <b> ou <strong> : Le texte est mis en gras (balise double) ;
  • <i> ou <em> : Le texte est mis en italique (balise double) ;
  • <u> : Le texte est souligné (balise double) ;
  • <h1> ou <h2> (jusqu'à h6) : Un titre dans la page (balise double) ;
  • <br/> : Passage à la ligne (balise simple).

Ces balises sont à utiliser avec beaucoup de précautions : il s'agit ici de vous enseigner à faire du HTML qui donne un résultat mais, en situation réelle, il convient d'utiliser les technologies correctes (en l'occurence, beaucoup de CSS). Nous reviendrons par la suite sur tout cela.

Un élément fondamental à savoir faire en HTML est un lien hypertexte. Cela donne au visiteur de votre site la possibilité de consulter une autre page, qu'elle soit sur votre site ou ailleurs.

Des liens :
Sélectionnez
<a href="http://www.site.ext/dossier/page-1.html">Texte affiché dans le lien</a>
<a href="page-2.html">Autre lien</a>

Il faut aussi savoir comment insérer une image dans votre page Web. Cela se fait au moyen d'une balise simple, en une seule partie (il n'y a pas de </img>).

Insérer des images :
Sélectionnez
<img src="http://www.site.ext/dossier/images/logo.jpg"/>
<img src="images/logo.jpg"/>

Pour les liens et les images, ce qui est dans l'attribut href ou src est ce que l'on appelle une URL (ou bien URI). Elle peut être absolue (avec le http:// et l'adresse du site) ou bien relative. Je vous recommande d'utiliser des adresses relatives tant que possible.

Puisque le HTML permet principalement de définir la structure d'un document (contrairement à la manière dont il est présenté), les navigateurs Web ignorent tous les passages à la ligne ainsi que les espaces (en double) insérés dans le code source. Cela vous permet de présenter votre code source HTML de manière à le rendre lisible, sans que cela ait d'impact sur le document final affiché par le navigateur. Les deux exemples suivants produisent le même affichage :

Exemple 1
Sélectionnez
<html><body>Hello world, I am Yogui!<br/>Ceci est un test.</body></html>
Exemple 2
Sélectionnez
<html>
    <body>
        Hello world, I am Yogui<br/>
        Ceci est un test.
    </body>
</html>

II-E. Formation

II-E-1. Organisme de référence en HTML

L'organisme de référence est le World Wide Web Consortium (W3C).

II-E-2. Nos ressources habituelles

  • La FAQ (X)HTML répond à vos questions posées dans nos forums ;
  • Les tutoriels (X)HTMLLes meilleurs cours (X)HTML vous permettront d'apprendre tout ce dont vous avez besoin ;
  • Les livres (X)HTMLLes meilleurs livres (X)HTML critiqués par la Rédaction pour toujours avoir une référence sous le coude ;
  • Les forums HTML, général conception Web et outils de développement Web vous permettent de poser toutes vos questions qui ne trouvent pas réponse dans nos autres ressources.

II-E-3. Notre sélection de cours :

Cours sur les formulaires en HTML

J'ai rédigé un cours complet sur les formulairesTutoriel HTML & PHP : les formulaires accessible à tous les lecteurs. Il vous guidera depuis vos premiers pas jusqu'à leur exploitation. Attention, il vous faut avoir des connaissances en PHP pour exploiter pleinement les formulaires (cf. plus loin), mais vous pouvez dès à présent vous renseigner sur leur fonctionnement.

Div et CSS : une mise en page rapide et facile

Pierre-Baptiste Naigeon vous propose un cours de mise en page au moyen de la balise HTML <div>. Les plus débutants d'entre vous n'ont pas besoin de s'en soucier, néanmoins il peut être intéressant à lire par tout le monde.

Écrire du bon code HTML

Voici un tutoriel que je citerai à plusieurs reprises...

Adrien Pellegrini a compilé pour vous les bonnes pratiques de développement en HTML.

Introduction à l'XHTML

Adrien Pellegrini vous présente le XHTMLIntroduction à l'XHTML (une évolution de HTML) en long et en large.

II-F. Les limites du HTML

Bien qu'il existe des outils très puissants pour créer des pages en HTML, il serait fastidieux de créer manuellement, une à une, toutes les pages d'un catalogue de produits. L'outil informatique existe pour nous faciliter la tâche, en particulier les tâches répétitives. Nous verrons plus loin que le HTML est en fait un objectif : c'est un document que nous allons créer à l'aide d'un langage de script situé sur le serveur. En général, nous ne créons pas intégralement de document HTML sans utiliser un langage de script. Suivant la terminologie que vous préférez, le HTML est habituellement un patron (couture), un moule (cuisine) ou encore un gabarit (c'est le terme adéquat).


Tutoriel WEB

Développement Web : "Zone Grand Débutant"

  • III. CSS : Présentation du document
    • III-A. Introduction
    • III-B. Outils nécessaires
    • III-C. Votre premier style
    • III-D. Formation
      • III-D-1. Organisme de référence
      • III-D-2. Nos ressources habituelles
      • III-D-3. Notre sélection de cours
        • CSS : Notions de base
        • Div et CSS : une mise en page rapide et facile
        • Écrire du bon code CSS

III. CSS : Présentation du document

III-A. Introduction

Les trois notions fondamentales :
  • Le fichier est au format CSS ;
  • Le document est à destination de l'internaute ;
  • L'outil est un autre document (une page Web HTML).

Les CSS (Cascading Style Sheet = feuille de styles) sont des documents au format texte, tout comme le HTML. La différence est qu'une CSS n'est prévue ni pour être visualisée par l'internaute ni pour être affichée directement dans le navigateur. Une feuille de styles n'est qu'un document qui définit comment une page HTML doit être affichée. Le navigateur Web s'occupe de charger la CSS sans que l'internaute doive intervenir ; une CSS a pour vocation d'agir en arrière plan.

En utilisant des styles, il est par exemple possible de dire que tous les liens, au lieu d'être bleus ou violets comme on en a l'habitude, doivent être gris ; ou bien que le texte est toujours orange.

En fait, l'idée est que le navigateur parcourt le document HTML. Lorsqu'il rencontre une balise, il demande à la CSS de quelle manière il doit l'afficher. La CSS ne sait rien faire d'autre que dire comment doit être affiché tel ou tel élément de la page Web.

Les CSS sont l'un des éléments qui constituent le DHTML : Dynamic HTML.

III-B. Outils nécessaires

Pour créer des feuilles de style, vous pouvez utiliser les mêmes outils que pour vos documents HTML. Vous n'avez besoin de rien pour les visualiser puisque ce n'est pas l'objectif : leur utilité est d'être combinées aux documents HTML. Votre navigateur Web sait ce qu'il doit faire des CSS. N'hésitez pas à consulter notre page d'Outils CSSLes meilleurs outils pour développer en CSS.

III-C. Votre premier style

Il y a trois manières de définir des styles dans une page Web. La plus simple est d'utiliser l'attribut style de la balise que l'on veut modifier.

Exemple :
Sélectionnez
<h1 style="font-style: italic; size: 1.5em;">Titre de la page</h1>

À l'intérieur de l'attribut style, il est possible de mettre n'importe quelle quantité de propriétés CSS : zéro, une, autant que l'on veut. L'ordre dans lequel on met ces propriétés influe rarement, nous n'allons donc pas nous en occuper pour le moment.

Un style s'écrit de la manière suivante : identifiant (nom du style) suivi de deux points, de la valeur et d'un point virgule. Dans l'exemple ci-dessus, nous avons les propriétés "font-style" et "size" avec les valeurs (respectivement) "italic" et "1.5em".

L'attribut style que je viens d'utiliser peut être ajouté à n'importe quelle balise HTML.

III-D. Formation

III-D-1. Organisme de référence

L'organisme de référence est le World Wide Web Consortium (W3C).

III-D-2. Nos ressources habituelles

  • La FAQ CSS répond à vos questions posées dans nos forums ;
  • Les tutoriels CSSLes meilleurs cours CSS vous permettront d'apprendre tout ce dont vous avez besoin ;
  • Les livres CSSLes meilleurs livres CSS critiqués par la Rédaction pour toujours avoir une référence sous le coude ;
  • Le forum CSS vous permet de poser toutes vos questions qui ne trouvent pas réponse dans nos autres ressources.

III-D-3. Notre sélection de cours

CSS : Notions de base

Pierre-Baptiste Naigeon vous présente son utilisation des CSS dans les pages Web avec son cours d'initiationTutoriel CSS : Notions de base.

Div et CSS : une mise en page rapide et facile

Pierre-Baptiste a également prévu pour vous un tutoriel vous enseignant à moins utiliser la balise <table> : utilisez la balise <div> pour structurer vos documents.

Écrire du bon code CSS

Adrien Pellegrini a parlé des feuilles de style dans son guide : style de programmation.


Tutoriel WEB

Développement Web : "Zone Grand Débutant"

  • IV. JavaScript : Dynamisme du document
    • IV-A. Introduction
    • IV-B. Outils nécessaires
    • IV-C. Vos premiers scripts JS
    • IV-D. Formation
      • IV-D-1. Organisme officiel
      • IV-D-2. Nos ressources habituelles
      • IV-D-3. Notre sélection de cours
        • Introduction à JavaScript
        • JavaScript dans les formulaires
        • Conseils d'écriture du code
        • Comparatif PHP/Javascript
    • IV-E. Les dangers de JavaScript

IV. JavaScript : Dynamisme du document

IV-A. Introduction

Les trois notions fondamentales :
  • Le fichier est au format JavaScript ;
  • Le document (ou programme) est à destination de l'internaute ;
  • L'outil est un navigateur Web.

Le code JavaScript est interprété par le navigateur Web (s'il n'est pas trop préhistorique et si sa configuration ne l'a pas désactivé).

Je viens déjà de vous présenter un inconvénient de JS : il peut être désactivé. Néanmoins sachez que c'est ce langage qui est derrière l'acronyme AJAX... JavaScript est donc fondamental dans le développement des sites Web d'aujourd'hui (de type Web 2.0), à savoir des sites qui ne se contentent pas d'afficher des pages Web mais qui demandent à l'internaute de s'impliquer, de participer, voire des sites qui s'adaptent au profil de leurs visiteurs.

Incruster du code JS dans une page Web permet à la page de réagir aux actions de l'internaute, par exemple "la souris survole tel bouton" ou encore "le formulaire vient d'être envoyé". Ainsi, nous pouvons utiliser JavaScript pour attraper des évènements et agir en conséquence.

ActionScript 3, la dernière version du langage de script pour Flash, utilise une syntaxe quasiment identique à celle de JavaScript.

IV-B. Outils nécessaires

Pour développer en JavaScript, il est recommandé d'avoir un éditeur de code plus puissant que ceux recommandés au début de cet article (avoir la documentation du langage à portée de main commence à devenir une condition importante). Cependant, surtout dans vos débuts, vous pourrez vous contenter de rechercher sur Internet et d'utiliser des codes sources déjà existants, en les adaptant à vos besoins.

En clair, il vous faut un bon éditeur de code + la documentation officielle + une bonne FAQ (cf. les liens ci dessous).

Un bon outil de développement JavaScript est AptanaSite officiel d'aptana, dans la famille d'Eclipse.

IV-C. Vos premiers scripts JS

Le code JavaScript doit être appelé depuis un attribut situé dans une balise HTML. Le nom de l'attribut utilisé commence par "on" et se poursuit par l'évènement désiré (exemples : onload, onsubmit, onmouseover, etc.).

Exemple d'action au chargement de la page Web :
Sélectionnez
<html>
<body onload="alert('Hello world!');"></body>
</html>

JavaScript est très souvent utilisé pour gérer des formulaires en ligne. Je ne compte pas vous montrer ici une utilisation complète mais j'espère que mes exemples vous donneront une vision d'ensemble.

Envoyer le formulaire uniquement si le nom d'utilisateur n'est pas vide :
Sélectionnez
<html>
<body>
<form onsubmit="if(document.getElementById('login').value == ''){ return false; } else{ return true; }">
    Nom d'utilisateur : <input type="text" id="login"/><br/>
    Mot de passe : <input type="text" id="password"/><br/>
    <input type="submit"/>
</form>
</body>
</html>

Oui, bien sûr, ce n'est ni proprement écrit ni facile à lire... Il faut bien voir que nous commençons à voir des techniques un peu plus complexes que HTML et CSS, il faut donc commencer à bien s'organiser.

Envoyer le formulaire uniquement si le nom d'utilisateur n'est pas vide + avertir l'internaute :
Sélectionnez
<html>
<head>
    <script type="text/javascript">
    function checkForm()
    {
        if(document.getElementById("login").value == "")
        {
            alert("Formulaire invalide : le nom d'utilisateur est vide");
            return false;
        }
        else
        {
            alert("Le formulaire est valide");
            return true;
        }
    }
    </script>
</head>
<body>
<form onsubmit="return checkForm();">
    Nom d'utilisateur : <input type="text" id="login"/><br/>
    Mot de passe : <input type="text" id="password"/><br/>
    <input type="submit" value="Envoyer"/>
</form>
</body>
</html>

Ici, le comportement de notre page Web est bien plus évident. Lorsque l'évènement onsubmit est déclenché par le formulaire (c'est-à-dire que l'internaute a validé le formulaire), la fonction checkForm() vérifie si le champ "login" est rempli. Si c'est bon, le formulaire est transmis ; sinon, il n'est pas envoyé.

Cela permet d'éviter d'envoyer des informations au serveur lorsque l'on sait qu'elles sont incomplètes, et ainsi d'éviter à l'internaute d'attendre que le serveur réponde. Ici, c'est le navigateur qui se charge de tout vérifier.

Ici encore, je vous ai proposé un exemple minimaliste. En situation réelle, il faut notamment utiliser les attributs "id" et "name" des contrôles du formulaire : j'en parle plus en détail dans mon cours sur les formulaires (cf. les liens en bas de page)

Sécurité
Dans l'exemple ci-dessus, le serveur Web ne doit pas partir du principe que tout formulaire reçu a été validé : ce serait une erreur grave. Le code JavaScript présenté ici sert uniquement à accélérer l'arrivée des réponses données à l'utilisateur ; il ne permet pas d'assurer que 100% des formulaires transmis sont valides.

IV-D. Formation

IV-D-1. Organisme officiel

Depuis que la fondation Mozilla a repris le développement du navigateur Netscape, elle a repris également le langage JavaScript.

La fondation Mozilla met à disposition la RéférenceRéférence JS 1.5 et le GuideGuide JS 1.5 de JavaScript 1.5, deux collections à toujours garder à portée de main.

IV-D-2. Nos ressources habituelles

  • La FAQ JavaScript et la FAQ AJAX répondent à vos questions posées dans nos forums ;
  • Les sources JavaScript vous donnent des codes permettant de résoudre des problématiques précises ;
  • Les tutoriels JavaScriptLes meilleurs cours CSS vous permettront d'apprendre tout ce dont vous avez besoin ;
  • Les livres JavaScriptLes meilleurs livres CSS critiqués par la Rédaction pour toujours avoir une référence sous le coude ;
  • Le forum JavaScript et le forum AJAX vous permettent de poser toutes vos questions qui ne trouvent pas réponse dans nos autres ressources.

IV-D-3. Notre sélection de cours

Introduction à JavaScript

Serge P. vous présente le langage JavaScript de manière très didactique et complète.

JavaScript dans les formulaires

Dans mon cours sur les formulaires, j'ai présenté une méthode simple de validation de formulaire au moyen de JavaScript.

Conseils d'écriture du code

Adrien Pellegrini a également couvert le langage JavaScript dans son guide de styleConseils d'écriture du code javaScript.

Comparatif PHP/Javascript

PHP et JavaScript étant très souvent confondus, Julp vous a préparé un tableau comparatif qui ne vous laissera plus aucun doute sur leurs différences.

IV-E. Les dangers de JavaScript

Ce paragraphe n'est qu'une reformulation de ce que j'ai déjà évoqué plus haut. Il est absolument fondamental que tout développeur ait parfaitement conscience de tous ces dangers.

Puisque JavaScript permet de vérifier certaines informations envoyées par l'internaute, la tentation est forte de faire confiance à une page Web dont on sait que du code JS effectue ces vérifications. Cependant, il faut bien se souvenir que la majorité des navigateurs Internet peuvent désactiver le JavaScript, ce qui rend ces précautions inutiles (tout du moins du point de vue sécurité). Par conséquent, JavaScript ne doit être utilisé que pour améliorer l'expérience utilisateur, pas pour la sécurité. Si un champ est vérifié par JS, il doit impérativement l'être à nouveau par le script de destination côté serveur.

J'insiste : JavaScript est à utiliser exclusivement pour faciliter la navigation dans votre site.


Tutoriel WEB

Développement Web : "Zone Grand Débutant"

  • V. PHP : Dynamisme du contenu
    • V-A. Introduction
    • V-B. Analogie
    • V-C. Outils nécessaires
    • V-D. Vos premiers scripts PHP
      • V-D-1. Introduction
      • V-D-2. Découvrir les variables
      • V-D-3. Découvrir les inclusions
    • V-E. Avertissement : ce que PHP n'est pas
    • V-F. Formation
      • V-F-1. Organisme officiel
      • V-F-2. Nos ressources habituelles
      • V-F-3. Notre sélection de cours
        • Comparatif PHP/Javascript
        • Guide de style
        • Les formulaires et PHP5
        • Les sessions PHP
      • V-F-4. Nos tests d'EDI
        • PHPEclipse : Programmez librement pour le Web
        • PHPEdit, un IDE complet pour PHP
        • Test complet de l'éditeur WebExpert de Visicom

V. PHP : Dynamisme du contenu

V-A. Introduction

Les trois notions fondamentales :
  • Le fichier est au format PHP ;
  • Le document est habituellement au format HTML et à destination du navigateur Web (qui se chargera de le transmettre à l'internaute) ;
  • L'outil est le serveur Web avec l'exécutable PHP.

Vous est-il déjà arrivé de créer toute une suite de documents HTML pour faire une galerie de photos ou un catalogue de produits ? Vous en conviendrez, c'est fastidieux...

Eh bien, la solution existe : un langage de script tel que PHP !

À l'origine, PHP fut créé par Rasmus Lerdorf pour ses besoins personnels : Personal Home Page (version 1). Depuis, le nom fut changé à Hypertext Preprocessor (ce qui présage de son utilité principale : créer dynamiquement des documents HTML). Depuis le 2 novembre 2006, PHP est en version 5.2 ; la branche 5.3 est diponible depuis le 30 juin 2009 ; la version 6 est reportée à une date encore inconue.

V-B. Analogie

Lorsque vous êtes dans un bar parisien, vous commandez votre boisson au serveur qui s'occupe d'aller la chercher au comptoir et de vous l'apporter. Vous pouvez alors consommer votre boisson.

Sur Internet, il se passe quelque chose de similaire : lorsque vous êtes dans un site Web, vous cliquez sur des liens pour consulter des documents. Le serveur Web reçoit vos demandes, s'occupe de rechercher le document voulu et vous l'envoie afin que vous puissiez le lire (c'est la consommation).

Dans le cas de scripts PHP, la "recherche" du document s'accompagne de ce que l'on appelle son "interprétation". Dans l'exemple du bar parisien, vous ne demandez pas systématiquement un "jus d'ananas" que le serveur se contente d'ouvrir devant vous : parfois, vous demandez un "café au lait" qui lui demande un peu de préparation. En fait, dans ce cas, ce n'est pas le serveur qui prépare la boisson : il sous traite votre demande à un collègue car cela lui prendrait trop de temps de le faire lui-même, or il a d'autres clients à servir.

Là encore, il se passe la même chose dans l'environnement Web. Lorsque le serveur Web reçoit une demande de document, il sous traite la tâche à PHP afin de pouvoir retourner à ses affaires : c'est PHP (et non le serveur Web) qui s'occupe de construire le document. Une fois qu'il est prêt, le document est envoyé de PHP au serveur Web, puis du serveur Web au navigateur Internet (c'est-à-dire à vous, l'internaute).

V-C. Outils nécessaires

Afin de programmer en PHP, il est fondamental d'utiliser un véritable EDI tel que PHPEditTest d'EDI pour PHP : PHPEdit ou PHPEclipse. Ces outils vous permettront d'être efficace. Toutefois, de nombreux développeurs continuent à utiliser des éditeurs simples comme Notepad++.

Avec l'expérience, vous verrez ce qui vous convient le mieux...

À part d'un logiciel d'édition de code et de votre navigateur Internet, vous aurez besoin d'un serveur Web. Apache est le plus connu d'entre eux mais il n'est pas toujours facile à installer, c'est pourquoi dans un premier temps je vous recommande WAMP Server, XAMPP (ce dernier ayant le mérite de très bien s'intégrer dans PHPEclipse) ou encore Zend Core (validé/supporté par Zend).

V-D. Vos premiers scripts PHP

V-D-1. Introduction

Les scripts PHP s'intègrent dans la page Web. Lorsque le document est demandé par le navigateur Web, le serveur Web (qui est à l'écoute) entend la demande et fait interpréter le script par PHP, puis il renvoie le résultat au navigateur.

Un script PHP est identifié par une balise particulière : <?php ouvre le script et ?> le referme. Tout ce qui se trouve à l'intérieur de cette balise est du PHP.

Vous devez enregistrer tous vos scripts à l'intérieur de la racine du serveur Web dans votre système de fichiers.

Le chemin par défaut dépend de votre serveur Web :
  • Zend Core 2 : C:\Program Files\Zend\Apache2\htdocs\
  • XAMPP : C:\Program Files\Xampp\htdocs\
  • WAMP Server : C:\wamp\www\
  • EasyPHP 1-8 : C:\Program Files\EasyPHP1-8\www\
  • Apache 2.2 : C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\
  • Apache 2.0 : C:\Program Files\Apache Group\Apache2\htdocs\
  • Apache 1.3 : C:\Program Files\Apache Group\Apache\htdocs\
  • etc.

V-D-2. Découvrir les variables

Mon premier script PHP : test.php
Sélectionnez
<html>
<head>
    <title><?php echo "Hello World!"; ?></title>
</head>
<body><h1><?php echo "Hello World!"; ?></h1><p><?php echo "Un bonjour de Yogui."; ?></p></body>
</html>

Pour visualiser le résultat, il n'est pas suffisant de double cliquer sur le fichier... Il vous faut passer par le serveur Web. Ainsi, ouvrez votre navigateur Internet et chargez la page :

Sélectionnez
http://localhost/test.php

Le résultat de ce script ne manquera pas de vous rappeler l'exemple de document HTML vu auparavant...

De la même manière qu'en HTML, les espaces et sauts de ligne ont peu d'importance en PHP. Le script suivant est équivalent au précédent :

Sélectionnez
<html>
<head>
    <title>
        <?php
        echo "Hello World!";
        ?>
    </title>
</head>
<body>
    <h1>
        <?php
        echo "Hello World!";
        ?>
    </h1>
    <p>
        <?php
        echo "Un bonjour de Yogui.";
        ?>
    </p>
</body>
</html>

Évidemment, l'intérêt de PHP est très limité dans ces exemples... Allons-y pas à pas, ceci étant une introduction.

Voyons maintenant avec une variable (une variable est un mot commençant par le signe "dollar" $) :

Sélectionnez
<html>
<head>
    <title>
        <?php
        $title = "Hello World!";
        echo $title;
        ?>
    </title>
</head>
<body>
    <h1>
        <?php
        $title = "Hello World!";
        echo $title;
        ?>
    </h1>
    <p>
        <?php
        $text = "Un bonjour de Yogui.";
        echo $text;
        ?>
    </p>
</body>
</html>

Voici un code équivalent mais à la construction plus flexible :

Sélectionnez
<?php
$title = "Hello World!";
$text = "Un bonjour de Yogui.";
?>
<html>
<head>
    <title><?php echo $title; ?></title>
</head>
<body>
    <h1><?php echo $title; ?></h1>
    <p><?php echo $text; ?></p>
</body>
</html>

Ici, j'utilise les variables $title et $text. Cela me permet de ne pas répéter "Hello World". Le gain est ici minime, cependant j'imagine que vous commencez à voir l'intérêt des variables : elles permettent de réutiliser du texte à l'infini, sans devoir le réécrire. Par ailleurs, si je souhaite modifier le titre de ma page, je n'ai plus qu'à modifier la variable au début du script pour que toute ma page soit mise à jour d'un seul coup. C'est là tout l'intérêt de PHP, mais il faut aller bien plus loin pour l'exploiter selon tout son potentiel...

Dans les équations mathématiques, une variable est une valeur inconnue ou recherchée. En PHP, c'est une valeur que l'on connaît mais que l'on peut modifier à volonté. Dans les deux cas, on utilise une équation : "x = 5" en mathématiques ou bien "$x = 5;" en PHP.

Ci-dessus, les lignes qui se trouvent dans les balises PHP s'appellent des expressions. Elles sont délimitées par des points virgules. Il faut prendre garde à ne pas oublier ce point virgule : il est fondamental car il sépare les expressions. Si on l'oublie, PHP a tendance à crier très fort qu'il y a une "syntax error" et il nous dit vers quelle ligne de notre script cela se produit.

Un peu de vocabulaire : donner une valeur à une variable s'appelle "assigner une valeur à une variable".

Allons maintenant un tout petit peu plus loin en utilisant ce que l'on appelle une structure de contrôle : la conditionnelle if.

Sélectionnez
<?php
if(isset($_GET["title"]))
{
    $title = $_GET["title"];
}
else
{
    $title = "Hello World";
}

$text = "$title, I am Yogui!";
?>
<html>
<head>
    <title><?php echo $title; ?></title>
</head>
<body>
    <h1><?php echo $title; ?></h1>
    <p><?php echo $text; ?></p>
</body>
</html>

Appelez ce script comme vous en avez maintenant l'habitude : le résultat est le même qu'auparavant. Maintenant, ajoutez ceci à la fin de la barre d'adresse du navigateur :

Sélectionnez
?title=bouh

Cela s'appelle un paramètre GET. Dans notre script, nous utilisons une variable $_GET qui teste la présence d'une variable "title". Si elle existe dans $_GET, alors on la met dans une variable locale que nous appelons $title, sinon on construit cette variable locale $title avec une valeur par défaut. Lorsque vous validez le chargement de la page, le titre et le contenu de la page ont pris la valeur que vous avez mise dans la barre d'adresse. Vous venez juste d'envoyer avec succès des informations au serveur Web et de faire votre première page réellement dynamique !

Dans ces exemples d'utilisation, nous avons utilisé empty() et isset(). Ces constructions du langage PHP s'apparentent à des fonctions, c'est-à-dire qu'on les utilise avec leur nom ("echo" ou "isset") et en mettant quelque chose dans des parenthèses. Dans le cas d'echo, les parenthèses sont facultatives.

Notez la syntaxe de la structure if : elle accepte un paramètre entre parenthèses comme le fait une fonction, puis il faut lui donner du code entre accolades. Ce qui est placé dans la branche du if n'est exécuté que si la condition est avérée, sinon seulement la branche du else est exécutée. C'est l'une ou l'autre, jamais les deux à la fois.

Sécurité
Je me dois de vous prévenir que le dernier exemple est vulnérable à ce que l'on appelle la faille XSS. Pour le moment, sachez simplement qu'il faut toujours faire attention aux informations que vous prenez de $_GET, $_POST, $_FILES, $_REQUEST et toutes ces variables remplies de données provenant de l'internaute.

V-D-3. Découvrir les inclusions

Un autre avantage majeur des scripts PHP (dits dynamiques) sur les fichiers HTML (dits statiques) est la possibilité d'appeler un script depuis un autre script. Ce sont des inclusions de scripts.

Une application typique de cette fonctionnalité est pour les éléments identiques de page en page sur un site : parties supérieure (header) et inférieure (footer), menu de navigation, espace de publicité, etc. En effet, si vous avez déjà fait un site de plusieurs pages en HTML, vous n'avez pas manqué de constater que la moindre modification dans l'un des espaces communs à toutes les pages, vous oblige à modifier de la même manière chacune de ces pages. C'est fastidieux, n'est-ce pas ?

PHP vous permet de découper vos pages en éléments indépendants que vous pouvez inclure les uns dans les autres, ce qui vous permet d'avoir un seul script pour chaque élément reproduisible. Cela simplifie les mises à jour de votre site puisque chaque élément se situe à un seul emplacement.

Voici un site minimaliste de trois pages avec des inclusions :

index.php
Sélectionnez
<?php
$title = 'Bienvenue';
include 'header.php';
?>
<h1><?php echo $title; ?></h1>
<!--
    Mettre ici le contenu de la page d'accueil
-->
<?php include 'footer.php'; ?>
catalogue.php
Sélectionnez
<?php
$title = 'Notre catalogue';
include 'header.php';
?>
<h1><?php echo $title; ?></h1>
<!--
    Mettre ici le contenu de la page catalogue
-->
<?php include 'footer.php'; ?>
contact.php
Sélectionnez
<?php
$title = 'Nous contacter';
include 'header.php';
?>
<h1><?php echo $title; ?></h1>
<!--
    Mettre ici le formulaire de contact
-->
<?php include 'footer.php'; ?>
header.php
Sélectionnez
<?php
if(empty($title))
{
    $title = 'Nouveau document';
}
?>
<html>
<head>
    <title><?php echo $title; ?></title>
</head>
<body>
footer.php
Sélectionnez
</body>
</html>

Je n'ai pas mis la balise h1 dans le script header.php ; vous verrez à l'utilisation pourquoi j'ai fait de cette manière.

V-E. Avertissement : ce que PHP n'est pas

PHP est avant tout un langage de script. Il permet de développer des applications très performantes et très utiles, mais il ne peut pas tout faire. Il est principalement utilisé pour des applications Web, c'est-à-dire pour exécuter du code sur un serveur Web. Ainsi, il ne faut pas s'étonner si PHP offre très peu de moyens de lire le port série, parallèle ou USB de votre machine, par exemple.

V-F. Formation

V-F-1. Organisme officiel

PHP est développé et maintenu par le PHP GroupSite officiel de PHP. La documentation du langage y est facilement accessible, elle est traduite en français et il est possible de lire les commentaires des internautes.

V-F-2. Nos ressources habituelles

  • La FAQ PHP répond à vos questions posées dans nos forums ;
  • Les sources PHP vous donnent des codes permettant de résoudre des problématiques précises ;
  • Les tutoriels PHPLes meilleurs cours PHP vous permettront d'apprendre tout ce dont vous avez besoin ;
  • Les livres PHPLes meilleurs livres PHP critiqués par la Rédaction pour toujours avoir une référence sous le coude ;
  • Le forum PHP vous permet de poser toutes vos questions qui ne trouvent pas réponse dans nos autres ressources.

V-F-3. Notre sélection de cours

Comparatif PHP/Javascript

Si vous n'êtes pas encore sûr de vous, commencez par réviser les différences entre les langages JavaScript et PHP grâce au comparatif de Julp.

Guide de style

Adrien Pellegrini n'a bien sûr pas omis PHP dans son guide de style.

Les formulaires et PHP5

Mon cours sur les formulaires contient toute une partie sur la récupération des données au moyen de PHP.

Les sessions PHP

Les sessions sont un mécanisme fondamental permettant de conserver des informations entre les diverses pages visitées par l'internaute. Par exemple, dans le modèle classique du Web, si l'on veut restreindre l'accès à une portion d'un site, il faut utiliser un formulaire de connexion. Cependant, sans utiliser les sessions, il faut que l'internaute remplisse et soumette ce formulaire à chaque fois qu'il souhaite visualiser une page, puisque le serveur a la mémoire courte... Les sessions permettent au serveur de ne pas la perdre ausi facilement.

Julp s'est associé à Mathieu Lemoine pour vous présenter les sessions PHP sous tous leurs aspects.

V-F-4. Nos tests d'EDI

Retrouvez la liste de nos ressources dans la page EDI PHPLes meilleurs outils PHP : Éditeurs, EDI.

PHPEclipse : Programmez librement pour le Web

Comme un grand nombre de développeurs ici-bas, il est très probable que dans le futur vous étendiez vos connaissances à d'autres langages que PHP. En ce cas, Eclipse est fait pour vous. Jean-Pierre Grossglauser a testé le plugin PHPEclipseTest logiciel : PHPEclipse.

Il existe d'autres dérivés d'Eclipse pour programmer en PHP. Quelques exemples sont : Eclipse PHP, Eclipse PDT, Zend Studio, etc.

PHPEdit, un IDE complet pour PHP

PHPEditTest logiciel : PHPEdit étant mon éditeur favori, j'en ai testé les majeures fonctionnalités pour vous.

Test complet de l'éditeur WebExpert de Visicom

BWP-Necromance et Pierre-Baptiste Naigeon ont testé WebExpert 6.5Test logiciel : WebExpert.


Tutoriel WEB

Développement Web : "Zone Grand Débutant"

  • VI. Base de données : Stockage des informations
    • VI-A. Introduction
    • VI-B. Outils nécessaires
    • VI-C. Votre première BDD
      • VI-C-1. L'analyse (conception de la structure)
        • Modèle Conceptuel des Données (MCD)
        • Modèle Logique des Données (MLD)
        • Modèle Physique des Données (MPD)
      • VI-C-2. Le SQL (création et mise à jour de la structure, consultation et mise à jour des informations)
      • VI-C-3. Exemples concrets
        • XML
        • MS Office Excel
        • MS Office Access
        • MySQL
    • VI-D. Formation
      • VI-D-1. Organisme de référence
      • VI-D-2. Nos ressources habituelles
      • VI-D-3. Notre sélection de cours
        • Conception d'une base de données
        • Quelques notions de manipulation de données : SQL
        • Utiliser une BDD avec PHP
        • Écrire du bon code SQL

VI. Base de données : Stockage des informations

VI-A. Introduction

Les trois notions fondamentales :
  • Le fichier est dans un format géré en interne par le SGBD et dont les détails ne nous importent pas ;
  • Le document est à destination d'un langage de script ;
  • L'outil est le SGBD et son API associée.

Je vous préviens, vous allez apprendre du vocabulaire !

Les bases de données (BDD) désignent en fait tous les systèmes de stockage qui permettent de conserver des informations (c'est-à-dire des données) dans un lieu sûr, à l'écart de l'application. Il peut s'agir de fichiers de texte, de fichiers au format XML, de systèmes de gestion de bases de données (SGBD), etc.

Vous avez certainement entendu l'un des noms suivants : Oracle, SQL Server, Access, MySQL ? Ce sont tous des SGBDR (le "R" signifie "relationnelles"). MS Office Excel permet également de faire des BDD mais pas au même niveau que les SGBDR que je viens de mentionner.

Une base de données relationnelle permet d'enregistrer les informations sans avoir aucun duplicata, ce qui réduit l'espace de stockage utilisé ainsi que les temps d'accès, tout en simplifiant la mise à jour. Les données (informations) y sont en relation les unes avec les autres (c'est ce qui évite les doublons).

Le principe d'une BDD relationnelle est d'enregistrer les informations de manière hiérarchisée :
  • Le SGBD contient des bases de données (exemples : "livre-d-or") : dans Excel, ce sont les "fichiers" ;
  • Chaque base de données est structurée en tables (exemples : "user", "message", "sujet") : dans Excel, ce sont les "feuilles" ;
  • Chaque table regroupe tous les champs d'une même entité (exemples : "id", "login") : dans Excel, ce sont les "colonnes" ;
  • Un champ est une valeur (exemples : "8480", "BrYs", "30724", "Yogui") : dans Excel, ce sont les "cellules".

Vous trouverez plus bas des exemples de bases de données.

VI-B. Outils nécessaires

Il est parfois utile d'avoir sous la main un outil permettant de dessiner les schémas de l'analyse. Vous pouvez vous tourner vers l'un des outils conseillés par SQLProPetit guide d'analyse des données à l'aide de la méthode MERISE.

Pour le SGBD (le programme lui-même), vous avez un choix très large. En effet, vous pouvez opter pour n'importe lequel des noms cités en introduction (ou un autre). Prenez simplement garde d'installer à la fois le service et le client. Vous pouvez vous aider de notre comparatifComparatif : Quel SGBD choisir ?.

Vous aurez besoin :
  • D'un outil pour développer votre code SQL (certains IDEs comme Zend Studio, PHPEdit et PHPEclipse intègrent cette fonctionnalité) ;
  • D'un outil de gestion de base de données (le SGBD, cf. notre comparatif) ;
  • D'un outil d'administration (sauf si celui qui est fourni en standard avec votre SGBD vous convient) : phpMyAdmin (MySQL), phpPgAdmin (PostgreSQL), TOAD pour Oracle ou MySQL, etc.

VI-C. Votre première BDD

En général, la construction d'une base de données commence par une phase d'analyse. Cela se fait au moyen d'une méthode d'analyse : historiquement, les français préfèrent la méthode Merise, tandis que le reste du monde utilise la méthode UML (qui peut également servir pour la programmation). Cette analyse conceptuelle permet de se représenter le fonctionnement du système d'informations pour lequel on cherche à construire une base de données.

Je vais vous proposer d'utiliser la méthode Merise car je la trouve simple d'approche et très performante.

VI-C-1. L'analyse (conception de la structure)

Modèle Conceptuel des Données (MCD)

Dans Merise, un MCD décrit le fonctionnement d'un système d'information d'un point de vue fonctionnel, sans aucune considération technique.

Voici comment un livre d'or est représenté selon une analyse conceptuelle avec la méthode Merise (pour rappel, un livre d'or est simplement une suite de messages écrits par des utilisateurs) :

MCD : Livre d'or
Modèle conceptuel d'un livre d'or

Pour dessiner ce schéma, j'ai utilisé AnalyseSIOutil gratuit de conception Merise, gratuit et très simple à utiliser.

Sans entrer dans les détails, il s'agit ici de deux entités "user" et "message" liées par une association "écrit". Chacune des deux entités est composée de champs, certains d'eux jouant le rôle d'identifiants (ils sont généralement soulignés). Notez que les entités sont représentées par des noms communs au singulier et que la relation est un verbe conjugué.

Modèle Logique des Données (MLD)▲

Suite à l'étape de modélisation conceptuelle ci-dessus, la méthode Merise fournit un procédé permettant d'aboutir à la structure finale de la base de données. C'est le Modèle Logique des Données (MLD), qui décrit comment sont organisées les données.

Le passage au MLD détermine la liste des champs de chacune des tables du système d'information décrit par le MCD. C'est une étape intermédiaire semi technique : les relations du MCD sont devenues des tables et des champs, mais aucun choix technique n'est encore fait.

Le schéma précédent se traduit par ce MLD :
  • user (id, login, password, website)
  • message (id, #user_id, title, text)

À chaque ligne du MLD est définie une table ainsi que la liste de ses champs. Les champs soulignés permettent de différencier un enregistrement d'un autre au sein d'une table, ils forment donc la clef primaire. Les champs marqués d'un signe dièse (#) sont des informations permettant de relier un enregistrement d'une table avec un enregistrement d'une autre table (lorsqu'ils ont la même valeur), et donc de faire référence à une clef primaire d'une autre table, c'est pourquoi on appelle ces champs des clefs étrangères (le champ "user_id" dans la table "message" est une clef étrangère pour le champ "id" dans la table "user").

La clef primaire est identifiée dès le MCD. Elle permet de récupérer un seul enregistrement dans une table.

La clef étrangère est identifiée à partir du MLD. Elle permet, à partir d'un enregistrement d'une table, de retrouver l'enregistrement correspondant dans une autre table. Dans notre exemple, le numéro d'un message permet de retrouver le nom de son auteur.

Modèle Physique des Données (MPD)

La dernière étape de la méthode Merise est la conversion du Modèle Logique en Modèle Physique des Données (MPD). En fait, le MPD peut ête composé soit de tableaux décrivant le schéma, soit du code SQL de création du schéma : le code SQL est une déduction directe du MPD (en fonction du SGBD choisi et de sa version).

Il s'agit simplement de décrire le type (chaîne de caractères, numérique...) de chacun des champs des tables. C'est très proche du SQL de création de la base de données.

Voici un MPD simplifié pour le MLD précédent :

Table : user
Nom | Type | Clef
id | numérique | primaire
login | chaîne | unique
password | chaîne |
website | chaîne |
Table : message
Nom | Type | Clef
id | numérique | primaire
user_id | numérique | étrangère
title | chaîne |
body | texte |

VI-C-2. Le SQL (création et mise à jour de la structure, consultation et mise à jour des informations)

Le SQL (Structured Query Language) permet de manipuler la structure des informations ainsi que les informations elles-mêmes.

Pour créer les tables de notre analyse (la structure de notre base de données), on peut utiliser le code SQL suivant :

Création de la structure en SQL :
Sélectionnez
CREATE TABLE guestbook.user (
    id INT(8) UNSIGNED NOT NULL auto_increment,
    login VARCHAR(50) NOT NULL,
    password VARCHAR(16) NOT NULL,
    website VARCHAR(255) DEFAULT '',
    created_at DATETIME DEFAULT NULL,
    PRIMARY KEY  (id)
);

CREATE TABLE guestbook.message (
    id INT(8) unsigned NOT NULL auto_increment,
    user_id INT(10) unsigned NOT NULL,
    title VARCHAR(50) NOT NULL,
    body TEXT NOT NULL,
    created_at DATETIME DEFAULT NULL,
    PRIMARY KEY  (id)
);

ALTER TABLE guestbook.user
ADD CONSTRAINT uk_user_login UNIQUE (login);

ALTER TABLE guestbook.message
ADD CONSTRAINT fk_message_user FOREIGN KEY (user_id)
    REFERENCES guestbook.user (id) ON DELETE CASCADE ON UPDATE CASCADE;

Ici, nous voyons qu'un champ user_id a été ajouté à la table message depuis l'analyse : c'est dû au fait qu'un message ne peut appartenir qu'à un utilisateur. Ainsi, nous pouvons déterminer qui a écrit quel message. L'ID de l'auteur est une information propre au message.

Une fois la structure du schéma prête, nous pouvons envoyer des requêtes pour en modifier ou pour en lire les données.

Voici comment remplir le schéma avec des informations :

Utilisateurs :
Sélectionnez
INSERT INTO user (login, password, website, created_at)
VALUES ("BrYs", "1234", "brys.developpez.com", NOW());

INSERT INTO user (login, password, website, created_at)
VALUES ("Yogui", "4321", "g-rossolini.developpez.com", NOW());
Messages :
Sélectionnez
INSERT INTO message (user_id, title, body, created_at)
VALUES (1, "Bonjour", "Un bonjour de Paris ;)", NOW());

INSERT INTO message (user_id, title, body, created_at)
VALUES (2, "Super site", "J'apprécie ton site, continue ainsi !", NOW());

INSERT INTO message (user_id, title, body, created_at)
VALUES (2, "Merci pour tout", "J'oubliais de dire que ton site m'a beaucoup servi !", NOW());

La recherche (lecture) se fait au moyen de l'instruction SELECT.

Toutes les infos de tous les utilisateurs :
Sélectionnez
SELECT *
FROM user;

L'instruction WHERE permet de filtrer les données retournées par la requête SQL.

Toutes les infos de l'utilisateur 'Yogui' :
Sélectionnez
SELECT *
FROM user
WHERE login = 'Yogui';

L'instruction JOIN permet de mettre en relation deux tables qui ont un champ en commun : dans cet exemple, il s'agit de user.id et message.user_id. Notez qu'il est préférable de réutiliser le nom des tables pour éviter les conflits : indiquer seulement id porterait à confusion entre l'ID du message et l'ID de l'utilisateur.

Tous les messages de l'utilisateur 'Yogui' :
Sélectionnez
SELECT user.login, message.title, message.body
FROM message
INNER JOIN user ON message.user_id = user.id
WHERE user.login = 'Yogui';

Ici, nous pouvons voir un exemple de la relation entre les tables user et message : nous utilisons le numéro de l'utilisateur pour dire à qui appartient chaque message. De cette manière, nous ne répétons pas les informations contenues dans la table "users", ce qui réduit l'espace disque utilisé et simplifie la mise à jour des informations des utilisateurs : il suffit de modifier le contenu de la table "users".

Le SQL est prévu pour être simple à lire et relativement intuitif à comprendre. Cependant, il existe mille manières d'arriver à un seul résultat. Je vous recommande de longuement l'étudier avant de vous lancer dans des schémas complexes, vous gagnerez en efficacité. C'est ce qui s'appelle la normalisation.

VI-C-3. Exemples concrets

Je vais utiliser le modèle conceptuel présenté ci-dessus pour vous donner un exemple de BDD avec plusieurs systèmes : XML, Excel, Access et MySQL.

Cette suite d'exemples est principalement destinée à vous donner une vision d'ensemble, de vous montrer qu'il est possible d'obtenir le même résultat de différentes manières.

XML

XML est simplement un format de stockage des données dans un fichier texte. On peut donc visualiser les données avec n'importe quel éditeur de texte, mais il faut développer une application avec un langage de programmation pour pouvoir effectuer des consultations complexes. Il existe un langage pour parcourir un arbre XML : XPath.

users.xml
Sélectionnez
<?xml version="1.0" encoding="UTF-8" ?>
<users>
    <user>
        <id>1</id>
        <login>BrYs</login>
        <password>1234</password>
        <website>brys.developpez.com</website>
        <created_at>2010-01-16 23:04:46</created_at>
    </user>
    <user>
        <id>2</id>
        <login>Yogui</login>
        <password>4321</password>
        <website>g-rossolini.developpez.com</website>
        <created_at>2010-01-16 23:04:47</created_at>
    </user>
</users>
messages.xml
Sélectionnez
<?xml version="1.0" encoding="UTF-8" ?>
<messages>
    <message>
        <id>1</id>
        <user_id>1</user_id>
        <title>Bonjour</title>
        <body>Un bonjour de Paris ;)</body>
        <created_at>2010-01-16 23:04:48</created_at>
    </message>
    <message>
        <id>2</id>
        <user_id>2</user_id>
        <title>Super site</title>
        <body>J'apprécie ton site, continue ainsi !</body>
        <created_at>2010-01-16 23:04:49</created_at>
    </message>
    <message>
        <id>3</id>
        <user_id>2</user_id>
        <title>Merci pour tout</title>
        <body>J'oubliais de dire que ton site m'a beaucoup servi !</body>
        <created_at>2010-01-16 23:04:50</created_at>
    </message>
</messages>

Exemple d'application permettant de retrouver les messages de Yogui :

xml-messages-yogui.php
Sélectionnez
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
<head>
    <title>Messages de Yogui (source : XML)</title>
    <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
</head>
<body>
<?php

function display($string)
{
    echo htmlentities(utf8_decode($string), ENT_QUOTES, 'ISO-8859-1');
}

$xml_users = file_get_contents("users.xml");
$xml_messages = file_get_contents("messages.xml");

$src_users = simplexml_load_string($xml_users);
$src_messages = simplexml_load_string($xml_messages);

$users = $src_users->xpath("/users/user[login = 'Yogui']");
$yogui = $users[0];

if($yogui)
{
    ?>
    <table border="1">
        <tr>
            <th>login</th>
            <th>title</th>
            <th>text</th>
        </tr>
        <?php
        $messages = $src_messages->xpath("/messages/message[user_id = '".$yogui->id."']");
        foreach($messages as $message)
        {
            ?>
            <tr>
                <td><?php display($yogui->login); ?></td>
                <td><?php display($message->title); ?></td>
                <td><?php display($message->text); ?></td>
            </tr>
            <?php
        }
        ?>
    </table>
    <?php
}

?>
</body>
</html>

Et voici le résultat dans le navigateur Web :

Image non disponible

XML est un très bon moyen d'enregistrer des données mais il comporte un inconvénient majeur : il n'y a aucun automatisme. La cohérence des données n'est pas contrôlée par un SGBD, ainsi je peux modifier n'importe quelle valeur user.id du fichier users.xml sans me rendre compte qu'ensuite je ne pourrai probablement plus utiliser la liaison avec le champ message.user_id du fichier messages.xml.

MS Office Excel

Excel ne dispose pas du langage SQL mais il permet néanmoins de sauvegarder les données avec l'organisation hiérarchique adoptée par les autres SGBD. C'est en quelque sorte une alternative graphique à XML, il n'y a pas besoin de s'occuper de remplir les balises mais seulement de remplir les cellules. C'est plus simple à remplir, mais plus difficile à utiliser avec une application externe.

Excel est à la fois le moteur de stockage et l'outil de visualisation des données. Le fichier de données n'est pas lisible avec n'importe quel éditeur de texte mais Excel permet d'effectuer des consultations complexes sur les données.

Dans un classeur "Livre d'or", créons les feuilles "user" et "message" :

Image non disponible
Image non disponible
Les feuilles du classeur :
  • user :
    1. Identifiant automatique ;
    2. Pseudonyme ;
    3. Mot de passe ;
    4. Site Web.
  • message :
    1. Identifiant automatique ;
    2. Identifiant de l'auteur ;
    3. Titre ;
    4. Texte.

Excel permet de filtrer les données feuille par feuille, mais pas de mettre en relation plusieurs feuilles. Il m'est par exemple impossible d'avoir directement la liste des messages de l'utilisateur "Yogui".

Pour obtenir la liste des messages de "Yogui", il faut commencer par obtenir son ID (colonne A) en filtrant la feuille "user" par la colonne B ("login") :

Image non disponible
Image non disponible
Nous n'avons que les informations de l'utilisateur 'Yogui'

En filtrant ensuite la feuille "message" sur la colonne B ("user_id") à l'aide de l'ID que nous venons d'obtenir, nous obtenons indirectement les messages de "Yogui" :

Image non disponible
Image non disponible
Nous n'avons que les messages de l'utilisateur 2, c'est-à-dire 'Yogui'

Cette méthode de recherche est fastidieuse, peu pratique. Il vaut mieux utiliser un SGBD dès lors que les feuilles sont liées les unes aux autres (même raison que pour XML).

MS Office Access▲

Access propose des fonctionnalités plus complètes qu'Excel pour la gestion de bases de données.

Access, tout comme Excel, est à la fois le moteur de stockage et l'outil de visualisation des données. Le fichier de données n'est pas lisible avec n'importe quel éditeur de texte. Access permet d'effectuer des consultations complexes sur les données. Il est difficile d'utiliser une application externe pour consulter les données.

Image non disponible
Ci-dessus : structure de la table "user"
Image non disponible
Ci-dessus : structure de la table "message"
Image non disponible
Ci-dessus : relations entre les tables "user" et "message"

Les données contenues dans les tables sont les mêmes que précédemment :

Image non disponible
Ci-dessus : informations contenues dans la table "user"
Image non disponible
Ci-dessus : informations contenues dans la table "message"

Access étant un SGBDR, il permet de relier les tables les unes aux autres. Cela nous permet donc d'obtenir en une opération la liste des messages de l'utilisateur "Yogui" à l'aide de la requête SQL proposée plus haut :

Image non disponible
Ci-dessus : requête en mode SQL
Image non disponible
Ci-dessus : résultat d'une requête

Access (et tous les équivalents des autres suites de bureautique, par exemple OpenOffice.org Base) est un très bon outil de gestion de BDD en bureautique mais il souffre de certaines lourdeurs. Une BDD Access ou Base est adaptée pour de petites applications pour un seul utilisateur sur son poste de travail, mais elle est impraticable en environnement Web.

MySQL

MySQL est un véritable SGBDR, c'est-à-dire qu'il permet principalement de conserver les données sur le disque dur et qu'il dispose d'une gestion interne des droits d'accès. Pour visualiser les données, il faut développer une application à l'aide d'un langage de programmation et du langage SQL. Des outils d'administration peuvent se substituer cette l'application externe pour les tâches d'administration de la base de données, mais l'application devra être développée à un moment ou à un autre afin de permettre aux utilisateurs d'utiliser la BDD. Dans le cas d'Internet, les utilisateurs sont les internautes, les visiteurs du site Web.

Nous pouvons par exemple utiliser MySQL Query Browser, un outil d'administration gratuit :

Image non disponible
Image non disponible
Image non disponible

L'intérêt d'utiliser un SGBD comme MySQL est d'avoir la possibilité de choisir l'application "client", c'est-à-dire l'application qui permet de consulter et de mettre à jour la BDD. Ci-dessus, j'ai utilisé une application de bureau mais, en développement Web, nous utiliserons très peu ce genre d'outils. Il est préférable de développer des pages Web à l'aide d'un langage de script comme PHP.

Exemple avec l'outil phpMyAdmin :

Image non disponible
Image non disponible
Image non disponible

Voici un exemple de script PHP donnant le même résultat :

mysql-messages-yogui.php
Sélectionnez
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
<head>
    <title>Messages de Yogui (source : MySQL)</title>
    <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
</head>
<body>
<?php

function display($string)
{
    echo htmlentities($string, ENT_QUOTES, 'ISO-8859-1');
}

mysql_connect('localhost', 'root', '') or die(mysql_error());
mysql_select_db('guestbook') or die(mysql_error());

$sql = "SELECT user.login, message.title, message.body
        FROM message
        INNER JOIN user ON message.user_id = user.id
        WHERE user.login = 'Yogui';";

$result = mysql_query($sql) or die(mysql_error());
if($result)
{
    ?>
    <table border="1">
        <tr>
            <th>login</th>
            <th>title</th>
            <th>text</th>
        </tr>
        <?php
        while($message = mysql_fetch_assoc($result))
        {
            ?>
            <tr>
                <td><?php display($message['login']); ?></td>
                <td><?php display($message['title']); ?></td>
                <td><?php display($message['text']); ?></td>
            </tr>
            <?php
        }
        ?>
    </table>
    <?php
}
?>
</body>
</html>

Et voici le résultat dans le navigateur Web :

Image non disponible

C'est à ce dernier résultat que nous voulons parvenir : MySQL en stockage des données + des scripts PHP pour les consulter.

Il est possible de mettre en place des règles de gestion afin d'empêcher la mise à jour de certains champs, ou bien d'effectuer certaines actions lorsque des évènements précis ont lieu. Par exemple ici, nous avons défini une containte d'intégrité qui relie les champs user.id et message.user_id : lorsque nous modifions une valeur user.id, MySQL met automatiquement à jour les valeurs correspondantes dans message.user_id de telle manière que la base de données reste toujours cohérente.

VI-D. Formation

VI-D-1. Organisme de référence

Malgré l'existence d'une norme SQL, il faut consulter chaque SGBD pour obtenir une documentation fiable. Les organismes ANSIAmerican National Standards Institute et ISOInternational Organization for Standardization se sont chargés de la normalisation du langage.

VI-D-2. Nos ressources habituelles

  • La FAQ MySQL et la FAQ PostgreSQL répondent à vos questions posées dans nos forums ;
  • Les sources PostgreSQL vous donnent des codes permettant de résoudre des problématiques précises ;
  • Les tutoriels MySQLLes meilleurs cours MySQL vous permettront d'apprendre tout ce dont vous avez besoin ;
  • Les livres MySQLLes meilleurs livres MySQL critiqués par la Rédaction et les livres PostgreSQLLes meilleurs livres PostgreSQL critiqués par la Rédaction pour toujours avoir une référence sous le coude ;
  • Le forum BDD, le forum MySQL et le forum PostgreSQL vous permettent de poser toutes vos questions qui ne trouvent pas réponse dans nos autres ressources.

VI-D-3. Notre sélection de cours

Conception d'une base de données

Cyril Gruau vous présente la conception de bases de données grâce à Merise. Laurent Audibert, pour sa part, vous propose UML2.

Quelques notions de manipulation de données : SQL

SQL fonctionne au moyen d'un serveur de bases de données. On y envoie des instructions au moyen d'un client : PHP jouera cet office dans vos applications Web.

J'ai mis plus haut un exemple de code utilisant une syntaxe "CREATE". C'est ce que l'on appelle le langage de définition de données (DDL) : il sert à manipuler la structure des informations de la base de données. Baptiste Wicht traite uniquement la création des tables, tandis que SQLPro est plus complet.

Après avoir créé vos tables avec le DDL, il peut être intéressant de les remplir avec vos informations : cela se fait au moyen du langage de manipulation de données (DML), vu ci-dessus par l'instruction "INSERT INTO". Elle sert à manipuler le contenu de la base de données, à savoir les informations elles-mêmes. Baptiste Wicht couvre simplement la manipulation de données, alors que SQLPro est là aussi exhaustif.

Enfin, le but ultime d'une base de données étant d'être consultée, vous pouvez utiliser l'instruction "SELECT" vue ci-dessus. De nouveau, Baptiste Wicht fait une présentation plus sommaire que SQLPro, fidèle à lui-même.

Utiliser une BDD avec PHP

En fait, SQL et PHP sont deux choses totalement différentes. L'un peu fonctionner sans l'autre mais ils peuvent également collaborer. Pour y parvenir, je vous recommande la lecture du cours "passer des requêtes MySQL en PHP" par Eusebius. Une fois que vous êtes un peu mieux préparés, je vous recommande le tutoriel de Pierre-Baptiste Naigeon sur la création d'un site dynamique.


Tutoriel WEB

Développement Web : "Zone Grand Débutant"

  • VII. Conclusion générale
    • VII-A. Épilogue
    • VII-B. Pour aller plus loin
    • VII-C. Contribuez

VII. Conclusion générale

VII-A. Épilogue

Apprendre à faire des pages Web n'est pas une mince affaire mais cela peut en valoir la peine. Je pense que le plus important est de ne pas perdre le fil, d'utiliser les technologies à bon escient et non dans tous les sens.

VII-B. Pour aller plus loin

Pour aller plus loin, je vous recommande la lecture de nos autres cours HTML, CSS, PHP, JavaScript et BDD.

En particulier, le résumé "Comprendre l'environnement Web" par Éric Berger pourra vous être bien utile.

VII-C. Contribuez

Si vous souhaitez contribuer à l'enrichissement de nos ressources, nous serions heureux d'accueillir vos propositions !


Tutoriel VBScript

  • Partie 1 - Les bases de HTML5

    1. Comment fait-on pour créer des sites web ?

    2. Votre première page web en HTML

    3. Organiser son texte

    4. Créer des liens

    5. Les images

    Partie 2 - Les joies de la mise en forme avec CSS

    1. Mettre en place le CSS

    2. Formatage du texte

    3. La couleur et le fond

    4. Les bordures et les ombres

    5. Création d'apparences dynamiques

    Partie 3 - Mise en page du site

    1. Structurer sa page

    2. Le modèle des boîtes

    3. Le positionnement en CSS

    4. TP: création d'un site pas à pas

    Partie 4 - Fonctionnalités évoluées

    1. Les tableaux

    2. Les formulaires

    3. La vidéo et l'audio

    4. Mise en page adaptative avec les Media Queries

    5. Aller plus loin

    Partie 5 - Annexes

    1. Envoyez votre site sur le Web

    2. Mémento des balises HTML

    3. Mémento des propriétés CSS

    4. Gérer la compatibilité entre les navigateurs


Tutoriel VBScript

Comment fait-on pour créer des sites web ?

https://vimeo.com/76776327

Bonjour et bienvenue à toutes et à tous !

Voici donc le premier chapitre de ce livre pour débutants, qui va vous apprendre à créer votre site web !

Nous allons passer un certain temps ensemble, tout dépendra de la vitesse à laquelle vous apprendrez. Si vous lisez ce livre régulièrement et à une bonne vitesse, vous l'aurez terminé en une à deux semaines. Mais si vous avez besoin d'un peu plus de temps, ne vous inquiétez pas : le principal est que vous y alliez à votre rythme, de préférence en prenant du bon temps.

Je vous propose de commencer par la question la plus simple mais aussi la plus importante : comment fonctionnent les sites web ?

Le fonctionnement des sites web

Comment fonctionnent les sites web ?

Non, n'ayez pas peur de poser des questions même si vous pensez qu'elles sont « bêtes ». Il est très important que nous en parlions un peu avant de nous lancer à fond dans la création de sites !

Je suis certain que vous consultez des sites web tous les jours. Pour cela, vous lancez un programme appelé le navigateur web en cliquant sur l'une des icônes représentées à la figure suivante.

Les icônes des navigateurs web les plus répandus
Les icônes des navigateurs web les plus répandus

Avec le navigateur, vous pouvez consulter n'importe quel site web. Voici par exemple un navigateur affichant le célèbre site web Wikipédia (figure suivante).

Le site web Wikipédia
Le site web Wikipédia

Je suis sûr que vous avez l'habitude d'utiliser un navigateur web ! Aujourd'hui, tout le monde sait aller sur le Web… mais qui sait vraiment comment le Web fonctionne ? Comment créer des sites web comme celui-ci ?

J'ai entendu parler de HTML, de CSS, est-ce que cela a un rapport avec le fonctionnement des sites web ?

Tout à fait !
Il s'agit de langages informatiques qui permettent de créer des sites web. Tous les sites web sont basés sur ces langages, ils sont incontournables et universels aujourd'hui. Ils sont à la base même du Web. Le langage HTML a été inventé par un certain Tim Berners-Lee en 1991…

Tim Berners-Lee suit encore aujourd'hui avec attention l'évolution du Web. Il a créé le World Wide Web Consortium (W3C) qui définit les nouvelles versions des langages liés au Web. Il a par ailleurs créé plus récemment la World Wide Web Foundation qui analyse et suit l'évolution du Web.

De nombreuses personnes confondent (à tort) Internet et le Web. Il faut savoir que le Web fait partie d'Internet.
Internet est un grand ensemble qui comprend, entre autres : le Web, les e-mails, la messagerie instantanée, etc.
Tim Berners-Lee n'est donc pas l'inventeur d'Internet, c'est « seulement » l'inventeur du Web.

Les langages HTML et CSS sont à la base du fonctionnement de tous les sites web. Quand vous consultez un site avec votre navigateur, il faut savoir que, en coulisses, des rouages s'activent pour permettre au site web de s'afficher. L'ordinateur se base sur ce qu'on lui a expliqué en HTML et CSS pour savoir ce qu'il doit afficher, comme le montre la figure suivante.

Du HTML à l'écran
Du HTML à l'écran

HTML et CSS sont deux « langues » qu'il faut savoir parler pour créer des sites web. C'est le navigateur web qui fera la traduction entre ces langages informatiques et ce que vous verrez s'afficher à l'écran.
Vous vous demandez sûrement pourquoi il faut connaître deux langages pour créer des sites web ? Je vous réponds sans plus tarder !

HTML et CSS : deux langages pour créer un site web

Pour créer un site web, on doit donner des instructions à l'ordinateur. Il ne suffit pas simplement de taper le texte qui devra figurer dans le site (comme on le ferait dans un traitement de texte Word, par exemple), il faut aussi indiquer où placer ce texte, insérer des images, faire des liens entre les pages, etc.

Les rôles de HTML et CSS

Pour expliquer à l'ordinateur ce que vous voulez faire, il va falloir utiliser un langage qu'il comprend. Et c'est là que les choses se corsent, parce qu'il va falloir apprendre deux langages !

Pourquoi avoir créé deux langages ? Un seul aurait suffi, non ?

Vous devez vous dire que manipuler deux langages va être deux fois plus complexe et deux fois plus long à apprendre… mais ce n'est pas le cas ! Je vous rassure, s'il y a deux langages c'est, au contraire, pour faciliter les choses. Nous allons avoir affaire à deux langages qui se complètent car ils ont des rôles différents :

  • HTML (HyperText Markup Language) : il a fait son apparition dès 1991 lors du lancement du Web. Son rôle est de gérer et organiser le contenu. C'est donc en HTML que vous écrirez ce qui doit être affiché sur la page : du texte, des liens, des images… Vous direz par exemple : « Ceci est mon titre, ceci est mon menu, voici le texte principal de la page, voici une image à afficher, etc. ».

  • CSS (Cascading Style Sheets, aussi appelées Feuilles de style) : le rôle du CSS est de gérer l'apparence de la page web (agencement, positionnement, décoration, couleurs, taille du texte…). Ce langage est venu compléter le HTML en 1996.

Vous avez peut-être aussi entendu parler du langage XHTML. Il s'agit d'une variante du HTML qui se veut plus rigoureuse et qui est donc un peu plus délicate à manipuler.
Pour faire simple, le HTML est apparu le premier en 1991. Début 2000, le W3C a lancé le XHTML en indiquant que ce serait l'avenir… mais le XHTML n'a pas percé comme on l'espérait. Retour aux sources en 2009 : le W3C abandonne le XHTML et décide de revenir au HTML pour le faire évoluer.
Il y a beaucoup de confusion autour de ces langages, alors qu'ils se ressemblent beaucoup. Aucun n'est vraiment meilleur que l'autre, il s'agit de deux façons de faire différentes. Dans ce cours, nous allons travailler sur la dernière version de HTML (HTML5) qui est aujourd'hui le langage d'avenir que tout le monde est incité à utiliser.

Vous pouvez très bien créer un site web uniquement en HTML, mais celui-ci ne sera pas très beau : l'information apparaîtra « brute ». C'est pour cela que le langage CSS vient toujours le compléter.

Pour vous donner une idée, la figure suivante montre ce que donne la même page sans CSS puis avec le CSS.

Avec et sans CSS
Avec et sans CSS

Le HTML définit le contenu (comme vous pouvez le voir, c'est brut de décoffrage !). Le CSS permet, lui, d'arranger le contenu et de définir la présentation : couleurs, image de fond, marges, taille du texte…

Comme vous vous en doutez, le CSS a besoin d'une page HTML pour fonctionner. C'est pour cela que nous allons d'abord apprendre les bases du HTML avant de nous occuper de la décoration en CSS.
Vos premières pages ne seront donc pas les plus esthétiques, mais qu'importe ! Cela ne durera pas longtemps.

Les différentes versions de HTML et CSS

Au fil du temps, les langages HTML et CSS ont beaucoup évolué. Dans la toute première version de HTML (HTML 1.0) il n'était même pas possible d'afficher des images !

Voici un très bref historique de ces langages pour votre culture générale.

Les versions de HTML

  • HTML 1 : c'est la toute première version créée par Tim Berners-Lee en 1991.

  • HTML 2 : la deuxième version du HTML apparaît en 1994 et prend fin en 1996 avec l'apparition du HTML 3.0. C'est cette version qui posera en fait les bases des versions suivantes du HTML. Les règles et le fonctionnement de cette version sont donnés par le W3C (tandis que la première version a été créée par un seul homme).

  • HTML 3 : apparue en 1996, cette nouvelle version du HTML rajoute de nombreuses possibilités au langage comme les tableaux, les applets, les scripts, le positionnement du texte autour des images, etc.

  • HTML 4 : il s'agit de la version la plus répandue du HTML (plus précisément, il s'agit de HTML 4.01). Elle apparaît pour la première fois en 1998 et propose l'utilisation de frames (qui découpent une page web en plusieurs parties), des tableaux plus complexes, des améliorations sur les formulaires, etc. Mais surtout, cette version permet pour la première fois d'exploiter des feuilles de style, notre fameux CSS !

  • HTML 5 : c'est LA dernière version. Encore assez peu répandue, elle fait beaucoup parler d'elle car elle apporte de nombreuses améliorations comme la possibilité d'inclure facilement des vidéos, un meilleur agencement du contenu, de nouvelles fonctionnalités pour les formulaires, etc. C'est cette version que nous allons découvrir ensemble.

Les versions de CSS

  • CSS 1 : dès 1996, on dispose de la première version du CSS. Elle pose les bases de ce langage qui permet de présenter sa page web, comme les couleurs, les marges, les polices de caractères, etc.

  • CSS 2 : apparue en 1999 puis complétée par CSS 2.1, cette nouvelle version de CSS rajoute de nombreuses options. On peut désormais utiliser des techniques de positionnement très précises, qui nous permettent d'afficher des éléments où on le souhaite sur la page.

  • CSS 3 : c'est la dernière version, qui apporte des fonctionnalités particulièrement attendues comme les bordures arrondies, les dégradés, les ombres, etc.

Notez que HTML5 et CSS3 ne sont pas encore des versions totalement finalisées par le W3C. Cependant, même s'il peut y avoir des changements mineurs dans ces langages, je vous recommande chaudement de commencer dès aujourd'hui avec ces nouvelles versions. Leurs apports sont nombreux et valent vraiment le coup. D'ailleurs, de nombreux sites web professionnels se construisent aujourd'hui sur ces dernières versions.

L'éditeur de texte

De quel logiciel vais-je avoir besoin pour créer mon site web ?
Vais-je devoir casser ma tirelire pour acheter un logiciel très complexe que je vais mettre des mois à comprendre ?

Il existe effectivement de nombreux logiciels dédiés à la création de sites web. Mais, je vous rassure, vous n'aurez pas à débourser un seul centime. Pourquoi aller chercher un logiciel payant et compliqué, alors que vous avez déjà tout ce qu'il faut chez vous ?

Eh oui, accrochez-vous bien parce qu'il suffit de… Bloc-Notes (figure suivante) !

Le logiciel Bloc-notes de Windows
Le logiciel Bloc-notes de Windows

Incroyable mais vrai : on peut tout à fait créer un site web uniquement avec Bloc-Notes, le logiciel d'édition de texte intégré par défaut à Windows. D'ailleurs, j'avoue, c'est comme cela que j'ai commencé moi-même il y a quelques années.

Il y a cependant des logiciels plus puissants aujourd'hui et personne n'utilise vraiment Bloc-Notes. On peut classer ces logiciels de création de site web en deux catégories :

  • Les WYSIWYG (What You See Is What You Get - Ce Que Vous Voyez Est Ce Que Vous Obtenez) : ce sont des programmes qui se veulent très faciles d'emploi, ils permettent de créer des sites web sans apprendre de langage particulier. Parmi les plus connus d'entre eux : Mozilla Composer, Microsoft Expression Web, Dreamweaver… et même Word ! Leur principal défaut est la qualité souvent assez mauvaise du code HTML et CSS qui est automatiquement généré par ces outils. Un bon créateur de site web doit tôt ou tard connaître HTML et CSS, c'est pourquoi je ne recommande pas l'usage de ces outils.

  • Les éditeurs de texte : ce sont des programmes dédiés à l'écriture de code. On peut en général les utiliser pour de multiples langages, pas seulement HTML et CSS. Ils se révèlent être de puissants alliés pour les créateurs de sites web !

Vous l'aurez compris, je vais vous inviter à utiliser un éditeur de texte dans ce cours. Voici quelques conseils, selon que vous êtes sous Windows, Mac OS X ou Linux.

Sous Windows

Il existe une grande quantité d'éditeurs de texte, je ne pourrai pas vous les présenter tous. Néanmoins, je vous invite à vous pencher sur Notepad++, l'un des plus utilisés parmi ceux disponibles pour Windows. Ce logiciel est simple, en français et gratuit.

Site web de Notepad++

Voici à quoi ressemble Notepad++ lorsque vous le lancez (figure suivante).

Notepad++

Je vous conseille de faire la manipulation suivante : allez dans le menu Langage > H > HTML. Cela permettra au logiciel de savoir que l'on va taper du HTML.
Lorsque vous utiliserez le logiciel, il colorera votre code (figure suivante), ce qui vous permettra de vous repérer plus facilement.

Coloration sous Notepad++
Coloration sous Notepad++

Pour l'instant, ne vous préoccupez pas de savoir ce que signifie tout ce charabia que vous pouvez voir. Je souhaitais simplement vous donner un aperçu des possibilités du logiciel.

Il existe d'autres éditeurs disponibles sous Windows. Si Notepad++ ne vous convient pas, vous pouvez essayer :

  • jEdit ;

  • PSpad ;

  • ConTEXT ;

  • … et bien d'autres si vous recherchez « Éditeur de texte » sur le Web.

Sous Mac OS X

Vous pouvez essayer l'un des logiciels suivants :

  • jEdit ;

  • Smultron ;

  • TextWrangler.

Sous Linux

Les éditeurs de texte sont légion sous Linux. Certains d'entre eux sont installés par défaut, d'autres peuvent être téléchargés facilement via le centre de téléchargement (sous Ubuntu notamment) ou au moyen de commandes comme apt-get et aptitude. Voici quelques logiciels que vous pouvez tester :

  • gEdit ;

  • Kate ;

  • vim ;

  • Emacs ;

  • jEdit.

Les navigateurs

Pourquoi le navigateur est important

Le navigateur est le programme qui nous permet de voir les sites web. Comme je vous l'ai expliqué plus tôt, le travail du navigateur est de lire le code HTML et CSS pour afficher un résultat visuel à l'écran. Si votre code CSS dit « Les titres sont en rouge », alors le navigateur affichera les titres en rouge. Le rôle du navigateur est donc essentiel !

On ne dirait pas, mais un navigateur est un programme extrêmement complexe. En effet, comprendre le code HTML et CSS n'est pas une mince affaire. Le principal problème, vous vous en rendrez vite compte, c'est que les différents navigateurs n'affichent pas le même site exactement de la même façon ! Il faudra vous y faire et prendre l'habitude de vérifier régulièrement que votre site fonctionne correctement sur la plupart des navigateurs.

Les navigateurs sur ordinateur

Télécharger les navigateurs

Il existe de nombreux navigateurs différents. Voici les principaux à connaître :

Navigateur | OS | Téléchargement | Commentaires
Google Chrome Google Chrome | Windows Mac Linux | Téléchargement | Le navigateur de Google, simple d'emploi et très rapide. C'est le navigateur que j'utilise au quotidien.
Mozilla Firefox Logo Firefox | Windows Mac Linux | Téléchargement | Le navigateur de la fondation Mozilla, célèbre et réputé. Je l'utilise fréquemment pour tester mes sites web.
Internet Explorer IE9 | Windows | Téléchargement (Déjà installé sur Windows) | Le navigateur de Microsoft, qui équipe tous les PC Windows. Je l'utilise fréquemment pour tester mes sites web.
Safari Logo Safari | Windows Mac | Téléchargement (Déjà installé sur Mac OS X) | Le navigateur d'Apple, qui équipe tous les Mac.
Opera Logo Opera | Windows Mac Linux | Téléchargement | L'éternel outsider. Il est moins utilisé mais propose de nombreuses fonctionnalités.

Il est conseillé d'installer plusieurs navigateurs sur son ordinateur pour s'assurer que son site fonctionne correctement sur chacun d'eux. De manière générale, je conseille de tester son site web régulièrement au moins sur Google Chrome, Mozilla Firefox et Internet Explorer.
Notez que Safari et Google Chrome affichent les sites web quasiment de la même façon. Il n'est pas forcément nécessaire de tester son site sur Safari et Google Chrome, même si c'est toujours plus sûr.

La figure suivante vous montre un aperçu du résultat produit par quelques-uns de ces principaux navigateurs sur la page d'accueil de Google.

Aperçu de quelques navigateurs
Aperçu de quelques navigateurs
Comprendre les différences entre navigateurs

Comme je vous le disais plus tôt, les navigateurs n'affichent pas toujours un même site web exactement de la même façon. Pourquoi ? Cela est dû au fait que les navigateurs ne connaissent pas toujours les dernières fonctionnalités de HTML et CSS. Par exemple, Internet Explorer a longtemps été en retard sur certaines fonctionnalités CSS (et paradoxalement, il a aussi été en avance sur quelques autres).

Pour compliquer les choses, plusieurs versions des navigateurs co-existent :

  • Firefox 2, Firefox 3.5, Firefox 3.6, Firefox 4 ;

  • Internet Explorer 6, Internet Explorer 7, Internet Explorer 8, Internet Explorer 9 ;

  • Chrome 8, Chrome 9, Chrome 10 ;

  • etc.

Chaque version prend en charge de nouvelles fonctionnalités mais, si les utilisateurs ne mettent pas à jour leur(s) navigateur(s), cela devient un problème pour les webmasters comme vous qui créent des sites web.
Chrome a résolu en grande partie le problème en mettant en place des mises à jour automatiques, sans intervention de l'utilisateur. Les utilisateurs de Firefox ne pensent pas toujours à mettre à niveau leur navigateur ; quant à Internet Explorer, les utilisateurs sont d'autant moins incités à mettre à jour leur navigateur que les dernières versions nécessitent aussi de passer à une version récente de Windows (Internet Explorer 9 n'est pas disponible pour Windows XP, par exemple).

Des sites comme normansblog.de et caniuse.com tiennent notamment à jour une liste des fonctionnalités CSS prises en charge par les différentes versions de chaque navigateur (figure suivante).

Les fonctionnalités gérées par les différents navigateurs Les fonctionnalités gérées par les différents navigateurs

Comme vous le voyez, c'est… compliqué.

L'essentiel des soucis viendra le plus souvent des anciennes versions d'Internet Explorer (IE6, IE7, IE8). Il faudra vérifier comment le site s'affiche sous ces anciennes versions… Attendez-vous à des surprises ! Vérifiez surtout que votre site s'affiche sans erreur, sans chercher à obtenir exactement le même rendu sur les vieilles versions de ces navigateurs.

Il existe sous Windows un programme appelé IETester. Il permet de vérifier le rendu de son site sous différentes versions d'Internet Explorer. À noter que ce programme est relativement instable (il plante souvent) mais il a le mérite d'exister.

Les navigateurs sur mobile

En plus des navigateurs que je vous ai présentés, il faut savoir qu'il existe des variantes de ces navigateurs conçues pour les téléphones portables, en particulier pour les smartphones.
De plus en plus de personnes consultent aujourd'hui des sites web sur leur portable, il faut donc connaître un minimum le fonctionnement des navigateurs des téléphones.

En fait, vous n'allez pas être dépaysés : la plupart des navigateurs sur smartphones sont les mêmes que sur ordinateur, dans une version plus légère adaptée aux mobiles. Tout dépend du type de téléphone.

  • iPhone : sur l'iPhone d'Apple, le navigateur utilisé est Safari Mobile. Il s'agit d'une version light et néanmoins très complète de Safari pour ordinateur.

  • Android : les portables sous Android bénéficient du navigateur Chrome Mobile. Là encore, il s'agit d'une version adaptée aux mobiles.

  • Windows Phone : sous Windows Phone, on retrouve… Internet Explorer Mobile ! Le principe est le même que pour les précédents navigateurs : il s'agit d'une version dédiée aux mobiles.

  • Blackberry : les Blackberry font exception car ils ont leur propre navigateur (il n'existe pas d'équivalent sur ordinateur). Néanmoins, les versions les plus récentes de ce navigateur se basent sur un noyau commun à Safari et Chrome (il s'agit du moteur de rendu Webkit). Par conséquent, l'affichage est en général proche de celui proposé par Safari et Chrome.

Les navigateurs pour mobiles prennent en charge la plupart des dernières fonctionnalités de HTML et CSS. De plus, le système de mise à jour automatisé des mobiles nous garantit que les utilisateurs auront le plus souvent les dernières versions.

Sachez néanmoins que des différences existent entre ces différents navigateurs mobiles et qu'il est conseillé de tester son site sur ces appareils aussi ! En particulier, l'écran étant beaucoup moins large, il faudra vérifier que votre site s'affiche correctement.

Les tablettes tactiles sont équipées des mêmes navigateurs, l'écran est simplement plus large. Ainsi, l'iPad est fourni avec Safari Mobile.

En résumé

  • Le Web a été inventé par Tim Berners-Lee au début des années 1990.

  • Pour créer des sites web, on utilise deux langages informatiques :

    • HTML : permet d'écrire et organiser le contenu de la page (paragraphes, titres…) ;

    • CSS : permet de mettre en forme la page (couleur, taille…).

  • Il y a eu plusieurs versions des langages HTML et CSS. Les dernières versions sont HTML5 et CSS3.

  • Le navigateur web est un programme qui permet d'afficher des sites web. Il lit les langages HTML et CSS pour savoir ce qu'il doit afficher.

  • Il existe de nombreux navigateurs web différents : Google Chrome, Mozilla Firefox, Internet Explorer, Safari, Opera… Chacun affiche un site web de manière légèrement différente des autres navigateurs.

  • Dans ce cours, nous allons apprendre à utiliser les langages HTML et CSS. Nous travaillerons dans un programme appelé « éditeur de texte » (Notepad++, jEdit, vim…).


Tutoriel VBScript

Votre première page web en HTML

https://vimeo.com/76776333

Ça y est, vous avez installé tous les logiciels ? Vous devriez maintenant avoir un éditeur de texte pour créer votre site (comme Notepad++) et plusieurs navigateurs pour le tester (Mozilla Firefox, Google Chrome, Internet Explorer…).

Dans ce chapitre, nous allons commencer à pratiquer ! Nous allons découvrir les bases du langage HTML et enregistrer notre toute première page web !
Alors oui, bien sûr, ne vous attendez pas encore à réaliser une page web exceptionnelle dès ce second chapitre, mais patience… cela viendra !

Créer une page web avec l'éditeur

Allez, mettons-nous en situation ! Comme je vous l'ai dit, nous allons créer notre site dans un éditeur de texte. Vous avez dû en installer un suite à mes conseils dans le premier chapitre : qu'il s'appelle Notepad++, PSpad, jEdit, vim, TextWrangler… peu importe. Ces logiciels ont un but très simple : vous permettre d'écrire du texte !

Dans la suite de ce cours, je travaillerai avec Notepad++. Je vais donc l'ouvrir (figure suivante).

Ouverture de Notepad++
Ouverture de Notepad++

Bon, qu'est-ce qu'on fait maintenant ? Qu'est-ce qu'on écrit sur cette feuille blanche ?

On va faire un petit essai. Je vous invite à écrire ce qui vous passe par la tête, comme moi à la figure suivante.

Du texte dans Notepad++
Du texte dans Notepad++

Vous pouvez écrire les mêmes phrases que moi ou ce que vous voulez ; le but est d'écrire quelque chose.

Maintenant, enregistrons ce fichier. Pour cela, c'est très simple : comme dans tous les programmes, vous avez un menu Fichier > Enregistrer. Une boîte de dialogue vous demande où enregistrer le fichier et sous quel nom. Enregistrez-le où vous voulez. Donnez au fichier le nom que vous voulez, en terminant par .html, par exemple test.html, comme indiqué à la figure suivante.

Enregistrement d'un fichier sous Notepad++
Enregistrement d'un fichier sous Notepad++

Je vous recommande de créer un nouveau dossier dans vos documents qui contiendra les fichiers de votre site. Pour ma part j'ai créé un dossier test dans lequel j'ai mis mon fichier test.html.

Ouvrez maintenant l'explorateur de fichiers dans le dossier où vous avez enregistré votre page. Vous y verrez le fichier que vous venez de créer (figure suivante).

Le fichier dans l'explorateur
Le fichier dans l'explorateur

L'icône qui représente le fichier dépend de votre navigateur web par défaut. Ici, l'icône est celle de Google Chrome, mon navigateur par défaut, mais le fichier a peut-être une autre icône chez vous. Voici par exemple les icônes qui apparaissent lorsque votre navigateur principal est Firefox ou Internet Explorer (figure suivante).

Icône fichier Firefox
Icône fichier Firefox
Icône fichier Internet Explorer
Icône fichier Internet Explorer

Faites simplement un double-clic sur ce fichier et… votre navigateur s'ouvre et, comme à la figure suivante, affiche le texte que vous avez écrit.

La page web affichée
La page web affichée

Cela ne marche pas bien, on dirait ! Tout le texte s'affiche sur la même ligne alors qu'on avait écrit deux lignes de texte différentes !?

En effet, bien vu !
Le texte s'affiche sur la même ligne alors qu'on avait demandé à l'écrire sur deux lignes différentes. Que se passe-t-il ?

En fait, pour créer une page web il ne suffit pas de taper simplement du texte comme on vient de le faire. En plus de ce texte, il faut aussi écrire ce qu'on appelle des balises, qui vont donner des instructions à l'ordinateur comme « aller à la ligne », « afficher une image », etc.

Les balises et leurs attributs

Bon, tout cela était trop facile. Évidemment, il a fallu que ces satanés informaticiens s'en mêlent et compliquent les choses. Il ne suffit pas d'écrire « simplement » du texte dans l'éditeur, il faut aussi donner des instructions à l'ordinateur. En HTML, on utilise pour cela des balises.

Les balises

Les pages HTML sont remplies de ce qu'on appelle des balises. Celles-ci sont invisibles à l'écran pour vos visiteurs, mais elles permettent à l'ordinateur de comprendre ce qu'il doit afficher.
Les balises se repèrent facilement. Elles sont entourées de « chevrons », c'est-à-dire des symboles < et >, comme ceci : <balise>

À quoi est-ce qu'elles servent ? Elles indiquent la nature du texte qu'elles encadrent. Elles veulent dire par exemple : « Ceci est le titre de la page », « Ceci est une image », « Ceci est un paragraphe de texte », etc.

On distingue deux types de balises : les balises en paires et les balises orphelines.

Les balises en paires

Elles s'ouvrent, contiennent du texte, et se ferment plus loin. Voici à quoi elles ressemblent :

<titre>Ceci est un titre</titre>

On distingue une balise ouvrante (<titre>) et une balise fermante (</titre>) qui indique que le titre se termine. Cela signifie pour l'ordinateur que tout ce qui n'est pas entre ces deux balises… n'est pas un titre.

Ceci n'est pas un titre <titre>Ceci est un titre</titre> Ceci n'est pas un titre
Les balises orphelines

Ce sont des balises qui servent le plus souvent à insérer un élément à un endroit précis (par exemple une image). Il n'est pas nécessaire de délimiter le début et la fin de l'image, on veut juste dire à l'ordinateur « Insère une image ici ».

Une balise orpheline s'écrit comme ceci :

<image />

Notez que le / de fin n'est pas obligatoire. On pourrait écrire seulement <image>. Néanmoins, pour ne pas les confondre avec le premier type de balise, les webmasters recommandent de rajouter ce / (slash) à la fin des balises orphelines. Vous me verrez donc mettre un / aux balises orphelines et je vous recommande de faire de même, c'est une bonne pratique.

Les attributs

Les attributs sont un peu les options des balises. Ils viennent les compléter pour donner des informations supplémentaires. L'attribut se place après le nom de la balise ouvrante et a le plus souvent une valeur, comme ceci :

<balise attribut="valeur">

À quoi cela sert-il ? Prenons la balise <image /> que nous venons de voir. Seule, elle ne sert pas à grand chose. On pourrait rajouter un attribut qui indique le nom de l'image à afficher :

<image nom="photo.jpg" />

L'ordinateur comprend alors qu'il doit afficher l'image contenue dans le fichier photo.jpg.

Dans le cas d'une balise fonctionnant « par paire », on ne met les attributs que dans la balise ouvrante et pas dans la balise fermante. Par exemple, ce code indique que la citation est de Neil Armstrong et qu'elle date du 21 Juillet 1969 :

<citation auteur="Neil Armstrong" date="21/07/1969">
C'est un petit pas pour l'homme, mais un bond de géant pour l'humanité.
</citation>

Toutes les balises que nous venons de voir sont fictives. Les vraies balises ont des noms en anglais (eh oui !), nous allons les découvrir dans la suite de ce cours.

Structure de base d'une page HTML5

Reprenons notre éditeur de texte (dans mon cas Notepad++). Je vous invite à écrire ou à copier-coller le code source ci-dessous dans Notepad++. Ce code correspond à la base d'une page web en HTML5 :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Titre</title>
    </head>

    <body>

    </body>
</html>

J'ai mis des espaces au début de certaines lignes pour « décaler » les balises. Ce n'est pas obligatoire et cela n'a aucun impact sur l'affichage de la page, mais cela rend le code source plus lisible. On appelle cela l'indentation. Dans votre éditeur, il suffit d'appuyer sur la touche Tab pour avoir le même résultat.

Copié dans Notepad++, cela donne la figure suivante.

Code HTML5 minimal dans Notepad++
Code HTML5 minimal dans Notepad++

Vous noterez que les balises s'ouvrent et se ferment dans un ordre précis. Par exemple, la balise <html> est la première que l'on ouvre et c'est aussi la dernière que l'on ferme (tout à la fin du code, avec </html>). Les balises doivent être fermées dans le sens inverse de leur ouverture. Un exemple :

  • <html><body></body></html> : correct. Une balise qui est ouverte à l'intérieur d'une autre doit aussi être fermée à l'intérieur.

  • <html><body></html></body> : incorrect, les balises s'entremêlent.

Euh, on pourrait avoir des explications sur toutes les balises que l'on vient de copier dans l'éditeur, m'sieur ?

Bien sûr, c'est demandé si gentiment.
Ne prenez pas peur en voyant toutes ces balises d'un coup, je vais vous expliquer leur rôle !

Le doctype

<!DOCTYPE html>

La toute première ligne s'appelle le doctype. Elle est indispensable car c'est elle qui indique qu'il s'agit bien d'une page web HTML.
Ce n'est pas vraiment une balise comme les autres (elle commence par un point d'exclamation), vous pouvez considérer que c'est un peu l'exception qui confirme la règle.

Cette ligne du doctype était autrefois incroyablement complexe. Il était impossible de la retenir de tête. Pour XHTML 1.0, il fallait écrire :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">.
Dans le cadre de HTML5, il a été décidé de la simplifier, pour le plus grand bonheur des webmasters. Quand vous voyez une balise doctype courte (<!DOCTYPE html>), cela signifie que la page est écrite en HTML5.

La balise </html>

<html>

</html>

C'est la balise principale du code. Elle englobe tout le contenu de votre page. Comme vous pouvez le voir, la balise fermante </html> se trouve tout à la fin du code !

L'en-tête <head> et le corps <body>

Une page web est constituée de deux parties :

  • L'en-tête <head> : cette section donne quelques informations générales sur la page comme son titre, l'encodage (pour la gestion des caractères spéciaux), etc. Cette section est généralement assez courte. Les informations que contient l'en-tête ne sont pas affichées sur la page, ce sont simplement des informations générales à destination de l'ordinateur. Elles sont cependant très importantes !

  • Le corps <body> : c'est là que se trouve la partie principale de la page. Tout ce que nous écrirons ici sera affiché à l'écran. C'est à l'intérieur du corps que nous écrirons la majeure partie de notre code.

Pour le moment, le corps est vide (nous y reviendrons plus loin). Intéressons-nous par contre aux deux balises contenues dans l'en-tête…

L'encodage (charset)
<meta charset="utf-8" />

Cette balise indique l'encodage utilisé dans votre fichier .html.

Sans rentrer dans les détails, car cela pourrait vite devenir compliqué, l'encodage indique la façon dont le fichier est enregistré. C'est lui qui détermine comment les caractères spéciaux vont s'afficher (accents, idéogrammes chinois et japonais, caractères arabes, etc.).

Il y a plusieurs techniques d'encodage portant des noms bizarres et utilisées en fonction des langues : ISO-8859-1, OEM 775, Windows-1253… Une seule cependant devrait être utilisée aujourd'hui autant que possible : UTF-8. Cette méthode d'encodage permet d'afficher sans aucun problème pratiquement tous les symboles de toutes les langues de notre planète ! C'est pour cela que j'ai indiqué utf-8 dans cette balise.

Il faut aussi que votre fichier soit bien enregistré en UTF-8. C'est le cas le plus souvent sous Linux par défaut mais, sous Windows, il faut généralement le dire au logiciel.

Sous Notepad++, allez dans le menu Encodage > Encoder en UTF-8 (sans BOM) pour que votre fichier soit enregistré en UTF-8 dès le début. Cela ne s'applique qu'au fichier actuellement ouvert.
Pour ne pas avoir à le faire pour chaque nouveau fichier, je vous conseille d'aller dans le menu Paramétrage > Préférences, onglet Nouveau document/Dossier. Sélectionnez UTF-8 sans BOM dans la liste.

Si vous avez un problème d'affichage des accents plus tard sur votre page web, c'est qu'il y a un problème avec l'encodage. Vérifiez que la balise indique bien UTF-8 et que votre fichier est enregistré en UTF-8 (votre éditeur de texte est capable de vous le dire, Notepad++ le fait dans le menu Encodage).

Le titre principal de la page
<title>

C'est le titre de votre page, probablement l'élément le plus important ! Toute page doit avoir un titre qui décrit ce qu'elle contient.
Il est conseillé de garder le titre assez court (moins de 100 caractères en général).

Le titre ne s'affiche pas dans votre page mais en haut de celle-ci (souvent dans l'onglet du navigateur). Enregistrez votre page web et ouvrez-la dans votre navigateur. Vous verrez que le titre s'affiche dans l'onglet, comme sur la figure suivante.

Le titre de la page apparaît en haut du navigateur
Le titre de la page apparaît en haut du navigateur

Il faut savoir que le titre apparaît aussi dans les résultats de recherche, comme sur Google (figure suivante).

Le titre de la page apparaît dans les recherches Google
Le titre de la page apparaît dans les recherches Google

Autant vous dire que bien choisir son titre est important !

Les commentaires

Nous avons appris à créer notre première vraie page HTML dans ce chapitre. Avant de terminer, j'aimerais vous présenter le principe des commentaires.

Un commentaire en HTML est un texte qui sert simplement de mémo. Il n'est pas affiché, il n'est pas lu par l'ordinateur, cela ne change rien à l'affichage de la page.

Bref, cela ne sert à rien ?

Eh bien si !
Cela sert à vous et aux personnes qui liront le code source de votre page. Vous pouvez utiliser les commentaires pour laisser des indications sur le fonctionnement de votre page.

Quel intérêt ? Cela vous permettra de vous rappeler comment fonctionne votre page si vous revenez sur votre code source après un long moment d'absence. Ne rigolez pas, cela arrive à tous les webmasters.

Insérer un commentaire

Un commentaire est une balise HTML avec une forme bien spéciale :

<!-- Ceci est un commentaire -->

Vous pouvez le mettre où vous voulez au sein de votre code source : il n'a aucun impact sur votre page, mais vous pouvez vous en servir pour vous aider à vous repérer dans votre code source (surtout s'il est long).

<!DOCTYPE html>
<html>
    <head>
        <!-- En-tête de la page -->
        <meta charset="utf-8" />
        <title>Titre</title>
    </head>

    <body>
        <!-- Corps de la page -->
    </body>
</html>

Tout le monde peut voir vos commentaires… et tout votre code HTML !

Terminons par une remarque importante : tout le monde peut voir le code HTML de votre page une fois celle-ci mise en ligne sur le Web. Il suffit de faire un clic droit sur la page et de sélectionner « Afficher le code source de la page » (l'intitulé peut changer selon votre navigateur), comme le montre la figure suivante.

Menu afficher le code source
Menu afficher le code source

Le code source s'affiche alors (figure suivante).

Affichage du code source
Affichage du code source

Vous pouvez tester cette manipulation sur n'importe quel site web, cela marche ! Garanti à 100%. Cela s'explique assez facilement : le navigateur doit obtenir le code HTML pour savoir ce qu'il faut afficher. Le code HTML de tous les sites est donc public.

La morale de l'histoire ? Tout le monde pourra voir votre code HTML et vous ne pouvez pas l'empêcher. Par conséquent, ne mettez pas d'informations sensibles comme des mots de passe dans les commentaires… et soignez votre code source, car je pourrai venir vérifier si vous avez bien suivi mon cours à la lettre !

Lorsque vous regarderez le code de certains sites web, ne prenez pas peur s'il vous paraît long ou ne pas respecter les mêmes règles que celles que je vous présente dans ce livre. Tous les sites ne sont pas écrits en HTML5 (loin de là) et, parfois, certains webmasters rédigent très mal leur code, ce ne sont pas toujours des exemples à suivre !

En résumé

  • On utilise l'éditeur de texte (Notepad++, jEdit, vim…) pour créer un fichier ayant l'extension .html (par exemple : test.html). Ce sera notre page web.

  • Ce fichier peut être ouvert dans le navigateur web simplement en faisant un double-clic dessus.

  • À l'intérieur du fichier, nous écrirons le contenu de notre page, accompagné de balises HTML.

  • Les balises peuvent avoir plusieurs formes :

    • <balise> </balise> : elles s'ouvrent et se ferment pour délimiter le contenu (début et fin d'un titre, par exemple).

    • <balise /> : balises orphelines (on ne les insère qu'en un seul exemplaire), elles permettent d'insérer un élément à un endroit précis (par exemple une image).

  • Les balises sont parfois accompagnées d'attributs pour donner des indications supplémentaires (exemple : <image nom="photo.jpg" />).

  • Une page web est constituée de deux sections principales : un en-tête (<head>) et un corps (<body>).

  • On peut afficher le code source de n'importe quelle page web en faisant un clic droit puis en sélectionnant Afficher le code source de la page.


Tutoriel VBScript

Organiser son texte

https://vimeo.com/76776336

Bon, la page blanche c'est bien joli, mais votre site web risque d'avoir un succès mitigé si vous le laissez comme cela.

Nous allons découvrir de nombreuses balises HTML dans ce chapitre. Certaines existent depuis la toute première version de HTML, d'autres ont été introduites plus récemment dans HTML5.

Nous allons voir successivement dans ce chapitre :

  • comment rédiger des paragraphes ;

  • comment structurer sa page avec les titres ;

  • comment donner de l'importance à certains mots de son texte ;

  • comment organiser les informations sous forme de listes.

Motivés ? Allez, vous allez voir, ce n'est pas compliqué.

Les paragraphes

La plupart du temps, lorsqu'on écrit du texte dans une page web, on le fait à l'intérieur de paragraphes. Le langage HTML propose justement la balise <p> pour délimiter les paragraphes.

<p>Bonjour et bienvenue sur mon site !</p>

  • <p> signifie « Début du paragraphe » ;

  • </p> signifie « Fin du paragraphe ».

Comme je vous l'ai dit au chapitre précédent, on écrit le contenu du site web entre les balises <body></body>. Il nous suffit donc de mettre notre paragraphe entre ces deux balises et nous aurons enfin notre première vraie page web avec du texte !

Je reprends donc exactement le même code qu'au chapitre précédent et j'y ajoute mon paragraphe :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Paragraphes</title>
    </head>

    <body>
        <p>Bonjour et bienvenue sur mon site !</p>
    </body>
</html>

Essayez, vous allez voir le résultat !
Bon, ok, ce n'est pas encore le nirvana mais c'est un bon début.

Mais ne nous arrêtons pas en si bon chemin. Nous allons voir maintenant quelque chose d'un peu particulier en HTML : le saut de ligne. Cela paraît simple et pourtant, cela ne fonctionne pas vraiment comme dans un traitement de texte habituel…

Sauter une ligne

En HTML, si vous appuyez sur la touche Entrée, cela ne crée pas une nouvelle ligne comme vous en avez l'habitude. Essayez donc ce code :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Essais de sauts de ligne</title>
    </head>

    <body>
        <p>Bonjour et bienvenue sur mon site !
            Ceci est mon premier test alors soyez indulgents s'il vous plaît, j'apprends petit à petit comment cela marche.
            Pour l'instant c'est un peu vide, mais revenez dans 2-3 jours quand j'aurai appris un peu plus de choses, je vous assure que vous allez être surpris !</p>
    </body>
</html>

Tout le texte s'affiche sur la même ligne alors qu'on est bien allé à la ligne dans le code ! Taper frénétiquement sur la touche Entrée dans l'éditeur de texte ne sert donc strictement à rien.

Comme vous devez vous en douter, il y a pourtant bien un moyen de faire des sauts de ligne en HTML.

En fait, si vous voulez écrire un deuxième paragraphe, il vous suffit d'utiliser une deuxième balise <p>.
Votre code HTML devrait donc être au final rempli de balises de paragraphe !

Un exemple :

<html>
    <head>
        <meta charset="utf-8" />
        <title>Paragraphes</title>
    </head>

    <body>
        <p>Bonjour et bienvenue sur mon site !
        Ceci est mon premier test alors soyez indulgents s'il vous plaît, j'apprends petit à petit comment cela marche.</p>

        <p>Pour l'instant c'est un peu vide, mais revenez dans 2-3 jours quand j'aurai appris un peu plus de choses, je vous assure que vous allez être surpris !</p>
    </body>
</html>

Le résultat se trouve à la figure suivante.

Deux paragraphes avec 2 balises <p>
Deux paragraphes avec 2 balises <p>

Oui, mais si je veux juste aller à la ligne dans un paragraphe et non pas sauter une ligne ?

Eh bien devinez quoi : il existe une balise « Aller à la ligne » !
C'est une balise orpheline qui sert juste à indiquer qu'on doit aller à la ligne : <br />. Vous devez obligatoirement la mettre à l'intérieur d'un paragraphe.

Voici comment l'utiliser dans un code :

<html>
    <head>
        <meta charset="utf-8" />
        <title>Sauts de ligne</title>
    </head>

    <body>
        <p>Bonjour et bienvenue sur mon site !<br />
        Ceci est mon premier test alors soyez indulgents s'il vous plaît, j'apprends petit à petit comment cela marche.</p>

        <p>Pour l'instant c'est un peu vide, mais revenez dans 2-3 jours quand j'aurai appris un peu plus de choses, je vous assure que vous allez être surpris !</p>
    </body>
</html>

Vous pouvez théoriquement mettre plusieurs balises <br /> d'affilée pour faire plusieurs sauts de lignes, mais on considère que c'est une mauvaise pratique qui rend le code délicat à maintenir. Pour décaler un texte avec plus de précision, on utilisera le CSS, ce langage qui vient compléter le HTML et dont je vous parlerai un peu plus loin.

Donc c'est compris ?

  • <p> </p> : pour organiser son texte en paragraphes ;

  • <br /> : pour aller à la ligne.

Maintenant qu'on sait écrire des paragraphes, voyons voir comment on crée des titres.

Les titres

Lorsque le contenu de votre page va s'étoffer avec de nombreux paragraphes, il va devenir difficile pour vos visiteurs de se repérer. C'est là que les titres deviennent utiles.

En HTML, on est verni, on a le droit d'utiliser six niveaux de titres différents. Je veux dire par là qu'on peut dire « Ceci est un titre très important », « Ceci est un titre un peu moins important », « Ceci est un titre encore moins important », etc. On a donc six balises de titres différentes :

  • <h1> </h1> : signifie « titre très important ». En général, on s'en sert pour afficher le titre de la page au début de celle-ci.

  • <h2> </h2> : signifie « titre important ».

  • <h3> </h3> : pareil, c'est un titre un peu moins important (on peut dire un « sous-titre » si vous voulez).

  • <h4> </h4> : titre encore moins important.

  • <h5> </h5> : titre pas important.

  • <h6> </h6> : titre vraiment, mais alors là vraiment pas important du tout.

Attention : ne confondez pas avec la balise <title> ! La balise <title> affiche le titre de la page dans la barre de titre du navigateur comme nous l'avons vu. Les titres <h1> et compagnie, eux, servent à créer des titres qui seront affichés dans la page web.

Ne vous laissez pas impressionner par toutes ces balises. En fait, six niveaux de titres, c'est beaucoup. Dans la pratique, personnellement, je n'utilise que les balises <h1>, <h2> et <h3>, et très rarement les autres (je n'ai pas souvent besoin de six niveaux de titres différents). Votre navigateur affiche le titre très important en très gros, le titre un peu moins important en un peu moins gros, etc.

Ne choisissez pas votre balise de titre en fonction de la taille qu'elle applique au texte ! Il faut impérativement bien structurer sa page en commençant par un titre de niveau 1 (<h1>), puis un titre de niveau 2 (<h2>), etc. Il ne devrait pas y avoir de sous-titre sans titre principal !
Si vous voulez modifier la taille du texte, sachez que nous apprendrons à faire cela en CSS un peu plus tard.

Essayez de créer une page web avec des titres pour voir ce que cela donne :

<html>
    <head>
        <meta charset="utf-8" />
        <title>Niveaux de titres</title>
    </head>

    <body>
        <h1>Titre super important</h1>
        <h2>Titre important</h2>
        <h3>Titre un peu moins important (sous-titre)</h3>

        <h4>Titre pas trop important</h4>
        <h5>Titre pas important</h5>
        <h6>Titre vraiment pas important du tout</h6>
    </body>
</html>

Allez, je vous donne un exemple d'utilisation des titres dans une page web (vous allez voir que je ne me sers pas de toutes les balises) :

<html>
<head>
    <meta charset="utf-8" />
    <title>Présentation du Site du Zéro</title>
</head>

<body>
    <h1>Bienvenue sur le Site du Zéro !</h1>

    <p>Bonjour et bienvenue sur mon site : le Site du Zéro.<br />
       Le Site du Zéro, qu'est-ce que c'est ?</p>

    <h2>Des cours pour débutants</h2>

    <p>Le Site du Zéro vous propose des cours (tutoriels) destinés aux débutants : aucune connaissance n'est requise pour lire ces cours !</p>

    <p>Vous pourrez ainsi apprendre, sans rien y connaître auparavant, à créer un site web, à programmer, à construire des mondes en 3D !</p>

    <h2>Une communauté active</h2>

    <p>Vous avez un problème, un élément du cours que vous ne comprenez pas ? Vous avez besoin d'aide pour créer votre site ?<br />
    Rendez-vous sur les forums ! Vous y découvrirez que vous n'êtes pas le seul dans ce cas et vous trouverez très certainement quelqu'un qui vous aidera aimablement à résoudre votre problème.</p>
</body>
</html>

Voilà une page web qui prend forme !

Oui, mais moi je veux centrer mon titre, l'écrire en rouge et le souligner !

Nous ferons tout cela lorsque nous apprendrons le CSS (dès la deuxième partie du cours). Il faut savoir que <h1> ne signifie pas « Times New Roman, taille 16 pt », mais « Titre important ».

Grâce au langage CSS, vous pourrez dire « Je veux que mes titres importants soient centrés, rouges et soulignés ». Pour le moment, en HTML, nous ne faisons que structurer notre page. Nous rédigeons le contenu avant de nous amuser à le mettre en forme.

La mise en valeur

Au sein de vos paragraphes, certains mots sont parfois plus importants que d'autres et vous aimeriez les faire ressortir. HTML vous propose différents moyens de mettre en valeur le texte de votre page.

Mettre un peu en valeur

Pour mettre un peu en valeur votre texte, vous devez utiliser la balise <em> </em>.
Son utilisation est très simple : encadrez les mots à mettre en valeur avec ces balises et c'est bon ! Je reprends un peu l'exemple de tout à l'heure et j'y mets quelques mots en évidence :

<html>
<head>
    <meta charset="utf-8" />
    <title>Emphase</title>
</head>

<body>
    <p>Bonjour et bienvenue sur mon site !<br />
    Ceci est mon premier test alors <em>soyez indulgents</em> s'il vous plaît, j'apprends petit à petit comment cela marche.</p>
</body>
</html>

Comme vous pouvez le voir, utiliser la balise <em> a pour conséquence de mettre le texte en italique. En fait, c'est le navigateur qui choisit comment afficher les mots. On lui dit que les mots sont assez importants et, pour faire ressortir cette information, il change l'apparence du texte en utilisant l'italique.

Mettre bien en valeur

Pour mettre un texte bien en valeur, on utilise la balise <strong> qui signifie « fort », ou « important » si vous préférez. Elle s'utilise exactement de la même manière que <em> :

<html>
<head>
    <meta charset="utf-8" />
    <title>Forte emphase</title>
</head>

<body>
    <p>Bonjour et bienvenue sur mon site !<br />
    Ceci est mon premier test alors <strong>soyez indulgents</strong> s'il vous plaît, j'apprends petit à petit comment cela marche.</p>
</body>
</html>

Vous voyez sûrement le texte s'afficher en gras. Là encore, le gras n'est qu'une conséquence. Le navigateur a choisi d'afficher en gras les mots importants pour les faire ressortir davantage.

La balise <strong> ne signifie pas « mettre en gras » mais « important ». On pourra décider plus tard, en CSS, d'afficher les mots « importants » d'une autre façon que le gras si on le souhaite.

Marquer le texte

La balise <mark> permet de faire ressortir visuellement une portion de texte. L'extrait n'est pas forcément considéré comme important mais on veut qu'il se distingue bien du reste du texte. Cela peut être utile pour faire ressortir un texte pertinent après une recherche sur votre site par exemple.

<html>
<head>
    <meta charset="utf-8" />
    <title>Marquage du texte</title>
</head>

<body>
    <p>Bonjour et bienvenue sur mon site !<br />
    Ceci est mon premier test alors <mark>soyez indulgents</mark> s'il vous plaît, j'apprends petit à petit comment cela marche.</p>
</body>
</html>

Par défaut, <mark> a pour effet de surligner le texte. On pourra changer l'affichage en CSS (décider de surligner dans une autre couleur, d'encadrer le texte, etc.). C'est le même principe que ce que je vous disais pour les balises précédentes : elles indiquent le sens des mots et non pas comment ceux-ci doivent s'afficher.

N'oubliez pas : HTML pour le fond, CSS pour la forme

Je vais peut-être vous sembler un peu lourd mais il est très important qu'on se comprenne bien car les débutants font souvent la même grosse erreur à ce stade. Ils ont vu les balises <em>, <strong>, <mark>… et ils se disent : « Chouette, j'ai découvert comment mettre en italique, en gras et comment surligner du texte en HTML ! ».

Et pourtant… ce n'est pas à cela que servent ces balises ! Je sais, je sais, vous allez me dire « Oui mais quand j'utilise <strong> le texte apparaît en gras, donc c'est pour mettre en gras. » et pourtant, c'est une erreur de croire que cette balise sert à cela.

Le rôle des balises est d'indiquer le sens du texte. Ainsi, <strong> indique à l'ordinateur « Ce texte est important ». C'est tout.
Et pour montrer que le texte est important, l'ordinateur décide de le mettre en gras (mais il pourrait aussi bien l'écrire en rouge !). La plupart des navigateurs affichent les textes importants en gras, mais rien ne les y oblige.

Je ne comprends pas. À quoi cela sert-il que l'ordinateur sache qu'un texte est important ?
Il n'est pas assez intelligent pour comprendre !

Détrompez-vous ! De nombreux programmes analysent le code source des pages web, à commencer par les robots de moteurs de recherche. Ces robots parcourent le Web en lisant le code HTML de tous les sites. C'est le cas des robots de Google et de Bing, par exemple. Les mots-clés « importants » ont tendance à avoir plus de valeur à leurs yeux, donc si quelqu'un fait une recherche sur ces mots, il a plus de chances de tomber sur votre site.
Bien entendu, c'est une explication grossière et il ne faut pas croire qu'utiliser la balise <strong> à tout-va améliorera votre référencement. Il faut simplement faire confiance aux ordinateurs : ils comprennent ce qu'un texte « important » veut dire et peuvent se servir de cette information.

Mais alors, comment fait-on pour mettre spécifiquement en gras, pour écrire en rouge, et tout et tout ?

Tout cela se fait en CSS. Souvenez-vous :

  • le HTML définit le fond (contenu, logique des éléments) ;

  • le CSS définit la forme (apparence).

Nous verrons le CSS plus loin, pour l'instant nous nous concentrons sur le HTML et ses balises, qui ont chacune un sens particulier.

Les listes

Les listes nous permettent souvent de mieux structurer notre texte et d'ordonner nos informations.
Nous allons découvrir ici deux types de listes :

  • les listes non ordonnées ou listes à puces ;

  • les listes ordonnées ou listes numérotées ou encore énumérations.

Liste non ordonnée

Une liste non ordonnée ressemble à ceci :

  • Fraises

  • Framboises

  • Cerises

C'est un système qui nous permet de créer une liste d'éléments sans notion d'ordre (il n'y a pas de « premier » ni de « dernier »). Créer une liste non ordonnée est très simple. Il suffit d'utiliser la balise <ul> que l'on referme un peu plus loin avec </ul>.
Commencez donc à taper ceci :

<ul></ul>

Et maintenant, voilà ce qu'on va faire : on va écrire chacun des éléments de la liste entre deux balises <li></li>. Chacune de ces balises doit se trouver entre <ul> et </ul>. Vous allez comprendre de suite avec cet exemple :

<ul>
    <li>Fraises</li>
    <li>Framboises</li>
    <li>Cerises</li>
</ul>

Le résultat se trouve à la figure suivante.

Une liste non ordonnée
Une liste non ordonnée

Notez que la liste doit être placée à l'intérieur de <body></body>. À partir de maintenant, je ne mets pas tout le code de la page pour rester lisible.

Retenez donc ces deux balises :

  • <ul></ul> délimite toute la liste ;

  • <li></li> délimite un élément de la liste (une puce).

Vous pouvez mettre autant d'éléments que vous voulez dans la liste à puces, vous n'êtes pas limités à trois éléments.

Et voilà, vous savez créer une liste à puces ! Pas si dur une fois qu'on a compris comment imbriquer les balises.

Pour ceux qui ont besoin de faire des listes complexes, sachez que vous pouvez imbriquer des listes à puces (créer une liste à puces dans une liste à puces). Si vous voulez faire ça, ouvrez une seconde balise <ul>à l'intérieur d'un élément <li></li>.
Si vous fermez les balises dans le bon ordre, vous n'aurez pas de problème. Attention néanmoins, cette technique est un peu compliquée à maîtriser.

Liste ordonnée

Une liste ordonnée fonctionne de la même façon, seule une balise change : il faut remplacer <ul></ul> par <ol></ol>.
À l'intérieur de la liste, on ne change rien : on utilise toujours des balises <li></li> pour délimiter les éléments.

L'ordre dans lequel vous placez les éléments de la liste est important. Le premier <li></li> sera l'élément n° 1, le second sera le n°2 etc…

Comme c'est particulièrement intuitif, je vous laisse admirer la simplicité de cet exemple (résultat à la figure suivante) :

<h1>Ma journée</h1>

<ol>
    <li>Je me lève.</li>
    <li>Je mange et je bois.</li>
    <li>Je retourne me coucher.</li>
</ol>
Une liste ordonnée
Une liste ordonnée

Par rapport à l'exemple précédent, tout ce qu'on a eu à changer est donc la balise <ol>.

Pour information, il existe un troisième type de liste, beaucoup plus rare : la liste de définitions. Elle fait intervenir les balises <dl> (pour délimiter la liste), <dt> (pour délimiter un terme) et <dd> (pour délimiter la définition de ce terme).

En résumé

  • Le HTML comporte de nombreuses balises qui nous permettent d'organiser le texte de notre page. Ces balises donnent des indications comme « Ceci est un paragraphe », « Ceci est un titre », etc.

  • Les paragraphes sont définis par la balise <p> </p> et les sauts de ligne par la balise <br />.

  • Il existe six niveaux de titre, de <h1> </h1> à <h6> </h6>, à utiliser selon l'importance du titre.

  • On peut mettre en valeur certains mots avec les balises <strong>, <em> et <mark>.

  • Pour créer des listes, on doit utiliser la balise <ul> (liste à puces, non ordonnée) ou <ol> (liste ordonnée). À l'intérieur, on insère les éléments avec une balise <li> pour chaque item.


Tutoriel VBScript

Créer des liens

https://vimeo.com/76845163

Au chapitre précédent, vous avez appris à créer une page HTML toute simple. D'accord, elle n'était pas franchement magnifique, mais c'était une vraie page HTML quand même.

Comme vous le savez, un site web est composé de plusieurs pages. Comment faire pour aller d'une page vers une autre ? À l'aide de liens pardi ! Dans ce chapitre, nous allons justement apprendre à créer des liens entre nos pages.

Je suppose que chacun d'entre vous sait ce qu'est un lien : il s'agit d'un texte sur lequel on peut cliquer pour se rendre sur une autre page.
On peut faire un lien d'une page a.html vers une page b.html, mais on peut aussi faire un lien vers un autre site (par exemple, http://www.siteduzero.com). Dans les deux cas, nous allons voir que le fonctionnement est le même.

Un lien vers un autre site

Il est facile de reconnaître les liens sur une page : ils sont écrits d'une façon différente (par défaut, en bleu et soulignés) et un curseur en forme de main apparaît lorsqu'on pointe dessus.

Je vous propose d'essayer de coder le lien qui amène vers le Site du Zéro, comme à la figure suivante.

Lien vers le Site du Zéro
Lien vers le Site du Zéro

Pour faire un lien, la balise que nous allons utiliser est très simple à retenir : <a>. Il faut cependant lui ajouter un attribut, href, pour indiquer vers quelle page le lien doit conduire.

Par exemple, le code ci-dessous est un lien qui amène vers le Site du Zéro, situé à l'adresse http://www.siteduzero.com :

<a href="http://www.siteduzero.com">Site du Zéro</a>

Nous allons placer ce lien au sein d'un paragraphe. Voici donc comment reproduire l'exemple de la figure précédente :

<p>Bonjour. Souhaitez-vous visiter le <a href="http://www.siteduzero.com">Site du Zéro</a> ?<br />
C'est un bon site ! ;-)</p>

Par défaut, le lien s'affiche en bleu souligné. Si vous avez déjà ouvert la page, le lien s'affiche en violet.
Nous verrons comment changer cette apparence lorsque nous étudierons le CSS.

Si vous voulez faire un lien vers un autre site, il suffit donc de copier son adresse (on parle d'URL) en http://. Notez que certains liens commencent parfois par https:// (sites sécurisés) ou d'autres préfixes (ftp://,…).

Si vous faites un lien vers un site qui comporte une adresse un peu bizarre avec des &, comme : http://www.site.com/?data=15&name=mateo21, vous devrez remplacer tous les « & » par « &amp; » dans votre lien comme ceci : http://www.site.com/?data=15&amp;name=mateo21.
Vous ne verrez pas la différence, mais cela est nécessaire pour avoir une page web correctement construite en HTML5.

Les liens que nous venons de voir sont appelés liens absolus car on indique l'adresse complète. Nous allons maintenant voir que l'on peut écrire les liens d'une façon un peu différente, ce qui va nous être utile pour faire des liens entre les pages de notre site.

Un lien vers une autre page de son site

Nous venons d'apprendre à créer des liens vers des sites existants. Mais je suis sûr que vous aimeriez faire des liens entre les différentes pages de votre site, non ?

Oui, justement, comment je fais pour faire un lien vers une autre page de mon site ? Je ne connais pas son adresse en http://…, je commence à peine à créer mon site là ! Je n'ai pas d'adresse.

En effet, pour le moment, vous êtes en train de créer votre site sur votre ordinateur. Vous êtes le seul à pouvoir le voir et il n'a pas encore « d'adresse web » qui commence en http:// comme la plupart des sites. Heureusement, cela ne va pas nous empêcher de travailler.

Deux pages situées dans un même dossier

Pour commencer, nous allons créer deux fichiers correspondant à deux pages HTML différentes. Comme je suis très inspiré, je vous propose de les appeler page1.html et page2.html. Nous aurons donc ces deux fichiers sur notre disque dans le même dossier (figure suivante).

Plusieurs fichiers HTML dans un même dossier
Plusieurs fichiers HTML dans un même dossier

Comment faire un lien de la page 1 vers la page 2, sans avoir d'adresse en http:// ? En fait, c'est facile : si les deux fichiers sont situés dans le même dossier, il suffit d'écrire comme cible du lien le nom du fichier vers lequel on veut amener. Par exemple : <a href="page2.html">. On dit que c'est un lien relatif.

Voici le code que nous allons utiliser dans nos fichiers page1.html et page2.html.

page1.html
<p>Bonjour. Souhaitez-vous consulter <a href="page2.html">la page 2</a> ?</p>
page2.html

La page 2 (page d'arrivée) affichera simplement un message pour indiquer que l'on est bien arrivé sur la page 2 :

<h1>Bienvenue sur la page 2 !</h1>

Deux pages situées dans des dossiers différents

Les choses se corsent un petit peu si les pages sont situées dans des dossiers différents. Idéalement, elles ne devraient pas être trop loin l'une de l'autre (dans un sous-dossier par exemple).

Imaginons que page2.html se trouve dans un sous-dossier appelé contenu, comme à la figure suivante.

Le fichier page2.html se trouve à l'intérieur du dossier contenu
Le fichier page2.html se trouve à l'intérieur du dossier contenu

Dans ce cas de figure, le lien doit être rédigé comme ceci :

<a href="contenu/page2.html">

S'il y avait plusieurs sous-dossiers, on écrirait ceci :

<a href="contenu/autredossier/page2.html">

Et si le fichier ne se trouve pas dans un sous-dossier mais dans un dossier « parent », on fait comment ?

Si votre fichier cible est placé dans un dossier qui se trouve « plus haut » dans l'arborescence, il faut écrire deux points comme ceci :

<a href="../page2.html">

Résumé en images

Les liens relatifs ne sont pas bien compliqués à utiliser une fois qu'on a compris le principe. Il suffit de regarder dans quel « niveau de dossier » se trouve votre fichier cible pour savoir comment écrire votre lien. La figure suivante fait la synthèse des différents liens relatifs possibles.

Les différents liens relatifs
Les différents liens relatifs

Un lien vers une ancre

Une ancre est une sorte de point de repère que vous pouvez mettre dans vos pages HTML lorsqu'elles sont très longues.
En effet, il peut alors être utile de faire un lien amenant plus bas dans la même page pour que le visiteur puisse sauter directement à la partie qui l'intéresse.

Pour créer une ancre, il suffit de rajouter l'attribut id à une balise qui va alors servir de repère. Ce peut être n'importe quelle balise, un titre par exemple.
Utilisez l'attribut id pour donner un nom à l'ancre. Cela nous servira ensuite pour faire un lien vers cette ancre. Par exemple :

<h2 id="mon_ancre">Titre</h2>

Ensuite, il suffit de créer un lien comme d'habitude, mais cette fois l'attribut href contiendra un dièse (#) suivi du nom de l'ancre. Exemple :

<a href="#mon_ancre">Aller vers l'ancre</a>

Normalement, si vous cliquez sur le lien, cela vous amènera plus bas dans la même page (à condition que la page comporte suffisamment de texte pour que les barres de défilement se déplacent automatiquement).
Voici un exemple de page comportant beaucoup de texte et utilisant les ancres (j'ai mis n'importe quoi dans le texte pour remplir ) :

<h1>Ma grande page</h1>

<p>
    Aller directement à la partie traitant de :<br />
    <a href="#cuisine">La cuisine</a><br />
    <a href="#rollers">Les rollers</a><br />
    <a href="#arc">Le tir à l'arc</a><br />
</p>
<h2 id="cuisine">La cuisine</h2>

<p>... (beaucoup de texte) ...</p>

<h2 id="rollers">Les rollers</h2>

<p>... (beaucoup de texte) ...</p>

<h2 id="arc">Le tir à l'arc</h2>

<p>... (beaucoup de texte) ...</p>

S'il ne se passe rien quand vous cliquez sur les liens, c'est qu'il n'y a pas assez de texte. Dans ce cas, vous pouvez soit rajouter du blabla dans la page pour qu'il y ait (encore) plus de texte, soit réduire la taille de la fenêtre de votre navigateur pour faire apparaître les barres de défilement sur le côté.

L'attribut id sert à donner un nom « unique » à une balise, pour s'en servir de repère. Et, croyez-moi, vous n'avez pas fini d'entendre parler de cet attribut. Ici, on s'en sert pour faire un lien vers une ancre mais, en CSS, il nous sera très utile pour « repérer » une balise précise, vous verrez.
Évitez cependant de créer des id avec des espaces ou des caractères spéciaux, utilisez simplement, dans la mesure du possible, des lettres et chiffres pour que la valeur soit reconnue par tous les navigateurs.

Lien vers une ancre située dans une autre page

Alors là je vous préviens, on va faire le Mégamix !

L'idée, c'est de faire un lien qui ouvre une autre page ET qui amène directement à une ancre située plus bas sur cette page.
En pratique c'est assez simple à faire : il suffit de taper le nom de la page, suivi d'un dièse (#), suivi du nom de l'ancre.

Par exemple : <a href="ancres.html#rollers">

… vous amènera sur la page ancres.html, directement au niveau de l'ancre appelée rollers.

Voici une page qui contient trois liens, chacun amenant vers une des ancres de la page de l'exemple précédent :

<h1>Le Mégamix</h1>
<p>
    Rendez-vous quelque part sur une autre page :<br />
    <a href="ancres.html#cuisine">La cuisine</a><br />
    <a href="ancres.html#rollers">Les rollers</a><br />
    <a href="ancres.html#arc">Le tir à l'arc</a><br />
</p>

Cas pratiques d'utilisation des liens

Je vais essayer de vous montrer ici quelques cas pratiques d'utilisation des liens. Par exemple, saviez-vous qu'il est très facile de faire des liens qui lancent un téléchargement ? Qui créent un nouvel e-mail ? Qui ouvrent une nouvelle fenêtre ?

Non ? Eh bien nous allons voir tout cela ici.

Un lien qui affiche une infobulle au survol

Vous pouvez utiliser l'attribut title qui affiche une bulle d'aide lorsqu'on pointe sur le lien. Cet attribut est facultatif.

Vous aurez un résultat ressemblant à la figure suivante.

Une infobulle

La bulle d'aide peut être utile pour informer le visiteur avant même qu'il n'ait cliqué sur le lien.
Voici comment reproduire ce résultat :

<p>Bonjour. Souhaitez-vous visiter le <a href="http://www.siteduzero.com" title="Réservé aux débutants">Site du Zéro</a> ?</p>

Un lien qui ouvre une nouvelle fenêtre

Il est possible de « forcer » l'ouverture d'un lien dans une nouvelle fenêtre. Pour cela, on rajoutera target="_blank" à la balise <a> :

<p>Bonjour. Souhaitez-vous visiter le <a href="http://www.siteduzero.com" target="_blank">Site du Zéro</a> ?<br />
Le site s'affichera dans une autre fenêtre.</p>

Selon la configuration du navigateur, la page s'affichera dans une nouvelle fenêtre ou un nouvel onglet. Vous ne pouvez pas choisir entre l'ouverture d'une nouvelle fenêtre ou d'un nouvel onglet.

Notez cependant qu'il est déconseillé d'abuser de cette technique car elle perturbe la navigation. Le visiteur lui-même peut décider s'il veut ouvrir le lien dans une nouvelle fenêtre. Il fera Maj + Clic sur le lien pour ouvrir dans une nouvelle fenêtre ou Ctrl + Clic pour ouvrir dans un nouvel onglet.

Un lien pour envoyer un e-mail

Si vous voulez que vos visiteurs puissent vous envoyer un e-mail, vous pouvez utiliser des liens de type mailto. Rien ne change au niveau de la balise, vous devez simplement modifier la valeur de l'attribut href comme ceci :

<p><a href="mailto:votrenom@bidule.com">Envoyez-moi un e-mail !</a></p>

Il suffit donc de faire commencer le lien par mailto: et d'écrire l'adresse e-mail où on peut vous contacter. Si vous cliquez sur le lien, un nouveau message vide s'ouvre, prêt à être envoyé à votre adresse e-mail.

Un lien pour télécharger un fichier

Beaucoup d'entre vous se demandent comment cela se passe pour le téléchargement d'un fichier… En fait, il faut procéder exactement comme si vous faisiez un lien vers une page web, mais en indiquant cette fois le nom du fichier à télécharger.

Par exemple, supposez que vous vouliez faire télécharger monfichier.zip. Placez simplement ce fichier dans le même dossier que votre page web (ou dans un sous-dossier) et faites un lien vers ce fichier :

<p><a href="monfichier.zip">Télécharger le fichier</a></p>

C'est tout ! Le navigateur, voyant qu'il ne s'agit pas d'une page web à afficher, va lancer la procédure de téléchargement lorsqu'on cliquera sur le lien.

En résumé

  • Les liens permettent de changer de page et sont, par défaut, écrits en bleu et soulignés.

  • Pour insérer un lien, on utilise la balise <a> avec l'attribut href pour indiquer l'adresse de la page cible. Exemple : <a href="http://www.siteduzero.com">.

  • On peut faire un lien vers une autre page de son site simplement en écrivant le nom du fichier : <a href="page2.html">.

  • Les liens permettent aussi d'amener vers d'autres endroits sur la même page. Il faut créer une ancre avec l'attribut id pour « marquer » un endroit dans la page, puis faire un lien vers l'ancre comme ceci : <a href="#ancre">.


Tutoriel VBScript

Les images

https://vimeo.com/76776344

Insérer une image dans une page web ? Vous allez voir, c'est d'une facilité déconcertante… Enfin presque. Il existe différents formats d'image que l'on peut utiliser sur des sites web, et on ne doit pas les choisir au hasard. En effet, les images sont parfois volumineuses à télécharger, ce qui ralentit le temps de chargement de la page (beaucoup plus que le texte !).

Pour faire en sorte que vos pages restent lisibles et rapides à télécharger, suivez donc activement mes conseils !

Les différents formats d'images

Savez-vous ce qu'est un format d'image ?

Quand vous avez une image « entre les mains », vous avez la possibilité de l'enregistrer dans plusieurs « formats » différents. Le poids (en Ko, voire en Mo) de l'image sera plus ou moins élevé selon le format choisi et la qualité de l'image va changer.

Par exemple, le logiciel de dessin Paint (même si c'est loin d'être le meilleur) vous propose de choisir entre plusieurs formats lorsque vous enregistrez une image (figure suivante).

Différents formats d'image proposés par Paint
Différents formats d'image proposés par Paint

Certains formats sont plus adaptés que d'autres selon l'image (photo, dessin, image animée…). Notre but ici est de faire le tour des différents formats utilisés sur le Web pour que vous les connaissiez et sachiez choisir celui qui convient le mieux à votre image. Rassurez-vous, il n'y a pas beaucoup de formats différents, cela ne sera donc pas bien long.

Toutes les images diffusées sur Internet ont un point commun : elles sont compressées. Cela veut dire que l'ordinateur fait des calculs pour qu'elles soient moins lourdes et donc plus rapides à charger.

Le JPEG

Les images au format JPEG (Joint Photographic Expert Group) sont très répandues sur le Web. Ce format est conçu pour réduire le poids des photos (c'est-à-dire la taille du fichier associé), qui peuvent comporter plus de 16 millions de couleurs différentes. La figure suivante est une photo enregistrée au format JPEG.

Une photo de montagne en JPEG
Une photo de montagne en JPEG

Les images JPEG sont enregistrées avec l'extension .jpg ou .jpeg.

Notez que le JPEG détériore un peu la qualité de l'image, d'une façon généralement imperceptible. C'est ce qui le rend si efficace pour réduire le poids des photos.
Quand il s'agit d'une photo, on ne peut généralement pas détecter la perte de qualité. Par contre, si ce n'est pas une photo, vous risquez de voir l'image un peu « baver ». Dans ce cas, il vaut mieux utiliser le format PNG.

Le PNG

Le format PNG (Portable Network Graphics) est le plus récent de tous. Ce format est adapté à la plupart des graphiques (je serais tenté de dire « à tout ce qui n'est pas une photo »). Le PNG a deux gros avantages : il peut être rendu transparent et il n'altère pas la qualité de l'image.

Le PNG a été inventé pour concurrencer un autre format, le GIF, à l'époque où il fallait payer des royalties pour pouvoir utiliser des GIF. Depuis, le PNG a bien évolué et c'est devenu le format le plus puissant pour enregistrer la plupart des images.

Le PNG existe en deux versions, en fonction du nombre de couleurs que doit comporter l'image :

  • PNG 8 bits : 256 couleurs ;

  • PNG 24 bits : 16 millions de couleurs (autant qu'une image JPEG).

La figure suivante est une image PNG en 24 bits, représentant la célèbre mascotte Zozor du Site du Zéro.

Zozor en PNG
Zozor en PNG

Une vieille version d'Internet Explorer (IE6) ne peut pas afficher correctement les images PNG 24 bits transparentes. Ce navigateur tend à être de moins en moins utilisé, mais gardez quand même cette information en tête.

Au fait, si le PNG 24 bits peut afficher autant de couleurs qu'une image JPEG, et qu'en plus il peut être rendu transparent sans modifier la qualité de l'image… quel est l'intérêt du JPEG ?

La compression du JPEG est plus puissante sur les photos. Une photo enregistrée en JPEG se chargera toujours beaucoup plus vite que si elle était enregistrée en PNG. Je vous conseille donc toujours de réserver le format JPEG aux photos.

Le GIF

C'est un format assez vieux, qui a été néanmoins très utilisé (et qui reste très utilisé par habitude). Aujourd'hui, le PNG est globalement bien meilleur que le GIF : les images sont généralement plus légères et la transparence est de meilleure qualité. Je vous recommande donc d'utiliser le PNG autant que possible.

Le format GIF est limité à 256 couleurs (alors que le PNG peut aller jusqu'à plusieurs millions de couleurs).

Néanmoins, le GIF conserve un certain avantage que le PNG n'a pas : il peut être animé.

Un GIF animé
Un GIF animé

Il existe un format adapté à chaque image

Si on résume, voici quel format adopter en fonction de l'image que vous avez :

  • Une photo : utilisez un JPEG.

  • N'importe quel graphique avec peu de couleurs (moins de 256) : utilisez un PNG 8 bits ou éventuellement un GIF.

  • N'importe quel graphique avec beaucoup de couleurs : utilisez un PNG 24 bits.

  • Une image animée : utilisez un GIF animé.

Les erreurs à éviter

Bannissez les autres formats

Les autres formats non cités ici, comme le format BITMAP (*.bmp) sont à bannir car bien souvent ils ne sont pas compressés, donc trop gros. Ils ne sont pas du tout adaptés au Web. On peut en mettre sur son site mais le chargement sera vraiment extrêmement long !

Choisissez bien le nom de votre image

Si vous voulez éviter des problèmes, prenez l'habitude d'enregistrer vos fichiers avec des noms en minuscules, sans espace ni accent, par exemple : mon_image.png.

Vous pouvez remplacer les espaces par le caractère underscore (« _ ») comme je l'ai fait ici.

Insérer une image

Revenons maintenant au code HTML pour découvrir comment placer des images dans nos pages web !

Insertion d'une image

Quelle est la fameuse balise qui va nous permettre d'insérer une image ? Il s'agit de… <img /> !

C'est une balise de type orpheline (comme <br />). Cela veut dire qu'on n'a pas besoin de l'écrire en deux exemplaires comme la plupart des autres balises que nous avons vues jusqu'ici. En effet, nous n'avons pas besoin de délimiter une portion de texte, nous voulons juste insérer une image à un endroit précis.

La balise doit être accompagnée de deux attributs obligatoires :

  • src : il permet d'indiquer où se trouve l'image que l'on veut insérer. Vous pouvez soit mettre un chemin absolu (ex. : http://www.site.com/fleur.png), soit mettre le chemin en relatif (ce qu'on fait le plus souvent). Ainsi, si votre image est dans un sous-dossier images, vous devrez taper : src="images/fleur.png"

  • alt : cela signifie « texte alternatif ». On doit toujours indiquer un texte alternatif à l'image, c'est-à-dire un court texte qui décrit ce que contient l'image. Ce texte sera affiché à la place de l'image si celle-ci ne peut pas être téléchargée (cela arrive), ou dans les navigateurs de personnes handicapées (non-voyants) qui ne peuvent malheureusement pas « voir » l'image. Cela aide aussi les robots des moteurs de recherche pour les recherches d'images. Pour la fleur, on mettrait par exemple : alt="Une fleur".

Les images doivent se trouver obligatoirement à l'intérieur d'un paragraphe (<p></p>). Voici un exemple d'insertion d'image :

<p>
    Voici une photo que j'ai prise lors de mes dernières vacances à la montagne :<br />
    <img src="images/montagne.jpg" alt="Photo de montagne" />
</p>

Bref, l'insertion d'image est quelque chose de très facile pour peu qu'on sache indiquer où se trouve l'image, comme on avait appris à le faire avec les liens.
La plus grosse « difficulté » (si on peut appeler cela une difficulté) consiste à choisir le bon format d'image. Ici, c'est une photo donc c'est évidemment le format JPEG qu'on utilise.

Je le répète : évitez à tout prix les accents, majuscules et espaces dans vos noms de fichiers et de dossiers. Voici un chemin qui va poser problème :
"Images du site/Image toute bête.jpg".
Il faudrait supprimer les espaces (ou les remplacer par le symbole « _ »), supprimer les accents et tout mettre en minuscules comme ceci :
"images_du_site/image_toute_bete.jpg".
Sachez donc que, si votre image ne s'affiche pas, c'est très certainement parce que le chemin est incorrect ! Simplifiez au maximum vos noms de fichiers et de dossiers, et tout ira bien.

Ajouter une infobulle

L'attribut permettant d'afficher une bulle d'aide est le même que pour les liens : il s'agit de title. Cet attribut est facultatif (contrairement à alt).

Voici ce que cela peut donner :

<p>
    Voici une photo que j'ai prise lors de mes dernières vacances à la montagne :<br />
    <img src="images/montagne.jpg" alt="Photo de montagne" title="C'est beau les Alpes quand même !" />
</p>

Survolez la photo avec la souris pour voir l'infobulle apparaître.

Miniature cliquable

Si votre image est très grosse, il est conseillé d'en afficher la miniature sur votre site. Ajoutez ensuite un lien sur cette miniature pour que vos visiteurs puissent afficher l'image en taille originale.

Il existe des millions de logiciels permettant de créer des miniatures d'images. J'utilise personnellement Easy Thumbnails. Je vais ainsi disposer de deux versions de ma photo, comme à la figure suivante) : la miniature et l'image d'origine.

La miniature et son image d'origine
La miniature et son image d'origine

Je les place toutes les deux dans un dossier appelé par exemple img. J'affiche la version montagne_mini.jpg sur ma page et je fais un lien vers montagne.jpg pour que l'image agrandie s'affiche lorsqu'on clique sur la miniature.

Voici le code HTML que je vais utiliser pour cela :

<p>
    Vous souhaitez voir l'image dans sa taille d'origine ? Cliquez dessus !<br />
    <a href="img/montagne.jpg"><img src="img/montagne_mini.jpg" alt="Photo de montagne" title="Cliquez pour agrandir" /></a>
</p>

Parfois, certains navigateurs choisissent d'afficher un cadre bleu (ou violet) pas très esthétique autour de votre image cliquable.
Heureusement, nous pourrons retirer ce cadre dans peu de temps grâce au CSS.

Les figures

Au cours de la lecture de ce livre, vous avez déjà rencontré plusieurs fois des figures. Ce sont des éléments qui viennent enrichir le texte pour compléter les informations de la page.

Les figures peuvent être de différents types :

  • images ;

  • codes source ;

  • citations ;

  • etc.

Bref, tout ce qui vient illustrer le texte est une figure. Nous allons ici nous intéresser aux images mais, contrairement à ce qu'on pourrait croire, les figures ne sont pas forcément des images : un code source aussi illustre le texte.

Création d'une figure

Reprenons par exemple cette capture d'écran du premier chapitre, représentée à la figure suivante.

Le logiciel Bloc-Notes
Le logiciel Bloc-Notes

En HTML5, on dispose de la balise <figure>. Voici comment on pourrait l'utiliser :

<figure>
    <img src="images/blocnotes.png" alt="Bloc-Notes" />
</figure>

Une figure est le plus souvent accompagnée d'une légende. Pour ajouter une légende, utilisez la balise <figcaption> à l'intérieur de la balise <figure>, comme ceci :

<figure>
    <img src="images/blocnotes.png" alt="Bloc-Notes" />
    <figcaption>Le logiciel Bloc-Notes</figcaption>
</figure>

Bien comprendre le rôle des figures

Un peu plus tôt dans ce chapitre, je vous ai dit que les images devaient être situées dans des paragraphes (placées à l'intérieur d'une balise <p></p>). Ce n'est pas tout à fait vrai.

Si vous faites de votre image une figure, l'image peut être située en-dehors d'un paragraphe.

<p>Connaissez-vous le logiciel Bloc-Notes ? On peut faire des sites web avec !</p>

<figure>
    <img src="images/blocnotes.png" alt="Bloc-Notes" />
    <figcaption>Le logiciel Bloc-Notes</figcaption>
</figure>

Je ne vois pas vraiment de changement. Quand dois-je placer mon image dans un paragraphe et quand dois-je la placer dans une figure ?

Bonne question ! Tout dépend de ce que votre image apporte au texte :

  • Si elle n'apporte aucune information (c'est juste une illustration pour décorer) : placez l'image dans un paragraphe.

  • Si elle apporte une information : placez l'image dans une figure.

La balise <figure> a un rôle avant tout sémantique. Cela veut dire qu'elle indique à l'ordinateur que l'image a du sens et qu'elle est importante pour la bonne compréhension du texte. Cela peut permettre à un programme de récupérer toutes les figures du texte et de les référencer dans une table des figures, par exemple.

Enfin, sachez qu'une figure peut très bien comporter plusieurs images. Voici un cas où cela se justifie :

<figure>
    <img src="images/internetexplorer.png" alt="Logo Internet Explorer" />
    <img src="images/firefox.png" alt="Logo Mozilla Firefox" />
    <img src="images/chrome.png" alt="Logo Google Chrome" />
    <figcaption>Logos des différents navigateurs</figcaption>
</figure>

En résumé

  • Il existe plusieurs formats d'images adaptées au Web :

    • JPEG : pour les photos ;

    • PNG : pour toutes les autres illustrations ;

    • GIF : similaire au PNG, plus limité en nombre de couleurs mais qui peut être animé.

  • On insère une image avec la balise <img />. Elle doit obligatoirement comporter au moins ces deux attributs : src (nom de l'image) et alt (courte description de l'image).

  • Si une image illustre le texte (et n'est pas seulement décorative), il est conseillé de la placer au sein d'une balise <figure>. La balise <figcaption> permet d'écrire la légende de l'image.


Tutoriel VBScript

Mettre en place le CSS

https://vimeo.com/76002176

Après avoir passé toute une première partie du cours à ne travailler que sur le HTML, nous allons maintenant découvrir le CSS que j'avais volontairement mis à l'écart. Le CSS n'est pas plus compliqué que le HTML. Il vient le compléter pour vous aider à mettre en forme votre page web.

Dans ce premier chapitre sur le CSS, nous allons voir la théorie sur le CSS : qu'est-ce que c'est ? À quoi cela ressemble-t-il ? Où est-ce qu'on écrit du code CSS ? Ces aspects théoriques ne sont pas bien compliqués mais vous devez obligatoirement les connaître car c'est la base du CSS. C'est d'ailleurs la seule chose que je vous demanderai de retenir par cœur en CSS, vous pourrez retrouver le reste dans le mémo en annexe.

Allez, ne traînons pas, je vois que vous brûlez d'impatience !

La petite histoire du CSS

Je vous avais avertis dès le début de ce cours : nous allons apprendre deux langages. Nous avons déjà bien entamé notre découverte du HTML, même s'il reste encore de nombreuses choses à apprendre (nous y reviendrons dans quelques chapitres). En revanche, il est temps maintenant de nous intéresser au CSS.

CSS (Cascading Style Sheets), c'est cet autre langage qui vient compléter le HTML.
Vous vous souvenez de son rôle ? Gérer la mise en forme de votre site.

Petit rappel : à quoi sert CSS ?

CSS ? C'est lui qui vous permet de choisir la couleur de votre texte.
Lui qui vous permet de sélectionner la police utilisée sur votre site.
Lui encore qui permet de définir la taille du texte, les bordures, le fond…

Et aussi, c'est lui qui permet de faire la mise en page de votre site. Vous pourrez dire : je veux que mon menu soit à gauche et occupe telle largeur, que l'en-tête de mon site soit calé en haut et qu'il soit toujours visible, etc.

Souvenez-vous de ce petit comparatif que nous avions vu dès le premier chapitre (figure suivante).

La même page HTML, sans et avec CSS (www.csszengarden.com)
La même page HTML, sans et avec CSS (www.csszengarden.com)

Grâce au HTML, nous avons pu rédiger le contenu de notre site mais il est brut de décoffrage. Le CSS vient compléter ce code pour mettre en forme tout cela et donner au contenu l'apparence que l'on souhaite.

CSS : des débuts difficiles

Il faut savoir qu'aux débuts du Web, CSS n'existait pas. En fait, il n'y avait initialement que le langage HTML.
Le HTML est né en 1991 et CSS en 1996. Alors, vous vous dites sûrement : comment faisait-on la mise en forme de 1991 à 1996 ? Eh bien, uniquement en HTML ! Il y avait en effet des balises HTML dédiées à la mise en forme. <font color="#aab1c3">, par exemple, permettait de définir la couleur du texte.

Cependant, les pages HTML commençaient à devenir assez complexes. Il y avait de plus en plus de balises et c'était un joyeux mélange entre le fond et la forme, qui rendait la mise à jour des pages web de plus en plus complexe. C'est pour cela que l'on a créé le langage CSS.

Cependant, le CSS n'a pas été adopté immédiatement par les webmasters, loin de là. Il fallait se défaire de certaines mauvaises habitudes et cela a pris du temps. Encore aujourd'hui, on peut trouver des sites web avec des balises HTML de mise en forme, anciennes et obsolètes, comme <font> !

CSS : la prise en charge des navigateurs

Tout comme le HTML, le CSS a évolué. Je vous avais indiqué qu'il y avait quatre versions importantes de CSS :

  • CSS 1 ;

  • CSS 2.0 ;

  • CSS 2.1 ;

  • CSS 3.

En fait, la version CSS 3 n'est pas encore totalement finalisée (ce n'est pas encore une version officielle). Cependant, elle est bien avancée et aujourd'hui déjà bien prise en charge par de nombreux navigateurs, ce qui fait qu'on peut déjà s'en servir.
Il serait dommage de passer à côté car CSS 3 apporte de nombreuses fonctionnalités à CSS (leur nombre double par rapport à CSS 2.1 !). Nous nous baserons donc dans ce cours sur CSS 3, qui reprend et complète la plupart des fonctionnalités de CSS 2.1.

Ce sont les navigateurs web qui font le travail le plus complexe : ils doivent lire le code CSS et comprendre comment afficher la page.

Au début des années 2000, Internet Explorer était le navigateur le plus répandu mais sa gestion du CSS est longtemps restée assez médiocre (pour ne pas dire carrément mauvaise). C'était la grande époque de la version 6 (IE6), hélas encore utilisée aujourd'hui par une petite partie des internautes (heureusement, cette proportion tend à diminuer).

Depuis, de nombreux navigateurs sont arrivés et ont chahuté Internet Explorer : Mozilla Firefox bien sûr, mais aussi Google Chrome. Et je ne vous parle pas du succès des Mac et iPhone avec leur navigateur Safari. Cela a incité Microsoft à réagir et publier (après une longue période d'inactivité) IE 7, puis IE 8 et IE 9. On parle déjà de IE 10.

Bon, ton cours d'histoire, c'est bien joli mais en quoi cela me concerne-t-il aujourd'hui ?

Que faut-il retenir de tout cela ? Que les navigateurs ne connaissent pas toutes les propriétés CSS qui existent. Plus le navigateur est vieux, moins il connaît de fonctionnalités CSS.

Je vais vous présenter dans ce cours un certain nombre de fonctionnalités de CSS qui ne marchent pas forcément sur les navigateurs les plus vieux. Je ne peux pas l'éviter, c'est comme cela : aucun navigateur ne connaît parfaitement toutes les fonctionnalités CSS de toute façon ! Au pire, si le navigateur ne connaît pas une propriété CSS, il l'ignore et ne met pas en forme, mais cela ne fait pas planter votre page : celle-ci sera donc toujours lisible.

Je vous recommande fortement de mettre dans vos favoris les sites www.caniuse.com et normansblog.de qui proposent des tables de compatibilité des fonctionnalités de HTML et CSS sur différents navigateurs (et sur leurs différentes versions). Regardez en particulier les tables de compatibilité pour CSS de www.caniuse.com (figure suivante).

Table de compatibilité CSS Table de compatibilité CSS

Table de compatibilité CSS de caniuse.com

Où écrit-on le CSS ?

Vous avez le choix car on peut écrire du code en langage CSS à trois endroits différents :

  • dans un fichier .css (méthode la plus recommandée) ;

  • dans l'en-tête <head> du fichier HTML ;

  • directement dans les balises du fichier HTML via un attribut style (méthode la moins recommandée).

Je vais vous présenter ces trois méthodes mais sachez d'ores et déjà que la première… est la meilleure.

Dans un fichier .css (recommandé)

Comme je viens de vous le dire, on écrit le plus souvent le code CSS dans un fichier spécial ayant l'extension .css (contrairement aux fichiers HTML qui ont l'extension .html). C'est la méthode la plus pratique et la plus souple. Cela nous évite de tout mélanger dans un même fichier. J'utiliserai cette technique dans toute la suite de ce cours.

Commençons à pratiquer dès maintenant ! Nous allons partir du fichier HTML suivant :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" href="style.css" />
        <title>Premiers tests du CSS</title>
    </head>

    <body>
        <h1>Mon super site</h1>

        <p>Bonjour et bienvenue sur mon site !</p>
        <p>Pour le moment, mon site est un peu <em>vide</em>. Patientez encore un peu !</p>
    </body>
</html>

Vous noterez le contenu de la ligne 5, <link rel="stylesheet" href="style.css" /> : c'est elle qui indique que ce fichier HTML est associé à un fichier appelé style.css et chargé de la mise en forme.

Enregistrez ce fichier sous le nom que vous voulez (par exemple page.html). Pour le moment, rien d'extraordinaire à part la nouvelle balise que nous avons ajoutée.

Maintenant, créez un nouveau fichier vide dans votre éditeur de texte (par exemple Notepad++) et copiez-y ce bout de code CSS (rassurez-vous, je vous expliquerai tout à l'heure ce qu'il veut dire) :

p
{
    color: blue;
}

Pour activer la coloration du code dans Notepad++, passez par les menus Langage > C > CSS.

Enregistrez le fichier en lui donnant un nom qui se termine par .css, comme style.css. Placez ce fichier .css dans le même dossier que votre fichier .html.

Dans Notepad++, vous devriez observer quelque chose de similaire à la figure suivante.

Fichiers HTML et CSS dans Notepad++
Fichiers HTML et CSS dans Notepad++

Dans votre explorateur de fichiers, vous devriez les voir apparaître côte à côte. D'un côté le .html, de l'autre le .css, comme à la figure suivante.

Fichiers HTML et CSS dans l'explorateur de fichiers
Fichiers HTML et CSS dans l'explorateur de fichiers

Ouvrez maintenant votre fichier page.html dans votre navigateur pour le tester, comme vous le faites d'habitude. Regardez, c'est magique : vos paragraphes sont écrits en bleu, comme dans la figure suivante !

Le texte est écrit en bleu
Le texte est écrit en bleu

Il est inutile d'ouvrir directement le fichier style.css dans le navigateur. Il faut ouvrir le fichier page.html (il fera automatiquement appel au fichier style.css).

Dans l'en-tête <head> du fichier HTML

Il existe une autre méthode pour utiliser du CSS dans ses fichiers HTML : cela consiste à insérer le code CSS directement dans une balise <style> à l'intérieur de l'en-tête <head>.

Voici comment on peut obtenir exactement le même résultat avec un seul fichier .html qui contient le code CSS (lignes 5 à 10) :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <style>
            p
            {
                color: blue;
            }
        </style>
        <title>Premiers tests du CSS</title>
    </head>

    <body>
        <h1>Mon super site</h1>

        <p>Bonjour et bienvenue sur mon site !</p>
        <p>Pour le moment, mon site est un peu <em>vide</em>. Patientez encore un peu !</p>
    </body>
</html>

Testez, vous verrez que le résultat est le même.

Directement dans les balises (non recommandé)

Dernière méthode, à manipuler avec précaution : vous pouvez ajouter un attribut style à n'importe quelle balise. Vous insérerez votre code CSS directement dans cet attribut :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Premiers tests du CSS</title>
    </head>

    <body>
        <h1>Mon super site</h1>

        <p style="color: blue;">Bonjour et bienvenue sur mon site !</p>
        <p>Pour le moment, mon site est un peu <em>vide</em>. Patientez encore un peu !</p>
    </body>
</html>

Cette fois, seul le texte du premier paragraphe (ligne 11), dont la balise contient le code CSS, sera coloré en bleu (figure suivante).

Le premier paragraphe est écrit en bleu
Le premier paragraphe est écrit en bleu

Quelle méthode choisir ?

Je trouve que la première méthode que tu recommandes est plus compliquée que les deux autres ! Pourquoi nous conseilles-tu de créer deux fichiers, j'étais bien, moi, avec juste un fichier .html !

Je vous recommande fortement de prendre l'habitude de travailler avec la première méthode parce que c'est celle utilisée par la majorité des webmasters… Pourquoi ?

Pour le moment, vous faites vos tests sur un seul fichier HTML. Cependant, votre site sera plus tard constitué de plusieurs pages HTML, on est d'accord ?
Imaginez : si vous placez le code CSS directement dans le fichier HTML, il faudra copier ce code dans tous les fichiers HTML de votre site ! Et si demain vous changez d'avis, par exemple si vous voulez que vos paragraphes soient écrits en rouge et non en bleu, il faudra modifier chaque fichier HTML un à un, comme le montre la figure suivante.

Le code CSS est répété dans chaque fichier HTML
Le code CSS est répété dans chaque fichier HTML

Si vous travaillez avec un fichier CSS externe, vous n'aurez besoin d'écrire cette instruction qu'une seule fois pour tout votre site, comme le montre la figure suivante.

Le code CSS est donné une fois pour toutes dans un fichier CSS
Le code CSS est donné une fois pour toutes dans un fichier CSS

Appliquer un style : sélectionner une balise

Maintenant que nous savons où placer le code CSS, intéressons-nous de plus près à ce code. Je vous ai donné, sans vous l'expliquer, un premier bout de code CSS :

p
{
    color: blue;
}

Dans un code CSS comme celui-ci, on trouve trois éléments différents :

  • Des noms de balises : on écrit les noms des balises dont on veut modifier l'apparence. Par exemple, si je veux modifier l'apparence de tous les paragraphes <p>, je dois écrire p.

  • Des propriétés CSS : les « effets de style » de la page sont rangés dans des propriétés. Il y a par exemple la propriété color qui permet d'indiquer la couleur du texte, font-size qui permet d'indiquer la taille du texte, etc. Il y a beaucoup de propriétés CSS et, comme je vous l'ai dit, je ne vous obligerai pas à les connaître toutes par cœur.

  • Les valeurs : pour chaque propriété CSS, on doit indiquer une valeur. Par exemple, pour la propriété color, il faut indiquer le nom de la couleur. Pour font-size, il faut indiquer quelle taille on veut, etc.

Schématiquement, une feuille de style CSS ressemble donc à cela :

balise1
{
    propriete1: valeur1;
    propriete2: valeur2;
    propriete3: valeur3;
}

balise2
{
    propriete1: valeur1;
    propriete2: valeur2;
    propriete3: valeur3;
    propriete4: valeur4;
}

balise3
{
    propriete1: valeur1;
}

Vous repérez dans cet extrait de code les balises, propriétés et valeurs dont je viens de vous parler.

Comme vous le voyez, on écrit le nom de la balise (par exemple h1) et on ouvre des accolades pour, à l'intérieur, mettre les propriétés et valeurs que l'on souhaite. On peut mettre autant de propriétés que l'on veut à l'intérieur des accolades. Chaque propriété est suivie du symbole « deux-points » ( : ) puis de la valeur correspondante. Enfin, chaque ligne se termine par un point-virgule ( ; ).

Je vous apprendrai de nombreuses propriétés dans les chapitres suivants. Pour le moment, dans les exemples, on va juste changer la couleur pour s'entraîner.

Le code CSS que nous avons utilisé jusqu'ici :

p
{
    color: blue;
}

… signifie donc en français : « Je veux que tous mes paragraphes soient écrits en bleu. ». Le résultat est visible à la figure suivante.

Paragraphes écrits en bleu
Paragraphes écrits en bleu

Essayez de changer le nom de la balise affectée par le code CSS. Par exemple, si j'écris h1, c'est le titre qui sera écrit en bleu. Modifiez votre fichier style.css comme ceci :

h1
{
    color: blue;
}

Maintenant, ouvrez à nouveau votre page HTML (souvenez-vous, c'est la page HTML qu'on ouvre dans le navigateur, pas le fichier CSS !) : vous devriez voir son titre s'afficher en bleu (figure suivante) !

Titre écrit en bleu
Titre écrit en bleu

Appliquer un style à plusieurs balises

Prenons le code CSS suivant :

h1
{
    color: blue;
}

em
{
    color: blue;
}

Il signifie que nos titres <h1> et nos textes importants <em> doivent s'afficher en bleu. Par contre, c'est un peu répétitif, vous ne trouvez pas ?

Heureusement, il existe un moyen en CSS d'aller plus vite si les deux balises doivent avoir la même présentation. Il suffit de combiner la déclaration en séparant les noms des balises par une virgule, comme ceci :

h1, em
{
    color: blue;
}

Le résultat se trouve à la figure suivante.

Titre et texte important écrits en bleu
Titre et texte important écrits en bleu

Cela signifie : « Je veux que le texte de mes <h1> et <em> soit écrit en bleu ».

Vous pouvez indiquer autant de balises à la suite que vous le désirez.

Des commentaires dans du CSS

Comme en HTML, il est possible de mettre des commentaires. Les commentaires ne seront pas affichés, ils servent simplement à indiquer des informations pour vous, par exemple pour vous y retrouver dans un looong fichier CSS.

D'ailleurs, vous allez vous en rendre compte, en général le fichier HTML est assez court et la feuille CSS assez longue (si elle contient tous les éléments de style de votre site, c'est un peu normal). Notez qu'il est possible de créer plusieurs fichiers CSS pour votre site si vous ressentez le besoin de séparer un peu votre code CSS (en fonction des différentes sections de votre site, par exemple).

… De quoi on parlait déjà ? Ah oui, les commentaires en CSS.

Donc, pour faire un commentaire, c'est facile ! Tapez /*, suivi de votre commentaire, puis */ pour terminer votre commentaire.
Vos commentaires peuvent être écrits sur une ou plusieurs lignes. Par exemple :

/*
style.css
---------

Par Mathieu Nebra
*/

p
{
    color: blue; /* Les paragraphes seront en bleu */
}

Il est possible que j'utilise les commentaires dans la suite du cours, pour vous donner des explications à l'intérieur même des fichiers .css.

Appliquer un style : class et id

Ce que je vous ai montré jusqu'ici a quand même un défaut : cela implique par exemple que TOUS les paragraphes possèdent la même présentation (ici, ils seront donc tous écrits en bleu).
Comment faire pour que certains paragraphes seulement soient écrits d'une manière différente ? On pourrait placer le code CSS dans un attribut style sur la balise que l'on vise (c'est la technique que je vous ai présentée un peu plus tôt) mais, comme je vous l'ai dit, ce n'est pas recommandé (il vaut mieux utiliser un fichier CSS externe).

Pour résoudre le problème, on peut utiliser ces attributs spéciaux qui fonctionnent sur toutes les balises :

  • l'attribut class ;

  • l'attribut id.

Que les choses soient claires dès le début : les attributs class et id sont quasiment identiques. Il y a seulement une petite différence que je vous dévoilerai plus bas.
Pour le moment, et pour faire simple, on ne va s'intéresser qu'à l'attribut class.

Comme je viens de vous le dire, c'est un attribut que l'on peut mettre sur n'importe quelle balise, aussi bien titre que paragraphe, image, etc.

<h1 class=""> </h1>
<p class=""> </p>
<img class="" />

Oui mais que met-on comme valeur à l'attribut class ?

En fait, vous devez écrire un nom qui sert à identifier la balise. Ce que vous voulez, du moment que le nom commence par une lettre.

Par exemple, je vais associer la classe introduction à mon premier paragraphe (ligne 12) :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" href="style.css" />
        <title>Premiers tests du CSS</title>
    </head>

    <body>
        <h1>Mon super site</h1>

        <p class="introduction">Bonjour et bienvenue sur mon site !</p>
        <p>Pour le moment, mon site est un peu <em>vide</em>. Patientez encore un peu !</p>
    </body>
</html>

Maintenant que c'est fait, votre paragraphe est identifié. Il a un nom : introduction. Vous allez pouvoir réutiliser ce nom dans le fichier CSS pour dire : « Je veux que seules les balises qui ont comme nom 'introduction' soient affichées en bleu ».

Pour faire cela en CSS, indiquez le nom de votre classe en commençant par un point, comme ci-dessous :

.introduction
{
    color: blue;
}

Testez le résultat : seul votre paragraphe appelé introduction va s'afficher en bleu (figure suivante) !

Seul le premier paragraphe s'affiche en bleu
Seul le premier paragraphe s'affiche en bleu

Et l'attribut id alors ?

Lui, il fonctionne exactement de la même manière que class, à un détail près : il ne peut être utilisé qu'une fois dans le code.

Quel intérêt ? Il y en a assez peu pour tout vous dire, cela vous sera utile si vous faites du JavaScript plus tard pour reconnaître certaines balises. D'ailleurs, nous avons déjà vu l'attribut id dans le chapitre sur les liens (pour réaliser des ancres). En pratique, nous ne mettrons des id que sur des éléments qui sont uniques dans la page, comme par exemple le logo :

<img src="images/logo.png" alt="Logo du site" id="logo" />

Si vous utilisez des id, lorsque vous définirez leurs propriétés dans le fichier CSS, il faudra faire précéder le nom de l'id par un dièse (#) :

#logo
{
    /* Indiquez les propriétés CSS ici */
}

Je ne vous propose pas de le tester, cela fonctionne exactement comme class.

Si vous vous emmêlez les pinceaux entre class et id retenez que deux balises peuvent avoir le même nom avec l'attribut class. Un nom d'id doit en revanche être unique dans la page HTML.

Les balises universelles

Il arrivera parfois que vous ayez besoin d'appliquer une class (ou un id) à certains mots qui, à l'origine, ne sont pas entourés par des balises.

En effet, le problème de class, c'est qu'il s'agit d'un attribut. Vous ne pouvez donc en mettre que sur une balise. Si, par exemple, je veux modifier uniquement « bienvenue » dans le paragraphe suivant :

<p>Bonjour et bienvenue sur mon site !</p>

Cela serait facile à faire s'il y avait une balise autour de « bienvenue » mais, malheureusement il n'y en a pas. Par chance, on a inventé… la balise-qui-ne-sert-à-rien.

En fait, on a inventé deux balises dites universelles, qui n'ont aucune signification particulière (elles n'indiquent pas que le mot est important, par exemple). Il y a une différence minime (mais significative !) entre ces deux balises :

  • <span> </span> : c'est une balise de type inline, c'est-à-dire une balise que l'on place au sein d'un paragraphe de texte, pour sélectionner certains mots uniquement. Les balises <strong> et <em> sont de la même famille. Cette balise s'utilise donc au milieu d'un paragraphe et c'est celle dont nous allons nous servir pour colorer « bienvenue ».

  • <div> </div> : c'est une balise de type block, qui entoure un bloc de texte. Les balises <p>, <h1>, etc. sont de la même famille. Ces balises ont quelque chose en commun : elles créent un nouveau « bloc » dans la page et provoquent donc obligatoirement un retour à la ligne. <div> est une balise fréquemment utilisée dans la construction d'un design, comme nous le verrons plus tard.

Pour le moment donc, nous allons utiliser plutôt la balise <span>. On la met autour de « bienvenue », on lui ajoute une classe (du nom qu'on veut), on crée le CSS et c'est gagné !

<p>Bonjour et <span class="salutations">bienvenue</span> sur mon site !</p>
.salutations
{
    color: blue;
}

Vous pouvez voir le résultat à la figure suivante.

Le mot « bienvenue » est écrit en bleu
Le mot « bienvenue » est écrit en bleu

Appliquer un style : les sélecteurs avancés

En CSS, le plus difficile est de savoir cibler le texte dont on veut changer la forme. Pour cibler (on dit « sélectionner ») les éléments de la page à modifier, on utilise ce qu'on appelle des sélecteurs. Vous en avez déjà utilisé quelques-uns un peu plus tôt dans ce chapitre, résumons-les pour commencer.

Les sélecteurs que vous connaissez déjà

Ces sélecteurs, que nous avons vus précédemment, sont de loin les plus couramment utilisés. Il faut les connaître par cœur. Commençons par la base de la base :

p
{

}

… signifie « Je veux toucher tous les paragraphes ». Après, c'est à vous de dire ce que vous faites à ces paragraphes (vous les écrivez en bleu, par exemple).

Nous avons aussi vu :

h1, em
{

}

… qui signifie « Tous les titres et tous les textes importants ». Nous avons sélectionné deux balises d'un coup.

Et enfin, nous avons vu comment sélectionner des balises précises à qui nous avons donné un nom grâce aux attributs class et id :

.class
{

}

#id
{

}

Vous savez quoi ? Il existe des dizaines d'autres façons de cibler des balises en CSS ! Nous n'allons pas toutes les voir car il y en a beaucoup et certaines sont complexes, mais voici déjà de quoi vous permettre d'être plus efficaces en CSS !

Les sélecteurs avancés

* : sélecteur universel
*
{

}

Sélectionne toutes les balises sans exception. On l'appelle le sélecteur universel.

A B : une balise contenue dans une autre
h3 em
{

}

Sélectionne toutes les balises <em> situées à l'intérieur d'une balise <h3>. Notez qu'il n'y a pas de virgule entre les deux noms de balises.

Exemple de code HTML correspondant :

<h3>Titre avec <em>texte important</em></h3>
A + B : une balise qui en suit une autre
h3 + p
{

}

Sélectionne la première balise <p> située après un titre <h3>.

Exemple :

<h3>Titre</h3>

<p>Paragraphe</p>
A[attribut] : une balise qui possède un attribut
a[title]
{

}

Sélectionne tous les liens <a> qui possèdent un attribut title.

Exemple :

<a href="http://site.com" title="Infobulle">
A[attribut="Valeur"] : une balise, un attribut et une valeur exacte
a[title="Cliquez ici"]
{

}

Idem, mais l'attribut doit en plus avoir exactement pour valeur « Cliquez ici ».

Exemple :

<a href="http://site.com" title="Cliquez ici">
A[attribut*="Valeur"] : une balise, un attribut et une valeur
a[title*="ici"]
{

}

Idem, l'attribut doit cette fois contenir dans sa valeur le mot « ici » (peu importe sa position).

Exemple :

<a href="http://site.com" title="Quelque part par ici">

D'autres sélecteurs existent !

Je ne vous ai présenté ici qu'une partie des sélecteurs CSS mais sachez qu'il en existe beaucoup d'autres. Si vous voulez une liste complète, vous pouvez vous renseigner directement à la source : sur le site du W3C ! C'est très complet.

Sachez que nous découvrirons certains de ces autres sélecteurs dans la suite de ce cours !

En résumé

  • CSS est un autre langage qui vient compléter le HTML. Son rôle est de mettre en forme votre page web.

  • Il faut être vigilant sur la compatibilité des navigateurs avec certaines fonctionnalités récentes de CSS3. Quand un navigateur ne connaît pas une instruction de mise en forme, il l'ignore simplement.

  • On peut écrire le code CSS à plusieurs endroits différents, le plus conseillé étant de créer un fichier séparé portant l'extension .css (exemple : style.css).

  • En CSS, on sélectionne quelles portions de la page HTML on veut modifier et on change leur présentation avec des propriétés CSS :

balise1
{
    propriete1: valeur1;
    propriete2: valeur2;
}

  • Il existe de nombreuses façons de sélectionner la portion de la page que l'on veut mettre en forme. Par exemple, on peut viser :

    • toutes les balises d'un même type, en écrivant simplement leur nom (h1 par exemple) ;

    • certaines balises spécifiques, auxquelles on a donné des noms à l'aide des attributs class ou id (.nomclasse ou #nomid) ;

    • uniquement les balises qui se trouvent à l'intérieur d'autres balises (h3 em).

    • etc.


Tutoriel VBScript

Formatage du texte

https://vimeo.com/76006303

Nous arrivons maintenant à un chapitre qui devrait beaucoup vous intéresser.

Non, le « formatage du texte » n'a rien à voir avec la destruction de toutes les données présentes sur votre disque dur ! Cela signifie simplement que l'on va modifier l'apparence du texte (on dit qu'on le « met en forme »).

Pas de surprise particulière : nous sommes toujours dans le CSS et nous allons réutiliser ce que nous venons d'apprendre dans le chapitre précédent. Nous allons donc travailler directement au sein du fichier .css que nous avons créé.

Ce chapitre va être l'occasion de découvrir de nombreuses propriétés CSS : nous allons voir comment modifier la taille du texte, changer la police, aligner le texte…

La taille

Pour modifier la taille du texte, on utilise la propriété CSS font-size. Mais comment indiquer la taille du texte ? C'est là que les choses se corsent car plusieurs techniques vous sont proposées :

  • Indiquer une taille absolue : en pixels, en centimètres ou millimètres. Cette méthode est très précise mais il est conseillé de ne l'utiliser que si c'est absolument nécessaire, car on risque d'indiquer une taille trop petite pour certains lecteurs.

  • Indiquer une taille relative : en pourcentage, « em » ou « ex », cette technique a l'avantage d'être plus souple. Elle s'adapte plus facilement aux préférences de taille des visiteurs.

Une taille absolue

Pour indiquer une taille absolue, on utilise généralement les pixels. Pour avoir un texte de 16 pixels de hauteur, vous devez donc écrire :

font-size: 16px;

Les lettres auront une taille de 16 pixels, comme le montre la figure suivante.

Une lettre de 16 pixels de hauteur
Une lettre de 16 pixels de hauteur

Voici un exemple d'utilisation (placez ce code dans votre fichier .css) :

p
{
    font-size: 14px; /* Paragraphes de 14 pixels */
}
h1
{
    font-size: 40px; /* Titres de 40 pixels */
}

Et le résultat est visible à la figure suivante.

Différentes tailles de texte
Différentes tailles de texte

Si vous le souhaitez, vous pouvez également définir des tailles en centimètres ou millimètres. Remplacez « px » par « cm » ou « mm ». Ces unités sont cependant moins bien adaptées aux écrans.

Une valeur relative

C'est la méthode recommandée car le texte s'adapte alors plus facilement aux préférences de tous les visiteurs.

Il y a plusieurs moyens d'indiquer une valeur relative. Vous pouvez par exemple écrire la taille avec des mots en anglais comme ceux-ci :

  • xx-small : minuscule ;

  • x-small : très petit ;

  • small : petit ;

  • medium : moyen ;

  • large : grand ;

  • x-large : très grand ;

  • xx-large : euh… gigantesque.

Vous pouvez tester l'utilisation de ces valeurs dans votre code CSS :

p
{
    font-size: small;
}
h1
{
    font-size: large;
}

Bon, cette technique a un défaut : il n'y a que sept tailles disponibles (car il n'y a que sept noms). Heureusement, il existe d'autres moyens. Ma technique préférée consiste à indiquer la taille en « em ».

  • Si vous écrivez 1em, le texte a une taille normale.

  • Si vous voulez grossir le texte, vous pouvez inscrire une valeur supérieure à 1, comme 1.3em.

  • Si vous voulez réduire le texte, inscrivez une valeur inférieure à 1, comme 0.8em.

Faites attention : pour les nombres décimaux, il faut mettre un point et non une virgule. Vous devez donc écrire « 1.4em » et non pas « 1,4em » !

Exemple :

p
{
    font-size: 0.8em;
}
h1
{
    font-size: 1.3em;
}

D'autres unités sont disponibles. Vous pouvez essayer le « ex » (qui fonctionne sur le même principe que le em mais qui est plus petit de base) et le pourcentage (80%, 130%…).

La police

Ah… La police… On touche un point sensible.

En effet, il se pose un problème : pour qu'une police s'affiche correctement, il faut que tous les internautes l'aient. Si un internaute n'a pas la même police que vous, son navigateur prendra une police par défaut (une police standard) qui n'aura peut-être rien à voir avec ce à quoi vous vous attendiez.

La bonne nouvelle, c'est que depuis CSS 3, il est possible de faire télécharger automatiquement une police au navigateur. Je vous expliquerai dans un second temps comment faire cela.

Modifier la police utilisée

La propriété CSS qui permet d'indiquer la police à utiliser est font-family. Vous devez écrire le nom de la police comme ceci :

balise
{
    font-family: police;
}

Seulement, pour éviter les problèmes si l'internaute n'a pas la même police que vous, on précise en général plusieurs noms de police, séparés par des virgules :

balise
{
    font-family: police1, police2, police3, police4;
}

Le navigateur essaiera d'abord d'utiliser la police1. S'il ne l'a pas, il essaiera la police2. S'il ne l'a pas, il passera à la police3, et ainsi de suite.
En général, on indique en tout dernier serif, ce qui correspond à une police par défaut (qui ne s'applique que si aucune autre police n'a été trouvée).

Il existe aussi une autre police par défaut appelée sans-serif. La différence entre les deux est la présence de petites pattes de liaison en bas des lettres, que la police sans-serif n'a pas. Oui, c'est subtil.

Oui, mais quelles sont les polices les plus courantes qu'on a le « droit » d'utiliser, me direz-vous ?
Voici une liste de polices qui fonctionnent bien sur la plupart des navigateurs :

  • Arial ;

  • Arial Black ;

  • Comic Sans MS ;

  • Courier New ;

  • Georgia ;

  • Impact ;

  • Times New Roman ;

  • Trebuchet MS ;

  • Verdana.

La figure suivante vous montre à quoi ressemblent ces polices.

Différentes polices

Ainsi, si j'écris :

p
{
    font-family: Impact, "Arial Black", Arial, Verdana, sans-serif;
}

… cela signifie : « Mets la police Impact ou, si elle n'y est pas, Arial Black, ou sinon Arial, ou sinon Verdana, ou si rien n'a marché, mets une police standard (sans-serif) ».

En général, il est bien d'indiquer un choix de trois ou quatre polices (+ serif ou sans-serif) afin de s'assurer qu'au moins l'une d'entre elles aura été trouvée sur l'ordinateur du visiteur.

Si le nom de la police comporte des espaces, je conseille de l'entourer de guillemets, comme je l'ai fait pour « Arial Black ».

Utiliser une police personnalisée avec @font-face

Je trouve le choix des polices trop limité.
Comment puis-je utiliser ma police préférée sur mon site web ?

Pendant longtemps, cela n'était pas possible. Aujourd'hui, avec CSS 3, il existe heureusement un moyen d'utiliser n'importe quelle police sur son site. Cela fonctionne bien avec la plupart des navigateurs.

Mais attention, il y a des défauts (ce serait trop beau sinon) :

  • Il faudra que le navigateur de vos visiteurs télécharge automatiquement le fichier de la police, dont le poids peut atteindre, voire dépasser 1 Mo…

  • La plupart des polices sont soumises au droit d'auteur, il n'est donc pas légal de les utiliser sur son site. Heureusement, il existe des sites comme fontsquirrel.com et dafont.com qui proposent en téléchargement un certain nombre de polices libres de droits. Je recommande en particulier fontsquirrel.com car il permet de télécharger des packs prêts à l'emploi pour CSS 3.

  • Il existe plusieurs formats de fichiers de polices et ceux-ci ne fonctionnent pas sur tous les navigateurs.

Voici les différents formats de fichiers de polices qui existent et qu'il faut connaître :

  • .ttf : TrueType Font. Fonctionne sur IE9 et tous les autres navigateurs.

  • .eot : Embedded OpenType. Fonctionne sur Internet Explorer uniquement, toutes versions. Ce format est propriétaire, produit par Microsoft.

  • .otf : OpenType Font. Ne fonctionne pas sur Internet Explorer.

  • .svg : SVG Font. Le seul format reconnu sur les iPhones et iPads pour le moment.

  • .woff : Web Open Font Format. Nouveau format conçu pour le Web, qui fonctionne sur IE9 et tous les autres navigateurs.

En CSS, pour définir une nouvelle police, vous devez la déclarer comme ceci :

@font-face {
    font-family: 'MaSuperPolice';
    src: url('MaSuperPolice.eot');
}

Le fichier de police (ici MaSuperPolice.eot) doit ici être situé dans le même dossier que le fichier CSS (ou dans un sous-dossier, si vous utilisez un chemin relatif).

Je croyais qu'il y avait plusieurs formats de police ?

Oui, d'ailleurs les .eot ne fonctionnent que sur Internet Explorer. L'idéal est de proposer plusieurs formats pour la police : le navigateur téléchargera celui qu'il sait lire. Voici comment indiquer plusieurs formats :

@font-face {
    font-family: 'MaSuperPolice';
    src: url('MaSuperPolice.eot') format('eot'),
         url('MaSuperPolice.woff') format('woff'),
         url('MaSuperPolice.ttf') format('truetype'),
         url('MaSuperPolice.svg') format('svg');
}

Pour tester le fonctionnement, je vous propose de télécharger une police sur Font Squirrel, par exemple Learning Curve Pro. Cliquez sur « @font-face Kit », cela vous permettra de télécharger un kit prêt à l'emploi avec tous les formats pour cette police.

Votre fichier CSS ressemblera au final à ceci :

@font-face { /* Définition d'une nouvelle police nommée LearningCurveProRegular */
    font-family: 'LearningCurveProRegular';
    src: url('LearningCurve_OT-webfont.eot');
    src: url('LearningCurve_OT-webfont.eot?#iefix') format('embedded-opentype'),
         url('LearningCurve_OT-webfont.woff') format('woff'),
         url('LearningCurve_OT-webfont.ttf') format('truetype'),
         url('LearningCurve_OT-webfont.svg#LearningCurveProRegular') format('svg');
}

h1 /* Utilisation de la police qu'on vient de définir sur les titres */
{
    font-family: 'LearningCurveProRegular', Arial, serif;
}

La première (grosse) section @font-face permet de définir un nouveau nom de police qui pourra être utilisé dans le fichier CSS. Ensuite, nous utilisons ce nom de police avec la propriété font-family, que nous connaissons, pour modifier l'apparence des titres <h1>. Vous pouvez voir le résultat à la figure suivante.

Affichage d'une police personnalisée
Affichage d'une police personnalisée

Vous noterez quelques bizarreries dans le CSS généré par le site Font Squirrel. Le but est de pallier certains bugs sur Internet Explorer car les anciennes versions ne comprennent pas quand on définit plusieurs formats. Cela explique donc la présence d'un ?#iefix dans le code.

Italique, gras, souligné…

Il existe en CSS une série de propriétés classiques de mise en forme du texte. Nous allons découvrir ici comment afficher le texte en gras, italique, souligné… et au passage nous verrons qu'il est même possible d'aller jusqu'à le faire clignoter !

Mettre en italique

Attends un peu là ! Je croyais que la balise <em> permettait de mettre un texte en italique ?!

Je n'ai jamais dit cela.
Retournez voir les chapitres précédents si vous avez des doutes, mais je n'ai jamais dit que la balise <em> était faite pour mettre le texte en italique (de même que je n'ai jamais dit que <strong> était faite pour mettre en gras).

<em>, mettez-vous bien cela dans la tête, est faite pour insister sur des mots. Cela veut dire que les mots qu'elle entoure sont assez importants.
Pour représenter cette importance, la plupart des navigateurs choisissent d'afficher le texte en italique, mais ce n'est pas une obligation.

Le CSS lui, permet de dire réellement : « Je veux que ce texte soit en italique ». Rien ne vous empêche, par exemple, de décider que tous vos titres seront en italique.

Concrètement, en CSS, pour mettre en italique, on utilise font-style qui peut prendre trois valeurs :

  • italic : le texte sera mis en italique.

  • oblique : le texte sera passé en oblique (les lettres sont penchées, le résultat est légèrement différent de l'italique proprement dit).

  • normal : le texte sera normal (par défaut). Cela vous permet d'annuler une mise en italique. Par exemple, si vous voulez que les textes entre <em> ne soient plus en italique, vous devrez écrire :

em
{
    font-style: normal;
}

Ainsi, dans l'exemple suivant, je me sers de font-style pour mettre en italique tous mes titres <h2> :

h2
{
    font-style: italic;
}

Mettre en gras

Et si nous passions à la mise en gras ?
Alors, là encore, n'oubliez pas que ce n'est pas <strong> qui permet de mettre en gras (son rôle est d'indiquer que le texte est important, donc le navigateur l'affiche généralement en gras). La mise en gras en CSS peut par exemple s'appliquer aux titres, à certains paragraphes entiers, etc. C'est à vous de voir.

La propriété CSS pour mettre en gras est font-weight et prend les valeurs suivantes :

  • bold : le texte sera en gras ;

  • normal : le texte sera écrit normalement (par défaut).

Voici par exemple comment écrire les titres en gras :

h1
{
    font-weight: bold;
}

Soulignement et autres décorations

La propriété CSS associée porte bien son nom : text-decoration. Elle permet, entre autres, de souligner le texte, mais pas seulement. Voici les différentes valeurs qu'elle peut prendre :

  • underline : souligné.

  • line-through : barré.

  • overline : ligne au-dessus.

  • blink : clignotant. Ne fonctionne pas sur tous les navigateurs (Internet Explorer et Google Chrome, notamment).

  • none : normal (par défaut).

Ce CSS va vous permettre de tester les effets de text-decoration :

h1
{
    text-decoration: blink;
}
.souligne
{
    text-decoration: underline;
}
.barre
{
    text-decoration: line-through;
}
.ligne_dessus
{
    text-decoration: overline;
}

Et le résultat est visible à la figure suivante.

Différentes mises en forme du texte
Différentes mises en forme du texte

L'alignement

Le langage CSS nous permet de faire tous les alignements connus : à gauche, centré, à droite et justifié.

C'est tout simple. On utilise la propriété text-align et on indique l'alignement désiré :

  • left : le texte sera aligné à gauche (c'est le réglage par défaut).

  • center : le texte sera centré.

  • right : le texte sera aligné à droite.

  • justify : le texte sera « justifié ». Justifier le texte permet de faire en sorte qu'il prenne toute la largeur possible sans laisser d'espace blanc à la fin des lignes. Les textes des journaux, par exemple, sont toujours justifiés.

Regardez les différents alignements sur cet exemple :

h1
{
    text-align: center;
}

p
{
    text-align: justify;
}

.signature
{
    text-align: right;
}

Le résultat est visible à la figure suivante.

Alignements du texte
Alignements du texte

Vous ne pouvez pas modifier l'alignement du texte d'une balise inline (comme <span>, <a>, <em>, <strong>…). L'alignement ne fonctionne que sur des balises de type block (<p>, <div>, <h1>, <h2>, …) et c'est un peu logique, quand on y pense : on ne peut pas modifier l'alignement de quelques mots au milieu d'un paragraphe !
C'est donc en général le paragraphe entier qu'il vous faudra aligner.

Les flottants

Le CSS nous permet de faire flotter un élément autour du texte. On dit aussi qu'on fait un « habillage ».

Pour que vous voyiez bien de quoi on parle, la figure suivante vous montre ce que nous allons apprendre à faire.

Une image flottante entourée par du texte
Une image flottante entourée par du texte

J'imagine que, maintenant, la question qui vous brûle les lèvres est : « Mais quelle est donc la propriété magique qui fait flotter ? ».
La réponse est… float (« flottant » en anglais). Cette propriété peut prendre deux valeurs très simples :

  • left : l'élément flottera à gauche.

  • right : l'élément flottera… à droite ! Oui, bravo.

L'utilisation des flottants est très simple :

  1. Vous appliquez un float à une balise.

  2. Puis vous continuez à écrire du texte à la suite normalement.

On peut aussi bien utiliser la propriété float sur des balises block que sur des balises inline. Il est courant de faire flotter une image pour qu'elle soit habillée par du texte, comme dans l'exemple précédent.

Faire flotter une image

Nous allons apprendre ici à faire flotter une image. Voici le code HTML que nous devons taper dans un premier temps :

<p><img src="flash.gif" class="imageflottante" alt="Image flottante" /> Ceci est un texte normal de paragraphe, écrit à la suite de l'image et qui l'habillera car l'image est flottante.</p>

Vous devez placer l'élément flottant en premier dans le code HTML. Si vous placez l'image après le paragraphe, l'effet ne fonctionnera pas.

Voici le seul bout de code CSS qu'on ait besoin de taper, qui permet de faire flotter l'image à gauche :

.imageflottante
{
    float: left;
}

Amusez-vous aussi à faire flotter l'image à droite, c'est tout bête : il suffit d'indiquer la valeur right et le tour est joué !

Stopper un flottant

Quand vous mettez en place un flottant, le texte autour l'habille. Mais comment faire si vous voulez qu'au bout d'un moment le texte continue en dessous du flottant ? On pourrait enchaîner plusieurs <br /> à la suite mais cela ne serait ni élégant ni très propre…

En gros, on aimerait pouvoir obtenir le même résultat qu'à la figure suivante.

Le texte sous l'image ignore la propriété float
Le texte sous l'image ignore la propriété float

Il existe en fait une propriété CSS qui permet de dire : « Stop, ce texte doit être en-dessous du flottant et non plus à côté ». C'est la propriété clear, qui peut prendre ces trois valeurs :

  • left : le texte se poursuit en-dessous après un float: left;

  • right : le texte se poursuit en-dessous après un float: right;

  • both : le texte se poursuit en-dessous, que ce soit après un float: left; ou après un float: right;.

Pour simplifier, on va utiliser tout le temps le clear: both, qui marche après un flottant à gauche et après un flottant à droite (cela fonctionne donc à tous les coups). Pour illustrer son fonctionnement, on va prendre ce code HTML :

<p><img src="flash.gif" class="imageflottante" alt="Image flottante" /></p>
<p>Ce texte est écrit à côté de l'image flottante.</p>
<p class="dessous">Ce texte est écrit sous l'image flottante.</p>

Et ce code CSS :

.imageflottante
{
    float: left;
}
.dessous
{
    clear: both;
}

Et voilà le travail.

On applique un clear: both; au paragraphe que l'on veut voir continuer sous l'image flottante et le tour est joué !

En résumé

  • On modifie la taille du texte avec la propriété CSS font-size. On peut indiquer la taille en pixels (16px), en « em » (1.3em), en pourcentage (110%), etc.

  • On change la police du texte avec font-family. Attention, seules quelques polices sont connues par tous les ordinateurs. Vous pouvez cependant utiliser une police personnalisée avec la directive @font-face : cela forcera les navigateurs à télécharger la police de votre choix.

  • De nombreuses propriétés de mise en forme du texte existent : font-style pour l'italique, font-weight pour la mise en gras, text-decoration pour le soulignement, etc.

  • Le texte peut être aligné avec text-align.

  • On peut faire en sorte qu'une image soit habillée (« entourée ») de texte avec float.


Tutoriel VBScript

La couleur et le fond

https://vimeo.com/76006316

Continuons notre tour d'horizon des propriétés CSS existantes. Nous allons nous intéresser ici aux propriétés liées de près ou de loin à la couleur. Nous verrons entre autres :

  • comment changer la couleur du texte ;

  • comment mettre une couleur ou une image d'arrière-plan ;

  • comment ajouter des ombres ;

  • comment jouer avec les niveaux de transparence.

Le CSS n'a pas fini de nous étonner !

Couleur du texte

Passons maintenant au vaste sujet de la couleur.

Comment cela, « vaste » ?

Vous connaissez déjà la propriété qui permet de modifier la couleur du texte : il s'agit de color. Nous allons nous intéresser aux différentes façons d'indiquer la couleur, car il y en a plusieurs.

Indiquer le nom de la couleur

La méthode la plus simple et la plus pratique pour choisir une couleur consiste à taper son nom (in english, of course).
Le seul défaut de cette méthode est qu'il n'existe que seize couleurs dites « standard ». D'autres couleurs officieuses existent mais, comme elles ne fonctionneront pas forcément de la même manière sur tous les navigateurs, je vais éviter de vous les montrer.

La figure suivante vous montre les seize couleurs que vous pouvez utiliser en tapant simplement leur nom.

Les seize noms de couleurs utilisables en CSS
Les seize noms de couleurs utilisables en CSS

Vous pouvez les apprendre par cœur si cela vous chante, en plus cela vous fera réviser votre anglais.

Pour passer tous les titres en marron, on peut donc écrire :

h1
{
    color: maroon;
}

Vous trouverez le résultat à la figure suivante.

Le titre est écrit en marron
Le titre est écrit en marron

La notation hexadécimale

Seize couleurs, c'est quand même un peu limite quand on sait que la plupart des écrans peuvent en afficher seize millions.
D'un autre côté, remarquez, s'il avait fallu donner un nom à chacune des seize millions de couleurs…

Heureusement, il existe en CSS plusieurs façons de choisir une couleur parmi toutes celles qui existent. La première que je vais vous montrer est la notation hexadécimale. Elle est couramment utilisée sur le Web mais il existe aussi une autre méthode que nous verrons plus loin.

Un nom de couleur en hexadécimal, cela ressemble à : #FF5A28. Pour faire simple, c'est une combinaison de lettres et de chiffres qui indiquent une couleur.
On doit toujours commencer par écrire un dièse (#), suivi de six lettres ou chiffres allant de 0 à 9 et de A à F.
Ces lettres ou chiffres fonctionnent deux par deux. Les deux premiers indiquent une quantité de rouge, les deux suivants une quantité de vert et les deux derniers une quantité de bleu. En mélangeant ces quantités (qui sont les composantes Rouge-Vert-Bleu de la couleur) on peut obtenir la couleur qu'on veut.

Ainsi, #000000 correspond à la couleur noire et #FFFFFF à la couleur blanche. Mais maintenant, ne me demandez pas quelle est la combinaison qui produit de l'orange couleur « coucher de soleil », je n'en sais strictement rien.

Certains logiciels de dessin, comme Photoshop, Gimp et Paint.NET, vous indiquent les couleurs en hexadécimal. Il vous est alors facile de copier-coller le code hexadécimal d'une couleur dans votre fichier CSS.

Voici par exemple comment on fait pour appliquer aux paragraphes la couleur blanche en hexadécimal :

p
{
    color: #FFFFFF;
}

Notez qu'il existe une notation raccourcie : on peut écrire une couleur avec seulement trois caractères. Par exemple : #FA3 équivaut à écrire #FFAA33.

La méthode RGB

Que signifie RGB ? En anglais, Rouge-Vert-Bleu s'écrit Red-Green-Blue, ce qui s'abrège en « RGB ». Comme avec la notation hexadécimale, pour choisir une couleur, on doit définir une quantité de rouge, de vert et de bleu.

Encore cette histoire tordue de quantités de rouge-vert-bleu ?

Oui mais là, vous allez voir que c'est beaucoup plus pratique et qu'avec un logiciel de dessin tout simple comme Paint, vous pouvez trouver la couleur que vous désirez. Voici la marche à suivre :

  1. Lancez le logiciel Paint depuis le menu Démarrer.

  2. Rendez-vous dans la section Modifier les couleurs, comme indiqué à la figure suivante.

  3. Une fenêtre s'ouvre. Dans la zone qui apparaît à droite, faites bouger les curseurs pour sélectionner la couleur qui vous intéresse. Supposons que vous soyez pris d'une envie folle d'écrire vos titres <h1> en rose bonbon (supposons seulement). Sélectionnez la couleur dans la fenêtre, comme à la figure suivante.

  4. Relevez les quantités de Rouge-Vert-Bleu correspondantes, indiquées en bas à droite de la fenêtre (ici 240-96-204). Recopiez ces valeurs dans cet ordre dans le fichier CSS, comme dans le code ci-dessous.

p
{
    color: rgb(240,96,204);
}
Modification des couleurs sous Paint
Modification des couleurs sous Paint
Sélection d'une couleur dans Paint
Sélection d'une couleur dans Paint

Comme vous avez pu le constater dans l'exemple, pour utiliser la méthode RGB, il faut taper rgb(Rouge, Vert, Bleu) en remplaçant « Rouge, Vert, Bleu » par les nombres correspondants. Pour information, ces quantités sont toujours comprises entre 0 et 255.

Et en Bonus Track…

Je vous conseille un petit logiciel tout simple, gratuit et en français, réalisé par Benjamin Chartier, précisément conçu pour choisir vos couleurs. Nul doute qu'il vous sera très utile pour vous aider à choisir vos couleurs. Ce logiciel s'appelle « La boîte à couleurs » (figure suivante).

La boîte à couleurs La boîte à couleurs

Comme vous pouvez le voir, il comporte plusieurs onglets. Je vous recommande de rester sur le premier (RVB) ou d'aller dans l'onglet Visuel. Les autres ne nous concernent pas. Évitez en particulier l'onglet Nom, qui propose des noms de couleurs parfois invalides (je vous rappelle qu'il existe seulement seize noms de couleurs « standard »).
Vous pouvez récupérer en bas à droite le numéro de la couleur en hexadécimal (le numéro commence toujours par un #) ou encore recopier les valeurs de Rouge-Vert-Bleu (RVB) dans le CSS.

Enfin, et c'est certainement la fonctionnalité la plus intéressante du logiciel, vous pouvez utiliser la pipette en haut à droite pour récupérer n'importe quelle couleur s'affichant sur votre écran !
Amusez-vous bien !

Couleur de fond

Pour indiquer une couleur de fond, on utilise la propriété CSS background-color. Elle s'utilise de la même manière que la propriété color, c'est-à-dire que vous pouvez taper le nom d'une couleur, l'écrire en notation hexadécimale ou encore utiliser la méthode RGB.

Pour indiquer la couleur de fond de la page web, il faut travailler sur la balise <body>. Eh oui, <body> correspond à l'ensemble de la page web, c'est donc en modifiant sa couleur de fond que l'on changera la couleur d'arrière-plan de la page.

Regardez très attentivement ce fichier CSS :

/* On travaille sur la balise body, donc sur TOUTE la page */
body
{
    background-color: black; /* Le fond de la page sera noir */
    color: white; /* Le texte de la page sera blanc */
}

Voici le rendu de ce code en figure suivante.

Texte en blanc sur fond noir
Texte en blanc sur fond noir

Eh mais tu as demandé à ce que le texte de la balise <body> soit écrit en blanc, et tous les paragraphes <p> et titres <h1> ont pris cette couleur. Comment cela se fait-il ?

Je voulais justement profiter de l'occasion pour vous en parler. Ce phénomène s'appelle l'héritage. Je vous rassure tout de suite, personne n'est mort.

Le CSS et l'héritage

En CSS, si vous appliquez un style à une balise, toutes les balises qui se trouvent à l'intérieur prendront le même style.

C'est en fait simple à comprendre et intuitif. La balise <body>, vous le savez, contient entre autres les balises de paragraphe <p> et de titre <h1>.

Si j'applique une couleur de fond noire et une couleur de texte blanche à la balise <body>, tous mes titres et paragraphes auront eux aussi un arrière-plan de couleur noire et un texte de couleur blanche… C'est ce phénomène qu'on appelle l'héritage : on dit que les balises qui se trouvent à l'intérieur d'une autre balise « héritent » de ses propriétés.

C'est d'ailleurs de là que vient le nom « CSS », qui signifie « Cascading Style Sheets », c'est-à-dire « Feuilles de style en cascade ». Les propriétés CSS sont héritées en cascade : si vous donnez un style à un élément, tous les sous-éléments auront le même style.

Cela veut dire que TOUT le texte de ma page web sera forcément écrit en blanc ?

Non, pas obligatoirement. Si vous dites par la suite que vous voulez vos titres en rouge, ce style aura la priorité et vos titres seront donc en rouge. En revanche, si vous n'indiquez rien de particulier (comme on l'a fait tout à l'heure), alors vos titres hériteront de la couleur blanche.
Cela ne fonctionne pas uniquement pour la couleur, entendons-nous bien. Toutes les propriétés CSS seront héritées : vous pouvez par exemple demander une mise en gras dans la balise <body> et tous vos titres et paragraphes seront en gras.

Exemple d'héritage avec la balise <mark>

On a tendance à croire qu'on ne peut modifier que la couleur de fond de la page. C'est faux : vous pouvez changer le fond de n'importe quel élément : vos titres, vos paragraphes, certains mots… Dans ce cas, ils apparaîtront surlignés (comme si on avait mis un coup de marqueur dessus).

Vous vous souvenez par exemple de la balise <mark> qui permet de mettre en valeur certains mots ? Utilisons-la à nouveau ici :

<h1>Qui a éteint la lumière ?</h1>

<p>Brr, il fait tout noir sur ce site, c'est un peu <mark>inquiétant</mark> comme ambiance non vous trouvez pas ?</p>

Par défaut, le texte s'affiche sur un fond jaune. Vous pouvez changer ce comportement en CSS :

body
{
    background-color: black;
    color: white;
}

mark
{
    /* La couleur de fond prend le pas sur celle de toute la page */
    background-color: red;
    color: black;
}

Sur le texte de la balise <mark>, c'est la couleur de fond rouge qui s'applique. En effet, même si le fond de la page est noir, c'est la propriété CSS de l'élément le plus précis qui a la priorité (figure suivante).

Un texte surligné en rouge sur un fond noir
Un texte surligné en rouge sur un fond noir

Le même principe vaut pour toutes les balises HTML et toutes les propriétés CSS ! Si vous dites :

  • mes paragraphes ont une taille de 1.2 em ;

  • mes textes importants (<strong>) ont une taille de 1.4 em ;

… on pourrait penser qu'il y a un conflit. Le texte important fait partie d'un paragraphe, quelle taille lui donner ? 1.2 em ou 1.4 em ? Le CSS décide que c'est la déclaration la plus précise qui l'emporte : comme <strong> correspond à un élément plus précis que les paragraphes, le texte sera écrit en 1.4 em.

Images de fond

Dans les exemples qui suivent, je vais modifier l'image de fond de la page. Cependant, tout comme pour la couleur de fond, n'oubliez pas que l'image de fond ne s'applique pas forcément à la page entière. On peut aussi mettre une image de fond derrière les titres, paragraphes, etc.

Appliquer une image de fond

La propriété permettant d'indiquer une image de fond est background-image. Comme valeur, on doit renseigner url("nom_de_l_image.png"). Par exemple :

body
{
    background-image: url("neige.png");
}

Ce qui nous donne la figure suivante.

Une image de fond sur la page
Une image de fond sur la page

Bien entendu, votre fond n'est pas forcément en PNG, il peut aussi être en JPEG ou en GIF.
L'adresse indiquant où se trouve l'image de fond peut être écrite en absolu (http://…) ou en relatif (fond.png).

Attention lorsque vous écrivez une adresse en relatif dans le fichier CSS ! L'adresse de l'image doit être indiquée par rapport au fichier .css et non pas par rapport au fichier .html. Pour simplifier les choses, je vous conseille de placer l'image de fond dans le même dossier que le fichier .css (ou dans un sous-dossier).

Options disponibles pour l'image de fond

On peut compléter la propriété background-image que nous venons de voir par plusieurs autres propriétés qui permettent de changer le comportement de l'image de fond.

background-attachment : fixer le fond

La propriété CSS background-attachment permet de « fixer » le fond. L'effet obtenu est intéressant car on voit alors le texte « glisser » par-dessus le fond. Deux valeurs sont disponibles :

  • fixed : l'image de fond reste fixe ;

  • scroll : l'image de fond défile avec le texte (par défaut).

body
{
    background-image: url("neige.png");
    background-attachment: fixed; /* Le fond restera fixe */
}
background-repeat : répétition du fond

Par défaut, l'image de fond est répétée en mosaïque. Vous pouvez changer cela avec la propriété background-repeat :

  • no-repeat : le fond ne sera pas répété. L'image sera donc unique sur la page.

  • repeat-x : le fond sera répété uniquement sur la première ligne, horizontalement.

  • repeat-y : le fond sera répété uniquement sur la première colonne, verticalement.

  • repeat : le fond sera répété en mosaïque (par défaut).

Exemple d'utilisation :

body
{
    background-image: url("soleil.png");
    background-repeat: no-repeat;
}
background-position : position du fond

On peut indiquer où doit se trouver l'image de fond avec background-position. Cette propriété n'est intéressante que si elle est combinée avec background-repeat: no-repeat; (un fond qui ne se répète pas).

Vous devez donner à background-position deux valeurs en pixels pour indiquer la position du fond par rapport au coin supérieur gauche de la page (ou du paragraphe, si vous appliquez le fond à un paragraphe). Ainsi, si vous tapez :

background-position: 30px 50px;

… votre fond sera placé à 30 pixels de la gauche et à 50 pixels du haut. Il est aussi possible d'utiliser ces valeurs en anglais :

  • top : en haut ;

  • bottom : en bas ;

  • left : à gauche ;

  • center : centré ;

  • right : à droite.

Il est possible de combiner ces mots. Par exemple, pour aligner une image en haut à droite, vous taperez :

background-position: top right;

Ainsi, si je veux afficher un soleil en image de fond (figure suivante), en un unique exemplaire (no-repeat), toujours visible (fixed) et positionné en haut à droite (top right), je vais écrire ceci :

body
{
    background-image: url("soleil.png");
    background-attachment: fixed; /* Le fond restera fixe */
    background-repeat: no-repeat; /* Le fond ne sera pas répété */
    background-position: top right; /* Le fond sera placé en haut à droite */
}
Un soleil placé en image de fond en haut à droite
Un soleil placé en image de fond en haut à droite

Combiner les propriétés

Si vous utilisez beaucoup de propriétés en rapport avec le fond (comme c'est le cas sur ce dernier exemple), vous pouvez utiliser une sorte de « super-propriété » appelée background dont la valeur peut combiner plusieurs des propriétés vues précédemment : background-image, background-repeat, background-attachment et background-position.

On peut donc tout simplement écrire :

body
{
    background: url("soleil.png") fixed no-repeat top right;
}

C'est la première « super-propriété » que je vous montre, il y en aura d'autres. Il faut savoir que :

  • L'ordre des valeurs n'a pas d'importance. Vous pouvez combiner les valeurs dans n'importe quel ordre.

  • Vous n'êtes pas obligés de mettre toutes les valeurs. Ainsi, si vous ne voulez pas écrire fixed, vous pouvez l'enlever sans problème.

Plusieurs images de fond

Depuis CSS3, il est possible de donner plusieurs images de fond à un élément. Pour cela, il suffit de séparer les déclarations par une virgule, comme ceci :

body
{
    background: url("soleil.png") fixed no-repeat top right, url("neige.png") fixed;
}

La première image de cette liste sera placée par-dessus les autres (figure suivante). Attention donc, l'ordre de déclaration des images a son importance : si vous inversez le soleil et la neige dans le code CSS précédent, vous ne verrez plus le soleil !

Images de fond multiples
Images de fond multiples

À noter que les images de fond multiples fonctionnent sur tous les navigateurs sauf sur les anciennes versions d'Internet Explorer, qui ne reconnaît cette fonctionnalité qu'à partir de la version 9 (IE9).

Une dernière chose avant d'en terminer avec les images de fond : dans tous ces exemples, j'ai appliqué un fond à la page entière (body). Mais cela ne doit pas vous faire oublier qu'on peut appliquer un fond à n'importe quel élément (un titre, un paragraphe, certains mots d'un paragraphe, etc.).
Je vous conseille donc, pour vous entraîner, d'essayer d'appliquer un fond à vos titres ou paragraphes. Si vous avez un peu de goût (contrairement à moi !) vous arriverez certainement à donner une très belle allure à votre page web.

La transparence

Le CSS nous permet de jouer très facilement avec les niveaux de transparence des éléments ! Pour cela, nous allons utiliser des fonctionnalités de CSS3 : la propriété opacity et la notation RGBa.

La propriété opacity

La propriété opacity, très simple, permet d'indiquer le niveau d'opacité (c'est l'inverse de la transparence).

  • Avec une valeur de 1, l'élément sera totalement opaque : c'est le comportement par défaut.

  • Avec une valeur de 0, l'élément sera totalement transparent.

Il faut donc choisir une valeur comprise entre 0 et 1. Ainsi, avec une valeur de 0.6, votre élément sera opaque à 60%… et on verra donc à travers !

Voici comment on peut l'utiliser :

p
{
    opacity: 0.6;
}

Voici un exemple qui va nous permettre d'apprécier la transparence. Vous en trouverez le rendu à la figure suivante.

body
{
    background: url('neige.png');
}

p
{
    background-color: black;
    color: white;
    opacity: 0.3;
}
Un paragraphe transparent
Un paragraphe transparent

Notez que la transparence fonctionne sur tous les navigateurs récents, y compris Internet Explorer à partir de IE9.

Si vous appliquez la propriété opacity à un élément de la page, tout le contenu de cet élément sera rendu transparent (même les images, les autres blocs à l'intérieur, etc.). Si vous voulez juste rendre la couleur de fond transparente, utilisez plutôt la notation RGBa que nous allons découvrir.

La notation RGBa

CSS3 nous propose une autre façon de jouer avec la transparence : la notation RGBa. Il s'agit en fait de la notation RGB que nous avons vue précédemment, mais avec un quatrième paramètre : le niveau de transparence (appelé « canal alpha »). De la même façon que précédemment, avec une valeur de 1, le fond est complètement opaque. Avec une valeur inférieure à 1, il est transparent.

p
{
    background-color: rgba(255, 0, 0, 0.5); /* Fond rouge à moitié transparent */
}

C'est aussi simple que cela. Vous pouvez obtenir exactement le même effet qu'avec opacity juste en jouant avec la notation RGBa, essayez !

Cette notation est connue de tous les navigateurs récents, y compris Internet Explorer (à partir de IE9). Pour les navigateurs plus anciens, il est recommandé d'indiquer la notation RGB classique en plus de RGBa.
Pour ces navigateurs, le fond ne sera alors pas transparent mais, au moins, il y aura bien une couleur d'arrière-plan.

p
{
    background-color: rgb(255,0,0); /* Pour les navigateurs anciens */
    background-color: rgba(255,0,0,0.5); /* Pour les navigateurs plus récents */
}

En résumé

  • On change la couleur du texte avec la propriété color, la couleur de fond avec background-color.

  • On peut indiquer une couleur en écrivant son nom en anglais (black, par exemple), sous forme hexadécimale (#FFC8D3) ou en notation RGB (rgb(250,25,118)).

  • On peut ajouter une image de fond avec background-image. On peut choisir de fixer l'image de fond, de l'afficher en mosaïque ou non, et même de la positionner où on veut sur la page.

  • On peut rendre une portion de la page transparente avec la propriété opacity ou avec la notation RGBa (identique à la notation RGB, avec une quatrième valeur indiquant le niveau de transparence).


Tutoriel VBScript

Les bordures et les ombres

https://vimeo.com/76002206

Nouveau chapitre, nouveau lot de propriétés CSS. Ici, nous allons nous intéresser aux bordures et aux effets d'ombrage que l'on peut appliquer, aussi bien sur le texte que sur les blocs qui constituent notre page.

Nous réutiliserons en particulier nos connaissances sur les couleurs pour choisir la couleur de nos bordures et de nos ombres.

Prêts à vous en mettre une nouvelle fois plein la vue ?

Bordures standard

Le CSS vous offre un large choix de bordures pour décorer votre page. De nombreuses propriétés CSS vous permettent de modifier l'apparence de vos bordures : border-width, border-color, border-style…

Pour aller à l'essentiel, je vous propose ici d'utiliser directement la super-propriété border qui regroupe l'ensemble de ces propriétés. Vous vous souvenez de la super-propriété background ? Cela fonctionne sur le même principe : on va pouvoir combiner plusieurs valeurs.

Pour border on peut utiliser jusqu'à trois valeurs pour modifier l'apparence de la bordure :

  • La largeur : indiquez la largeur de votre bordure. Mettez une valeur en pixels (comme 2px).

  • La couleur : c'est la couleur de votre bordure. Utilisez, comme on l'a appris, soit un nom de couleur (black, red,…), soit une valeur hexadécimale (#FF0000), soit une valeur RGB (rgb(198, 212, 37)).

  • Le type de bordure : là, vous avez le choix. Votre bordure peut être un simple trait, ou des pointillés, ou encore des tirets, etc. Voici les différentes valeurs disponibles :

    • none : pas de bordure (par défaut) ;

    • solid : un trait simple ;

    • dotted : pointillés ;

    • dashed : tirets ;

    • double : bordure double ;

    • groove : en relief ;

    • ridge : autre effet relief ;

    • inset : effet 3D global enfoncé ;

    • outset : effet 3D global surélevé.

Ainsi, pour avoir une bordure bleue, en tirets, épaisse de 3 pixels autour de mes titres, je vais écrire :

h1
{
    border: 3px blue dashed;
}

La figure suivante vous présente les différents styles de bordures que vous pouvez utiliser.

Les différents types de bordures
Les différents types de bordures

En haut, à droite, à gauche, en bas…

Qui a dit que vous étiez obligés d'appliquer la même bordure aux quatre côtés de votre élément ?
Taratata, si vous voulez mettre des bordures différentes en fonction du côté (haut, bas, gauche ou droite), vous pouvez le faire sans problème. Dans ce cas, vous devrez utiliser ces quatre propriétés :

  • border-top : bordure du haut ;

  • border-bottom : bordure du bas ;

  • border-left : bordure de gauche ;

  • border-right : bordure de droite.

Il existe aussi des équivalents pour paramétrer chaque détail de la bordure si vous le désirez : border-top-width pour modifier l'épaisseur de la bordure du haut, border-top-color pour la couleur du haut, etc.

Ce sont aussi des super-propriétés, elles fonctionnent comme border mais ne s'appliquent donc qu'à un seul côté.

Pour ajouter une bordure uniquement à gauche et à droite des paragraphes, on écrira donc :

p
{
    border-left: 2px solid black;
    border-right: 2px solid black;
}

On peut modifier les bordures de n'importe quel type d'élément sur la page. Nous l'avons fait ici sur les paragraphes mais on peut aussi modifier la bordure des images, des textes importants comme <strong>, etc.

Bordures arrondies

Les bordures arrondies, c'est un peu le Saint Graal attendu par les webmasters depuis des millénaires (ou presque). Depuis que CSS3 est arrivé, il est enfin possible d'en créer facilement !

La propriété border-radius va nous permettre d'arrondir facilement les angles de n'importe quel élément. Il suffit d'indiquer la taille (« l'importance ») de l'arrondi en pixels :

p
{
    border-radius: 10px;
}

L'arrondi se voit notamment si l'élément a des bordures, comme sur la figure suivante.

Des bordures arrondies
Des bordures arrondies

… ou s'il a une couleur de fond, comme sur la figure suivante.

Un fond aux coins arrondis
Un fond aux coins arrondis

On peut aussi préciser la forme de l'arrondi pour chaque coin. Dans ce cas, indiquez quatre valeurs :

p
{
    border-radius: 10px 5px 10px 5px;
}

Les valeurs correspondent aux angles suivants dans cet ordre :

  1. en haut à gauche ;

  2. en haut à droite ;

  3. en bas à droite ;

  4. en bas à gauche.

Enfin, il est possible d'affiner l'arrondi de nos angles en créant des courbes elliptiques figure suivante). Dans ce cas, il faut indiquer deux valeurs séparées par une barre oblique (slash, caractère /). Le mieux est certainement de tester pour voir l'effet :

p
{
    border-radius: 20px / 10px;
}
Bordures arrondies elliptiques
Bordures arrondies elliptiques

Les bordures arrondies fonctionnent avec tous les navigateurs récents, y compris Internet Explorer à partir de la version 9 (IE9).
Pour les anciennes versions de Mozilla Firefox, Chrome et Safari, il était nécessaire d'utiliser ce qu'on appelle des « préfixes vendeurs », c'est-à-dire qu'il fallait écrire dans le code CSS différentes versions de la propriété (-moz-border-radius pour Firefox, -webkit-border-radius pour Safari, etc.). Ce n'est heureusement plus nécessaire aujourd'hui, sauf si vous voulez gérer les anciennes versions de ces navigateurs.

Les ombres

Les ombres font partie des nouveautés récentes proposées par CSS3. Aujourd'hui, il suffit d'une seule ligne de CSS pour ajouter des ombres dans une page !

Nous allons ici découvrir deux types d'ombres :

  • les ombres des boîtes ;

  • les ombres du texte.

box-shadow : les ombres des boîtes

La propriété box-shadow s'applique à tout le bloc et prend quatre valeurs dans l'ordre suivant :

  1. le décalage horizontal de l'ombre ;

  2. le décalage vertical de l'ombre ;

  3. l'adoucissement du dégradé ;

  4. la couleur de l'ombre.

Par exemple, pour une ombre noire de 6 pixels, sans adoucissement, on écrira :

p
{
    box-shadow: 6px 6px 0px black;
}

Cela donne le résultat illustré à la figure suivante (j'ai ajouté une bordure au paragraphe pour qu'on voie mieux l'effet).

Une ombre sous le paragraphe
Une ombre sous le paragraphe

Ajoutons un adoucissement grâce au troisième paramètre (figure suivante). L'adoucissement peut être faible (inférieur au décalage), normal (égal au décalage) ou élevé (supérieur au décalage). Essayons un décalage normal :

p
{
    box-shadow: 6px 6px 6px black;
}
Une ombre adoucie sous le paragraphe
Une ombre adoucie sous le paragraphe

On peut aussi rajouter une cinquième valeur facultative : inset. Dans ce cas, l'ombre sera placée à l'intérieur du bloc, pour donner un effet enfoncé :

p
{
    box-shadow: 6px 6px 6px black inset;
}

Je vous laisse essayer de voir le résultat.

La propriété box-shadow fonctionne sur tous les navigateurs récents, IE9 inclus. Pour certains navigateurs, en particulier les navigateurs mobiles, il faut encore rajouter un préfixe. Ainsi, il faudra écrire une version -webkit-box-shadow pour que cela fonctionne sur les navigateurs Android et iOS.

text-shadow : l'ombre du texte

Avec text-shadow, vous pouvez ajouter une ombre directement sur les lettres de votre texte ! Les valeurs fonctionnent exactement de la même façon que box-shadow : décalage, adoucissement et couleur.

p
{
    text-shadow: 2px 2px 4px black;
}

Le résultat est illustré à la figure suivante.

Texte ombré

Cette propriété est reconnue par tous les navigateurs récents, sauf Internet Explorer, qui ne la reconnaît qu'à partir de la version IE10.

En résumé

  • On peut appliquer une bordure à un élément avec la propriété border. Il faut indiquer la largeur de la bordure, sa couleur et son type (trait continu, pointillés…).

  • On peut arrondir les bordures avec border-radius.

  • On peut ajouter une ombre aux blocs de texte avec box-shadow. On doit indiquer le décalage vertical et horizontal de l'ombre, son niveau d'adoucissement et sa couleur.

  • Le texte peut lui aussi avoir une ombre avec text-shadow.


Tutoriel VBScript

Création d'apparences dynamiques

https://vimeo.com/76006324

C'est une de ses forces : le CSS nous permet aussi de modifier l'apparence des éléments de façon dynamique, c'est-à-dire que des éléments peuvent changer de forme une fois que la page a été chargée. Nous allons faire appel à une fonctionnalité puissante du CSS : les pseudo-formats.

Nous verrons dans ce chapitre comment changer l'apparence :

  • au survol ;

  • lors du clic ;

  • lors du focus (élément sélectionné) ;

  • lorsqu'un lien a été consulté.

Vous allez voir que le langage CSS n'a pas fini de nous étonner !

Au survol

Nous allons découvrir dans ce chapitre plusieurs pseudo-formats CSS. Le premier que je vais vous montrer s'appelle :hover. Comme tous les autres pseudo-formats que nous allons voir, c'est une information que l'on rajoute après le nom de la balise (ou de la classe) dans le CSS, comme ceci :

a:hover
{

}

:hover signifie « survoler ». a:hover peut donc se traduire par : « Quand la souris est sur le lien » (quand on pointe dessus).

À partir de là, c'est à vous de définir l'apparence que doivent avoir les liens lorsqu'on pointe dessus. Laissez libre cours à votre imagination, il n'y a pas de limite.

Voici un exemple de présentation des liens, mais n'hésitez pas à inventer le vôtre :

a /* Liens par défaut (non survolés) */
{
   text-decoration: none;
   color: red;
   font-style: italic;
}

a:hover /* Apparence au survol des liens */
{
   text-decoration: underline;
   color: green;
}

On a défini ici deux versions des styles pour les liens :

  • pour les liens par défaut (non survolés) ;

  • pour les liens au survol.

Le résultat se trouve à la figure suivante.

Changement d'apparence au survol de la souris
Changement d'apparence au survol de la souris

Sympa, n'est-ce pas ?

Même si on l'utilise souvent sur les liens, vous pouvez modifier l'apparence de n'importe quel élément. Par exemple, vous pouvez modifier l'apparence des paragraphes lorsqu'on pointe dessus :

p:hover /* Quand on pointe sur un paragraphe */
{

}

Au clic et lors de la sélection

Vous pouvez interagir encore plus finement en CSS. Nous allons voir ici que nous pouvons changer l'apparence des éléments lorsque l'on clique dessus et lorsqu'ils sont sélectionnés !

:active : au moment du clic

Le pseudo-format :active permet d'appliquer un style particulier au moment du clic. En pratique, il n'est utilisé que sur les liens.

Le lien gardera cette apparence très peu de temps : en fait, le changement intervient lorsque le bouton de la souris est enfoncé. En clair, ce n'est pas forcément toujours bien visible.

On peut par exemple changer la couleur de fond du lien lorsque l'on clique dessus :

a:active /* Quand le visiteur clique sur le lien */
{
    background-color: #FFCC66;
}

:focus : lorsque l'élément est sélectionné

Là, c'est un peu différent. Le pseudo-format :focus applique un style lorsque l'élément est sélectionné.

C'est-à-dire ?

Une fois que vous avez cliqué, le lien reste « sélectionné » (il y a une petite bordure en pointillés autour). C'est cela, la sélection.

Ce pseudo-format pourra être appliqué à d'autres balises HTML que nous n'avons pas encore vues, comme les éléments de formulaires.

Essayons pour l'instant sur les liens :

a:focus /* Quand le visiteur sélectionne le lien */
{
    background-color: #FFCC66;
}

Sous Google Chrome et Safari, l'effet ne se voit que si l'on appuie sur la touche Tab.

Lorsque le lien a déjà été consulté

Il est possible d'appliquer un style à un lien vers une page qui a déjà été vue. Par défaut, le navigateur colore le lien en un violet assez laid (de mon point de vue du moins !).

Vous pouvez changer cette apparence avec :visited (qui signifie « visité »). En pratique, sur les liens consultés, on ne peut pas changer beaucoup de choses à part la couleur (figure suivante).

a:visited /* Quand le visiteur a déjà vu la page concernée */
{
    color: #AAA; /* Appliquer une couleur grise */
}
Liens visités en gris
Liens visités en gris

Si vous ne souhaitez pas que les liens déjà visités soient colorés d'une façon différente, il vous faudra leur appliquer la même couleur qu'aux liens normaux. De nombreux sites web font cela (le Site du Zéro y compris !). Une exception notable : Google… ce qui est plutôt pratique, puisque l'on peut voir dans les résultats d'une recherche si on a déjà consulté ou non les sites que Google nous présente.

En résumé

  • En CSS, on peut modifier l'apparence de certaines sections dynamiquement, après le chargement de la page, lorsque certains évènements se produisent. On utilise pour cela les pseudo-formats.

  • Le pseudo-format :hover permet de changer l'apparence au survol (par exemple : a:hover pour modifier l'apparence des liens lorsque la souris pointe dessus).

  • Le pseudo-format :active modifie l'apparence des liens au moment du clic, :visited lorsqu'un lien a déjà été visité.

  • Le pseudo-format :focus permet de modifier l'apparence d'un élément sélectionné.


Tutoriel VBScript

Structurer sa page

https://vimeo.com/76136486

Nous approchons de plus en plus du but. Si nos pages web ne ressemblent pas encore tout à fait aux sites web que nous connaissons, c'est qu'il nous manque les connaissances nécessaires pour faire la mise en page.

En général, une page web est constituée d'un en-tête (tout en haut), de menus de navigation (en haut ou sur les côtés), de différentes sections au centre… et d'un pied de page (tout en bas).

Dans ce chapitre, nous allons nous intéresser aux nouvelles balises HTML dédiées à la structuration du site. Ces balises ont été introduites par HTML5 (elles n'existaient pas avant) et vont nous permettre de dire : « Ceci est mon en-tête », « Ceci est mon menu de navigation », etc.

Pour le moment, nous n'allons pas encore faire de mise en page. Nous allons en fait préparer notre document HTML pour pouvoir découvrir la mise en page dans les prochains chapitres.

Les balises structurantes de HTML5

Je vais vous présenter ici les nouvelles balises introduites par HTML5 pour structurer nos pages. Vous allez voir, cela ne va pas beaucoup changer l'apparence de notre site pour le moment, mais il sera bien construit et prêt à être mis en forme ensuite !

<header> : l'en-tête

La plupart des sites web possèdent en général un en-tête, appelé header en anglais. On y trouve le plus souvent un logo, une bannière, le slogan de votre site…

Vous devrez placer ces informations à l'intérieur de la balise <header> :

<header>
    <!-- Placez ici le contenu de l'en-tête de votre page -->
</header>

La figure suivante, par exemple, représente une partie du Site du Zéro et vous pouvez voir son en-tête.

L'en-tête du Site du Zéro
L'en-tête du Site du Zéro

L'en-tête peut contenir tout ce que vous voulez : images, liens, textes…

Il peut y avoir plusieurs en-têtes dans votre page. Si celle-ci est découpée en plusieurs sections, chaque section peut en effet avoir son propre <header>.

<footer> : le pied de page

À l'inverse de l'en-tête, le pied de page se trouve en général tout en bas du document. On y trouve des informations comme des liens de contact, le nom de l'auteur, les mentions légales, etc.

<footer>
    <!-- Placez ici le contenu du pied de page -->
</footer>

La figure suivante vous montre à quoi ressemble le pied de page du Site du Zéro.

Pied de page du Site du Zéro
Pied de page du Site du Zéro

<nav> : principaux liens de navigation

La balise <nav> doit regrouper tous les principaux liens de navigation du site. Vous y placerez par exemple le menu principal de votre site.

Généralement, le menu est réalisé sous forme de liste à puces à l'intérieur de la balise <nav> :

<nav>
    <ul>
        <li><a href="index.html">Accueil</a></li>
        <li><a href="forum.html">Forum</a></li>
        <li><a href="contact.html">Contact</a></li>
    </ul>
</nav>

En figure suivante, vous pouvez observer le menu principal de navigation du Site du Zéro, qui pourrait utiliser la balise <nav>.

Le menu de navigation du Site du Zéro
Le menu de navigation du Site du Zéro

<section> : une section de page

La balise <section> sert à regrouper des contenus en fonction de leur thématique. Elle englobe généralement une portion du contenu au centre de la page.

<section>
    <h1>Ma section de page</h1>
    <p>Bla bla bla bla</p>
</section>

Sur la page d'accueil du portail Free.fr, on trouve plusieurs blocs qui pourraient être considérés comme des sections de page (figure suivante).

Des sections de page sur le portail de Free
Des sections de page sur le portail de Free

Chaque section peut avoir son titre de niveau 1 (<h1>), de même que l'en-tête peut contenir un titre <h1> lui aussi. Chacun de ces blocs étant indépendant des autres, il n'est pas illogique de retrouver plusieurs titres <h1> dans le code de la page web. On a ainsi « Le titre <h1> du <header> », « Le titre <h1> de cette <section> », etc.

<aside> : informations complémentaires

La balise <aside> est conçue pour contenir des informations complémentaires au document que l'on visualise. Ces informations sont généralement placées sur le côté (bien que ce ne soit pas une obligation).

<aside>
    <!-- Placez ici des informations complémentaires -->
</aside>

Il peut y avoir plusieurs blocs <aside> dans la page.

Sur Wikipédia, par exemple, il est courant de voir à droite un bloc d'informations complémentaires à l'article que l'on visualise. Ainsi, sur la page présentant la planète Saturne (figure suivante), on trouve dans ce bloc les caractéristiques de la planète (dimensions, masse, etc.).

Bloc d'informations complémentaires sur Wikipédia
Bloc d'informations complémentaires sur Wikipédia

<article> : un article indépendant

La balise <article> sert à englober une portion généralement autonome de la page. C'est une partie de la page qui pourrait ainsi être reprise sur un autre site. C'est le cas par exemple des actualités (articles de journaux ou de blogs).

<article>
    <h1>Mon article</h1>
    <p>Bla bla bla bla</p>
</article>

Par exemple, voici un article sur le Site du Zéro en figure suivante.

Un article publié sur le Site du Zéro
Un article publié sur le Site du Zéro

Résumé

Ouf, cela fait beaucoup de nouvelles balises à retenir.
Heureusement, je vous ai fait un petit schéma (figure suivante) pour vous aider à retenir leur rôle !

Sections de la page identifiées par les balises
Sections de la page identifiées par les balises

Ne vous y trompez pas : ce schéma propose un exemple d'organisation de la page. Rien ne vous empêche de décider que votre menu de navigation soit à droite, ou tout en haut, que vos balises <aside> soient au-dessus, etc.
On peut même imaginer une seconde balise <header>, placée cette fois à l'intérieur d'une <section>. Dans ce cas-là, elle sera considérée comme étant l'en-tête de la section.
Enfin, une section ne doit pas forcément contenir un <article> et des <aside>. Utilisez ces balises uniquement si vous en avez besoin. Rien ne vous interdit de créer des sections contenant seulement des paragraphes, par exemple.

Exemple concret d'utilisation des balises

Essayons d'utiliser les balises que nous venons de découvrir pour structurer notre page web. Le code ci-dessous reprend toutes les balises que nous venons de voir au sein d'une page web complète :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Zozor - Le Site Web</title>
    </head>

    <body>
        <header>
            <h1>Zozor</h1>
            <h2>Carnets de voyage</h2>
        </header>

        <nav>
            <ul>
                <li><a href="#">Accueil</a></li>
                <li><a href="#">Blog</a></li>
                <li><a href="#">CV</a></li>
            </ul>
        </nav>

        <section>
            <aside>
                <h1>À propos de l'auteur</h1>
                <p>C'est moi, Zozor ! Je suis né un 23 novembre 2005.</p>
            </aside>
            <article>
                <h1>Je suis un grand voyageur</h1>
                <p>Bla bla bla bla (texte de l'article)</p>
            </article>
        </section>

        <footer>
            <p>Copyright Zozor - Tous droits réservés<br />
            <a href="#">Me contacter !</a></p>
        </footer>

    </body>
</html>

Ce code peut vous aider à comprendre comment les balises doivent être agencées. Vous y reconnaissez un en-tête, un menu de navigation, un pied de page… et, au centre, une section avec un article et un bloc <aside> donnant des informations sur l'auteur de l'article.

À quoi ressemble la page que nous venons de créer ?

À rien !
Si vous testez le résultat, vous verrez juste du texte noir sur fond blanc (figure suivante). C'est normal, il n'y a pas de CSS ! Par contre, la page est bien structurée, ce qui va nous être utile pour la suite.

Une page bien structurée mais sans CSS
Une page bien structurée mais sans CSS

Les liens sont volontairement factices (d'où la présence d'un simple #), ils n'amènent donc nulle part (eh, c'est juste une page de démo) !

Je ne comprends pas l'intérêt de ces balises. On peut très bien obtenir le même résultat sans les utiliser !

C'est vrai. En fait, ces balises sont seulement là pour expliquer à l'ordinateur « Ceci est l'en-tête », « Ceci est mon pied de page », etc. Elles n'indiquent pas, contrairement à ce qu'on pourrait penser, où doit être placé le contenu. C'est le rôle du CSS, comme nous le verrons dans peu de temps maintenant.

À l'heure actuelle, pour tout vous dire, ces balises ont encore assez peu d'utilité. On pourrait très bien utiliser des balises génériques <div> à la place pour englober les différentes portions de notre contenu. D'ailleurs, c'est comme cela qu'on faisait avant l'arrivée de ces nouvelles balises HTML5.

Néanmoins, il est assez probable que, dans un futur proche, les ordinateurs commencent à tirer parti intelligemment de ces nouvelles balises. On peut imaginer par exemple un navigateur qui choisisse d'afficher les liens de navigation <nav> de manière toujours visible ! Quand l'ordinateur « comprend » la structure de la page, tout devient possible.

Assurer la compatibilité avec IE

Les nouvelles balises que nous venons de voir ne sont reconnues par Internet Explorer que depuis sa version 9 (IE9). Cela va poser un problème car, quand les anciennes versions d'IE ne connaissent pas une balise… elles ne traitent pas correctement la page (impossible de modifier leur CSS par exemple) !

Cela peut heureusement se régler assez facilement à l'aide d'un script JavaScript. Les scripts sont des petits morceaux de code qui permettent de manipuler la page web et d'effectuer certaines actions. Nous n'allons pas nous intéresser ici au JavaScript (ce n'est pas le sujet de ce cours) mais il faut savoir que ce type de script est appelé depuis les pages HTML d'une façon assez similaire à l'appel des fichiers CSS.

Les fichiers JavaScript portent généralement l'extension .js. Dans le code HTML, on les place en général dans la balise <head> avec cette balise :

<script src="monscript.js"></script>

Si je vous présente (brièvement) JavaScript ici, c'est parce qu'un petit script répondant au doux nom de HTML5shiv permet de faire en sorte que les balises que nous venons de voir (<header>, <footer>, <section>…) s'affichent correctement sur les anciennes versions d'Internet Explorer (IE6, IE7, IE8). Concrètement, il vous suffit d'ajouter les lignes suivantes dans votre code :

<!--[if lt IE 9]>
    <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

Placez ce code dans la balise <head> comme ceci :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <!--[if lt IE 9]>
            <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
        <![endif]-->
        <title>Inclusion de HTML5shiv</title>
    </head>

    <body>

    </body>
</html>

Et voilà, votre site s'affichera désormais sans problème dans Internet Explorer !

Sans rentrer dans le détail, sachez que <!--[if lt IE 9]> est un commentaire conditionnel. C'est un commentaire spécial qui n'est lu que par Internet Explorer. Il permet de faire en sorte que le script s'exécute uniquement sur les versions d'Internet Explorer inférieures à IE9 (les autres navigateurs n'en ont pas besoin et ignoreront le commentaire).

En résumé

  • Plusieurs balises ont été introduites avec HTML5 pour délimiter les différentes zones qui constituent la page web :

    • <header> : en-tête ;

    • <footer> : pied de page ;

    • <nav> : liens principaux de navigation ;

    • <section> : section de page ;

    • <aside> : informations complémentaires ;

    • <article> : article indépendant.

  • Ces balises peuvent être imbriquées les unes dans les autres. Ainsi, une section peut avoir son propre en-tête.

  • Ces balises ne s'occupent pas de la mise en page. Elles servent seulement à indiquer à l'ordinateur le sens du texte qu'elles contiennent. On pourrait très bien placer l'en-tête en bas de la page si on le souhaite.

  • Le code JavaScript HTML5shiv permet de faire en sorte que ces balises soient reconnues pour les versions d'Internet Explorer antérieures à IE9.


Tutoriel VBScript

Le modèle des boîtes

https://vimeo.com/76136489

Une page web peut être vue comme une succession et un empilement de boîtes, qu'on appelle « blocs ». La plupart des éléments vus au chapitre précédent sont des blocs : <header> , <article> , <nav> … Mais nous connaissions déjà d'autres blocs : les paragraphes <p> , les titres <h1> …

Dans ce chapitre, nous allons apprendre à manipuler ces blocs comme de véritables boîtes. Nous allons leur donner des dimensions, les agencer en jouant sur leurs marges, mais aussi apprendre à gérer leur contenu… pour éviter que le texte ne dépasse de ces blocs !

Ce sont des notions fondamentales dont nous allons avoir besoin pour mettre en page notre site web… Soyez attentifs !

Les balises de type block et inline

En HTML, la plupart des balises peuvent se ranger dans l'une ou l'autre de deux catégories :

  • Les balises inline : c'est le cas par exemple des liens <a></a> .

  • Les balises block : c'est le cas par exemple des paragraphes <p></p> .

Il existe en fait plusieurs autres catégories très spécifiques, par exemple pour les cellules de tableau (type table-cell ) ou les puces (type list-item ). Nous n'allons pas nous y intéresser pour le moment car ces balises sont minoritaires.

Mais comment je reconnais une balise inline d'une balise block ?

C'est en fait assez facile :

  • block: une balise de type block sur votre page web crée automatiquement un retour à la ligne avant et après. Il suffit d'imaginer tout simplement un bloc. Votre page web sera en fait constituée d'une série de blocs les uns à la suite des autres. Mais vous verrez qu'en plus, il est possible de mettre un bloc à l'intérieur d'un autre, ce qui va augmenter considérablement nos possibilités pour créer le design de notre site !

  • inline: une balise de type inline se trouve obligatoirement à l'intérieur d'une balise block. Une balise inline ne crée pas de retour à la ligne, le texte qui se trouve à l'intérieur s'écrit donc à la suite du texte précédent, sur la même ligne (c'est pour cela que l'on parle de balise « en ligne »).

Pour bien visualiser le concept, voici en figure suivante un petit schéma que je vous ai concocté.

Différence entre une balise inline et une balise block Différence entre une balise inline et une balise block

  • Sur fond bleu, vous avez tout ce qui est de type block.

  • Sur fond jaune, vous avez tout ce qui est de type inline.

Comme vous pouvez le voir, les blocs sont les uns en-dessous des autres. On peut aussi les imbriquer les uns à l'intérieur des autres (souvenez-vous, nos blocs <section> contiennent par exemple des blocs <aside> !).
La balise inline <a></a> , elle, se trouve à l'intérieur d'une balise block et le texte vient s'insérer sur la même ligne.

Quelques exemples

Afin de mieux vous aider à assimiler quelles balises sont inline et quelles balises sont block, voici un petit tableau dressant la liste de quelques balises courantes.

Balises block | Balises inline
<p> | <em>
<footer> | <strong>
<h1> | <mark>
<h2> | <a>
<article> | <img />
… | …

Ce tableau n'est pas complet, loin de là. Si vous voulez avoir la liste complète des balises qui existent et savoir si elles sont de type inline ou block, reportez-vous à l' annexe donnant la liste des balises HTML.

Les balises universelles

Vous les connaissez déjà car je vous les ai présentées il y a quelques chapitres. Ce sont des balises qui n'ont aucun sens particulier (contrairement à <p> qui veut dire « paragraphe », <strong> « important », etc.).
Le principal intérêt de ces balises est que l'on peut leur appliquer une class (ou un id ) pour le CSS quand aucune autre balise ne convient.

Il existe deux balises génériques et, comme par hasard, la seule différence entre les deux est que l'une d'elle est inline et l'autre est block :

  • <span></span> (inline) ;

  • <div></div> (block).

Respectez la sémantique !

Les balises universelles sont « pratiques » dans certains cas, certes, mais attention à ne pas en abuser. Je tiens à vous avertir de suite : beaucoup de webmasters mettent des <div> et des <span> trop souvent et oublient que d'autres balises plus adaptées existent.

Voici deux exemples :

  • Exemple d'un span inutile : <span class="important"> . Je ne devrais jamais voir ceci dans un de vos codes alors qu'il existe la balise <strong> qui sert à indiquer l'importance !

  • Exemple d'un div inutile : <div class="titre"> . Ceci est complètement absurde puisqu'il existe des balises faites spécialement pour les titres ( <h1> , <h2> …).

Oui, vous allez me dire qu'au final le résultat (visuel) est le même. Je suis tout à fait d'accord. Mais les balises génériques n'apportent aucun sens à la page et ne peuvent pas être comprises par l'ordinateur. Utilisez toujours d'autres balises plus adaptées quand c'est possible. Google lui-même le conseille pour vous aider à améliorer la position de vos pages au sein de ses résultats de recherche !

Les dimensions

Nous allons ici travailler uniquement sur des balises de type block.

Pour commencer, intéressons-nous à la taille des blocs. Contrairement à un inline, un bloc a des dimensions précises. Il possède une largeur et une hauteur. Ce qui fait, ô surprise, qu'on dispose de deux propriétés CSS :

  • width : c'est la largeur du bloc. À exprimer en pixels (px) ou en pourcentage (%).

  • height : c'est la hauteur du bloc. Là encore, on l'exprime soit en pixels (px), soit en pourcentage (%).

Pour être exact, width et height représentent la largeur et la hauteur du contenu des blocs. Si le bloc a des marges (on va découvrir ce principe un peu plus loin), celles-ci s'ajouteront à la largeur et la hauteur.

Par défaut, un bloc prend 100% de la largeur disponible. On peut le vérifier en appliquant à nos blocs des bordures ou une couleur de fond (figure suivante).

Les blocs prennent toute la largeur disponible Les blocs prennent toute la largeur disponible

Maintenant, rajoutons un peu de CSS afin de modifier la largeur des paragraphes. Le CSS suivant dit : « Je veux que tous mes paragraphes aient une largeur de 50% ».

p
{
    width: 50%;
}

Le résultat est visible à la figure suivante.

Un paragraphe de 50% de largeur Un paragraphe de 50% de largeur

Les pourcentages seront utiles pour créer un design qui s'adapte automatiquement à la résolution d'écran du visiteur.
Toutefois, il se peut que vous ayez besoin de créer des blocs ayant une dimension précise en pixels :

p
{
   width: 250px;
}

Minimum et maximum

On peut demander à ce qu'un bloc ait des dimensions minimales et maximales. C'est très pratique car cela nous permet de définir des dimensions « limites » pour que notre site s'adapte aux différentes résolutions d'écran de nos visiteurs :

  • min-width : largeur minimale ;

  • min-height : hauteur minimale ;

  • max-width : largeur maximale ;

  • max-height : hauteur maximale.

Par exemple, on peut demander à ce que les paragraphes occupent 50% de la largeur et exiger qu'il fassent au moins 400 pixels de large dans tous les cas :

p
{
    width: 50%;
    min-width: 400px;
}

Observez le résultat en modifiant la largeur de la fenêtre de votre navigateur. Vous allez voir que, si celle-ci est trop petite, le paragraphe se force à occuper au moins 400 pixels de largeur.

Les marges

Il faut savoir que tous les blocs possèdent des marges. Il existe deux types de marges :

  • les marges intérieures ;

  • les marges extérieures.

Regardez bien le schéma qui se trouve à la figure suivante.

Marges extérieure et intérieure Marges extérieure et intérieure

Sur ce bloc, j'ai mis une bordure pour qu'on repère mieux ses frontières.

  • L'espace entre le texte et la bordure est la marge intérieure (en vert).

  • L'espace entre la bordure et le bloc suivant est la marge extérieure (en rouge).

En CSS, on peut modifier la taille des marges avec les deux propriétés suivantes :

  • padding : indique la taille de la marge intérieure. À exprimer en général en pixels (px).

  • margin : indique la taille de la marge extérieure. Là encore, on utilise le plus souvent des pixels.

Les balises de type inline possèdent également des marges. Vous pouvez donc aussi essayer ces manipulations sur ce type de balises.

Pour bien voir les marges, prenons deux paragraphes auxquels j'applique simplement une petite bordure (figure suivante) :

p
{
    width: 350px;
    border: 1px solid black;
    text-align: justify;
}
Marges par défaut sur les paragraphes Marges par défaut sur les paragraphes

Comme vous pouvez le constater, il n'y a par défaut pas de marge intérieure ( padding ). En revanche, il y a une marge extérieure ( margin ). C'est cette marge qui fait que deux paragraphes ne sont pas collés et qu'on a l'impression de « sauter une ligne ».

Les marges par défaut ne sont pas les mêmes pour toutes les balises de type block. Essayez d'appliquer ce CSS à des balises <div> qui contiennent du texte, par exemple : vous verrez que, dans ce cas, il n'y a par défaut ni marge intérieure, ni marge extérieure !

Supposons que je veuille rajouter une marge intérieure de 12 px aux paragraphes (figure suivante) :

p
{
    width: 350px;
    border: 1px solid black;
    text-align: justify;
    padding: 12px; /* Marge intérieure de 12px */
}
Une marge intérieure ajoutée aux paragraphes Une marge intérieure ajoutée aux paragraphes

Maintenant, je veux que mes paragraphes soient plus espacés entre eux. Je rajoute la propriété margin pour demander à ce qu'il y ait 50 px de marge entre deux paragraphes (figure suivante) :

p
{
   width: 350px;
   border: 1px solid black;
   text-align: justify;
   padding: 12px;
   margin: 50px; /* Marge extérieure de 50px */
}

Une marge extérieure ajoutée aux paragraphes Une marge extérieure ajoutée aux paragraphes

Mais ??? Une marge s'est rajoutée à gauche aussi !

Eh oui, margin (comme padding d'ailleurs) s'applique aux quatre côtés du bloc.
Si vous voulez spécifier des marges différentes en haut, en bas, à gauche et à droite, il va falloir utiliser des propriétés plus précises… Le principe est le même que pour la propriété border , vous allez voir !

En haut, à droite, à gauche, en bas… Et on recommence !

L'idéal serait que vous reteniez les termes suivants en anglais :

  • top : haut ;

  • bottom : bas ;

  • left : gauche ;

  • right : droite.

Ainsi, vous pouvez retrouver toutes les propriétés de tête.
Je vais quand même vous faire la liste des propriétés pour margin et padding , histoire que vous soyez sûrs que vous avez compris le principe.

Voici la liste pour margin :

  • margin-top : marge extérieure en haut ;

  • margin-bottom : marge extérieure en bas ;

  • margin-left : marge extérieure à gauche ;

  • margin-right : marge extérieure à droite.

Et la liste pour padding :

  • padding-top : marge intérieure en haut ;

  • padding-bottom : marge intérieure en bas ;

  • padding-left : marge intérieure à gauche ;

  • padding-right : marge intérieure à droite.

Il y a d'autres façons de spécifier les marges avec les propriétés margin et padding . Par exemple :
margin: 2px 0 3px 1px; signifie « 2 px de marge en haut, 0 px à droite (le px est facultatif dans ce cas), 3 px en bas, 1 px à gauche ».
Autre notation raccourcie : margin: 2px 1px; signifie « 2 px de marge en haut et en bas, 1 px de marge à gauche et à droite ».

Centrer des blocs

Il est tout à fait possible de centrer des blocs. C'est même très pratique pour réaliser un design centré quand on ne connaît pas la résolution du visiteur.

Pour centrer, il faut respecter les règles suivantes :

  • donnez une largeur au bloc (avec la propriété width ) ;

  • indiquez que vous voulez des marges extérieures automatiques, comme ceci : margin: auto; .

Essayons cette technique sur nos petits paragraphes (lignes 3 et 4) :

p
{
    width: 350px; /* On a indiqué une largeur (obligatoire) */
    margin: auto; /* On peut donc demander à ce que le bloc soit centré avec auto */
    border: 1px solid black;
    text-align: justify;
    padding: 12px;
    margin-bottom: 20px;
}

Et voici le résultat à la figure suivante.

Centrage des paragraphes Centrage des paragraphes

Ainsi, le navigateur centre automatiquement nos paragraphes !

Il n'est cependant pas possible de centrer verticalement un bloc avec cette technique. Seul le centrage horizontal est permis.

Quand ça dépasse…

Lorsqu'on commence à définir des dimensions précises pour nos blocs, comme on vient de le faire, il arrive qu'ils deviennent trop petits pour le texte qu'ils contiennent.

Les propriétés CSS que nous allons voir ici ont justement été créées pour contrôler les dépassements… et décider quoi faire si jamais cela devait arriver.

overflow : couper un bloc

Supposons que vous ayez un long paragraphe et que vous vouliez (pour une raison qui ne regarde que vous) qu'il fasse 250 px de large et 110 px de haut. Ajoutons-lui une bordure et remplissons-le de texte… à ras-bord (figure suivante) :

p
{
    width: 250px;
    height: 110px;
    text-align: justify;
    border: 1px solid black;
}
Le texte dépasse du bloc de paragraphe
Le texte dépasse du bloc de paragraphe

Horreur ! Le texte dépasse des limites du paragraphe !

Eh oui ! Vous avez demandé des dimensions précises, vous les avez eues ! Mais… le texte ne tient pas à l'intérieur d'un si petit bloc.

Si vous voulez que le texte ne dépasse pas des limites du paragraphe, il va falloir utiliser la propriété overflow . Voici les valeurs qu'elle peut accepter :

  • visible (par défaut) : si le texte dépasse les limites de taille, il reste visible et sort volontairement du bloc.

  • hidden : si le texte dépasse les limites, il sera tout simplement coupé. On ne pourra pas voir tout le texte.

  • scroll : là encore, le texte sera coupé s'il dépasse les limites. Sauf que cette fois, le navigateur mettra en place des barres de défilement pour qu'on puisse lire l'ensemble du texte. C'est un peu comme un cadre à l'intérieur de la page.

  • auto : c'est le mode « pilote automatique ». En gros, c'est le navigateur qui décide de mettre ou non des barres de défilement (il n'en mettra que si c'est nécessaire). C'est la valeur que je conseille d'utiliser le plus souvent.

Avec overflow: hidden; le texte est donc coupé (on ne peut pas voir la suite), comme sur la figure suivante.

Le texte est coupé aux limites du paragraphe
Le texte est coupé aux limites du paragraphe

Essayons maintenant overflow: auto; avec le code CSS suivant (résultat à la figure suivante) :

p
{
    width: 250px;
    height: 110px;
    text-align: justify;
    border: 1px solid black;
    overflow: auto;
}

Des barres de défilement sont ajoutées au paragraphe Des barres de défilement sont ajoutées au paragraphe

Eurêka ! Des barres de défilement nous permettent maintenant de consulter le contenu qui n'était pas visible.

Il existe une ancienne balise HTML, <iframe> , qui donne à peu près le même résultat. Cependant, l'usage de cette balise est déconseillé aujourd'hui. Elle permet de charger tout le contenu d'une autre page HTML au sein de votre page.

word-wrap : couper les textes trop larges

Si vous devez placer un mot très long dans un bloc, qui ne tient pas dans la largeur, vous allez adorer word-wrap . Cette propriété permet de forcer la césure des très longs mots (généralement des adresses un peu longues).

La figure suivante représente ce que l'on peut avoir quand on écrit une URL un peu longue dans un bloc.

Le texte déborde en largeur
Le texte déborde en largeur

L'ordinateur ne sait pas « couper » l'adresse car il n'y a ni espace, ni tiret. Il ne sait pas faire la césure.

Avec le code suivant, la césure sera forcée dès que le texte risque de dépasser (figure suivante).

p
{
    word-wrap: break-word;
}
Le texte est coupé pour ne pas déborder
Le texte est coupé pour ne pas déborder

Je conseille d'utiliser cette fonctionnalité dès qu'un bloc est susceptible de contenir du texte saisi par des utilisateurs (par exemple sur les forums de votre futur site). Sans cette astuce, on peut « casser » facilement le design d'un site (en écrivant par exemple une longue suite de « aaaaaaaaaaa »).

En résumé

  • On distingue deux principaux types de balises en HTML :

    • Le type block ( <p> , <h1> …) : ces balises créent un retour à la ligne et occupent par défaut toute la largeur disponible. Elles se suivent de haut en bas.

    • Le type inline ( <a> , <strong> …) : ces balises délimitent du texte au milieu d'une ligne. Elles se suivent de gauche à droite.

  • On peut modifier la taille d'une balise de type block avec les propriétés CSS width (largeur) et height (hauteur).

  • On peut définir des minima et maxima autorisés pour la largeur et la hauteur : min-width , max-width , min-height , max-height .

  • Les éléments de la page disposent chacun de marges intérieures ( padding ) et extérieures ( margin ).

  • S'il y a trop de texte à l'intérieur d'un bloc de dimensions fixes, il y a un risque de débordement. Dans ce cas, il peut être judicieux de rajouter des barres de défilement avec la propriété overflow ou de forcer la césure avec word-wrap .


Tutoriel VBScript

Le positionnement en CSS

https://vimeo.com/76136497

Voici venu le moment tant attendu : nous allons apprendre à modifier la position des éléments sur notre page. La théorie que nous allons voir ici nous sera indispensable au prochain chapitre, dans lequel nous réaliserons ensemble, pas à pas, le design de notre premier site !

Vous allez voir, il existe plusieurs techniques permettant d'effectuer la mise en page de son site. Chacune a ses avantages et ses défauts, ce sera à vous de sélectionner celle qui vous semble la meilleure selon votre cas.

Le positionnement flottant

La technique présentée ici l'est à titre d'information. Elle est utilisée par la majorité des sites à l'heure actuelle mais comporte un certain nombre de défauts. Une meilleure technique, le positionnement inline-block, sera présentée un peu plus loin : je vous encourage à l'utiliser autant que possible.

Vous vous souvenez de la propriété float ? Nous l'avons utilisée pour faire flotter une image autour du texte (figure suivante).

L'image flotte autour du texte grâce à la propriété float
L'image flotte autour du texte grâce à la propriété float

Il se trouve que cette propriété est aujourd'hui utilisée par la majorité des sites web pour… faire la mise en page ! En effet, si on veut placer son menu à gauche et le contenu de sa page à droite, c'est a priori un bon moyen. Je dis bien a priori car, à la base, cette propriété n'a pas été conçue pour faire la mise en page et nous allons voir qu'elle a quelques petits défauts.

Reprenons le code HTML structuré que nous avons réalisé il y a quelques chapitres :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" href="style.css" />
        <title>Zozor - Le Site Web</title>
    </head>

    <body>
        <header>
            <h1>Zozor</h1>
            <h2>Carnets de voyage</h2>
        </header>

        <nav>
            <ul>
                <li><a href="#">Accueil</a></li>
                <li><a href="#">Blog</a></li>
                <li><a href="#">CV</a></li>
            </ul>
        </nav>

        <section>
            <aside>
                <h1>À propos de l'auteur</h1>
                <p>C'est moi, Zozor ! Je suis né un 23 novembre 2005.</p>
            </aside>
            <article>
                <h1>Je suis un grand voyageur</h1>
                <p>Bla bla bla bla (texte de l'article)</p>
            </article>
        </section>

        <footer>
            <p>Copyright Zozor - Tous droits réservés

            <a href="#">Me contacter !</a></p>
        </footer>

    </body>
</html>

Je rappelle que, sans CSS, la mise en page ressemble à la figure suivante.

Une page HTML sans CSS
Une page HTML sans CSS

Nous allons essayer de placer le menu à gauche et le reste du texte à droite. Pour cela, nous allons faire flotter le menu à gauche et laisser le reste du texte se placer à sa droite.

Nous voulons que le menu occupe 150 pixels de large. Nous allons aussi rajouter une bordure noire autour du menu et une bordure bleue autour du corps (à la balise <section>) pour bien les distinguer :

nav
{
    float: left;
    width: 150px;
    border: 1px solid black;
}

section
{
    border: 1px solid blue;
}

Voici le résultat à la figure suivante. Ce n'est pas encore tout à fait cela.

Le menu est bien positionné mais collé au texte
Le menu est bien positionné mais collé au texte

Il y a deux défauts (mis à part le fait que c'est encore bien moche) :

  • Le texte du corps de la page touche la bordure du menu. Il manque une petite marge…

  • Plus embêtant encore : la suite du texte passe… sous le menu !

On veut bien que le pied de page (« Copyright Zozor ») soit placé en bas sous le menu mais, par contre, on aimerait que tout le corps de page soit constitué d'un seul bloc placé à droite.

Pour résoudre ces deux problèmes d'un seul coup, il faut ajouter une marge extérieure à gauche de notre <section>, marge qui doit être par ailleurs supérieure à la largeur du menu. Si notre menu fait 150 px, nous allons par exemple donner une marge extérieure gauche de 170 px à notre section de page (figure suivante), ici à la ligne 10.

nav
{
    float: left;
    width: 150px;
    border: 1px solid black;
}

section
{
    margin-left: 170px;
    border: 1px solid blue;
}
Le corps de page est bien aligné à droite du menu
Le corps de page est bien aligné à droite du menu

Voilà, le contenu de la page est maintenant correctement aligné.

À l'inverse, vous pouvez aussi préférer qu'un élément se place obligatoirement sous le menu. Dans ce cas, il faudra utiliser… clear: both;, que nous avions déjà découvert, qui oblige la suite du texte à se positionner sous l'élément flottant.

Transformez vos éléments avec display

Je vais vous apprendre ici à modifier les lois du CSS (brrr…). Accrochez-vous !

Il existe en CSS une propriété très puissante : display. Elle est capable de transformer n'importe quel élément de votre page d'un type vers un autre. Avec cette propriété magique, je peux par exemple imposer à mes liens (originellement de type inline) d'apparaître sous forme de blocs :

a
{
    display: block;
}

À ce moment-là, les liens vont se positionner les uns en-dessous des autres (comme des blocs normaux) et il devient possible de modifier leurs dimensions !

Voici quelques-unes des principales valeurs que peut prendre la propriété display en CSS (il y en a encore d'autres) :

Valeur | Exemples | Description
inline | <a>, <em>, <span>… | Eléments d'une ligne. Se placent les uns à côté des autres.
block | <p>, <div>, <section>… | Eléments en forme de blocs. Se placent les uns en-dessous des autres et peuvent être redimensionnés.
inline-block | <select>, <input> | Eléments positionnés les uns à côté des autres (comme les inlines) mais qui peuvent être redimensionnés (comme les blocs).
none | <head> | Eléments non affichés.

On peut donc décider de masquer complètement un élément de la page avec cette propriété. Par exemple, si je veux masquer les éléments qui ont la classe « secret », je vais écrire :

.secret
{
    display: none;
}

Pour faire apparaître ces éléments par la suite, vous devrez faire appel à JavaScript. Certains sites web utilisent cette technique pour, par défaut, masquer les sous-menus qui ne s'affichent que lorsqu'on parcourt les menus.

Et quel est ce nouveau type bizarre, inline-block ? C'est un mélange ?

Oui, ce type d'élément est en fait une combinaison des inlines et des blocs. C'est un peu le meilleur des deux mondes : les éléments s'affichent côte à côte et peuvent être redimensionnés.

Peu de balises sont affichées comme cela par défaut, c'est surtout le cas des éléments de formulaire (comme <input>) que nous découvrirons un peu plus tard. Par contre, avec la propriété display, nous allons pouvoir transformer d'autres balises en inline-block, ce qui va nous aider à réaliser notre design.

Le positionnement inline-block

Les manipulations que demande le positionnement flottant se révèlent parfois un peu délicates sur des sites complexes. Dès qu'il y a un peu plus qu'un simple menu à mettre en page, on risque d'avoir à recourir à des clear: both; qui complexifient rapidement le code de la page.

Si le positionnement flottant reste, de loin, le mode de positionnement le plus utilisé sur le Web à l'heure actuelle, d'autres techniques existent et bien peu de webmasters le savent. L'une d'elles, étonnamment puissante, est passée sous le nez des concepteurs de sites web alors qu'elle existe depuis CSS 2.1, c'est-à-dire depuis plus de dix ans ! Elle consiste à transformer vos éléments en inline-block avec la propriété display.

Quelques petits rappels sur les éléments de type inline-block :

  • Ils se positionnent les uns à côté des autres (exactement ce qu'on veut pour placer notre menu et le corps de notre page !).

  • On peut leur donner des dimensions précises (là encore, exactement ce qu'on veut !).

Nous allons transformer en inline-block les deux éléments que nous voulons placer côte à côte : le menu de navigation et la section du centre de la page.

nav
{
    display: inline-block;
    width: 150px;
    border: 1px solid black;
}

section
{
    display: inline-block;
    border: 1px solid blue;
}

Ce qui nous donne comme résultat la figure suivante.

Le menu et le corps sont côte à côte… mais positionnés en bas !
Le menu et le corps sont côte à côte… mais positionnés en bas !

Argh !
Ce n'est pas tout à fait ce qu'on voulait. Et en fait, c'est normal : les éléments inline-block se positionnent sur une même ligne de base (appelée baseline), en bas.

Heureusement, le fait d'avoir transformé les éléments en inline-block nous permet d'utiliser une nouvelle propriété, normalement réservée aux tableaux : vertical-align. Cette propriété permet de modifier l'alignement vertical des éléments. Voici quelques-unes des valeurs possibles pour cette propriété :

  • baseline : aligne de la base de l'élément avec celle de l'élément parent (par défaut) ;

  • top : aligne en haut ;

  • middle : centre verticalement ;

  • bottom : aligne en bas ;

  • (valeur en px ou %) : aligne à une certaine distance de la ligne de base (baseline).

Il ne nous reste plus qu'à aligner nos éléments en haut (lignes 6 et 13), et le tour est joué (figure suivante) !

nav
{
    display: inline-block;
    width: 150px;
    border: 1px solid black;
    vertical-align: top;
}

section
{
    display: inline-block;
    border: 1px solid blue;
    vertical-align: top;
}
Le menu et le corps sont alignés en haut et côte à côte
Le menu et le corps sont alignés en haut et côte à côte

Vous noterez que le corps (la <section>) ne prend pas toute la largeur. En effet, ce n'est plus un bloc ! La section occupe seulement la place dont elle a besoin.
Si cela ne vous convient pas pour votre design, modifiez la taille de la section avec width.

Et voilà ! Pas besoin de s'embêter avec les marges, aucun risque que le texte passe sous le menu… Bref, c'est parfait !

… Quoi ? Pardon, on me signale dans l'oreillette qu'un certain navigateur vient jouer les trouble-fête…

inline-block et compatibilité Internet Explorer

Le positionnement inline-block est parfaitement compris par Internet Explorer à partir de IE8.

Pour les anciennes versions, IE6 et IE7 en particulier, le positionnement inline-block fonctionne… mais uniquement sur les éléments qui étaient des inline à la base !

On peut heureusement régler ce problème avec une petite « bidouille » : si le navigateur est IE6 ou IE7, on transforme l'élément en inline et on change son comportement en lui donnant le layout (en lui affectant la propriété zoom: 1;). L'élément pourra alors être redimensionné.

Le layout est un mode d'affichage un peu particulier d'Internet Explorer, qui peut être la source de nombreux bugs. Comme cela devient rapidement très technique, je passe volontairement là-dessus et je vous invite, si le sujet vous intéresse, à consulter article sur HasLayout sur le site Alsacréations.

Pour commencer, il va falloir créer une seconde feuille de style CSS spéciale pour Internet Explorer 6 et 7. On va utiliser pour cela un commentaire conditionnel, que nous avions déjà aperçu auparavant, qui ne sera lu que par IE6 et IE7 :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" href="style.css" />
        <!--[if lte IE 7]>
        <link rel="stylesheet" href="style_ie.css" />
        <![endif]-->

        <title>Zozor - Le Site Web</title>
    </head>

Si le navigateur est IE6 ou IE7, une seconde feuille de style CSS, style_ie.css, sera chargée et viendra s'ajouter à la première. Dedans, nous ferons toutes nos « bidouilles » pour régler les problèmes liés aux vieilles versions d'Internet Explorer, afin que notre site s'affiche correctement chez tout le monde, même chez ceux qui vivent encore à la préhistoire ;-) .

Dans style_ie.css, rajoutez simplement le code suivant :

nav, section
{
    display: inline;
    zoom: 1;
}

Voilà, c'est tout ! Dans votre feuille de style classique (style.css), continuez à utiliser inline-block comme avant. Ceux qui ont IE6 ou IE7 liront en plus ce code un peu spécial, qui leur permet d'obtenir le même résultat visuel !

Les positionnements absolu, fixe et relatif

Il existe d'autres techniques un peu particulières permettant de positionner avec précision des éléments sur la page :

  • Le positionnement absolu : il nous permet de placer un élément n'importe où sur la page (en haut à gauche, en bas à droite, tout au centre, etc.).

  • Le positionnement fixe : identique au positionnement absolu mais, cette fois, l'élément reste toujours visible, même si on descend plus bas dans la page. C'est un peu le même principe que background-attachment: fixed; (si vous vous en souvenez encore).

  • Le positionnement relatif : permet de décaler l'élément par rapport à sa position normale.

Comme pour les flottants, les positionnements absolu, fixé et relatif fonctionnent aussi sur des balises de type inline.
Toutefois, vous verrez qu'on l'utilise bien plus souvent sur des balises block que sur des balises inline.

Il faut d'abord faire son choix entre les trois modes de positionnement disponibles. Pour cela, on utilise la propriété CSS position à laquelle on donne une de ces valeurs :

  • absolute : positionnement absolu ;

  • fixed : positionnement fixe ;

  • relative : positionnement relatif.

Nous allons étudier un à un chacun de ces positionnements.

Le positionnement absolu

Le positionnement absolu permet de placer un élément (réellement) n'importe où sur la page. Pour effectuer un positionnement absolu, on doit écrire :

element
{
    position: absolute;
}

Mais cela ne suffit pas ! On a dit qu'on voulait un positionnement absolu, mais encore faut-il dire où l'on veut que le bloc soit positionné sur la page.
Pour ce faire, on va utiliser quatre propriétés CSS :

  • left : position par rapport à la gauche de la page ;

  • right : position par rapport à la droite de la page ;

  • top : position par rapport au haut de la page ;

  • bottom : position par rapport au bas de la page.

On peut leur donner une valeur en pixels, comme 14px, ou bien une valeur en pourcentage, comme 50%.

Si ce n'est pas très clair pour certains d'entre vous, la figure suivante devrait vous aider à comprendre.

Positionnement absolu de l'élément sur la page
Positionnement absolu de l'élément sur la page

Avec cela, vous devriez être capables de positionner correctement votre bloc.

Il faut donc utiliser la propriété position et au moins une des quatre propriétés ci-dessus (top, left, right ou bottom). Si on écrit par exemple :

element
{
    position: absolute;
    right: 0px;
    bottom: 0px;
}

… cela signifie que le bloc doit être positionné tout en bas à droite (0 pixel par rapport à la droite de la page, 0 par rapport au bas de la page).

Si on essaye de placer notre bloc <nav> en bas à droite de la page, on obtient le même résultat qu'à la figure suivante.

Le menu est positionné en bas à droite de l'écran
Le menu est positionné en bas à droite de l'écran

On peut bien entendu ajouter une marge intérieure (padding) au menu pour qu'il soit moins collé à sa bordure.

Les éléments positionnés en absolu sont placés par-dessus le reste des éléments de la page ! Par ailleurs, si vous placez deux éléments en absolu vers le même endroit, ils risquent de se chevaucher. Dans ce cas, utilisez la propriété z-index pour indiquer quel élément doit apparaître au-dessus des autres.

element
{
    position: absolute;
    right: 0px;
    bottom: 0px;
    z-index: 1;
}
element2
{
    position: absolute;
    right: 30px;
    bottom: 30px;
    z-index: 2;
}

L'élément ayant la valeur de z-index la plus élevée sera placé par dessus les autres, comme le montre la figure suivante.

Positionnement des éléments absolus
Positionnement des éléments absolus

Une petite précision technique qui a son importance : le positionnement absolu ne se fait pas forcément toujours par rapport au coin en haut à gauche de la fenêtre ! Si vous positionnez en absolu un bloc A qui se trouve dans un autre bloc B, lui-même positionné en absolu (ou fixe ou relatif), alors votre bloc A se positionnera par rapport au coin supérieur gauche du bloc B. Faites le test, vous verrez !

Le positionnement fixe

Le principe est exactement le même que pour le positionnement absolu sauf que, cette fois, le bloc reste fixe à sa position, même si on descend plus bas dans la page.

element
{
    position: fixed;
    right: 0px;
    bottom: 0px;
}

Essayez d'observer le résultat, vous verrez que le menu reste dans le cas présent affiché en bas à droite même si on descend plus bas dans la page (figure suivante).

Le menu reste affiché en bas à droite en toutes circonstances Le menu reste affiché en bas à droite en toutes circonstances

Le positionnement relatif

Plus délicat, le positionnement relatif peut vite devenir difficile à utiliser. Ce positionnement permet d'effectuer des « ajustements » : l'élément est décalé par rapport à sa position initiale.

Prenons par exemple un texte important, situé entre deux balises <strong>. Pour commencer, je le mets sur fond rouge pour qu'on puisse mieux le repérer :

strong
{
   background-color: red; /* Fond rouge */
   color: yellow; /* Texte de couleur jaune */
}

Cette fois, le schéma que je vous ai montré tout à l'heure pour les positions absolue et fixe ne marche plus. Pourquoi ? Parce que l'origine a changé : le point de coordonnées (0, 0) ne se trouve plus en haut à gauche de votre fenêtre comme c'était le cas tout à l'heure. Non, cette fois l'origine se trouve en haut à gauche… de la position actuelle de votre élément.

Tordu n'est-ce pas ? C'est le principe de la position relative. Le schéma en figure suivante devrait vous aider à comprendre où se trouve l'origine des points.

Origine de la position relative
Origine de la position relative

Donc, si vous faites un position: relative; et que vous appliquez une des propriétés top, left, right ou bottom, le texte sur fond rouge va se déplacer par rapport à la position où il se trouve.

Prenons un exemple : je veux que mon texte se décale de 55 pixels vers la droite et de 10 pixels vers le bas. Je vais donc demander à ce qu'il soit décalé de 55 pixels par rapport au « bord gauche » et de 10 pixels par rapport au « bord haut » (lignes 6 à 8) :

strong
{
   background-color: red;
   color: yellow;

   position: relative;
   left: 55px;
   top: 10px;
}

Le texte est alors décalé par rapport à sa position initiale, comme illustré à la figure suivante.

Le texte est décalé
Le texte est décalé

En résumé

  • La mise en page d'un site web s'effectue en CSS. Plusieurs techniques sont à notre disposition.

  • Le positionnement flottant (avec la propriété float) est l'un des plus utilisés à l'heure actuelle. Il permet par exemple de placer un menu à gauche ou à droite de la page. Néanmoins, cette propriété n'a pas été initialement conçue pour cela et il est préférable, si possible, d'éviter cette technique.

  • Le positionnement inline-block consiste à affecter un type inline-block à nos éléments grâce à la propriété display. Ils se comporteront comme des inlines (placement de gauche à droite) mais pourront être redimensionnés comme des blocs (avec width et height). Cette technique est à préférer au positionnement flottant.

  • Le positionnement absolu permet de placer un élément où l'on souhaite sur la page, au pixel près.

  • Le positionnement fixe est identique au positionnement absolu mais l'élément restera toujours visible même si on descend plus bas dans la page.

  • Le positionnement relatif permet de décaler un bloc par rapport à sa position normale.

  • Un élément A positionné en absolu à l'intérieur d'un autre élément B (lui-même positionné en absolu, fixe ou relatif) se positionnera par rapport à l'élément B, et non par rapport au coin en haut à gauche de la page.


Tutoriel VBScript

TP : création d'un site pas à pas

https://vimeo.com/76136500

Enfin, nous y voilà. C'est un chapitre un peu particulier, assez différent de ce que vous avez lu jusqu'à maintenant. En fait, c'est ce que j'appelle un « TP » (Travaux Pratiques). Maintenant, vous ne pouvez plus vous contenter de lire mes chapitres à moitié endormis, vous allez devoir mettre la main à la pâte en même temps que moi.

Vous avez lu beaucoup de théorie jusqu'ici mais vous vous demandez sûrement comment font les webmasters pour créer d'aussi beaux sites. Vous vous dites que vous êtes encore loin d'avoir les connaissances nécessaires pour construire tout un site… Eh bien vous vous trompez !

Maquettage du design

Je vois d'ici le tableau. Vous vous dites « Chouette, on va créer un site complet », vous ouvrez votre éditeur de texte (Notepad++ par exemple), et vous me regardez en me demandant « Bon, par quelle ligne de code on commence ? ».

Et là, je dois justement vous arrêter. Prenez un crayon et un papier : il faut d'abord réfléchir à ce que vous voulez créer comme site. De quoi va-t-il parler ? Avez-vous un thème, un objectif ?

Je sais, par expérience, que la plupart d'entre vous « cherche juste à apprendre » pour le moment. Vous n'avez donc peut-être pas encore d'idée précise en tête. Dans ce cas, je vous suggère de créer un site pour vous présenter, pour assurer votre présence sur le Web : ce site parlera de vous, il y aura votre CV, vos futures réalisations et pourquoi pas votre blog.

En ce qui me concerne, dans ce TP, je vais réaliser le site web de notre mascotte Zozor, le célèbre âne du Site du Zéro (figure suivante). Zozor a décidé de partir en voyage à travers le monde et sa première étape sera… San Francisco ! Il veut donc créer un site web pour qu'on le connaisse et pour qu'on suive son périple à travers le monde.

L'âne Zozor, la mascote du Site du Zéro
L'âne Zozor, la mascote du Site du Zéro

La première étape consiste à maquetter le design, pour avoir un objectif du site web à réaliser. À partir de là, deux possibilités :

  • soit vous êtes des graphistes (ou vous en connaissez un) ayant l'habitude d'imaginer des designs, avec des logiciels comme Photoshop ;

  • soit vous n'êtes pas très créatifs, vous manquez d'inspiration et, dans ce cas, vous allez chercher votre inspiration sur des sites web comme freehtml5templates.com, qui vous proposent des idées de design et qui peuvent même vous donner le code HTML / CSS tout prêt !

Pour ma part j'ai fait appel à Fan Jiyong, un graphiste, qui m'a proposé le design (qui me plaît beaucoup !) que vous pouvez voir à la figure suivante.

La maquette du site web que nous allons réaliser La maquette du site web que nous allons réaliser

Conception de la maquette : Fan Jiyong

Cette maquette est en fait une simple image du résultat qu'on veut obtenir. Je demande au graphiste de me fournir les éléments qui vont m'aider à construire le design, c'est-à-dire les codes couleurs utilisés, les images découpées (figure suivante) ainsi que les polices dont j'aurai besoin.

Télécharger les images et les polices

Quelques-unes des images « découpées » utilisées dans le design

Il ne nous reste plus qu'à réaliser ce site web ! Nous allons procéder en deux temps :

  1. Nous allons construire le squelette HTML de la page.

  2. Puis nous allons le mettre en forme et le mettre en page avec CSS.

Allez, au boulot !

Organiser le contenu en HTML

La première chose à faire est de distinguer les principaux blocs sur la maquette. Ces blocs vont constituer le squelette de notre page.

Pour créer ce squelette, nous allons utiliser différentes balises HTML :

  • les balises structurantes de HTML5, que nous connaissons : <header>, <section>, <nav>, etc. ;

  • la balise universelle <div> quand aucune balise structurante ne convient.

Comment je sais quelle balise utiliser moi ?

C'est à vous de décider. De préférence, utilisez une balise qui a du sens (comme les balises structurantes <header>, <section>, <nav>) mais, si aucune balise ne vous semble mieux convenir, optez pour la balise générique <div>.

Regardez la figure suivante pour voir ce que je vous propose comme structure.

Maquette découpée en différentes sections Maquette découpée en différentes sections

On peut imaginer d'autres façons de faire le découpage, retenez bien que ma proposition n'est pas forcément la seule et unique solution !

Toutes les balises que l'on va utiliser n'apparaissent pas sur cette maquette mais cela vous permet d'avoir une idée de l'imbrication que je propose pour les éléments.

Le HTML n'est pas vraiment la partie complexe de la réalisation du site web. En fait, si vous avez bien compris comment imbriquer des balises, vous ne devriez pas avoir de mal à réaliser un code approchant du mien :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" href="style.css" />
        <title>Zozor - Carnets de voyage</title>
    </head>

    <body>
        <div id="bloc_page">
            <header>
                <div id="titre_principal">
                    <img src="images/zozor_logo.png" alt="Logo de Zozor" id="logo" />
                    <h1>Zozor</h1>
                    <h2>Carnets de voyage</h2>
                </div>

                <nav>
                    <ul>
                        <li><a href="#">Accueil</a></li>
                        <li><a href="#">Blog</a></li>
                        <li><a href="#">CV</a></li>
                        <li><a href="#">Contact</a></li>
                    </ul>
                </nav>
            </header>

            <div id="banniere_image">
                <div id="banniere_description">
                    Retour sur mes vacances aux États-Unis...
                    <a href="#" class="bouton_rouge">Voir l'article <img src="images/flecheblanchedroite.png" alt="" /></a>
                </div>
            </div>

            <section>
                <article>
                    <h1><img src="images/ico_epingle.png" alt="Catégorie voyage" class="ico_categorie" />Je suis un grand voyageur</h1>
                    <p>Lorem ipsum dolor sit amet...</p>
                    <p>Vivamus sed libero nec mauris pulvinar facilisis ut non sem...</p>
                    <p>Phasellus ligula massa, congue ac vulputate non, dignissim at augue...</p>
                </article>
                <aside>
                    <h1>À propos de l'auteur</h1>
                    <img src="images/bulle.png" alt="" id="fleche_bulle" />
                    <p id="photo_zozor"><img src="images/zozor_classe.png" alt="Photo de Zozor" /></p>
                    <p>Laisse-moi le temps de me présenter : je m'appelle Zozor, je suis né un 23 novembre 2005.</p>
                    <p>Bien maigre, n'est-ce pas ? C'est pourquoi, aujourd'hui, j'ai décidé d'écrire ma biographie (ou zBiographie, comme vous voulez !) afin que les zéros sachent qui je suis réellement.</p>
                    <p><img src="images/facebook.png" alt="Facebook" /><img src="images/twitter.png" alt="Twitter" /><img src="images/vimeo.png" alt="Vimeo" /><img src="images/flickr.png" alt="Flickr" /><img src="images/rss.png" alt="RSS" /></p>
                </aside>
            </section>

            <footer>
                <div id="tweet">
                    <h1>Mon dernier tweet</h1>
                    <p>Hii haaaaaan !</p>
                    <p>le 12 mai à 23h12</p>
                </div>
                <div id="mes_photos">
                    <h1>Mes photos</h1>
                    <p><img src="images/photo1.jpg" alt="Photographie" /><img src="images/photo2.jpg" alt="Photographie" /><img src="images/photo3.jpg" alt="Photographie" /><img src="images/photo4.jpg" alt="Photographie" /></p>
                </div>
                <div id="mes_amis">
                    <h1>Mes amis</h1>
                    <ul>
                        <li><a href="#">Pupi le lapin</a></li>
                        <li><a href="#">Mr Baobab</a></li>
                        <li><a href="#">Kaiwaii</a></li>
                        <li><a href="#">Perceval.eu</a></li>
                    </ul>
                    <ul>
                        <li><a href="#">Belette</a></li>
                        <li><a href="#">Le concombre masqué</a></li>
                        <li><a href="#">Ptit prince</a></li>
                        <li><a href="#">Mr Fan</a></li>
                    </ul>
                </div>
            </footer>
        </div>
    </body>
</html>

Petite particularité : comme vous le voyez, tout le contenu de la page est placé dans une grande balise <div> ayant pour idbloc_page (on l'appelle aussi parfois main_wrapper en anglais). Cette balise englobe tout le contenu, ce qui va nous permettre de fixer facilement les dimensions de la page et de centrer notre site à l'écran.

Pour le reste, aucune grosse difficulté à signaler. Notez que je n'ai pas forcément pensé à toutes les balises du premier coup : en réalisant le design en CSS, il m'est parfois apparu qu'il était nécessaire d'englober une partie des balises d'un bloc <div> pour m'aider dans la réalisation du design.

Pour le moment, comme vous vous en doutez, le site web n'est pas bien beau (et encore, je suis gentil). Vous pouvez voir le résultat actuel à la figure suivante.

Apparence du site web constitué uniquement du HTML
Apparence du site web constitué uniquement du HTML

C'est en CSS que la magie va maintenant opérer.

Mettre en forme en CSS

Les choses se compliquent un peu plus lorsqu'on arrive au CSS. En effet, il faut du travail (et parfois un peu d'astuce) pour obtenir un résultat se rapprochant de la maquette. Je dis bien « se rapprochant » car vous ne pourrez jamais obtenir un résultat identique au pixel près.

Mettez-vous bien cela en tête : le but est d'obtenir le rendu le plus proche possible, sans chercher la perfection. Même si vous obtenez selon vous « la perfection » sur un navigateur, vous pouvez être sûrs qu'il y aura des différences sur un autre navigateur (plus ancien) ou sur une autre machine que la vôtre. Nous allons donc faire au mieux et ce sera déjà du travail, vous verrez.

Pour mettre en forme le design, je vais procéder en plusieurs étapes. Je vais m'occuper des éléments suivants, dans cet ordre :

  1. Polices personnalisées.

  2. Définition des styles principaux de la page (largeur du site, fond, couleur par défaut du texte).

  3. En-tête et liens de navigation.

  4. Bannière (représentant le pont de San Francisco).

  5. Section principale du corps de page, au centre.

  6. Pied de page (footer).

Les polices personnalisées

Pour les besoins du design, mon graphiste a utilisé trois polices sur sa maquette :

  • Trebuchet MS (police courante) ;

  • BallparkWeiner (police exotique) ;

  • Day Roman (police exotique).

Vous trouverez ces polices dans le fichier que je vous ai fait télécharger un peu plus haut. Si ce n'est pas encore fait, je vous encourage fortement à le télécharger.

La plupart des ordinateurs sont équipés de Trebuchet MS (quoique pas nécessairement tous, on pourrait la faire télécharger). Par contre, les deux autres polices sont un peu originales et ne sont sûrement pas présentes sur les ordinateurs de vos visiteurs. Nous allons les leur faire télécharger.

Comme vous le savez, il faut proposer plusieurs versions de ces polices pour les différents navigateurs. Dafont ne propose que le .ttf en téléchargement. Par contre, FontSquirrel propose un générateur de polices à utiliser en CSS3 avec @font-face : vous lui envoyez un .ttf, l'outil transforme le fichier dans tous les autres formats nécessaires et vous fournit même le code CSS prêt à l'emploi !

Je m'en suis servi pour générer les différentes versions des deux polices exotiques que je vais utiliser. Ensuite, dans mon fichier CSS, je rajoute ce code qui m'a été fourni par FontSquirrel pour déclarer les nouvelles polices :

/* Définition des polices personnalisées */

@font-face
{
    font-family: 'BallparkWeiner';
    src: url('polices/ballpark.eot');
    src: url('polices/ballpark.eot?#iefix') format('embedded-opentype'),
         url('polices/ballpark.woff') format('woff'),
         url('polices/ballpark.ttf') format('truetype'),
         url('polices/ballpark.svg#BallparkWeiner') format('svg');
    font-weight: normal;
    font-style: normal;
}

@font-face
{
    font-family: 'Dayrom';
    src: url('polices/dayrom.eot');
    src: url('polices/dayrom.eot?#iefix') format('embedded-opentype'),
         url('polices/dayrom.woff') format('woff'),
         url('polices/dayrom.ttf') format('truetype'),
         url('polices/dayrom.svg#Dayrom') format('svg');
    font-weight: normal;
    font-style: normal;
}

En plus de cela, il faut bien entendu mettre à disposition les fichiers des polices. Comme vous le voyez, j'ai créé un sous-dossier polices dans lequel j'ai mis les différentes versions de mes polices.

Définition des styles principaux

On peut maintenant s'attaquer à définir quelques styles globaux pour tout le design de notre page. On va définir une image de fond, une police et une couleur de texte par défaut, et surtout on va dimensionner notre page et la centrer à l'écran.

/* Eléments principaux de la page */

body
{
    background: url('images/fond_jaune.png');
    font-family: 'Trebuchet MS', Arial, sans-serif;
    color: #181818;
}

#bloc_page
{
    width: 900px;
    margin: auto;
}

section h1, footer h1, nav a
{
    font-family: Dayrom, serif;
    font-weight: normal;
    text-transform: uppercase;
}

Avec #bloc_page, le bloc qui englobe toute la page, j'ai fixé les limites à 900 pixels de large. Avec les marges automatiques, le design sera centré.

Si vous souhaitez créer un design qui s'adapte aux dimensions de l'écran du visiteur, définissez une largeur en pourcentage plutôt qu'en pixels.

J'ai utilisé la propriété CSS text-transform: uppercase; (que nous n'avons pas vue auparavant) pour faire en sorte que mes titres soient toujours écrits en majuscules. Cette propriété transforme en effet le texte en majuscules (elle peut aussi faire l'inverse avec lowercase). Notez qu'on aurait aussi pu écrire les titres directement en majuscules dans le code HTML.

La figure suivante vous montre ce qu'on obtient pour le moment avec le code CSS. On est encore loin du résultat final mais on se sent déjà un petit peu plus « chez soi ».

Le fond et les limites de la page commencent à apparaître
Le fond et les limites de la page commencent à apparaître

En-tête et liens de navigation

D'après la structure que j'ai proposée, l'en-tête contient aussi les liens de navigation. Commençons par définir l'en-tête et, en particulier, le logo en haut à gauche. Nous verrons ensuite comment mettre en forme les liens de navigation.

L'en-tête
/* Header */

header
{
    background: url('images/separateur.png') repeat-x bottom;
}

#titre_principal
{
    display: inline-block;
}

header h1
{
    font-family: 'BallparkWeiner', serif;
    font-size: 2.5em;
    font-weight: normal;
}

#logo, header h1
{
    display: inline-block;
    margin-bottom: 0px;
}

header h2
{
    font-family: Dayrom, serif;
    font-size: 1.1em;
    margin-top: 0px;
    font-weight: normal;
}

Nous créons une distinction entre l'en-tête et le corps de page grâce à une image de fond. Les éléments sont positionnés en inline-block et nous personnalisons les polices et les dimensions. Rien d'extraordinaire pour le moment.

Les liens de navigation

La mise en forme des liens de navigation est un petit peu plus intéressante. Vous l'avez vu, j'ai créé une liste à puces pour les liens… mais une telle liste s'affiche habituellement en hauteur, et non en largeur. Heureusement, cela se change facilement, vous allez voir :

/* Navigation */

nav
{
    display: inline-block;
    width: 740px;
    text-align: right;
}

nav ul
{
    list-style-type: none;
}

nav li
{
    display: inline-block;
    margin-right: 15px;
}

nav a
{
    font-size: 1.3em;
    color: #181818;
    padding-bottom: 3px;
    text-decoration: none;
}

nav a:hover
{
    color: #760001;
    border-bottom: 3px solid #760001;
}

La principale nouveauté est la définition CSS list-style-type: none;, qui permet de retirer l'image ronde servant de puce. Chaque élément de la liste (<li>) est positionné en inline-block, ce qui nous permet de placer les liens côte à côte comme nous le souhaitions.

Le reste des définitions ne contient rien d'extraordinaire : des dimensions, des couleurs, des bordures… Autant de choses que vous connaissez déjà. Notez que je ne trouve pas forcément les bonnes valeurs du premier coup, il me faut parfois tâtonner un peu pour trouver une apparence proche de la maquette d'origine.

La figure suivante représente le résultat que nous obtenons avec les derniers ajouts de CSS.

L'en-tête est mis en page
L'en-tête est mis en page

La bannière

Bien, passons maintenant à un exercice un peu plus difficile mais très intéressant : la bannière ! Notre maquette comporte une jolie bannière représentant le pont de San Francisco. Cette bannière, sur votre site, peut être amenée à évoluer. Ici, elle peut servir à illustrer, par exemple, le dernier billet de blog de notre ami Zozor, qui vient de visiter San Francisco.

La bannière est intéressante à plus d'un titre :

  • elle comporte des angles arrondis ;

  • la description est écrite sur un fond légèrement transparent ;

  • le bouton « Voir l'article » est réalisé en CSS, avec des angles arrondis ;

  • une ombre vient donner du volume à la bannière.

Voici le code que j'ai utilisé pour réaliser toute la bannière :

/* Bannière */

#banniere_image
{
    margin-top: 15px;
    height: 200px;
    border-radius: 5px;
    background: url('images/sanfrancisco.jpg') no-repeat;
    position: relative;
    box-shadow: 0px 4px 4px #1c1a19;
    margin-bottom: 25px;
}

#banniere_description
{
    position: absolute;
    bottom: 0;
    border-radius: 0px 0px 5px 5px;
    width: 99.5%;
    height: 33px;
    padding-top: 15px;
    padding-left: 4px;
    background-color: rgb(24,24,24); /* Pour les anciens navigateurs */
    background-color: rgba(24,24,24,0.8);
    color: white;
    font-size: 0.8em;
}

.bouton_rouge
{
    display: inline-block;
    height: 25px;
    position: absolute;
    right: 5px;
    bottom: 5px;
    background: url('images/fond_degraderouge.png') repeat-x;
    border: 1px solid #760001;
    border-radius: 5px;
    font-size: 1.2em;
    text-align: center;
    padding: 3px 8px 0px 8px;
    color: white;
    text-decoration: none;
}

.bouton_rouge img
{
    border: 0;
}

Ce code est assez technique et riche en fonctionnalités CSS. C'est peut-être la partie la plus délicate à réaliser dans cette page.

Vous pouvez constater que j'ai choisi d'afficher l'image du pont sous forme d'image de fond dans le bloc <div> de la bannière.

J'ai aussi donné une position relative à la bannière, sans utiliser de propriétés pour en modifier le décalage… Pourquoi ? A priori, une position relative sans décalage ne sert à rien… Et pourtant, cela m'a été particulièrement utile pour placer le bouton « Voir l'article » en bas à droite de la bannière. En effet, j'ai placé le bouton en absolu à l'intérieur.

Le bouton ne devrait-il pas se placer en bas à droite de la page ?

Non, souvenez-vous ce que je vous avais dit : si un bloc est positionné en absolu dans un autre bloc lui-même positionné en absolu, fixe ou relatif, alors il se positionne à l'intérieur de ce bloc.
Notre bannière est positionnée en relatif (sans décalage). Comme le bouton est positionné en absolu à l'intérieur, il se place donc en bas à droite de la bannière !

C'est une technique particulièrement utile et puissante dans la réalisation d'un design, souvenez-vous en !

Dernier détail : pour la légende de la bannière, j'ai choisi d'utiliser la transparence avec la notation RGBa plutôt que la propriété opacity. En effet, opacity aurait rendu tout le contenu du bloc transparent, y compris le bouton « Voir l'article » à l'intérieur. J'ai trouvé préférable de rendre transparente seulement la couleur de fond plutôt que tout le bloc.

Le résultat est plutôt sympathique (figure suivante).

La bannière est mise en forme
La bannière est mise en forme

Cela en jette, vous ne trouvez pas ?

Pour réaliser le dégradé du bouton « Voir l'article », j'ai utilisé une image de fond représentant le dégradé et j'ai répété cette image horizontalement. Sachez qu'il existe une propriété CSS3 linear-gradient qui permet de réaliser des dégradés sans avoir à recourir à une image de fond. Son usage étant un peu complexe actuellement, j'ai choisi de ne pas l'utiliser dans cet exemple, mais vous pouvez vous documenter à son sujet si vous le souhaitez !

Le corps

Le corps, au centre de la page, est dans notre cas constitué d'une unique balise <section> (mais il pourrait y en avoir plusieurs, bien sûr).

Pas beaucoup de difficultés sur le corps, le positionnement du bloc « À propos de l'auteur » se fait en inline-block. On joue avec les angles arrondis et les ombres, on ajuste un peu les marges et les dimensions du texte, et nous y voilà !

/* Corps */

article, aside
{
    display: inline-block;
    vertical-align: top;
    text-align: justify;
}

article
{
    width: 625px;
    margin-right: 15px;
}

.ico_categorie
{
    vertical-align: middle;
    margin-right: 8px;
}

article p
{
    font-size: 0.8em;
}

aside
{
    position: relative;
    width: 235px;
    background-color: #706b64;
    box-shadow: 0px 2px 5px #1c1a19;
    border-radius: 5px;
    padding: 10px;
    color: white;
    font-size: 0.9em;
}

#fleche_bulle
{
    position: absolute;
    top: 100px;
    left: -12px;
}

#photo_zozor
{
    text-align: center;
}

#photo_zozor img
{
    border: 1px solid #181818;
}

aside img
{
    margin-right: 5px;
}

La petite difficulté ici était de réussir à placer la flèche à gauche du bloc <aside> « À propos de l'auteur » pour donner l'effet d'une bulle. Là encore, notre meilleur ami est le positionnement absolu. La technique est la même : je positionne le bloc <aside> en relatif (sans effectuer de décalage), ce qui me permet ensuite de positionner l'image de la flèche en absolu par rapport au bloc <aside> (et non par rapport à la page entière). En jouant sur le décalage de l'image, je peux la placer avec précision où je veux, au pixel près (figure suivante) !

Le corps de la page est mis en forme
Le corps de la page est mis en forme

Le pied de page

Il ne nous reste plus que le pied de page à mettre en forme. Celui-ci est constitué de trois sous-blocs que j'ai matérialisés par des <div> auxquels j'ai donné des id pour mieux les repérer. Ces blocs sont positionnés en inline-block les uns à côté des autres.

/* Footer */

footer
{
    background:  url('images/ico_top.png') no-repeat top center, url('images/separateur.png') repeat-x top, url('images/ombre.png') repeat-x top;
    padding-top: 25px;
}

footer p, footer ul
{
    font-size: 0.8em;
}

footer h1
{
    font-size: 1.1em;
}

#tweet, #mes_photos, #mes_amis
{
    display: inline-block;
    vertical-align: top;
}

#tweet
{
    width: 28%;
}

#mes_photos
{
    width: 35%;
}

#mes_amis
{
    width: 31%;
}

#mes_photos img
{
    border: 1px solid #181818;
    margin-right: 2px;
}

#mes_amis ul
{
    display: inline-block;
    vertical-align: top;
    margin-top: 0;
    width: 48%;
    list-style-image: url('images/ico_liensexterne.png');
    padding-left: 2px;
}

#mes_amis a
{
    text-decoration: none;
    color: #760001;
}

Deux petites particularités à signaler sur le pied de page :

  • J'ai utilisé la fonctionnalité des images de fond multiples de CSS3, ce qui m'a permis de réaliser le séparateur entre le corps et le pied de page. Il est constitué de trois images : le séparateur, la petite flèche vers le haut et un léger dégradé.

  • J'ai modifié la puce de la liste « Mes amis », en bas à droite, avec la propriété list-style-image qui m'a permis d'utiliser une image personnalisée plutôt que les puces standard. Il existe de nombreuses propriétés CSS spécifiques comme celle-ci et nous ne pouvons pas toutes les voir une par une dans ce cours mais, maintenant que vous êtes des habitués du CSS, vous n'aurez aucun mal à apprendre à les utiliser simplement en lisant l'annexe listant les principales propriétés CSS.

Et voilà, notre design est terminé (figure suivante) !

Le pied de page est mis en forme
Le pied de page est mis en forme

Ah, vous pensez en avoir fini ? Il reste hélas encore un peu de travail : il faut tester notre site sur différents navigateurs. Idéalement, il vaut mieux le faire au fur et à mesure de la mise en place du design. En particulier, les anciennes versions d'Internet Explorer (IE6 à IE8) méritent qu'on s'y attarde car le résultat n'est pas forcément celui auquel on s'attendait…

Assurer la compatibilité avec IE

Depuis Internet Explorer 9 (IE9), nous n'avons plus vraiment de raisons de nous plaindre du légendaire retard d'Internet Explorer dans la gestion du CSS. Voyez vous-mêmes le résultat (figure suivante), il est très bon sur ce navigateur sans aucune adaptation nécessaire.

Le site sous IE9 : aucun problème à signaler !
Le site sous IE9 : aucun problème à signaler !

Par contre, vous risquez d'attraper quelques cheveux blancs en regardant le résultat sur les anciennes versions d'Internet Explorer.

Comment je fais pour voir le résultat sous IE6 à IE8, si je suis équipé d'IE9 ?

Je vous avais parlé d'IETester, un outil pratique mais instable (il plante souvent). Vous pouvez l'essayer pour tester votre site sur les anciennes versions d'IE.

Il y a cependant une solution plus stable et plus rapide : appuyez sur la touche F12 de votre clavier lorsque vous êtes sous IE9 et une barre dédiée aux développeurs web apparaît. Là, un menu vous permet de changer le comportement d'IE (figure suivante) afin de simuler les anciennes versions (à partir de IE7).

Changement du moteur de rendu sous IE
Changement du moteur de rendu sous IE

Là, en général, il arrive qu'on prenne très peur.
La figure suivante vous montre ce qu'on obtient en « mode IE7 ».

Le site sous IE7 : rien ne s'affiche correctement !
Le site sous IE7 : rien ne s'affiche correctement !

Avant de préparer votre valise pour aller vivre en Patagonie loin de ce monde cruel, laissez-moi vous redonner le moral avec cette phrase rassurante : tout problème a une solution (répétez cela autant de fois que nécessaire).

En fait, notre site ne rencontre que deux problèmes principaux sur les anciennes versions d'IE :

  • Le positionnement inline-block n'est pas bien géré sous IE6 et IE7, ce qui fait que la plupart de nos positionnements ne fonctionnent pas pour le moment… Mais nous avons vu qu'une astuce permet de régler le problème sans trop d'efforts !

  • Les balises structurantes de HTML5 (<header>, <nav>, <aside>…) ne sont pas gérées sous IE6, IE7 et IE8, ce qui pose de gros problèmes d'affichage… Mais, là encore, un petit script ajouté au début de votre code HTML permet de régler le problème !

Par contre, il faudra faire une croix sur certaines fonctionnalités plus récentes de CSS3 qui ne sont pas gérées sur ces vieilles versions :

  • les coins arrondis ;

  • les images de fond multiples ;

  • la transparence ;

  • les ombres.

Étant donné que ce sont des fonctionnalités liées à l'apparence, nous ne chercherons pas à les faire fonctionner sur les anciennes versions d'IE. Si toutefois vous y tenez, sachez que, là encore, des scripts existent et permettent d'émuler la plupart de ces fonctionnalités manquantes, mais cela vous demandera pas mal de travail supplémentaire et votre site risque d'être plus lent sur ces navigateurs. Du moment que le site reste lisible sur les anciennes versions d'IE, je vous recommande de ne pas vous préoccuper trop de ces problèmes.

Lorsqu'on accepte que son site soit « un peu moins beau » sur les anciennes versions des navigateurs, on dit qu'on fait une dégradation gracieuse. Cela veut dire qu'on ne cherche pas à obtenir tous les effets, mais on s'efforce d'avoir un site qui reste quand même lisible sur les vieux navigateurs.

Faire fonctionner les balises structurantes de HTML5

Nous l'avons vu, il suffit d'ajouter un simple bout de code JavaScript dans l'en-tête de son site et le tour est joué (lignes 6 à 8) :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" href="style.css" />
        <!--[if lt IE 9]>
        <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
        <![endif]-->
        <title>Zozor - Carnets de voyage</title>
    </head>

Le fichier JavaScript sera téléchargé depuis les serveurs de Google : c'est une technique rapide qui vous évite d'avoir à gérer vous-mêmes le fichier. Si vous le souhaitez, vous pouvez aussi en récupérer une copie et la placer à côté des fichiers de votre site.

Régler le positionnement inline-block

Pour gérer le positionnement inline-block, nous avons vu qu'il était nécessaire de créer une feuille de style spéciale pour les anciennes versions d'Internet Explorer. Il faut utiliser un CSS un peu différent pour que les vieilles versions d'IE « comprennent » ce qu'il faut faire.

En créant une feuille de style spéciale pour les vieilles versions d'IE (qu'on pourrait appeler style_ie.css) et en utilisant la technique ci-dessous, on peut reproduire le comportement des inline-block :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" href="style.css" />
        <!--[if lte IE 7]>
        <link rel="stylesheet" href="style_ie.css" />
        <![endif]-->

        <title>Zozor - Le Site Web</title>
    </head>

La feuille de style style_ie.css contiendra des déclarations comme celle-ci :

element
{
    display: inline;
    zoom: 1;
}

Cette technique doit être appliquée sur chaque élément positionné en inline-block.

D'autres différences existent sur les vieilles versions d'IE : le texte n'est pas toujours à la bonne taille, certains blocs sont eux aussi mal dimensionnés, etc. Ces différences doivent être réglées au cas par cas dans la feuille style_ie.css.

Vérifier la validité

Le W3C propose sur son site web un outil appelé le « Validateur » (« Validator » en anglais).
Le validateur est une sorte de programme qui va analyser votre code source et vous dire s'il est correctement écrit ou s'il comporte des erreurs que vous devez corriger.

Souvenez-vous : le W3C a établi des normes. Il est nécessaire de les respecter, pour qu'on soit sûr que tous les sites web parlent la même « langue ».

Il existe un validateur pour HTML et un validateur pour CSS (à mettre dans vos favoris !). Celui pour CSS comportant quelques bugs (il signale comme invalides des feuilles CSS qui sont tout à fait valides), nous ne nous y attarderons pas. Par contre, le validateur HTML va être très intéressant pour nous : voici son adresse http://validator.w3.org.

Vous pouvez valider votre page web de trois façons différentes, c'est pour cela qu'il y a trois onglets :

  • adresse (URL) ;

  • envoi du fichier .html ;

  • copier-coller du code HTML.

Pour le moment, notre site web n'est pas encore disponible sur le Web, ce qui fait qu'il n'a pas d'adresse URL. Le mieux est donc d'envoyer le fichier .html que l'on a fait ou encore de copier-coller directement le code HTML.

Si vous envoyez votre code HTML et que tout se passe bien, le validateur va vous répondre avec le message représenté à la figure suivante.

Le validateur du W3C nous informe que notre page ne comporte pas d'erreur
Le validateur du W3C nous informe que notre page ne comporte pas d'erreur

Dans ce cas, cela signifie que tout va bien et que vous avez bien construit votre page !

Malheureusement, il arrivera souvent que vous ayez des erreurs. Dans ce cas, évitez de paniquer comme cela :

AU SEEECOUUUUUUUURS !!! Ma page web n'est pas valide, je ne vais pas m'en sortir, je suis cerné par les erreurs, faites quelque chose aidez-mmmoiiiiii !

Vous aviez une belle page web, elle s'affichait bien, elle était jolie, et pourtant le validateur vous répond avec un message rouge inquiétant, en vous disant que votre page web n'est pas bien construite.

Tout d'abord, mettez-vous bien ceci en tête : ce n'est pas parce que votre page web s'affiche correctement qu'elle ne comporte pas d'erreur. Votre page web peut être toute belle et comporter beaucoup d'erreurs.

Quel intérêt de les corriger alors ?

Il faut savoir que les navigateurs « essaient » de ne pas afficher les erreurs, lorsqu'ils en rencontrent, pour ne pas perturber l'internaute. Mais rien ne vous dit que d'autres navigateurs ne vont pas se comporter bizarrement !

Avoir une page web valide, c'est donc avoir la possibilité de dormir tranquille en sachant que l'on a bien fait les choses comme il faut. Cela simplifie le travail des programmes qui lisent les pages web.
De plus, et c'est vérifié, une page web correctement construite aura plus de chances d'être mieux positionnée dans les résultats de recherche de Google, ce qui vous amènera… plus de visiteurs !

Voici une liste de conseils qui peuvent vous aider à résoudre les erreurs qui risquent de vous être signalées tôt ou tard :

  • Tous vos textes doivent en général être dans des balises de paragraphes. Il est interdit de mettre du texte directement entre les balises <body></body> sans l'avoir entouré des fameux <p></p>. Ceci est aussi valable pour les retours à la ligne <br />, qui doivent être à l'intérieur de paragraphes. C'est une erreur ultra-courante chez les débutants.

<p>Ceci est un texte correctement placé dans un paragraphe.
<br />
Les balises <br /> doivent se trouver à l'intérieur d'un paragraphe, ne l'oubliez pas</p>

Ceci est un texte en-dehors d'un paragraphe. C'est interdit.
<br />

  • Toutes vos images doivent comporter un attribut alt qui indique ce que contient l'image. Si, par hasard, votre image est purement décorative (vous ne pouvez pas en trouver de description), vous êtes autorisés à ne rien mettre comme valeur pour l'attribut alt.

<!-- L'image comporte une description -->
<img src="photo.jpg" alt="Une photo de moi" />

<!-- L'image ne comporte pas de description mais a quand même un attribut alt -->
<img src="deco.png" alt="" />

  • Vos balises doivent être fermées dans l'ordre.

<!-- Les balises ne sont pas fermées dans leur ordre d'ouverture -->
<p>Texte <em>important</p></em>

<!-- Les balises sont fermées dans leur ordre d'ouverture -->
<p>Texte <em>important</em></p>

Gardez bien ce schéma en tête, beaucoup de débutants font cette erreur.

  • Si vos liens comportent des &, vous devez les remplacer par le code &amp; pour éviter toute confusion au navigateur.

<!-- Exemple d'un mauvais lien en HTML -->
<a href="http://www.site.com/?jour=15&mois=10&an=2000">

<!-- Exemple d'un bon lien en HTML -->
<a href="http://www.site.com/?jour=15&amp;mois=10&amp;an=2000">

  • Vérifiez enfin que vous n'avez pas utilisé des balises anciennes et désormais obsolètes en HTML5 (comme le vieux <frame>, la balise <marquee>…

Le validateur vous dira « Element XXX undefined » (balise inconnue) ou encore « There is no attribute XXX » (attribut inconnu).

Tout le monde fait des erreurs, alors ne paniquez pas. Corrigez pas à pas votre page web jusqu'à ce que le validateur vous affiche un beau résultat en vert.

Le code final

Je mets à disposition le code final de la page web que nous avons réalisée. Vous pouvez également visualiser le résultat (figure suivante) en ligne grâce à un code web.

Apparence finale du site web Apparence finale du site web

Vous pouvez aussi télécharger un fichier ZIP contenant tous les fichiers du site pour pouvoir le tester chez vous :

Télécharger les fichiers du site (500 Ko)

Pour ajuster au mieux le site sur les anciennes versions d'Internet Explorer, vous verrez je n'ai pas créé dans ce code final de feuille style_ie.css. À la place, j'ai utilisé une autre technique qui consiste à donner une classe spéciale (comme .ie7) à la balise <body> uniquement sur les anciennes versions d'IE, ce qui me permet de savoir quelle est la version du navigateur dans le fichier CSS (.ie7 footer permet par exemple de modifier le style du footer sur IE7).


Tutoriel VBScript

Les tableaux

https://vimeo.com/76812666

Indispensables pour organiser les informations, les tableaux sont un petit peu délicats à construire en HTML : cela explique que je vous les présente seulement maintenant. Il va en effet falloir imbriquer de nouvelles balises HTML dans un ordre précis.

Nous allons commencer par construire des tableaux basiques, puis nous les complexifierons au fur et à mesure : fusion de cellules, division en multiples sections… Nous découvrirons aussi les propriétés CSS liées aux tableaux, qui nous permettront de personnaliser leur apparence.

Un tableau simple

La première balise à connaître est <table> </table>. C'est cette balise qui permet d'indiquer le début et la fin d'un tableau.

Cette balise est de type bloc, il faut donc la placer en dehors d'un paragraphe. Exemple :

<p>Ceci est un paragraphe avant le tableau.</p>

<table>
   <!-- Ici, on écrira le contenu du tableau -->
</table>

<p>Ceci est un paragraphe après le tableau.</p>

Bon, et qu'est-ce qu'on écrit à l'intérieur du tableau ?

Là, préparez-vous à subir une avalanche de nouvelles balises.
Pour commencer en douceur, voici deux nouvelles balises très importantes :

  • <tr> </tr> : indique le début et la fin d'une ligne du tableau ;

  • <td> </td> : indique le début et la fin du contenu d'une cellule.

En HTML, un tableau se construit ligne par ligne. Dans chaque ligne (<tr>), on indique le contenu des différentes cellules (<td>).
Schématiquement, un tableau se construit comme à la figure suivante.

Un tableau, avec des cellules contenues dans des lignes
Un tableau, avec des cellules contenues dans des lignes

On a une balise de ligne (<tr>) qui englobe un groupe de cellules (<td>).
Par exemple, si je veux faire un tableau à deux lignes, avec trois cellules par ligne (donc trois colonnes), je devrai taper ceci :

<table>
   <tr>
       <td>Carmen</td>
       <td>33 ans</td>
       <td>Espagne</td>
   </tr>
   <tr>
       <td>Michelle</td>
       <td>26 ans</td>
       <td>États-Unis</td>
   </tr>
</table>

Le résultat est un peu déprimant (figure suivante).

Un tableau sans bordures
Un tableau sans bordures

C'est un tableau ça ?
Le texte s'est écrit à la suite et il n'y a même pas de bordures !

Oui, un tableau sans CSS paraît bien vide. Et justement, rajouter des bordures est très simple, vous connaissez déjà le code CSS correspondant !

td /* Toutes les cellules des tableaux... */
{
    border: 1px solid black; /* auront une bordure de 1px */
}

Et voici le résultat à la figure suivante.

Chaque cellule a sa propre bordure
Chaque cellule a sa propre bordure

Hum, ce n'est pas encore aussi parfait que ce qu'on voudrait. En effet, on aimerait qu'il n'y ait qu'une seule bordure entre deux cellules, or ce n'est pas le cas ici.

Heureusement, il existe une propriété CSS spécifique aux tableaux, border-collapse, qui signifie « coller les bordures entre elles ».
Cette propriété peut prendre deux valeurs :

  • collapse : les bordures seront collées entre elles, c'est l'effet qu'on recherche ici ;

  • separate : les bordures seront dissociées (valeur par défaut)

table
{
    border-collapse: collapse; /* Les bordures du tableau seront collées (plus joli) */
}
td
{
    border: 1px solid black;
}

La figure suivante représente le résultat obtenu.

Les bordures sont collées les unes aux autres
Les bordures sont collées les unes aux autres

Voilà qui est mieux !

La ligne d'en-tête

Maintenant que l'on a ce qu'on voulait, on va rajouter la ligne d'en-tête du tableau. Dans l'exemple ci-dessous, les en-têtes sont « Nom », « Âge » et « Pays ».
La ligne d'en-tête se crée avec un <tr> comme on l'a fait jusqu'ici, mais les cellules qu'elle contient sont, cette fois, encadrées par des balises <th> et non pas <td> !

<table>
   <tr>
       <th>Nom</th>
       <th>Âge</th>
       <th>Pays</th>
   </tr>

   <tr>
       <td>Carmen</td>
       <td>33 ans</td>
       <td>Espagne</td>
   </tr>
   <tr>
       <td>Michelle</td>
       <td>26 ans</td>
       <td>États-Unis</td>
   </tr>
</table>

La ligne d'en-tête est très facile à reconnaître pour deux raisons :

  • les cellules sont des <th> au lieu des <td> habituels ;

  • c'est la première ligne du tableau (c'est idiot, mais encore faut-il le préciser).

Comme le nom des cellules est un peu différent pour l'en-tête, il faut penser à mettre à jour le CSS pour lui dire d'appliquer une bordure sur les cellules normales et sur l'en-tête (figure suivante).

table
{
    border-collapse: collapse;
}
td, th /* Mettre une bordure sur les td ET les th */
{
    border: 1px solid black;
}
Un tableau avec un en-tête
Un tableau avec un en-tête

Comme vous pouvez le constater, votre navigateur a mis en gras le texte des cellules d'en-tête. C'est ce que font en général les navigateurs mais, si vous le désirez, vous pouvez changer cela à coups de CSS : modifier la couleur de fond des cellules d'en-tête, leur police, leur bordure, etc.

Titre du tableau

Normalement, tout tableau doit avoir un titre. Le titre permet de renseigner rapidement le visiteur sur le contenu du tableau.
Notre exemple est constitué d'une liste de personnes… oui mais alors ? Qu'est-ce que cela représente ? Sans titre de tableau, vous le voyez, on est un peu perdu.

Heureusement, il y a <caption> !
Cette balise se place tout au début du tableau, juste avant l'en-tête. C'est elle qui contient le titre du tableau (figure suivante) :

<table>
   <caption>Passagers du vol 377</caption>

   <tr>
       <th>Nom</th>
       <th>Âge</th>
       <th>Pays</th>
   </tr>
   <tr>
       <td>Carmen</td>
       <td>33 ans</td>
       <td>Espagne</td>
   </tr>
   <tr>
       <td>Michelle</td>
       <td>26 ans</td>
       <td>États-Unis</td>
   </tr>
</table>
Un tableau avec un titre
Un tableau avec un titre

C'est quand même plus clair !

Sachez que vous pouvez changer la position du titre avec la propriété CSS caption-side qui peut prendre deux valeurs :

  • top : le titre sera placé au-dessus du tableau (par défaut) ;

  • bottom : le titre sera placé en dessous du tableau.

Un tableau structuré

Nous avons appris à construire des petits tableaux simples. Ces petits tableaux suffisent dans la plupart des cas, mais il arrivera que vous ayez besoin de réaliser des tableaux plus… complexes.

Nous allons découvrir deux techniques particulières :

  • Pour les gros tableaux, il est possible de les diviser en trois parties :

    • En-tête ;

    • Corps du tableau ;

    • Pied de tableau.

  • Pour certains tableaux, il se peut que vous ayez besoin de fusionner des cellules entre elles.

Diviser un gros tableau

Si votre tableau est assez gros, vous aurez tout intérêt à le découper en plusieurs parties. Pour cela, il existe des balises HTML qui permettent de définir les trois « zones » du tableau :

  • l'en-tête (en haut) : il se définit avec les balises <thead></thead> ;

  • le corps (au centre) : il se définit avec les balises <tbody></tbody> ;

  • le pied du tableau (en bas) : il se définit avec les balises <tfoot></tfoot>.

Que mettre dans le pied de tableau ? Généralement, si c'est un long tableau, vous y recopiez les cellules d'en-tête. Cela permet de voir, même en bas du tableau, à quoi se rapporte chacune des colonnes. Schématiquement, un tableau en trois parties se découpe donc comme illustré à la figure suivante.

Un tableau découpé en plusieurs parties
Un tableau découpé en plusieurs parties

C'est un peu déroutant mais il est conseillé d'écrire les balises dans l'ordre suivant :

  1. <thead>

  2. <tfoot>

  3. <tbody>

Dans le code, on renseigne donc d'abord la partie du haut, ensuite la partie du bas, et enfin la partie principale (<tbody>). Le navigateur se chargera d'afficher chaque élément au bon endroit, ne vous inquiétez pas.

Voici donc le code à écrire pour construire le tableau en trois parties :

<table>
   <caption>Passagers du vol 377</caption>

   <thead> <!-- En-tête du tableau -->
       <tr>
           <th>Nom</th>
           <th>Âge</th>
           <th>Pays</th>
       </tr>
   </thead>

   <tfoot> <!-- Pied de tableau -->
       <tr>
           <th>Nom</th>
           <th>Âge</th>
           <th>Pays</th>
       </tr>
   </tfoot>

   <tbody> <!-- Corps du tableau -->
       <tr>
           <td>Carmen</td>
           <td>33 ans</td>
           <td>Espagne</td>
       </tr>
       <tr>
           <td>Michelle</td>
           <td>26 ans</td>
           <td>États-Unis</td>
       </tr>
       <tr>
           <td>François</td>
           <td>43 ans</td>
           <td>France</td>
       </tr>
       <tr>
           <td>Martine</td>
           <td>34 ans</td>
           <td>France</td>
       </tr>
       <tr>
           <td>Jonathan</td>
           <td>13 ans</td>
           <td>Australie</td>
       </tr>
       <tr>
           <td>Xu</td>
           <td>19 ans</td>
           <td>Chine</td>
       </tr>
   </tbody>
</table>

Il n'est pas obligatoire d'utiliser ces trois balises (<thead>, <tbody>, <tfoot>) dans tous les tableaux. En fait, vous vous en servirez surtout si votre tableau est assez gros et que vous avez besoin de l'organiser plus clairement.
Pour les « petits » tableaux, vous pouvez garder sans problème l'organisation plus simple que nous avons vue au début.

3, 2, 1… Fusioooon !

Dans certains tableaux complexes, vous aurez besoin de « fusionner » des cellules entre elles.
Un exemple de fusion ? Regardez le tableau à la figure suivante, qui dresse une liste de films et indique à qui ils s'adressent.

Un tableau contenant des titres de films et leur public
Un tableau contenant des titres de films et leur public

Pour le dernier film, vous voyez que les cellules ont été fusionnées : elles ne font plus qu'une. C'est exactement l'effet qu'on cherche à obtenir.

Pour effectuer une fusion, on rajoute un attribut à la balise <td>. Il faut savoir qu'il existe deux types de fusion :

    • La fusion de colonnes : c'est ce que je viens de faire dans cet exemple. La fusion s'effectue horizontalement.

On utilisera l'attribut colspan.

    • La fusion de lignes : là, deux lignes seront groupées entre elles. La fusion s'effectuera verticalement.

On utilisera l'attribut rowspan.

Comme vous le savez, vous devez donner une valeur à l'attribut (que ce soit colspan ou rowspan). Il faut indiquer le nombre de cellules à fusionner entre elles. Dans notre exemple, nous avons fusionné deux cellules : celle de la colonne « Pour enfants ? » et celle de « Pour adolescents ? ». On devra donc écrire :

<td colspan="2">

… qui signifie : « Cette cellule est la fusion de deux cellules ». Il est possible de fusionner plus de cellules à la fois (trois, quatre, cinq… autant que vous voulez).

Voilà le code HTML qui me permet de réaliser la fusion correspondant au tableau précédent :

<table>
   <tr>
       <th>Titre du film</th>
       <th>Pour enfants ?</th>
       <th>Pour adolescents ?</th>
   </tr>
   <tr>
       <td>Massacre à la tronçonneuse</td>
       <td >Non, trop violent</td>
       <td>Oui</td>
   </tr>
   <tr>
       <td>Les bisounours font du ski</td>
       <td>Oui, adapté</td>
       <td>Pas assez violent...</td>
   </tr>
   <tr>
       <td>Lucky Luke, seul contre tous</td>
       <td colspan="2">Pour toute la famille !</td>
   </tr>
</table>

Une remarque importante : vous voyez que la ligne 19 ne contient que deux cellules au lieu de trois (il n'y a que deux balises <td>). C'est tout à fait normal car j'ai fusionné les deux dernières cellules entre elles. Le <td colspan="2"> indique que cette cellule prend la place de deux cellules à la fois.

Et pour la fusion verticale avec rowspan, on fait comment ?

Cela se complique un petit peu. Pour notre exemple, nous allons « inverser » l'ordre de notre tableau : au lieu de mettre les titres de films à gauche, on va les placer en haut.
C'est une autre façon de voir le tableau : au lieu de le construire en hauteur, on peut le construire en longueur.

Dans ce cas, le colspan n'est plus adapté, c'est un rowspan qu'il faut utiliser :

<table>
   <tr>
       <th>Titre du film</th>
       <td>Massacre à la tronçonneuse</td>
       <td>Les bisounours font du ski</td>
       <td>Lucky Luke, seul contre tous</td>
   </tr>
   <tr>
       <th>Pour enfants ?</th>
       <td>Non, trop violent</td>
       <td>Oui, adapté</td>
       <td rowspan="2">Pour toute la famille !</td>
   </tr>
   <tr>
       <th>Pour adolescents ?</th>
       <td>Oui</td>
       <td>Pas assez violent...</td>
   </tr>
</table>

Résultat : les cellules sont fusionnées verticalement (figure suivante) !

Les cellules ont été fusionnées verticalement
Les cellules ont été fusionnées verticalement

Notez qu'on peut modifier l'alignement vertical du texte des cellules de tableaux avec la propriété vertical-align que nous avons découverte dans le chapitre sur la mise en page.

En résumé

  • Un tableau s'insère avec la balise <table> et se définit ligne par ligne avec <tr>.

  • Chaque ligne comporte des cellules <td> (cellules normales) ou <th> (cellules d'en-tête).

  • Le titre du tableau se définit avec <caption>.

  • On peut ajouter une bordure aux cellules du tableau avec border. Pour fusionner les bordures, on utilise la propriété CSS border-collapse.

  • Un tableau peut être divisé en trois sections : <thead> (en-tête), <tbody> (corps) et <tfoot> (bas du tableau). L'utilisation de ces balises n'est pas obligatoire.

  • On peut fusionner des cellules horizontalement avec l'attribut colspan ou verticalement avec rowspan. Il faut indiquer combien de cellules doivent être fusionnées.


Tutoriel VBScript

Les formulaires

https://vimeo.com/76812669

Toute page HTML peut être enrichie de formulaires interactifs, qui invitent vos visiteurs à renseigner des informations : saisir du texte, sélectionner des options, valider avec un bouton… tout est possible !

Nous arrivons cependant aux limites du langage HTML car il faut ensuite pouvoir analyser les informations que le visiteur a saisies… et cela ne peut pas se faire en langage HTML. Comme nous allons le voir, le traitement des résultats doit s'effectuer dans un autre langage, par exemple le PHP.

En attendant, nous avons un grand nombre de nouvelles balises HTML à découvrir. Bienvenue dans le monde merveilleux des formulaires, un monde où les boutons, les cases à cocher et les listes déroulantes vivent en harmonie (enfin presque).

Créer un formulaire

Lorsqu'il vous prend subitement l'envie d'insérer un formulaire dans votre page HTML, vous devez pour commencer écrire une balise <form> </form>. C'est la balise principale du formulaire, elle permet d'en indiquer le début et la fin.

<p>Texte avant le formulaire</p>

<form>
   <p>Texte à l'intérieur du formulaire</p>
</form>

<p>Texte après le formulaire</p>

Notez qu'il faut obligatoirement mettre des balises de type block (comme <p> </p>) à l'intérieur de votre formulaire si vous souhaitez y faire figurer du texte.

Voilà pour la structure de base. Maintenant, soyez attentifs : ce que j'ai à vous dire n'est pas évident parce qu'on est à la limite du HTML.

On va prendre un exemple pour que les choses soient claires. Supposons que votre visiteur vienne de taper un commentaire dans votre formulaire, par exemple un message qu'il aimerait publier sur vos forums. Ce message doit être envoyé pour que vous puissiez le recevoir (logique, non ?) et l'afficher pour vos autres visiteurs.

Eh bien c'est là le problème, ou plutôt les problèmes, que l'on va se poser :

  • Problème n°1 : comment envoyer le texte saisi par le visiteur ? Par quel moyen ?

  • Problème n°2 : une fois que les données ont été envoyées, comment les traiter ? Souhaitez-vous recevoir le message automatiquement par mail ou préférez-vous qu'un programme se charge de l'enregistrer quelque part, puis de l'afficher sur une page visible par tout le monde ?

Pour fournir les réponses à ces deux problèmes, vous devez ajouter deux attributs à la balise <form> :

  • method : cet attribut indique par quel moyen les données vont être envoyées (réponse au problème n°1). Il existe deux solutions pour envoyer des données sur le Web :

    • method="get" : c'est une méthode en général assez peu adaptée car elle est limitée à 255 caractères. La particularité vient du fait que les informations seront envoyées dans l'adresse de la page (http://…), mais ce détail ne nous intéresse pas vraiment pour le moment. La plupart du temps, je vous recommande d'utiliser l'autre méthode : post.

    • method="post" : c'est la méthode la plus utilisée pour les formulaires car elle permet d'envoyer un grand nombre d'informations. Les données saisies dans le formulaire ne transitent pas par la barre d'adresse.

  • action : c'est l'adresse de la page ou du programme qui va traiter les informations (réponse au problème n°2). Cette page se chargera de vous envoyer un e-mail avec le message si c'est ce que vous voulez, ou bien d'enregistrer le message avec tous les autres dans une base de données.
    Cela ne peut pas se faire en HTML et CSS, on utilisera en général un autre langage dont vous avez peut-être entendu parler : PHP.

On va donc maintenant compléter la balise <form> avec les deux attributs qu'on vient de voir.

Pour method, vous l'aurez deviné, je vais mettre la valeur post.
Pour action, je vais taper le nom d'une page fictive en PHP (traitement.php). C'est cette page qui sera appelée lorsque le visiteur cliquera sur le bouton d'envoi du formulaire.

<p>Texte avant le formulaire</p>

<form method="post" action="traitement.php">
   <p>Texte à l'intérieur du formulaire</p>
</form>

<p>Texte après le formulaire</p>

Pour le moment, on ne sait pas ce qu'il se passe à l'intérieur de la page traitement.php : je vous demande de me faire confiance et d'imaginer que cette page existe et fonctionne.

Notre priorité, pour le moment, est de découvrir en HTML/CSS comment faire pour insérer des zones de texte, des boutons et des cases à cocher dans votre page web. C'est ce que nous allons voir maintenant.

Les zones de saisie basiques

Bien, retour au concret.

Nous allons passer en revue les différentes balises HTML permettant de saisir du texte dans un formulaire.
Il faut savoir qu'il y a deux zones de texte différentes :

  • La zone de texte monoligne : comme son nom l'indique, on ne peut y écrire qu'une seule ligne. Elle sert à saisir des textes courts, par exemple un pseudo.

  • La zone de texte multiligne : cette zone de texte permet d'écrire une quantité importante de texte sur plusieurs lignes, par exemple une dissertation sur l'utilité du HTML dans le développement des pays d'Asie du Sud-Est (ce n'est qu'une suggestion hein…).

Zone de texte monoligne

La figure suivante montre à quoi ressemble une zone de texte monoligne.

Une zone de texte monoligne
Une zone de texte monoligne

Pour insérer une zone de texte dans une ligne, on va utiliser la balise <input />.

On retrouvera cette balise plusieurs fois dans la suite de ce chapitre. À chaque fois, c'est la valeur de son attribut type qui va changer.

Pour créer une zone de texte à une ligne, on doit écrire :

<input type="text" />

Ce n'est pas encore suffisant : il faut donner un nom à votre zone de texte. Ce nom n'apparaît pas sur la page mais il vous sera indispensable par la suite. En effet, cela vous permettra (en PHP par exemple) de reconnaître d'où viennent les informations : vous saurez que tel texte est le pseudo du visiteur, tel texte est le mot de passe qu'il a choisi, etc.

Pour donner un nom à un élément de formulaire, on utilise l'attribut name. Ici, on va supposer qu'on demande au visiteur de rentrer son pseudo :

<input type="text" name="pseudo" />

Essayons donc de créer un formulaire très basique avec notre champ de texte :

<form method="post" action="traitement.php">
   <p><input type="text" name="pseudo" /></p>
</form>

Comme d'habitude, je vous invite fortement à essayer ce code chez vous afin d'observer le résultat.

Les libellés

Cette zone de texte est bien jolie mais si votre visiteur tombe dessus, il ne sait pas ce qu'il doit écrire. C'est justement le rôle de la balise <label> :

<form method="post" action="traitement.php">
    <p>
        <label>Votre pseudo</label> : <input type="text" name="pseudo" />
    </p>
</form>

Ce code donne exactement le résultat que vous avez pu observer à la figure précédente.

Mais cela ne suffit pas. Il faut lier le label à la zone de texte.
Pour ce faire, on doit donner un nom à la zone de texte, non pas avec l'attribut name mais avec l'attribut id (que l'on peut utiliser sur toutes les balises).

Un name et un id sur le champ ? Cela ne va-t-il pas faire double emploi ?

Si, un peu. Personnellement, je donne la même valeur au name et à l'id, cela ne pose pas de problème.

Pour lier le label au champ, il faut lui donner un attribut for qui a la même valeur que l'id du champ… Le mieux est de le voir sur un exemple :

<form method="post" action="traitement.php">
   <p>
       <label for="pseudo">Votre pseudo</label> : <input type="text" name="pseudo" id="pseudo" />
   </p>
</form>

Essayez de cliquer sur le texte « Votre pseudo » : vous allez voir que le curseur se place automatiquement dans la zone de texte correspondante.

Quelques attributs supplémentaires

On peut ajouter un certain nombre d'autres attributs à la balise <input /> pour personnaliser son fonctionnement :

  • On peut agrandir le champ avec size.

  • On peut limiter le nombre de caractères que l'on peut saisir avec maxlength.

  • On peut pré-remplir le champ avec une valeur par défaut à l'aide de value.

  • On peut donner une indication sur le contenu du champ avec placeholder. Cette indication disparaîtra dès que le visiteur aura cliqué à l'intérieur du champ.

Dans l'exemple suivant, la zone de texte contient une indication permettant de comprendre ce qu'il faut saisir ; le champ fait 30 caractères de long mais on ne peut écrire que 10 caractères maximum à l'intérieur :

<form method="post" action="traitement.php">
    <p>
        <label for="pseudo">Votre pseudo :</label>
        <input type="text" name="pseudo" id="pseudo" placeholder="Ex : Zozor" size="30" maxlength="10" />
    </p>
</form>

Testez vous-mêmes le résultat pour observer le comportement du champ. En attendant, voici le rendu du champ dans son état initial en figure suivante.

Un champ de texte avec une indication (placeholder) Un champ de texte avec une indication (placeholder)

Zone de mot de passe

Vous pouvez facilement faire en sorte que la zone de texte se comporte comme une « zone de mot de passe », c'est-à-dire une zone où on ne voit pas à l'écran les caractères saisis. Pour créer ce type de zone de saisie, utilisez l'attribut type="password".

Je complète mon formulaire. Il demande maintenant au visiteur son pseudo et son mot de passe :

<form method="post" action="traitement.php">
   <p>
       <label for="pseudo">Votre pseudo :</label>
       <input type="text" name="pseudo" id="pseudo" />

       <br />
       <label for="pass">Votre mot de passe :</label>
       <input type="password" name="pass" id="pass" />

   </p>
</form>

Testez la zone de mot de passe : vous verrez que les caractères ne s'affichent pas à l'écran, comme sur la figure suivante.

Une zone de saisie de mot de passe Une zone de saisie de mot de passe

Zone de texte multiligne

Pour créer une zone de texte multiligne, on change de balise : nous allons utiliser <textarea> </textarea>.

Comme pour tout autre élément du formulaire, il faut lui donner un nom avec name et utiliser un label qui explique de quoi il s'agit.

<form method="post" action="traitement.php">
   <p>
       <label for="ameliorer">Comment pensez-vous que je pourrais améliorer mon site ?</label><br />
       <textarea name="ameliorer" id="ameliorer"></textarea>
   </p>
</form>

Et voici le résultat en image (figure suivante) !

Une (petite) zone de saisie multiligne
Une (petite) zone de saisie multiligne

Comme vous pouvez le constater, c'est un peu petit ! Heureusement, on peut modifier la taille du <textarea> de deux façons différentes.

  • En CSS : il suffit d'appliquer les propriétés CSS width et height au <textarea>.

  • Avec des attributs : on peut ajouter les attributs rows et cols à la balise <textarea>. Le premier indique le nombre de lignes de texte qui peuvent être affichées simultanément, et le second le nombre de colonnes.

Pourquoi ouvre-t-on la balise <textarea> pour la fermer juste après ?

Vous pouvez pré-remplir le <textarea> avec une valeur par défaut. Dans ce cas, on n'utilise pas l'attribut value : on écrit tout simplement le texte par défaut entre la balise ouvrante et la balise fermante !

<form method="post" action="traitement.php">
   <p>
       <label for="ameliorer">
       Comment pensez-vous que je puisse améliorer mon site ?
       </label>
       <br />

       <textarea name="ameliorer" id="ameliorer" rows="10" cols="50">
       Améliorer ton site ?!
       Mais enfin ! Il est tellement génialissime qu'il n'est pas nécessaire de l'améliorer !
       </textarea>
   </p>
</form>

Et voici le résultat à la figure suivante.

Une zone de saisie multiligne pré-remplie
Une zone de saisie multiligne pré-remplie

Les zones de saisie enrichies

HTML5 apporte de nombreuses fonctionnalités nouvelles relatives aux formulaires. De nouveaux types de champs sont en effet apparus avec cette version. Il suffit de donner à l'attribut type de la balise <input /> l'une des nouvelles valeurs disponibles. Faisons un petit tour d'horizon !

Tous les navigateurs ne connaissent pas encore ces zones de saisie enrichies. À leur place, les anciennes versions des navigateurs afficheront une simple zone de saisie monoligne (comme si on avait écrit type="text"). Entre nous, c'est parfait : les nouveaux navigateurs peuvent profiter des dernières fonctionnalités, tandis que les anciens affichent une zone de texte de remplacement qui convient tout aussi bien.
Vous avez donc tout intérêt à utiliser ces nouvelles zones de saisie dès aujourd'hui ! Au mieux, vos visiteurs profiteront des nouvelles fonctionnalités, au pire, ils ne verront aucun problème.

E-mail

Vous pouvez demander à saisir une adresse e-mail :

<input type="email" />

Le champ vous semblera a priori identique mais votre navigateur sait désormais que l'utilisateur doit saisir une adresse e-mail. Il peut afficher une indication si l'adresse n'est pas un e-mail, c'est ce que fait Firefox par exemple (figure suivante).

Un champ e-mail mal renseigné est entouré de rouge dans Firefox
Un champ e-mail mal renseigné est entouré de rouge dans Firefox

Sachez que certains navigateurs, comme les navigateurs mobiles sur iPhone et Android, affichent un clavier adapté à la saisie d'e-mail (figure suivante).

Clavier de saisie d'e-mail sur un iPhone
Clavier de saisie d'e-mail sur un iPhone

Une URL

Avec le type url, on peut demander à saisir une adresse absolue (commençant généralement par http://) :

<input type="url" />

Même principe : si le champ ne vous semble pas différent sur votre ordinateur, sachez que celui-ci comprend bel et bien que le visiteur est censé saisir une adresse. Les navigateurs mobiles affichent par exemple un clavier adapté à la saisie d'URL (figure suivante).

Clavier de saisie d'URL sur iPhone
Clavier de saisie d'URL sur iPhone

Numéro de téléphone

Ce champ est dédié à la saisie de numéros de téléphone :

<input type="tel" />

Sur iPhone, par exemple, un clavier adapté s'affiche lorsqu'on doit remplir le champ (figure suivante).

Clavier de saisie de numéro de téléphone sur un iPhone
Clavier de saisie de numéro de téléphone sur un iPhone

Nombre

Ce champ permet de saisir un nombre entier :

<input type="number" />

Le champ s'affichera en général avec des petites flèches pour changer la valeur (figure suivante).

Champ de saisie de nombre Champ de saisie de nombre

Vous pouvez personnaliser le fonctionnement du champ avec les attributs suivants :

  • min : valeur minimale autorisée.

  • max : valeur maximale autorisée.

  • step : c'est le « pas » de déplacement. Si vous indiquez un pas de 2, le champ n'acceptera que des valeurs de 2 en 2 (par exemple 0, 2, 4, 6…).

Un curseur

Le type range permet de sélectionner un nombre avec un curseur (aussi appelé slider), comme à la figure suivante :

<input type="range" />

Un curseur grâce au type range Un curseur grâce au type range

Vous pouvez utiliser là aussi les attributs min, max et step pour restreindre les valeurs disponibles.

Couleur

Ce champ permet de saisir une couleur :

<input type="color" />

En pratique, il reste assez peu mis en œuvre par les navigateurs à l'heure actuelle. Ne vous étonnez pas si vous voyez seulement un champ de texte classique.

Date

Différents types de champs de sélection de date existent :

  • date : pour la date (05/08/1985 par exemple) ;

  • time : pour l'heure (13:37 par exemple) ;

  • week : pour la semaine ;

  • month : pour le mois ;

  • datetime : pour la date et l'heure (avec gestion du décalage horaire) ;

  • datetime-local pour la date et l'heure (sans gestion du décalage horaire).

Exemple :

<input type="date" />

Comme vous le voyez, il y a le choix !
À l'heure actuelle, peu de navigateurs gèrent ce type de champ à part Opera.

Recherche

On peut créer un champ de recherche comme ceci :

<input type="search" />

Le navigateur décide ensuite comment afficher le champ de recherche. Ainsi, il peut ajouter une petite loupe au champ pour signifier que c'est un champ de recherche et éventuellement mémoriser les dernières recherches effectuées par le visiteur.

Les éléments d'options

HTML vous offre une ribambelle d'éléments d'options à utiliser dans votre formulaire. Ce sont des éléments qui demandent au visiteur de faire un choix parmi une liste de possibilités. Nous allons passer en revue :

  • les cases à cocher ;

  • les zones d'options ;

  • les listes déroulantes.

Les cases à cocher

Créer une case à cocher ? Rien de plus simple ! Nous allons réutiliser la balise <input />, en spécifiant cette fois le type checkbox :

<input type="checkbox" name="choix" />

Rajoutez un <label> bien placé, et le tour est joué !

<form method="post" action="traitement.php">
   <p>
       Cochez les aliments que vous aimez manger :<br />
       <input type="checkbox" name="frites" id="frites" /> <label for="frites">Frites</label><br />
       <input type="checkbox" name="steak" id="steak" /> <label for="steak">Steak haché</label><br />
       <input type="checkbox" name="epinards" id="epinards" /> <label for="epinards">Epinards</label><br />
       <input type="checkbox" name="huitres" id="huitres" /> <label for="huitres">Huitres</label>
   </p>
</form>

Et voici le résultat en figure suivante.

Des cases à cocher
Des cases à cocher

N'oubliez pas de donner un nom différent à chaque case à cocher, cela vous permettra d'identifier plus tard lesquelles ont été cochées par le visiteur.

Enfin, sachez que vous pouvez faire en sorte qu'une case soit cochée par défaut avec l'attribut checked :

<input type="checkbox" name="choix" checked />

Normalement, tout attribut possède une valeur. Dans le cas présent, en revanche, ajouter une valeur n'est pas obligatoire : la présence de l'attribut suffit à faire comprendre à l'ordinateur que la case doit être cochée.
Si cela vous perturbe, sachez que vous pouvez donner n'importe quelle valeur à l'attribut (certains webmasters écrivent parfois checked="checked" mais c'est un peu redondant !). Dans tous les cas, la case sera cochée.

Les zones d'options

Les zones d'options vous permettent de faire un choix (et un seul) parmi une liste de possibilités. Elles ressemblent un peu aux cases à cocher mais il y a une petite difficulté supplémentaire : elles doivent être organisées en groupes. Les options d'un même groupe possèdent le même nom (name), mais chaque option doit avoir une valeur (value) différente.

La balise à utiliser est toujours un <input />, avec cette fois la valeur radio pour l'attribut type.

Les choses seront plus claires sur l'exemple ci-dessous :

<form method="post" action="traitement.php">
   <p>
       Veuillez indiquer la tranche d'âge dans laquelle vous vous situez :<br />
       <input type="radio" name="age" value="moins15" id="moins15" /> <label for="moins15">Moins de 15 ans</label><br />
       <input type="radio" name="age" value="medium15-25" id="medium15-25" /> <label for="medium15-25">15-25 ans</label><br />
       <input type="radio" name="age" value="medium25-40" id="medium25-40" /> <label for="medium25-40">25-40 ans</label><br />
       <input type="radio" name="age" value="plus40" id="plus40" /> <label for="plus40">Encore plus vieux que ça ?!</label>
   </p>
</form>

Ce qui nous donne la figure suivante.

Des boutons radio
Des boutons radio

Pourquoi avoir mis le même nom pour chaque option ? Tout simplement pour que le navigateur sache de quel « groupe » le bouton fait partie.
Essayez d'enlever les attributs name, vous verrez qu'il devient possible de sélectionner tous les éléments d'options. Or, ce n'est pas ce que l'on veut, c'est pour cela qu'on les « lie » entre eux en leur donnant un nom identique.

Vous noterez que cette fois on a choisi un id différent de name. En effet, les valeurs de name étant identiques, on n'aurait pas pu différencier les id (et vous savez bien qu'un id doit être unique !). Voilà donc pourquoi on a choisi de donner à l'id la même valeur que value.

Si vous avez deux zones d'options différentes, il faut donner un name unique à chaque groupe, comme ceci :

<form method="post" action="traitement.php">
   <p>
       Veuillez indiquer la tranche d'âge dans laquelle vous vous situez :<br />
       <input type="radio" name="age" value="moins15" id="moins15" /> <label for="moins15">Moins de 15 ans</label><br />
       <input type="radio" name="age" value="medium15-25" id="medium15-25" /> <label for="medium15-25">15-25 ans</label><br />
       <input type="radio" name="age" value="medium25-40" id="medium25-40" /> <label for="medium25-40">25-40 ans</label><br />
       <input type="radio" name="age" value="plus40" id="plus40" /> <label for="plus40">Encore plus vieux que ça ?!</label>
   </p>
   <p>
       Sur quel continent habitez-vous ?<br />
       <input type="radio" name="continent" value="europe" id="europe" /> <label for="europe">Europe</label><br />
       <input type="radio" name="continent" value="afrique" id="afrique" /> <label for="afrique">Afrique</label><br />
       <input type="radio" name="continent" value="asie" id="asie" /> <label for="asie">Asie</label><br />
       <input type="radio" name="continent" value="amerique" id="amerique" /> <label for="amerique">Amérique</label><br />
       <input type="radio" name="continent" value="australie" id="australie" /> <label for="australie">Australie</label>
   </p>
</form>

L'attribut checked est, là aussi, disponible pour sélectionner une valeur par défaut.

Les listes déroulantes

Les listes déroulantes sont un autre moyen élégant de faire un choix parmi plusieurs possibilités. Le fonctionnement est un peu différent. On va utiliser la balise <select> </select> qui indique le début et la fin de la liste déroulante. On ajoute l'attribut name à la balise pour donner un nom à la liste.

Puis, à l'intérieur du <select> </select>, nous allons placer plusieurs balises <option> </option> (une par choix possible). On ajoute à chacune d'elles un attribut value pour pouvoir identifier ce que le visiteur a choisi.

Voici un exemple d'utilisation :

<form method="post" action="traitement.php">
   <p>
       <label for="pays">Dans quel pays habitez-vous ?</label><br />
       <select name="pays" id="pays">
           <option value="france">France</option>
           <option value="espagne">Espagne</option>
           <option value="italie">Italie</option>
           <option value="royaume-uni">Royaume-Uni</option>
           <option value="canada">Canada</option>
           <option value="etats-unis">États-Unis</option>
           <option value="chine">Chine</option>
           <option value="japon">Japon</option>
       </select>
   </p>
</form>

Le résultat obtenu est représenté à la figure suivante.

Une liste déroulante Une liste déroulante

Si vous voulez qu'une option soit sélectionnée par défaut, utilisez cette fois l'attribut selected :

<option value="canada" selected>Canada</option>

Vous pouvez aussi grouper vos options avec la balise <optgroup> </optgroup>. Dans notre exemple, pourquoi ne pas séparer les pays en fonction de leur continent ?

<form method="post" action="traitement.php">
   <p>
       <label for="pays">Dans quel pays habitez-vous ?</label><br />
       <select name="pays" id="pays">
           <optgroup label="Europe">
               <option value="france">France</option>
               <option value="espagne">Espagne</option>
               <option value="italie">Italie</option>
               <option value="royaume-uni">Royaume-Uni</option>
           </optgroup>
           <optgroup label="Amérique">
               <option value="canada">Canada</option>
               <option value="etats-unis">Etats-Unis</option>
           </optgroup>
           <optgroup label="Asie">
               <option value="chine">Chine</option>
               <option value="japon">Japon</option>
           </optgroup>
       </select>
   </p>
</form>

Le résultat obtenu est représenté à la figure suivante.

Les options sont regroupées par continent Les options sont regroupées par continent

Les groupes ne peuvent pas être sélectionnés. Ainsi, dans notre exemple, on ne peut pas choisir « Europe » : seuls les noms de pays sont disponibles pour la sélection.

Finaliser et envoyer le formulaire

Nous y sommes presque. Il ne nous reste plus qu'à agrémenter notre formulaire de quelques dernières fonctionnalités (comme la validation), puis nous pourrons ajouter le bouton d'envoi du formulaire.

Regrouper les champs

Si votre formulaire grossit et comporte beaucoup de champs, il peut être utile de les regrouper au sein de plusieurs balises <fieldset>. Chaque <fieldset> peut contenir une légende avec la balise <legend>. Regardez cet exemple :

<form method="post" action="traitement.php">

   <fieldset>
       <legend>Vos coordonnées</legend> <!-- Titre du fieldset -->

       <label for="nom">Quel est votre nom ?</label>
       <input type="text" name="nom" id="nom" />

       <label for="prenom">Quel est votre prénom ?</label>
       <input type="text" name="prenom" id="prenom" />

       <label for="email">Quel est votre e-mail ?</label>
       <input type="email" name="email" id="email" />

   </fieldset>

   <fieldset>
       <legend>Votre souhait</legend> <!-- Titre du fieldset -->

       <p>
           Faites un souhait que vous voudriez voir exaucé :

           <input type="radio" name="souhait" value="riche" id="riche" /> <label for="riche">Etre riche</label>
           <input type="radio" name="souhait" value="celebre" id="celebre" /> <label for="celebre">Etre célèbre</label>
           <input type="radio" name="souhait" value="intelligent" id="intelligent" /> <label for="intelligent">Etre <strong>encore</strong> plus intelligent</label>
           <input type="radio" name="souhait" value="autre" id="autre" /> <label for="autre">Autre...</label>
       </p>

       <p>
           <label for="precisions">Si "Autre", veuillez préciser :</label>
           <textarea name="precisions" id="precisions" cols="40" rows="4"></textarea>
       </p>
   </fieldset>
</form>

Le résultat obtenu est représenté à la figure suivante.

Les champs sont regroupés Les champs sont regroupés

Sélectionner automatiquement un champ

Vous pouvez placer automatiquement le curseur dans l'un des champs de votre formulaire avec l'attribut autofocus. Dès que le visiteur chargera la page, le curseur se placera dans ce champ.

Par exemple, pour que le curseur soit par défaut dans le champ prenom :

<input type="text" name="prenom" id="prenom" autofocus />

Rendre un champ obligatoire

Vous pouvez faire en sorte qu'un champ soit obligatoire en lui donnant l'attribut required.

<input type="text" name="prenom" id="prenom" required />

Le navigateur indiquera alors au visiteur, si le champ est vide au moment de l'envoi, qu'il doit impérativement être rempli.

Les anciens navigateurs, qui ne reconnaissent pas cet attribut, enverront le contenu du formulaire sans vérification. Pour ces navigateurs, il sera nécessaire de compléter les tests avec, par exemple, des scripts JavaScript.

On dispose de pseudo-formats en CSS pour changer le style des éléments requis (:required) et invalides (:invalid). N'oubliez pas non plus que vous disposez du pseudo-format :focus pour changer l'apparence d'un champ lorsque le curseur se trouve à l'intérieur.

:required
{
    background-color: red;
}

Le bouton d'envoi

Il ne nous reste plus qu'à créer le bouton d'envoi. Là encore, la balise <input /> vient à notre secours. Elle existe en quatre versions :

  • type="submit" : le principal bouton d'envoi de formulaire. C'est celui que vous utiliserez le plus souvent. Le visiteur sera conduit à la page indiquée dans l'attribut action du formulaire.

  • type="reset" : remise à zéro du formulaire.

  • type="image" : équivalent du bouton submit, présenté cette fois sous forme d'image. Rajoutez l'attribut src pour indiquer l'URL de l'image.

  • type="button" : bouton générique, qui n'aura (par défaut) aucun effet. En général, ce bouton est géré en JavaScript pour exécuter des actions sur la page. Nous ne l'utiliserons pas ici.

On peut changer le texte affiché à l'intérieur des boutons avec l'attribut value.

Pour créer un bouton d'envoi on écrira donc par exemple :

<input type="submit" value="Envoyer" />

Ce qui nous donne la figure suivante.

Un bouton d'envoi
Un bouton d'envoi

Lorsque vous cliquez sur le bouton « Envoyer », le formulaire vous amène alors à la page indiquée dans l'attribut action. Souvenez-vous, nous avions imaginé une page fictive : traitement.php.

Le problème, c'est que vous ne pouvez pas créer cette page seulement en HTML. Il est nécessaire d'apprendre un nouveau langage, comme le PHP, pour pouvoir « récupérer » les informations saisies et décider quoi en faire. Cela tombe bien, j'ai aussi rédigé un cours sur le langage PHP pour ceux que cela intéresse ! Ce cours existe également en livre : Concevez votre site web avec PHP et MySQL, de Mathieu Nebra, paru chez Simple IT dans la collection le Livre du Zéro, ISBN 978-2-9535278-1-0.

Certains sites comme swisstools.net proposent des services appelés « MailForm » qui se chargent de vous envoyer un e-mail lorsqu'un de vos visiteurs a rempli le formulaire. Cela vous dispense d'apprendre un nouveau langage mais ce n'est pas très pratique : vous devrez soit payer, soit voir de la publicité… et vous n'avez pas beaucoup de possibilités de personnaliser le traitement des données.

En résumé

  • Un formulaire est une zone interactive de la page, dans laquelle vos visiteurs peuvent saisir des informations.

  • On délimite un formulaire avec la balise <form> à laquelle il faut ajouter deux attributs : method (mode d'envoi des données) et action (page vers laquelle le visiteur sera redirigé après envoi du formulaire et qui traitera les informations).

  • Une grande partie des éléments du formulaire peut s'insérer avec la balise <input />. La valeur de son attribut type permet d'indiquer quel type de champ doit être inséré :

    • text : zone de texte ;

    • password : zone de texte pour mot de passe ;

    • tel : numéro de téléphone ;

    • checkbox : case à cocher ;

    • etc.

  • La balise <label> permet d'écrire un libellé. On l'associe à un champ de formulaire avec l'attribut for, qui doit avoir la même valeur que l'id du champ de formulaire.

  • On peut rendre un champ obligatoire avec l'attribut required, faire en sorte qu'il soit sélectionné par défaut avec autofocus, donner une indication dans le champ avec placeholder…

  • Pour récupérer ce que les visiteurs ont saisi, le langage HTML ne suffit pas. Il faut utiliser un langage « serveur » comme PHP… Si vous voulez aller plus loin, il va donc falloir apprendre un nouveau langage !


Tutoriel VBScript

La vidéo et l'audio

https://vimeo.com/76812708

Depuis l'arrivée de Youtube et Dailymotion, il est devenu courant aujourd'hui de regarder des vidéos sur des sites web. Il faut dire que l'arrivée du haut débit a aidé à démocratiser les vidéos sur le Web.

Cependant, aucune balise HTML ne permettait jusqu'ici de gérer la vidéo. Il fallait à la place utiliser un plugin, comme Flash. Encore aujourd'hui, Flash reste de loin le moyen le plus utilisé pour regarder des vidéos sur Youtube, Dailymotion, Vimeo et ailleurs. Mais utiliser un plugin a de nombreux défauts : on dépend de ceux qui gèrent le plugin (en l'occurence, l'entreprise Adobe, qui possède Flash), on ne peut pas toujours contrôler son fonctionnement, il y a parfois des failles de sécurité… Au final, c'est assez lourd.

C'est pour cela que deux nouvelles balises standard ont été créées en HTML5 : <video> et <audio> !

Les formats audio et vidéo

Lorsque je vous ai présenté les images et la balise <img />, j'ai commencé par un petit tour d'horizon des différents formats d'images (JPEG, PNG, GIF, etc.). Pour la vidéo et l'audio, je vais faire pareil… mais c'est plus compliqué.

En fait, le fonctionnement des vidéos est même tellement complexe qu'on pourrait faire un cours entier à ce sujet ! Étant donné qu'on parle ici de HTML, nous n'allons pas passer toutes nos prochaines nuits à étudier les subtilités de l'encodage vidéo. Je vais donc simplifier les choses et vous expliquer juste ce que vous avez besoin de savoir.

Les formats audio

Pour diffuser de la musique ou n'importe quel son, il existe de nombreux formats. La plupart d'entre eux sont compressés (comme le sont les images JPEG, PNG et GIF) ce qui permet de réduire leur poids :

  • MP3 : vous ne pouvez pas ne pas en avoir entendu parler ! C'est l'un des plus vieux, mais aussi l'un des plus compatibles (tous les appareils savent lire des MP3), ce qui fait qu'il est toujours très utilisé aujourd'hui.

  • AAC : utilisé majoritairement par Apple sur iTunes, c'est un format de bonne qualité. Les iPod, iPhone et autres iPad savent les lire sans problème.

  • OGG : le format Ogg Vorbis est très répandu dans le monde du logiciel libre, notamment sous Linux. Ce format a l'avantage d'être libre, c'est-à-dire qu'il n'est protégé par aucun brevet.

  • WAV (format non compressé) : évitez autant que possible de l'utiliser car le fichier est très volumineux avec ce format. C'est un peu l'équivalent du Bitmap (BMP) pour l'audio.

Aucun navigateur ne gère tous ces formats à la fois. Retenez surtout la compatibilité pour les MP3 et OGG :

Navigateur | MP3 | OGG
Internet Explorer | Oui | -
Chrome | Oui | Oui
Firefox | - | Oui
Safari | Oui | -
Opera | - | Oui

Il n'y a pas de format « idéal » reconnu par tous les navigateurs ?

Eh non ! Heureusement, on pourra proposer différents formats aux navigateurs qui sélectionneront alors celui qu'ils savent lire.

Les formats vidéo

Le stockage de la vidéo est autrement plus complexe. On a besoin de trois éléments :

  • Un format conteneur : c'est un peu comme une boîte qui va servir à contenir les deux éléments ci-dessous. On reconnaît en général le type de conteneur à l'extension du fichier : AVI, MP4, MKV…

  • Un codec audio : c'est le format du son de la vidéo, généralement compressé. Nous venons de les voir, on utilise les mêmes : MP3, AAC, OGG…

  • Un codec vidéo : c'est le format qui va compresser les images. C'est là que les choses se corsent, car ces formats sont complexes et on ne peut pas toujours les utiliser gratuitement. Les principaux à connaître pour le Web sont :

    • H.264 : l'un des plus puissants et des plus utilisés aujourd'hui… mais il n'est pas 100% gratuit. En fait, on peut l'utiliser gratuitement dans certains cas (comme la diffusion de vidéos sur un site web personnel), mais il y a un flou juridique qui fait qu'il est risqué de l'utiliser à tout va.

    • Ogg Theora : un codec gratuit et libre de droits, mais moins puissant que H.264. Il est bien reconnu sous Linux mais, sous Windows, il faut installer des programmes pour pouvoir le lire.

    • WebM : un autre codec gratuit et libre de droits, plus récent. Proposé par Google, c'est le concurrent le plus sérieux de H.264 à l'heure actuelle.

Quelle est la compatibilité des codecs vidéo sur les différents navigateurs ? Là encore, vous allez voir que c'est un joyeux bazar :

Navigateur | H.264 | Ogg Theora | WebM
Internet Explorer | Oui | - | Oui
Chrome | - | Oui | Oui
Firefox | - | Oui | Oui
Safari | Oui | - | -
Opera | Oui | Oui | Oui

Là encore, aucun format ne sort du lot. Il est conseillé de proposer chaque vidéo dans plusieurs formats pour qu'elle soit lisible sur un maximum de navigateurs.

Pour convertir une vidéo dans ces différents formats, je vous conseille l'excellent logiciel gratuit Miro Video Converter que vous pouvez télécharger grâce au code web ci-dessous.

Il vous suffit de glisser-déposer votre vidéo dans la fenêtre du programme et de sélectionner le format de sortie souhaité. Cela vous permettra de créer plusieurs versions de votre vidéo !

Insertion d'un élément audio

La balise <audio> que nous allons découvrir est reconnue par tous les navigateurs récents, y compris Internet Explorer à partir de la version 9 (IE9).

En théorie, il suffit d'une simple balise pour jouer un son sur notre page :

<audio src="musique.mp3"></audio>

En pratique, c'est un peu plus compliqué que cela.
Si vous testez ce code… vous ne verrez rien ! En effet, le navigateur va seulement télécharger les informations générales sur le fichier (on parle de métadonnées) mais il ne se passera rien de particulier.

Vous pouvez compléter la balise des attributs suivants :

  • controls : pour ajouter les boutons « Lecture », « Pause » et la barre de défilement. Cela peut sembler indispensable, et vous vous demandez peut-être pourquoi cela n'y figure pas par défaut, mais certains sites web préfèrent créer eux-mêmes leurs propres boutons et commander la lecture avec du JavaScript.

  • width : pour modifier la largeur de l'outil de lecture audio.

  • loop : la musique sera jouée en boucle.

  • autoplay : la musique sera jouée dès le chargement de la page. Évitez d'en abuser, c'est en général irritant d'arriver sur un site qui joue de la musique tout seul !

  • preload : indique si la musique peut être préchargée dès le chargement de la page ou non. Cet attribut peut prendre les valeurs :

    • auto (par défaut) : le navigateur décide s'il doit précharger toute la musique, uniquement les métadonnées ou rien du tout.

    • metadata : charge uniquement les métadonnées (durée, etc.).

    • none : pas de préchargement. Utile si vous ne voulez pas gaspiller de bande passante sur votre site.

On ne peut pas forcer le préchargement de la musique, c'est toujours le navigateur qui décide.
Les navigateurs mobiles, par exemple, ne préchargent jamais la musique pour économiser la bande passante (le temps de chargement étant long sur un portable).

Ajoutons les contrôles et ce sera déjà mieux !

<audio src="hype_home.mp3" controls></audio>

L'apparence du lecteur audio change en fonction du navigateur. La figure suivante représente par exemple le lecteur audio dans Google Chrome.

Le lecteur audio dans Google Chrome
Le lecteur audio dans Google Chrome

Pourquoi ouvrir la balise pour la refermer immédiatement après ?

Cela vous permet d'afficher un message ou de proposer une solution de secours pour les navigateurs qui ne gèrent pas cette nouvelle balise. Par exemple :

<audio src="hype_home.mp3" controls>Veuillez mettre à jour votre navigateur !</audio>

Ceux qui ont un navigateur récent ne verront pas le message. Les anciens navigateurs, qui ne comprennent pas la balise, afficheront en revanche le texte qui se trouve à l'intérieur.

Je vous conseille de proposer une solution de secours en Flash, comme Dewplayer. Vous placerez le code correspondant à Flash entre les balises <audio> et </audio> : ainsi, les anciens navigateurs afficheront le lecteur Flash, tandis que les nouveaux afficheront le lecteur natif.

On a vu que certains navigateurs ne géraient pas le MP3, comment faire ?

Il faut proposer plusieurs versions du fichier audio. Dans ce cas, on va construire notre balise comme ceci :

<audio controls>
    <source src="hype_home.mp3">
    <source src="hype_home.ogg">
</audio>

Le navigateur prendra automatiquement le format qu'il reconnaît.
Notez que la balise <source> ne doit pas être fermée (pas de </source> ni de / de fin).

Insertion d'une vidéo

La balise <video⁪⁪⁪> que nous allons découvrir est reconnue par tous les navigateurs récents, y compris Internet Explorer à partir de la version 9 (IE9).

Il suffit d'une simple balise <video⁪⁪⁪> pour insérer une vidéo dans la page :

<video src="sintel.webm"⁪></video⁪⁪>

Mais, là encore, vous risquez d'être déçus si vous utilisez seulement ce code. Aucun contrôle ne permet de lancer la vidéo !

Rajoutons quelques attributs (la plupart sont les mêmes que pour la balise <audio>) :

  • poster : image à afficher à la place de la vidéo tant que celle-ci n'est pas lancée. Par défaut, le navigateur prend la première image de la vidéo mais, comme il s'agit souvent d'une image noire ou d'une image peu représentative de la vidéo, je vous conseille d'en créer une ! Vous pouvez tout simplement faire une capture d'écran d'un moment de la vidéo.

  • controls : pour ajouter les boutons « Lecture », « Pause » et la barre de défilement. Cela peut sembler indispensable, mais certains sites web préfèrent créer eux-mêmes leurs propres boutons et commander la lecture avec du JavaScript. En ce qui nous concerne, ce sera largement suffisant !

  • width : pour modifier la largeur de la vidéo.

  • height : pour modifier la hauteur de la vidéo.

  • loop : la vidéo sera jouée en boucle.

  • autoplay : la vidéo sera jouée dès le chargement de la page. Là encore, évitez d'en abuser, c'est en général irritant d'arriver sur un site qui lance quelque chose tout seul !

  • preload : indique si la vidéo peut être préchargée dès le chargement de la page ou non. Cet attribut peut prendre les valeurs :

    • auto (par défaut) : le navigateur décide s'il doit précharger toute la vidéo, uniquement les métadonnées ou rien du tout.

    • metadata : charge uniquement les métadonnées (durée, dimensions, etc.).

    • none : pas de préchargement. Utile si vous souhaitez éviter le gaspillage de bande passante sur votre site.

On ne peut pas forcer le préchargement de la vidéo, c'est toujours le navigateur qui décide.

Les proportions de la vidéo sont toujours conservées. Si vous définissez une largeur et une hauteur, le navigateur fera en sorte de ne pas dépasser les dimensions indiquées mais il conservera les proportions.

Voici un code un peu plus complet :

<video src="sintel.webm" controls poster="sintel.jpg" width="600">⁪</video⁪⁪>

Et le résultat à la figure suivante.

Une vidéo avec les options de lecture et une taille définie
Une vidéo avec les options de lecture et une taille définie

Pourquoi ouvrir et refermer immédiatement après la balise ?

La réponse est la même que pour la balise <audio>. Cela vous permet d'afficher un message ou d'utiliser une technique de secours (en Flash) si le navigateur ne reconnaît pas la balise :

<video⁪⁪⁪ src="sintel.webm" controls poster="sintel.jpg" width="600">
    Il est temps de mettre à jour votre navigateur !
</video>

Comment contenter tous les navigateurs, puisque chacun reconnaît des formats vidéo différents ?

Vous utiliserez la balise <source> à l'intérieur de la balise <video⁪⁪⁪> pour proposer différents formats. Le navigateur prendra celui qu'il reconnaît :

<video controls poster="sintel.jpg" width="600">
    <source src="sintel.mp4">
    <source src="sintel.webm">
    <source src="sintel.ogv">
</video>

Les iPhone, iPad et iPod ne reconnaissent à l'heure actuelle que le format H.264 (fichier .mp4)… et uniquement si celui-ci apparaît en premier dans la liste ! Je vous recommande donc d'indiquer le format H.264 en premier pour assurer une compatibilité maximale.

Comment afficher la vidéo en plein écran ?

Ce n'est pas possible à l'heure actuelle. En fait, il existe bien un moyen sous Firefox mais il est un peu caché : il faut faire un clic droit sur la vidéo, puis sélectionner « Plein écran ».

Il n'y a pas de moyen de forcer le plein écran, même en JavaScript. Cela peut se comprendre, car des sites pourraient perturber fortement la navigation des visiteurs en affichant des vidéos en plein écran sans leur demander leur accord !

Comment protéger ma vidéo, je ne veux pas qu'on puisse la copier facilement !

Ce n'est pas possible. Les balises n'ont pas été conçues pour limiter ou empêcher le téléchargement. C'est assez logique quand on y pense : pour que le visiteur puisse voir la vidéo, il faut bien de toute façon qu'il la télécharge d'une manière ou d'une autre !

N'espérez donc pas empêcher le téléchargement de votre vidéo avec cette technique.

Les lecteurs vidéo Flash permettent de « protéger » le contenu des vidéos mais, là encore, des solutions de contournement existent. De nombreux plug-ins permettent de télécharger les vidéos, de Youtube par exemple.

En résumé

  • Insérer de la musique ou de la vidéo n'était pas possible autrefois en HTML. Il fallait recourir à un plugin comme Flash.

  • Depuis HTML5, les balises <audio> et <video⁪⁪⁪> ont été introduites et permettent de jouer de la musique et des vidéos sans plugin.

  • Il existe plusieurs formats audio et vidéo. Il faut notamment connaître :

    • pour l'audio : MP3 et Ogg Vorbis ;

    • pour la vidéo : H.264, Ogg Theora et WebM.

  • Aucun format n'est reconnu par l'ensemble des navigateurs : il faut proposer différentes versions de sa musique ou de sa vidéo pour satisfaire tous les navigateurs.

  • Il faut ajouter l'attribut controls aux balises <audio> et <video⁪⁪⁪> pour permettre au visiteur de lancer ou d'arrêter le média.

  • Ces balises ne sont pas conçues pour empêcher le téléchargement de la musique et de la vidéo. Vous ne pouvez pas protéger votre média contre la copie.


Tutoriel VBScript

Mise en page adaptative avec les Media Queries

https://vimeo.com/76812667

Savez-vous quelle est la première préoccupation des webmasters qui mettent en place le design de leur site ? La résolution d'écran de leurs visiteurs. Eh oui : selon les écrans, il y a plus ou moins de place, plus ou moins de pixels de largeur.

Cette information est importante lorsque vous construisez un design : comment votre site doit-il s'afficher en fonction des différentes résolutions d'écran ? Si vous avez un écran large, vous risquez d'oublier que certaines personnes naviguent avec des écrans plus petits. Et je ne vous parle même pas des navigateurs des smartphones, qui sont encore moins larges.

C'est là que les media queries entrent en jeu. Ce sont des règles à appliquer pour changer le design d'un site en fonction des caractéristiques de l'écran ! Grâce à cette technique, nous pourrons créer un design qui s'adapte automatiquement à l'écran de chaque visiteur !

Mise en place des media queries

Les media queries font partie des nouveautés de CSS3. Il ne s'agit pas de nouvelles propriétés mais de règles que l'on peut appliquer dans certaines conditions. Concrètement, vous allez pouvoir dire « Si la résolution de l'écran du visiteur est inférieure à tant, alors applique les propriétés CSS suivantes ». Cela vous permet de changer l'apparence du site dans certaines conditions : vous pourrez augmenter la taille du texte, changer la couleur de fond, positionner différemment votre menu dans certaines résolutions, etc.
Contrairement à ce qu'on pourrait penser, les media queries ne concernent pas que les résolutions d'écran. Vous pouvez changer l'apparence de votre site en fonction d'autres critères comme le type d'écran (smartphone, télévision, projecteur…), le nombre de couleurs, l'orientation de l'écran (portrait ou paysage), etc. Les possibilités sont très nombreuses !

Les media queries fonctionnent sur tous les navigateurs récents, y compris Internet Explorer à partir de la version 9 (IE9).

Appliquer une media query

Les media queries sont donc des règles qui indiquent quand on doit appliquer des propriétés CSS. Il y a deux façons de les utiliser :

  • en chargeant une feuille de style .css différente en fonction de la règle (ex : « Si la résolution est inférieure à 1280px de large, charge le fichier petite_resolution.css ») ;

  • en écrivant la règle directement dans le fichier .css habituel (ex : « Si la résolution est inférieure à 1280px de large, charge les propriétés CSS ci-dessous »).

Chargement d'une feuille de style différente

Vous vous souvenez de la balise <link /> qui permet, dans notre code HTML, de charger un fichier .css ?

<link rel="stylesheet" href="style.css" />

On peut lui ajouter un attribut media, dans lequel on va écrire la règle qui doit s'appliquer pour que le fichier soit chargé. On dit qu'on fait une « requête de media » (media query en anglais). Voici un exemple :

<link rel="stylesheet" media="screen and (max-width: 1280px)" href="petite_resolution.css" />

Au final, votre code HTML pourrait proposer plusieurs fichiers CSS : un par défaut (qui est chargé dans tous les cas) et un ou deux autres qui seront chargés en supplément uniquement si la règle correspondante s'applique.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" href="style.css" /> <!-- Pour tout le monde -->
        <link rel="stylesheet" media="screen and (max-width: 1280px)" href="petite_resolution.css" /> <!-- Pour ceux qui ont une résolution inférieure à 1280px -->
        <title>Media queries</title>
    </head>
Chargement des règles directement dans la feuille de style

Une autre technique, que je préfère personnellement pour des raisons pratiques, consiste à écrire ces règles dans le même fichier CSS que d'habitude.
Dans ce cas, on écrit la règle dans le fichier .css comme ceci :

@media screen and (max-width: 1280px)
{
    /* Rédigez vos propriétés CSS ici */
}

Les règles disponibles

Il existe de nombreuses règles permettant de construire des media queries. Je vous présente ici les principales :

  • color : gestion de la couleur (en bits/pixel).

  • height : hauteur de la zone d'affichage (fenêtre).

  • width : largeur de la zone d'affichage (fenêtre).

  • device-height : hauteur du périphérique.

  • device-width : largeur du périphérique.

  • orientation : orientation du périphérique (portrait ou paysage).

  • media : type d'écran de sortie. Quelques-unes des valeurs possibles :

    • screen : écran « classique » ;

    • handheld : périphérique mobile ;

    • print : impression ;

    • tv : télévision ;

    • projection : projecteur ;

    • all : tous les types d'écran.

On peut rajouter le préfixe min- ou max- devant la plupart de ces règles. Ainsi, min-width signifie « Largeur minimale », max-height « Hauteur maximale », etc.
La différence entre width et device-width se perçoit surtout sur les navigateurs mobiles des smartphones, nous en reparlerons plus loin.

Les règles peuvent être combinées à l'aide des mots suivants :

  • only : « uniquement » ;

  • and : « et » ;

  • not : « non ».

Voici quelques exemples de media queries pour vous aider à bien comprendre le principe.

/* Sur les écrans, quand la largeur de la fenêtre fait au maximum 1280px */
@media screen and (max-width: 1280px)

/* Sur tous types d'écran, quand la largeur de la fenêtre est comprise entre 1024px et 1280px */
@media all and (min-width: 1024px) and (max-width: 1280px)

/* Sur les téléviseurs */
@media tv

/* Sur tous types d'écrans orientés verticalement */
@media all and (orientation: portrait)

Les anciens navigateurs, notamment IE6, IE7 et IE8, ne connaissent pas les media queries mais sont capables d'interpréter le début de la règle (ils savent lire @media screen par exemple). Ils vont donc lire les propriétés CSS qui suivent même s'ils ne sont pas concernés par la règle ! Pour éviter cela, une astuce consiste à utiliser le mot-clé only que ces vieilles versions ne connaissent pas :
« @media only screen » ne provoquera pas de bug sur les vieux navigateurs.

Tester les media queries

Les media queries sont surtout utilisées pour adapter le design du site aux différentes largeurs d'écran.

Faisons un test tout simple : nous allons changer la couleur et la taille du texte si la fenêtre fait plus ou moins de 1024 pixels de large. Pour ce test, je vais utiliser la seconde méthode qui consiste à écrire la règle directement dans le même fichier .css que d'habitude :

/* Paragraphes en bleu par défaut */
p
{
    color: blue;
}

/* Nouvelles règles si la fenêtre fait au plus 1024px de large */
@media screen and (max-width: 1024px)
{
    p
    {
        color: red;
        background-color: black;
        font-size: 1.2em;
    }
}

Dans notre feuille CSS, nous avons d'abord demandé à ce que le texte des paragraphes soit écrit en bleu, jusque là rien de nouveau. En revanche, nous avons ajouté une media query qui s'applique à tous les écrans dont la largeur ne dépasse pas 1024px. À l'intérieur, nous avons appliqué des règles CSS sur les paragraphes pour les écrire plus gros et en rouge.

Résultat : la page n'a pas la même apparence selon la taille de la fenêtre (figure suivante) ! Essayez de la redimensionner pour voir !

Tester ce code

L'apparence du texte change en fonction de la taille de la fenêtre
L'apparence du texte change en fonction de la taille de la fenêtre

Mise en pratique des media queries sur le design

Bon, changer la couleur du texte, c'est bien joli mais cela n'apporte pas grand-chose. Par contre, cela devient de suite plus intéressant quand on se sert des media queries pour modifier l'apparence de son site en fonction de la résolution. Vous allez voir qu'on peut faire tout ce qu'on veut !

Pour cet exemple, je vous propose de reprendre le design que nous avons créé pour le site web de Zozor (figure suivante).

Le site web réalisé lors du TP
Le site web réalisé lors du TP

Le site est bien adapté à la plupart des résolutions d'écran mais, quand l'écran est plus petit que 1024 px, il devient nécessaire de « scroller » vers la droite pour voir toute la page. Le site n'est donc pas très pratique à consulter sur un petit écran.

Je vous propose d'utiliser les media queries pour changer l'apparence du site sur les résolutions inférieures à 1024 px de largeur. Nous allons opérer les modifications suivantes :

  • le menu de navigation en haut à droite sera disposé en hauteur plutôt qu'en largeur, et les liens seront écrits en plus petit ;

  • la bannière avec le pont de San Francisco (le Golden Gate) sera supprimée, car elle prend beaucoup de place et n'apporte pas beaucoup d'informations ;

  • le bloc <aside> « À propos de l'auteur » sera placé sous l'article (et non pas à côté), et son contenu sera réorganisé (la photo de Zozor sera positionnée en flottant).

On pourrait bien entendu faire beaucoup d'autres modifications : changer la couleur, la disposition du pied de page, etc. Mais cela sera déjà bien suffisant pour nous entraîner avec les media queries.

Nous allons travailler directement à l'intérieur du fichier style.css que nous avons réalisé lors du TP. Nous y ajouterons quelques instructions media queries pour adapter le design. Je vous invite à télécharger les fichiers du TP si vous ne les avez pas déjà.

Télécharger le TP

La page

Pour le moment, la largeur de la page est fixée à 900 px et le contenu est centré :

#bloc_page
{
    width: 900px;
    margin: auto;
}

À la suite de ces lignes, je vous propose d'ajouter la règle media query suivante :

@media all and (max-width: 1024px)
{
    #bloc_page
    {
        width: auto;
    }
}

La règle signifie : « Pour tous les types d'écrans, si la largeur de la fenêtre ne dépasse pas 1024 px, alors exécuter les règles CSS suivantes ».

Les règles CSS en question sont très simples, il n'y en a en fait qu'une seule : on donne une largeur automatique à la page (plutôt qu'une largeur fixe de 900 px). La page prendra alors tout l'espace disponible dans la fenêtre. Cela évite l'apparition de barres de défilement horizontales sur les petites résolutions.

auto est la valeur par défaut de la propriété width. Par défaut, les blocs ont une largeur automatique (ils prennent toute la place disponible). Cette valeur « écrase » celle que nous avions forcée à 900px quelques lignes plus haut : nous revenons donc au comportement par défaut du bloc.

Le menu de navigation

Nous voulons que le menu de navigation prenne moins de place sur les petites résolutions. Plutôt que de lui donner une dimension fixe, nous allons lui redonner sa dimension automatique flexible d'origine. Chaque élément du menu s'écrira en dessous du précédent : pour cela, nous transformerons les puces en block plutôt qu'en inline-block.

Enfin, le texte sera écrit plus petit et nous retirons la bordure en bas des liens lors du survol, car elle est moins adaptée à cette disposition.

@media all and (max-width: 1024px)
{
    nav
    {
        width: auto;
        text-align: left;
    }

    nav li
    {
        display: block;
        padding-left: 4px;
    }

    nav a
    {
        font-size: 1.1em;
    }

    nav a:hover
    {
        border-bottom: 0;
    }
}

La bannière

Pour retirer la bannière, rien de plus simple : nous utilisons la propriété display à laquelle nous affectons la valeur none. Si la fenêtre est trop petite, nous préférons masquer complètement la bannière :

@media all and (max-width: 1024px)
{
    #banniere_image
    {
        display: none;
    }
}

Le bloc « À propos de l'auteur »

Plutôt que de placer ce bloc à droite de l'article, nous allons le faire passer en-dessous. Ce type de disposition « de haut en bas » est plus adapté aux petits écrans.

À l'intérieur du bloc, nous réajustons un peu la position des éléments : la photo de Zozor, notamment, sera placée en flottant à droite.

@media all and (max-width: 1024px)
{
    article, aside
    {
        width: auto;
        display: block;
        margin-bottom: 15px;
    }

    #fleche_bulle
    {
        display: none;
    }

    #photo_zozor img
    {
        width: 110px;
        float: right;
        margin-left: 15px;
    }

    aside p:last-child
    {
        text-align: center;
    }
}

Que signifie aside p:last-child ?

C'est un sélecteur avancé que nous n'avons pas utilisé jusqu'ici. aside p signifie « Tous les paragraphes à l'intérieur de la balise <aside> ». Avec :last-child, on cible uniquement le dernier paragraphe dans le bloc aside (celui qui contient les liens vers Facebook et Twitter), pour pouvoir centrer les images. Bien entendu, on aurait aussi pu affecter une class ou un id à ce paragraphe pour le cibler directement, mais je n'ai pas voulu modifier le code HTML.

Le résultat

La page est désormais complètement réorganisée lorsque la fenêtre fait 1024 px ou moins de largeur. Regardez par vous-mêmes le résultat, la figure suivante parle d'elle-même !

Le même site, présenté différemment en fonction de la largeur de l'écran Le même site, présenté différemment en fonction de la largeur de l'écran

Media queries et navigateurs mobiles

Comme vous le savez sûrement, les écrans des smartphones sont beaucoup moins larges que nos écrans habituels (seulement quelques centaines de pixels de large). Pour s'adapter, les navigateurs mobiles affichent le site en « dézoomant », ce qui permet d'avoir un aperçu de l'ensemble de la page. La zone d'affichage simulée est appelée le viewport : c'est la largeur de la fenêtre du navigateur sur le mobile.

En CSS, avec les media queries, si vous ciblez l'écran avec max-width sur un mobile, celui-ci va comparer la largeur que vous indiquez avec celle de son viewport. Le problème, c'est que le viewport change selon le navigateur mobile utilisé !

Navigateur | Largeur du viewport par défaut
Opera Mobile | 850 pixels
iPhone Safari | 980 pixels
Android | 800 pixels
Windows Phone 7 | 1024 pixels

Un iPhone se comporte comme si la fenêtre faisait 980 px de large, tandis qu'un Android se comporte comme si la fenêtre faisait 800 px !

Pour cibler les smartphones, plutôt que d'utiliser max-width, il peut être intéressant de recourir à max-device-width : c'est la largeur du périphérique. Les périphériques mobiles ne dépassant pas 480 px de large, on pourra viser uniquement les navigateurs mobiles avec cette media query :

@media all and (max-device-width: 480px)
{
    /* Vos règles CSS pour les mobiles ici */
}

Pourquoi ne pas cibler les mobiles avec la règle media handheld ?

Je vois que vous suivez, très bien ! En effet, on peut (en théorie) cibler les écrans mobiles avec le media handheld… Malheureusement, aucun navigateur mobile à part Opera mobile ne reconnaît handheld. Ils se comportent tous comme s'ils étaient des écrans normaux (screen). On ne peut donc pas vraiment utiliser handheld pour viser les mobiles.

Vous pouvez modifier la largeur viewport du navigateur mobile avec une balise meta à insérer dans l'en-tête (<head>) du document :

<meta name="viewport" content="width=320" />

Vous pouvez utiliser cette balise pour modifier la façon dont le contenu de votre page s'organise sur les mobiles. Pour obtenir un rendu facile à lire, sans zoom, vous pouvez demander à ce que le viewport soit le même que la largeur de l'écran :

<meta name="viewport" content="width=device-width" />

En résumé

  • Les media queries permettent de charger des styles CSS différents en fonction de certains paramètres.

  • Les paramètres autorisés par les media queries sont nombreux : nombre de couleurs, résolution de l'écran, orientation… En pratique, on s'en sert surtout pour modifier l'apparence du site en fonction des différentes résolutions d'écran.

  • On crée une media query avec la directive @media suivie du type d'écran et d'une ou plusieurs conditions (comme la largeur maximale d'écran). Le style CSS qui suit sera activé uniquement si les conditions sont remplies.

  • Les navigateurs mobiles simulent une largeur d'écran : on appelle cela le viewport.

  • On peut cibler les smartphones grâce à une règle basée sur le nombre réel de pixels affichés à l'écran : max-device-width.


Tutoriel VBScript

Aller plus loin

Alors que ce cours touche à sa fin, la tentation est grande de penser que l'on a tout vu. Tout vu ? Vous n'avez quand même pas cru cela ? Allons bon, il vous reste des centaines de choses à découvrir, que ce soit sur HTML, CSS, ou les technologies qui y sont liées (PHP, JavaScript…).

Ce chapitre a pour but de vous donner quelques directions pour compléter votre apprentissage. Alors ne soyez pas tristes, car vous n'avez pas fini de faire des découvertes !

Du site web à l'application web (JavaScript, AJAX…)

JavaScript est un langage qui existe depuis de nombreuses années maintenant et que l'on utilise fréquemment sur le Web en plus de HTML et CSS. C'est probablement l'un des premiers langages que vous voudrez apprendre maintenant que vous avez des connaissances en HTML et CSS.

À quoi JavaScript peut-il bien servir ? On ne peut pas tout faire avec HTML et CSS ?

On peut faire déjà beaucoup de choses en HTML et CSS mais, lorsqu'on veut rendre sa page plus interactive, un langage comme JavaScript devient indispensable.

Voici quelques exemples de ce à quoi peut servir JavaScript :

  • On l'utilisera le plus souvent pour modifier des propriétés CSS sans avoir à recharger la page. Par exemple, vous pointez sur une image et le fond de votre site change de couleur (ce n'est pas possible à faire avec un :hover car cela concerne deux balises différentes, c'est bien là une limite du CSS).

  • On peut l'utiliser aussi pour modifier le code source HTML sans avoir à recharger la page, pendant que le visiteur consulte la page.

  • Il permet aussi d'afficher des boîtes de dialogue à l'écran du visiteur…

  • … ou encore de modifier la taille de la fenêtre.

JavaScript est un langage qui se rapproche des langages de programmation tels que le C, C++, Python, Ruby… À l'inverse, HTML et CSS sont davantage des langages de description : ils décrivent comment la page doit apparaître mais ils ne donnent pas d'ordres directs à l'ordinateur (« fais ceci, fais cela… »), contrairement à JavaScript.

JavaScript n'a aucun rapport avec le langage Java. Seuls les noms se ressemblent.

JavaScript est régulièrement utilisé aujourd'hui pour faire de l'AJAX (Asynchronous JavaScript And XML). Cette technique permet de modifier une partie de la page web que le visiteur consulte en échangeant des données avec le serveur. Cela donne l'impression que les pages sont plus dynamiques et plus réactives. Le visiteur n'a plus besoin de recharger systématiquement toute la page.

Les navigateurs sont de plus en plus efficaces dans leur traitement de JavaScript, ce qui fait que les pages qui utilisent JavaScript sont de plus en plus réactives. On peut ainsi arriver aujourd'hui à créer des sites qui deviennent littéralement des applications web, l'équivalent de logiciels mais disponibles sous forme de sites web !
Un exemple célèbre : Google Docs, la suite bureautique de Google, disponible sur le Web (figure suivante).

Le tableur Google Docs
Le tableur Google Docs

Pour en savoir plus sur JavaScript, lisez le tutoriel du Site du Zéro !

Lire le tutoriel Javascript

Technologies liées à HTML5 (Canvas, SVG, Web Sockets…)

Le W3C ne travaille pas que sur les langages HTML et CSS. Ce sont certes les plus connus, mais le W3C cherche aussi à définir d'autres technologies qui viennent compléter HTML et CSS. Elles sont nombreuses et on les confond d'ailleurs souvent avec HTML5.

En fait, HTML5 est devenu un mot très utilisé qui fait référence à d'autres technologies que HTML. Quand quelqu'un vous parle de « HTML5 » aujourd'hui, il fait peut-être aussi référence à d'autres éléments qui sortent du cadre strict du HTML.

Voici une petite liste de ces nouvelles technologies introduites en parallèle de HTML5 (notez que certaines ne sont pas vraiment « nouvelles » mais elles reviennent sur le devant de la scène) :

  • Canvas : permet de dessiner au sein de la page web, à l'intérieur de la balise HTML <canvas>. On peut dessiner des formes (triangles, cercles…) mais aussi ajouter des images, les manipuler, appliquer des filtres graphiques… Au final, cela nous permet de réaliser aujourd'hui de véritables jeux et des applications graphiques directement dans des pages web ! Vous pouvez par exemple consulter le tutoriel du Site du Zéro sur Canvas (code web : 510274).

  • SVG : permet de créer des dessins vectoriels au sein des pages web. À la différence de Canvas, ces dessins peuvent être agrandis à l'infini (c'est le principe du vectoriel). Le logiciel Inkscape est connu pour permettre de dessiner des SVG. Il existe un tutoriel sur le Site du Zéro sur SVG (code web : 678000).

  • Drag & Drop : permet de faire « glisser-déposer » des objets dans la page web, de la même façon qu'on peut faire glisser-déposer des fichiers sur son bureau. Gmail l'utilise pour permettre d'ajouter facilement des pièces jointes à un e-mail.

  • File API : permet d'accéder aux fichiers stockés sur la machine du visiteur (avec son autorisation). On l'utilisera notamment en combinaison avec le Drag & Drop.

  • Géolocalisation : pour localiser le visiteur et lui proposer des services liés au lieu où il se trouve (ex. : les horaires des salles de cinéma proches). La localisation n'est pas toujours très précise, mais cela peut permettre de repérer un visiteur à quelques kilomètres près (avec son accord).

  • Web Storage : permet de stocker un grand nombre d'informations sur la machine du visiteur. C'est une alternative plus puissante aux traditionnels cookies. Les informations sont hiérarchisées, comme dans une base de données.

  • Appcache : permet de demander au navigateur de mettre en cache certains fichiers, qu'il ne cherchera alors plus à télécharger systématiquement. Très utile pour créer des applications web qui peuvent fonctionner même en mode « hors ligne » (déconnecté).

  • Web Sockets : permet des échanges plus rapides, en temps réel, entre le navigateur du visiteur et le serveur qui gère le site web (c'est une sorte d'AJAX amélioré). C'est un peu l'avenir des applications web, qui pourront devenir aussi réactives que les vrais programmes.

  • WebGL : permet d'introduire de la 3D dans les pages web, en utilisant le standard de la 3D OpenGL (figure suivante). Les scènes 3D sont directement gérées par la carte graphique.

La plupart de ces technologies s'utilisent avec JavaScript. Il s'agit donc de nouvelles fonctionnalités que l'on peut utiliser en JavaScript.

Une application web 3D utilisant WebGL
Une application web 3D utilisant WebGL

Comme vous le voyez, vous avez de nouveaux mondes à découvrir ! Dès que vous connaîtrez suffisamment JavaScript, vous pourrez aller encore plus loin dans la gestion de votre site web… que vous pourrez même transformer en véritable application !

Les sites web dynamiques (PHP, JEE, ASP .NET…)

Les langages dont nous allons parler ici sont eux aussi des langages de programmation. Comme JavaScript ? Oui, mais avec une différence importante : JavaScript s'exécute sur la machine de vos visiteurs, tandis que les langages que nous allons voir s'exécutent sur le « serveur » qui contient votre site web.

Quelle différence cela fait-il que le programme tourne sur la machine du visiteur ou sur le serveur ?

Les différences sont importantes. Tout d'abord, en termes de puissance, un serveur sera bien souvent plus rapide que la machine de vos visiteurs, ce qui permet d'effectuer des calculs plus complexes. Vous avez aussi davantage de contrôle côté serveur qu'en JavaScript… Mais le JavaScript reste irremplaçable car il y a certaines actions que vous ne pouvez faire que du côté « visiteur ».

Les langages serveur permettent de générer la page web lorsque le visiteur arrive sur votre site (figure suivante). Chaque visiteur peut donc obtenir une page web personnalisée suivant ses besoins !

Échange de données avec un serveur
Échange de données avec un serveur

Les langages ne servent donc pas aux mêmes choses, mais ils se complètent. Si vous combinez HTML + CSS + JavaScript + PHP, par exemple, vous pouvez faire de l'AJAX (échanges de données entre la page et le serveur), vous pouvez effectuer des calculs, stocker des informations dans des bases de données… bref, faire de vrais sites web dynamiques !

Les langages « côté serveur » sont nombreux. Citons-en quelques-uns :

  • PHP : l'un des plus connus. Facile à utiliser et puissant, il est utilisé notamment par Facebook… et le Site du Zéro. J'ai d'ailleurs rédigé un tutoriel sur PHP sur le Site du Zéro.

  • JEE (Java) : très utilisé dans le monde professionnel, il s'agit d'une extension du langage Java qui permet de réaliser des sites web dynamiques, puissants et robustes. Au début, il est un peu plus complexe à prendre en main que PHP.

  • ASP .NET (C#) : assez semblable à JEE, c'est le langage de Microsoft. On l'utilise en combinaison avec d'autres technologies Microsoft (Windows Server…). Il utilise le puissant framework .NET, véritable couteau suisse des développeurs, qui offre de nombreuses fonctionnalités.

  • Django (Python) : une extension du langage Python qui permet de réaliser rapidement et facilement des sites web dynamiques. Il est connu pour générer des interfaces d'administration prêtes à l'emploi.

  • Ruby on Rails (Ruby) : une extension du langage Ruby, assez similaire à Django, qui permet de réaliser des sites web dynamiques facilement et avec une grande souplesse.

Connaître l'un de ces langages est indispensable si vous voulez traiter le résultat des formulaires HTML ! Souvenez-vous de la balise <form> : je vous avais expliqué comment créer des formulaires, mais pas comment récupérer les informations saisies par vos visiteurs. Il vous faut obligatoirement un langage serveur, comme PHP, pour récupérer et traiter ces données !

Au final, ces langages vous permettent de réaliser vos rêves les plus fous sur votre site web :

  • forums ;

  • newsletter ;

  • compteur de visiteurs ;

  • système de news automatisé ;

  • gestion de membres ;

  • jeux web (jeux de stratégie, élevage d'animaux virtuels…) ;

  • etc.

Il est indispensable de connaître les langages HTML et CSS avant d'apprendre un langage serveur comme PHP !

Bonne découverte !


Tutoriel VBScript

Envoyez votre site sur le Web

Votre site est tout beau, tout propre, tout prêt… mais comme il est sur votre disque dur, personne d'autre ne va pouvoir en profiter !

Vous aimeriez donc l'envoyer sur le Web, mais… vous ne savez pas comment faire.
Nous allons découvrir dans cette annexe tout ce qu'il faut savoir pour envoyer son site sur le Web :

  1. Comment réserver un nom de domaine ?

  2. Qu'est-ce qu'un hébergeur et comment cela fonctionne-t-il ?

  3. Enfin, comment utiliser un client FTP pour pouvoir transférer les fichiers sur le Net ?

Le nom de domaine

Savez-vous ce qu'est un nom de domaine ?
Il s'agit en fait d'une adresse sur le Web : siteduzero.com est par exemple un nom de domaine.

Un nom de domaine est constitué de deux parties : siteduzero.com.

  • En rouge, le nom de domaine proprement dit. Il s'agit d'un nom que l'on peut en général choisir librement, tant que personne ne l'a réservé avant nous. Il peut contenir des lettres et des chiffres, et depuis 2012, certains caractères accentués (comme le « ç » français, le « é » ou le « è »).

  • En bleu, l'extension (aussi appelée « TLD », de l'anglais top-level domain). Il existe grosso modo une extension par pays (.fr pour la France, .be pour la Belgique, .ca pour le Canada, etc.). Toutefois, il y a aussi des extensions utilisées au niveau international comme .com, .net, .org. Elles étaient au départ réservées aux sites commerciaux, aux organisations, … mais cela fait longtemps que tout le monde peut les réserver. D'ailleurs, .com est très probablement l'extension la plus utilisée sur le Web.

En général, un site web voit son adresse précédée par www, comme par exemple www.siteduzero.com. Cela ne fait pas partie du nom de domaine : en fait, www est ce qu'on appelle un sous-domaine, et on peut en théorie en créer autant qu'on veut une fois qu'on est propriétaire du nom de domaine.
Le www a été adopté par tous les webmasters, c'est une sorte de convention, mais elle n'est absolument pas obligatoire.

Réserver un nom de domaine

Moi aussi je veux un nom de domaine pour mon site ! Comment dois-je faire ?

Alors j'ai une bonne et une mauvaise nouvelle. Comme d'habitude, on va commencer par la mauvaise :

  • la mauvaise : ce n'est pas gratuit…

  • la bonne : … ce n'est vraiment pas cher du tout.

En effet, un nom de domaine coûte entre 7 et 12 euros par an.
Le prix peut varier en fonction de l'extension. Ainsi, l'extension .info est généralement proposée à plus bas prix et peut s'avérer être une alternative intéressante. Mais si vous voulez une adresse plus « courante », il faudra plutôt viser une extension de type .com ou encore .fr.

Pour réserver un nom de domaine, deux solutions :

  • Passer par un registrar spécialisé. C'est un organisme qui sert d'intermédiaire entre l'ICANN (l'organisation qui gère l'ensemble des noms de domaine au niveau international) et vous. 1&1, OVH et Gandi sont de célèbres registrars français.

  • Encore mieux : vous pouvez commander le nom de domaine en même temps que l'hébergement (c'est ce que je vous conseille). De cette manière, vous faites d'une pierre deux coups, vu que vous aurez de toute façon besoin de l'hébergement et du nom de domaine.

Dans ce chapitre, nous allons voir comment commander un nom de domaine en même temps que l'hébergement, c'est de loin la solution la plus simple et la moins coûteuse pour vous.

L'hébergeur

Intéressons-nous maintenant à l'hébergeur.

Qu'est-ce qu'un hébergeur et pourquoi aurais-je besoin de lui ?

Sur Internet, tous les sites web sont stockés sur des ordinateurs particuliers appelés serveurs (figure suivante). Ce sont des ordinateurs généralement très puissants, qui restent tout le temps allumés. Ils contiennent les pages des sites web et les délivrent aux internautes qui les demandent, à toute heure du jour et de la nuit.

Un serveur

Un serveur ne possède pas d'écran car, la plupart du temps, il tourne tout seul sans qu'il y ait besoin de faire quoi que ce soit dessus. Comme vous le voyez, les serveurs sont très plats : c'est un format spécial de serveur (appelé « 1U »). Cela permet de les empiler dans des baies, c'est-à-dire une sorte d'armoire climatisée pour serveurs (figure suivante).

Une baie de serveurs
Une baie de serveurs

Comme vous le voyez, il y a un écran pour toute la baie. C'est suffisant car on ne branche l'écran sur un serveur que si celui-ci rencontre un problème. La plupart du temps, heureusement, le serveur travaille sans broncher.

Le rôle de l'hébergeur

L'hébergeur est une entreprise qui se charge de gérer des baies de serveurs. Elle s'assure du bon fonctionnement des serveurs 24h/24, 7j/7. En effet, si l'un d'eux tombe en panne, tous les sites présents sur la machine deviennent inaccessibles (et cela fait des clients mécontents).

Ces baies se situent dans des lieux particuliers appelés datacenters (figure suivante). Les datacenters sont donc en quelque sorte des « entrepôts à serveurs » et leur accès est très protégé.

Un datacenter, dans lequel on voit plusieurs baies de serveurs
Un datacenter, dans lequel on voit plusieurs baies de serveurs

Il est aussi possible, en théorie, d'héberger un site sur son propre ordinateur. Toutefois, c'est complexe : il vaut mieux avoir des connaissances en Linux, l'ordinateur doit être assez puissant, tourner jour et nuit et… surtout… la connexion doit être à très très haut débit (surtout en upload, la vitesse d'envoi des fichiers compte énormément). Les particuliers n'ont en règle générale pas une connexion suffisamment puissante pour héberger des sites, contrairement aux datacenters : ceux-ci sont câblés en fibre optique (ce qui permet d'atteindre des vitesses de plusieurs Gbps !)

Bref, gérer un serveur soi-même est complexe et, la plupart du temps, les particuliers et les entreprises font appel à un hébergeur dont c'est le métier.

Trouver un hébergeur

Les hébergeurs, contrairement aux registrars, sont très très nombreux. Il y en a de tous types, à tous les prix. Il y a un vocabulaire à connaître pour vous repérer dans leurs offres :

    • Hébergement mutualisé : si vous optez pour une offre d'hébergement mutualisé, votre site sera placé sur un serveur gérant plusieurs sites à la fois (peut-être une centaine, peut-être plus). C'est l'offre la moins chère et c'est celle que je vous recommande de viser si vous démarrez votre site web.

    • Hébergement dédié virtuel : cette fois, le serveur ne gère que très peu de sites (généralement moins d'une dizaine). Cette offre est généralement adaptée aux sites qui d'un côté ne peuvent plus tenir sur un hébergement mutualisé car ils ont trop de trafic (trop de visiteurs), mais qui par ailleurs ne peuvent pas se payer un hébergement dédié (voir ci-dessous).

    • Hébergement dédié (on parle aussi de « serveur dédié ») : c'est le nec plus ultra. Le serveur gère uniquement votre site et aucun autre. Attention, cela coûte assez cher et il vaut mieux avoir des connaissances en Linux pour administrer le serveur à distance.

Par exemple, le Site du Zéro est lui-même sur un hébergement dédié, car son trafic est très important.

Mais où puis-je trouver un hébergeur ?

Oh ça, c'est très simple.
Une recherche dans Google de « hébergeur web » vous donnera plusieurs millions de résultats. Vous n'aurez que l'embarras du choix.

Dans la suite de ce tutoriel, je vais vous montrer comment cela fonctionne avec l'hébergeur 1&1, auprès de qui nous avons pu obtenir des réductions spécialement pour les visiteurs d'OpenClassrooms. :)

Si vous le souhaitez, vous pouvez bien entendu recourir à un autre hébergeur de votre choix. Je sais que les lecteurs de ce tutoriel utilisent parfois aussi PlanetHoster et MavenHosting
La suite de ce chapitre détaille la procédure pour héberger votre site chez 1&1, mais sachez que cela fonctionne quasiment de la même manière avec PlanetHoster, MavenHosting ou tout autre hébergeur.

Revenons à 1&1. Cet hébergeur propose plusieurs offres d'hébergement mutualisé, qui sont mensuelles et sans engagement. À tout moment de l'année, vous pouvez changer votre formule d'abonnement ou bien l'arrêter tout simplement. Vous pouvez voir le détail des offres à la figure suivante.

Les offres d'hébergement de 1&1

Les offres d'hébergement 1&1

Commander un hébergement pour votre site web

Cliquez sur le bouton "Continuer" dans l'offre 1&1 Unlimited. On vous demande ensuite de choisir le nom de domaine de votre site, c'est-à-dire l'adresse à laquelle on pourra le trouver. Cochez la case en fonction des extensions que vous voulez utiliser (.com, .fr...). Un seul nom de domaine étant compris dans l'offre, je vous recommande de ne cocher qu'une seule case (par exemple ".com"). Si vous en cochez plusieurs, il faudra payer un peu plus.

On vous demande de choisir le nom de domaine de votre site

On vous demande de choisir le nom de domaine de votre site

Notez que, si vous avez les moyens, c'est en général une bonne idée d'acheter plusieurs noms de domaine similaires. Ca vous évite d'être victime de "domain parking", c'est-à-dire de personnes qui achètent des noms de domaines semblables au vôtre pour vous les revendre au prix fort ensuite quand vous voyez que vos visiteurs se trompent de site.

Une fois que c'est fait, 1&1 va vérifier que le nom de domaine que vous demandez n'est pas déjà pris :

Vérifiez si le nom de domaine est libre avant de continuer

Vérifiez si le nom de domaine est libre avant de continuer

Si le domaine est libre, vous pouvez continuer ! Cliquez simplement sur "Continuer". :)

On vous proposera ensuite plusieurs offres commerciales (acheter plus de domaines, un générateur de sites...). A moins qu'elles ne vous intéressent, je vous invite à cliquer sur "Non merci" à chaque fois :

On vous propose d'acheter d'autres noms de domaine (facultatif)

On vous propose d'acheter d'autres noms de domaine (facultatif)

Vous devriez à la fin arriver sur votre panier.

Il ne vous reste plus qu'à renseigner vos coordonnées et finaliser l'achat.
Une fois les formalités et le paiement effectués, vous êtes redirigés vers 1&1, qui vous confirme la prise en compte de votre commande. Vous devriez recevoir un peu plus tard un e-mail vous indiquant toutes les informations nécessaires pour mettre en place votre site. Conservez-les précieusement, vous en aurez besoin.

Lorsque vous avez reçu par e-mail vos identifiants pour vous connecter au serveur de votre hébergeur, vous pouvez passer à l'étape suivante : envoyer votre site web sur le serveur de votre hébergeur !

Utiliser un client FTP

Installer un client FTP

FTP signifie File Transfer Protocol et, pour faire court et simple, c'est le moyen que l'on utilise pour envoyer nos fichiers.
Il existe des logiciels permettant d'utiliser le FTP pour transférer vos fichiers sur Internet.

Bien entendu, des logiciels FTP, il en existe des centaines, gratuits, payants, français, anglais, etc.
Pour que nous soyons sur la même longueur d'onde, je vais vous proposer celui que j'utilise, qui est gratuit et en français : FileZilla (figure suivante).

L'icône du célèbre client FTP FileZilla
L'icône du célèbre client FTP FileZilla

Ce logiciel n'a rien à avoir avec Mozilla, si ce n'est qu'il se termine lui aussi par « zilla ». N'allez donc pas croire que je vous force à utiliser des logiciels d'un même éditeur, c'est tout à fait faux. D'ailleurs, vous pouvez utiliser n'importe quel autre logiciel FTP si cela vous chante, cela ne me dérange absolument pas.

Quoiqu'il en soit, je vais vous montrer quelle est la marche à suivre avec FileZilla. Et la première étape, c'est bien entendu de le télécharger !

Télécharger FileZilla

Prenez la version correspondant à votre système d'exploitation (Windows, Mac OS X ou Linux).

Je vous fais confiance pour l'installation, elle est toute simple et vous ne devriez pas avoir de problème.
Lancez le logiciel, vous devriez voir quelque chose ressemblant à la figure suivante.

FileZilla est ouvert
FileZilla est ouvert

À première vue, cela semble un peu compliqué (à première vue seulement). En fait, le principe est très simple.
Il y a quatre grandes zones à connaître dans la fenêtre :

  1. En haut, vous verrez apparaître les messages qu'envoie et reçoit le logiciel. Si vous avez un peu de chance, vous verrez même la machine vous dire bonjour (si si, je vous jure). En général, cette zone ne nous intéresse pas vraiment, sauf s'il y a des messages d'erreur en rouge…

  2. À gauche, c'est votre disque dur. Dans la partie du haut, vous avez les dossiers et, dans la partie du bas, la liste des fichiers du dossier actuel.

  3. À droite, c'est la liste des fichiers envoyés sur le serveur sur Internet. Pour le moment il n'y a rien car on ne s'est pas connecté, mais cela va venir, ne vous en faites pas.

  4. Enfin, en bas, vous verrez apparaître les fichiers en cours d'envoi (et le pourcentage d'envoi).

La première étape va être de se connecter au serveur de votre hébergeur.

Configurer le client FTP

Quel que soit l'hébergeur que vous avez choisi, cela fonctionne toujours de la même manière. On va vous fournir trois informations qui sont indispensables pour que FileZilla puisse se connecter au serveur :

  • L'IP : c'est « l'adresse » du serveur. Le plus souvent, on vous donnera une information du type ftp.mon-site.com, mais il peut aussi s'agir d'une suite de nombres comme 122.65.203.27.

  • Le login : c'est votre identifiant, on vous a probablement demandé de le choisir. Vous avez peut-être mis votre pseudo, ou le nom de votre site. Mon login pourrait par exemple être mateo21.

  • Le mot de passe : soit on vous a demandé de choisir un mot de passe, soit (c'est plus probable) on vous en a attribué un d'office (un truc imprononçable du genre crf45u7h).

Si vous avez ces trois informations, vous allez pouvoir continuer.
Si vous ne les avez pas, il faut que vous les cherchiez, c'est indispensable. On vous les a probablement envoyées par e-mail. Sinon, n'hésitez pas à les demander à votre hébergeur (IP, login et mot de passe).

Maintenant que nous sommes en possession de ces informations, nous allons les donner à FileZilla, qui en a besoin pour se connecter au serveur.

Cliquez sur la petite icône en haut à gauche (pas sur la petite flèche à droite, mais bien sur l'image), représentée à la figure suivante.

L'icône de connexion de FileZilla
L'icône de connexion de FileZilla

Une fenêtre s'ouvre. Cliquez sur Nouveau site et donnez-lui le nom que vous voulez (par exemple « Site du Zéro »). À droite, vous allez devoir indiquer les trois informations dont je viens de vous parler, comme à la figure suivante.

Les trois informations à donner à FileZilla
Les trois informations à donner à FileZilla

Vous pouvez distinguer en haut l'hôte (c'est là qu'il faut indiquer ftp.monsite.com, par exemple). Cochez Type d'authentification : Normale pour pouvoir saisir le login et le mot de passe.

Cliquez sur Connexion et le tour est (presque) joué.

Transférer les fichiers

À ce stade, deux possibilités :

  • Soit la connexion a réussi : vous voyez alors apparaître en haut des messages en vert comme « Connecté ». Dans ce cas, la zone de droite de la fenêtre de FileZilla devrait s'activer et vous verrez les fichiers qui se trouvent déjà sur le serveur (il se peut qu'il y en ait déjà quelques-uns).

  • Soit cela a planté, vous avez plein de messages écrits en rouge et là, eh bien… il n'y a pas trente-six solutions : vous vous êtes trompés en tapant l'IP, ou le login, ou le mot de passe. Un de ces éléments est incorrect, veillez à les redemander à votre hébergeur car s'ils sont bons cela doit marcher.

Si la connexion a réussi, alors ce que vous avez à faire est très simple : dans la partie de gauche, cherchez où se trouvent, sur votre disque dur, vos fichiers .html et .css (mais aussi vos images .jpg, .png, .gif, etc.).
À gauche, faites un double-clic sur le fichier que vous voulez transférer. Au bout de quelques secondes, il apparaîtra à droite, ce qui voudra dire qu'il a été correctement envoyé sur le serveur, et donc qu'il est accessible sur Internet !

Vous pouvez envoyer n'importe quel type de fichier. Bien entendu, généralement on envoie des fichiers .php, .html, .css et des images, mais vous pouvez aussi très bien envoyer des .pdf, des programmes, des .zip, etc.

La figure suivante, par exemple, représente le résultat que l'on obtient après avoir transféré un fichier index.html et quelques autres fichiers.

Des fichiers sont hébergés sur le FTP
Des fichiers sont hébergés sur le FTP

Il apparaît à droite, ce qui veut dire qu'il est maintenant disponible sur le serveur.

Veuillez noter qu'il faut que votre page d'accueil s'appelle index.html. C'est la page qui sera chargée lorsqu'un nouveau visiteur arrivera sur votre site.

Vous pouvez aussi transférer des dossiers entiers d'un seul coup : il suffit de faire un glisser-déposer du dossier depuis la partie de gauche (ou directement de la fenêtre de votre système d'exploitation) jusqu'à la partie de droite de la fenêtre de FileZilla.

Une fois configuré, vous pouvez voir que l'envoi de fichiers est très simple.

En résumé

  • Pour le moment, votre site web n'est visible que par vous, sur votre ordinateur. Il faut l'envoyer sur le Web pour qu'il soit visible par tout le monde.

  • Vous avez besoin de deux éléments :

    • Un nom de domaine : c'est l'adresse de votre site web. Vous pouvez réserver une adresse en .com, .fr, .net… Par exemple : siteduzero.com.

    • Un hébergeur : c'est lui qui va stocker votre site web sur une machine appelée « serveur ». Son rôle sera d'envoyer votre site à vos visiteurs à toute heure du jour et de la nuit.

  • Pour transmettre les fichiers de votre site au serveur de votre hébergeur, il faut utiliser un client FTP comme FileZilla.

  • Pour vous connecter au serveur, vous avez besoin de trois informations : l'adresse IP du serveur (ou son nom d'hôte), votre login et votre mot de passe. Ceux-ci vous sont fournis par votre hébergeur.


Tutoriel VBScript

Mémento des balises HTML

Cette page est une liste non exhaustive des balises HTML qui existent. Vous trouverez ici un grand nombre de balises HTML. Nous en avons déjà vu certaines dans le cours, mais il y en a d'autres que nous n'avons pas eu l'occasion d'étudier. Généralement, les balises que nous n'avons pas étudiées sont des balises un peu plus rarement utilisées. Peut-être trouverez-vous votre bonheur dans ce lot de nouvelles balises.

Vous pouvez vous servir de cette annexe comme d'un aide-mémoire lorsque vous développez votre site web.

Attention, j'insiste : cette annexe n'est pas complète et c'est volontaire. Je préfère mettre moins de balises et garder seulement celles qui me semblent les plus utiles dans la pratique.

Mémento

Balises de premier niveau

Les balises de premier niveau sont les principales balises qui structurent une page HTML. Elles sont indispensables pour réaliser le « code minimal » d'une page web.

Balise | Description
<html> | Balise principale
<head> | En-tête de la page
<body> | Corps de la page

Code minimal d'une page HTML :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Titre</title>
    </head>

    <body>

    </body>
</html>

Balises d'en-tête

Ces balises sont toutes situées dans l'en-tête de la page web, c'est-à-dire entre <head> et </head> :

Balise | Description
<link /> | Liaison avec une feuille de style
<meta /> | Métadonnées de la page web (charset, mots-clés, etc.)
<script> | Code JavaScript
<style> | Code CSS
<title> | Titre de la page

Balises de structuration du texte

Balise | Description
<abbr> | Abréviation
<blockquote> | Citation (longue)
<cite> | Citation du titre d'une œuvre ou d'un évènement
<q> | Citation (courte)
<sup> | Exposant
<sub> | Indice
<strong> | Mise en valeur forte
<em> | Mise en valeur normale
<mark> | Mise en valeur visuelle
<h1> | Titre de niveau 1
<h2> | Titre de niveau 2
<h3> | Titre de niveau 3
<h4> | Titre de niveau 4
<h5> | Titre de niveau 5
<h6> | Titre de niveau 6
<img /> | Image
<figure> | Figure (image, code, etc.)
<figcaption> | Description de la figure
<audio> | Son
<video> | Vidéo
<source> | Format source pour les balises <audio> et <video>
<a> | Lien hypertexte
<br /> | Retour à la ligne
<p> | Paragraphe
<hr /> | Ligne de séparation horizontale
<address> | Adresse de contact
<del> | Texte supprimé
<ins> | Texte inséré
<dfn> | Définition
<kbd> | Saisie clavier
<pre> | Affichage formaté (pour les codes sources)
<progress> | Barre de progression
<time> | Date ou heure

Balises de listes

Cette section énumère toutes les balises HTML permettant de créer des listes (listes à puces, listes numérotées, listes de définitions…)

Balise | Description
<ul> | Liste à puces, non numérotée
<ol> | Liste numérotée
<li> | Élément de la liste à puces
<dl> | Liste de définitions
<dt> | Terme à définir
<dd> | Définition du terme

Balises de tableau

Balise | Description
<table> | Tableau
<caption> | Titre du tableau
<tr> | Ligne de tableau
<th> | Cellule d'en-tête
<td> | Cellule
<thead> | Section de l'en-tête du tableau
<tbody> | Section du corps du tableau
<tfoot> | Section du pied du tableau

Balises de formulaire

Balise | Description
<form> | Formulaire
<fieldset> | Groupe de champs
<legend> | Titre d'un groupe de champs
<label> | Libellé d'un champ
<input /> | Champ de formulaire (texte, mot de passe, case à cocher, bouton, etc.)
<textarea> | Zone de saisie multiligne
<select> | Liste déroulante
<option> | Élément d'une liste déroulante
<optgroup> | Groupe d'éléments d'une liste déroulante

Balises sectionnantes

Ces balises permettent de construire le squelette de notre site web.

Balise | Description
<header> | En-tête
<nav> | Liens principaux de navigation
<footer> | Pied de page
<section> | Section de page
<article> | Article (contenu autonome)
<aside> | Informations complémentaires

Balises génériques

Les balises génériques sont des balises qui n'ont pas de sens sémantique.

En effet, toutes les autres balises HTML ont un sens : <p> signifie « Paragraphe », <h2> signifie « Sous-titre », etc.
Parfois, on a besoin d'utiliser des balises génériques (aussi appelées balises universelles) car aucune des autres balises ne convient. On utilise le plus souvent des balises génériques pour construire son design.

Il y a deux balises génériques : l'une est inline, l'autre est block.

Balise | Description
<span> | Balise générique de type inline
<div> | Balise générique de type block

Ces balises ont un intérêt uniquement si vous leur associez un attribut class, id ou style :

  • class: indique le nom de la classe CSS à utiliser.

  • id: donne un nom à la balise. Ce nom doit être unique sur toute la page car il permet d'identifier la balise. Vous pouvez vous servir de l'ID pour de nombreuses choses, par exemple pour créer un lien vers une ancre, pour un style CSS de type ID, pour des manipulations en JavaScript, etc.

  • style: cet attribut vous permet d'indiquer directement le code CSS à appliquer. Vous n'êtes donc pas obligés d'avoir une feuille de style à part, vous pouvez mettre directement les attributs CSS. Notez qu'il est préférable de ne pas utiliser cet attribut et de passer à la place par une feuille de style externe, car cela rend votre site plus facile à mettre à jour par la suite.

Ces trois attributs ne sont pas réservés aux balises génériques : vous pouvez aussi les utiliser sans aucun problème dans la plupart des autres balises.


Tutoriel VBScript

Mémento des propriétés CSS

Cette page est une liste non exhaustive des propriétés CSS qui existent en CSS3. Pour la plupart, ce sont des propriétés que nous avons vues dans le cours, mais vous trouverez aussi quelques nouvelles propriétés que nous n'avons pas abordées.

La liste est non exhaustive car mon but n'est pas de faire la liste de toutes les propriétés CSS qui peuvent exister : il y en a vraiment trop (plus de deux cents !) et certaines sont très rarement utilisées.

Mémento

Propriétés de mise en forme du texte

Je résume ici la plupart des propriétés de mise en forme du texte.

Qu'est-ce que la mise en forme de texte ? C'est tout ce qui touche à la présentation du texte proprement dit : le gras, l'italique, le souligné, la police, l'alignement, etc.

Propriété | Valeurs (exemples) | Description
font-family | police1, police2, police3 , serif, sans-serif, monospace | Nom de police
@font-face | Nom et source de la police | Police personnalisée
font-size | 1.3em, 16px, 120%... | Taille du texte
font-weight | bold, normal | Gras
font-style | italic, oblique, normal | Italique
text-decoration | underline, overline, line-through, blink, none | Soulignement, ligne au-dessus, barré ou clignotant
font-variant | small-caps, normal | Petites capitales
text-transform | capitalize, lowercase, uppercase | Capitales
font | - | Super propriété de police. Combine : font-weight , font-style , font-size , font-variant , font-family .
text-align | left, center, right, justify | Alignement horizontal
vertical-align | baseline, middle, sub, super, top, bottom | Alignement vertical (cellules de tableau ou éléments inline-block uniquement)
line-height | 18px, 120%, normal... | Hauteur de ligne
text-indent | 25px | Alinéa
white-space | pre, nowrap, normal | Césure
word-wrap | break-word, normal | Césure forcée
text-shadow | 5px 5px 2px blue (horizontale, verticale, fondu, couleur) | Ombre de texte

Propriétés de couleur et de fond

Propriété | Valeurs (exemples) | Description
color | nom , rgb(rouge,vert,bleu), rgba(rouge,vert,bleu,transparence), #CF1A20... | Couleur du texte
background-color | Identique à color | Couleur de fond
background-image | url('image.png') | Image de fond
background-attachment | fixed, scroll | Fond fixe
background-repeat | repeat-x, repeat-y, no-repeat, repeat | Répétition du fond
background-position | (x y) , top, center, bottom, left, right | Position du fond
background | - | Super propriété du fond. Combine : background-image , background-repeat , background-attachment , background-position
opacity | 0.5 | Transparence

Propriétés des boîtes

Propriété | Valeurs (exemples) | Description
width | 150px, 80%... | Largeur
height | 150px, 80%... | Hauteur
min-width | 150px, 80%... | Largeur minimale
max-width | 150px, 80%... | Largeur maximale
min-height | 150px, 80%... | Hauteur minimale
max-height | 150px, 80%... | Hauteur maximale
margin-top | 23px | Marge en haut
margin-left | 23px | Marge à gauche
margin-right | 23px | Marge à droite
margin-bottom | 23px | Marge en bas
margin | 23px 5px 23px 5px (haut, droite, bas, gauche) | Super-propriété de marge. Combine : margin-top , margin-right , margin-bottom , margin-left .
padding-left | 23px | Marge intérieure à gauche
padding-right | 23px | Marge intérieure à droite
padding-bottom | 23px | Marge intérieure en bas
padding-top | 23px | Marge intérieure en haut
padding | 23px 5px 23px 5px (haut, droite, bas, gauche) | Super-propriété de marge intérieure. Combine : padding-top , padding-right , padding-bottom , padding-left .
border-width | 3px | Épaisseur de bordure
border-color | nom , rgb(rouge,vert,bleu), rgba(rouge,vert,bleu,transparence), #CF1A20... | Couleur de bordure
border-style | solid, dotted, dashed, double, groove, ridge, inset, outset | Type de bordure
border | 3px solid black | Super-propriété de bordure. Combine border-width , border-color , border-style . Existe aussi en version border-top , border-right , border-bottom , border-left .
border-radius | 5px | Bordure arrondie
box-shadow | 6px 6px 0px black (horizontale, verticale, fondu, couleur) | Ombre de boîte

Propriétés de positionnement et d'affichage

Propriété | Valeurs (exemples) | Description
display | block, inline, inline-block, table, table-cell, none... | Type d'élément ( block , inline , inline-block , none …)
visibility | visible, hidden | Visibilité
clip | rect (0px, 60px, 30px, 0px) rect (haut, droite, bas, gauche) | Affichage d'une partie de l'élément
overflow | auto, scroll, visible, hidden | Comportement en cas de dépassement
float | left, right, none | Flottant
clear | left, right, both, none | Arrêt d'un flottant
position | relative, absolute, static | Positionnement
top | 20px | Position par rapport au haut
bottom | 20px | Position par rapport au bas
left | 20px | Position par rapport à la gauche
right | 20px | Position par rapport à la droite
z-index | 10 | Ordre d'affichage en cas de superposition. La plus grande valeur est affichée par-dessus les autres.

Propriétés des listes

Propriété | Valeurs (exemples) | Description
list-style-type | disc, circle, square, decimal, lower-roman, upper-roman, lower-alpha, upper-alpha, none | Type de liste
list-style-position | inside, outside | Position en retrait
list-style-image | url('puce.png') | Puce personnalisée
list-style | - | Super-propriété de liste. Combine list-style-type , list-style-position , list-style-image .

Propriétés des tableaux

Propriété | Valeurs (exemples) | Description
border-collapse | collapse, separate | Fusion des bordures
empty-cells | hide, show | Affichage des cellules vides
caption-side | bottom, top | Position du titre du tableau

Autres propriétés

Propriété | Valeurs (exemple) | Description
cursor | crosshair, default, help, move, pointer, progress, text, wait, e-resize, ne-resize, auto... | Curseur de souris
Mémento des balises HTML Gérer la compatibilité entre les navigateurs


Tutoriel NSI

Hébergeur web

Un article de Wikipédia, l'encyclopédie libre.

Aller à : navigation, rechercher

Un hébergeur web (ou hébergeur internet) est une entité ayant pour vocation de mettre à disposition des internautes des sites web conçus et gérés par des tiers.

Il donne ainsi accès à tous les internautes au contenu déposé dans leurs comptes par les webmestres souvent via un logiciel FTP ou un gestionnaire de fichiers. Pour cela, il maintient des ordinateurs allumés et connectés 24 heures sur 24 à Internet (des serveurs web par exemple) par une connexion à très haut débit (plusieurs centaines de Mb/s), sur lesquels sont installés des logiciels : serveur HTTP (souvent Apache), serveur de messagerie, de base de données...

Concentration des serveurs hôtes de l'Internet projetée sur une carte politique du monde ; chiffres obtenus en 2009.

Sommaire

  • 1 Activité
  • 2 IP et DNS
  • 3 Catégories d'hébergement
  • 4 Hébergement d'applications
    • 4.1 Hébergement de données de santé
  • 5 Législation
  • 6 Notes et références
  • 7 Voir aussi

Activité

La principale activité de l'hébergeur web consiste à installer ses serveurs, à les sécuriser (par une alimentation électrique ondulée, secourue par un groupe électrogène, une salle climatisée équipée de dispositifs anti-incendie), à les tenir à jour en installant les mises à jour de sécurité pour éviter les attaques malveillantes, à les réparer en cas de panne, à y installer les technologies logicielles souhaitées par les clients ou qu'il souhaite leur offrir (comme les langages de programmation internet et les modules supplémentaires de ces langages).

L'hébergement Internet trouve sa justification par diverses raisons parmi lesquelles :

  • la nécessité de sécuriser le service hébergé,
  • la mise à disposition par le prestataire de ressources conséquentes (bande passante en téléchargement...),
  • le conseil et les services de support associés.

IP et DNS

Lorsqu'un visiteur demande une page à son navigateur Web, celui-ci interroge des serveurs DNS pour connaître l'adresse IP du serveur hébergeant ce site. Dès qu'il obtient la réponse, le navigateur va interroger ce serveur et lui demander cette page. Le serveur web va alors chercher la page sur son ou ses disques durs (s'il s'agit d'une page statique), ou la fabriquer à l'aide d'un script (s'il s'agit d'une page dynamique), puis l'envoyer au navigateur, qui l'affiche sur l'écran du visiteur.

Il peut être important de localiser l'endroit où l'hébergeur a ses serveurs. La plupart des moteurs de recherche se basent aussi sur la localisation des serveurs afin d'effectuer le référencement d'un site Web.

Catégories d'hébergement

La plupart des offres d'hébergement sont regroupées en grandes catégories :

  • Les hébergements partagés ou mutualisés : Chaque serveur héberge plusieurs sites, jusqu'à plusieurs milliers, et ce dans le but de mutualiser les coûts. Le principal avantage est le prix, le principal inconvénient est que le client mutualisé n'est pas l'administrateur du serveur, il est donc souvent tributaire du bon vouloir de l'hébergeur s'il souhaite une technologie particulière.
    Dans certaines configurations d'hébergement mutualisé, l'utilisateur peut être administrateur d'un serveur virtuel sur lequel son site est déployé. Il continue cependant à partager les ressources système avec les autres clients mutualisés.
  • Les hébergements dédiés : Le client dispose alors de son propre serveur, et peut en général l'administrer comme il le souhaite, ce qui est le principal avantage de ce type d'offre. Le fournisseur du serveur reste cependant propriétaire du serveur. Les inconvénients sont : le prix beaucoup plus élevé que les hébergements mutualisés, et le besoin de compétences pour administrer la machine correctement.
  • L'hébergement virtuel dédié via un hyperviseur qui offre au client la souplesse d'un dédié (le client administre sa machine à sa convenance) en lui fournissant une machine virtuelle qui utilise une partie des ressources d'un serveur (physique) par des techniques de virtualisation (informatique).
  • Les hébergements dédiés dits « managés », avec « serveur dédié infogéré » ou « clés en main » : Le client dispose de son propre serveur mais les techniciens de l'hébergeur s'occupent de sa gestion système. Cette solution est parfaite si vous n'avez aucune connaissance technique sur son administration. Il suffit simplement de déposer son site. Ce type d'hébergement cherche à s'adapter aux besoins.
  • La colocation : L'hébergeur met, dans son centre de traitement de données, un espace à disposition du client, de sorte qu'il puisse placer son propre serveur à l'intérieur (La plupart du temps dans des armoires spéciales nommées racks ou « baies »). L'hébergeur met également à disposition du client un câble d'alimentation électrique et un câble ethernet pour qu'il puisse alimenter et connecter son serveur à Internet. Ce système est censé coûter moins cher, puisque la location du serveur n'est pas comprise, mais les systèmes de sécurité et des badges dans les centres de traitement de données peuvent coûter plus cher que la location.

La plupart des hébergeurs sont payants. Il reste néanmoins quelques hébergeurs gratuits. Dans ce cas, les prestations gratuites sont souvent des offres d'appel pour les prestations payantes, plus riches en fonctionnalités et plus performantes.

Les entreprises font face à de nombreux challenges au niveau de l’hébergement de leurs infrastructures et applications informatiques. Tiraillées entre des exigences de performance vitales pour leur activité et des contraintes en termes de dépenses et d’investissements, elles se tournent le plus souvent vers des solutions privilégiant mutualisation et industrialisation. La virtualisation, l'« informatique dans les nuages » et les applications en mode SaaS sont de plus en plus envisagées comme des alternatives à l'hébergement interne.

Hébergement d'applications

En 2009, selon une étude[1] menée par MARKESS International auprès de 150 entreprises, les domaines applicatifs les plus concernés par l’hébergement externe sont les sites web et les portails, suivis des applications de gestion de la relation client, de ressources humaines, et les extranets. Dans une moindre proportion, car plus souvent gérées en direct par les directions informatiques, se trouvent les applications de messagerie, de sécurité, de stockage et sauvegarde. Viennent ensuite par ordre décroissant de citations mais très dépendants des secteurs d’activité concernés :

  • Les applications de commerce électronique (e-commerce), les intranets et applications collaboratives incluant non seulement des fonctionnalités de messagerie mais aussi d'agenda, de gestion de tâches, etc., et les applications de gestion de contenus ;
  • Les applications de gestion commerciale et de gestion des forces de vente, les PGI (Progiciel de Gestion Intégré), les applications de finance, de production, et les plates-formes de développement applicatif.

Hébergement de données de santé

Depuis 2007, et la décision de mettre en œuvre un dossier médical personnel, on trouve une nouvelle catégorie d'hébergement d'applications : l'hébergement d'applicatifs contenant des données de santé à caractère personnel. Cette activité est conditionnée par un agrément des hébergeurs, délivré par une commission étudiant les candidatures depuis 2009. Cette nouvelle activité met en évidence deux faits :

  • du fait de leurs importantes infrastructures, les hébergeurs sont maintenant reconnus comme les plus à mêmes de sécuriser les informations,
  • si notre société vise à faciliter l'accès aux informations, l'État français se dote de mesures permettant de sécuriser les données personnelles via identifications des accédants, et mise en œuvre des dernières technologies de chiffrement et d'authentification.

Législation

Cette section adopte un point de vue régional ou culturel particulier et doit être internationalisée.

En 2004, en France, le député Jean Dionis a présenté une loi qui impose aux hébergeurs de se doter de moyens capables de bloquer les sites comportant des contenus à caractère raciste ou pédo-pornographique. Ce mouvement législatif avait déjà été entamé par l'affaire Altern.org. Si les hébergeurs ne sont plus en mesure de filtrer les informations qu'ils hébergent, ils ont néanmoins une obligation de prompte intervention concernant tout signalement de contenu illicite et autre.

Concernant les données de santé à caractère personnel, celles-ci sont régies par les dispositions :

  • de l'article R. 1111-12 du décret no 2006-6 du 4 janvier 2006,
  • des articles L. 1421-2 et L. 1421-3, relatifs au contrôle de l'Inspection générale des affaires sociales et des agents de l'État mentionnés à l'article L. 1421-1 : Les agents chargés du contrôle peuvent être assistés par des experts désignés par le ministre chargé de la santé.

Notes et références

  1. ↑ Etude Approches d'Hébergement avec le Cloud Computing & la Virtualisation, 2009-2011 - MARKESS International


Tutoriel NSI

Site d'hébergement de fichiers

Un article de Wikipédia, l'encyclopédie libre.

Aller à : navigation, rechercher

Les sites d'hébergement de fichiers sont des services qui permettent aux utilisateurs d’héberger des fichiers sur leurs serveurs. Certains hébergent tous les types de fichiers, d'autres se classent selon les types de fichiers qu’ils prennent en charge : vidéos, photographies, ou autres..

De nombreux sites web ont suivi le lancement de YouTube, un site américain qui héberge des vidéos et les diffuse en streaming depuis 2005. La popularité de ces sites n'a cessé d'augmenter.

Sommaire

  • 1 Histoire
  • 2 Hébergement de vidéos
    • 2.1 Offres pour les entreprises
  • 3 Hébergement d’images
    • 3.1 Fonctionnement
  • 4 Hébergement d'objet 3D
  • 5 Hébergement de fichiers en un clic
  • 6 Hébergement privé de fichiers
  • 7 Infraction au droit d'auteur
  • 8 Notes et références
  • 9 Annexes
    • 9.1 Articles connexes

Histoire

Cette section est vide, insuffisamment détaillée ou incomplète. Votre aide est la bienvenue !

Hébergement de vidéos

Les sites d’hébergement de vidéos permettent d’héberger sur leurs serveurs des vidéos et de les diffuser en streaming. On trouve beaucoup de sites web qui offrent ce service, des sites tels que YouTube, Dailymotion, Wat TV, DreamVids, Hulu ou RuTube proposent ce genre de service.

En mars 2008, le long métrage Révolta, Kilomètre Zéro, de Jean-Michel Ben Soussan, est le premier film de cinéma proposé légalement sur DailyMotion [1]. En juin 2009, Home, le film documentaire de Yann Arthus-Bertrand, est diffusé sur YouTube [2].

Offres pour les entreprises

Certaines entreprises ont développé une offre d'hébergement vidéo en marque blanche, proposant ainsi à des éditeurs de sites web de proposer des vidéos sur leur propre site dans un lecteur :

  • intégrant une charte graphique à leur image,
  • pouvant intégrer des solutions tierces d'affichages publicitaires,
  • ou encore permettant de gérer l'accès et aux ressources afin d'assurer leur retour sur investissement.

Ces offres sont recherchées, en particulier, dans les domaines de la presse en ligne, de la communication institutionnelle, de la formation continue ou interne ou encore de la vente en ligne de productions audiovisuelles.

Les sociétés proposant ce type de solution se distinguent par leur modèle économique :

  • la facturation par heure de vidéo diffusée : Brightcove, Wistia, Dailymotion Cloud
  • la facturation au volume de vidéos hébergées : Libcast, Vimeo Pro

Hébergement d’images

Article détaillé : Partage de photographies.

Un hébergeur d’images permet aux internautes d'envoyer des photographies et des images sur un serveur informatique afin de les stocker, et de les partager facilement avec leurs proches et d’autres internautes.

Fonctionnement

L’utilisation est très simple : après le téléchargement de l’image, l’internaute a le choix entre plusieurs codes prêts à l'emploi (copier-coller) selon la destination et l’utilisation de l’image.

Ces codes sont généralement disponibles sous forme de lien (x)HTML et BBCode (pour la plupart des forums) ou bien sous la forme d'une miniature liée à l'image originale.

Le modèle économique des hébergeurs d’images implique souvent qu'ils offrent ce service gratuitement aux utilisateurs en échange d'affichages de publicités, nécessaires pour les financer (ce sont les publicitaires qui rémunèrent les hébergeurs). On peut citer par exemple le site imgur.

Pour ceux qui souhaitent partager leurs œuvres, l'hébergeur Flickr gère les licences d'utilisation des photos, ce qui permet ensuite une utilisation libre (ou non) des images hébergées.

Hébergement d'objet 3D

En informatique, l'hébergement d'objet 3D est une forme d'hébergement internet proposant aux internautes de diffuser leurs fichiers 3D sur le web, généralement pour être importé dans un logiciel 3D.

Cet hébergement est une base de données de modèles 3D en accès libre ou non permettant le dépôt et le téléchargement de données par les utilisateurs / communautés.

Chaque société de logiciel propose des objets 3D gratuits ou payants dans leur format ou plusieurs formats 3D avec les textures.

Banque de donnée 3D
 | Société | Logiciel | Format | Utilisation
3D warehouse | Google | Google SketchUp | Collada (.dae) et .kmz (Keyhole Markup Language compressé) | Google Earth
POV-Ray search collection | POV-Ray |  |  |
Virtual Earth-3DVIA | Microsoft | TrueSpace (en) | 3D XAML | Microsoft XNA , 3D wpf, plug-in Virtual Earth 3D
BlendSwap |  | Blender | Format de données .blend de Blender | Utilisation dans Blender et conversion possibles dans d'autres formats via Blender.

Hébergement de fichiers en un clic

Un site d'hébergement de fichiers en un clic (one-click hoster en anglais) permet à un internaute de mettre en ligne n'importe quel type de fichier. Le fichier est alors disponible pour n'importe quel internaute.

Ce type de site propose généralement une version gratuite limitée à l'envoi de fichiers d'une certaine taille. La limitation peut également être au niveau du nombre de téléchargements simultanés, au niveau du nombre de téléchargements journaliers... Il est généralement nécessaire de taper un code présent sous la forme de captcha afin de lancer le téléchargement. Il faut aussi très souvent attendre quelques secondes voire quelques minutes avant que le téléchargement ne commence. Toutes ces limitations peuvent être contournées à l’aide de débrideurs.

La version payante permet généralement de télécharger davantage de fichiers simultanément, d'enlever la limite de poids du fichier, d'éviter d'avoir à taper le captcha, d'éviter d'avoir à attendre ou d'éviter la limite de téléchargement journalière.

Hébergement privé de fichiers

L'hébergement privé de fichiers permet de ne pas rendre le fichier hébergé accessible à tous les internautes. Ce type d'hébergement est essentiellement destiné à faire du partage de fichier entre connaissances ou dans un cadre professionnel. Il nécessite le plus souvent un mot de passe dédié.amalgram

est un exemple de site privé de stockage et de partage de photos.

Infraction au droit d'auteur

Ces sites sont aussi utilisés pour distribuer et partager des fichiers sans l’accord de leur auteur. Les avis à ce sujet divergent : le comité international du Congrès des États-Unis a déclaré que le site suisse allemand RapidShare est utilisé pour partager des films, des musiques et d’autres contenus illégaux sans l’accord de leur auteur[3]. En 2009-2010, Atari Europe S.A.S.U. a poursuivi RapidShare en justice, mais la cour régionale a conclu que RapidShare était utilisé pour des usages légaux.

Notes et références

  1. ↑ Dailymotion long film légal - Tayo.fr, 25 avril 2008
  2. ↑ Besson renoue avec Google et diffuse Home en ligne - Clubic, 27 avril 2009
  3. ↑ (en) « RIAA joins congressional caucus in unveiling first-ever list of notorious illegal sites », RIAA,‎ 19-05-2010 (consulté le 2011-01-16)

Annexes

Articles connexes

  • Partage de fichiers

Sites d'hébergement de fichiers :

  • Google Drive
  • Infinit
  • MediaFire
  • Megaupload
  • Mega
  • RapidShare
  • Ubuntu One
  • Partage-fichiers
  • Jolishare
  • TransferNow
voir Plateformes de distribution en ligne
Liseuses | Amazon Kindle · Bookeen · Google Play · iBooks · Kobo Touch · Nook · PocketBook · Sony Reader · Tolino
Documents | Blogger · Google Documents · LiveJournal · OverBlog · Pastebins (Pastebay) · YouScribe · Scribd · Calaméo · TypePad · WordPress · Wattpad
Livre numérique | Amazon Kindle · YouScribe · Scribd · Google Play · iBooks · Kobo · Oyster books
Fichiers | e-nautia · Free · MediaFire · Google Drive · Dropbox · SkyDrive · Mega · Megaupload · Seafile · RapidShare · Ubuntu One · SpiderOak · HubiC
Musiques | Magasin de musique en ligne · Amie Street · Beatport · Beats Music · Beezik · Classical Archives · Deezer · Dogmazic · Fnac Jukebox · Google Play · Grooveshark · Imeem · iMesh · iTunes Store · Jamendo · Jiwa · KaZaA · Qobuz · Last.fm · Magnatune · Mixcloud · Musopen · musicMe · Napster · Nokia Music Store · Pandora · rara.com · Rdio · Sony Entertainment Network · Rhapsody · Simfy · Spotify · SoundCloud · Starzik · Vodafone Music · Xbox Music
Images | Amalgram · Corbis · DeviantART · ImageShack · Imgur · Ipernity · Flickr · Fotolia · Fotolog · Getty Images · Nikon Image Space · Panoramio · Picasa · Pixabay · Shutterstock · SmugMug · Wikimedia Commons · Trekearth · Zooomr
Vidéos | 56.com · Canalplay · Dailymotion · Hulu · iTunes Store · Joost · Libcast · LiveLeak · Megavideo · Metacafe · Netflix · PlayStation Store · RuTube · Sony Entertainment Network · TOU.TV · Tudou · Veoh · Vimeo · Wat TV · Youku · YouTube · Zattoo
Articles liés | Logiciel abandonné · BitTorrent · Freeware · Open Music Model · Partage de fichiers en pair à pair · Shareware · Site d'hébergement de fichiers

· Portail de l’informatique Portail de l’informatique

· Portail d’Internet Portail d’Internet

Ce document provient de « http://fr.wikipedia.org/w/index.php?title=Site_d%27hébergement_de_fichiers&oldid=111970714 ».

Catégories :

  • Cloud computing
  • Partage de fichiers sur Internet

Catégories cachées :

  • Page utilisant des arguments dupliqués dans les appels de modèle
  • Article contenant un appel à traduction en anglais
  • Portail:Informatique/Articles liés
  • Portail:Internet/Articles liés
  • Portail:Médias/Articles liés


Hébergement web - LE comparateur des hébergeurs

  • menu bas TROUVER UN HÉBERGEUR

    Trouvez le meilleur hébergeur pour votre site web :

    Hébergeur généraliste

    • Hébergement mutualisé
    • Hébergement illimité
    • Hébergement nom de domaine
    • Hébergement de forum
    • Hébergement discount
    • Hébergement écolo
    • Hébergement Linux
    • Hébergement Windows
    • Hébergement grand débutant

    Hébergeur spécialisé

    • Hébergement Ruby on Rail
    • Hébergement PHP
    • Hébergement ASP
    • Hébergement SSL
    • Hébergement mail
    • Hébergement phpBB
    • Hébergement Streaming
    • Hébergement Coldfusion
    • Hébergement Frontpage
    • Hébergement mobile

    Hébergeur E-commerce

    • Hébergement Prestashop
    • Hébergement Magento
    • Hébergement ZenCart
    • Hébergement eCommerce

    Hébergeur Professionnel

    • Hébergement serveur
    • Hébergement managé
    • Hébergement VPS
    • Hébergement revendeur

    Hébergeur CMS

    • Hébergement SPIP
    • Hébergement Joomla
    • Hébergement Drupal
    • Hébergement PHP-Nuke
    • Hébergement Wordpress
    • Hébergement Moodle
    • Hébergement Blog

    Hébergeur par Pays

    • Hébergement Web France
    • Hébergement Web Suisse
    • Hébergement Web Europe
    • Hébergement Web US
    • Hébergement Web Canada
    • Hébergement Web autres pays
  • menu bas HÉBERGEMENT PROFESSIONNEL

    Tous les outils pour démarrer et pour gérer votre hébergeur professionnel.

    Je veux être hébergeur

    • Hébergement marque blanche
    • Hébergement Revendeur
    • Hébergement dédié
    • Hébergement "cloud"

    Je suis hébergeur

    • Panneaux de contrôle
    • Domaines à prix de gros
    • Hébergement Colocation
  • menu bas GUIDE & ARTICLES

    Tout savoir sur l'hébergement web

    Le guide de Top10hébergeurs - les dernières nouvelles de l'hébergement web

    Les tutoriels top10hebergeurs :
    Tout savoir pour bien gérer son hébergement

    Articles

    • Nouvelles de l'industrie
    • Création de sites web
    • Interviews Hébergeurs
    • Nom de domaine
    • SEO/SEM
    • Spécial débutant
    • Hébergement dédié
    • Hébergement mutualisé
    • Serveurs

    Guide Débutant

    • Guide spécial débutants
    • 36 questions à se poser
    • Choisir son 1er hébergeur
    • Changer d'hébergeur
    • Hébergement gratuit
    • Glossaire
  • menu bas ÉVALUATIONS CLIENTS

    Lire ou laisser un avis

    • Voir tous les avis hébergeurs
    • Classement des hébergeurs par avis
    • Evaluer un hébergeur
    • Gagnez 100€ en laissant un avis
  • menu bas OUTILS

    Outils Webmasters

    • whois
    • SEO
    • Référencer votre hébergeur
  • menu bas ANNUAIRE

    Annuaire Hébergeurs

    • Hébergeurs France
    • Hébergeurs USA
    • Hébergeurs Canada
    • Hébergeurs Suisse
    • Hébergeurs UK
    • Hébergeurs Pays-Bas
    • Hébergeurs Allemagne
    • Autres hébergeurs Europe
    • Autres hébergeurs Monde

    • Voir tout l'annuaire
  • menu bas CONTACT

    Contactez-nous!

    • Question générale
    • Evaluer un hébergeur

    Participer au site

    • Proposer un article
    • Pourquoi proposer un article?

    Contact professionnel

    • Soumettre un communiqué de presse
    • Enregistrer un hébergeur
    • Demander une interview
    • Partenariat
    • Publicité

    Newsletter

    • S'inscrire
    • Se désinscrire

    Autres

    • Sitemap
    • Règlement
    • TOS
    • Twitter
    • RSS Feed
    • Technorati
    • Delicious
  • Top 10 Hébergeurs
  • Accueil

Les meilleurs hébergeurs mutualisés

Nous testons et comparons, quotidiennement, les meilleurs solutions d'hébergement web. Tous les hébergeurs notés ici proposent au moins un pack mutualisé à moins de 10 euros par mois comprenant un nom de domaine gratuit. Si vous débutez, n'hésitez pas à commencer par lire les avis. Vous cherchez une évaluation sur un hébergeur en particulier? Consultez notre annuaire.

Voir aussi nos rubriques : Serveur dédié - Prestashop - Revendeur - Linux - Hébergement pour les nuls - Wordpress

  • Hébergement France
  • Hébergement USA
  • Hébergement Canada

Meilleurs Hébergeurs France

# | Hébergeur | Caractéristiques | Points Forts | Avis Hébergement Web
1 | Ex2 Clé USB offerte Clé USB offerte Serveurs en France Avis Hébergeur Ex2Hosting | Espace: illimité Trafic: illimité Prix: 6,45€ /m | 1 Domaine gratuit, Meilleur support 24h/24, Satisfait ou remboursé | Comparatif Ex2Hosting Comparatif Ex2 Lire les avis sur Ex2Hosting Avis Ex2 Donnez votre avis sur Ex2Hosting Laisser un avis
2 | Planethoster code réduction PlanetHoster -20% code ⇒ top10hebergeurs Le meilleur support Avis Hébergeur Planethoster | Espace: 60 Go Trafic: illimité Prix: 5,99€ /m | Domaines hébergés illimités, Domaine gratuit | Donnez votre avis Planethoster Comparatif Planethoster Lire les avis Planethoster Avis Planethoster Donnez votre avis Planethoster Laisser un avis
3 | 1&1 France code réduction 1and1 Discount sur la 1ère année Bien pour débuter Avis Hébergeur 1&1 France | Espace: illimité Trafic: illimité Prix: 6,99€ 4,99€ /m | 1 domaine gratuit Outils de création 1&1, CDN, 140 apps | Donnez votre avis sur votre hebergement web Comparatif 1&1 France Donnez votre avis sur votre hebergement web Avis 1&1 France Donnez votre avis sur votre hebergement web Laisser un avis
4 | Ikoula Offre Best of Avis Hébergeur ikoula | Espace: 50 Go Trafic: illimité Prix: 4,99€ HT /m | 1 Domaine gratuit, 100 comptes mail, 80 appli offertes | Comparatif iKoula Comparatif iKoula Lire les avis sur iKoula Avis iKoula Donnez votre avis sur iKoula Laisser un avis
5 | Infomaniak code réduction Infomaniak Changer d'héb. gratuitement! Recommandé par Top10Héb. Avis Hébergeur Infomaniak | Espace: 60 Go Trafic: illimité Prix: 7,42€ /m | 1 Domaine gratuit, 40GB de backup, tranfert gratuit | Donnez votre avis sur votre hebergement web Comparatif Infomaniak Donnez votre avis sur votre hebergement web Avis Infomaniak Donnez votre avis sur votre hebergement web Laisser un avis
Voir la suite du classement hébergement France

Meilleurs Hébergeurs USA

Les hébergeurs US offrent des tarifs très avantageux et sont parfaitement adaptés à l'hébergement d'un site français - pour débuter - (paiement par CB, paypal,etc.), et l'interface de l'hébergement peut, pour cPanel, être changée en français. Un petit niveau d'anglais est requis si vous souhaitez contacter le support technique en cas de problème.

# | Hébergeur | Caractéristiques | Points Forts | Avis Hébergement Web
1 | Inmotion hosting Excellente solution Ecommerce Avis Hébergeur InMotion | Espace: illimité Traffic: illimité Prix: 5,95$ /m | Domaine gratuit, Choix du data center, Excellent Service Client | Comparatif InMotion Comparatif Inmotion Lire les avis sur InMotion Avis InMotion Donnez votre avis sur InMotion Laisser un avis
2 | JustHost coupon réduction JustHost - 50% avec code 50OFF L'illimité à prix cassé! Avis Hébergeur JustHost | Espace: illimité Traffic: illimité Prix: 6,95$ 3,95$ /m | Domaine gratuit, Choix du data center, 250 $US crédit Marketing | Comparatif JustHost Comparatif JustHost Lire les avis sur JustHost Avis JustHost Donnez votre avis sur JustHost Laisser un avis
3 | HostPapa.com Meilleur rapport qualité/prix Avis Hébergeur HostPapa | Espace: illimité Trafic: illimité Prix: 3,95$ /m | Domaine gratuit, Hébergement illimité, Logiciel création de site | Donnez votre avis sur votre hebergement web Comparatif HostPapa Lire les avis sur HostPapa Avis HostPapa Donnez votre avis sur HostPapa Laisser un avis
4 | Host Gator 4500 templates gratuits! Avis Hébergeur Host Gator | Espace: illimité Traffic: illimité Prix: 6,95$ /m | Domaine gratuit, 5GB de backup | Comparatif HostGator Comparatif HostGator Lire les avis sur HostGator Avis HostGator Donnez votre avis sur HostGator Laisser un avis
5 | Fat Cow Conseillé pour un 1er site! Avis Hébergeur Fat Cow | Espace: illimité Traffic: illimité Prix: 4,83$ /m | Domaine gratuit, Hébergement illimité, 75 $US crédit Marketing | Comparatif Fatcow Comparatif Fat Cow Lire les avis sur Fatcow Avis FatCow Donnez votre avis sur Fatcow Laisser un avis
Voir la suite du classement hébergement US

Meilleurs Hébergeurs Canada

Tout comme l'hébergement web aux Etats-Unis, l'hébergement au Canada bénéficie de tarifs très avantageux, la concurrence du marché local étant généralement plus élevée qu'en Europe. La plupart de ses hébergeurs offrent aussi un support en français, attention cependant au décalage horaire!.

# | Hébergeur | Caractéristiques | Points Forts | Avis Hébergement Web
1 | Ex2Hosting Meilleur support Avis Hébergeur Ex2Hosting | Espace: 100 Go Trafic: illimité Prix: 5,29C$/m | 1 Domaine gratuit, Le meilleur support, Satisfait ou remboursé | Lire les avis sur Ex2Hosting Avis Ex2Hosting Donnez votre avis sur Ex2Hosting Laisser un avis
2 | HostPapa Hébergeur france - 36$ avec code promo TTHW Meilleur rapport qualité/prix Avis Hébergeur HostPapa | Espace: illimité Trafic: illimité Prix: 5,95$ 3,95C$ /m | Le meilleur tarif!! Hébergement illimité, 100 C$ crédit Marketing | Lire les avis sur HostPapa Avis HostPapa Donnez votre avis sur HostPapa Laisser un avis
3 | Planethoster.ca Hébergeur france Offre complète et évolutive Avis Hébergeur Planethoster | Espace: 50 Go Trafic: illimité Prix: 5,99 C$ /m | Domaines hébergés illimités, Domaine gratuit | Lire les avis Planethoster Avis Planethoster Donnez votre avis Planethoster Laisser un avis
4 | MavenHosting.ca Hébergeur france Conseillé pour un 1er site! Avis Hébergeur MavenHosting.ca | Espace: 75 Go Trafic: illimité Prix: 6,99 C$ /m | Domaine gratuit, Techniciens 24h/24, 10 domaines hébergés | Lire les avis sur MavenHosting.ca Avis MavenHosting Donnez votre avis sur MavenHosting.ca Laisser un avis
5 | Netfirms Ultra facile d'accès pour débuter Avis hébergeur Netfirms | Espace: 250 GB Trafic: 2 500 GB Prix: 7,16 C$ /m | 2 domaines gratuits, Hébergement illimité, 100 $US crédit Marketing | Lire les avis sur Netfirms Avis Netfirms Donnez votre avis sur Netfirms Laisser un avis
Voir la suite du classement hébergement Canada

La méthode top10hébergeurs - Notre classement des meilleurs hébergements web est 100% indépendant. Notre équipe se base, en particulier pour l'hébergement mutualisé, sur le critère rapport qualité/prix. D'autres éléments et caractéristiques entrent en compte tels que le nombre d'options proposés, la facilité d'utilisation, les services clients et techniques, et bien sûr l'avis des utilisateurs.

Les meilleurs hébergeurs

  • Meilleur Hébergement économique (France)
  • Meilleur Hébergement VPS (France)
  • Meilleur Hébergement de Forum (France)
  • Meilleur Hébergement d'Email (France)
  • Meilleur Hébergement eCommerce (France)
  • Meilleur Hébergement Unix (France)
  • Meilleur Hébergement Windows (France)
  • Meilleur Hébergement PHP (France)
  • Meilleur Hébergement Revendeur (US)
  • Meilleur Hébergement VPS (US)

A la une

Chargement...

Hébergement illimité - Aucune limite pour moins de 5 Euros par mois!

hebergement illimite - dreamhost | Dreamhost.com- Un des meilleurs hébergeurs US Hébergement illimité de domaines, espace web illimité et trafic illimité. Visit http://www.top10hebergeurs.com/hebergement.php?m=dreamhost pour plus de détails. 8,95$US / mois pour un an. Dreamhost offre $40 de réduction aux lecteurs de Top10Hébergeurs. Entrez le coupon "COMPHEBERGEMENT" lors de la commande.
Hebergement illimite - Just Host | JustHost.com - Hébergement web professionnel. Hébergement illimité de domaines, espace web illimité et trafic illimité. Voir http://www.top10hebergeurs.com/hebergement.php?m=JustHostpour plus de détails. 3,95$US / mois pour un an.

Hébergement "vert" - Sauvez la planête!

Infomaniak.fr - S'engage pour la planète: 100% énergie renouvelable | Infomaniak.fr - S'engage pour la planète: 100% énergie renouvelable. 1 nom de domaine gratuit, 60 Go d'espace disque, 40 Go backup personnel, PHP & MySQL. Base de données, comptes FTP, sous-domaine et trafic 100% illimité. Voir http://www.top10hebergeurs.com/hebergement.php?m=Infomaniak pour consulter la charte écologique.. Tarifs à partir de 7,5€/mois.
hostpapa | HostPapa.eu - Un Hébergement boosté à l'énergie renouvelable Domaine gratuit à vie, espace web et trafic illimités, possilité d'héberger un nombre de sites illimités! Voir http://www.top10hebergeurs.com/hebergement.php?m=HostPapa-eu pour plus de détails. Tarifs les moins cher du marché pôur une offre très complète. Réduction exclusive sur vos packs d'hébergement!

En savoir plus sur l'Hébergement

Spécial Webmaster débutant - Choisir son 1er hébergeur
Vous vous lancez pour la première fois dans l'achat d'un hébergement pour votre site web, Top 10 Hébergeurs a rédigé pour vous les règles de bases pour vous repérer dans la jungle des hébergeurs.

Quel hébergement web choisir?
Chaque jours, des milliers de webmasters publient leurs sites sur Internet et le marché de l’hébergement est de plus en plus encombré pour suivre ce rythme effréné.

Comment faire le tri dans les offres d’hébergement web ?
Le choix de l’hébergement web est sans aucun doute une des décisions les plus importantes à prendre pour toute entreprise désireuse de s’implanter durablement sur Internet. De nos jours, il est aisé de trouver un fournisseur d’accès à Internet fiable et de qualité, mais le choix de l’hébergeur peut parfois s’avérer un cauchemar.

Accessibilité et uptime, la base d'un bon hébergement web
L'uptime correspond au pourcentage du temps pendant lequel l'hébergeur est accessible via Internet. La plupart des hébergeurs annoncent qu'ils ont un uptime de 99% ou 99.9%, mais cela correspond souvent au temps de fonctionnement du serveur (i.e le serveur est effectivement sous-tension), sans prendre en compte la disponibilité réelle de celui-ci sur l'Internet.

Les différentes catégories d'hébergement web
Les offres d'hébergement web sont regroupées en plusieurs catégories : L'hébergement gratuit, l'hébergement partagé ou mutualisé, l'hébergement « revendeur », l'hébergement dédié virtuel, l'hébergement dédié, l' hébergement dédié dits « managé », « infogéré » ou « clés en main », la colocation, l'hébergement en cluster et bien sûr l'hébergement « maison » (un serveur placé chez vous).

cPanel – un panneau de contrôle complet pour l’hébergement
cPanel est très populaire et est rapidement devenu le panneau de contrôle d’hébergement le plus utilisé sur le web. La première impression qu’on a de cPanel est la simplicité : une simple interface avec plusieurs icônes représentant les fonctions principales du panneau de contrôle.

Guide des solutions d’hébergement
La palette des offres d’hébergement a largement évoluée ces dernières années. On trouve désormais plusieurs offres bien distinctes, chacune avec ses forces et faiblesses. Voici quelques explications pour trouver l’offre la mieux adaptée à vos besoins.

Bases de l’hébergement web
Trouver l’hébergeur web adapté à son site est la première étape pour un webmaster. Vous payez un hébergeur web pour avoir votre site disponible en ligne et partout dans le monde 24h/24 et 7 jours sur 7.

Un hébergement écologique pour un meilleur environnement
Des millions de sites web existent sur le web, hébergés par des milliers de serveurs web, consommant de plus en plus d’énergie. Pour combattre ce problème croissant, beaucoup d’hébergeurs web font fonctionner leurs serveurs et leurs bureaux grâce à des sources alternatives d’énergie.

L’importance des panneaux de contrôle d’hébergement de sites internet
La plupart des hébergeurs web incluent un panneau de contrôle dans leurs offres. Pour un propriétaire de site internet ou des clients d’un hébergeur web les panneaux de contrôle sont la base de leur hébergement.

Créez votre site Internet
Du HTML au serveur FTP, l’ABC pour créer votre site et le publier sur Internet.

Comparatif Hébergements

  • Hébergement mutualisé France
  • Hébergement mutualisé US
  • Hébergement mutualisé Canada
  • Hébergement illimité de domaines
  • Hébergement eCommerce
  • Hébergement Revendeurs
  • Pub Yahoo/Google gratuite

Meilleur Hébergeur par catégorie

  • Hébergement Professionnel France
  • Hébergement Professionnel US
  • Hébergement Serveur Privé France
  • Hébergement Serveur Privé US
  • Hébergement Dédié France
  • Hébergement Dédié US
  • Hébergement Mutualisé France
  • Hébergement Mutualisé US
  • Hébergement pas cher
  • Hébergement Windows
  • Hébergement Linux
  • Hébergement PHP
  • Hébergement Email
  • Hébergement ASP
  • Hébergement Joomla
  • Hébergement SPIP
  • Hébergement Prestashop
  • Hébergement Wordpress
  • Hébergement Budget US
  • Hébergement Blog

Guide Hébergement Web

  • Annuaire des Hébergeurs Web
  • Le guide Top10Hébergeurs
  • L'avis des utilisateurs
  • Soumettre un avis sur un hébergeur
  • Contactez-nous
  • Rejoignez-notre mailing list

Outils Webmasters

  • Référencer votre hébergeur
  • Boîte à outils SEO
  • Glossaire
  • Outils-web.com

Publicité

Ressources

  • Comparatif Hébergement
  • Cartes de voeux
  • Réduction Price-Minister
  • Hébergement Professionnel
  • Annuaire Hébergement
  • Ma Revue Web
  • Tirages photos gratuits
  • HostPapa
  • Code reduction
  • Ex2 Hébergeur Web
  • Infomaniak
  • Optimisez votre site web
  • Pagerank et outils SEO
  • JustHost
  • Meilleur VPN
Comparatif Hébergement | Articles Hébergement | Guide Hébergeurs | Avis Hébergement | TOS |
A propos | Contact | Sitemap

Copyright © 2003 - 2014 Top 10 Hébergeurs - Mind The Web, Inc.


Hébergement de site - Hébergement Asp - Solo Windows

Amen.fr
  • Business Apps
  • WebMail
  • Revendeurs
  • Renouvellements
  • Assistance
  • Déconnexion
    Espace client

    Mot de passe oublié?

  • Domaines
    Domaines

    Créez votre identité sur le web

    • Enregistrements
    • Transferts
    • Nouveaux domaines
    • Pré-enregistrement
    • Domaines expirés
    • Evaluation
    • Pack Web Nom+
    • Domaine Premium
    Protection de domaine

    Protégez votre marque sur le web

    • Gestion de domaines
    • Récupération
    • TM Clearinghouse
    • Revendeurs
    • Nos clients
    • Contacts

    Informations

    Nouveaux domaines

    Plus de 700 nouvelles opportunités

    • Enregistrement privé
    • Toutes les extensions
    • Quel domaine choisir
    • Questions fréquentes
    • Renouvellements
  • Serveurs
    Cloud VPS

    Contrôle et puissance selon vos exigences

    • Configurer et acheter un serveur privé
    • Besoin d'aide?
    Serveurs dédiés

    Performance, sécurité et fiabilité

    • Dell Dual 3220
    • Dell Dual DS1.5
    • Dell Quad E3-1230
    • Dell Dual Hex DS6.5
    • Besoin d'aide?

    Informations

    • Systemes de paiements
    • Ferme de Serveur
    • FAQ
  • Email
    Email

    Créez vos boîtes mail personnalisées

    • Comparatif
    • Starter
    • Professional
    • WebMail
    • 10/100/500 email
    • Antivirus + antispam

    Informations

    • WebMail Accéder
    • Question fréquentes
    • Renouveler vos comptes
    • Configuration du compte
  • Hébergement
    Hébergement

    Toute la souplesse dont vous avez besoin

    • Starter
    • Professional
    • Premium
    • Comparatif Linux
    • Comparatif Windows
    • App Manager
    • Version d'essai
    APPS

    Donnez vie à votre espace web en un clic

    • Wordpress Blog
    • Joomla CMS
    • Prestashop Ecommerce
    • Version d'essai
    • Drupal CMS
    • PhpBB Forum
    • ZenPhoto Gallery

    Informations

    • Parternaires
    • Fiabilité
    • Questions fréquentes
    • Renouvellements
  • Office 365 new!
    Office 365

    Travailler et partager.

    • Panoramique
    • Qu'est-ce qu'Office 365?
    • Comparez les formules
    • Pourquoi Office 365
    • Exchange
    • Sharepoint
    • OneDrive
    • Lync

    Informations

    • Support
  • Création de site
    Cloud Site

    L'outil de dernière génération pour la création de sites

    • Panoramique
    • Explorez
    • Achetez
    • Comparez les formules
    • Support
    • Essai gratuit
    WebSite

    Créez votre site web professionnel

    • Starter
    • Professional
    • Premium
    • Comparatif
    • Avantages
    • Version d'essai
    E-commerce

    Ouvrez votre eBoutique et faîtes des affaires sur le web

    • Starter
    • Professional
    • Premium
    • Platinum
    • Comparatif
    • Pourquoi nous choisir
    • Clés En Main

    Informations

    • Question fréquentes

    APPS

    Donnez vie à votre espace web en un clic

    • Essai gratuit
    • Wordpress Blog
    • Joomla CMS
    • Prestashop Ecommerce
  • Sécurité
    SiteLock

    La solution idéale pour défendre votre site

    • Défendre votre site
    • Caractéristiques
    • Comparaison
    SSL Certificats

    Votre business en ligne plus sûr

    • SSL123
    • SSL Web Server
    • SSL Web Server Wildcard

    Informations

    • Guides de SiteLock
    • FAQ SiteLock
    • FAQ SSL Certificats
  • Référencement
    Marketing Online

    Augmentez le nombre de visites de votre site

    • Publicité sur Facebook
    • Publicité sur Youtube
    • Publicité sur Adwords
    • SEO

Hébergement Solo Windows

Pack hébergement sans nom de domaine

Souscrivez à un hébergement sans nom de domaine. Vous l'associerez plus tard à un nom de domaine présent dans votre espace client.
Caractéristiques | Starter | Professional | Premium
Système | Windows Server 2012 R2 | Windows Server 2012 R2 | Windows Server 2012 R2
Web Server | Microsoft IIS 8.5 | Microsoft IIS 8.5 | Microsoft IIS 8.5
Dedicated application pools | Oui | Oui | Oui
Espace disque | 2Go | 100Go | 1.000Go
Trafic mensuel web/FTP (entrant/sortant) en Go Info
Aussi appelée largeur de bande passante; équivaut au nombre de visiteurs que votre site peut recevoir.
 100 500 illimité
Hébergement Alias | 3 | illimité | illimité
Tolérance d'erreur | inclus | inclus | inclus
Architecture cluster | inclus | inclus | inclus
Distribution de charge | inclus | inclus | inclus
Alias de domaines | 1 | illimité | illimité
Sous-domaines | illimité | illimité | illimité
Enregistrement de nom de domaine | 1 | 1 | 1
Support WebMatrix Info
Instrument de développement Microsoft pour la publication de sites dynamiques supportant des applications open source. Le service peut être activé à la demande.
 Oui Oui Oui
Support Visual Studio 2013 | Oui | Oui | Oui
.NET Trust Level Info
Si vous souhaitez activer le mode Full Trust pour votre application, vous devez entrer le <trust level="Full"/> entre les balises <system.web> de ligne présente dans votre web.config de fichier
Full trust Full trust Full trust
Système & Langages | Starter | Professional | Premium
ASP.NET | 3.5\4.5.1 | 3.5\4.5.1 | 3.5\4.5.1
Classic ASP | Oui | Oui | Oui
SilverLight | 5 | 5 | 5
Ajax\LINQ | Oui | Oui | Oui
SSI | Oui | Oui | Oui
ASP.NET MVC | 5 | 5 | 5
IIS Media Services | Oui | Oui | Oui
PHP | 5.6.\5.5\5.4\5.3 | 5.6.\5.5\5.4\5.3 | 5.6.\5.5\5.4\5.3
Perl | 5.16 | 5.16 | 5.16
Python | 2.7 | 2.7 | 2.7
Node.js | Oui | Oui | Oui
Tout voir
Cacher
Composants de serveur | Starter | Professional | Premium
CDOSYS | Oui | Oui | Oui
AspEmail - AspEmail.Net | Oui | Oui | Oui
AspUpload | Oui | Oui | Oui
AspPDF | Oui | Oui | Oui
Asp AdRotator | Oui | Oui | Oui
AspJpeg | Oui | Oui | Oui
Microsoft Chart Controls | Oui | Oui | Oui
WebSocket | Oui | Oui | Yes
Dynamic IP Restrictions | Oui | Oui | Oui
IIS Smooth Streaming | Oui | Oui | Oui
GZip Compression | Oui | Oui | Oui
Base de données MySQL | Starter | Professional | Premium
Bases de données | 1 | 10 | 50
Version | 5 | 5 | 5
Espace de base de données | 1Go | 2Go | 5Go
Nombre d'utilisateurs | Illimité | Illimité | Illimité
MySQL Connector ODBC | Oui | Oui | Oui
MySQL Connector .NET | Non | Oui | Oui
Requêtes par heure par utilisateur | Illimité | Illimité | Illimité
PhpMyAdmin | Oui | Oui | Oui
Tout voir
Cacher
Base de données SQL Server 2008 | Starter | Professional | Premium
Base de données - 2 10
Espace de base de données - 50Mo 100Mo
Espace de log de transaction - 25Mo 50Mo
Nombre d'utilisateurs - 2 illimité
MyLittleAdmin - Oui Oui
MyLittleBackup, sauvegarde sur requête - Oui Oui
MyLittleBackup, sauvegarde programmée - Oui Oui
Tout voir
Cacher
Outils de gestion | Starter | Professional | Premium
Gestionnaire de fichiers | Oui | Oui | Oui
Utilisateurs FTP Info
Le FTP sert à envoyer des fichiers entre votre ordinateur et nos serveurs dans les deux sens.
 illimité illimité illimité
Fichiers protégés par mot de passe Info
Vous pouvez protéger avec un mot de passe des zones de votre site en utilisant un assistant dans l'espace client.
 Oui Oui Oui
Contrôle de trafic | Oui | Oui | Oui
Contrôle de l'espace de stockage | Oui | Oui | Oui
WebDav | Oui | Oui | Oui
Cron | No | Oui | Oui
IIS Remote Administration Info
L'Hébergement Windows de Amen supporte la gestion à distance de votre site web. Le service peut être activé à la demande.
 Oui Oui Oui
Web Deploy | 3.5 | 3.5 | 3.5
Tout voir
Cacher
Outils de marketing | Starter | Professional | Premium
Statistiques Info
Toutes nos offres d'hébergement comprennent des outils statistiques comme AWStats ou Urchin 7.
 AWStats AWStats Urchin 7
Outils développeurs | Starter | Professional | Premium
Habiliter/désabiliter la navigation par dossiers | Oui | Oui | Oui
Tâches CRON | Non | Oui | Oui
Tools | Starter | Professional | Premium
BlogEngine.NET | Supporté | Supporté | Supporté
DasBlog | Supporté | Supporté | Supporté
Sécurité | Starter | Professional | Premium
Pare-feu physique | Oui | Oui | Oui
Sauvegarde journalière | Oui | Oui | Oui
Accès aux fichiers de sauvegarde | Non | Oui | Oui
Support | Starter | Professional | Premium
Garantie de remboursement pendant 10 jours | Oui | Oui | Oui
FAQ Info
Accédez à notre base de connaissance 24/7 en ligne.
Vous trouverez des conseils et du support sur divers sujets associés à vos produits et services, ainsi que des tutoriels vidéo.
 Oui Oui Oui
Prix annuel HT | à partir de 24,00 € | à partir de 60,00 € | à partir de 132,00 €
Prix annuel TTC | à partir de 28,80 € | à partir de 72,00 € | à partir de 158,40 €

Packs d'hébergement complets

Nom de domaine gratuit pendant un an, comptes de messagerie, application Ecommerce et WebSite inclus dans chaque pack d'hébergement

  • Starter
  • Professional
  • Premium

Caractéristiques

  • Partenaires technologiques
  • 99,9% de disponibilité
  • Sécurité maximale
  • Contrôles 24/7
  • Espace client multifonctions
  • Statistiques avancées Urchin
Partager sur Facebook, Twitter, etc

Amen, keep it simple!

Internet transforme nos vies et notre façon de travailler. Voilà pourquoi nous évoluons vers des solutions toujours plus fiables, originales et intuitives.

En savoir plus sur Amen »

Copyright © 1999 - 2015 Amen

Amen du groupe Dada

  • Français
  • Português
  • Nederlands
S'abonner à notre newsletter

En vous abonnant vous acceptez nos clauses de confidentialité

A propos d'Amen
  • A propos
  • Nos implantations
  • Nos partenaires
  • Données Personnelles
  • Mentions légales
  • Amen recrute
  • Assistance
  • Nos tarifs
  • Nous contacter
  • Presse
  • Options de paiement
  • Conditions Générales
  • Formulaire de renonciation
Information

Nos experts sont disponibles à tout moment pour vous aider !
Vous pouvez commander les produits souhaités directement sur notre site ou par téléphone:

0811 88 77 66

Du lundi au vendredi 9h - 19h (appel local)

Suivez-nous:

Facebook Twitter Google+ LinkedIn Youtube
Ouvrir Fermer le plan du site

Amen - Plan du site

Domaines

  • Domaines
  • Enregistrements
  • Transferts
  • Nouveaux domaines
  • Pré-enregistrement
  • Domaines expirés
  • Evaluation
  • Pack Web Nom+
  • Domaine Premium
  • Protection de domaine
  • Gestion de domaines
  • Récupération
  • TM Clearinghouse
  • Revendeurs
  • Nos clients
  • Contacts

Serveurs

  • Cloud VPS
  • Configurer et acheter un serveur privé
  • Besoin d'aide?
  • Serveurs dédiés
  • Dell Dual 3220
  • Dell Dual DS1.5
  • Dell Quad E3-1230
  • Dell Dual Hex DS6.5
  • Besoin d'aide?

Email

  • Email
  • Comparatif
  • Starter
  • Professional
  • WebMail
  • 10/100/500 email
  • Antivirus + antispam

Hébergement

  • Hébergement
  • Starter
  • Professional
  • Premium
  • Comparatif Linux
  • Comparatif Windows
  • App Manager
  • Version d'essai
  • APPS
  • Wordpress Blog
  • Joomla CMS
  • Prestashop Ecommerce
  • Version d'essai
  • Drupal CMS
  • PhpBB Forum
  • ZenPhoto Gallery

Office 365

  • Office 365
  • Panoramique
  • Qu'est-ce qu'Office 365?
  • Comparez les formules
  • Pourquoi Office 365
  • Exchange
  • Sharepoint
  • OneDrive
  • Lync

Création de site

  • Cloud Site
  • Panoramique
  • Explorez
  • Achetez
  • Support
  • Essai gratuit
  • WebSite
  • Starter
  • Professional
  • Premium
  • E-commerce
  • Starter
  • Professional
  • Premium
  • Platinum
  • Clés En Main

Sécurité

  • SiteLock
  • Défendre votre site
  • Caractéristiques
  • Comparaison
  • SSL Certificats
  • SSL123
  • SSL Web Server
  • SSL Web Server Wildcard

Référencement

  • Marketing Online
  • Publicité sur Facebook
  • Publicité sur Youtube
  • Publicité sur Adwords
  • SEO


Hebergement Web - Guide de l'hebergement de sites web en France

SCRIPT Hebergement Web - Guide de l'hebergement de sites web en France

Forums Hebergement Web

  • Comparatif
  • Forums
  • Ajouter un hébergeur
  • S'inscrire
Changer le Style: Changer la couleur pour rouge Changer la couleur pour bleu Changer la couleur pour vert
Hebergement Web
Favoris et Partager

Bienvenue sur hebergement web ! Nous offrons un comparatif d'hébergeurs web fiable et indépendant. Vous pouvez consulter le comparatif pour choisir votre hébergeur web idéal et utiliser notre forums pour poser vos questions. N'hésitez pas à vous enregistrer pour poster des messages dans le forums. Si vous avez des questions, vous pouvez consulter notre FAQ

Hébergement
Hebergement Web Hébergement web Hebergement Gratuit Hébergement gratuit Hebergement Mutualise Hébergement mutualisé Hebergement Serveur Dedie Hébergement dédié Commentaires et avis de clients Commentaires de clients Offres detaillees Offres détaillées
Par technologies
Hebergement Linux Hébergement linux / unix Hebergement Windows Hébergement windows Hebergement PHP Hébergement php Hebergement Asp/.NET Hébergement asp/.NET
Infos complémentaires
Noms de domaines Conception de sites web Ressources
Publicité
Hebergeur Web Recommande
Offres Spéciales
infomaniak.fr
60gb d'espace, profitez de 10 mois gratuit pour un transfert de site, bande passante illimitée, ftp, mysql ! Votre offre ici
Forums
Accueil des forums Hébergement Web Technique Business Communauté
» Utilisateurs Actifs: 19
0 membre(s) et 19 invité(s)
Le record de connectés est de 361, 25/08/2012 à 00h24.
Annuaire des meilleurs hébergeurs

Notre annuaire d'hébergeurs vous permet de trouver facilement l'hébergement correspondant aux besoins de votre site web. Chaque hote enregistré contient une description détaillée des possibilités qu'il offre ainsi que les commentaires des clients existants. hebergementweb.org est un site indépendant qui n'est affilié à aucun des hébergeurs mentionnés sur le site.

Hébergement gratuit | Hébergement mutualisé
Hébergement serveur dédié | Hébergement linux
Hebergement windows | Noms de domaines
Hebergement php | Hebergement asp/.NET

Offres spéciales

Voici quelques offres sélectionnées particulièrement intéressantes en provenance d'hébergeurs enregistrés sur hebergementweb.org. Cliquez sur le nom de l'hote pour accéder aux commentaires des clients.

Hébergeur | Offre
planethoster.net | Hébergement Illimité + php 5 + MySQL 4&5 + FTP illimités + Backups Externes (r1soft) + Support 24/7 + MultiDomaines => En promotion pour 5.99€/mois !

Discussions sélectionnées

Attention 1and1 - Avis - La face cachée de la société 1and1 (41 réponses)
dans Hébergement Web

Référencement Google: FAQ et ressources pour le novice (25 réponses)
dans Référencement, moteurs de recherche

Google se lance dans l'hébergement (13 réponses)
dans Hébergement Web

Software pour un forum (8 réponses)
dans Software et Scripts

Hébergement d'un blog (9 réponses)
dans Hébergement Web

Bienvenue sur HebergementWeb.org ! (8 réponses)
dans HebergementWeb.org

A propos d'hebergementweb.org

Notre site a pour vocation d'aider ses visiteurs à trouver le meilleur hébergement de site web en France/francophone correspondant à leur besoin. Que ce soit un hébergement gratuit ou payant, en serveur mutualisé ou dédié, sous Windows ou Linux, PHP ou asp, Hebergement Web propose un panel d'hébergeurs couvrant l'ensemble de la demande d'hébergement Internet professionnel, et ce, des pages perso au site officiel d'une société.

Notre annuaire et notre système d'enregistrement des hébergeurs vous permettent de rechercher et de visualiser immédiatement les différentes offres d'hébergement disponibles, ainsi que les services associés à l'hébergement comme les noms de domaines, la conception de sites web et les courriels.

Une section vous permet également de visualiser des offres d'hébergement variées fournies par les hébergeurs du répertoire. Enfin, une section vous propose divers liens et ressources ayant trait à l'hébergement professionnel de sites web.

Pour ceux nécessitant un support plus personnalisé, une réponse à une question précise d'ordre général ou technique, nos forums sont à votre disposition.
Bienvenue, Non inscrit.
Identifiant:
Mot de passe:

S'inscrire
» Rechercher Hebergeur
» Recherche avancée
» Nouvelles
Meilleur Comparatif Francophone
Jan 19, 2011 - 7:54 AM - par quentin
Depuis 2004, Hebergement web est la meilleure référence francophone pour bien choisir son hébergeur web. Clients d'un hébergeur internet, partagez votre avis! Hébergeurs, inscrivez-vous! C'est gratuit!
Top 3 Meilleurs Hébergeurs

hebergementweb.org
Notez votre hebergeur ! Enregistrer un hebergeur Publicite Echange de liens Nous contacter
Publicité
Hebergement Site Web
Partenaires
Big Boards Serveur Dédié Outils pour webmaster Hebergeur d'image Annuaire Hebergement Emploi Top 10 Hebergeurs Web Hébergement Web Hebergement site web Creation site internet Votre site ici
Comparatif Hébergement Web

Fuseau horaire GMT +2. Il est actuellement 18h36.

Nous contacter - Hebergement Web - Haut de page

Édité par : vBulletin
Copyright © 2000 - 2015, Jelsoft Enterprises Ltd. Tous droits réservés.
  • Comparatif
  • S'inscrire
  • FAQ
  • Membres
  • Calendrier
  • Recherche
  • Messages du jour
  • Marquer les forums comme lus
Hébergé par PlanetHoster
Copyright ©2004 - 2015, HebergementWeb.org. Tous les droits réservés.
Hebergement Web | Hebergement Mutualisé | Serveur Dédié | Noms de domaines
Hebergement Web offre un comparatif de solutions d'hébergement site web indépendant

Forums Hebergement Web


Top 10 Meilleurs Hébergeurs Web. Comparatif 2014-2015

Ajouter par mois Top 10 Meilleurs Hébergeurs Web. Comparatif 2014-2015

Liste d’hébergement site web

Liste de catégories d’hébergement web

Avis des utilisateurs

Articles à propos de l’hébergement web et nom de domaines

Didacticiels et tutoriels sur l’hébergement web

Main Menu
  • Accueil
  • Solutions d'Hébergement
    • Hébergeur E-commerce L'internet et le e-commerce ont radicalement modifié les moy …
    • Liste d'hébergeurs de site Web Un hébergeur site web (ou hébergeur site internet) est consi …
    • Meilleur serveur dédié On parle d’hébergement de serveur dédié (Dedicated Server) l …
    • Revendeur Hébergement Le revendeur d'hébergement est tout simplement un des différ …
    • Serveur cloud pas cher Vous en avez assez de payés pour du trafic et des ressources …
    • Serveur Privé Virtuel VPS Un serveur privé virtuel, en anglais virtual private server …
    • Tous les Types d'Hébergement Web
    • AIDER À DÉCIDER
    • Guide simple d'hébergementTrouver le meilleur hébergeur web en répondant à ces questions
    • LISTE GEOGRAPHIQUE
    • Hébergeur par régionTrouvez un hébergeur dans votre pays
    • Tout les hébergeurs de site
  • Chercher un Domaine
    • Domaine
    • Enregistrer un nom de domaineUtilisez notre outil pour trouver votre nom de domaine
    • À PROPOS DES DOMAINES
    • Comment choisir un nom de domaine pour votre site web
    • Comment fonctionne l'enregistrement de nom de domaine privé
    • Ête-vous satisfait de votre registraire de nom de domaine
    • Plus d'articles à propos des noms de domaine
  • Guide d’Achat
    • OUTILS
    • Guide d'Achat SimpleTrouver votre hébergeur web idéale en répondant à ces questions
    • Recherche Avancée d’Hébergeurs WebAvez-vous des préférences détaillées? Utilisez notre outil de recherche avancée d'hébergement web.
    • Comparer un ou plusieurs hébergeursComparer les forfaits d'hébergement web
    • Outils WebLiens vers d'autres outils Web
    • GUIDE D’ACHAT
    • 10 erreurs à éviter sur la page d'accueil
    • 10 erreurs nouveaux blogueurs Wordpress
    • 10 Pires Hébergeurs web T1 2013
    • 15 points à respecter avant de changer de template WordPress
    • 2 millions de mots de passe volés
    • Voir tous les articles
  • Avis
    • CHOIX DES CLIENTS
    • Bluehost Avis Bluehost
    • Webhostinghub Meilleur Hébergeur Wordpress
    • Arvixe Arvixe meilleur fiabilité
    • Avis du top hébergeurs
    • Voir tous les avis
    • AIDER LES AUTRES
    • Soumettre un avis
  • Coupons
    • COUPONS
    • Nos CouponsUtilisez nos offres promos exclusifs pour des prix imbattables sur l'hébergement web.
  • Apprendre
    • CENTRE D'APPRENTISSAGE
    • ArticlesTout sur l'hébergement web, noms de domaine, conception de sites Web et bien plus encore...
    • TutorielsDevenir un expert avec nos didacticiels
  • Mail

Les meilleurs hebergeurs Web 2014-2015

Bienvenue à tophebergeur.com – Le plus important comparateur indépendant d'hébergeurs web sur le net. Des renseignements et analyses en profondeur sur tous les principaux fournisseurs d'hébergement au monde accompagnés d'avis et de témoignages par de vrais clients. Recherchez et comparez les sociétés en utilisant nos outils puissants et uniques et trouver le meilleur pour votre site. Voici notre comparatif mis à jour du top 10 hébergeurs de site en France, aux États-Unis, Canada ainsi qu’ailleurs pour l'année 2014-2015.

  • Top 10
    hebergeurs Français
  • Top 10
    hebergeurs Américains
  • Top 10
    hebergeurs Canadiens

Meilleur Hébergement web professionnel en Canada

# | Hébergeur Web | Prix | Action
1 | Rapidenet | 4.50 CAD par mois | Visiter Avis
2 | Myhosting | 4.95 USD 6.45 par mois | Visiter Avis
3 | Hostpapa Canada | 3.95 CAD 7.95 par mois | Visiter Avis
4 | Planethoster Canada | 17.59 CAD par mois | Visiter Avis
- 5 | WHC | 7.95 CAD par mois | Visiter Avis

Liste complete du top 10 hébergement web Canada

Meilleur Hébergement web professionnel en France

# | Hébergeur Web | Prix | Action
1 | Ex2hosting | 3.99 EURO par mois | Visiter Avis
2 | Planethoster France | 5.99 EURO par mois | Visiter Avis
3 | 1Hebergement | 3.95 EURO 4.72 par mois | Visiter Avis
4 | Infomaniak France | 7.50 EURO par mois | Visiter Avis
5 | Mavenhosting France | 2.99 EURO 4.99 par mois | Visiter Avis
6 | Hostpapa France | 1.00 EURO 5.99 par mois | Visiter Avis
7 | Ikoula | 1.99 EURO par mois | Visiter Avis
8 | Netissime | 4.99 EURO 9.99 par mois | Visiter Avis

Liste complete du top 10 hébergement web France

Meilleur Hébergement web professionnel en Etats Unis

# | Hébergeur Web | Prix | Action
1 | Siteground | 3.95 USD 6.95 par mois | Visiter Avis
2 | Arvixe | 4.00 USD 7.00 par mois | Visiter Avis
3 | Inmotion | 5.99 USD 7.99 par mois | Visiter Avis
4 | Webhostinghub | 3.99 USD 6.95 par mois | Visiter Avis
5 | Fatcow | 3.50 USD 6.95 par mois | Visiter Avis
6 | Ipage | 1.99 USD 7.99 par mois | Visiter Avis

Liste complete du top 10 hébergement web Etats Unis

Connaitre l'hébergeur de n'importe quel site web

Avec notre outil de recherche avancé vous pouvez désormais connaitre l’hébergeur ainsi que l’emplacement du serveur de n’importe quel site internet. Il vous suffit tout simplement d’ajouter l’adresse du site dans la boite de recherche et puis cliquer sur le bouton rechercher.

Choisir un plan d'hebergement Web qui convient à votre site

Etes vous un particulier, un webmaster, ou une entreprise enquête d’hebergement (Web hosting ou encore webhost en anglais) partagé Linux / Windows ou d'un serveur dédié ou encore d'un serveur privévirtuel efficaces et abordables pour votre site ou pour votre business enligne! Cette tâche peut vous sembler bien effrayante tout particuliérement quand vous avez a choisir parmi des milliers d’hébergeurs web! Notre site a spécialement été concu pour vous fournir un guide précieux. Celui-ci vous aidera a comparer et puis dénicher l'hébergeur offrant le meilleur rapport qualité / prix.

  • Hébergement anonyme offsh …
  • Serveurs de jeux
  • Serveur dédié OpenSuse
  • Colocation serveur Housin …
  • Meilleur Serveur Privé Wi …
  • Hébergement WebDav
  • Hebergeur Ghost
  • Hebergeur Professionnel E …
  • Hebergeur Sugarcrm
  • Hébergeur Bitcoin
  • Hébergeur anti-DDOS
  • Hebergeur Concrete5

Articles

La vérité de l'hébergement illimité
La vérité de l'hébergement illimité

14 novembre, 2014

Lorsque vous entendez le terme illimité dans une offre d’hébergement, vous vous attendez certainement à des capacités de stockage illimitées, des noms … lire la suite

Point sur l'industrie

0 Commentaires

Bien choisir un hébergement web
Bien choisir un hébergement web

12 novembre, 2014

Lorsque vous créez un blog ou un site internet, vous devez faire l’acquisition d’un hébergeur web. Mais comment choisir un bon hébergeur correspondant … lire la suite

Conseil d'achat

1 Commentaires

Comment améliorer votre boutique en ligne
Comment améliorer votre boutique en ligne

17 octobre, 2014

Tout propriétaire d’un site e-commerce ne souhaite qu’une chose : que la réputation de son site grandisse. Un site connu dégage plus de clients et don … lire la suite

Webdesign et programmation

0 Commentaires

Comment satisfaire vos clients
Comment satisfaire vos clients

7 octobre, 2014

Un client satisfait est un client qui reviendra très certainement faire ses achats sur votre site de e-commerce. Il y a même de fortes chances pour qu … lire la suite

Conseil d'achat

0 Commentaires

Namecheap ou Godaddy : qui choisir?
Namecheap ou Godaddy : qui choisir?

24 septembre, 2014

Lorsque vous décidez de créer votre propre site internet, il y a une étape primordiale à respecter : celle de choisir un nom de domaine. Bien évidemme … lire la suite

Nom Domaines

0 Commentaires

Paypal vs Skrill (Moneybooker)
Paypal vs Skrill (Moneybooker)

8 septembre, 2014

Toute personne possédant ou souhaitant créer un business sur internet est amenée à se retrouver dans le cas d’opter pour tel ou tel moyen de paiement … lire la suite

Point sur l'industrie

1 Commentaires

» Plus d'Articles

Tutoriels

Comment installer SSL dans Wordpress
Comment installer SSL dans Wordpress

28 février, 2015

Tous les jours, nous révélons des informations personnelles sur internet. Rien que pendant la dernière heure, j’ai utilisé ma carte de crédit, acheté … lire la suite

Wordpress

0 Commentaires

Comment nettoyer un .htaccess hacké
Comment nettoyer un .htaccess hacké

18 février, 2015

Dans cet article nous allons discuter de mesures que vous pouvez prendre pour nettoyer et réparer un fichier .htaccess piraté. Le fichier .htaccess e … lire la suite

cPanel

0 Commentaires

Surveiller la bande passante dans whm
Surveiller la bande passante dans whm

14 février, 2015

Un des plus grands défis auquel les revendeurs doivent faire face est de savoir comment répartir les ressources du serveur entre plusieurs individus. … lire la suite

Revendeur

0 Commentaires

Modification de répertoire squelette dans WHM
Modification de répertoire squelette dans WHM

26 janvier, 2015

En tant que revendeur de l'hébergement web, vous devez saisir toutes les occasions d'apposer votre marque dans l'expérience d'hébergement. Comme il es … lire la suite

Revendeur

0 Commentaires

Ajouter des fichiers du serveur directement dans wordpress
Ajouter des fichiers du serveur directement dans wordpress

24 janvier, 2015

La page de téléchargement de fichier dans WordPress vous permet d'insérer des images, des médias vidéos ou audio dans vos articles, soit un à la fois … lire la suite

Wordpress

0 Commentaires

Ajouter un package et une liste de fonctions dans WHM
Ajouter un package et une liste de fonctions dans WHM

17 janvier, 2015

En tant que revendeur d'hébergement Web, WHM vous permet d'avoir un contrôle extrêmement précis sur les diverses caractéristiques et configurations de … lire la suite

Revendeur

0 Commentaires

» Plus Tutoriels

Différents types d’hébergement de site web

Un nombre incalculable de compagnies d’hébergement web foisonnent actuellement sur internet. Choisir un fournisseur d’hébergement web dépend du type de site web que vous désirez mettre en œuvre : un site de hobby, un blog ou un e-commerce.

Vous pourrez alors déterminer en conséquence l’hébergement adéquat. Les sites d’hébergement web les plus utilisés sont les types d’hébergement : partagé, gratuit et dédié. Les services d’hébergement gratuits imposent par exemple un emplacement de pubs indésirables et encombrantes sur les pages web de l’utilisateur qui peuvent vraiment agacer les visiteurs.

Les autres programmes d’hébergement offrent un bon support, de bonnes options et une largeur de bande passante intéressante mais requièrent des frais mensuels.

Outils Webmaster

  • Analyseur de site web
  • Ping Blog
  • Générateur De Texte Glitterfy
  • Générateur de code "ajouter aux favoris"
  • Générateur de message d'alerte (Popup)
  • Créer un menu simple en quelques clicks
  • 77 outils d'optimisation SEO

À propos de ce site

Nous sommes un groupe de webmasters professionnels écœurés et dégoutés de cette armada d’hébergeurs web sans scrupule qui abondent sur internet. Nous avons alors décidé de nous réunir et de créer un site fiable qui permette d’offrir un certain nombre d’hébergeurs web triés sur le volet, de mettre en garde le visiteur sur les pièges et subterfuges présents dans le monde de l’hébergement web et de le guider vers l’hébergement qui correspond le mieux à ses attentes.

Pour élever des fournisseurs de services d’hébergement au rang du top 5 ou 10, nous avons évalué d’autres critères basés sur:

  • L’ancienneté de l'hébergeur dans le domaine de l’hébergement site web
  • La fiabilité de l’infrastructure d’hébergement et l’échelle de commodités d’accès aux données
  • Le coût mensuel du programme d’hébergement web et les frais d’installation
  • Les caractéristiques-clé de l’hébergement : l’espace de disque, la largeur de bande, les fonctionnalités côté serveur, la disponibilité d’un e-commerce, d’autres services extras gratuits tels que des modèles de conception de sites, un marché internet et des moyens de promotion de site.
  • Le nombre de récompenses et d’honneurs
  • La facilité d'utilisation
  • Le panneau de configuration: Cpanel, Plesk etc.
  • Le nombre de clients de l'hebergeur web
  • Les niveaux de satisfaction des clients (des témoignages)
  • Le niveau d’assistance aux clients

Vous trouverez ici toutes les informations utiles sur les services du type “hébergement web professionnel” ou “serveurs dédiés” et des critiques sur les meilleurs hébergements web présents sur le web

L’hébergement de site partagé

Un grand nombre de webmasters choisissent l'option mutualisée pour héberger leurs site internet. Ce type permet d’accueillir plus d’un client sur un seul et même serveur. On peut bénificier de plusieurs avantages comme avoir la possibilité de travailler avec différents langages de serveur tels que : ASP, PHP, MySQL. De plus, une importante largeur de bande passante et un nombre important d’adresse email.

Un hébergeur gratuit ou un hébergeur internet payant!

Les bannières de pubs sont monnaie courante dans l’hebergement web gratuit (comme par exemple 000webhost qu'on déconseil fortement). Il n’existe que très peu de fournisseurs gratuits qui fournissent de bonnes options. Il ne s’agit cependant que d’exceptions à la règle. La plupart des programmes d’hébergement web gratuits n’offrent pas aux utilisateurs des bases de données MySQL, plusieurs comptes email ou la possibilité d’utiliser tous les langages de serveur. Le type de domaine qu’on obtient sur un hébergement gratuit est typiquement un sous-domaine (votresite.exemplenomdedomaine.com) ou sous forme d'un annuaire (www.tophebergeur.com/~votresite). Nous vous recommandons vivement d’éviter ce genre d’hébergement de site. Vous n’en serez que plus satisfait et apaisé

L’hébergement web dédié - serveurs dédiés

L’hébergement dédié - location de serveurs dédiés - est une bonne option pour quiconque qui veut avoir un contrôle total de l’ensemble du serveur. Vous bénicierez ainsi de la performance, de l'indépendance et de la felxibilité. Sachez aussi qu’il existe certaines catégories : Un serveur géré est lorsque l'hébergeur se charge de la gestion et de la maintenance du serveur. L'utilisateur peut choisir de se charger d'adminsitrer lui même le serveur. Néanmoins, l’hébergement dédié non-géré est compliqué et exige plus de temps et de connaissances techniques approfondies.

Il s’agit – là d’un bref résumé d’une pléthore de compagnies d’hébergement de site web. Oui, nous l’admettons, dénicher le meilleur service qui réponde au mieux à nos besoins est une tâche fort laborieuse. En premier lieu, sachez que la fonction de votre site web déterminera le type d’hébergement internet. Puis, les caractéristiques, le support, la fiabilité et le contrôle décident du prix. Vous pouvez parcourir notre site et comparer entre plusiers hébergeurs de site, en trouver un qui vous convienne et au final, avoir votre site en ligne.

En apprendre plus sur les hébergeurs de site internet

Nous sommes fiers de partager avec vous notre savoir sur ce sujet. Nous vous invitons à consulter nos articles et à en connaitre davantage sur ce vaste domaine qu’est le web. Vous découvrirez ses faces cachés et apprendrez entre autres à mettre en place un site web et les différents types d’hébergeurs internet présents sur le marché. Soyez assurés d’un savoir complet et régulièrement mis à jour par notre formidable équipe soucieuse de vous offrir le meilleur de leurs compétences de pointe dans ce domaine.

Un aperçu de notre comparatif d'hebergement web

Vous trouverez sur ce guide une analyse fine, précise et de qualité hautement professionnelle sur ce que nous jugeons être les meilleurs hebergeurs sites web du marché ou encore le top hébergeur . D’abord et avant tout, jamais nous ne vous recommanderons un service d’hebergement de site sans l’avoir préalablement essayé ou accumulé assez d'informations et de données sur lui. En effet, nous gérons des sites hébergés sur des fournisseurs qui figurent au meilleur top 5 ou top 10. Vous disposez là de la toute première analyse d’experts sur les services d’hébergement de qualité supérieure et à moindre coût. Les tableaux comparatifs, vous permettent d'avoir un aperçu rapide et facile des différents plans et offres. Vous aurez aussi la possibilité de consulter l'avis des autres utilisateurs et webmasters.

Les hébergeurs site web qui sont proposés ici sont localisés un peu patout dans le monde, principalement en France aux États Unis au Canada et en Suisse. Nous tenons à vous fournir uniquement l’information nécessaire dont vous avez besoin pour effectuer un choix judicieux et éclairé de la meilleure compagnie pour votre site. Vous cherchez un hébergeur mutualisé Français ou un hebergeur Américain, un hebergeur dédié en France ou aux États Unis ou encore vous voulez héberger votre boutique en ligne. vous aurez sans doute l'opportunité de choisir un parmi les tops (Top 10 ou top 5). Nous faisons de notre mieux pour rendre le contenu de ce site agréable, simple et surtout utile. Nous sommes convaincus que le lire vous fera épargner beaucoup de temps, d’argent et de tracas inutiles! Le plus important est que vous trouviez le fournisseur idéal qui répond au mieux à vos besoins. Sachez aussi que les critères de classement et comparatif des hébergeurs de site ne sont pas seulement basés sur le prix et les caractéristiques du service.

Notre garantie

Parce que des milliers de visiteurs affluent chaque jour sur notre site, nous sommes en mesure de négocier les tarifs d’hébergement web les plus avantageux avec les fournisseurs. Vous êtes ainsi assurés de bénéficier des meilleurs services d’hébergement au prix le plus bas sur tophebergeur.com.

La décision de choisir un hébergeur web incombe à l'acheteur: Notre site n'est qu'un guide et un annuaire des hébergeurs web et nous ferons de notre mieux pour vous procurer les meilleurs conseils pour choisir un plan d'hébergement qui répond au mieux à vos besoins.

Nous vous recommandons fortement de faire une recherche exhaustive avant de prendre votre utltime choix.

Notre site n'assumera aucune responsabilité sur ce qui peut arriver avec votre hébergeur par la suite

Note: il arrive que certains des hébergeurs de site listés sur notre annuaire nous donnent des commissions sur les ventes générées à partir de notre site.

Derniers Articles

  • La vérité de l'hébergement illimité
  • Bien choisir un hébergement web
  • Comment améliorer votre boutique en ligne
  • Comment satisfaire vos clients
  • Namecheap ou Godaddy : qui choisir?

Derniers Tutoriels

  • Comment installer SSL dans Wordpress
  • Comment nettoyer un .htaccess hacké
  • Surveiller la bande passante dans whm
  • Modification de répertoire squelette dans WHM
  • Ajouter des fichiers du serveur directement dans wordpress

Catégories Webhosting

  • Hébergeur Prestashop
  • Meilleur Hébergeur Sharepoint
  • Meilleur Hébergeur Joomla
  • Hébergement Wordpress
  • Hébergement Xoops

Meilleurs Hébergeurs

  1. Siteground
  2. Arvixe
  3. Bluehost
  4. Webhostinghub
  5. Inmotion
  6. Ex2hosting

Copyright http://www.tophebergeur.com/ © 2008-2014. Tous droits réservés

  • Mentions légales
  • Sitemap


Hébergement internet - WebsiteOut

Hebergement

Commandez votre hebergement
Commande - Etape 1/4
Pour passer commande de votre hébergement remplissez simplement notre formulaire ci-dessous.

Choisissez votre nom de domaine :
http:// www . | exemple : monsiteweb . com
vous possédez déja ce nom de domaine et désirez l'utiliser pour héberger votre site | vous souhaitez que WebsiteOut crée ce nom de domaine pour vous
Nous enregistrerons gratuitement votre nom de domaine en .com, .net, .org, .info, .biz, .co.uk, .org.uk, .me.uk, .be, .ch, .de, .us, .fr, .eu, ou .ca
Pour les domaines en .com, .net, .org, .info, .biz, .be, .co.uk, .org.uk, .me.uk et .ch aucune condition particulière ne s'applique.
Pour bénéficier d'un domaine en .de, vous devez être résident en Allemagne.
Pour bénéficier d'un domaine en .us, vous devez être résident aux Etats-Unis.
Pour bénéficier d'un domaine en .ca, vous devez être résident au Canada.
Pour bénéficier d'un domaine en .fr ou .eu, vous devez être résident d'un pays Européen.
Exemple de sites

Questions? Contactez nous. © Copyright 2000-2010 WebsiteOut - Tous droits réservés.
Lire notre Déclaration de confidentialité et nos Conditions générales de vente.
WebsiteOut est une marque déposée
Nous acceptons les paiements par Carte de Crédit, Paypal, Chèque et Virement.


Hébergement - Exemple de sites

Hebergeur
Exemple de sites

Nous hébergeons les sites Internet de particuliers, d'entreprises, d'associations et d'organisations gouvernementales.

Vous trouverez ci-dessous un exemple de quelques sites que nous hébergeons.
Cliquez ici pour accéder au site Cliquez ici pour accéder au site Cliquez ici pour accéder au site Cliquez ici pour accéder au site Cliquez ici pour accéder au site Cliquez ici pour accéder au site Cliquez ici pour accéder au site Cliquez ici pour accéder au site Cliquez ici pour accéder au site Cliquez ici pour accéder au site Cliquez ici pour accéder au site Cliquez ici pour accéder au site Cliquez ici pour accéder au site Cliquez ici pour accéder au site Cliquez ici pour accéder au site Cliquez ici pour accéder au site

Questions? Contactez nous. © Copyright 2000-2010 WebsiteOut - Tous droits réservés.
Lire notre Déclaration de confidentialité et nos Conditions générales de vente.
WebsiteOut est une marque déposée
Nous acceptons les paiements par Carte de Crédit, Paypal, Chèque et Virement.


Hébergement internet | Comment nous contacter

Accueil Hébergement
 | Vous trouverez ci-dessous la liste des adresses e-mail auxquelles vous pouvez nous contacter. N'hésitez pas à nous écrire, notre équipe professionnelle et dynamique se fera un plaisir de vous répondre.
 |  | Direction WebsiteOut : direction@websiteout.net Service commercial : vente@websiteout.net Développement de partenariat : partenaire@websiteout.net Support technique : support@websiteout.net Développement et design du site: webmaster@websiteout.net
Retourner à la page d'accueil
Exemple de sites hébergés

Questions? Contactez nous. © Copyright 2000-2010 WebsiteOut - Tous droits réservés.
Lire notre Déclaration de confidentialité et nos Conditions générales de vente.
WebsiteOut est une marque déposée
Nous acceptons les paiements par Carte de Crédit, Paypal, Chèque et Virement.


Prix hébergement web et nom de domaine - Hébergements internet mutualisés php - mysql

Nous mettons à votre disposition l'offre d'hébergement la plus complète afin de vous permettre une présence optimale sur Internet.
Détail de notre offre d'hébergement : Commander votre hébergement

Hébergement

 Messagerie
50 à 500 Mo d'espace disque | Comptes mail pop
Accès FTP privé 24h/24 | Alias illimités + Alias collecteur
Trafic illimité | Redirections
Hébergement ouvert immédiatement | Double Anti-virus + Anti-spam
Mise en service offerte | Sécurisation 128 bits POP-SSL et SMTP-SSL
Statistiques de fréquentation en option
Bande passante à très haut débit (110 Gb/s) | Configuration Technique
Sauvegarde | Serveurs Linux (100% compatible avec PC et Mac)
Support technique 24h/24 | Apache
Inscription de votre site dans Google, YAHOO!,
msn, voila, altavista, alltheweb 		PHP + ZendOptimizer
Serveurs hautes performances
Redondances réseau
Nom de domaine de votre site web
Frais d'enregistrement inclus, frais Internic inclus | Base de Données
Frais de transfert offerts | Base MySQL
Sous-domaines illimités | Interface de gestion (phpMyAdmin)

N'attendez plus, bénéficiez dès
aujourd'hui d'un hébergement de qualité
Exemple de sites

Questions? Contactez nous. © Copyright 2000-2010 WebsiteOut - Tous droits réservés.
Lire notre Déclaration de confidentialité et nos Conditions générales de vente.
WebsiteOut est une marque déposée
Nous acceptons les paiements par Carte de Crédit, Paypal, Chèque et Virement.


Hébergeur - Hebergement de site web - La qualité a petit prix - WebsiteOut

Trouver un hébergeur de qualité pour votre site web devrait toujours être aussi facile. Nos offres incluent :

50, 100, 200 Mo d'espace d'hébergement et plus
Votre nom de domaine offert
Nombre illimité de sous-domaines
Traffic illimité
Protection anti-virus+anti-spam de vos comptes mail
Aucune publicité insérée sur votre site
Frais de mise en service offerts
Support technique 7j/7 sans frais
Inscription de votre site dans Google, YAHOO!,
msn, Bing, voila, altavista, alltheweb

Le tout à partir de seulement 53 € par an, tout compris.

Voir le détail de notre offre d'hébergement
Voir quelques-unes de nos références :

Choisissez votre nom de domaine :
http://www . |
 | exemple : http://www.monsiteweb.com
Votre Hébergement
Nous offrons un service exceptionnel
et personnel pour tous vos projets Web.
Notre hébergement est économique,
performant et professionnel.

Voir le détail de notre offre

Voir quelques sites hébergés

hebergement site - satisfait ou remboursé
Notre Technologie
Nos serveurs sont paramétrés de manière à vous offrir d'excellentes performances. Nous avons fait le choix des logiciels les plus performants et les plus sûrs du marché : Linux, Apache, PHP, MySQL, ProFtpd, QMail

En savoir plus sur notre technologie

Notre Connectivité
La configuration de nos serveurs Linux vous garantissent un temps d'accessibilité record. Notre réseau est architecturé de telle sorte que nous anticipons les besoins en augmentant continuellement et en avance nos capacités.

En savoir plus sur notre connectivité

Vos Questions (et les réponses)
Vous trouverez ici les réponses à toutes vos questions.

Consulter les FAQs

Questions? Contactez nous. © Copyright 2000-2010 WebsiteOut - Tous droits réservés.
Lire notre Déclaration de confidentialité et nos Conditions générales de vente.
WebsiteOut est une marque déposée
Nous acceptons les paiements par Carte de Crédit, Paypal, Chèque et Virement.
Service édité par WEBSITEOUT (tm)


Tout savoir sur l'hébergement de site web | Hébergeur | WebsiteOut

Hebergeur
Hebergeur

I. Questions relatives à l'hébergement, au supports, à la programmation, aux spams, accès FTP, ...

  1. Qu'est-ce que l'hébergement de sites web ?

    Nous hébergeons des sites web pour des particuliers, des associations, des entreprises et des professionnels. Autrement dit, nous louons de l'espace disque et des ressources système sur nos serveurs pour ces sites. C'est notre role d'hébergeur d'assurer que votre site sera bien visible sur Internet partout dans le monde. Le choix d'un bon hébergeur est important.

  2. Est-il possible d'avoir un exemple de quelques-uns des sites que vous hébergez ?

    Nous hébergeons les sites de diverses organisations, sociétés et particuliers. Vous pourrez visualiser quelques uns des sites que nous hébergeons en cliquant ici.

  3. Comment puis-je commander un hébergement pour mon site internet ?

    Il vous suffit simplement de vous rendre sur la partie bon de commande et de compléter celui-ci sans omettre de compléter chaque champ.
    Pour commander votre hébergement, cliquez ici !

  4. J'habite au Canada, puis-je héberger mon site chez vous ?

    Oui ! Quelque soit l'endroit où vous habitez, nous pouvons héberger votre site.

  5. Mon site sera t-il visible depuis n'importe quel pays ?

    Biensûr, votre site sera visible depuis n'importe quel endroit de la planète.

  6. Vos serveurs sont sous Linux mais mon PC est sous Windows, cela posera t-il un problème ?

    Absolument pas. Nos serveurs tournent sous Linux pour des raisons de sécurité et de performance. Mais vous pouvez concevoir votre site sur votre PC Windows ou Mac, nous l'hébergerons sans problème.
    En bref, le fait que nos serveurs soient sous Linux ne sera absolument pas un obstacle (bien au contraire).

  7. Votre offre inclu t-elle l'enregistrement de mon nom de domaine ?

    Oui, en effet. Nous nous chargerons d'enregistrer gratuitement (sans aucun frais supplémentaire pour vous !) votre nom de domaine en .com, .net, .org, .biz, .info, .be, .ch, .de, .fr, .eu, .us, .ca, .co.uk, .org.uk ou .me.uk

  8. Je possède déjà un nom de domaine, sera t-il possible d'héberger mon site ?

    Oui. Nous vous indiquerons les démarches à suivre dans ce cas.

  9. Pouvez-vous héberger n'importe quelle extension de nom de domaine ? (.fr, .ch, .uk, par exemple ?)

    Tout à fait. Quelque soit l'extension de votre nom de domaine (votresite.fr, votresite.ch, ou autre), nous pouvons l'héberger.

  10. Le support technique est-il gratuit ?

    Le support technique est effectivement gratuit. Toutefois nous vous invitons à consulter les F.A.Q. avant d'écrire au support technique.
    Nous sommes responsables du bon fonctionnement des serveurs, des comptes des clients et de toutes les options qui s'y rattachent. Vous pouvez faire appel au support technique en tout temps lorsque vous avez un problème ou qu'une fonctionnalité de votre site ne semble pas être opérationnelle.
    Attention, l'équipe du support technique ne s'occupe pas des problèmes de programmation. Ceci inclut par exemple les scripts HTML, CSS, PHP, l'utilisation des fichiers type .htaccess et .htpasswd

  11. Avez-vous un service de conception de sites web ?

    Oui. Envoyez un e-mail à notre service commercial si vous souhaitez plus d'informations sur ce sujet.

  12. Peut-on mensualiser le règlement ?

    Pour faciliter la gestion de notre comptabilité, la facturation est annuelle.

  13. Acceptez-vous d'héberger des sites pour adultes ?

    En aucun cas nous acceptons d'héberger des sites X, pornographiques, ayant trait à la pédophilie, à la xénophobie. Des hébergeurs spécialisés autorisent ce genre de sites, nous n'en faisons pas partie.

  14. J'héberge un site pornographique chez vous ! Que peut-il m'arriver ?

    Nous nous réservons le droit de couper le site en question, sans délais d'attente ou préavis.

  15. Puis-je utiliser mon hébergement dans une opération de SPAM ?

    Non. Le spam est illégal. Si vous utilisez votre hébergement pour faire du spam ou si votre site prend part à une opération de spam, nous le désactiverons immédiatement et sans préavis.

  16. Les fichiers FLASH (.swf) sont-ils supportés ?

    Oui, nos modules supportent dans leur ensemble vos créations sous Flash.

  17. Puis-je activer la partie E-mail de mon module d'hébergement uniquement ?

    Nous activons l'ensemble de votre domaine dès la réception de votre commande. Libre à vous, à partir de ce moment, d'en utiliser que la partie relative à vos comptes de courrier électronique.

  18. Dois-je disposer d'une adresse IP pour commander un hébergement chez WebSiteOut ?

    Non, absolument pas ! Il n'est pas du tout nécessaire de disposer d'une adresse IP pour s'héberger chez WebSiteOut, nous nous occupons de vous en affecter une.

  19. J'ai commandé un hébergement chez WebSiteOut, dans combien de temps puis-je transférer mes fichiers ?

    Notre politique est de vous permettre de mettre votre site en ligne le plus vite possible. Nous ouvrirons votre hébergement immédiatement après que vous avez remplit notre formulaire de commande.

  20. Mes fichiers sont en place sur vos serveurs, mon domaine n'est pas encore actif, puis-je déjà visualiser mon site sur Internet ?

    Oui ! Nous vous fournirons une adresse à laquelle vous pourrez visualiser votre site, avant même que votre nom de domaine soit actif.

  21. A partir de quel moment serai-je facturé pour les services commandés ?

    Vous serez facturé à partir de l'activation de votre commande chez WebSiteOut.

  22. Les 3 w (www.) sont-ils nécessaires pour accéder à mon site ?

    Non, chez WebSiteOut il n'est pas nécessaire d'encoder votre URL avec les 3 w, votresite.com fera tout aussi bien l'affaire sur votre naviguateur... sympa n'est-ce pas ?

  23. Qu'est-ce qu'une page d'erreur ?

    Comme son nom l'indique une page qui apparaît lorsque l'url encodé par un de vos visiteurs est erronée; en général il s'agit d'une page par défaut indiquant la fameuse erreur 404 "cette page n'existe pas!" ... Vous l'avez certainement déjà rencontrée. Il en existe de différents types, mais la plus connue est la 404.

  24. La mise en place d'une page d'erreur sur vos serveurs est-elle gratuite ?

    Oui, cette opération est entièrement gratuite.

  25. Puis-je mettre en place ma propre page d'erreur 404 ?

    Vous pouvez paramétrer vous-même votre page erreur 404 de la manière suivante :
    Personnalisez votre page erreur 404 en HTML. Enregistrez-la dans un fichier nommé 404.html et stockez-la dans le répertoire web de votre site. Simple, non ?

  26. Quelle est la bande passante chez WebSiteOut ?

    Notre réseau mondial est architecturé et surveillé de telle sorte que nous anticipons les besoins en augmentant continuellement et en avance nos capacités.
    Suite au récent déploiement de notre nouveau ring européen basé sur des liens OC48, nous améliorons encore notre connectivité et notre redondance puisque nous disposons maintenant des liens suivants :
    - 2x 25 Gbps vers Londres (2 liens OC48 sur redondants)
    - 2x 25 Gbps vers Amsterdam (2 liens OC48 sur redondant)
    - 1x 822 Mbps vers Frankfort (redondé par les liens Frankfort/Londres)
    Ceci monte notre connectivité maximale à près de 110 Gbps.

  27. Je suis un particulier, ai-je le droit d'avoir un .com ?

    Oui ! Vous pourrez avoir un .com
    Nous nous chargerons de l'enregistrer pour vous.

  28. Je n'ai jamais créé de site web. Je ne connais rien au HTML. Que me conseillez-vous ?

    Si vos connaissances en terme de création de site web sont limitées ou si vous ne connaissez rien au HTML, nous vous fournirons un logiciel très facile à utiliser et qui vous permettra de créer un site complet, sans aucun besoin de connaissances techniques. Il vous suffira simplement de nous demander ce logiciel après avoir passé commande de votre hébergement.

  29. Comment puis-je mettre un compteur de visite sur mon site ?

    Nous vous offrons la possibilité de mettre un compteur de visite sur votre site.
    Nos compteurs de visite sont gratuits et sans aucun pop-up publicitaire (contrairement aux autres compteurs que vous trouverez ailleurs).
    Nous vous invitons à vous rendre dans la section suivante : mettre un compteur de visite

  30. Proposez-vous les protocoles FTP-SSL, POP-SSL et SMTP-SSL ?

    Nous offrons en effet les protocoles FTP (transfert de fichier), POP (mail entrant) et SMTP (mail sortant) au format SSL crypté 128 bits.
    Cela permet de garantir une totale confidentialité et sécurité dans les communications emails que vous ferez en utilisant votre hébergement ainsi que dans les échanges de fichiers que vous réaliserez entre votre ordinateur et nos serveurs. Vous avez ainsi la garantie qu'aucune information précieuse ne peut être interceptée et tomber entre de mauvaises mains.
    Nous sommes le seul hébergeur à offrir un tel niveau de sécurité.
    Pour le FTP-SSL, le numéro de port est le 21 (SSL explicite)
    Pour le POP-SSL, le numéro de port est le 995
    Pour le SMTP-SSL, le numéro de port est le 465
    Notre certificat racine, que vous pourrez installer sur votre ordinateur, est téléchargeable ici : racine.crt

  31. Vos solutions d'hébergement supportent-elles les CMS tels que SPIP, Mambo/Joomla, etc ?

    Oui, nos hébergements sont bien adaptés aux CMS tels que SPIP, Mambo/Joomla, Drupal, Pivot, WordPress, eZ publish, et autre, que vous pourrez librement installer et configurer.

  32. Comment puis-je bien référencer mon site internet gratuitement ?

    Votre site internet doit se composer de titres différents pour chaque page et d'un meta description pour fournir une petite présentation de votre page web.
    Ensuite à l'intérieur de votre page vous devez informer le moteur de recherche par différentes balises.
    H1 : titre de votre page visible pour l'internaute.
    H2 : Texte résumant la page web
    H3 : Sous menu ou sous titre se trouvant dans votre page
    Le H3 peut être un H2 si vous n'avez pas de résumé dans votre page.

  33. Est-ce que le HTML5 et CSS3 sont acceptés sur votre site ?

    Bien sur ! Vous pouvez programmer en HTML5 et CSS3 sur nos serveurs. Nous vous le conseillons pour le référencement de votre site.
    Il est également possible de programmer du JQUERY, AJAX sur votre hébergement internet.

  34. Quels modes de règlement acceptez-vous ?

    Nous acceptons les règlements par carte bancaire, PayPal, virement bancaire et chèque.

Retourner à la liste des FAQs
Exemple de sites

Questions? Contactez nous. © Copyright 2000-2010 WebsiteOut - Tous droits réservés.
Lire notre Déclaration de confidentialité et nos Conditions générales de vente.
WebsiteOut est une marque déposée
Nous acceptons les paiements par Carte de Crédit, Paypal, Chèque et Virement.


Hébergement internet

Hebergement

III. Questions sur le FTP, les types de fichiers, logiciels à utiliser, ...

  1. Qu'est que le FTP ?

    FTP est un terme anglais signifiant File Transfer Protocol qui signifie Protocole de Transfert de Fichier. C'est un protocole de communication entre votre ordinateur personnel et l'ordinateur distant, en général le serveur de votre hébergeur sur lequel votre site est hébergé. Ce protocole permet donc de transférer les fichiers qui composent votre site web vers l'emplacement approprié, et ceci afin qu'ils soient visibles par vos visiteurs.

  2. Aurai-je un accès illimité FTP afin de mettre à jour mon site ?

    Oui. Vous avez un accès FTP illimité 24h/24, 7jours/7. Ce qui signifie que vous pouvez réaliser la mise à jour des pages de votre site quand vous le souhaitez. Les modifications de celles-ci seront prises en compte immédiatement.

  3. Mon site est-il encore accessible lorsque je transfère mes fichiers via FTP ?

    Oui bien sûr, votre site reste accessible lors de votre transfert de fichiers. Les modifications apportées dans vos pages apparaîtront dès que ces pages seront effectivement transférées sur nos serveurs.

  4. Comment faire pour transférer mes fichiers via FTP ?

    Vous devez vous procurer un logiciel client FTP. Ils sont nombreux et les plus connus sont WS_FTP, CuteFTP, FileZilla, etc.

  5. Où puis-je me procurer ce type de programmes ?

    Ils sont disponibles sur internet. Vous pouvez par exemple les trouver aux adresses suivantes :
    FileZilla (gratuit) : http://filezilla.sourceforge.net/
    WS_FTP : http://www.ftpplanet.com/tutorial/dwnld_ftp_client.htm
    CuteFTP : http://www.cuteftp.com/download/index.shtml

  6. Quel client FTP puis-je utiliser avec mon MAC - MACHINTOSH ?

    Vous avez le choix, les plus connu sont :
    Fetch : http://www.fetchsoftworks.com/
    Transmit : http://www.panic.com/transmit/

  7. Je suis un nouveau client, quand puis-je transférer mes fichiers ?

    Dès que vous aurez reçu vos informations techniques vous pourrez commencer, et ceci afin que votre site puisse être visible dès que la procédure d'enregistrement de votre domaine et/ou le transfert de vos DNS soient effectués. Une fois cette procédure terminée, votre site sera visible sur l'internet.

  8. Puis-je changer mon mot de passe ?

    Pour des raisons de sécurité nous n'offrons pas cette possibilité en ligne. Toute demande de changement de mot de passe devra être faite par e-mail auprès de notre support technique. Nous vous conseillons de conserver votre mot de passe à l'abri de toute indiscrétion.

Retourner à la liste des FAQs
Exemple de sites

Questions? Contactez nous. © Copyright 2000-2010 WebsiteOut - Tous droits réservés.
Lire notre Déclaration de confidentialité et nos Conditions générales de vente.
WebsiteOut est une marque déposée
Nous acceptons les paiements par Carte de Crédit, Paypal, Chèque et Virement.


Hébergement internet

Hebergement

IV. Questions relatives aux mails, configuration des boites mails, capacités des boites mails, spam, antivirus, interface de gestion, ...

  1. Mon adresse email est-elle du type dupond@nom_de_domaine ou du type dupond@www.nom_de_domaine ?

    L'usage veut plutôt que l'on utilise dupond@nom_de_domaine. Le format dupond@www.nom_de_domaine ne pourra pas fonctionner.

  2. Comment paramétrer Outlook express ?

    Suite à votre commande nous vous ferons parvenir une documentation contenant entre autres des indications sur le paramètrage de Outlook Express.

  3. Vos serveurs supportent-ils l'accentuation de mes messages ?

    Absolument, quelque soit votre logiciel d'envoi de courrier (Outlook Express, Eudora ou autre), vos accents seront tenus en considération dans vos messages, donc pas de problème pour les é'èçàù~e et consorts ;-)

  4. Quels sont les serveurs POP et SMTP à utiliser ?

    Suite à votre commande, vous recevrez par e-mail le document de mise en service contenant l'adresse des différents serveurs à utiliser ainsi que des indications sur le paramètrage de Outlook Express.

Retourner à la liste des FAQs
Exemple de sites

Questions? Contactez nous. © Copyright 2000-2010 WebsiteOut - Tous droits réservés.
Lire notre Déclaration de confidentialité et nos Conditions générales de vente.
WebsiteOut est une marque déposée
Nous acceptons les paiements par Carte de Crédit, Paypal, Chèque et Virement.


Hébergement internet - Hebergeur avec Php et MySQL optimisé

Hebergement

V. Questions relatives à PHP

  1. Qu'est-ce que le PHP ?

    C'est un langage de script, Open Source et multi-plateformes (Unix, Linux, Windows), comparable en quelque sorte à la technologie ASP de Microsoft.
    Il supporte l'ensemble des protocoles du Web (HTTP, SMTP, LDAP, ...) et offre un accès natif aux principales bases de données du marché PHP. Il offre ainsi toutes les fonctionnalités permettant de construire des sites Web dynamiques performants.
    La version que nous vous mettons à disposition a été optimisée par la technologie Zend. Le PHP est aujourd'hui l'un des langages coté serveur le plus performant du marché.
    Pour en savoir plus, consultez le site http://www.php.net/

  2. Que faut-il que je fasse pour exécuter mes fichiers PHP ?

    Vous n'avez pas besoin de faire quelque chose en particulier. Les fichiers php sont exécutés automatiquement s'ils ont l'extension .php3, .php ou .php4.

  3. Je souhaite par exemple utiliser un script qui permet d'envoyer un email via un formulaire, de faire fonctionner un livre d'or ou un forum. Comment faire ?

    Il existe sur Internet des scripts à télécharger gratuitement :
    http://www.phpscripts-fr.net/

Retourner à la liste des FAQs
Exemple de sites

Questions? Contactez nous. © Copyright 2000-2010 WebsiteOut - Tous droits réservés.
Lire notre Déclaration de confidentialité et nos Conditions générales de vente.
WebsiteOut est une marque déposée
Nous acceptons les paiements par Carte de Crédit, Paypal, Chèque et Virement.


Tutoriel de site dynamique - Classes d'abstraction

I. Introduction

I-A. Remerciements

Je tiens à remercier Pierre-Baptiste Naigeon pour avoir fourni le tutoriel de départ.

I-B. Prélude

Ce tutoriel traite de l'organisation d'un site Web en séparant au maximum les couches impliquées, ce qui permet de rendre le code aisément maintenable. Je n'ai pas la prétention de mettre des exemples pour toutes les solutions possibles (car elles sont nombreuses). Non, je me contenterai de vous mettre sur la voie en vous donnant un exemple concret.
Avant de commencer, voyons ce que sont les classes d'abstraction et pourquoi il peut être intéressant de les utiliser.
L'article de Pierre-Baptiste Naigeon auquel je me réfère se trouve ici :
http://pbnaigeon.developpez.com/tutoriel/PHP/conception-site-dynamique/

Je ne remettrai absolument pas en cause ses choix. Je me contenterai ici de réécrire son code en utilisant des techniques d'abstraction. La sécurité doit être pensée dès le départ, sous peine d'être inefficace. La réécriture du code que nous allons effectuer serait un bon moment pour y porter son attention mais ce n'est pas mon propos.

I-C. Problématique

Lorsque nous créons un site Web en PHP, nous nous rendons généralement compte qu'il y a deux éléments étrangers au code PHP. Il s'agit de la source de données (fichiers, BDD, etc.) et du destinataire des données (page Web, image, fichier PDF, animation Flash, etc.).
PHP permet de tout gérer mais cela donne un mélange détonnant, dans le code source. C'est malgré tout (et malheureusement) la méthode suivie par un très grand nombre de développeurs.
Les éditeurs de code pallient parfois ce problème en proposant une colorisation syntaxique intelligente. Cependant, c'est peu satisfaisant.

Je propose de réfléchir à séparer toutes les couches : cela aurait le mérite de rendre le code source du site Web plus facile à maintenir.

Il s'agit de déléguer les tâches qui conviennent peu à PHP. C'est un peu comme déléguer la présentation aux feuilles de style plutôt que de tout spécifier dans le code HTML.

Quelles sont les couches d'un site Web, du point de vue du navigateur ?
  • La structure de la page et le contenu (XML, etc.)) ;
  • La présentation du contenu (XSL, etc.).

Lorsque nous utilisons une feuille de style CSS, nous faisons exactement la même chose que ce que je m'apprête à expliquer : déléguer une tâche.

Quelles sont les couches d'un site Web, du point de vue du serveur ?
  • Les informations brutes : la base de données (MySQL, PostgreSQL, Oracle, etc.) ;
  • Les traitements : le langage de script (ASP.NET, etc.) ;
  • L'affichage : la page Web affichée par le navigateur (HTML, XHTML, XML, etc.).

Il est clair ici que chaque couche peut être gérée par une technologie ou une autre. Nous allons nous situer dans la couche centrale en utilisant PHP.
Pour nous, les deux autres couches seront des entités abstraites. Nous allons nous détacher des cas particuliers en utilisant des objets qui se chargeront d'effectuer les tâches comme bon leur semble. Comment ils le feront ne sera pas notre préoccupation.

I-D. Que sont les classes d'abstraction ? title="Haut de page">

Les classes d'objets que nous allons utiliser.
Dans notre cas, puisque nous avons deux couches desquelles nous souhaitons nous détacher, nous allons utiliser deux classes d'abstraction. En réalité, je donnerai plusieurs exemples de chaque cas pour que vous puissiez faire votre choix, mais l'application finale n'en utilisera qu'une de chaque : il s'agit d'une classe d'abstraction de base de données et d'un moteur de templates.

La classe d'abstraction de la base de données permet d'extraire les informations de la base de données sans utiliser de fonctions spécifiques à un système de gestion de base de données. Nous les demandons, le moteur se charge de les récupérer en fonction du SGBD utilisé.

La classe moteur de gabarit permet d'envoyer nos informations à la page de destination sans à avoir à nous préoccuper de l'organisation de ces informations dans la page de destination. Nous les envoyons, le moteur se charge de les organiser en fonction du gabarit défini.

Je vais en profiter pour présenter une méthode permettant de rendre une application multilingue.

I-E. Arborescence dans le système de fichiers

Pierre-Baptiste a parlé de l'arborescence du menu dans le site. Pour ma part, je vais traiter de l'arborescence des fichiers que nous enregistrons sur le serveur.

Le répertoire du site
  • / - Répertoire racine ;
  • /includes - Répertoire des scripts à inclure ;
  • /language - Répertoire des fichiers de langue ;
  • /templates - Répertoire des différents gabarits


Tutoriel de site dynamique - Classes d'abstraction

II. La base de données

II-A. Introduction

Il existe de nombreuses classes d'abstraction de bases de données. Parmi les plus connues, on compte PEAR::DB et PDO ; de plus, chaque collection de scripts (comme phpBB ) a développé sa propre classe... Je vais vous proposer d'utiliser PDO (PHP Data Objects).

PDO est disponible à partir de PHP 5.0 ou 5.1 suivant votre système d'exploitation.

Pour charger l'extension, il faut activer deux lignes de votre fichier php.ini : " extension=php_pdo " ainsi que " extension=php_pdo_mysql " (suivant votre système de gestion de base de données, ici MySQL).

II-B. Principe

Commençons par déterminer la problématique.

Schéma classique d'interrogation d'une base de données avec MySQL :
Sélectionnez
<?php
$id = 10;
mysql_connect("server", "login", "password")
    or die(basename(__FILE__)."<br />".__LINE__."<br />".mysql_error());
mysql_select_db("database")
    or die(basename(__FILE__)."<br />".__LINE__."<br />".mysql_error());
$sql = "SELECT `field` FROM `table` WHERE `id` < ".$id;
$result = mysql_query($sql)
    or die(basename(__FILE__)."<br />".__LINE__."<br />".mysql_error());
while($row = mysql_fetch_assoc($result)
{
    echo "field: ".$row["field"]."<br />";
}
mysql_close();
?>

Le problème est le suivant : si je souhaite donner ce script à quelqu'un ou bien si je change de serveur de bases de données, je serai contraint de réécrire tout le code qui concerne la base de données (puisque les fonctions MySQL ne seront plus disponibles).
La solution est d'utiliser ce que l'on appelle un wrapper , c'est-à-dire des fonctions ou une classe qui me permettent de faire la même chose sans appeler aucune fonction spécifique à un système en particulier (ici : MySQL).

Schéma classique d'interrogation d'une base de données avec PDO :
Sélectionnez
<?php
$id = 10;
try
{
    $db = new PDO("mysql:host=server;dbname=database", "login", "password");

    $sql = 'SELECT `field` FROM `table` WHERE `id` < :id';
    $statement = $db->prepare($sql);
    $statement->execute(array(":id" => $id));

    if($rows = $statement->fetchAll())
    {
        foreach($rows as $row)
        {
            echo "field: ".$row["field"]."<br />";
        }
    }

    $db = NULL;
}
catch (PDOException $exception)
{
    die("Erreur : " . $exception->getMessage() . "<br/>");
}
?>

Avec cette technique, un changement de SGBD se fait simplement en modifiant l'instanciation de l'objet de la classe PDO !

II-C. Procédure

Quelle est la procédure pour réécrire un script ?
Il faut trouver tous les appels à des fonctions spécifiques au SGBD utilisé et les remplacer par leur équivalent en utilisant la classe d'abstraction.

Trouver dans le fichier : index.php
Sélectionnez
connexion_DB("developpez");
Remplacer par :
Sélectionnez
define("BDD_CONNECTION", "mysql:host=localhost;dbname=BASE_TEST");
set_exception_handler("exception_handler");
$db = new PDO(BDD_CONNECTION, "root", "");

Nous venons d'instancier l'objet de base de données. C'est cet objet $db que nous utiliserons tout au long du script.
Nous avons aussi assigné la gestion des erreurs à une fonction. Cela nous permet d'éviter d'écrire les blocs try-catch comme ci-dessus. Chacun sa méthode de faire : ici, j'ai opté pour le plus simple. Dans une application réelle, il est conseillé d'attraper l'exception et de la gérer correctement. D'une manière ou d'une autre, il est fortement conseillé de gérer l'erreur (au moyen du gestionnaire ou bien au moyen de try-catch ) car, en cas d'erreur non gérée, PHP afficherait toutes les informations nécessaires au débogage (y compris le mot de passe de l'utilisateur de la base de données) !
La fonction de gestion d'erreurs est la suivante :

Ajouter dans le fichier : mes-fonctions.php
Sélectionnez
function exception_handler($exception)
{
    $message  = "Wrong query : " . $exception->getMessage() . "<br>\n";
    $message .= "Please, send this message to the webmaster";
    die($message);
}

Nous n'aurons plus besoin de la fonction "connexion_DB", nous pouvons donc la supprimer. Il en va de même pour la fonction "deconnexion_DB".
Voici maintenant comment procéder à l'exécution d'une requête :

Trouver dans le fichier : mes-fonctions.php
Sélectionnez
$strSQL = "SELECT * FROM PAGES WHERE Id_page = ".$_ENV["id_page"];
$resultat = requete_SQL($strSQL);
$tabl_result = mysql_fetch_array($resultat);
Remplacer par :
Sélectionnez
global $db;
$sql = "SELECT * FROM PAGES WHERE Id_page = :id_page";
$statement = $db->prepare($sql);
$statement->execute(array(":id_page"   => $_ENV["id_page"]));
$tabl_result = $statement->fetch();

Le processus est très similaire à ce que nous connaissons déjà. Il s'agit de préparer la requête, de l'exécuter et de récupérer les résultats. L'étape de préparation peut être évitée mais elle a l'avantage d'optimiser automatiquement la requête tout en protégeant contre les injections SQL : il serait dommage de s'en passer.
C'est lors de l'exécution que nous envoyons les paramètres à la requête. Cela a l'avantage de permettre de préparer une seule fois la requête mais en l'exécutant plusieurs fois avec des paramètres différents.
La méthode fetch() permet de récupérer uniquement l'enregistrement suivant, tandis que la méthode fetchAll() permet de tous les récupérer en une fois.

Il faut modifier toutes les requêtes de cette manière. C'est la première fois que je le fais et j'y suis parvenu sans être vraiment à ce que je fais, donc j'imagine que vous n'aurez pas trop de problèmes non plus.

Voici le code complet de Pierre-Baptiste converti à cette étape : [ FTP ] ou [ HTTP ].


Tutoriel de site dynamique - Classes d'abstraction

III. Les gabarits

III-A. Introduction

Ici, il y a davantage de travail. En effet, pour afficher du HTML, nous n'utilisons aucune fonction spéciale. Il s'agit donc de mettre en place un système qui mette en évidence le fait que nous souhaitons afficher du HTML.
La démarche peut sembler complexe mais je vous assure qu'elle a d'énormes avantages, notamment de permettre d'extraire tout le code HTML du fichier PHP. Les avantages sont évidents : il est plus facile de trouver un bug dans le PHP (puisqu'il n'y a plus de HTML parasite) et il est plus facile de modifier l'apparence de la page (puisque le code PHP n'est pas dans le même fichier).
Tout comme pour les classes d'abstraction de base de données, il existe de nombreux moteurs de templates comme Smarty, PHPLib, etc. De plus, chaque collection de script telle que phpBB dispose là aussi de son propre moteur.

J'ai choisi d'utiliser le moteur de templates de phpBB2 car je l'utilise souvent et je l'apprécie. Je l'ai un peu modifié pour mes besoins : je lui fais gérer la convertion des variables en entités HTML. Pour cela, j'ai modifié la classe pour qu'elle appelle htmlentities() avec tous ses paramètres. La différence se fait lors de l'instanciation car il est possible de modifier le comportement par défaut (ENT_QUOTES et "iso-8859-1") :

Exemples de déclaration de l'objet $template
Sélectionnez
$template = new Template("./templates/default/");
$template = new Template("./templates/titoumimi", "ISO-8859-1");
$template = new Template("./templates/titoumimi", "UTF-8", ENT_QUOTES);

Voici le source du moteur de templates, à décompresser et à placer dans le répertoire "/includes" : [ FTP ] ou [ HTTP ].

Pour terminer cette introduction, voici le schéma minimum d'utilisation d'un template :

/index.php
Sélectionnez
define("TEMPLATE_FOLDER", "./templates/titoumimi");
$template = new Template(TEMPLATE_FOLDER);
$template->set_filenames(array("index" => "index.tpl"));
// Mettre ici le code de la page
$template->pparse("index");

Globalement, les modifications à apporter aux scripts de Pierre-Baptiste sont :
  • Les portions de code qui envoient du HTML et/ou du texte de manière répétitive seront remplacées par un appel à assign_block_vars() chacune ;
  • Les portions de code qui n'envoient du HTML et/ou du texte qu'une fois dans la page seront remplacées par un ou plusieurs appels à assign_vars().

III-B. Gabarit fondamental

Commençons par écrire notre gabarit général, c'est-à-dire la structure de la page d'index :

/templates/default/index.tpl
Sélectionnez
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <!-- Insère les mots-clés extraits de la DB dans les meta -->
    <META NAME="keywords" lang="fr" CONTENT="{HEAD_MOTS_CLES}">
    <!-- Insère la description extraite de la DB dans les meta -->
    <META NAME="Description" CONTENT="{HEAD_DESCRIPTION}">
    <meta http-equiv="Content-Type" content="text/html; charset={TPL_CHARSET}">
    <!-- Insère le titre extrait de la DB dans la balise correspondante -->
    <title>{HEAD_TITRE}</title>
    <link rel="stylesheet" type="text/css" href="{THEMES_FOLDER}/final.css">
</head>
<body>
    <div id="menu_horizontal">
    </div>
    <div id="chemin_fer">
    </div>
    <div id="bloc_central">
        <div id="menu_vertical">
        </div>
        <div id="contenu">
           {PAGE_CONTENU}
        </div>
    </div>

Il est intéressant de noter plusieurs choses :
  • Nous n'avons plus aucune des balises <?php et ?> ;
  • Toutes les portions <?php echo $var; ?> ont été remplacées par des sortes de variables entre accolades comme {HEAD_TITRE} ;
  • J'ai laissé vides les blocs DIV pour le moment car ils ont besoin de davantage d'attention ;
  • J'ai mis une variable {TPL_CHARSET} qui semble provenir de nulle part : c'est un cas particulier assigné par le moteur de templates (suite aux modifications apportées par mes soins) ;

III-C. Script PHP fondamental

Il faut maintenant modifier le script PHP afin qu'il utilise notre gabarit :

/index.php
Sélectionnez
<?php
// Active tous les warning. Utile en phase de développement
// En phase de production, remplacer E_ALL par 0
error_reporting(E_ALL | E_STRICT);
define("BDD_CONNECTION",  "mysql:host=localhost;dbname=developpez");
define("TEMPLATE_FOLDER", "./templates/titoumimi");
define("THEMES_FOLDER",   "./themes/titoumimi");
// Inclusions diverses
include_once("./includes/mes-fonctions.php");
include_once("./includes/template.php");
// Construction de l'objet de la classe de gabarit
$template = new Template(TEMPLATE_FOLDER);
$template->set_filenames(array("index" => "index.tpl"));
// Construction de l'objet de la classe de connexion à la base de données
set_exception_handler("exception_handler");
$db = new PDO(BDD_CONNECTION, "root", "");
// Définit l'Id de la page d'accueil (1 dans cet exemple)
// Pensez à le modifier si ce n'est pas le cas chez vous.
$id_page_accueil = 1;
// Récupère l'id de la page courante passée par l'URL
// Si non défini, on considère que la page est la page d'accueil
if (isset($_GET["id_page"]))
{
    $_ENV["id_page"] = $_GET["id_page"];
}
else
{
    $_ENV["id_page"] = $id_page_accueil;
}
// Extrait les informations correspondantes à la page en cours de la DB
extraction_infos_DB();
// Le reste des traitements viendra ici
// Envoi des variables 'globales' au gabarit
$template->assign_vars(array(
    "THEMES_FOLDER"    => THEMES_FOLDER,
    "HEAD_MOTS_CLES"   => $_ENV["mots_cles"],
    "HEAD_DESCRIPTION" => $_ENV["description"],
    "HEAD_TITRE"       => $_ENV["titre"],
    "PAGE_CONTENU"     => $_ENV["contenu"]
    ));
$template->pparse("index");
?>
Il est intéressant de noter plusieurs choses :
  • Nous ouvrons la balise <?php uniquement en début de script et la refermons avec ?> uniquement en fin de script (nous n'avons plus de code HTML brut) ;
  • Les divers affichages des variables de la superglobale $_ENV; ont été déplacés dans l'appel à assign_vars(), ce qui permet de les regrouper et donc de mieux les gérer.

III-D. Les "blocks"

Ensuite, occupons-nous des blocs qui se répètent. Nous aurons besoin de notre objet $template dans les deux fonctions concernées : affiche_chemin_fer() et affiche_menu(). Je propose de l'inclure à la liste des globales commes nous l'avons fait pour $db :

/includes/mes-fonctions.php
Sélectionnez
function affiche_chemin_fer($idpage)
{
    global $db, $template;
/includes/mes-fonctions.php
Sélectionnez
function affiche_menu($idpage)
{
    global $db, $template;

Tout d'abord, le chemin de fer :

/templates/index.tpl
Sélectionnez
<div id="chemin_fer">
    Vous &ecirc;tes ici :
<!-- BEGIN un_niveau -->
     -&gt; <a href="index.php?id_page={un_niveau.ID}">{un_niveau.TITRE}</a>
<!-- END un_niveau -->
</div>

Le moteur de templates saura qu'il devra répéter ce lien à chaque fois qu'on lui parlera du bloc "un_niveau".
Voici le code PHP associé :

/includes/mes-fonctions.php
Sélectionnez
function affiche_chemin_fer($idpage)
{
    global $db, $template;
    // Si l'id de la page en cours est différent de 0
    // (0 = page parente de la page racine = inexistante)
    if($idpage != 0)
    {
        $pages = array();
        $sql = "SELECT * FROM PAGES WHERE Id_page = :id_page";
        $statement = $db->prepare($sql);
        do
        {
            // on récupère les informations de la page en cours dans la DB
            $statement->execute(array(":id_page"   => $idpage));
            $tabl_results = $statement->fetch();
            // Envoi au template
            $pages[] = $tabl_results;
            $idpage = $tabl_results["Id_parent"];
        } while($idpage);
        if(!empty($pages))
        {
            $nb_pages = count($pages);
            for($i = $nb_pages-1; $i >= 0; --$i)
            {
                $template->assign_block_vars("un_niveau", array(
                    "ID"	=> $pages[$i]["Id_page"],
                    "TITRE" => $pages[$i]["Titre"]
                    ));
            }
        }
    }
}

Le principe est d'appeler assign_block_vars() à chaque itération. Ici, j'ai déporté ces appels dans une autre boucle afin de pouvoir afficher le menu à l'envers (comme Pierre-Baptiste l'a fait dans son article). J'ai enlevé la récursivité pour me simplifier la tâche.
Au passage, nous pouvons noter que PDO nous permet de ne pas préparer la requête avant chaque exécution. En effet, une fois la requête préparée, elle peut être exécutée plusieurs fois à la suite avec des paramètres différents. Il faut simplement prendre garde à toujours récupérer tous les tuples avant de l'exécuter à nouveau.

Voyons ensuite les deux menus :

/templates/index.tpl
Sélectionnez
<div id="menu_horizontal">
<!-- BEGIN menu_horizontal -->
    <ul>
<!-- BEGIN un_niveau -->
        <li><a href="index.php?id_page={menu_horizontal.un_niveau.ID}">{menu_horizontal.un_niveau.TITRE}</a></li>
<!-- END un_niveau -->
    </ul>
<!-- END menu_horizontal -->
</div>
/templates/index.tpl
Sélectionnez
<div id="bloc_central">
    <div id="menu_vertical">
<!-- BEGIN menu_vertical -->
        <ul>
<!-- BEGIN un_niveau -->
            <li>
                <a href="index.php?id_page={menu_vertical.un_niveau.ID}">{menu_vertical.un_niveau.TITRE}</a>
            </li>
<!-- END un_niveau -->
        </ul>
<!-- END menu_vertical -->
    </div>
    <div id="contenu">
        {PAGE_CONTENU}
    </div>
</div>
/includes/mes-fonctions.php
Sélectionnez
function affiche_menu($idpage, $menu)
{
    global $db, $template;
    $sql = "SELECT * FROM PAGES WHERE Id_parent = :id_page";
    $statement = $db->prepare($sql);
    $statement->execute(array(":id_page"   => $idpage));
    $tabl_results = $statement->fetchAll();
    // Si la page n'a pas de page fille, alors on modifie la requète pour obtenir ses pages soeurs.
    if (count($tabl_results) == 0)
    {
        $statement->execute(array(":id_page"   => $_ENV["id_parent"]));
        $tabl_results = $statement->fetchAll();
    }
    if(count($tabl_results))
    {
        $template->assign_block_vars($menu, array());
        foreach($tabl_results as $tabl_result)
        {
            $template->assign_block_vars($menu.".un_niveau", array(
                "ID"      => $tabl_result["Id_page"],
                "TITRE"   => $tabl_result["Titre"]
                ));
        }
    }
}

Ici, nous devons imbriquer deux blocs : le bloc racine ("menu_horizontal" ou "menu_vertical") permet d'initaliser la liste à puces dans le template et le bloc interne ("un_niveau") contient les éléments de cette liste.

Il faut maintenant appeler les fonctions de Pierre-Baptiste pour que nos blocks soient générés :

/index.php
Sélectionnez
// Le reste des traitements viendra ici
affiche_menu($id_page_accueil, 'menu_horizontal');
affiche_menu($_ENV['id_page'], 'menu_vertical');
affiche_chemin_fer($_ENV['id_page']);

III-E. Le pied de page

Terminons par le pied de page, ultra simple :

/templates/default/pied-page.tpl
Sélectionnez
    <hr />
Ceci est le pied de page...
</body>
</html>
/pied-page.php
Sélectionnez
<?php
$template->set_filenames(array("pied-page" => "pied-page.tpl"));
$template->pparse("pied-page");
?>

Voici le code complet de Pierre-Baptiste converti à cette étape : [ FTP] ou [ HTTP ].


Tutoriel de site dynamique - Classes d'abstraction

IV. Les langues

Dans cette partie, je vais vous présenter la méthode que j'utilise pour traduire un site Web.

IV-A. Le texte "hard-coded"

Dans l'exemple de Pierre-Baptiste, il y a plusieurs messages inclus directement dans le code. Nous allons créer des fichiers de langue pour les contenir :

/language/fr.php
Sélectionnez
<?php
define("L_YOURE_HERE",  "Vous êtes ici : ");
define("L_FOOTER",      "Ceci est le pied de page...");
define("L_DIE",         "Mauvaise requête : %s<br />\nVeuillez envoyer ce message à un administrateur");
?>
/language/en.php
Sélectionnez
<?php
define("L_YOURE_HERE",  "You are here: ");
define("L_FOOTER",      "This is the footer...");
define("L_DIE",         "Wrong query: %s<br />\nPlease send this message to the webmaster");
?>

Vous remarquerez l'utilisation du préfixe "L_" : cela permet de s'assurer que les constantes que nous définissons ici n'entreront pas en conflit avec d'autres constantes. Cela permet également d'utiliser les fonctionnalités d'autocomplétion de code de votre éditeur favori.
Il faut évidemment inclure ce fichier dans notre script :

/index.php
Sélectionnez
include_once("./includes/mes-fonctions.php");
include_once("./includes/template.php");
include_once("./language/fr.php");

L'intérêt de cette méthode est de permetre de changer la langue simplement en incluant tel fichier (de langue) ou tel autre. Vous pourriez par exemple conserver l'infrmation de langue dans une session ou dans un profil utilisateur.
Il faut maintenant utiliser les nouvelles variables :

/templates/default/index.tpl
Sélectionnez
    <div id="chemin_fer">
        {L_YOURE_HERE}
/templates/default/pied-page.tpl
Sélectionnez
    <hr />
    {L_FOOTER}
/index.php
Sélectionnez
// Envoi des variables 'globales' au gabarit
$template->assign_vars(array(
    "THEMES_FOLDER"    => THEMES_FOLDER,
    "HEAD_MOTS_CLES"   => $_ENV["mots_cles"],
    "HEAD_DESCRIPTION" => $_ENV["description"],
    "HEAD_TITRE"       => $_ENV["titre"],
    "PAGE_CONTENU"     => $_ENV["contenu"],
    "L_YOURE_HERE"     => L_YOURE_HERE,
    "L_FOOTER"         => L_FOOTER
    ));
/includes/mes-fonctions.php
Sélectionnez
function exception_handler($exception) {
    if(defined("L_DIE"))
    {
        die(sprintf(L_DIE, $exception->getMessage()));
    }
    else
    {
        die($exception->getMessage());
    }
}

À ce stade, le code du site proposé par Pierre-Baptiste est complètement réécrit. L'objectif que je m'étais proposé en début d'article est atteint. Ce qui vient ensuite est un bonus, une réflexion plus poussée.

Voici le code complet de Pierre-Baptiste converti jusqu'à cette étape : [ FTP ] ou [ HTTP ].

IV-B. La base de données

" Oui, mais là il reste encore plein de mots en français ! "
Ahhh, en effet. Nous n'avons pas traduit la base de données...

Traduire la base de données implique une charge de travail importante en permanence. En effet, il faut enregistrer chaque message dans chaque langue. Imaginez un site d'annonces dans cinq langues : vos utilisateurs devraient envoyer chaque annonce (titre + contenu) dans ces cinq langues, sans quoi elles ne seraient pas affichées par tous les visiteurs. Quelle galère !
Je vous conseille fortement de bien réfléchir à ce que cela implique.
Anecdote : j'ai développé un site qu'un client voulait en plusieurs langues. Résultat : les produits sont ok dans sa langue maternelle mais cela fait plusieurs mois que les traductions sont vides. Il est parfois préférable de revoir ses ambitions à la baisse...

Bref.
Voici comment je m'y prends : je définis une table "language" dans la base de données. Ensuite, je sépare les champs de type texte de chaque table pour laquelle je souhaite proposer une traduction. Il vous faudra des notions de bases de données relationnelles pour aborder cette partie, notamment ce qui touche aux clefs étrangères.

Avant : Schéma de la base de données de Pierre-Baptiste
Maintenant : Schéma de la base de données avec mes modifications

Exemple de modification
Nous souhaitons traduire la page " Accueil " ( Id_page=1 , Id_parent=0 ) en français ( Id_langue=1 ) et en anglais ( Id_langue=2 ).
Il nous faut utiliser la nouvelle table pages_lang pour effectuer la jointure entre la page et la langue . Nous y introduisons donc les identifiants des tuples à relier (il y a deux langues donc deux étapes) : Id_page=1 et Id_langue=1 avec Titre="Accueil" , puis Id_page=1 et Id_langue=2 avec Titre="Home" .

Voici maintenant la totalité des modifications

SQL de création de la base de données
Sélectionnez
CREATE TABLE `langues` (
`Id_langue` int(11) NOT NULL auto_increment,
`Nom` varchar(255) NOT NULL,
`Diminutif` varchar(5) NOT NULL,
PRIMARY KEY  (`Id`)
);
CREATE TABLE `pages` (
`Id_page` int(11) NOT NULL auto_increment,
`Id_parent` int(11) NOT NULL default '1',
PRIMARY KEY  (`Id_page`)
);
CREATE TABLE `pages_lang` (
`Id_page` int(11) NOT NULL,
`Id_langue` int(11) NOT NULL default '1',
`Titre` varchar(255) NOT NULL,
`Mots_cles` varchar(255) NOT NULL,
`Description` varchar(255) NOT NULL,
`Contenu` TEXT NOT NULL,
PRIMARY KEY  (`Id_page`,`Id_langue`)
);
INSERT INTO `langues`
(`Id_langue`, `Nom`, `Diminutif`)
VALUES
(1, 'Français', 'fr'),
(2, 'English', 'en');
INSERT INTO `pages`
(`Id_page`, `Id_parent`)
VALUES
(1, 0),
(2, 1),
(3, 1),
(4, 1),
(5, 1),
(6, 2),
(7, 2),
(8, 2),
(9, 3),
(10, 3),
(11, 10),
(12, 10);
INSERT INTO `pages_lang`
(`Id_page`, `Id_langue`, `Titre`, `Mots_cles`, `Description`, `Contenu`)
VALUES
(1, 1, 'Accueil', 'Accueil', 'Accueil', 0x4163637565696c),
(1, 2, 'Home', 'Home', 'Home', 0x486f6d65),
(2, 1, 'Mon corps de rêve', 'Mon corps de rêve', 'Mon corps de rêve', 0x4d6f6e20636f7270732064652072c3aa7665),
(2, 2, 'My heavenly body', 'My heavenly body', 'My heavenly body', 0x4d792068656176656e6c7920626f6479),
(3, 1, 'Mes vacances', 'Mes vacances', 'Mes vacances', 0x4d657320766163616e636573),
(3, 2, 'My holidays', 'My holidays', 'My holidays', 0x4d7920686f6c6964617973),
(4, 1, 'Mes loisirs', 'Mes loisirs', 'Mes loisirs', 0x4d6573206c6f6973697273),
(4, 2, 'My hobbies', 'My hobbies', 'My hobbies', 0x4d7920686f6262696573),
(5, 1, 'Me contacter', 'Me contacter', 'Me contacter', 0x4d6520636f6e746163746572),
(5, 2, 'Contact me', 'Contact me', 'Contact me', 0x436f6e74616374206d65),
(6, 1, 'Mes abdos Kro', 'Mes abdos Kro', 'Mes abdos Kro', 0x4d6573206162646f73204b726f),
(6, 2, 'My Kro muscles', 'My Kro muscles', 'My Kro muscles', 0x4d79204b726f206d7573636c6573),
(7, 1, 'Mes mains', 'Mes mains', 'Mes mains', 0x4d6573206d61696e73),
(7, 2, 'My hands', 'My hands', 'My hands', 0x4d792068616e6473),
(8, 1, 'Mon profil Grec', 'Mon profil Grec', 'Mon profil Grec', 0x4d6f6e2070726f66696c2047726563),
(8, 2, 'My greek profile', 'My greek profile', 'My greek profile', 0x4d7920677265656b2070726f66696c65),
(9, 1, 'Au ski', 'Au ski', 'Au ski', 0x417520736b69),
(9, 2, 'Skying', 'Skying', 'Skying', 0x536b79696e67),
(10, 1, 'A la mer', 'A la mer', 'A la mer', 0x41206c61206d6572),
(10, 2, 'At the beach', 'At the beach', 'At the beach', 0x417420746865206265616368),
(11, 1, 'Mer du Nord', 'Mer du Nord', 'Mer du Nord', 0x4d6572206475204e6f7264),
(11, 2, 'North Sea', 'North Sea', 'North Sea', 0x4e6f72746820536561),
(12, 1, 'Mer Morte', 'Mer Morte', 'Mer Morte', 0x4d6572204d6f727465),
(12, 2, 'Dead Sea', 'Dead Sea', 'Dead Sea', 0x4465616420536561);

Alors oui, évidemment, cela fait des chiffres partout, ce n'est pas lisible.
Vous savez quoi ? Une base de données n'est pas faite pour être lisible à l'oeil nu. Elle doit contenir des données aussi segmentées que possible. C'est aux requêtes d'assembler les données de manière à leur donner du sens
C'est ici qu'il devient particulièrement intéressant de conserver dans une session les informations sur la langue en cours.

Voici le code complet de Pierre-Baptiste converti à cette étape : [ FTP ] ou [ HTTP ].


Tutoriel de site dynamique - Classes d'abstraction

V. Conclusion

V-A. Épilogue

Voici ce à quoi nous sommes parvenus :
  • Nous utilisons une base de données sans pour autant utiliser aucune fonction spécifique à un SGBD ;
  • Notre base de données ne contient que des informations élémentaires qu'il serait futile de chercher à segmenter davantage ;
  • Nous envoyons les informations de la base de données à un moteur de templates qui se charge de tout l'affichage à l'aide de gabarits ;
  • Nous avons des scripts PHP dont le code n'est pas parasité par des incises en HTML ;
  • Nous avons des gabarits écrits en HTML pur, que nous pourrions aisément donner à un graphiste ;
  • Nos gabarits ne contiennent ni information ni même texte : ils ne contiennent que la structure du document HTML final et permettent uniquement de savoir où sont positionnés les éléments ;
  • Nous avons une feuille de style CSS pour gérer la présentation (par opposition à "structure") des informations dans notre page Web ;
  • Simplement en modifiant quelques petites constantes, nous avons la possibilité de changer le SGBD, le gabarit, le style et la langue de notre site !

Je souhaite attirer votre attention sur un élément supplémentaire qui me tient à coeur : l'organisation du code.
Lorsque l'on utilise ce genre de classes d'abstraction, il est généralement intéressant d'y réfléchir afin de ne pas s'y perdre.

Personnellement, je vous recommande cette structure pour chacun de vos scripts :
  • Inclure un script common.php qui s'occupe d'inclure tous les scripts nécessaires (configuration, classes, fonctions), d'instancier les classes comme PDO et Template, de déterminer la langue par défaut (en incluant le fichier correspondant) et d'effectuer les éventuelles modifications de la base de données (tous types de requêtes sauf SELECT) ;
  • Inclure un script header.php couplé à un gabarit header.tpl pour avoir un affichage d'en tête identique sur toutes vos pages sans à avoir à répéter le code ;
  • Le code de votre script actuel ;
  • Inclure un script footer.php couplé à un gabarit footer.tpl pour avoir un affichage de pied de page identique sur toutes vos pages sans à avoir à répéter le code.

À titre de démonstration, voici une version plus ou moins finale du projet de site ci-dessus : [ FTP ] ou [ HTTP ]. Il ne vous reste plus qu'à gérer tout cela à l'aide de sessions et vous aurez un site totalement dynamique !