Titre de la page dynamique en dérivant la classe page

Contenu du snippet

Ce petit bout de code permet d'avoir dans le code dans la page me.Title = "...."

Pour arriver à ce résultat, j'ai dérivé la classe System.Web.UI.Page.J'avais déja publier une source qui permettait de faire ca, mais celle ci est beaucoup plus puissante :)

Le code par lui meme est relativement assez simple, quand on le regarde il n'y a rien d'extraordinaire, j'ai créer une classe BasePage, qui dérive de System.Web.UI.Page, j'ai surchargé la méthode Render, et c'est à peu pres tout :)

Je vais d'abord vous expliquer comment faire fonctionner ce code, puis je vous dirais comment je suis arrivé jusqu'a ce code.

Tout d'abord, pour utiliser le code ci dessous, vous devez l'inclure dans un fichier vb :p Ensuite il faut faire quelques mofication, au sein de la page aspx.vb.

d'origine celle ci est de la structure :

Public Class Contacts
Inherits System.Web.UI.Page
...
end class

Nous on veut la fare dériver de BasePage qui elle meme dérive de System.Web.UI.Page la page ressemblera donc à ca :

Public Class Contacts
Inherits BasePage
...
end class

Maintenant vous avez deux possibilité :
- soit en rester la (dans le cas notre code ne servirait à rien :p), le titre de la page affiché sera celui contenu dans le .aspx
- Soit se servir de mon code :) pour cela rien de plus simple dans le page_load de la page faites tout simplement
me.Title = "Le titre de la page"
Dans ce cas, si vous avez un titre dans le .aspx il sera remplacé, mais libre à vous de modifier BasePage pour qu'il répondent à vos attentes

L'utilisation du code est donc tres simple. Mais la facon d'arriver à celui ci est loin d'etre simple

d'abord l'idée vient d'un message sur le net qui dit que c'etait possible de faire ca en asp.net 2.0, mais comme tout le monde le sait cette version n'existe pas, il me fallait donc une solution.
Tout de suite j'ai cherché à dériver System.Web.UI.Page, une fois fait j'ai regardé les differentes méthodes que j'aurais pu utiliser, et c'est la méthode Render qui me convenait le mieux.
d'habitude quand on utilise la méthode Render
dans la plupart des cas, on fait
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)

'Traitement du MyBase

MyBase.RenderControl(writer)

End Sub

J'ai essayé de trouvé tout ce que je pouvais dans le MyBase, mais rien de simple qui me permettait d'intercepter le rendu de la page, j'ai essayé de regarder ce que je pouvais faire dans le Me, rien de spécial non plus, mais un petit truc m'a attiré l'oeil, j'ai vu qd je debuggais avec VS.net que Me.Controls ne contenait que 3 controles, j'ai regardé dedans si par hasard il pouvait se trouver mon bonheur, et oui !!! j'ai vu en faisait des response.write a co que le premier controle contenait le Header le deuxieme je ne sais pas trop quoi (ce n'etais pas un LiteralControl donc il a pas aimé les response.write :p) et le dernier la fin de la page, de la j'en ai deduit que le 2eme contenait le corp de la page :).
Maintenant que j'avais trouvé tout ceci, restait à y mettre en forme autrement qu'avec des response.write :p. J'ai enlevé mon MyBase.Render(Writer) qui me servait plus à rien, et j'ai cherché à faire un rendu de ces 3 controles, mais le problème c'est que le render de LiteralControl est Protected, de là j'ai cherché des moyens pour contourner ce problème etc... je me suis apercu (bien trop tardivement) que le RenderControl n'etait pas Protected, je me demande toujours la difference entre le RenderControl, et le Render et pourkoi l'un est protected l'autre pas, mais tout ce que j'ai constaté c'est que ca marche !!!!
J'ai remis en forme tout ca essayé de faire un code assez propre et c'etait finit :)

Je vous ai montré l'exemple pour mettre le Title, il est simple maintenant de faire de meme avec les autres balises meta ... et on pourrait meme allé plus loin en encadrant le viewstate de <div style="display:none"></div> pour le rendre XHTML Compliant, comme c'est déja le cas dans asp.net 2.0 ....

Je ferais surement un jour ces quelques ajouts, mais si vous en faites aussi, n'hésitez pas à me les donner :)

UPDATES :
- 31 mai 04 :
- suppression d'un "<" qui trainait à la fin de cHeader
- ajout de la possibilité d'avoir un titre sans qu'il y ai la balise <title> dans le .aspx
- ajout de la propriété AddTitle qui permet de spécifier comment l'on doit rajouter le titre, tres simple à comprendre
Exemple : Me.AddTitle = BasePage.AddTitleMode.AddAfter

Source / Exemple :


Public Class BasePage
    Inherits System.Web.UI.Page

    Public Enum AddTitleMode As Byte
        ReplaceMode = 1
        AddBefore = 2
        AddAfter = 3
    End Enum

#Region " Propriété "

    Private _Title As String
    Public Property Title() As String
        Get
            Return _Title.ToString
        End Get
        Set(ByVal Value As String)
            _Title = Value
        End Set
    End Property

    Private _AddTitle As AddTitleMode = AddTitleMode.ReplaceMode
    Public Property AddTitle() As AddTitleMode
        Get
            Return _AddTitle
        End Get
        Set(ByVal Value As AddTitleMode)
            _AddTitle = Value
        End Set
    End Property
#End Region

    Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)

        Dim isFoundTitle As Boolean = False
        'simple compteur
        Dim i As Integer = 0
        For Each cControl As Control In Me.Controls()

            ''' seul le premier control contient ce qu'il nous interesse
            ''' je fais le necessaire seulement si la propriété Title
            ''' n'est pas vide, ainsi elle gardera sa valeur mis dans la page aspx
            If Not Title = "" And i = 0 Then

                ''' Pour l'instant dans tous les cas que j'ai rencontré 
                ''' Le premier control etait un literal control qui 
                ''' Contenait tout le heade de la page
                Dim cHeader As LiteralControl = CType(cControl, LiteralControl)

                ''' Je le decoupe pour ajouter ce que je veux
                Dim Header() As String = cHeader.Text.Split("<")

                ''' on vide le titre qu'il contient déja mais c'est mon choix
                ''' C'est assez simple de le rajouter derriere ou devant a vous de voir
                cHeader.Text = ""

                ''' Je fais une boucle sur tous et scute celui qui commence par
                ''' title, j'ai rajouté ToLower car dans la page il y a de multiple
                ''' facon de l'ecrire
                ''' si celui ci est trouvé, j'ajout le titre 
                ''' dans tout les cas je rajoute le bout du header au controle
                For Each s As String In Header
                    If s.ToLower.StartsWith("title") Then
                        Select Case _AddTitle
                            Case AddTitleMode.ReplaceMode
                                s = "Title>" & _Title
                            Case AddTitleMode.AddBefore
                                s = s.Insert(6, _Title)
                            Case AddTitleMode.AddAfter
                                s = s.Insert(s.Length, _Title)
                        End Select
                        isFoundTitle = True
                    End If
                    cHeader.Text &= s & "<"
                Next

                '''Il reste le dernier "<" qui traine 
                cHeader.Text = cHeader.Text.Remove(cHeader.Text.Length - 1, 1)

                ''' On rajoute le titre juste apres le head au cas où il n'y aurait pas de balise title dans le .apsx
                If Not isFoundTitle Then cHeader.Text = cHeader.Text.Insert(cHeader.Text.ToLower.IndexOf("<head>") + 6, vbNewLine & "<Title>" & _Title & "</Title>")

                ''' Une fois tout ca fait, j'envoie cette partie 
                cHeader.RenderControl(writer)
            Else
                ''' il existe d'autre partie, que je renvoie aussi 
                ''' je pense que dans la plupart des cas, c'est constitué de la manière suivante :
                ''' - Me.controls(0) contient le Header de la page du debut de la page jusqu'au <body>
                ''' - Me.controls(1) contient la balise form donc de <form> jusqu'a </form>
                ''' - Me.controls(2) contient la fermeture de la page du </body> jusqu'au </html>
                ''' 
                ''' puisqu'on peut avoir plusieurs form dans une seule page, il peut y avoir plus 
                ''' que 3 controls dans la pages
                cControl.RenderControl(writer)
            End If

            i += 1
        Next

    End Sub

End Class

Conclusion :


Les commentaires sont toujours les bienvenus :)

Je rajouterais des trucs de temps en temps

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.