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

Soyez le premier à donner votre avis sur cette source.

Snippet vu 8 135 fois - Téléchargée 28 fois

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

Ajouter un commentaire

Commentaires

spaceclic
Messages postés
9
Date d'inscription
lundi 26 janvier 2004
Statut
Membre
Dernière intervention
20 avril 2005
-
sachant que <title id="titre" runat="server"></title> fonctionne également
spaceclic
Messages postés
9
Date d'inscription
lundi 26 janvier 2004
Statut
Membre
Dernière intervention
20 avril 2005
-
Il ne supprime pas la balise a chaque fois, si elle est bien formulé comme la dit killergege

<title id="titre" runat="server"/>
jesusonline
Messages postés
6827
Date d'inscription
dimanche 15 décembre 2002
Statut
Modérateur
Dernière intervention
13 octobre 2010
16 -
je sais qu'il y a plus simple, mais dans ton cas, si tu as VS.net, il va te supprimer le runat=server à chaque fois que tu vas aller dans le mode design, donc tu vas avoir des erreurrs.

Sinon j'ia encore plus simple : attendre asp.net

et tout simplement ecrire me.Header.Title = " .... " c'est tout :D

Cyril
killergege2
Messages postés
6
Date d'inscription
mercredi 8 septembre 2004
Statut
Membre
Dernière intervention
17 juillet 2005
-
Encore beaucoup plus simple !!!!!!
Je crois que tu t'es un peu cassé la tête pour rien (enfin, d'après ce que j'ai compris, ca fait la même chose)

Il suffit de définir le tag title comme un tag traité par le serveur :

Dans le .ASPX
<title id="mytitle" runat="server" />

Dans le ASPX.VB
Déclaration du tag en global:
Protected mytitle As HtmlGenericControl

Modification du texte :
mytitle.InnerText = "Mon titre"

Il est ainsi possible de travailler avec n'importe quel tag HTML et modifier tout les attributs et parametres (notamment peut être très utile avec les inputs).

Autre exemple avec un meta tag (description):
<meta name="description" runat="server" id="mydescription" />

Protected mydescription As HtmlGenericControl


mydescription.Attributes.Add("content", "description du site")
jesusonline
Messages postés
6827
Date d'inscription
dimanche 15 décembre 2002
Statut
Modérateur
Dernière intervention
13 octobre 2010
16 -
Je ne vois pas vraiment ou veut tu en venir, mais je pense que ta solution est tres semblable a l'astuce de Rayban donc meme reponse ...

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.