Vous êtes sur la page 1sur 13

MODULE : PROGRAMMATION DE SITES WEB DYNAMIQUE

LEON :MASTER PAGE


Formateur :A BENDAOUD OFPPT/DRPS/ISGI LAAYOUNE

Les Master Pages


Prenons lexemple dun site compos de trois grandes parties : une bannire en haut, un
pied de page comportant notamment le copyright et le corps de la page. Seul le corps
change quel que soit la partie du site dans laquelle nous nous trouvons. Au lieu de refaire
chaque page tout notre affichage avec un risque doublier ou de changer quelque chose
au passage, on va tout simplement crer une Master Page. Voyons ce que cest et en
quoi cela va nous simplifier grandement la tche.

1. Introduction
Une Master Page est en fait une page Web qui va servir de modle pour les autres pages.
Plus exactement, on va dfinir sur une page quel Master Page (page matre en franais)
elle va devoir utiliser. Pour que cela puisse fonctionner, la Master Page contient des
ContentPlaceHolder avec des ID diffrents. Ce sont ces conteneurs que le page va
remplir. En rsum : une page va pointer vers un modle quelle va utiliser. Dans ce
modle se trouvent un ou plusieurs conteneurs. La page qui a t appel par lutilisateur
ne fera que remplir le ou les conteneurs avec le code que nous avons spcifi (du moins
si nous avons dfini un contenu pour le conteneur). Voila pour la partie thorique :
passons maintenant la cration et lutilisation dune Master Page.

2. Cration et utilisation dune page matre


Pour crer une page matre, faites comme pour rajouter nimporte quel page : clic droit
sur le nom du projet, Ajouter, Nouvel Elment. Dans la fentre qui souvre (voir image cidessous) choisissez Page matre.

Propos par :A BENDAOUD

Vous verrez alors souvrir une page avec ce code ci :


Code par dfaut de la page maitre Maitre1.Master

<%@ Master Language="C#" AutoEventWireup="true"


CodeBehind="Maitre1.master.cs" Inherits="WebApplication1.Maitre1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Page sans titre</title>
<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form2" runat="server">
<div>
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>
Comme vous pouvez le constater, cette page correspond une page ASPX normale la
diffrence que la directive en haut ne sappelle pas Page mais Master. Autre chose : Il
contient, par dfaut, deux ContentPlaceHolder. Un dans le head et un dans le body pour
tre plus exact. Ce sont des conteneurs qui vont nous permettre de placer le code
spcifique chaque page. On peut donc rajouter depuis nimporte quel page utilisant
cette page matre : des en-ttes (dans le head) et du contenu dans le body. Il est bien
entendu possible de rajouter ses propres ContentPlaceHolder.
La prochaine tape va tre de crer notre propre page matre et de lutiliser dans la page
Default.aspx.

Propos par :A BENDAOUD

Pour cela voyons dabord le code de la page matre une fois modifi (les modifications
sont soulignes) :
Code de la page matre

<%@ Master Language="C#" AutoEventWireup="true"


CodeBehind="Maitre1.master.cs" Inherits="WebApplication1.Maitre1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Page matre</title>
<asp:ContentPlaceHolder ID="head" runat="server" />
</head>
<body>
<form id="form2" runat="server">
<h1>Contenu de la page en cours</h1>
<div style="border:solid 2px black;height: 200px;">
<asp:ContentPlaceHolder ID="Body" runat="server" />
</div>
<p style="border:solid 2px black;">Pied de page
</p>
</form>
</body>
</html>
On a rajout du HTML et du CSS tout simple. Maintenant voyons comment utiliser notre
page matre comme modle pour notre page Default.aspx. Sur le plan technique, la page
matre possde dj le Doctype ainsi que les balises html, head et body. Notre page
Default.aspx nen a donc pas besoin : il ne lui reste que la directive page. Cest dans
celle-ci que nous allons dire que cette page doit utiliser notre page matre. Pour cela nous
utilisons la proprit MasterPageFile. Il y a une autre proprit qui est Title et qui nous
permet de modifier le titre de la page mme sil a t dfini dans la page matre (comme
cest le cas ici). La directive page doit maintenant ressembler ceci :
Directive de notre page Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"


Inherits="WebApplication1._Default" MasterPageFile="~/Maitre1.Master"
Title="Test" %>
A partir de maintenant notre page utilise la page matre. On peut dailleurs lafficher.
Voici le rsultat :

Propos par :A BENDAOUD

Cet exemple nous montre bien que lon nest pas oblig de mettre du contenu dans la
page matre. Si vous regardez la barre dadresse vous verrez que la proprit Title de la
page Default.aspx a bien modifi le titre de la page. Maintenant que nous savons utiliser
les pages matres dans nos pages, nous allons apprendre y ajouter du contenu.

3. Ajouter du contenu
Maintenant que cest un peu plus clair dans vos esprits nous allons voir comment ajouter
du contenu. Pour cela nous avons une page Default.aspx qui va afficher dans le corps de
la page un formulaire qui nous permettra de rentrer notre pseudo. Et une seconde page
qui va rcuprer le pseudo et lafficher. Pour cela on va utiliser la page matre faites plus
haut.
Pour ajouter du contenu au ContentPlaceHolder de la page matre, il va falloir rajouter
une balise spciale : asp:Content.
Page Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"


Inherits="WebApplication1._Default" MasterPageFile="~/Maitre1.Master"
Title="Test" %>
<asp:Content ID="Content1" ContentPlaceHolderID="Body" Runat="Server">
</asp:Content>
Il y a un ID par dfaut sur le Content. Celui-ci nest pas obligatoire. En revanche on est
oblig de spcifier quel ContentPlaceHolder on va remplir avec la proprit
ContentPlaceHolderId, qui, comme vous le comprenez va prendre comme paramtre lID
du ContentPlaceHolder. Ensuite le runat="server" car cest une balise ASP.NET. Cest
lintrieur de cette balise Content que lon va placer notre code. Bien entendu on peut
mettre plusieurs balise Content pour remplir les diffrents ContentPlaceHolder qui se
trouvent dans la page matre. Remplissons-le avec notre formulaire.
Page Default.aspx

<asp:Content ID="Content1" ContentPlaceHolderID="Body" Runat="Server">


<asp:Label ID="Pseudo" runat="server" Text="Pseudo" />
<asp:TextBox ID="PseudoBox" runat="server" />
<br />

Propos par :A BENDAOUD

<asp:Button ID="Valider" runat="server" Text="Envoyer"


OnClick="Envoi_Pseudo" /> </asp:Content>
C# - Page Default.aspx.cs

protected void Envoi_Pseudo(object sender, EventArgs e)


{
Session["Pseudo"] = PseudoBox.Text;
Response.Redirect("GestionFormulaire.aspx");
}
-------------------------------------------------------------------------------VB.NET Page Default.asp.vb

Protected Sub Envoi_Pseudo(ByVal sende As Object, ByVal e As EventArgs)


Session("Pseudo") = PseudoBox.Text
Response.Redirect("GestionFormulaire.aspx")
End Sub
Ensuite faisons la page qui va rcuprer le pseudo :

Page GestionFormulaire.aspx

<%@ Page Language="C#" AutoEventWireup="true"


CodeBehind="GestionFormulaire.aspx.cs"
Inherits="WebApplication1.GestionFormulaire"
MasterPageFile="~/Maitre1.Master" Title="Rsultat formulaire" %>
<asp:Content ID="Content1" ContentPlaceHolderID="Body" Runat="Server">
<asp:Label ID="PseudoLabel" runat="server" Text="Aucun pseudo" />
</asp:Content>
C# - Page GestionFormulaire.aspx.cs

protected void Page_Load(object sender, EventArgs e)


{
if (Session["Pseudo"] != null)
PseudoLabel.Text = Session["Pseudo"].ToString();
}
-------------------------------------------------------------------------------VB.NET Page GestionFormulaire.aspx.vb

Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)


Handles Me.Load
If Session("Pseudo") <> Nothing Then
PseudoLabel.Text = Session("Pseudo").ToString()
End If
End Sub
Voici un exemple fait avec les deux pages ci-dessus :

Propos par :A BENDAOUD

Remarque : Si vous dfinissez du contenu dans un des ContentPlaceHolder, ce contenu


sera pris comme contenu par dfaut. C'est--dire que si une page utilisant cette page
matre ne possde pas de contenu pour ce ContentPlaceHolder, le contenu par dfaut
sera affich.

4. Lier toutes les pages une page matre


Nous avons vu comment utiliser une page matre sur une page. Il est aussi possible de
dfinir au niveau de lapplication que toutes les pages utiliseront une page matre. On va
donc utiliser le Web.config qui est, nous le rappelons, le fichier de configuration de notre
application Web, pour dfinir ceci.
On va crer une balise pages dans le system.web. Voici quoi cela doit ressembler :
Web.config

<system.web> <pages masterPageFile="~/Maitre1.Master" /> </system.web>


Faites le test : enlevez les proprits MasterPageFile des deux pages ASPX aprs avoir
rajout la balise page dans le Web.config.

5. Modification par code behind


Tout comme une page ASPX on peut utiliser du code behind. Nous allons plus e ndtail
comment grer cela par rapport aux pages ASPX.

a) Utiliser les proprits de la page matre dans les autres pages


Pour comprendre cet exemple nous allons faire quelque chose de simple. La page matre
contiendra une TextBox et la page Default.aspx va contenir un bouton et un Label.
Quand on clic sur le bouton on prend la valeur de la TextBox et la place dans le Label.
AccesMaitre.Master

<div>
<asp:TextBox ID="TextBox" runat="server">
</asp:TextBox><br /><br />
<asp:ContentPlaceHolder ID="Body" runat="server">
</asp:ContentPlaceHolder>

Propos par :A BENDAOUD

</div>
Avec laccesseur qui permet de rcuprer le texte entr dans la TextBox :
AccesMaitre.Master.cs

public string Recuperation


{
get
{
return TextBox.Text;
}
}
-------------------------------------------------------------------------------AccesMaitre.Master.vb

Public ReadOnly Property Recuperation() As String


Get
Return TextBox.Text
End Get
End Property
Notre page matre est prte. Il ne reste plus qua faire notre page Default.aspx. Pour
pouvoir rcuprer la proprit, et donc accder au texte, il va falloir spcifier dans la
page Default.aspx le chemin vers la proprit (ou les sil y en a plusieurs). Pour ce faire
nous devons spcifier un chemin virtuel vers la page matre avec la directive MasterType
et sa proprit VirtualPath. Une fois ceci fait on peut rcuprer les mthodes de la page
matre grce lobjet Master. Pour comprendre un peu mieux voici le code de la page
Default.aspx. Regardez le attentivement pour comprendre son fonctionnement.
Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"


Inherits="WebApplication1._Default" MasterPageFile="~/AccesMaitre.Master"
Title="Test" %>
<%@ MasterType VirtualPath="~/AccesMaitre.Master" %>
<asp:Content ID="Content1" ContentPlaceHolderID="Body" Runat="Server">
<asp:Button ID="Button1" runat="server" Text="Charger le Label"
OnClick="ChargeLabel" />
<asp:Label ID="Label1" runat="server" Text="Vide !">
</asp:Label>
</asp:Content>
Default.aspx.cs

protected void ChargeLabel(object sender, EventArgs e)


{
Label1.Text = Master.Recuperation;
}
-------------------------------------------------------------------------------Default.aspx.vb

Protected Sub ChargeLabel(ByVal sender As Object, ByVal e As EventArgs)


Label1.Text = Master.Recuperation
End Sub

Propos par :A BENDAOUD

Avec cette mthode on peut accder nimporte quelle proprit de la page matre.
Remarquez quil faut quand mme que la proprit ou mthode en question soit
publique.

b) Accder aux contrles de la page matre


Tout comme on peut accder aux mthodes et proprits de la page matre depuis le
code behind dune autre page, on peut aussi accder ses contrles.
Reprenons lautre exemple, au lieu dappeler une mthode de la page matre on va tout
simplement accder au contrle TextBox et rcuprer son texte. Pour faire cela nous
navons pas besoin de chemin virtuel comme nous avions eu besoin pour accder aux
mthodes. Voici ce que va contenir notre vnement clic du bouton de Default.aspx.

Default.aspx.cs

protected void ChargeLabel(object sender, EventArgs e)


{
Label1.Text = ((TextBox)Master.FindControl("TextBox")).Text;
}
-------------------------------------------------------------------------------Default.aspx.vb

Protected Sub ChargeLabel(ByVal sender As Object, ByVal e As EventArgs)


Label1.Text = CType(Master.FindControl("TextBox"), TextBox).Text
End Sub
Avec cette faon dcrire et dans ce cas on obtient le mme rsultat quavec un
accesseur. Mais cest utile dans dautre cas.

6. Imbrication des pages matre


Tout comme un conteneur peut contenir un autre conteneur, une page maitre peut en
contenir une autre. Lutilit est que lorsque que nous de allons avoir une partie du site
lgrement diffrente du reste (par exemple il faut un menu gauche), et bien il suffira
davoir une page matre qui se base sur la premire et ne fait que rajouter le menu. Ceci
est un exemple parmi tant dautres possibles bien sur.
Pour ce qui est de la technique, cela nest pas plus compliqu que dutiliser une page
maitre avec un page aspx. C'est--dire que le seconde page matre aura une balise
Content, par exemple sur le ContentPlaceHolder nomm Body plus haut. Et que dans ce
Content nous aurons un ContentPlaceHolder qui se situera droite de la page et un
menu (par exemple une liste dans un div). Ainsi la partie du site qui a besoin dun menu
va utiliser la seconde page matre (que nous nommerons AffichMenu.Master).
Voici ce que cela donne :
Principale.Master

<%@ Master Language="C#" AutoEventWireup="true"


CodeBehind="Principale.master.cs" Inherits="WebApplication1.Principale" %>

Propos par :A BENDAOUD

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Page sans titre</title>
<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form2" runat="server">
<div>
<h1>Page Principale</h1>
<div style="border: solid black 2px; padding: 10px;">ContentPlaceHolder :
Body <asp:ContentPlaceHolder ID="Body" runat="server">
</asp:ContentPlaceHolder>
</div>
</div>
</form>
</body>
</html>
AffichMenu.Master

<%@ Master Language="C#" AutoEventWireup="true"


MasterPageFile="~/Principale.Master" CodeBehind="AffichMenu.master.cs"
Inherits="WebApplication1.AffichMenu" %>
<asp:Content ID="Content1" runat="server" ContentPlaceHolderID="Body">
<div style="height: 300px; border: solid black 2px;">Content : Body
<div style="height: 200px; border: solid 2px green; float: left;">
<ul>
<li>Lien 1</li>
<li>Lien 2</li>
<li>Lien 3</li>
<li>Lien 4</li>
</ul>
</div>
<div> <asp:ContentPlaceHolder ID="Body2" runat="server" />
</div>
</div>
</asp:Content>
Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"


Inherits="WebApplication1._Default" MasterPageFile="~/AffichMenu.Master"
Title="Test" %>
<asp:Content ID="Content1" ContentPlaceHolderID="Body2" Runat="Server">
Contenu de Default.aspx<br />
Voici comment on ajoute un menu pour certaines pages
</asp:Content>

Propos par :A BENDAOUD

Regardez bien le code de la page AffichMenu.Master. Cest lui le plus important. Vous
voyez quil ressemble beaucoup une page aspx qui utiliserait une page matre avec
juste la directive qui reste Master. Elle comporte aussi un Content pour remplir le Body.
Dedans on dfini larchitecture de notre page et on remet un ContentPlaceHolder
lendroit o lon veut que le contenu de la page se place. Le reste (laffichage, les
bordures, couleurs ) est du CSS simple. Vous pouvez voir si dessous un aperu de ce
que lon obtient sur le navigateur.

Attention : Les ContentPlaceHolder de la premire page matre sont TOUS remplac par
le contenu de la balise Content leur correspondant dans la seconde page matre et cela
mme sil ny a rien. Ainsi si vous faites un page matre avec un ContentPlaceHolder
nomm BodyContent et qui contiendra les donnes spcifiques chaque page, une fois
votre seconde page matre pass ce ContentPlaceHolder nexistera plus. On ne pourra
donc pas, depuis une page qui utilise la seconde page matre, ajouter les donnes
principales. Pour contourner cela il faut tout simplement redfinir ce ContentPlaceHolder :
Premire page matre

<asp:ContentPlaceHolder runat="server" ID="BodyContent" />


Seconde page matre Redfinition de BodyContent

<asp:Content
ID="Content1"
ContentPlaceHolderID="BodyContent"> <asp:ContentPlaceHolder
ID="BodyContent" />
</asp:Content>

runat="server"
runat="server"

Une fois ceci fais, vous pourrez faire appel au ContentPlaceHolder BodyContent depuis
votre page ASPX.

10

Propos par :A BENDAOUD

7. Changer dynamiquement de page matre


Il est intressant de pouvoir proposer plusieurs affichages diffrents de notre site aux
utilisateurs. Pour cela il suffit tout simplement de changer de page matre. Le contenu
restera le mme mais laffichage lui changera. Ainsi on peut facilement changer
compltement la faon dafficher le site mais les donnes resteront les mmes. Seul
problme : comment savoir quel page matre lutilisateur veut utiliser sans avoir lui
redemander chaque page. Et bien pour cela reportez-vous au chapitre sur la Gestion
dtat qui traite les sessions, les cookies, les variables dans les url, les champs cachs .
Autant de manires diffrentes pour stocker cette donne. Dans notre cas on va
simplement utiliser la session.
Une chose importante savoir pour pouvoir changer dynamiquement la page matre,
cest que lon peut le faire depuis le code behind avec laccesseur MasterPageFile de
lobjet Page. Plus important encore : quand peut-on modifier la page matre ? ET bien on
connait le cycle de la page. En sachant cela on remarque quon ne peut modifier la page
matre qua lvnement PreInit.
On garde AffichMenu.Master et on ajoute cela :
AffichMenuDroite.Master

<%@ Master Language="C#" AutoEventWireup="true"


CodeBehind="AffichMenuDroite.master.cs"
MasterPageFile="~/Principale.Master"
Inherits="WebApplication1.AffichMenuDroite" %>
<asp:Content ID="Content1" runat="server" ContentPlaceHolderID="Body">
<div style="height: 300px; border: solid black 2px;">Content : Body
<div style="height: 200px; border: solid 2px green; float: right;">
<ul>
<li>Lien 1</li>
<li>Lien 2</li>
<li>Lien 3</li>
<li>Lien 4</li>
</ul>
</div>
<div>
<asp:ContentPlaceHolder ID="Body2" runat="server" />
</div>
</div>
</asp:Content>
Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"


Inherits="WebApplication1._Default" MasterPageFile="~/AffichMenu.Master"
Title="Test" %>
<asp:Content ID="Content1" ContentPlaceHolderID="Body2" Runat="Server">
Choisissez votre Master Page : <br />
<asp:ListBox ID="ListBox1" runat="server" >
<asp:ListItem Text="AffichMenuGauche.Master" Value="Gauche" />
<asp:ListItem Text="AffichMenuDroite.Master" Value="Droite" />
</asp:ListBox><br /> <asp:Button ID="Button1" runat="server" Text="Button"
OnClick="ChangerMaster" />

11

Propos par :A BENDAOUD

</asp:Content>
Default.aspx.cs

public partial class _Default : System.Web.UI.Page


{
protected void Page_PreInit(object sender, EventArgs e)
{
if (Session["Master"] != null)
{
if (Session["Master"].ToString() == "Gauche")
MasterPageFile = "AffichMenu.Master";
if (Session["Master"].ToString() == "Droite")
MasterPageFile = "AffichMenuDroite.Master";
}
}
protected void ChangerMaster(object sender, EventArgs e)
{
Session["Master"] = ListBox1.SelectedValue;
Response.Redirect("Default.aspx");
}
}
-------------------------------------------------------------------------------Default.aspx.vb

Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As EventArgs)


Handles Me.PreInit
If Session("Master") <> Nothing Then
If Session("Master").ToString() = "Gauche" Then
MasterPageFile = "AffichMenu.Master"
End If
If Session("Master").ToString() = "Droite" Then
MasterPageFile = "AffichMenuDroite.Master"
End If
End If
End Sub
Protected Sub ChangerMaster(ByVal sender As Object, ByVal e As EventArgs)
Session("Master") = ListBox1.SelectedValue
Response.Redirect("Default.aspx")
End Sub
Voici ce que cela donne aprs avoir choisi le menu droite et avoir appuy sur le bouton
:

12

Propos par :A BENDAOUD

13

Propos par :A BENDAOUD