Website Development with CMS Craft CMS
Craft CMS is a PHP/Yii-based CMS with source code on GitHub, running on MySQL or PostgreSQL. It stands out with a flexible field system, powerful Twig templater, built-in multi-site support and localization. It occupies the niche between WordPress (too limited for complex structures) and fully custom solutions.
Strengths of Craft CMS
Matrix Fields — content blocks of arbitrary structure within a field, similar to WordPress Gutenberg, but with code rather than UI constructor. Allows building page builder without plugins.
Sections — three types: Channel (blog, news), Structure (page hierarchy), Single (single pages). Each Section has its own Entry Types with different field sets.
Relations — native two-way relationships between Entries of any types.
Live Preview — the editor sees changes in real-time in an iframe with the actual page.
Typical Site Architecture
Sections:
├── Homepage (Single)
│ └── Entry Type: homepage
│ └── Fields: hero (Matrix), about (Matrix), stats (Table)
│
├── Services (Structure)
│ └── Entry Type: service
│ └── Fields: intro (Text), features (Matrix), cta (Object)
│
├── Blog (Channel)
│ ├── Entry Type: article
│ │ └── Fields: body (Matrix), author (Users), tags (Tags)
│ └── Entry Type: video
│ └── Fields: videoUrl (URL), transcript (Redactor)
│
└── Team (Channel)
└── Entry Type: teamMember
└── Fields: role (Text), bio (Redactor), photo (Assets)
Matrix Field — Foundation of Flexible Layout
Matrix Field contains blocks of different types. Example of a pageContent field:
Block Types:
├── richText: body (Redactor)
├── imageBlock: image (Assets), caption (Text), alignment (Select)
├── codeBlock: code (Code), language (Select)
├── quote: text (Text), author (Text), role (Text)
├── cta: title (Text), text (Text), buttonLabel (Text), buttonUrl (URL)
└── gallery: images (Assets multiple), columns (Select 2/3/4)
In Twig template:
{% for block in entry.pageContent.all() %}
{% switch block.type %}
{% case "richText" %}
<div class="prose">{{ block.body }}</div>
{% case "imageBlock" %}
<figure class="image-block align-{{ block.alignment }}">
{% set image = block.image.one() %}
{% if image %}
<img src="{{ image.getUrl('large') }}"
alt="{{ image.alt }}"
width="{{ image.width }}"
height="{{ image.height }}">
{% if block.caption %}
<figcaption>{{ block.caption }}</figcaption>
{% endif %}
{% endif %}
</figure>
{% case "cta" %}
<div class="cta-block">
<h3>{{ block.title }}</h3>
<p>{{ block.text }}</p>
<a href="{{ block.buttonUrl }}" class="btn">{{ block.buttonLabel }}</a>
</div>
{% case "gallery" %}
<div class="gallery cols-{{ block.columns }}">
{% for image in block.images.all() %}
<img src="{{ image.getUrl('medium') }}" alt="{{ image.alt }}">
{% endfor %}
</div>
{% endswitch %}
{% endfor %}
Queries via ElementQuery
{# Latest posts with pagination #}
{% set query = craft.entries()
.section('blog')
.type('article')
.status('live')
.orderBy('postDate desc')
.limit(12) %}
{% set totalPosts = query.count() %}
{% set posts = query.offset(pageInfo.offset).all() %}
{% for post in posts %}
{% include '_components/post-card' with { post: post } %}
{% endfor %}
{% if pageInfo.totalPages > 1 %}
{% include '_components/pagination' %}
{% endif %}
Image Transformations
{# Transformations — Named Transforms or inline #}
{% set transform = {
width: 1200,
height: 630,
mode: 'crop',
position: 'center-center',
format: 'webp',
quality: 85
} %}
<picture>
<source
srcset="{{ entry.heroImage.one().getUrl({ width: 800, format: 'webp' }) }} 800w,
{{ entry.heroImage.one().getUrl({ width: 1600, format: 'webp' }) }} 1600w"
type="image/webp">
<img
src="{{ entry.heroImage.one().getUrl(transform) }}"
alt="{{ entry.heroImage.one().alt }}"
loading="lazy">
</picture>
Plugin Ecosystem
| Plugin | Purpose |
|---|---|
| SEOmatic | SEO meta, OpenGraph, Schema.org, Sitemap |
| Redactor | Rich text editor |
| CKEditor | Alternative rich text |
| Feed Me | Import from RSS/XML/CSV |
| Commerce | Full e-commerce |
| Formie | Form builder |
| Blitz | Static caching (like Full Page Cache) |
| Vite | Vite integration for assets |
Development Timeline
| Stage | Time |
|---|---|
| Installation, configuration, section structure | 1–2 days |
| Content Model (fields, Matrix) | 2–3 days |
| Twig templates | 3–7 days |
| Plugins (SEO, forms, etc.) | 1–2 days |
| Deploy + staging | 1 day |
| Corporate website (10–15 pages) | 10–15 days |
| Complex portal | 4–8 weeks |







