Back to Tutorials
Custom Block Types in Drupal 8 — Stat Card Example
Build a reusable custom block type in Drupal 8 with fields, Twig templates, and conditional rendering.
Create a custom block type in Drupal 8 with structured fields and a custom Twig template. This example builds a "Stat Card" block.
Define the Block Type
Go to Structure > Block layout > Block types > Add and create a new block type with these fields:
| Field | Type | Machine name |
|---|---|---|
| Icon | Text (plain) | field_icon |
| Primary Text | Text (plain) | field_primary_text |
| Secondary Text | Text (plain) | field_secondary_text |
| Button URL | Link | field_button |
Identify the Twig Template
Enable Twig debugging in services.yml:
yaml
parameters:
twig.config:
debug: true
Inspect the page source to find the template suggestion, e.g.:
block--inline-block--stat-card.html.twig
Create the Template
Place the template in your theme's templates/ directory:
twig
{%- set primary = content.field_primary_text|render|striptags|trim -%}
{%- set secondary = content.field_secondary_text|render|striptags|trim -%}
{%- set icon = content.field_icon|render|striptags|trim -%}
{%- set button_url = content.field_button[0]['#url']|render|striptags|trim -%}
{%- set button_text = content.field_button[0]['#title']|render|striptags|trim -%}
<div class="stat-card">
{% if icon %}
<div class="stat-card__icon">{{ icon }}</div>
{% endif %}
<h3 class="stat-card__primary">{{ primary }}</h3>
{% if secondary %}
<p class="stat-card__secondary">{{ secondary }}</p>
{% endif %}
{% if button_url is not empty %}
<a href="{{ button_url }}" class="stat-card__button">
{{ button_text }}
</a>
{% endif %}
</div>
Style the Block
css
.stat-card {
padding: 2rem;
border-radius: 0.5rem;
background: #f8f9fa;
text-align: center;
}
.stat-card__icon {
font-size: 2.5rem;
margin-bottom: 1rem;
}
.stat-card__primary {
font-size: 2rem;
font-weight: 700;
margin: 0;
}
.stat-card__secondary {
color: #6c757d;
margin-top: 0.5rem;
}
.stat-card__button {
display: inline-block;
margin-top: 1rem;
padding: 0.5rem 1.5rem;
background: #007bff;
color: white;
border-radius: 0.25rem;
text-decoration: none;
}
Key Twig Patterns
twig
{# Strip HTML and trim whitespace from rendered fields #}
{{ content.field_name|render|striptags|trim }}
{# Check if a field has a value #}
{% if content.field_name|render|striptags|trim is not empty %}
{# Access link field URL and title #}
{{ content.field_link[0]['#url'] }}
{{ content.field_link[0]['#title'] }}