Configuration of Entry Types and Sections in Craft CMS
Sections and Entry Types are the foundation of content structure in Craft CMS. Incorrect architecture at this level leads to rework in a month. Understanding the difference between Section types reduces design time.
Section Types
Channel — collection of entries without hierarchy. Blog, news, products, vacancies. URL is built like /blog/{slug}.
Structure — hierarchical pages with nesting and manual sorting capability. Documentation, catalog with subcategories. URL: /services/web-development/landing-pages.
Single — one unique entry. Homepage, About, Contact. No slug, no archive.
Entry Types
Each Section can have multiple Entry Types with different field sets. Example for Section Blog:
Section: blog (Channel)
├── Entry Type: article
│ └── Fields: body (Matrix), readingTime (calculated), podcast (false)
├── Entry Type: podcast
│ └── Fields: audioFile (Asset), transcript (Redactor), duration (Number)
└── Entry Type: video
└── Fields: videoUrl (URL), thumbnail (Asset), youtubeId (computed)
Render differently by type in Twig:
{% switch entry.type.handle %}
{% case 'article' %}
{% include '_blog/_article' %}
{% case 'podcast' %}
{% include '_blog/_podcast' %}
{% case 'video' %}
{% include '_blog/_video' %}
{% endswitch %}
Configuration via Project Config (YAML)
# config/project/sections/blog.yaml
name: Blog
handle: blog
type: channel
enableVersioning: true
defaultPlacement: end
propagationMethod: all
siteSettings:
default:
hasUrls: true
uriFormat: 'blog/{slug}'
template: blog/_entry
enabledByDefault: true
entryTypes:
article:
name: Article
handle: article
hasTitleField: true
titleTranslationMethod: site
fieldLayout:
- type: craft\fieldlayoutelements\TitleField
- type: craft\fieldlayoutelements\CustomField
fieldUid: [uid-of-body-field]
- type: craft\fieldlayoutelements\CustomField
fieldUid: [uid-of-categories-field]
Structure with Nesting
Section: services (Structure)
├── maxLevels: 3
├── enableVersioning: true
└── defaultSort: structure (manual tree sorting)
Query child elements:
{# Get all descendants of current page #}
{% set children = craft.entries()
.section('services')
.descendantOf(entry)
.level(entry.level + 1)
.orderBy('lft asc')
.all() %}
Fields with translationMethod Option
With multi-site support, it's important to set translation correctly:
-
none— one value for all sites -
site— own value for each site -
language— own value for each language -
siteGroup— own value for site group
Configuration of 5–8 sections with Entry Types takes 1–2 days.







