Personnaliser l'affichage de votre contenu à l'aide des modèles

Bien que certains modules de Yapla permettent d'afficher les données des fonctionnalités Données et Événements (pour les types congrès), il est possible de créer de toute pièce un modèle d'affichage de ces données dans votre site Web Yapla. Plusieurs exemples sont possibles : la programmation de votre congrès, les conférenciers de votre congrès, une liste d'offre d'emploi, une liste d'individu ou de ressources, etc.

Dans cet article destiné aux développeurs de site Web, vous comprendrez les étapes à franchir pour créer vos premiers modèles.

Prérequis

Pour accéder à la création des modèles de Yapla, vous devez avoir le forfait Premium et un site Web Yapla. Vous devez également avoir créé un objet dans la fonctionnalité Données. Les objets que vous souhaitez récupérer doivent avoir une visibilité publique.

visibilite_objet.png

Créer un modèle

Vous pouvez créer les modèles depuis la tuile Vue et modèles de votre site Web dans la fonctionnalité lSite Web, puis dans l'onglet Modèles.

Types de modèles

  • Modèle de module Yapla: Pour personnaliser l'apparence et les fonctionnalités d'un module Yapla existant. Certains modules peuvent avoir plusieurs modèles pour leurs différentes interfaces.
  • Modèle indépendant: Pour créer un modèle de zéro, non lié à un module Yapla

modele.png

Tous les modèles offrent les mêmes possibilités: un modèle utilisant le moteur de rendu Vue JS, du CSS et une requête GraphQL pour récupérer des informations depuis Données. La requête et le CSS sont optionnels et seront chargés uniquement lorsque le modèle est utilisé sur une page.

Les modèles de module sont pré-remplis par défaut avec le code de base du module pour faciliter leur personnalisation.

Afficher le modèle

Pour afficher un modèle il faut utiliser le module correspondant au type de modèle que vous avez utilisé. Dans le cas d'un modèle personnalisé pour le module de site web "Programmation d'événement" par exemple, il faut aller sélectionner le modèle dans la configuration du module.

modele_suite.png

Pour un modèle indépendant c'est le module "Affichage personnalisé d'objets" qu'il faut utiliser.

perso_module.png

Récupérer des informations depuis Données

Les modèles peuvent accéder aux entrées d'objets dans Données à l'aide d'une API GraphQL générée à partir des objets publics de votre association. Un schéma statique est généré et peut être consulté à l'aide d'un logiciel tiers (tel que Postman par exemple) à l'adresse suivante: https://votresite.com/fr/graphql.

C'est avec cette API que le modèle peut interagir pour récupérer vos données. Dans l'onglet "Requête" du modèle se trouve l'éditeur GraphQL, il vient avec une analyse syntaxique de votre requête et offre de l'auto-complétion intelligente à partir du schéma de votre association.

Exemple de schéma d'objets Yapla

type Query {
  allCharacterEntries(
    after: String
    first: Int
    before: String
    last: Int
  ): characterEntryConnection
  allEpisodeEntries(
    after: String
    first: Int
    before: String
    last: Int
  ): episodeEntryConnection
}

"A connection to a list of items."
type characterEntryConnection {
  "Information to aid in pagination."
  pageInfo: PageInfo!

  "Information to aid in pagination"
  edges: [characterEntryEdge]
}

"Information about pagination in a connection."
type PageInfo {
  "When paginating forwards, are there more items?"
  hasNextPage: Boolean!

  "When paginating backwards, are there more items?"
  hasPreviousPage: Boolean!

  "When paginating backwards, the cursor to continue."
  startCursor: String

  "When paginating forwards, the cursor to continue."
  endCursor: String
}

"An edge in a connection"
type characterEntryEdge {
  "The item at the end of the edge"
  node: characterEntry

  "A cursor for use in pagination"
  cursor: String!
}

type characterEntry {
  identifiant: Float
  status: String
  name: String
  appears_in(
    after: String
    first: Int
    before: String
    last: Int
  ): episodeEntryConnection
}

"A connection to a list of items."
type episodeEntryConnection {
  "Information to aid in pagination."
  pageInfo: PageInfo!

  "Information to aid in pagination"
  edges: [episodeEntryEdge]
}

"An edge in a connection"
type episodeEntryEdge {
  "The item at the end of the edge"
  node: episodeEntry

  "A cursor for use in pagination"
  cursor: String!
}

type episodeEntry {
  identifiant: Float
  status: String
  name: String
  characters(
    after: String
    first: Int
    before: String
    last: Int
  ): characterEntryConnection
}

Exemple de requête

query {
  episodes: allEpisodeEntries {
    edges {
      node {
        name
        characters {
          edges {
            node {
              name
            }
          }
        }
      }
      cursor
    }
  }
}

Le composant <Query> 

Le composant <Query> permet d'executer la requête et de récupérer le résultat retourné par le serveur. Le résultat est retourné dans les props du slot du composant. Si on continue l'exemple au-dessus, pour afficher la liste des épisodes on utiliserait le code suivant:

<Query v-slot="{ queryData }">
  <h3>Épisodes</h3>
  <div class="episodes">
    <div
      v-for="(episodes, i) in queryData?.episodes.edges"
      :key="i"
      class="episode"
    >
      <p>{{ episode.node.name }}</p>
      <div class="characters">
        <p>Personnages de l'épisode</p>
        <div
          v-for="(character, y) in episode.node.characters.edges"
          :key="y"
          class="character"
        >
          <p>{{ character.node.name }}</p>
          <p></p>
        </div>
      </div>
    </div>
  </div>
</Query>

Pagination

L'API générée par Yapla offre de la pagination avec curseur. En combinant les retours du serveur avec le composant <Query> on peut mettre en place deux types de pagination:

  • Une liste infinie
  • Une pagination bidirectionnelle non numérotée

Liste infinie

Pour mettre en place une pagination de type liste infinie on peut se servir des variables suivantes:

  • pageInfo.hasNextPage pour savoir si on a atteint la fin des résultats
  • pageInfo.endCursor pour définir le point de départ du prochain segment de résultats

On aura également besoin d'utiliser la fonction fetchNext du composant <Query> et rajouter les paramètres de pagination à la requête GraphQL. Le tout dans un exemple simple:

query ($first: Int, $after: String) {
  episodes: allEpisodeEntries(first: $first, after: $after) {
    edges {
      node {
        name
      }
      pageInfo {
        hasNextPage
        endCursor
      }
      cursor
    }
  }
}

Requête paginée

<Query :first="5" v-slot="{ queryData, aggregatedData, isLoading, fetchNext }">
  <h3>Épisodes</h3>
  <div class="episodes">
    <div
      v-for="(episodes, i) in aggregatedData?.episodes.edges"
      :key="i"
      class="episode"
    >
      <p>{{ episode.node.name }}</p>
    </div>
    <button
      v-if="queryData?.episodes?.pageInfo?.hasNextPage"
      :loading="isLoading"
      @click="fetchNext(5, queryData.episodes.pageInfo.endCursor)"
    >
      Charger plus d'épisodes
    </button>
  </div>
</Query>

Dans cet exemple on pagine les épisodes 5 par 5 et on utilise la variable aggregatedData pour combiner les nouveaux résultats aux anciens et obtenir l'effet d'une liste infinie

Bidirectionnelle

Pour la pagination bidirectionnelle, la méthode est très similaire mais on rajoute l'autre sens donc les variables suivantes:

  • pageInfo.hasPreviousPage
  • pageInfo.startCursor
  • fetchPrevious dans le composant <Query>

Voila un exemple simple d'affichage épisode par épisode :

query ($first: Int, $after: String, $last: Int, $before: String) {
  episodes: allEpisodeEntries(
    first: $first
    last: $last
    after: $after
    before: $before
  ) {
    edges {
      node {
        name
      }
      pageInfo {
        hasPreviousPage
        hasNextPage
        endCursor
        startCursor
      }
      cursor
    }
  }
}

Note: Le nom des variables de query est très important et ne doit pas différer des exemples pour que le composant <Query> puisse les remplir avec les bonnes informations.

<Query :first="1" v-slot="{ queryData, isLoading, fetchNext, fetchPrevious }">
  <h3>Épisode</h3>
  <div class="episode">
    <p v-if="queryData?.episodes.edges.length > 0">
      {{ queryData?.episodes.edges[0].node.name }}
    </p>
    <button
      v-if="queryData?.episodes?.pageInfo?.hasNextPage"
      :loading="isLoading"
      @click="fetchNext(1, queryData.episodes.pageInfo.endCursor)"
    >
      Episode suivant
    </button>
    <button
      v-if="queryData?.episodes?.pageInfo?.hasPreviousPage"
      :loading="isLoading"
      @click="fetchPrevious(1, queryData.episodes.pageInfo.startCursor)"
    >
      Episode précédent
    </button>
  </div>
</Query>

Combiner du contenu de Données avec un modèle de module

Il est également possible d'utiliser le composant <Query> et l'API GraphQL de votre site dans des modèles de module Yapla. Vous pouvez également conditionner l'appel du composant en fonction d'un des paramètres du module. Par exemple pour afficher dans le détail d'un atelier des ressources additionnelles en fonction de la catégorie de l'atelier.

<div class="workshop-detail">
  <Query
    v-slot="{queryData}"
    v-if="workshop?.tags.find(t => t.name === 'Ressources')"
  >
    <div class="resources-link">
      <p v-for="(resource, i) in queryData?.resources.edges" :key="i">
        {{ resource.node.name }}
      </p>
    </div>
  </Query>
</div>

Pour aller plus loin : quelques références

<Query>

Le composant permettant d'exécuter la requête du modèle et en retournant le résultat.

Paramètres

  • first: number : Le nombre de résultat à retourner en commençant par le début. Utilisé dans la requête pour paginer les résultats.
  • last: number : Le nombre de résultat à retourner en commençant par la fin. Utilisé dans la requête pour paginer les résultats.

Variables

Accessibles depuis le scope du slot.

  • queryData: Object : Contient les résultats de la dernière requête GraphQL, formatés en suivant le schéma spécifié dans l'onglet Requête.
  • aggregatedData : Object Contient les résultats combinés de toutes les requêtes GraphQL (les variables edges sont combinées ensemble). Utilisé pour mettre en place une pagination de type liste infinie.
  • isLoading: boolean : Reflète l'état de chargement de la requête actuelle.

Méthodes

  • fetchNext(size: number, cursor: string) : Permet de récupérer le nombre de résultats spécifiés après le cursor.
  • fetchPrevious(size: number, cursor: string) : Permet de récupérer le nombre de résultats spécifiés avant le cursor.

<Button>

Composant utilitaire Yapla pour des boutons utilisant le design de votre site.

Paramètres

  • type?: string<'primary'|'secondary'> : Définit le style du bouton comme primaire ou secondaire. Défaut: 'primary'
  • disabled?: boolean : Permet de désactiver le bouton Défaut: false
  • loading?: boolean : Permet d'afficher un état de chargement sur le bouton et de le désactiver Défaut: false

Événements

  • @click: Appelé lorsque le bouton est cliqué

Documentation connexe

Cet article vous a-t-il été utile ?

Commentaires

0 commentaire

Vous devez vous connecter pour laisser un commentaire.