Publié jeudi 23 septembre 2010 04:22 par Adrien Siffermann

[Internet Explorer 9] Activer la fonctionnalité “Pinned Site” sur votre site ASP.Net

Internet Explorer 9 apporte son lot de nouvelles fonctionnalités en terme d’expérience de navigation, et parmi elles la possibilité d’épingler un site Web à la barre des tâches de Windows 7. L’idée générale est que certains sites Web sont réellement des applications Web, que l’on ouvre le matin et qu’on ne referme que le soir : c’est le cas par exemple pour votre site SharePoint, Facebook, Gmail, et plus encore pour des applications métiers.

Avec cette nouvelle fonctionnalité, IE9 nous permet de lancer en un clic une application Web, mais aussi de bénéficier d’une liste d’actions spécifiques à cette dernière, de recevoir des notifications visuelles ou de contrôler le site à partir d’une barre d’actions dans la miniature de la barre des tâches.

 

Comment ça marche ?

Pour ceux qui n’auraient pas encore eu le temps ou l’occasion de tester tout ça, commençons par un petit aperçu fonctionnel Sourire

Je navigue sur Facebook, et je fais un glisser déposer de l’onglet (ou de la favicon) sur ma barre des tâches Windows 7.

J’ai alors une grande icône qui s’ajoute dans ma barre des tâches, et le clic droit m’ouvre un menu avec des tâches personnalisées (en l’occurrence un accès direct aux actualités, aux messages…)

La fenêtre de mon application Facebook est elle aussi personnalisée : on retrouve l’icône en haut à gauche, et les boutons de navigation adoptent la couleur dominante de celle-ci.

Quand une nouvelle notification arrive sur Facebook, l’icône de la barre des tâches se modifie pour me le notifier de façon plus visuelle.

De la même manière, nous pouvons aussi épingler un site Web au menu Démarrer grâce à une option dans le menu Fichier d’Internet Explorer 9.

Nous retrouvons ainsi une icône similaire, avec la même liste de tâches.

 

Comment personnaliser ce bouton pour notre application Web ?

Le contrôle du comportement des boutons de lancement d’un site Web épinglé se fait de deux manières : grâce à des balises meta dans la balise head des pages du site et une API JavaScript. Nous allons nous concentrer ici sur la première partie qui permet la personnalisation générale du bouton et de la liste des tâches.

 

Personnalisation générale du bouton

Cinq balises meta spécifiques permettent de personnaliser le bouton qui va être épinglé dans la barre des tâches.

Nom Valeur Exemple
application-name Le nom du bouton. Si il n’est pas précisé, celui-ci sera automatiquement assigné avec le titre de la page Web.
<meta name="application-name" content="Mon application"/>
msapplication-tooltip Un texte qui sera affiché en bulle d’aide sur le survol du bouton du site épinglé.
<meta name="msapplication-tooltip" content="Ouvrir mon application !"/>
msapplication-starturl L’URL relative ou absolue à ouvrir sur le clic du bouton. Par défaut, ce sera la page affichée au moment où l’utilisateur épingle le site Web.
<meta name="msapplication-starturl" content="/"/>
msapplication-navbutton-color La couleur des boutons Retour et Suivant. Par défaut, cette couleur se base sur la couleur dominante de la favicon du site.
<meta name="msapplication-navbutton-color" content="#008eb0"/>
msapplication-window La largeur et la hauteur de la fenêtre à la première ouverture. Ces valeurs sont écrasées si l’utilisateur redimensionne la fenêtre.
<meta name="msapplication-window" content="width=800;height=600"/>

Pour l’icône, c’est encore plus simple, puisque Internet Explorer 9 identifie automatiquement la favicon définie sur le site pour l’assigner au bouton de la barre des tâches de Windows 7. Un petit exemple :

    <link rel="shortcut icon" type="image/x-icon" href="/Images/myicon.ico" /> 
    <link rel="icon" type="image/ico" href="/Images/myicon.ico" />

Nous pouvons cependant améliorer la résolution et le graphisme de notre icône. En effet, une favicon affichée dans un navigateur a une taille de 16x16 pixels, alors que celle de notre bouton sur Windows 7 est de 32x32 pixels. Vous pouvez donc inclure ces deux résolutions au sein de votre icône.

 

Personnalisation de la liste des tâches

Là encore, nous allons pouvoir définir une liste de tâches pour notre application Web avec des balises meta. Le nom de la balise doit être msapplication-task et sa valeur peut définir trois propriétés : le nom de la tâche, l’URL de la page et l’icône à afficher.

    <meta name="msapplication-task" content="name=Ma tâche;action-uri=/Page1.aspx;icon-uri=/Images/icon1.ico"/>

L’URL peut aussi être absolue ou relative. Attention cependant : l’URL sera relative à la page depuis laquelle l’utilisateur aura épinglé le site Web. Il n’y a pas de restrictions de domaine, vous pouvez donc très bien pointer sur un autre site. Enfin, un site Web peut définir jusqu’à 5 tâches différentes.

Une autre information importante, dont nous allons tirer parti dans la suite de cet article : la liste des tâches peut être mise à jour ! Il suffit de changer nos balises meta, et la liste sera modifiée au prochain lancement de notre application Web.

 

Comment tirer profit d’ASP.Net pour mettre en œuvre cette fonctionnalité ?

Maintenant que nous avons vu les principes de base, comment allons-nous pouvoir implémenter cela facilement dans une application ASP.Net ?

Si l’ajout de quelques balises meta semble trivial, la réalité est pourtant un peu plus complexe. Idéalement, voici ce dont on pourrait avoir envie pour la personnalisation de notre site épinglé :

  • Le nom et la bulle d’aide du bouton doivent être affichés dans la langue de l’utilisateur
  • De même, les noms des tâches doivent être localisés
  • Les tâches étant in fine des liens vers des pages existantes de mon application Web, j’aimerais pouvoir “marquer” les cinq pages que je veux mettre en avant
  • J’aimerais également pouvoir afficher des tâches différentes selon mes utilisateurs
  • Enfin, cette fonctionnalité étant un “plus” ergonomique, j’aimerais bien pouvoir mettre tout ça en œuvre rapidement, et sans écrire des pages de code ! Sourire

Pour la démonstration, nous allons partir d’un site très simple (basé sur le modèle de projet Visual Studio 2010). Vous trouverez la solution complète à la fin de cet article.

L’authentification par formulaire est activée sur le site, avec les Provider SQL par défaut.

Le site contient trois parties distinctes :

  • Une page d’accueil publique
  • Une zone “Utilisateur”
    Composée de trois pages, elle n’est accessible qu’aux utilisateurs identifiés du rôle “User”. Physiquement, elles se trouvent dans un même dossier “User” sécurisé grâce à un Web.config.
  • Une zone “Administrateur”
    Composée de cinq pages, elle n’est accessible qu’aux utilisateurs identifiés du rôle “Admin”. Physiquement, elles se trouvent dans un même dossier “Admin” sécurisé grâce à un Web.config.

Pour l’affichage du menu, nous utilisons comme il se doit un fichier SiteMap, qui précise pour chaque page quel est le rôle nécessaire à son affichage :

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" enableLocalization="true">
  <siteMapNode url="" title=""  description="" roles="*">
    <siteMapNode url="~/Default.aspx" resourceKey="Home" roles="*" />
    <siteMapNode url="" roles="Admin" resourceKey="Admin">
      <siteMapNode roles="Admin" resourceKey="AdminPage1" url="~/Admin/AdminPage1.aspx" />
      <siteMapNode roles="Admin" resourceKey="AdminPage2" url="~/Admin/AdminPage2.aspx" />
      <siteMapNode roles="Admin" resourceKey="AdminPage3" url="~/Admin/AdminPage3.aspx" />
      <siteMapNode roles="Admin" resourceKey="AdminPage4" url="~/Admin/AdminPage4.aspx" />
      <siteMapNode roles="Admin" resourceKey="AdminPage5" url="~/Admin/AdminPage5.aspx" />
    </siteMapNode>
    <siteMapNode roles="User" resourceKey="UserPage1" url="~/User/UserPage1.aspx" />
    <siteMapNode roles="User" resourceKey="UserPage2" url="~/User/UserPage2.aspx" />
    <siteMapNode roles="User" resourceKey="UserPage3" url="~/User/UserPage3.aspx" />
  </siteMapNode>
</siteMap>

Ce fichier est également localisé, grâce à l’attribut enableLocalization et aux attributs resourceKey qui précisent pour chaque nœud quelle ressource doit être affichée. Les titres sont alors définis dans le fichier de ressources global attaché à notre SiteMap :

Afin que les rôles soient correctement pris en compte pour le filtrage de notre SiteMap, nous devons ajouter quelques lignes dans notre Web.config à la racine.

<configuration>
  <!-- ... -->
  <system.web>
    <!-- ... -->
    <siteMap defaultProvider="SiteMapProvider" enabled="true">
      <providers>
        <add name="SiteMapProvider" type="System.Web.XmlSiteMapProvider" securityTrimmingEnabled="true" siteMapFile="Web.sitemap"/>
      </providers>
    </siteMap>
    <!-- ... -->
  </system.web>
  <!-- ... -->
</configuration>

Voilà pour la présentation de notre application ASP.Net, passons maintenant au cœur du sujet ! Sourire

 

Personnalisation générale du bouton

Cette première partie ne présente pas de difficultés particulières. Nous allons simplement ajouter les balises meta et link dont nous avons besoin dans la balise head de notre MasterPage :

    <link rel="shortcut icon" type="image/x-icon" href="/Images/Icons/Imajin.ico" /> 
    <link rel="icon" type="image/ico" href="/Images/Icons/Imajin.ico" />

    <meta name="application-name" runat="server" meta:resourcekey="ApplicationName" />
    <meta name="msapplication-tooltip" runat="server" meta:resourcekey="ApplicationToolTip"/>
    <meta name="msapplication-starturl" content="/"/>
    <meta name="msapplication-window" content="width=800;height=600"/>
    <meta name="msapplication-navbutton-color" content="#008eb0"/>

Notons simplement que nous avons localisé le nom et la bulle d’aide avec les attributs meta:resourcekey. Ainsi, nous pouvons définir les valeurs dans le fichier de ressources local pour notre MasterPage.

 

Personnalisation de la liste des tâches

Nous allons maintenant devoir ruser un peu Clignement d'œil

Récapitulons nos besoins :

  • On veut afficher une liste de balises meta, avec un nom localisé et une URL pour chacune
  • On veut que cette liste change selon l’utilisateur connecté
  • On veut pouvoir marquer simplement les pages à afficher dans cette liste

Au final, cela ressemble de très près à un menu, tel que nous l’avons mis en place avec le fichier SiteMap ! Pour choisir quelles pages vont être affichées, nous pouvons ajouter des attributs personnalisés dans notre fichier SiteMap, et filtrer nos éléments en fonction de cet attribut. Voilà ce que ça donne :

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" enableLocalization="true">
  <siteMapNode url="" title=""  description="" roles="*">
    <siteMapNode url="~/Default.aspx" resourceKey="Home" roles="*" />
    <siteMapNode url="" roles="Admin" resourceKey="Admin">
      <siteMapNode roles="Admin" resourceKey="AdminPage1" url="~/Admin/AdminPage1.aspx" />
      <siteMapNode roles="Admin" resourceKey="AdminPage2" url="~/Admin/AdminPage2.aspx" IncludeInTasks="true" TaskIcon="/Images/Icons/Templates.ico" />
      <siteMapNode roles="Admin" resourceKey="AdminPage3" url="~/Admin/AdminPage3.aspx" />
      <siteMapNode roles="Admin" resourceKey="AdminPage4" url="~/Admin/AdminPage4.aspx" IncludeInTasks="true" TaskIcon="/Images/Icons/Users.ico" />
      <siteMapNode roles="Admin" resourceKey="AdminPage5" url="~/Admin/AdminPage5.aspx" IncludeInTasks="true" TaskIcon="/Images/Icons/Groups.ico" />
    </siteMapNode>
    <siteMapNode roles="User" resourceKey="UserPage1" url="~/User/UserPage1.aspx" IncludeInTasks="true" TaskIcon="/Images/Icons/Profile.ico" />
    <siteMapNode roles="User" resourceKey="UserPage2" url="~/User/UserPage2.aspx" IncludeInTasks="true" TaskIcon="/Images/Icons/Signatures.ico" />
    <siteMapNode roles="User" resourceKey="UserPage3" url="~/User/UserPage3.aspx" />
  </siteMapNode>
</siteMap>

Comme vous le constatez, nous en avons profité pour inclure ici aussi l’icône que nous allons afficher pour chacune de nos tâches.

Pour l’affichage, nous allons tout simplement utiliser un Repeater directement dans la balise head de notre MasterPage. Celui-ci sera bindé sur la SiteMapDataSource que nous utilisons déjà pour notre menu.

    <asp:Repeater ID="rptTasks" runat="server" EnableViewState="false" DataSourceId="SiteMapDataSource" OnItemDataBound="OnTasksItemDataBound">
        <ItemTemplate>

            <meta name="msapplication-task" content="<%# "name=" + Eval("Title") + ";action-uri=" + Eval("Url") + ";icon-uri=" + Eval("[TaskIcon]") %>"/>

            <asp:Repeater ID="rptSubTasks" runat="server" EnableViewState="false" DataSource='<%# Eval("ChildNodes") %>' OnItemDataBound="OnTasksItemDataBound">
                <ItemTemplate>
                    <meta name="msapplication-task" content="<%# "name=" + Eval("Title") + ";action-uri=" + Eval("Url") + ";icon-uri=" + Eval("[TaskIcon]") %>"/>
                </ItemTemplate>
            </asp:Repeater>

        </ItemTemplate>
    </asp:Repeater>

Nous avons en fait mis deux Repeater imbriqués pour pouvoir parcourir les deux niveaux de notre SiteMap. L’attribut content de nos balises meta se construit simplement en concaténant les trois propriétés à définir, qui nous viennent tout droit des SiteMapNode.

A ce stade, nous affichons tous les éléments, il nous faut encore écrire un peu de code sur l’évènement OnItemDataBound pour pouvoir les filtrer en fonction de notre attribut IncludeInTasks :

    protected void OnTasksItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        SiteMapNode node = e.Item.DataItem as SiteMapNode;
        string include = node["IncludeInTasks"];
   
        if (String.IsNullOrEmpty(include) || include != "true")
        {
            if (node.HasChildNodes)
            {
                e.Item.Controls[0].Visible = false;
            }
            else
            {
                e.Item.Visible = false;
            }
        }
    }

Pour chaque nœud bindé, nous vérifions la valeur de l’attribut IncludeInTasks. Si celui-ci n’est pas présent ou que sa valeur n’est pas égale à true, nous le cachons.

Et le tour est joué ! Sourire

Résultat quand on n’est pas identifié sur le site :

Résultat en tant que membre du rôle “User” :

Résultat en tant que membre des rôles “Admin” et “User” :

Vous pouvez télécharger la solution complète ci-dessous :

La base de données contient deux utilisateurs :

  • Login : user
    Password : user
    Rôles : User
  • Login : admin
    Password : admin
    Rôles : User, Admin

 

Nous avons vu aujourd’hui comment bénéficier des dernières nouveautés d’Internet Explorer 9 en matière d’expérience de navigation sur nos applications ASP.Net, et ce sans déployer trop d’efforts d’implémentation.

J’espère que cela vous sera utile !

Adrien

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

# re: [Internet Explorer 9] Activer la fonctionnalité “Pinned Site” sur votre site ASP.Net @ jeudi 23 septembre 2010 09:21

Sympa :-)

Du coup pour gérer une notification à la facebook, tu mets juste à jour la shortcut icon ?

Gribouillon

# re: [Internet Explorer 9] Activer la fonctionnalité “Pinned Site” sur votre site ASP.Net @ jeudi 23 septembre 2010 11:00

Ben mince alors, j'avai oublié que tu avais un blog Adrien!

En tout cas, super tuto :p

azra

# re: [Internet Explorer 9] Activer la fonctionnalité “Pinned Site” sur votre site ASP.Net @ jeudi 23 septembre 2010 12:54

Merci ;)

@Flo : Ben moi aussi figure toi :p

@Sébastien : Non, les paramètres généraux (le nom, la description, et l'icône) du bouton ne se mettent pas à jour : ils restent tels qu'ils étaient au moment où l'utilisateur a épinglé le site. Cela se fait avec l'API JavaScript dédiée, que je n'ai pas encore vraiment explorée... Mais je ferai peut-être un autre post à ce sujet :)

Adrien Siffermann

# re: [Internet Explorer 9] Activer la fonctionnalité “Pinned Site” sur votre site ASP.Net @ jeudi 23 septembre 2010 14:00

Ca ressemble un peu au application chrome http://www.nirmaltv.com/2008/09/03/how-to-set-up-application-shortcuts-in-google-chrome/

VANNESTE Xavier


Les 10 derniers blogs postés

- Les actualités de la semaine sur c2i.fr (14 mai - 20 mai) par Richard Clark le il y a 3 heures et 47 minutes

- Reactive Extensions : Consommer des services avec Rx Partie 3, les pièges à éviter par Léonard Labat le il y a 12 heures et 52 minutes

- SharePoint Blog Site, problème d’archives par Le Blog (Vert) d'Arnaud JUND le il y a 23 heures et 28 minutes

- Soirée ALT.NET Mai - 3 présentations par #Rui le 05-18-2012, 11:59

- [ #SharePoint 2010][ #SQLServer 2012] AlwaysOn pour SharePoint (2/4) : Configuration (2e partie)… par Le blog de Patrick [MVP SharePoint] le 05-18-2012, 11:31

- Team Foundation Server 11: tous les trésors cachés du site d’équipe par Philess le 05-16-2012, 19:01

- [PowerShell 3] Télécharger et installer la documentation en ligne par Blog de SPBrouillet (Pierrick BROUILLET) le 05-16-2012, 17:36

- [#SharePoint 2010][#SQLServer 2012] AlwaysOn pour SharePoint (1/4) : Configuration (1ère partie)… par Le blog de Patrick [MVP SharePoint] le 05-16-2012, 12:10

- Job Day @MIC Brussels - .Net Developers on Mobile applications par Le Blog (Vert) d'Arnaud JUND le 05-15-2012, 20:26

- [SharePoint 2010] – SharePoint 2010, Windows (Server) 8 et des erreurs IIS sont dans une VM… par Blog de SPBrouillet (Pierrick BROUILLET) le 05-14-2012, 12:10