Это инструмент CLI, который извлекает данные из Contentful CMS и преобразует их в файлы Markdown или YAML для использования с генератором статического сайта. Его можно использовать с любым генератором статических сайтов, который использует Markdown с интерфейсом YAML, но у него есть некоторые функции, специфичные для Hugo. Он также включает в себя простой сервер Express, который может получать веб-перехватчики от Contentful для повторного запуска команд получения и удаления (полезно при запуске среды предварительного просмотра).
Установите Node.js (минимальная поддерживаемая версия — Node v18).
с НПМ
# local install
npm install contentful-hugo
# global install
npm install contentful-hugo -g
с ПНПМ
# local install
pnpm install contentful-hugo
# global install
pnpm install contentful-hugo -g
Завершите настройку, затем выполните следующие команды в терминале
# # 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 ]
флаг | псевдонимы | описание |
---|---|---|
--init | Инициализируйте каталог. Создает файл конфигурации и короткие коды по умолчанию для полей с форматированным текстом. | |
--предварительный просмотр | -П | Запускается в режиме предварительного просмотра, который извлекает как опубликованные, так и неопубликованные записи из Contentful. |
--ждать | -W | Подождите указанное количество миллисекунд, прежде чем извлекать данные из Contentful. |
--config | -С | Укажите путь к файлу конфигурации. |
--сервер | -С | Запускайте в режиме сервера, чтобы получать вебхуки от Contentful. |
--порт | Укажите порт для режима сервера (по умолчанию 1414). | |
--чистый | Удалите все каталоги, указанные в SingleTypes иRepeatableTypes. | |
--помощь | Показать справку | |
--версия | Показать номер версии |
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 "
}
}
В этом примере, когда вы запускаете npm run dev
он сначала использует Contentful-Hugo для получения данных Contentful, а затем запускает сервер Hugo. Точно так же, когда вы выполняете команду npm run build
она сначала использует contentful-hugo для извлечения контентных данных, а затем запускаетhugo hugo --minify
для создания уменьшенной версии вашего сайта Hugo.
Попытка использовать этот пакет до завершения настройки вернет ошибку в консоли.
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.
По умолчанию эта библиотека будет искать следующие переменные среды. Вы также можете переопределить эти значения с помощью файла конфигурации. (Смотрите конфигурацию)
.env Файл:
Чтобы объявить эти переменные среды, создайте файл .env
в корневом каталоге вашего проекта.
CONTENTFUL_SPACE = ' <space-id> '
CONTENTFUL_TOKEN = ' <content-accessToken> '
# optional but required for preview mode
CONTENTFUL_PREVIEW_TOKEN = ' <preview-accessToken> '
Вы также можете объявить переменные среды в командной строке.
Powershell:
$ env: CONTENTFUL_SPACE = " <contentful_space_id> "
$ env: CONTENTFUL_TOKEN = " <contentful_acessToken> "
$ env: CONTENTFUL_PREVIEW_TOKEN = " <contentful_preview_accessToken> "
Баш:
export CONTENTFUL_SPACE= " <contentful_space_id> "
export CONTENTFUL_TOKEN= " <contentful_accessToken> "
export CONTENTFUL_PREVIEW_TOKEN= " <contentful_preview_accessToken> "
Прежде чем начать, вам нужно будет создать файл конфигурации в корне вашего репозитория. Contentful-hugo по умолчанию будет искать следующие файлы в качестве конфигурации.
contentful-hugo.config.ts
contentful-hugo.config.js
contentful-hugo.config.yaml
contentful-hugo.yaml
contentful-settings.yaml
Вы также можете указать собственный файл конфигурации, используя флаг --config
. (Файлы конфигурации Javascript или YAML являются единственными поддерживаемыми в настоящее время типами файлов)
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' ,
} ,
] ,
} ) ;
Конфигурация JavaScript во многом аналогична конфигурации машинописного текста.
import { defineConfig } from 'contentful-hugo' ;
export default defineConfig ( {
// stuff goes here
} ) ;
Синтаксис CommonJS также должен работать (на самом деле я не проверяю это, возможно, он работает, а может и нет)
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
поле | необходимый | описание |
---|---|---|
космос | необязательный | Идентификатор Contentful Space (по умолчанию используется переменная среды CONTENTFUL_SPACE, если она не установлена) |
жетон | необязательный | Токен доставки контента (по умолчанию используется переменная среды CONTENTFUL_TOKEN, если она не установлена) |
предварительный просмотрТокен | необязательный | Токен предварительного просмотра контента (по умолчанию используется переменная среды CONTENTFUL_PREVIEW_TOKEN, если она не установлена) |
среда | необязательный | Идентификатор среды содержимого (по умолчанию «главный», если не установлен) |
поле | необходимый | описание |
---|---|---|
идентификатор | необходимый | Идентификатор типа контента |
каталог | необходимый | Каталог, в котором вы хотите создать файл(ы) |
имя файла | необходимый | Имя сгенерированного файла |
расширение файла | необязательный | Может быть «md», «yml», «yaml» или «json» (по умолчанию «md»). |
ГлавноеСодержание | необязательный | Идентификатор поля, которое должно быть основным содержимым Markdown. (Может быть полем уценки, форматированным текстом или строковым полем) |
тип | необязательный | Вручную установите значение для поля «тип» во вступительной части (см. документацию Hugo). |
разрешить записи | необязательный | Разрешите указанные ссылочные поля и/или поля активов в один из параметров свойств. |
переопределяет | необязательный | Выполняйте пользовательские переопределения значений полей или имен полей. |
фильтры | необязательный | Принимает объект параметров поиска по содержимому для фильтрации результатов. См. содержательную документацию |
игнорировать локали | необязательный | Игнорировать настройки локализации и использовать только локаль по умолчанию (по умолчанию false) |
пользовательские поля | необязательный | Принимает объект полей и значений. Значения могут быть стандартным статическим значением или функцией, которая принимает запись Contentful в качестве параметра и возвращает значение. |
поле | необходимый | описание |
---|---|---|
идентификатор | необходимый | Идентификатор типа контента |
каталог | необходимый | Каталог, в котором вы хотите создавать файлы |
имя файла | необязательный | Свойство записи, которое будет указывать имя файла. (По умолчанию это будет sys.id ) |
расширение файла | необязательный | Может быть «md», «yml», «yaml» или «json» (по умолчанию «md»). |
isHeadless | необязательный | Превращает все записи в типе контента в обезглавленные листовые пакеты (см. документацию Hugo). Невозможно установить значение true, если для isTaxonomy установлено значение true. |
isTaxonomy (экспериментальный) | необязательный | Организуйте записи в файловой структуре с учетом пользовательских метаданных таксономии (см. документацию Hugo). Невозможно установить значение true, если для параметра isHeadless установлено значение true. |
ГлавноеСодержание | необязательный | Идентификатор поля, которое должно быть основным содержимым уценки. (Может быть полем уценки, форматированным текстом или строковым полем) |
тип | необязательный | Вручную установите значение для поля «тип» во вступительной части (см. документацию Hugo). |
разрешить записи | необязательный | Присвойте указанным ссылочным полям и/или полям активов одно из их свойств. |
переопределяет | необязательный | Выполняйте пользовательские переопределения значений полей или имен полей. |
фильтры | необязательный | Принимает объект параметров поиска по содержимому для фильтрации результатов. См. содержательную документацию |
игнорировать локали | необязательный | Игнорировать настройки локализации и использовать только локаль по умолчанию (по умолчанию false) |
пользовательские поля | необязательный | Принимает объект полей и значений. Значения могут быть стандартным статическим значением или функцией, которая принимает запись Contentful в качестве параметра и возвращает значение. |
В конфигурации также есть поле locales
, которое позволяет вам указать, из каких локалей вы хотите извлечь данные. Это поле может принимать массив строк, массив объектов или их комбинацию.
По умолчанию для нескольких переводов будут использоваться расширения файлов, специфичные для локали.
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
} )
После настройки локалей в Contentful Hugo вам необходимо обновить конфигурацию Hugo, чтобы учесть эти локали. Для получения более подробной информации обратитесь к документации Хьюго.
# config.toml
[ languages ]
[ languages . en-us ]
# language settings
[ languages . fr-fr ]
# language settings
Иногда бывают случаи, когда вам нужно поместить контент в каталог на основе его языкового стандарта, а не использовать перевод на основе расширения файла. Для этого просто включите [locale]
в путь к файлу вашего каталога.
При использовании каталогов, специфичных для локали, расширения файлов, специфичные для локали (например, en.md
или fr.md
), удаляются.
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
*/
} ,
] ,
} ) ;
Рекомендуемая настройка Contentful Hugo — это игнорирование каталогов вашего контента (обычно ./content
) и данных (обычно ./data
) в системе контроля версий. Это связано с тем, что contentful-hugo создаст эти каталоги во время сборки. Однако это создает проблемы в тех случаях, когда у вас есть страницы, которые не управляются в Contentful и не генерируются во время сборки из другого источника.
Чтобы решить эту проблему, в Contentful-Hugo есть параметр staticContent
. Этот параметр принимает входной каталог ( inputDir
), который может быть зафиксирован в git, и выходной каталог ( outputDir
), который будет вашим стандартным каталогом содержимого или данных. Все элементы во входном каталоге будут скопированы в выходной каталог во время сборки и сохранят свою структуру папок.abs
Например, в конфигурации ниже ./static_content/posts/my-post.md
будет скопирован в ./content/posts/my-post.md
, а ./static_data/global-settings.yaml
будет скопирован в ./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 также будет отслеживать изменения файлов во входном каталоге во время работы в режиме сервера.
Вот пример динамического изменения параметров token
, previewToken
и environment
в зависимости от любого произвольного условия.
// 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
}
}
} ]
}
]
} )
Для файлов конфигурации JS вы можете использовать помощник defineConfig
или импортировать тип 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
} ;
Пример настройки .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
Файлы будут созданы в каталоге, указанном в файле конфигурации. Вступительная часть будет в формате YAML. Файлы одного типа будут называться в соответствии с именем файла, указанным в файле конфигурации. Файлы повторяющихся типов будут называться по идентификатору их записи в Contenful, что упрощает связывание файлов вместе.
Следующие поля всегда будут отображаться в вашей заставке:
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
Такие ресурсы, как изображения и видео, содержат некоторую дополнительную информацию, которая позволяет легко реализовать такие вещи, как замещающий текст или макеты, основанные на знании размеров изображения. Поля следующие:
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)
Если вы используете Hugo, вы можете получить доступ к информации, как показано ниже:
< img
src =" {{ .Params.assetFieldName.url }} "
width =" {{ .Params.assetFieldName.width }} "
/>
Для изображений вы можете добавить параметры к URL-адресу ресурса, чтобы использовать API изображений Contentful.
< img
src =" {{ .Params.assetFieldname.url }}?w=200&h=200&fit=fill "
width =" 200 "
height =" 200 "
/>
Эта же информация также появится в массивах ресурсов, например в галерее:
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
Связанные записи будут включать поля для своего идентификатора и идентификатора типа контента.
linkedEntry :
id : <contentful-entry-id>
typeId : <content-type-ID>
# example with array of linked entries
relatedArticles :
- id : ' 41UFfIhszbS1kh95bomMj7 '
typeId : ' articles '
- id : ' 85UFfIhsacS1kh71bpqMj7 '
typeId : ' articles '
Все файлы названы в честь их идентификатора записи в Contentful, что позволяет легко получить их с помощью .Site.GetPage
в 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 }}
Простой пример
{{ with . Params . myEntryField }}
{{ $ pagePage := print "path/to/entryDir/" . id }}
{{ with site. GetPage $ pagePath }}
{{ . Title }}
{{ . Params . someOtherField }}
{{ end }}
{{ end }}
Соответствующая документация:
Поле форматированного текста, заданное как «mainContent» для типа контента, будет отображаться как уценка для Hugo.
Динамический контент, такой как embedded-entry-blocks
отображается как короткие коды с включенными параметрами, которые можно использовать для получения необходимых данных.
<!-- 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" >}}
Прежде чем получать данные форматированного текста, убедитесь, что вы запустили contentful-hugo --init
, чтобы у вас были все короткие коды форматированного текста. Получив эти короткие коды, вы можете расширять и изменять их в соответствии со своими потребностями.
В список коротких кодов форматированного текста входят:
По умолчанию короткие коды richtext отображают уведомление о ненастроенном элементе.
Вы можете настроить их, перейдя по адресу layouts/shortcodes/contentful-hugo/{shortcode-name}.html
Поле форматированного текста будет создавать вложенные массивы, отражающие структуру JSON, которая имеется в API. Каждый узел необходимо будет пройти циклически и создать HTML в зависимости от поля 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 : []
Кроме того, будет сгенерирована текстовая версия поля с использованием идентификатора поля, к которому добавлен «_plaintext». Это позволяет вам быстро получить текст сам по себе без каких-либо других данных. Простой вариант использования — использование вывода открытого текста для автоматического создания метаописания веб-страницы.
richTextField_plaintext : ' This is a simple paragraph. This is a paragraph with italicized text. '
Опция разрешения записей позволяет указать свойство из связанной записи или актива, в которое будет преобразовано значение этого поля. Например, предположим, что у вас есть тип контента category
, на который ссылаются posts
. Обычно contentful-hugo даст следующий результат
category :
id : some-entry-id
contentType : category
Хотя это упрощает поиск категории, этот формат не позволяет использовать встроенные функции таксономии Hugo. С помощью resolveEntries
вы можете исправить это.
// 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' ,
} ,
] ,
]
} )
Теперь в поле категории в качестве значения будет отображаться только слаг.
category : my-category-slug
Функция разрешения записей работает как с полями ссылок, так и с полями активов, а также с множественными полями ссылок и множественными полями активов.
Переопределения можно использовать для изменения имен и значений полей.
Вот простой пример изменения имени поля с «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
также имеет параметры valueTransformer
, которые позволяют вам манипулировать данными полей, которые будут отображаться во вступительной части. valueTransformer
принимает метод, который имеет значение поля в качестве параметра, а затем возвращает окончательный результат, который появится во вступительной части. (Имейте в виду, что, поскольку valueTransformer
должен быть методом, этот параметр будет работать только в файлах конфигурации JavaScript)
Вот пример, в котором мы меняем имя поля с «url» на «videoId», а затем используем valueTransformer
для извлечения идентификатора видео из URL-адреса и затем помещаем его во вступление.
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
} ,
} ,
} ,
] ,
} ,
] ;
При использовании параметра valueTransformer
для полей, содержащих массивы, обязательно просматривайте значение при манипулировании им.
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 ;
} ,
} ,
} ,
} ,
] ;
Теперь поле authors
будет выглядеть так:
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
Как вы можете видеть, это можно использовать для получения результатов, аналогичных resolveEntries
, resolveEntries
может возвращать только одно свойство, а с помощью переопределений вы можете делать со значениями полей все, что захотите.
Вы можете использовать опцию filters
для ввода параметров поиска, что позволяет фильтровать записи на основе некоторых их свойств. Для получения дополнительной информации о параметрах содержательного поиска посетите их документацию.
Имейте в виду, что следующие параметры поиска будут игнорироваться: 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'
} ,
} ,
] ;
} )
Вы можете использовать параметр customFields
, чтобы добавить дополнительные поля к вашим записям. Конфигурация настраиваемых полей может быть статическим значением или методом, который принимает запись Contentful в качестве параметра и возвращает значение.
Допустим, у нас есть авторский тип контента со следующими полями:
Вот пример конфигурации:
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 } ` ;
} ,
} ,
} ,
] ,
} ) ;
Вот что даст эта конфигурация
---
firstName : ' John '
lastName : ' Doe '
slug : ' john-doe '
myCustomField : ' myCustomFieldValue ' # custom field
fullName : ' John Doe ' # custom field
---
Вы также можете использовать это для конкретных полей Hugo, таких как параметры сборки.
// 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
}
}
}
Это некоторые известные проблемы.
--wait
. Вот пример, где мы ждем еще 6 секунд contentful-hugo --wait=6000
.hugo server --disableFastRender