Dies ist ein CLI-Tool, das Daten aus Contentful CMS abruft und sie in Markdown- oder YAML-Dateien zur Verwendung mit einem statischen Site-Generator umwandelt. Es kann mit jedem statischen Site-Generator verwendet werden, der Markdown mit YAML-Frontmatter verwendet, verfügt jedoch über einige Funktionen, die speziell für Hugo gelten. Es enthält außerdem einen einfachen Express-Server, der Webhooks von Contentful empfangen kann, um Abruf- und Löschbefehle erneut auszulösen (nützlich beim Ausführen einer Vorschauumgebung).
Installieren Sie Node.js (mindestens unterstützte Version ist Node v18)
mit NPM
# local install
npm install contentful-hugo
# global install
npm install contentful-hugo -g
mit PNPM
# local install
pnpm install contentful-hugo
# global install
pnpm install contentful-hugo -g
Schließen Sie die Konfiguration ab und führen Sie dann die folgenden Befehle im Terminal aus
# # 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 ]
Flagge | Aliase | Beschreibung |
---|---|---|
--init | Initialisieren Sie das Verzeichnis. Erzeugt eine Konfigurationsdatei und Standard-Shortcodes für Contentful-Rich-Text-Felder | |
--Vorschau | -P | Wird im Vorschaumodus ausgeführt, der sowohl veröffentlichte als auch unveröffentlichte Einträge von Contentful abruft |
--Warten | -W | Warten Sie die angegebene Anzahl von Millisekunden, bevor Sie Daten aus Contentful abrufen. |
--config | -C | Geben Sie den Pfad zu einer Konfigurationsdatei an. |
--Server | -S | Im Servermodus ausführen, um Webhooks von Contentful zu empfangen |
--Hafen | Geben Sie den Port für den Servermodus an (Standard 1414) | |
--sauber | Löschen Sie alle in „singleTypes“ und „repeatableTypes“ angegebenen Verzeichnisse | |
--helfen | Hilfe anzeigen | |
--Version | Versionsnummer anzeigen |
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 "
}
}
Wenn Sie in diesem Beispiel npm run dev
ausführen, wird zuerst contentful-hugo verwendet, um Contentful-Daten abzurufen, und dann wird der Hugo-Server gestartet. Wenn Sie den Befehl npm run build
ausführen, wird auf die gleiche Weise zunächst „contentful-hugo“ verwendet, um Contentful-Daten abzurufen, und dann hugo --minify
ausgeführt, um eine minimierte Version Ihrer Hugo-Site zu erstellen.
Wenn Sie versuchen, dieses Paket vor Abschluss der Konfiguration zu verwenden, wird in der Konsole ein Fehler zurückgegeben
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.
Standardmäßig sucht diese Bibliothek nach den folgenden Umgebungsvariablen. Sie können diese Werte auch mit der Konfigurationsdatei überschreiben. (Siehe Konfiguration)
.env-Datei:
Um diese Umgebungsvariablen zu deklarieren, erstellen Sie eine .env
Datei im Stammverzeichnis Ihres Projekts.
CONTENTFUL_SPACE = ' <space-id> '
CONTENTFUL_TOKEN = ' <content-accessToken> '
# optional but required for preview mode
CONTENTFUL_PREVIEW_TOKEN = ' <preview-accessToken> '
Sie können die Umgebungsvariablen auch in der Befehlszeile deklarieren
Powershell:
$ env: CONTENTFUL_SPACE = " <contentful_space_id> "
$ env: CONTENTFUL_TOKEN = " <contentful_acessToken> "
$ env: CONTENTFUL_PREVIEW_TOKEN = " <contentful_preview_accessToken> "
Bash:
export CONTENTFUL_SPACE= " <contentful_space_id> "
export CONTENTFUL_TOKEN= " <contentful_accessToken> "
export CONTENTFUL_PREVIEW_TOKEN= " <contentful_preview_accessToken> "
Bevor Sie beginnen, müssen Sie eine Konfigurationsdatei im Stammverzeichnis Ihres Repositorys erstellen. Contentful-Hugo sucht standardmäßig nach den folgenden Dateien als Konfiguration.
contentful-hugo.config.ts
contentful-hugo.config.js
contentful-hugo.config.yaml
contentful-hugo.yaml
contentful-settings.yaml
Sie können auch eine benutzerdefinierte Konfigurationsdatei mit dem Flag --config
angeben. (Javascript- oder YAML-Konfigurationsdateien sind die einzigen derzeit akzeptierten Dateitypen)
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' ,
} ,
] ,
} ) ;
Eine Javascript-Konfiguration ist so ziemlich die gleiche wie eine Typescript-Konfiguration.
import { defineConfig } from 'contentful-hugo' ;
export default defineConfig ( {
// stuff goes here
} ) ;
Die CommonJS-Syntax sollte auch funktionieren (ich teste nicht wirklich dagegen, vielleicht funktioniert es, vielleicht auch nicht).
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
Feld | erforderlich | Beschreibung |
---|---|---|
Raum | optional | Contentful Space-ID (Standardmäßig wird die Umgebungsvariable CONTENTFUL_SPACE verwendet, wenn sie nicht festgelegt ist) |
Token | optional | Inhaltsbereitstellungs-Token (Standardmäßig wird die Umgebungsvariable CONTENTFUL_TOKEN verwendet, wenn sie nicht festgelegt ist) |
VorschauToken | optional | Inhaltsvorschau-Token (Standardmäßig wird die Umgebungsvariable CONTENTFUL_PREVIEW_TOKEN verwendet, wenn sie nicht festgelegt ist) |
Umfeld | optional | Inhaltsumgebungs-ID (Standardmäßig „Master“, wenn nicht festgelegt) |
Feld | erforderlich | Beschreibung |
---|---|---|
Ausweis | erforderlich | Contentful-Inhaltstyp-ID |
Verzeichnis | erforderlich | Verzeichnis, in dem die Datei(en) generiert werden sollen |
Dateiname | erforderlich | Name der generierten Datei |
Dateierweiterung | optional | Kann „md“, „yml“, „yaml“ oder „json“ sein (standardmäßig „md“) |
Hauptinhalt | optional | Feld-ID für das Feld, das der Haupt-Markdown-Inhalt sein soll. (Kann ein Markdown-, Richtext- oder String-Feld sein) |
Typ | optional | Legen Sie den Wert für das Feld „Typ“ im Frontmatter manuell fest (siehe Hugo-Dokumente). |
auflösenEinträge | optional | Lösen Sie die angegebenen Referenzfelder und/oder Asset-Felder in einen ihrer Eigenschaftenparameter auf |
überschreibt | optional | Führen Sie benutzerdefinierte Überschreibungen für Feldwerte oder Feldnamen durch |
Filter | optional | Akzeptiert ein Objekt mit Contentful-Suchparametern, um Ergebnisse zu filtern. Siehe Contentful-Dokumente |
ignorierenLocales | optional | Lokalisierungseinstellungen ignorieren und nur vom Standardgebietsschema abrufen (Standardwert ist „false“). |
benutzerdefinierteFelder | optional | Akzeptiert ein Objekt mit Feldern und Werten. Die Werte können ein standardmäßiger statischer Wert oder eine Funktion sein, die den Contentful-Eintrag als Parameter akzeptiert und einen Wert zurückgibt |
Feld | erforderlich | Beschreibung |
---|---|---|
Ausweis | erforderlich | Contentful-Inhaltstyp-ID |
Verzeichnis | erforderlich | Verzeichnis, in dem die Dateien generiert werden sollen |
Dateiname | optional | Eintragseigenschaft, die den Dateinamen angibt. (Standardmäßig ist dies sys.id ) |
Dateierweiterung | optional | Kann „md“, „yml“, „yaml“ oder „json“ sein (standardmäßig „md“) |
istHeadless | optional | Wandelt alle Einträge in einem Inhaltstyp in Headless-Blatt-Bündel um (siehe Hugo-Dokumente). Kann nicht auf „true“ gesetzt werden, wenn isTaxonomy auf „true“ gesetzt ist. |
isTaxonomy (experimentell) | optional | Organisieren Sie Einträge in der Dateistruktur und ermöglichen Sie benutzerdefinierte Taxonomie-Metadaten (siehe Hugo-Dokumente). Kann nicht auf true gesetzt werden, wenn isHeadless auf true gesetzt ist. |
Hauptinhalt | optional | Feld-ID für das Feld, das der Haupt-Markdown-Inhalt sein soll. (Kann ein Markdown-, Richtext- oder String-Feld sein) |
Typ | optional | Legen Sie den Wert für das Feld „Typ“ im Frontmatter manuell fest (siehe Hugo-Dokumente). |
auflösenEinträge | optional | Lösen Sie die angegebenen Referenzfelder und/oder Asset-Felder in eine ihrer Eigenschaften auf |
überschreibt | optional | Führen Sie benutzerdefinierte Überschreibungen für Feldwerte oder Feldnamen durch |
Filter | optional | Akzeptiert ein Objekt mit Contentful-Suchparametern, um Ergebnisse zu filtern. Siehe Contentful-Dokumente |
ignorierenLocales | optional | Lokalisierungseinstellungen ignorieren und nur vom Standardgebietsschema abrufen (Standardwert ist „false“). |
benutzerdefinierteFelder | optional | Akzeptiert ein Objekt mit Feldern und Werten. Die Werte können ein standardmäßiger statischer Wert oder eine Funktion sein, die den Contentful-Eintrag als Parameter akzeptiert und einen Wert zurückgibt |
Die Konfiguration verfügt außerdem über ein locales
-Feld, mit dem Sie angeben können, aus welchen Gebietsschemas Sie ziehen möchten. Dieses Feld kann ein Array von Zeichenfolgen, ein Array von Objekten oder eine Kombination davon annehmen.
Standardmäßig werden für mehrere Übersetzungen länderspezifische Dateierweiterungen verwendet.
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
} )
Nachdem Sie Gebietsschemas in Contentful Hugo konfiguriert haben, müssen Sie Ihre Hugo-Konfiguration aktualisieren, um diese Gebietsschemas zu berücksichtigen. Weitere Informationen finden Sie in den Hugo-Dokumenten.
# config.toml
[ languages ]
[ languages . en-us ]
# language settings
[ languages . fr-fr ]
# language settings
Es gibt manchmal Fälle, in denen Sie Inhalte basierend auf ihrem Gebietsschema in einem Verzeichnis platzieren möchten, anstatt eine auf Dateierweiterungen basierende Übersetzung zu verwenden. Dazu fügen Sie einfach [locale]
in den Dateipfad Ihres Verzeichnisses ein.
Bei der Verwendung von gebietsschemaspezifischen Verzeichnissen werden die gebietsschemaspezifischen Dateierweiterungen (z. B. en.md
oder fr.md
) gelöscht
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
*/
} ,
] ,
} ) ;
Das empfohlene Setup für Contentful Hugo besteht darin, dass Ihre Inhaltsverzeichnisse (normalerweise ./content
) und Datenverzeichnisse (normalerweise ./data
) in der Versionskontrolle ignoriert werden. Dies liegt daran, dass contentful-hugo diese Verzeichnisse zur Erstellungszeit generiert. Dies führt jedoch zu Problemen, wenn Sie über Seiten verfügen, die nicht in Contentful verwaltet werden und zum Zeitpunkt der Erstellung nicht von einer anderen Quelle generiert werden.
Um dieses Problem zu lösen, verfügt Contentful-Hugo über einen staticContent
Parameter. Dieser Parameter akzeptiert ein Eingabeverzeichnis ( inputDir
), das an Git übergeben werden kann, und ein Ausgabeverzeichnis ( outputDir
), das Ihr Standardinhalts- oder Datenverzeichnis wäre. Alle Elemente im Eingabeverzeichnis werden zur Erstellungszeit in das Ausgabeverzeichnis kopiert und behalten ihre Ordnerstruktur bei.abs
In der folgenden Konfiguration wird beispielsweise ./static_content/posts/my-post.md
nach ./content/posts/my-post.md
und ./static_data/global-settings.yaml
nach ./data/global-settings.yaml
kopiert ./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 achtet auch auf Dateiänderungen in den Eingabeverzeichnissen, während es im Servermodus ausgeführt wird.
Hier ist ein Beispiel für die dynamische Änderung der Optionen token
, previewToken
und environment
abhängig von einer beliebigen Bedingung.
// 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
}
}
} ]
}
]
} )
Für JS-Konfigurationsdateien können Sie den defineConfig
Helfer verwenden oder den ContentfulHugoConfig
-Typ importieren.
//////////// 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
} ;
Beispiel für ein .gitignore
Setup
# 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
Dateien werden in dem in der Konfigurationsdatei angegebenen Verzeichnis generiert. Die Titelseite wird im YAML-Format vorliegen. Dateien einzelner Typen werden nach dem in der Konfigurationsdatei angegebenen Dateinamen benannt. Dateien wiederholbarer Typen werden in Contenful nach ihrer Eintrags-ID benannt, was das Verknüpfen von Dateien erleichtert.
Die folgenden Felder werden immer in Ihrem Frontmatter erscheinen:
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
Assets wie Bilder und Videos enthalten einige zusätzliche Informationen, die es einfach machen, Dinge wie Alternativtext oder Layouts zu implementieren, die auf der Kenntnis der Bildabmessungen basieren. Die Felder lauten wie folgt:
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)
Wenn Sie Hugo verwenden, können Sie wie folgt auf die Informationen zugreifen:
< img
src =" {{ .Params.assetFieldName.url }} "
width =" {{ .Params.assetFieldName.width }} "
/>
Für Bilder können Sie Parameter an die Asset-URL anhängen, um die Bilder-API von Contentful zu nutzen
< img
src =" {{ .Params.assetFieldname.url }}?w=200&h=200&fit=fill "
width =" 200 "
height =" 200 "
/>
Dieselben Informationen werden auch in Asset-Arrays wie einer Galerie angezeigt:
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
Verknüpfte Einträge enthalten Felder für ihre ID und ihre Inhaltstyp-ID.
linkedEntry :
id : <contentful-entry-id>
typeId : <content-type-ID>
# example with array of linked entries
relatedArticles :
- id : ' 41UFfIhszbS1kh95bomMj7 '
typeId : ' articles '
- id : ' 85UFfIhsacS1kh71bpqMj7 '
typeId : ' articles '
Alle Dateien sind nach ihrer Eintrags-ID in Contentful benannt, sodass sie mit .Site.GetPage
in Hugo einfach abgerufen werden können
// 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 }}
Einfaches Beispiel
{{ with . Params . myEntryField }}
{{ $ pagePage := print "path/to/entryDir/" . id }}
{{ with site. GetPage $ pagePath }}
{{ . Title }}
{{ . Params . someOtherField }}
{{ end }}
{{ end }}
Relevante Dokumentation:
Ein Rich-Text-Feld, das als „mainContent“ für einen Inhaltstyp festgelegt ist, wird als Markdown für Hugo gerendert.
Dynamische Inhalte wie embedded-entry-blocks
werden als Shortcodes mit enthaltenen Parametern gerendert, die zum Abrufen der erforderlichen Daten verwendet werden können.
<!-- 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" >}}
Stellen Sie vor dem Abrufen von Rich-Text-Daten sicher, dass Sie contentful-hugo --init
ausgeführt haben, damit Sie über alle Rich-Text-Shortcodes verfügen. Sobald Sie diese Shortcodes haben, können Sie sie erweitern und an Ihre Bedürfnisse anpassen.
Die Liste der Rich-Text-Shortcodes umfasst:
Standardmäßig zeigen die Richtext-Funktionscodes eine Benachrichtigung für ein nicht konfiguriertes Element an.
Sie können sie anpassen, indem Sie zu layouts/shortcodes/contentful-hugo/{shortcode-name}.html
navigieren
Ein Rich-Text-Feld erzeugt verschachtelte Arrays, die die JSON-Struktur widerspiegeln, die sie in der API haben. Jeder Knoten muss durchlaufen werden und abhängig vom nodeType-Feld HTML erzeugen.
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 : []
Darüber hinaus wird eine Klartextversion des Feldes generiert, indem die Feld-ID mit angehängtem „_plaintext“ verwendet wird. Auf diese Weise können Sie den Text ohne weitere Daten schnell abrufen. Ein einfacher Anwendungsfall wäre die Verwendung der Klartextausgabe, um automatisch eine Meta-Beschreibung für eine Webseite zu generieren.
richTextField_plaintext : ' This is a simple paragraph. This is a paragraph with italicized text. '
Mit der Option „Einträge auflösen“ können Sie eine Eigenschaft eines referenzierten Eintrags oder Assets angeben, in die dieser Feldwert aufgelöst werden soll. Angenommen, Sie haben einen category
, auf den in posts
verwiesen wird. Normalerweise liefert contentful-hugo das folgende Ergebnis
category :
id : some-entry-id
contentType : category
Dies erleichtert zwar das Auffinden der Kategorie, dieses Format ermöglicht jedoch nicht die Nutzung der integrierten Taxonomiefunktionen von Hugo. Mit dem Parameter resolveEntries
können Sie hier Abhilfe schaffen.
// 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' ,
} ,
] ,
]
} )
Jetzt wird im Kategoriefeld nur noch der Slug als Wert angezeigt.
category : my-category-slug
Die Funktion zum Auflösen von Einträgen funktioniert sowohl mit Referenzfeldern als auch mit Asset-Feldern sowie mit mehreren Referenz- und mehreren Asset-Feldern.
Überschreibungen können verwendet werden, um Feldnamen und Feldwerte zu ändern.
Hier ist ein einfaches Beispiel für die Änderung eines Feldnamens von „url“ in „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
verfügt außerdem über eine valueTransformer
-Option, mit der Sie die Felddaten bearbeiten können, die in frontmatter angezeigt werden. valueTransformer
verwendet eine Methode, die den Feldwert als Parameter hat, und gibt dann das Endergebnis zurück, das im Frontmatter angezeigt wird. (Beachten Sie, dass diese Option nur in Javascript-Konfigurationsdateien funktioniert, da valueTransformer
eine Methode sein muss.)
Hier ist ein Beispiel, in dem wir den Feldnamen von „url“ in „videoId“ ändern und dann den valueTransformer
verwenden, um die Video-ID aus der URL zu extrahieren und sie dann im Frontmatter zu platzieren.
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
} ,
} ,
} ,
] ,
} ,
] ;
Wenn Sie die Option valueTransformer
für Felder verwenden, die Arrays enthalten, stellen Sie sicher, dass der Wert beim Bearbeiten in einer Schleife durchlaufen wird.
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 ;
} ,
} ,
} ,
} ,
] ;
Das Feld authors
sieht nun folgendermaßen aus:
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
Wie Sie sehen, kann dies verwendet werden, um ähnliche Ergebnisse wie der Parameter resolveEntries
zu erzielen, aber resolveEntries
kann nur eine Eigenschaft zurückgeben, während Sie mit Überschreibungen mit den Feldwerten machen können, was Sie wollen.
Mithilfe der filters
können Sie Suchparameter eingeben, sodass Sie Einträge anhand einiger ihrer Eigenschaften filtern können. Weitere Informationen zu Contentful-Suchparametern finden Sie in den entsprechenden Dokumenten.
Beachten Sie, dass die folgenden Suchparameter ignoriert werden: content_type
, skip
, order
und 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'
} ,
} ,
] ;
} )
Mit dem Parameter customFields
können Sie Ihren Einträgen zusätzliche Felder hinzufügen. Die Konfiguration für benutzerdefinierte Felder kann ein statischer Wert oder eine Methode sein, die einen Contentful-Eintrag als Parameter akzeptiert und einen Wert zurückgibt.
Nehmen wir an, wir haben einen Autoreninhaltstyp mit den folgenden Feldern:
Hier ist eine Beispielkonfiguration:
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 } ` ;
} ,
} ,
} ,
] ,
} ) ;
Folgendes wird diese Konfiguration bewirken
---
firstName : ' John '
lastName : ' Doe '
slug : ' john-doe '
myCustomField : ' myCustomFieldValue ' # custom field
fullName : ' John Doe ' # custom field
---
Sie können dies auch für Hugo-spezifische Felder wie Build-Optionen verwenden
// 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
}
}
}
Dies sind einige bekannte Probleme.
--wait
hinzu. Hier ist ein Beispiel, bei dem wir weitere 6 Sekunden contentful-hugo --wait=6000
warten.hugo server --disableFastRender
aus