Il s'agit d'un outil CLI qui extrait les données de Contentful CMS et les transforme en fichiers Markdown ou YAML à utiliser avec un générateur de site statique. Il peut être utilisé avec n'importe quel générateur de site statique qui utilise Markdown avec le frontmatter YAML, mais il possède certaines fonctionnalités spécifiques à Hugo. Il comprend également un simple serveur Express qui peut recevoir des webhooks de Contentful pour redéclencher les commandes d'obtention et de suppression (utile lors de l'exécution d'un environnement de prévisualisation).
Installez Node.js (la version minimale prise en charge est Node v18)
avec NMP
# local install
npm install contentful-hugo
# global install
npm install contentful-hugo -g
avec PNPM
# local install
pnpm install contentful-hugo
# global install
pnpm install contentful-hugo -g
Terminez la configuration puis exécutez la ou les commandes suivantes dans le terminal
# # initialize the directory
contentful - hugo -- init
# # fetch content from contentful
contentful - hugo [ flags ]
npx contentful - hugo -- init
npx contentful - hugo [ flags ]
# or when using pnpm
pnpm contentful - hugo -- init
pnpm contentful - hugo [ flags ]
drapeau | pseudonymes | description |
---|---|---|
--init | Initialisez le répertoire. Génère un fichier de configuration et des codes courts par défaut pour les champs de texte enrichi Contentful | |
--aperçu | -P | Fonctionne en mode aperçu, qui extrait les entrées publiées et non publiées de Contentful |
--attendez | -W | Attendez le nombre de millisecondes spécifié avant d'extraire les données de Contentful. |
--config | -C | Spécifiez le chemin d'accès à un fichier de configuration. |
--serveur | -S | Exécuter en mode serveur pour recevoir les webhooks de Contentful |
--port | Spécifiez le port pour le mode serveur (par défaut 1414) | |
--faire le ménage | Supprimez tous les répertoires spécifiés dans singleTypes et RepeatableTypes | |
--aide | Afficher l'aide | |
--version | Afficher le numéro de version |
contentful - hugo -- wait = 2000 -- preview -- config = " my_custom_config.js "
# or
contentful - hugo -- wait 2000 -- preview -- config my_custom_config.js
{
"name" : " my-hugo-project " ,
"scripts" : {
"dev" : " contentful-hugo --preview && hugo server " ,
"build" : " contentful-hugo && hugo --minify "
}
}
Dans cet exemple, lorsque vous exécutez npm run dev
il utilisera d'abord contentful-hugo pour extraire les données Contentful, puis démarrera le serveur Hugo. De la même manière, lorsque vous exécutez la commande npm run build
il utilisera d'abord contentful-hugo pour extraire les données Contentful, puis exécutera hugo --minify
pour créer une version minifiée de votre site Hugo.
Essayer d'utiliser ce package avant de terminer la configuration renverra une erreur dans la console
Error: There is an error in your config file, or it does ' t exits.
Check your config for errors or run "contentful-hugo --init" to create a config file.
Par défaut, cette bibliothèque recherchera les variables d'environnement suivantes. Vous pouvez également remplacer ces valeurs avec le fichier de configuration. (Voir configuration)
Fichier .env :
Pour déclarer ces variables d'environnement, créez un fichier .env
dans le répertoire racine de votre projet.
CONTENTFUL_SPACE = ' <space-id> '
CONTENTFUL_TOKEN = ' <content-accessToken> '
# optional but required for preview mode
CONTENTFUL_PREVIEW_TOKEN = ' <preview-accessToken> '
Vous pouvez également déclarer les variables d'environnement dans la ligne de commande
PowerShell :
$ env: CONTENTFUL_SPACE = " <contentful_space_id> "
$ env: CONTENTFUL_TOKEN = " <contentful_acessToken> "
$ env: CONTENTFUL_PREVIEW_TOKEN = " <contentful_preview_accessToken> "
Frapper:
export CONTENTFUL_SPACE= " <contentful_space_id> "
export CONTENTFUL_TOKEN= " <contentful_accessToken> "
export CONTENTFUL_PREVIEW_TOKEN= " <contentful_preview_accessToken> "
Avant de commencer, vous devrez créer un fichier de configuration à la racine de votre référentiel. Contentful-hugo recherchera par défaut les fichiers suivants en tant que configuration.
contentful-hugo.config.ts
contentful-hugo.config.js
contentful-hugo.config.yaml
contentful-hugo.yaml
contentful-settings.yaml
Vous pouvez également spécifier un fichier de configuration personnalisé à l'aide de l'indicateur --config
. (Les fichiers de configuration Javascript ou YAML sont les seuls types de fichiers actuellement acceptés)
import { defineConfig } from 'contentful-hugo' ;
export default defineConfig ( {
// fetches from default locale if left blank
locales : [ 'en-US' , 'fr-FR' ] ,
contentful : {
// defaults to CONTENTFUL_SPACE env variable
space : 'space-id' ,
// defaults to CONTENTFUL_TOKEN env variable
token : 'content-deliver-token' ,
// defaults to CONTENTFUL_PREVIEW_TOKEN env variable
previewToken : 'content-preview-token' ,
// defaults to "master"
environment : 'master' ,
} ,
singleTypes : [
{
id : 'homepage' ,
directory : 'content' ,
fileName : '_index' ,
} ,
{
id : 'siteSettings' ,
directory : 'data' ,
fileName : 'settings' ,
fileExtension : 'yaml' , // default is md
} ,
] ,
repeatableTypes : [
{
id : 'posts' ,
directory : 'content/posts' ,
mainContent : 'content' ,
resolveEntries : {
categories : 'fields.slug' ,
author : 'fields.name' ,
relatedPosts : 'sys.id' ,
} ,
} ,
{
id : 'seoFields' ,
isHeadless : true ,
directory : 'content/seo-fields' ,
customFields : {
// these fields will be added to the frontmatter
myCustomField : 'myCustomFieldVal' ,
myOtherCustomField : ( entry ) => {
return entry . fields . whatever ;
} ,
} ,
} ,
{
id : 'reviews' ,
directory : 'content/reviews' ,
mainContent : 'reviewBody' ,
} ,
{
id : 'category' ,
directory : 'content/categories' ,
isTaxonomy : true ,
} ,
] ,
staticContent : [
{
inputDir : 'static_content' ,
outputDir : 'content' ,
} ,
] ,
} ) ;
Une configuration javascript est à peu près la même qu’une configuration dactylographiée.
import { defineConfig } from 'contentful-hugo' ;
export default defineConfig ( {
// stuff goes here
} ) ;
La syntaxe CommonJS devrait également fonctionner (je ne teste pas réellement cela, peut-être que cela fonctionne, peut-être que ce n'est pas le cas)
const { defineConfig } = require ( 'contentful-hugo' ) ;
module . exports = defineConfig ( {
// stuff goes here
} ) ;
# contentful-hugo.config.yaml
locales : # fetches from default locale if left blank
- en-US
- fr-FR
contentful :
space : ' space-id ' # defaults to CONTENTFUL_SPACE env variable
token : ' content-deliver-token ' # defaults to CONTENTFUL_TOKEN env variable
previewToken : ' content-preview-token ' # defaults to CONTENTFUL_PREVIEW_TOKEN env variable
environment : ' master ' # defaults to "master"
singleTypes :
# fetches only the most recently updated entry in a particular content type
# Generated file will be named after the fileName setting
- id : homepage
directory : content
fileName : _index
- id : siteSettings
directory : data
fileName : settings
fileExtension : yaml # default is md
repeatableTypes :
# fetches all the entries of a content type and places them in a directory.
# Generated files will be named after their Entry ID in Contentful.
- id : posts
directory : content/posts
fileExtension : md
mainContent : content
resolveEntries : # resolves a reference or asset field to a specific property
categories : fields.slug
author : fields.name
relatedPosts : sys.id
- id : seoFields
isHeadless : true
directory : content/seo-fields
customFields :
# will be added to the frontmatter
myCustomFields : ' myCustomFieldValue '
- id : reviews
directory : content/reviews
mainContent : reviewBody
- id : staff
isHeadless : true
directory : content/staff
- id : category
directory : content/categories
isTaxonomy : true
champ | requis | description |
---|---|---|
espace | facultatif | ID Contentful Space (par défaut, la variable d'environnement CONTENTFUL_SPACE si elle n'est pas définie) |
jeton | facultatif | Jeton de livraison de contenu (par défaut, la variable d'environnement CONTENTFUL_TOKEN si elle n'est pas définie) |
aperçuToken | facultatif | Jeton d'aperçu du contenu (par défaut, la variable d'environnement CONTENTFUL_PREVIEW_TOKEN si elle n'est pas définie) |
environnement | facultatif | ID d'environnement de contenu (par défaut, "maître" s'il n'est pas défini) |
champ | requis | description |
---|---|---|
identifiant | requis | Identifiant du type de contenu |
annuaire | requis | Répertoire dans lequel vous souhaitez que le(s) fichier(s) soient générés |
nom de fichier | requis | Nom du fichier généré |
Extension de fichier | facultatif | Peut être "md", "yml", "yaml" ou "json" (par défaut "md") |
contenu principal | facultatif | ID de champ pour le champ dont vous souhaitez qu'il soit le contenu principal de Markdown. (Peut être un champ de démarque, de texte enrichi ou de chaîne) |
taper | facultatif | Définir manuellement la valeur du champ "type" dans le frontmatter (voir la documentation Hugo) |
résoudre les entrées | facultatif | Résoudre les champs de référence et/ou les champs d'actif spécifiés en l'un de ses paramètres de propriétés |
remplacements | facultatif | Effectuer des remplacements personnalisés pour les valeurs ou les noms de champs |
filtres | facultatif | Accepte un objet de paramètres de recherche Contentful pour filtrer les résultats. Voir les documents de contenu |
ignorer les paramètres locaux | facultatif | Ignorer les paramètres de localisation et extraire uniquement les paramètres régionaux par défaut (la valeur par défaut est false) |
champs personnalisés | facultatif | Accepte un objet de champs et de valeurs. Les valeurs peuvent être une valeur statique standard ou une fonction qui accepte l'entrée Contentful comme paramètre et renvoie une valeur |
champ | requis | description |
---|---|---|
identifiant | requis | Identifiant du type de contenu |
annuaire | requis | Répertoire où vous souhaitez que les fichiers soient générés |
nom de fichier | facultatif | Propriété d'entrée qui indiquera le nom du fichier. (Par défaut, ce sera sys.id ) |
Extension de fichier | facultatif | Peut être "md", "yml", "yaml" ou "json" (par défaut "md") |
est sans tête | facultatif | Transforme toutes les entrées d'un type de contenu en paquets de feuilles sans tête (voir la documentation Hugo). Ne peut pas être défini sur true lorsque isTaxonomy est défini sur true. |
isTaxonomie (expérimental) | facultatif | Organisez les entrées dans une structure de fichiers permettant des métadonnées de taxonomie personnalisées (voir la documentation Hugo). Ne peut pas être défini sur true lorsque isHeadless est défini sur true. |
contenu principal | facultatif | ID de champ pour le champ dont vous souhaitez qu'il soit le contenu principal de la démarque. (Peut être un champ de démarque, de texte enrichi ou de chaîne) |
taper | facultatif | Définir manuellement la valeur du champ "type" dans le frontmatter (voir la documentation Hugo) |
résoudre les entrées | facultatif | Résoudre les champs de référence et/ou les champs d'actifs spécifiés dans l'une de leurs propriétés |
remplacements | facultatif | Effectuer des remplacements personnalisés pour les valeurs ou les noms de champs |
filtres | facultatif | Accepte un objet de paramètres de recherche Contentful pour filtrer les résultats. Voir les documents de contenu |
ignorer les paramètres locaux | facultatif | Ignorer les paramètres de localisation et extraire uniquement les paramètres régionaux par défaut (la valeur par défaut est false) |
champs personnalisés | facultatif | Accepte un objet de champs et de valeurs. Les valeurs peuvent être une valeur statique standard ou une fonction qui accepte l'entrée Contentful comme paramètre et renvoie une valeur |
La configuration comporte également un champ locales
qui vous permet de spécifier les paramètres régionaux à partir desquels vous souhaitez extraire. Ce champ peut prendre un tableau de chaînes, un tableau d'objets ou une combinaison.
Par défaut, les extensions de fichiers spécifiques aux paramètres régionaux seront utilisées pour plusieurs traductions.
const { defineConfig } = require ( 'contentful-hugo' ) ;
// produce en-us.md and fr-fr.md files
module . exports = defineConfig ( {
locales : [ 'en-US' , 'fr-FR' ] ;
// rest of config
} )
// produce en.md and fr.md files
module . exports = defineConfig ( {
locales : [
{
code : 'en-US' ,
mapTo : 'en'
} ,
{
code : 'fr-FR' ,
mapTo : 'fr'
}
]
// rest of config
} )
// produce en-us.md files and fr.md files
module . exports = defineConfig ( {
locales : [
'en-US' ,
{
code : 'fr-FR' ,
mapTo : 'fr'
}
]
// rest of config
} )
Après avoir configuré les paramètres régionaux dans Contentful Hugo, vous devrez mettre à jour votre configuration Hugo pour tenir compte de ces paramètres régionaux. Consultez la documentation Hugo pour plus de détails.
# config.toml
[ languages ]
[ languages . en-us ]
# language settings
[ languages . fr-fr ]
# language settings
Il arrive parfois que vous souhaitiez placer le contenu dans un répertoire en fonction de ses paramètres régionaux plutôt que d'utiliser une traduction basée sur une extension de fichier. Pour ce faire, incluez simplement [locale]
dans le chemin du fichier de votre répertoire.
Lors de l'utilisation de répertoires spécifiques aux paramètres régionaux, les extensions de fichiers spécifiques aux paramètres régionaux (c'est-à-dire en.md
ou fr.md
) sont supprimées.
const { defineConfig } = require ( 'contentful-hugo' ) ;
module . exports = defineConfig ( {
locales : [ 'en' , 'fr' ]
singleTypes : [
{
id : 'settings' ,
fileName : 'settings' ,
fileExtension : 'yaml' ,
directory : 'data/[locale]'
/*
produces:
- data/en/settings.yaml
- data/fr/settings.yaml
*/
}
]
repeatableTypes : [
{
id : 'post' ,
directory : 'content/[locale]/post' ,
/*
produces:
- content/en/post/[entryId].md
- content/fr/post/[entryId].md
*/
} ,
] ,
} ) ;
La configuration recommandée pour Contentful Hugo consiste à ignorer vos répertoires de contenu (généralement ./content
) et de données (généralement ./data
) dans le contrôle de version. En effet, contentful-hugo générera ces répertoires au moment de la construction. Cependant, cela crée des problèmes dans les cas où vous avez des pages qui ne sont pas gérées dans Contentful et qui ne sont pas générées au moment de la construction par une autre source.
Pour résoudre ce problème, Contentful-Hugo dispose d'un paramètre staticContent
. Ce paramètre accepte un répertoire d'entrée ( inputDir
) qui peut être validé dans git, et un répertoire de sortie ( outputDir
) qui serait votre contenu standard ou votre répertoire de données. Tous les éléments de inputDir seront copiés dans OutputDir au moment de la construction et conserveront leur structure de dossiers.abs
Par exemple, dans la configuration ci-dessous, ./static_content/posts/my-post.md
sera copié dans ./content/posts/my-post.md
et ./static_data/global-settings.yaml
sera copié dans ./data/global-settings.yaml
.
const { defineConfig } = require ( 'contentful-hugo' ) ;
module . exports = defineConfig ( {
// rest of config
staticContent : [
{
// all items in ./static_content will be copied to ./content
inputDir : 'static_content' ,
outputDir : 'content' ,
} ,
{
// all items in ./static_data will be copied to ./data
inputDir : 'static_data' ,
outputDir : 'data' ,
} ,
] ,
} ) ;
Contentful-Hugo surveillera également les modifications de fichiers dans inputDir lors de l'exécution en mode serveur.
Voici un exemple de modification dynamique des options token
, previewToken
et environment
en fonction de toute condition arbitraire.
// contentful-hugo.config.js
const { defineConfig } = require ( 'contentful-hugo' ) ;
require ( 'dotenv' ) . config ( ) ; // assuming you have "dotenv" in your dependencies
const myMasterToken = process . env . CONTENTFUL_MASTER_TOKEN ;
const myMasterPreviewToken = process . env . CONTENTFUL_MASTER_PREVIEW_TOKEN ;
const myStagingToken = process . env . CONTENTFUL_STAGING_TOKEN ;
const myStagingPreviewToken = process . env . CONTENTFUL_STAGING_PREVIEW_TOKEN ;
// set some condition
const isStaging = true || false ;
module . exports = defineConfig ( {
contentful : {
space : 'my-space-id' ,
token : isStaging ? myStagingToken : myMasterToken ,
preview : isStaging ? myStagingPreviewToken : myMasterPreviewToken ,
environment : isStaging ? 'staging' : 'master' ,
} ,
// rest of config
} ) ;
const { defineConfig } = require ( 'contentful-hugo' ) ;
// contentful-hugo.config.js
module . exports = defineConfig ( {
repeatableTypes : [
{
id : "trips" ,
directory : "content/trips"
overrides : {
// change the url field name to "slug"
url : {
fieldName : "slug"
}
/*
rename "distanceInKilometers" to "distanceInMiles"
and change the field value from km to mi
*/
distanceInKilometers : {
fieldName : "distanceInMiles" , valueTransformer : ( val ) => {
if ( typeof val === 'number' ) {
return val * 0.621371
}
return 0
}
}
}
}
]
} )
// ALTERNATIVE SYNTAX
module . exports = defineConfig ( {
repeatableTypes : [
{
id : "trips" ,
directory : "content/trips"
overrides : [
{
field : "url" ,
options : {
// change the url field name to "slug" in frontmatter
fieldName : "slug"
}
} ,
{
field : "distanceInKilometers" ,
options : {
// rename "distanceInKilometers" to "distanceInMiles"
fieldName : "distanceInMiles" ,
// convert distance to miles and output the result in frontmatter
valueTransformer : ( val ) => {
if ( typeof val === 'number' ) {
return val * 0.621371
}
return 0
}
}
} ]
}
]
} )
Pour les fichiers de configuration JS, vous pouvez utiliser l'assistant defineConfig
ou importer le type ContentfulHugoConfig
.
//////////// OPTION 1 ////////////
const { defineConfig } = require ( 'contentful-hugo' ) ;
module . exports = defineConfig ( {
// config goes here
} ) ;
//////////// OPTION 2 ////////////
/**
* @type {import('contentful-hugo').ContentfulHugoConfig}
*/
module . exports = {
// rest of config
} ;
Exemple de configuration .gitignore
# general stuff
.env
node_modules
public
resources
# Contenful Hugo stuff
# temp folder that contentful uses to track files
.contentful-hugo
# since content and data is coming from Contentful
# usually you'll want to ignore those directories
content
data
Les fichiers seront générés dans le répertoire spécifié dans le fichier de configuration. Les documents préliminaires seront au format YAML. Les fichiers de types uniques seront nommés d'après le nom de fichier spécifié dans le fichier de configuration. Les fichiers de types répétables seront nommés d'après leur ID d'entrée dans Contenful, ce qui facilite la liaison des fichiers entre eux.
Les champs suivants apparaîtront toujours dans votre frontmatter :
date : # defaults to sys.createdAt unless you have a field with the id "date" then it get's overwritten
sys :
id : # the entry id
updatedAt : # the last time this entry was updated in Contentful
createdAt : # when the entry was created in Contentful
revision : # the revision number
space : # the space id
contentType : # the content type id
Les ressources telles que les images et les vidéos sont accompagnées d'informations supplémentaires qui facilitent la mise en œuvre d'éléments tels que du texte alternatif ou des mises en page qui reposent sur la connaissance des dimensions de l'image. Les champs sont les suivants :
assetFieldName :
assetType : # indicates the asset mime type such as image/png, video/mp4, audio/mp3, ect.
url : # url of the asset
title : # title of the asset written in Contentful
description : # description of the asset written in Contentful
width : # width of the asset (images only)
height : # height of the asset (images only)
Si vous utilisez Hugo, vous pouvez accéder aux informations comme ci-dessous :
< img
src =" {{ .Params.assetFieldName.url }} "
width =" {{ .Params.assetFieldName.width }} "
/>
Pour les images, vous pouvez ajouter des paramètres à l'URL de l'actif afin d'utiliser l'API d'images de Contentful.
< img
src =" {{ .Params.assetFieldname.url }}?w=200&h=200&fit=fill "
width =" 200 "
height =" 200 "
/>
Ces mêmes informations apparaîtront également dans des tableaux d'actifs comme une galerie :
myGallery :
- assetType : ' image/jpg '
url : ' //link-to-image.jpg '
title : ' Image 1 '
description : ' Image 1 Description '
width : 500
height : 500
- assetType : ' image/jpg '
url : ' //link-to-image-2.jpg '
title : ' Image 2 '
description : ' Image 2 Description '
width : 1920
height : 1080
Les entrées liées incluront des champs pour son identifiant et son identifiant de type de contenu.
linkedEntry :
id : <contentful-entry-id>
typeId : <content-type-ID>
# example with array of linked entries
relatedArticles :
- id : ' 41UFfIhszbS1kh95bomMj7 '
typeId : ' articles '
- id : ' 85UFfIhsacS1kh71bpqMj7 '
typeId : ' articles '
Tous les fichiers sont nommés d'après leur identifiant d'entrée dans Contentful, ce qui facilite leur récupération à l'aide de .Site.GetPage
dans Hugo
// if you have access to the "Page" object
{{ with . Site . GetPage "<path-to-file>/<entry-id>" }}
{{ . Title }}
{{ end }}
// if you don't have access to the "Page" object
// for example in a nested partial
{{ with site. GetPage "<path-to-file>/<entry-id>" }}
{{ . Title }}
{{ end }}
Exemple simple
{{ with . Params . myEntryField }}
{{ $ pagePage := print "path/to/entryDir/" . id }}
{{ with site. GetPage $ pagePath }}
{{ . Title }}
{{ . Params . someOtherField }}
{{ end }}
{{ end }}
Documents pertinents :
Un champ de texte enrichi défini comme « mainContent » pour un type de contenu sera rendu sous forme de démarque pour Hugo.
Le contenu dynamique tel que embedded-entry-blocks
est rendu sous forme de codes courts avec des paramètres inclus qui peuvent être utilisés pour récupérer les données nécessaires.
<!-- example embedded entry -->
<!-- you can use the id, contentType, and parentContentType parameters to fetch the desired data -->
{{< contentful-hugo/embedded-entry id="nTLo2ffSJJp5QrnrO5IU9" contentType="gallery" parentContentType="post" >}}
Avant de récupérer des données de texte enrichi, assurez-vous d'avoir exécuté contentful-hugo --init
afin d'avoir tous les codes courts de texte enrichi. Une fois que vous disposez de ces shortcodes, vous pouvez les étendre et les modifier en fonction de vos besoins.
La liste des codes courts de texte enrichi comprend :
Par défaut, les codes courts Richtext afficheront une notification pour un élément non configuré.
Vous pouvez les personnaliser en accédant à layouts/shortcodes/contentful-hugo/{shortcode-name}.html
Un champ de texte enrichi produira des tableaux imbriqués reflétant la structure JSON qu'ils ont dans l'API. Chaque nœud devra être parcouru en boucle et produire du HTML en fonction du champ nodeType.
richTextField :
- nodeType : ' paragraph '
data : {}
content :
- data : {}
marks : []
value : ' This is a simple paragraph. '
nodeType : ' text '
- nodeType : ' paragraph '
data : {}
content :
- data : {}
marks : []
value : ' This is a paragraph with '
nodeType : ' text '
- data : {}
marks :
- type : ' italic '
value : ' italicized text. '
nodeType : ' text '
- nodeType : ' embedded-asset-block '
data :
assetType : ' image/jpeg '
url : ' //images.ctfassets.net/some-image-url.jpg '
title : ' Image title will appear here '
description : ' Image description will appear here '
width : 1920
height : 1080
content : []
De plus, une version en texte brut du champ sera générée en utilisant l'ID de champ suivi de "_plaintext". Cela vous permet de récupérer rapidement le texte lui-même sans aucune autre donnée. Un cas d'utilisation simple consisterait à utiliser la sortie en texte brut pour générer automatiquement une méta description pour une page Web.
richTextField_plaintext : ' This is a simple paragraph. This is a paragraph with italicized text. '
L'option de résolution des entrées vous permet de spécifier une propriété à partir d'une entrée ou d'un actif référencé pour résoudre cette valeur de champ. Par exemple, supposons que vous ayez un type de contenu category
référencé dans posts
. Normalement, contentful-hugo donnera le résultat suivant
category :
id : some-entry-id
contentType : category
Bien que cela facilite la recherche de la catégorie, ce format ne vous permet pas d'utiliser les fonctionnalités de taxonomie intégrées à Hugo. Avec le paramètre resolveEntries
vous pouvez remédier à ce problème.
// from the config file
module . exports = defineConfig ( {
repeatableTypes : [
id : 'posts' ,
directory : 'content/posts' ,
resolveEntries : {
category : 'fields.slug'
}
// alternative syntax
resolveEntries : [
{
field : 'category' ,
resolveTo : 'fields.slug' ,
} ,
] ,
]
} )
Désormais, le champ de catégorie affichera uniquement le slug comme valeur.
category : my-category-slug
La fonctionnalité de résolution des entrées fonctionne à la fois avec les champs de référence et les champs d'actif, ainsi qu'avec plusieurs champs de référence et plusieurs champs d'actif.
Les remplacements peuvent être utilisés pour modifier les noms et les valeurs des champs.
Voici un exemple simple de modification d'un nom de champ de "url" à "videoUrl".
repeatableTypes: [
{
id : 'youtubeVideo' ,
directory : 'content/_youtubeVideo' ,
isHeadless : true ,
overrides : {
// the name of the url field to videoUrl
url : {
fieldName : 'videoUrl'
}
}
// alternative syntax
overrides : [
{
field : 'url' ,
options : {
fieldName : 'videoUrl' ,
} ,
} ,
] ,
} ,
] ;
overrides
a également une option valueTransformer
qui vous permet de manipuler les données de champ qui apparaîtront dans le frontmatter. valueTransformer
prend une méthode qui a la valeur du champ comme paramètre, puis renvoie le résultat final qui apparaîtra dans le frontmatter. (Sachez que puisque valueTransformer
doit être une méthode, cette option ne fonctionnera que dans les fichiers de configuration javascript)
Voici un exemple où nous changeons le nom du champ de "url" à "videoId", puis nous utilisons le valueTransformer
pour extraire l'identifiant de la vidéo de l'URL, puis le plaçons dans le frontmatter.
repeatableTypes: [
{
id : 'youtubeVideo' ,
directory : 'content/_youtubeVideo' ,
isHeadless : true ,
overrides : {
url : {
fieldName : 'videoId' ,
// "value" is whatever value is currently saved in the field.
// in this case it's a url for a youtube video
valueTransformer : ( value ) => {
if ( ! value ) {
return null ;
}
const url = new URL ( value ) ;
// extract the video id from the url and return it
return url . searchParams . get ( 'v' ) ;
}
}
}
// alternative syntax
overrides : [
{
field : 'url' ,
options : {
fieldName : 'videoId' ,
valueTransformer : ( value ) => {
// transform the value
} ,
} ,
} ,
] ,
} ,
] ;
Lorsque vous utilisez l'option valueTransformer
sur des champs contenant des tableaux, assurez-vous de parcourir la valeur lors de sa manipulation.
repeatabledTypes: [
{
id : 'post' ,
directory : 'content/posts' ,
overrides : {
authors : {
valueTransformer : ( authorRefs ) => {
const authors = [ ] ;
for ( const ref of authorRefs ) {
// get the name, photo, and bio of the author
// and add it to the array
authors . push ( {
name : ref . fields . name ,
photo : ref . fields . photo . fields . file . url ,
bio : ref . fields . bio ,
} ) ;
}
return authors ;
} ,
} ,
} ,
} ,
] ;
Maintenant, le champ authors
ressemblera à ceci :
authors :
- name : Some Name
photo : //images.cfassets.net/path-to-photo.jpg
bio : some bio text
- name : Some other name
photo : //images.cfassets.net/path-to-photo.jpg
bio : some other bio text
Comme vous pouvez le voir, cela peut être utilisé pour produire des résultats similaires au paramètre resolveEntries
, mais resolveEntries
ne peut renvoyer qu'une seule propriété tandis qu'avec les remplacements, vous pouvez faire ce que vous voulez avec les valeurs du champ.
Vous pouvez utiliser l'option filters
pour saisir des paramètres de recherche vous permettant de filtrer les entrées en fonction de certaines de leurs propriétés. Pour plus d'informations sur les paramètres de recherche Contentful, visitez leurs documents.
Sachez que les paramètres de recherche suivants seront ignorés content_type
, skip
, order
, limit
module . exports = defineConfig ( {
singleTypes : [
// get a homepage with a specific entryId
{
id : 'homepage' ,
directory : 'content' ,
fileName : '_index' ,
filters : {
'sys.id' : 'my-homepace-id'
}
}
]
repeatableTypes : [
// only get events that start after 01/01/2020
{
id : 'events' ,
directory : 'content/events' ,
filters : {
'fields.startDate[gte]' : '2020-01-01T00:00:00Z' ,
} ,
} ,
// get posts where author is "John Doe" and contains the tag "flowers"
{
id : 'posts' ,
directory : 'content/posts' ,
filters : {
'fields.author' : 'John Doe' ,
'fields.tags' : 'flowers'
} ,
} ,
] ;
} )
Vous pouvez utiliser le paramètre customFields
pour ajouter des champs supplémentaires à vos entrées. La configuration des champs personnalisés peut être une valeur statique ou une méthode qui accepte une entrée Contentful comme paramètre et renvoie une valeur.
Disons que nous avons un type de contenu auteur avec les champs suivants :
Voici un exemple de configuration :
module . exports = defineConfig ( {
// rest of config
repeatableTypes : [
{
id : 'author' ,
directory : 'content/authors' ,
customFields : {
// both "myCustomField" and "fullName"
// will be appended to the frontmatter for author entries
myCustomField : 'myCustomFieldValue' ,
fullName : ( entry ) => {
const { firstName , lastName } = entry . fields ;
return ` ${ firstName } ${ lastName } ` ;
} ,
} ,
} ,
] ,
} ) ;
Voici à quoi aboutira cette configuration
---
firstName : ' John '
lastName : ' Doe '
slug : ' john-doe '
myCustomField : ' myCustomFieldValue ' # custom field
fullName : ' John Doe ' # custom field
---
Vous pouvez également l'utiliser pour les champs spécifiques à Hugo comme les options de construction.
// prevent a content type from appearing in list pages
{
customFields : {
_build : {
render : 'alway' ,
list : 'never' ,
publishResources : true
}
}
}
// prevent a content type from rendering a single page
{
customFields : {
_build : {
render : 'never' ,
list : 'always' ,
publishResources : true
}
}
}
Ce sont quelques problèmes connus.
--wait
à votre script. Voici un exemple où nous attendons 6 secondes supplémentaires contentful-hugo --wait=6000
.hugo server --disableFastRender