Intégrer Yammer à SharePoint : Yammer Embed et API REST

Yammer offre deux modes pour son intégration aux sites et applications tierces : Yammer Embed ou une API REST. Voici un descriptif des possibilités offertes par chacun.

Yammer embed

Mode simplifié d’ajout de Yammer à un contenu HTML :

  • Un javascript Yammer à référencer
  • Un bloc HTML comme conteneur
  • Une fonction d’appel avec options


<div id="embedded-feed" style="height:800px;width:400px;"></div>

<script type="text/javascript" src="https://assets.yammer.com/assets/platform_embed.js"></script>
<script type="text/javascript"> yam.connect.embedFeed({
container: "#embedded-feed",
network: "mcnext.com",
feedType: "group",
feedId: "2211345"});
</script>

Note : il est possible d’obtenir cela très facilement en l’exportant directement à partir d’un groupe Yammer ou en utilisant l’utilitaire de configuration fourni par Yammer.

Fonctionnalités offertes

Les fonctionnalités offertes sont exactement les mêmes qu’à l’intérieur d’un flux Yammer :

  • Lecture de messages
  • Ecriture de messages avec pièces jointes
  • Like
  • Suivi
  • Partage
  • Réponse
  • Ajout de sujets
  • Se l’envoyer par email

Le rendu est fait dans une iframe dont la hauteur et la largeur sont fixes.

Les options disponibles

  • Réseau auquel se connecter
    Par défaut le réseau actif de l’utilisateur
  • Forcer la connexion au réseau principal de l’utilisateur, même s’il vient de visiter un réseau externe
  • ID du groupe Yammer utilisé par défaut lors de la saisie d’un nouvel élément
  • Texte à afficher dans la zone de saisie avant que l’utilisateur ait commencé à écrire son message
    Post-IntegrerYammer-TexteParDefaut
  • Type de flux :
    • MyFeed = flux de l’utilisateur
    • Group = choix d’un groupe à afficher par ID
    • User = choix d’un utilisateur à afficher par ID
    • Topic = choix d’un sujet à afficher par ID
    • Open Graph = commentaires sur l’élément courant (par exemple une page d’article ou un document). Plusieurs paramètres complémentaires sont disponibles pour permettre de choisir l’élément commenté, les métadonnées associées au poste…
  • Si le composant utilise le SSO

Modification de l’apparence

Le composant sera affiché dans une iframe et peut être sujet à modifications dans le futur : il ne faut pas chercher à modifier son apparence.

Il est néanmoins possible d’indiquer :

  • Si le header doit être affiché (nom du réseau)
    Post-IntegrerYammer-Header
  • Si le footer doit être affiché (option de déconnexion)
    Post-IntegrerYammer-Footer
  • Si le nom du réseau doit être caché dans le header : si le header est affiché, alors il indiquera un message neutre comme « Conversations Yammer » plutôt que d’indiquer le nom du réseau

API REST

Une api REST permet d’intégrer Yammer comme souhaité au sein de n’importe quelle application. L’apparence est alors complètement personnalisable puisque tout est à la charge du développeur.

Une documentation très complète et claire est fournie sur le site de développement Yammer.

Connexion

Il faut :

  1. Enregistrer l’application dans Yammer
  2. S’authentifier en utilisant le bouton Yammer ou en OAuth.

Une ID d’application est nécessaire pour la connexion. Tous les utilisateurs devront accepter l’application.

Limites d’appels

Le nombre de requêtes par utilisateur et par application est limité. Une erreur sera retournée lorsque l’utilisateur dépassera cette limite. La limite est différente selon le type d’élément demandé :

  • Messages = 10 requêtes en 30 secondes
  • Notifications = 10 requêtes en 30 secondes
  • Tous les autres = 10 requêtes en 10 secondes

Possibilités

Voici les différentes possibilités offertes par l’API REST :

Messages

Type de requête Description Commentaires
GET
  Derniers messages Il est possible de récupérer tout le thread ou uniquement le premier message de chacun.

·        Tous

·        Flux de l’utilisateur

·        Top

·        Suivis

·        Envoyés

·        Messags privés

·        Reçus

  Messages d’un thread
  Messages liés à un sujet
POST
  Ecrire un nouveau message ·        Corps du message

·        ID du groupe dans lequel poster

·        ID du message pour la réponse

·        Utilisateur à qui envoyer le message en privé

·        S’il s’agit d’un broadcast

·        Sujets

·        Pièces jointes

·        Objet opengraph associé

  Envoyer une copie d’un message par email à l’utilisateur courant
  Liker un message
DELETE
  Supprimer un message Par ID
  Unliker un message

Corps d’un message

  • Parsed : les URL sont telles quelles, les mentions d’utilisateurs sont mises sous la forme user:id
  • Plain : les URL sont telles quelles, les mentions utilisateurs sont sous la forme « Nom complet »
  • Rich : HTML à afficher, avec les balises <a></a> pour les URL

Propriétés d’un message

  • ID
  • ID de l’utilisateur ayant posté
  • Date de création
  • ID du réseau
  • Type de message
  • Type de sender
  • URL
  • ID du groupe
  • Body
  • ID de thread
  • Type de client (web, app…)
  • ID des utilisateurs notifiés
  • Message privé ou publique
  • Pièces jointes
    • ID
    • Type
    • Nom
    • Description
    • ID du réseau
    • URL
    • URL de la miniature
    • Type d’objet
    • Nom de l’objet
    • URL de l’hôte
    • HTML à afficher
  • LikedBy : nombre + liste des utilisateurs

Utilisateurs

Type de requête Requête Commentaires
GET
  Utilisateurs du réseau Paginée, triée par nombre de messages, nombre de followers ou alphabétiquement
  Utilisateur courant
  Utilisateur par ID
  Utilisateur par email
  Utilisateurs d’un groupe Paginée, triée par nombre de messages, nombre de followers ou alphabétiquement
  Utilisateurs ayant utilisé un sujet
  Utilisateurs ayant liké un message
  Relations pour l’utilisateur courant ou par ID Supérieurs, subordonnés et collègues
POST
  Créer un utilisateur
  Inviter un utilisateur au réseau Yammer actif
  Ajouter une relation
DELETE
  Supprimer un utilisateur
PUT
  Modifier un utilisateur

Propriétés d’un utilisateur

  • Email
  • ID
  • Réseau : ID, Nom, Domaines
  • Etat
  • Activation : Date, auto activé ou non
  • Nom complet
  • URL du profil
  • Image de profil (48×48)
  • Date de naissance
  • S’il est administrateur
  • Statistiques : nombre de followers, nombre de personnes suivies
  • Poste
  • Département
  • Emplacement
  • Téléphone de travail
  • Téléphone mobile
  • Intérêts
  • Résumé
  • Expertise
  • Diplômes
  • Entreprises précédentes

Groupes

Type de requête Requête Commentaires
GET
  Groupes suggérés
POST
  Rejoindre un groupe
DELETE
  Quitter un groupe
  Supprimer une suggestion de groupe

Suivi

Type de requête Requête Commentaires
GET
  Utilisateurs suggérés pour le suivi
  Vérifier si on suit un utilisateur
  Vérifier si on suit un thread
  Vérifier si on suit un sujet
  S’abonner à un élément
DELETE
  Se désabonner d’un élément
  Supprimer une suggestion d’utilisateur à suivre

Autres

Type de requête Requête Commentaires
GET
  Notifications de l’utilisateur courant
  Recherche Faire des requêtes de recherche, comme dans le portail Yammer
  Liste des réseaux auxquels l’utilisateur a accès

[SPC14] SPC408 // SharePoint 2013 Apps with AngularJS

Mail de Christian

Jeudi 06/03/2014 à 9h00

Speaker
Jeremy Thake – VP of Global Product Innovation @ AvePoint Inc. // MVP @jthake C’est sa dernière session en tant que MVP puisqu’il va rejoindre l’équipe produit chez Microsoft ! Awesome !

Résumé
Bonne session, un peu trop courte qui donne une bonne introduction à AngularJS qui est très large pour tenir dans une seule session.
Ce framework est assez complet mais complété par jQuery et d’autres modules, on peut faire une App SharePoint 2013 avec des frameworks très puissants. Tout cela en gardant une propreté dans le code javascript qui sans ça peut devenir assez compliqué à lire.
Le framework propose des très bon mécanismes de data binding, assez propres etc.

// Agenda
Pourquoi AngularJS
Intro à AngularJS
Getting started in SharePoint
CompleteMe App
Tips and Tricks

// Pourquoi AngularJS
Même si AngularJS est fait par Google, il dit que le modèle de développement a changé en utilisant les différents outils mis à dispo par tous pour accomplir son but.
Il existe depuis janvier 2010, il y a plus de 600 contributeurs, 2500 requêtes produits. C’est un outil très supporté.
Les développeurs Google sont vraiment impliqués dans le développement d’AngularJS Beaucoup de ressources existent sur le marché, sur le net. Des ebooks, des sites comme PluralSight, Codeacademy, Il présente un slide de Google, comme quoi GWT était très populaire mais a baissé, à contrario de AngularJS qui les a déplacé tous. Backbone, embuer ou knockoutjs sont eux restés assez bas.
Il aime beaucoup
Google feedback un outil avait pris 6 mois pour 3 dév et 17000 lignes de code. Avec AngularJS, cela a pris 3 semaines, 1500 lignes de code.
Plusieurs avantages
-Gestion du DOM et de l’AJAX,
-Une structure très bien définie
-Tout existe pour faire une App qui fait du CRUD -Testable, il y a un framework de test dans AngularJS qui facilite les Model View .. AngularJS utilise un modèle view … whatever. Pour ne pas appeler ça MVC, MVVM qui ne correspondait pas bien.

// Intro à AngularJS
La base.
Utilisation dans <html> l’attribut ng-app.
Data-binding : on peut changer le modèle, la donnée, la vue est automatiquement changée avec un système de watch/espion.
Cela se fait grâce à {{ phones.length }}.
On utilise angular.module(‘myApp’, []); qui permet de créer son module.
Le scope permet de gérer la vue, l’objet $scope passé en paramètre de la création du control.
Il y créé un tableau de téléphones, avec des caractéristiques.
Et ensuite dans l’HTML, il utilise ng-controller pour déclarer le nom de sa fonction qui crée le control.

// DEMO : AngularJS 101
Il utilise un jsfiddle. Il y montre une sorte de repeater fait en Angular grâce à l’attribut ng-repeat.
Il fait un ng-repeat= »contact in contacts » où contacts est une collection.

// Directives
Il a déjà montré le ng-controller.
<edit-in-place value= »contact.name » />
app.directive(‘editInPlace’, function() { … Cela permet de créer des attributs custom. Ici edit-in-place.
Il y montre que cela lui permet d’avoir des composants comme un mode edit, qui rafraichit un autre ng-repeat qui lui affiche la valeur.
La valeur saisie dans son mode édit est mis à jour en live par AngularJS plus bas où il l’affiche.

// Factory et provider
Factory : Il permet de créer comme en .NET plusieurs instances.
Provider : autre permet de réaliser des couches d’abstractions Les deux en fait. Mais il passe vite, il n’a pas le temps de détailler et nous invite à fouiller.

// Broadcaster
Il y a un concept qui permet de broadcaster une valeur qui propage la valeur tout seul vers différentes vues dans la page.

// Animations
Il montre qu’il y a également dans AngularJS un système d’animation plutôt puissant.

// Avec SharePoint 2013
Il ne peut pas utiliser le body, il met ng-app= »myApp » sur une simple div ce qui lui permet d’avoir plusieurs apps dans une page SharePoint

// DEMO : CompleteMe App
Il montre une App tâche qui lui permettra d’avoir une liste de tâches où il peut faire des rappels particuliers comme « jamais », dans « 1 an » etc.
Son app est créée en SharePoint hosted sur Visual Studio.
Dans les scripts, il y a un dossier controller et un services.
Sur sa page Default.aspx, il ajoute la déclaration des javascript jquery, angulaire, bootstrap.
Il charge les js de son modèle AngularJS.
Il charge les js SharePoint pour par exemple les people picker. Il a fait un post pour expliquer comment mettre ça en place (il y a des problèmes quand on ajoute plusieurs people pickers normalement).
Il montre la plomberie de son App, avec notamment la requête qui gère l’échec de requête. Et sur le succès de requête, il ajoute les items dans le tableau de son controller.
Dans le cas d’un minifiy, il faut déclarer le controller d’une certaine façon car AJAX Minifier remplace les noms des variables ce qui casse la déclaration Angular. C’est donc contournable.
Le template est normalement mis dans un attribut template HTMLdans le javascript. Pour contourner ça, il faut passer par la directive compile qui permet d’externaliser et charger un template HTML avec un templateLoader qui fait un HTTP get du template. Dans le retourne du compile, il y a un prelink à compléter. Il faut voir son post pour mieux comprendre avec les exemples.
Pour la sauvegarde de ses items, il utilise du JSOM avec les promises jQuery.
Il nous invite à regarder la bibliothèque breeze qui permet de créer des entités. Il ne détaille pas ici car ce n’est pas le sujet.

// Tips and tricks
Il n’est pas bon en CSS haha. Il conseille d’utiliser UI Bootstrap, un module qui peut être à AngularJS qui permet assez facilement de faire des layouts, des formulaires avec validations, datepicker, du responsive etc.
Pour les people picker, aller voir son billet sur son post pour faire ça car l’exemple MSDN n’est pas top.
Utiliser moment.js qui permet de gérer facilement les temps en js.
Visual Studio Online, permet d’avoir un TFS, et il conseille de l’utiliser pour faire du code review simple avec un compte live id.

Christian

SPC14] SPC414 // Search content enrichment and extensibility in SharePoint 2013

Mail de Christian

Mercredi 05/03/2014 à 13h45

Speaker
Brent Groom – Senior Premier Field Engineer @ Microsoft Consulting Services Sreedhar Mallangi – Senior Consultant @ Microsoft Consulting Services

Résumé
C’est une session on-prem sur la façon dont on peut étendre les sources de contenus d’un moteur de recherche SharePoint 2013.
On utilise Search Indexing Toolkit (SIT) qui facilite la création de connecteurs de contenus.
On peut utiliser Content Enrichment Web Service (CEWS Pipeline Toolkit) aussi pour enrichir le contenu indexé par des informations supplémentaires.
Une session très intéressante et qui montre surtout comment le moteur de recherche SharePoint 2013 peut être étendu et configuré avec notamment un ajout de code qui permet d’ajouter du contenu spécifique à nos résultats, tout en gardant une expérience utilisateur poussée où on vient enrichir du contenu indexé pour par exemple enrichir le panneau de raffinement de métadonnées qui ne sont pas automatiquement indexées.

// Agenda
Identifier les extension de contenu
Connecteurs custom
Enrichissement du contenu
Toolkits de la communauté

// Architecture overview
Il décrit l’architecture du service de recherche et notamment le composant de crawl qui prend en input plusieurs connecteurs possibles.
On peut sur SharePoint 2013 faire du crawl continu.

// Content ingestion
Pourquoi est-ce important. On va voir comment fonctionne l’input de contenu, la gestion de contenus crawlante et comment on peut avoir des connecteurs spécifiques propres à chaque contenu.
FAST ESP (Enterprise Search Platforms), permettait d’avoir des APIs d’extraction de contenu.
Maintenant sur SharePoint 2013, on a des connecteurs, des handlers (pour file share, sharepoint, profils), et des connecteurs BCS.
Business Connectivity Services permet pour rappel de connecter des données externes vers SharePoint. BCS peut être utilisé comme source de contenu pour la recherche SharePoint.
On peut faire du BCS sans code avec OData ou SQL.
Ou BCS avec du code avec du WCF ou de l’assembly .NET pour extraire du contenu.

// Search Indexing Toolkit – SIT
C’est une implémentation générique d’un connecteur d’indexation Il a un modèle de données générique mais implémente la complexité du batching, du crawling (full/incrémentale), security trimming (gestion de la sécurité dans les résultats).
Dans le package il y a de l’XML avec un modèle, une interface à implémenter éventuellement.
SIT XML file connecter peut indexer n’importe quel fichier XML.
Bon il va très vite dans ce qu’il sait faire, en résumé c’est un outil top, qui est scalable, performant, flexible.

// DEMO
Il ouvre le package SIT. On voit des éléments de démos. Des DLL, des classes à récupérer. Et des scripts powershell permettent de déployer le tout.
Il montre un fichier XML qui liste différents documents à crawler.
Un autre de configuration SIT.
Le docandidpath permet au connecteur de savoir dans le fichier XML des éléments à crawler, comment le connecteur doit accéder (en DOM) à l’URL de l’identifiant du document.
Il lance une commande Powershell et utilise le Powershell qui va déployer notamment dans le GAC. Un autre Powershell lui permet d’enregistrer le fichier XML de configuration sur le service de recherche et d’ajouter le type de source de contenu à sa content source.
Eventuellement le script peut lancer un full crawl.
En allant voir dans le schéma de recherche, on voit qu’un certain nombre de Managed Properties sont créées pour être utilisées dans les résultats de recherches.
On peut désactiver ça en allant dans les crawled proprettes.
Il ouvre ULS Viewer et filtre sur la catégorie contient SIT pour voir comment se comporte le crawl.
Il utilise Search Query Tool disponible sur Codeplex pour faire une requête et tester son contenu.
Il fait une recherche sur la contentsource wikiabstracts qu’il a créé, et trouve les résultats de son fichier.

// SIT ISearchConnector interface
En implémentant cette interface, il y a 6 méthodes à implémenter.
Le ContentSource permet de définir le nom de la source de contenu.
Initialize() permet d’initialiser les paramètres du connecteur (lieu de stockage etc).
GetAllItems() permet grâce avec les paramètres offset (taille du match), crawlType, changeToken et changeTokenUpdate qui permettent de différencier le contenu de deux crawl consécutifs. Cette méthode génère un tableau d’ID de document.
GetSpecificItem(id) permet de retrouver un item en fonction de son ID fournit ci-dessus.
GetSpecificItemData(id) permet de récupérer le contenu.
GetSecurityDescriptorForSpecificItem(itemId, aclmeta, usesPluggableAuth) permet de gérer la sécurité d’un item (security trimming).

// Item level security
Chaque document doit supporter la sécurité NTLM, et être taggé.
Sinon on doit implémenter custom claims avec un provider ou security trimmer.

// Exemples de scénarios
Crawler des fichiers XML générés depuis des applications tierces.
SQL Server avec du security trimming.
SQL Server avec un BLOB relié sur un partage réseau.

// Content enrichment
C’est la façon d’enrichir du contenu existant.
Content Enrichement Web Service (CEWS).
C’est un web service qui est configuré sur le moteur de recherche via Powershell qui va prendre en input des données déjà existantes, et fournir en sortie des managed propreties qui seraient enrichies, nettoyées ou en tout cas traitées.
Il nous montre dans un rapport du service de recherche que cet enrichissement prend très peu de temps.
Quelques éléments à prendre en compte, c’est que les propriétés doivent exister, que c’est case sensitives, qu’on ne peut pas utiliser d’alias, et des propriétés par défaut sont parfois déroutantes car ressemblant à des propriétés existantes (DisplayAuthors vs Author). Enfin certaines propriétés sont en readonly (body). On ne peut avoir qu’un seul webservice par service application de recherche.
Attention à augmenter la capacité de la ferme en conséquence, et la topologie serveur.
Quelques techniques pour implémenter ça.
On peut utilise WCF Routing grâce à .NET 4.0.(http://aka.ms/Pqkjjj) Faire du Load balancine pour gérer la scalability.

// CEWS Pipeline Toolkit
Il y a un toolkit facilitant l’amélioration du contenu.
Il améliore le Search Index.
C’est fait en WCF avec un XML de configuration.
Il permet de simplifier et de cacher des complexité d’agrégation de service, de gestion de scalability.
Ce qu’il y a dans le package ? 55 stages permettant de gérer vraiment plus configurations avec l’XML de configuration. Cela fonctionne sur SharePoint 2010 avec FAST, ou SharePoint 2013 .. ou tout seul.
On peut le customiser avec Visual Studio 2012 et .NET 4.5.
Il y a beaucoup de documentation sur le wiki TechNet.

// DEMO
Il va montrer de quoi le package est composé.
Il montre déjà le résultat, il recherche « europe » et voit qu’il y a des éléments venant de wikipedia avec des raffinements sur la gauche, wikipedia population, la catégorie wikipedia qui sont custom.
On navigue dans pas mal de fichiers XML dans le package CEWSPT pour décrire comment les raffinements sont faits. Impossible de tout retranscrire mais il explique en gros que c’est très flexible et configurable, et que l’usage est plutôt bien documenté.

// How to get the tools
On peut récupérer les outils via un contact chez MCS, un contact chez PFE.
Le disponibilité en public est en cours d’approbation.

Christian

La Content Search Web Part et les Display Template

Content Search Web Part

Présentation de la CSWP

SharePoint 2013 apporte son lot de nouveautés, l’une d’entre elles est l’ajout d’une Web Part nommé « Content Search », « Recherche de contenu » en français. Cette dernière permet d’interroger le moteur de recherche pour restituer une information. Cette Web Part est une version amélioré de la Content Query Web Part qui ne reste, pour beaucoup, qu’un vestige des versions précédentes de SharePoint. Il faut noter que cette webpart est disponible pour la version Enterprise sur on-premises. Quant aux éditions Office 365 et SharePoint Online, la CSWP est désormais disponible sur les plans Entreprise (E3, E4, A3, A4, G3 et G4) au même titre que la fonctionnalité de Cross-Site Publishing et la navigation par facettes.

Content Search Web Part

Content Search Web Part

Dans les propriétés de cette Web Part, il est possible de définir une requête à l’intérieur de laquelle l’index du moteur de recherche est interrogé. Ces requêtes, une fois exécutée, retournent des résultats suivant plusieurs paramètres, à savoir:

  • Une source de résultats (anciennement l’étendue ou Scope)
  • Des règles de requêtes
CSWP

Propriété Content Search Web Part

Query Builder

Une interface de conception appelée Query Builder est à notre disposition pour créer la requête en sélectionnant la source de résultat, l’ordre avec laquelle les informations doivent remonter, etc. …Il est également possible de passer l’interface en mode avancé.  A partir de là, nous pouvons récupérer certaines propriétés et autres mots clés afin de filtrer le résultat. Le filtre de propriété apporte une grande profondeur dans la formulation de nos requêtes, il est entre autre possible de récupérer directement les paramètres d’URL.

Liste filtre Query Builder

Liste filtre Query Builder

Dans cet exemple, nous utilisons le filtre URLToken sur notre propriété ProductCatalogGroupNumberOWSTEXT afin de récupérer le deuxième paramètre de notre URL.

SPTokenURL

SPTokenURL

Cette propriété nous permet, in fine, de n’afficher que les résultats correspondants au deuxième paramètre d’URL. Dans ce contexte il s’agit de n’afficher que les produits faisant partit du groupe « 2146″.

Query Builder

Query Builder

Les Display Template

Présentation des modèles

Une fois que la requête est définie, il faut mettre en forme les résultats. Je vous vois venir de loin avec vos modifications de fichiers XSLT … Ici, il n’en est pas questions, nous allons utiliser les composants natifs livrés avec notre SharePoint 2013 : les Display Template et Control Display Template.

Ces derniers sont disponibles dans la galerie de pages maitre et mise en pages. De nombreux autres Templates sont également de la partie: Filter Display Template, Group Display Template, HTML Master Page pour ne citer qu’eux, mais ces derniers ne font pas l’objet de ce poste, donc je ne m’arrêterais pas dessus.

Lors des premières manipulations de ces fichiers, vous remarquerez assez rapidement que lorsque vous ajoutez un nouveau Template, un fichier JavaScript y est associé. Un conseil, n’y touchez pas. Le fichier associé est en fait le résultat d’une conversion du fichier source html en JS.  Une propriété « Associated File » est présente pour le fichier HTML.

Fichier associé

Display Template, fichier associé

Gestion des modèles

Dans le cadre de ce poste, nous récupérons des modèles par défaut pour en faire de nouveaux « custom ». Pour le modèle de type Control, nous partons sur le Control_List.html et pour celui de l’Item, nous prendrons le Item_Default.html. Une fois la copie de ces fichiers effectuée, il faut renommer le contenu de la balise <Title> avec quelque chose de plus approprié. Une fois nos modèles téléchargés, nous pouvons les associer à notre Web Part en les sélectionnant dans notre catégorie Display Template.

Control et Item display template

Control et Item display template

L’image ci-dessous illustre le positionnement de nos Display et Control Template dans le cadre d’un tableau de résultats. Ici, l’objectif est d’avoir un tableau dans lequel nous pouvons récupérer les éléments issus de notre requête définies plus haut.

Schéma display template

Schema Display Template

Comme mentionné précédemment, je vous recommande fortement de vous appuyer sur les modèles standard, de renommer les Title et l’ID de notre div et de les utiliser tel quel au début. Ensuite, une fois que vous avez l’assurance qu’il s’agit bien de votre modèle qui est utilisé pour l’affichage, vous pourrez effectuer les modifications dans SharePoint Designer 2013, ou par le biais d’un éditeur de texte comme Notepad++.

Modification des modèles

Plusieurs balises propres à SharePoint sont disponibles dans ces modèles afin de faciliter la récupération et la transformation des éléments issus de la recherche.

  • _#= ctx.RenderGroups(ctx) =#_  et _#= ctx.RenderItems(ctx) =#_ sont des fonctions utilisés pour appeler nos Display Template
  • _#= ctx.CurrentItem.xxx =#_ est une fonction utilisée pour afficher le rendu de notre propriété (ex : Title, Path, etc …).

Les propriétés disponible sont définies au début du modèle, dans la section  <mso:ManagedPropertyMapping msdt:dt= »string »>. Il est possible de rajouter des propriétés gérées dans cette même section. Dans notre cas, nous souhaitons rajouter des propriétés gérés liées à catalogue de produits provenant d’un autre site :

Managed properties display template

Managed properties display template

Un peu plus bas dans notre modèle, nous pouvons ajouter nos CSS et JavaScripts dans la balise <script>

Par exemple:

Javascript display template

Javascript display template

Il suffit ensuite d’éditer le code HTML juste en dessous pour créer notre tableau.

Notre Display Control

<table class="artis-tasktable" id="_#= encodedID =#_">
    <thead>
        <tr>
            <th>Product Model</th>
            <th>Product Name</th>
            <th>Price (in $)</th>
            <th>Color</th>
            <th>Size</th>
            <th>Weight</th>
        </tr>
    </thead>
    <tbody>
         _#= ctx.RenderGroups(ctx) =#_
    </tbody>
</table>      </div>
</body>
</html>

Notre Display Item 

        <div id="_#= containerId =#_" data-displaytemplate="ItemLargePicture">
            <div id="_#= pictureContainerId =#_">
                <h1 id="_#= line1Id =#_"> _#= line1 =#_</h1>
                <a href="_#= linkURL =#_" title="_#= $htmlEncode(line1) =#_" id="_#= pictureLinkId =#_">
                    _#= pictureMarkup =#_
                </a>
            </div>
        <div id="itemdescription">
            <p class="currency">$ _#= Math.round(ctx.CurrentItem.CostOWSCURR * 100) / 100 =#_ </p>
            <ul class="desclist">
                <li><span class="desc">Description:</span> _#= ctx.CurrentItem.Description =#_ </li>
                <li><span class="desc">Color:</span> _#= ctx.CurrentItem.ColorOWSTEXT =#_ </li>
                <li><span class="desc">Weight:</span> _#= ctx.CurrentItem.WeightOWSTEXT =#_ </li>
                <li><span class="desc">Size:</span> _#= ctx.CurrentItem.SizeOWSTEXT =#_ </li>               
            </ul>
         </div>
        </div>
    </div>
</body>
</html>

Et voilà le résultat final. Et surtout, n’oubliez pas de publier vos modèles !

Display Template

Display Template

Les conditions dans les types de résultats : Types de contenus ou types de contenus ?

En allant plus avant dans la création de nouveaux types de résultats pour la présentation de résultats de recherche personnalisés, je me suis heurté à un élément de langage que je qualifierais pour le moins de déroutant.

D’où proviennent ces « types de contenus » (Figure 1-Liste des types de contenus) que l’on doit insérer comme condition d’un type de résultat. En cherchant dans les types de contenus de mon site, je n’ai rien trouvé comme correspondance.

result_types_1

result_types_2

Figure 1-Liste des types de contenus

La dénomination en anglais est légèrement moins déroutante (je plaisante) : on parle de « site content types » pour les types de contenus que vous connaissez déjà bien et de « types of content » (Figure 2) pour les éléments de conditions de « Result Types ».

result_types_3

Figure 2-Type of content

La liste des types de contenu (ou types of content) est non modifiable.

Elle provient d’un dictionnaire interne de type <string, PropertyRule> de la classe Microsoft.Office.Server.Search.Administration.MappedPropertyRules imbriquée dans la classe Microsoft.Office.Server.Search.Administration.PropertyRule

Le fait de sélectionner « Microsoft Word » comme type de contenu dans la liste est équivalent à définir les conditions suivantes sur la propriété personnalisée « FileType » : FileType= »docx » OR FileType= »doc » OR FileType= »docm » OR FileType= »dot » OR FileType= »dotx »

Pour être plus parlant les 2 cas suivants sont totalement identiques :

Cas 1 : Définition de conditions par type de contenu

result_types_4

Cas 2 : Définition de conditions par propriétés

result_types_5

Vous trouverez ci-dessous un tableau des équivalences :

Condition « Type de contenu » Condition avec propriétés personnalisées équivalentes
Microsoft Access
FileType="accdb" OR FileType="accdc"
OR FileType="accde" OR FileType="accdr"
OR FileType="accdt"
Microsoft Excel
FileType="xls" OR FileType="xlsx"
OR FileType="xlsm" OR FileType="xlsb"
OR FileType="xltm" OR FileType="xltx"
OR FileType="xlam"
Microsoft OneNote
FileType="one"
Microsoft PowerPoint
FileType="ppt" OR FileType="pptx"
OR FileType="pptm"
Microsoft Publisher
FileType="pub"
Microsoft Visio
FileType="vdw" OR FileType="vdx"
OR FileType="vsd" OR FileType="vss"
OR FileType="vst" OR FileType="vsx"
OR FileType="vtx"
Microsoft Word
FileType="docx" OR FileType="doc"
OR FileType="docm" OR FileType="dot"
OR FileType="dotx"
Discussion
StartsWith(ContentTypeId,"0x012002")
Répondre
StartsWith(ContentTypeId,"0x0107")
Courrier électronique
FileType="eml" OR FileType="msg"
OR FileType="exch"
Image
FileType="bmp" OR FileType="dib"
OR FileType="jpeg" OR FileType="png"
OR FileType="gif" OR FileType="rle"
OR FileType="wmf" OR FileType="ico"
OR FileType="wpd" OR FileType="odg"
OR FileType="tiff"
PDF
FileType="pdf"
Texte
FileType="odt" OR FileType="txt"
OR FileType="url" OR FileType="csv"
Vidéo SharePoint
StartsWith(ContentTypeId),"0x0120D520A808"
OR SecondaryFileExtension="wmv"
OR SecondaryFileExtension="avi"
OR SecondaryFileExtension="mpg"
OR SecondaryFileExtension="asf"
OR SecondaryFileExtension="mp4"
OR SecondaryFileExtension="ogg"
OR SecondaryFileExtension="ogv"
OR SecondaryFileExtension="webm"
XML
FileType="xml" OR FileType="infopathml"
Zip
FileType="zip"
Blog SharePoint
WebTemplate="blog"
Communauté SharePoint
WebTemplate="COMMUNITY"
Forum de discussion SharePoint
contentclass="sts_list_discussionboard"
OR contentclass="sts_listitem_discussionboard"
Bibliothèque de documents SharePoint
contentclass="sts_list_documentlibrary"
Liste SharePoint
contentclass="sts_list" OR contentclass="sts_list_432"
OR contentclass="sts_list_genericlist"
OR contentclass="sts_list_agenda"
OR contentclass="sts_list_announcements"
OR contentclass="sts_list_contacts"
OR contentclass="sts_list_events"
OR contentclass="sts_list_issuetracking"
OR contentclass="sts_list_links"
OR contentclass="urn:content-class:spspeople"
OR contentclass="sts_list_gantttasks"
OR contentclass="urn:content-classes:spssiteregistry"
OR contentclass="sts_list_tasks"
Billet Microblog SharePoint
StartsWith(ContentTypeId,
"0x01FD4FB0210AB50249908EAA47E6BD3CFE8B")
OR StartsWith(ContentTypeId,
"0x01FD59A0DF25F1E14AB882D2C87D4874CF84")
Bibliothèque d’images SharePoint
contentclass="sts_list_picturelibrary"
Site SharePoint
contentclass="sts_site"
OR contentclass="sts_web"
Enquête SharePoint
contentclass="sts_list_survey"
OR contentclass="sts_listitem_survey"
Wiki SharePoint
StartsWith(ContentTypeId),"0x010108")
OR StartsWith(ContentTypeId),
"0x010100C568DB52D9D0A14D9B2FD
CC96666E9F2007948130EC3DB06
4584E219954237AF39004C1F8B4
6085B4d22B1CDC3DE08CFFB9C")
Élément de la liste des bibliothèques d’images SharePoint
contentclass="sts_listitem_picturelibrary"
Élément de liste SharePoint
contentclass="sts_listitem_6510"
OR contentclass="sts_listitem_contacts"
OR contentclass="sts_listitem_events"
OR contentclass="sts_listitem_issuetracking"
OR contentclass="sts_listitem_links"
OR contentclass="urn:content-classes:spslisting"
OR contentclass="urn:content-class:spslisting:news"
OR contentclass="urn:content-classes:spspersonlisting"
OR contentclass="sts_listitem_gantttasks"
OR contentclass="urn:content-class:spssearchquery"
OR contentclass="urn:content-classes:spssitelisting"
OR contentclass="sts_listitem_tasks"
OR contentclass="urn:content-classes:spstextlisting"
OR contentclass="sts_listitem_genericlist"
Page web
FileType="html" OR FileType="mhtml"
AND contentclass!="sts_listitem_documentlibrary"
Fichier Vidéo
SecondaryFileExtension="wmv"
OR SecondaryFileExtension="avi"
OR SecondaryFileExtension="mpg"
OR SecondaryFileExtension="asf"
OR SecondaryFileExtension="mp4"
OR SecondaryFileExtension="ogg"
OR SecondaryFileExtension="ogv"
OR SecondaryFileExtension="webm"

Pour terminer, un petit script Windows PowerShell pour énumérer les types de résultats et leurs conditions par défaut au niveau d’une collection de sites. Il vous permettra de vérifier la correspondance entre une condition par défaut (type de contenu) et un ensemble de conditions personnalisées.

# Définition du site SharePoint
$siteUrl = "http://intranet.contoso.com";
$site = Get-SPSite $siteUrl;

# Définition d'un objet SearchObjectOwner
# pour récupérer le paramétrage de recherche
$searchOwner = New-Object 
  Microsoft.Office.Server.Search.Administration.SearchObjectOwner(
  [Microsoft.Office.Server.Search.Administration.SearchObjectLevel]::SPSite,
  $site.RootWeb);

# get current search service application
$sspApp = Get-SPEnterpriseSearchServiceApplication;

# Création d'un ResultItemTypeManager à partir
# d'une application de service de recherche
$resMgr = New-Object
  Microsoft.Office.Server.Search.Administration.ResultItemTypeManager($sspApp);

# Récupération des types de résultats liés
$resMgr.GetResultItemTypes($searchOwner, $false) | % {
  Write-Host ("{0}" -f $_.name) -foregroundcolor cyan;
  foreach ($pr in $_.Rules.PropertyRules) {
    Write-Host (" PropertyRule={0}" -f $pr) -foregroundcolor yellow;
  };
}

Les Composed Looks dans SharePoint 2013

Introduction

Beaucoup de choses ont changé depuis l’arrivée de la nouvelle version de SharePoint. Vous rappelez-vous des thèmes dans SharePoint 2010 ? Et bien dites maintenant bonjour aux …  Composed Looks !

Change the look

Galerie des Composed Looks

Les Composed Looks, c’est quoi ?

Pour en donner une définition simple, les Composed Looks sont un assemblage de composants graphiques qui vont vous permettre en un minimum d’effort  de créer des thèmes.

Bien sûre, ces derniers ne seront pas pertinents pour tous vos projets mais ils ne sont pas à négliger car cette nouvelle fonctionnalité va vous permettre de composer une charte graphique de manière très simple en utilisant :

  • une Master Page
  • une palette de couleurs
  • une palette de polices
  • une image de fond

Lire la suite