هذه أداة CLI تسحب البيانات من Contentful CMS وتحولها إلى ملفات Markdown أو YAML لاستخدامها مع منشئ موقع ثابت. يمكن استخدامه مع أي منشئ موقع ثابت يستخدم Markdown مع YAML frontmatter، ولكنه يحتوي على بعض الميزات الخاصة بـ Hugo. يتضمن أيضًا خادم Express بسيط يمكنه تلقي خطافات الويب من Contentful لإعادة تشغيل أوامر الحصول على وحذفها (مفيدة عند تشغيل بيئة المعاينة).
تثبيت Node.js (الحد الأدنى للإصدار المدعوم هو Node v18)
مع NPM
# 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 |
--انتظر | -دبليو | انتظر العدد المحدد من المللي ثانية قبل سحب البيانات من Contentful. |
--config | -ج | حدد المسار إلى ملف التكوين. |
--server | -س | قم بالتشغيل في وضع الخادم لتلقي خطافات الويب من 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 لسحب بيانات Contentful ثم تشغيل 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> '
يمكنك أيضًا الإعلان عن متغيرات البيئة في سطر الأوامر
بوويرشيل:
$ 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 افتراضيًا عن الملفات التالية كملف config.
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' ,
} ,
] ,
} ) ;
تكوين جافا سكريبت يشبه إلى حد كبير تكوين TypeScript.
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_TOKEN إذا لم يتم تعيينها) |
معاينةToken | خياري | الرمز المميز لمعاينة المحتوى (الإعدادات الافتراضية لمتغير البيئة CONTENTFUL_PREVIEW_TOKEN إذا لم يتم تعيينه) |
بيئة | خياري | معرف البيئة المحتوى (الإعدادات الافتراضية إلى "رئيسي" إذا لم يتم تعيينها) |
مجال | مطلوب | وصف |
---|---|---|
بطاقة تعريف | مطلوب | معرف نوع المحتوى المحتوى |
دليل | مطلوب | الدليل الذي تريد إنشاء الملف (الملفات) فيه |
اسم الملف | مطلوب | اسم الملف الذي تم إنشاؤه |
fileExtension | خياري | يمكن أن تكون "md" أو "yml" أو "yaml" أو "json" (القيمة الافتراضية هي "md") |
mainContent | خياري | معرف الحقل للحقل الذي تريد أن يكون محتوى Markdown الرئيسي. (يمكن أن يكون حقل تخفيض السعر، أو النص المنسق، أو حقل السلسلة) |
يكتب | خياري | قم بتعيين قيمة حقل "النوع" يدويًا في المادة الأمامية (راجع مستندات Hugo) |
ResolveEntries | خياري | قم بحل الحقول المرجعية المحددة و/أو حقول الأصول إلى أحد معلمات خصائصها |
يتجاوز | خياري | قم بإجراء تجاوزات مخصصة لقيم الحقول أو أسماء الحقول |
المرشحات | خياري | يقبل كائنًا من معلمات البحث المحتوى لتصفية النتائج. راجع المستندات ذات المحتوى |
تجاهلLocales | خياري | تجاهل إعدادات الترجمة واسحب فقط من اللغة الافتراضية (الإعدادات الافتراضية خطأ) |
customFields | خياري | يقبل كائنًا من الحقول والقيم. يمكن أن تكون القيم قيمة ثابتة قياسية أو دالة تقبل الإدخال Contentful كمعلمة وترجع قيمة |
مجال | مطلوب | وصف |
---|---|---|
بطاقة تعريف | مطلوب | معرف نوع المحتوى المحتوى |
دليل | مطلوب | الدليل الذي تريد إنشاء الملفات فيه |
اسم الملف | خياري | خاصية الإدخال التي ستحدد اسم الملف. (افتراضيًا سيكون هذا هو sys.id ) |
fileExtension | خياري | يمكن أن تكون "md" أو "yml" أو "yaml" أو "json" (القيمة الافتراضية هي "md") |
com.isHeadless | خياري | يحول كافة الإدخالات في نوع المحتوى إلى حزم أوراق مقطوعة الرأس (راجع مستندات Hugo). لا يمكن ضبطه على "صحيح" عند ضبط isTaxonomy على "صحيح". |
التصنيف (تجريبي) | خياري | قم بتنظيم الإدخالات في بنية الملف مما يسمح ببيانات تعريف التصنيف المخصصة (راجع مستندات Hugo). لا يمكن ضبطه على "صحيح" عندما يتم ضبط isHeadless على "صحيح". |
mainContent | خياري | معرف الحقل للحقل الذي تريد أن يكون محتوى تخفيض السعر الرئيسي. (يمكن أن يكون حقل تخفيض السعر، أو النص المنسق، أو حقل السلسلة) |
يكتب | خياري | قم بتعيين قيمة حقل "النوع" يدويًا في المادة الأمامية (راجع مستندات Hugo) |
ResolveEntries | خياري | قم بتحليل الحقول المرجعية المحددة و/أو حقول الأصول إلى إحدى خصائصها |
يتجاوز | خياري | قم بإجراء تجاوزات مخصصة لقيم الحقول أو أسماء الحقول |
المرشحات | خياري | يقبل كائنًا من معلمات البحث المحتوى لتصفية النتائج. راجع المستندات ذات المحتوى |
تجاهلLocales | خياري | تجاهل إعدادات الترجمة واسحب فقط من اللغة الافتراضية (الإعدادات الافتراضية خطأ) |
customFields | خياري | يقبل كائنًا من الحقول والقيم. يمكن أن تكون القيم قيمة ثابتة قياسية أو دالة تقبل الإدخال 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 الخاص بك ليأخذ في الاعتبار هذه اللغات. راجع مستندات 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
) الذي سيكون المحتوى القياسي أو دليل البيانات. سيتم نسخ جميع العناصر الموجودة في inputDir إلى 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 أيضًا تغييرات الملف في inputDir أثناء التشغيل في وضع الخادم.
فيما يلي مثال على تغيير خيارات 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. سيتم تسمية الملفات ذات الأنواع الفردية باسم fileName المحدد في ملف التكوين. سيتم تسمية الملفات ذات الأنواع القابلة للتكرار بعد معرف الإدخال الخاص بها في 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 للأصل من أجل الاستفادة من واجهة برمجة تطبيقات الصور الخاصة بـ 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 }}
الوثائق ذات الصلة:
سيتم عرض حقل النص المنسق الذي تم تعيينه باعتباره "المحتوى الرئيسي" لنوع المحتوى كتخفيض لـ 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
بحيث يكون لديك جميع الرموز القصيرة للنص المنسق. بمجرد حصولك على هذه الرموز القصيرة، يمكنك توسيعها وتعديلها لتناسب احتياجاتك.
تتضمن قائمة الرموز القصيرة للنص المنسق ما يلي:
بشكل افتراضي، ستظهر رموز النص المنسق القصيرة إشعارًا لعنصر لم يتم تكوينه.
يمكنك تخصيصها بالانتقال إلى layouts/shortcodes/contentful-hugo/{shortcode-name}.html
سينتج عن حقل النص المنسق صفائف متداخلة تعكس بنية JSON الموجودة في واجهة برمجة التطبيقات (API). ستحتاج كل عقدة إلى التكرار وإنتاج HTML اعتمادًا على حقل نوع العقدة.
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
. عادة سوف يعطي هوغو المحتوى النتيجة التالية
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
يجب أن تكون طريقة، فإن هذا الخيار سيعمل فقط في ملفات تكوين جافا سكريبت)
فيما يلي مثال حيث قمنا بتغيير اسم الحقل من "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
لإضافة حقول إضافية إلى إدخالاتك. يمكن أن يكون تكوين الحقول المخصصة قيمة ثابتة أو طريقة تقبل إدخال المحتوى كمعلمة وترجع قيمة.
لنفترض أن لدينا نوع محتوى المؤلف مع الحقول التالية:
فيما يلي مثال للتكوين:
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 المحددة مثل Build Options
// 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