1.1.x → SDC
Upgrading¶
Up to and including 1.1.x, IXM Blocks rendered every block type from hand-written Twig inside its own submodule. This release moves all of that rendering into SDCs — the block types stay exactly where they are; their templates become thin adapters that map fields onto a component.
There is no data to migrate. Block types, paragraph types, fields, existing block content and every block placement survive the upgrade untouched, under the same machine names.
What moves, and what doesn't¶
| Layer | Before | After |
|---|---|---|
| Block types, paragraph types, fields | Submodule config/optional/ |
Unchanged |
| Existing block content and placements | Content entities | Unchanged |
| Markup | Inline in block--ixm-blocks-*.html.twig |
components/<name>/<name>.twig |
| CSS | Bootstrap utility classes in the template, plus theme overrides | components/<name>/<name>.css, driven by custom properties |
| JS | Submodule js/, attached by a submodule library |
components/<name>/js/, attached by the component |
| Theming hook | Override the template, or out-specify the classes | Set --theme-* and --<component>-* |
| Reuse outside a block | None | Place the component directly in Drupal Canvas |
What you need installed¶
composer require drupal/ixm_blocks always pulls in bootstrap_components and twig_tweak — the root module can't enable without them, since four submodules render through bootstrap_components' Card/Carousel/Accordion/Modal SDCs, and Hero Banner reads its site-wide default via twig_tweak's drupal_config(). Core requirement is ^10 || ^11.
Beyond that, what else you need depends entirely on how content gets placed:
| Placing components via | What you need |
|---|---|
| Drupal Canvas | Just ixm_blocks. Canvas maps fields to props directly — no submodule needed. |
| Layout Builder | Also enable the matching ixm_blocks_<type> submodule (e.g. ixm_blocks_tabs) — it ships the block type and paragraph fields Layout Builder places. |
| Hand-coded in a theme | Just ixm_blocks — a developer includes the SDC directly. |
| Paragraphs field only (no Layout Builder) | Just ixm_blocks, plus your own paragraph--*.twig bridge — none is shipped. |
A Canvas-only site never needs to enable a single ixm_blocks_<type> submodule. See Architecture § Companion modules per path for the full requirements list, including third-party companions like bootstrap_ui_kit or canvas_icon_picker.
The upgrade¶
-
1
composer require drupal/ixm_blocks -
2
drush updb -yOne post-update hook,
install_hero_banner_settings, createsixm_blocks.hero_banner.settingson sites that installed the module before that config existed. -
3
drush cr
What will break in a themed site¶
Content is safe. A theme that reached into the old markup is not, and there is no automated fix for it, because the old markup no longer exists.
-
Any
block--ixm-blocks-*.html.twigin your theme still wins, and keeps rendering the old markup against the new CSS. -
The templates no longer emit layout utilities: grid decisions live in the component now. Selectors written against those classes silently stop matching.
-
Three libraries moved or disappeared. Naming one in
libraries-override, or callingattach_library()on one, throws once it no longer resolves.
Delete the override and re-express the intent as tokens, or keep it and accept that the component's stylesheet no longer applies to it.
The Statistics block is the clearest case:
{# 1.1.x #}
<div class="ixm-stats-block">
<div class="statistic-item col-12 col-md-3 text-center">
<div class="row g-0 h2 text-primary">…</div>
{# now: the block emits the row, the component emits the item #}
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-4 g-4 justify-content-center text-center">
<div class="statistic-item">
<div class="statistics-count-line">…</div>
.ixm-stats-block is gone, .statistic-item no longer carries column classes, and the numeral's wrapper is .statistics-count-line rather than a .row.h2.text-primary. The .js-count hook survives.
| Library | Now |
|---|---|
ixm_blocks_statistics/statistics-counter |
Removed. The counter ships with the statistic component and attaches itself. |
ixm_blocks_hero/hero-player |
Removed. hero-player.js moved into the hero_banner component. |
ixm_blocks_table/ixm-blocks-tablesaw |
Moved to ixm_blocks/ixm-blocks-tablesaw, attached by the table component. |
Block type → component¶
| Block type | Renders through |
|---|---|
| Statistics | ixm_blocks:statistic |
| Ping Pong | ixm_blocks:ping_pong |
| CTA Icons | ixm_blocks:cta_icon_item |
| Tabs | ixm_blocks:tabs, ixm_blocks:tab_item |
| Table | ixm_blocks:table |
| Hero | ixm_blocks:hero_banner, ixm_blocks:hero_banner_slide |
| Boilerplate | ixm_blocks:ping_pong |
| Cards | bootstrap_components:card |
| Carousel | bootstrap_components:carousel, bootstrap_components:carousel_item |
| Accordion | bootstrap_components:accordion, bootstrap_components:accordion_item |
| Modal | bootstrap_components:modal |
Text, Media and Icon Media have no block type behind them: they exist only as components, for Canvas and for other components to compose.
Rewriting an override as tokens¶
Most theme overrides existed to change one visual decision. Nearly all of them collapse to a declaration. A theme that squared off the table and killed its stripes used to need this:
/* before: fighting the template's classes */
.block-ixm-blocks-table .table {
--bs-table-striped-bg: transparent;
}
.block-ixm-blocks-table .table-responsive {
border-radius: 0 !important;
}
and now needs this, where the first declaration also squares off every other component in the set:
:root {
--theme-radius-lg: 0;
}
.ixm-table {
--ixm-table-stripe-color: transparent;
}
The rule for which layer to reach for is in Theming; the full vocabulary is in the token reference. Each component page lists the tokens that component actually reads, with the values three different themes give them.
What you gain¶
-
Canvas placement
Every component is droppable in Drupal Canvas without a block content entity behind it.
-
Themeable without a rebuild
No Sass compile, no template override, no patch: a custom theme is a set of custom property declarations.
-
Admin settings
Hero Banner carousel default and icon settings now have real forms under Configuration » Content authoring » IXM Blocks.
-
A click-to-play video facade
YouTube and Vimeo stay off the page until a visitor asks for them.
Rolling back¶
Nothing in the upgrade rewrites content, so rolling back is a code revert plus a cache rebuild:
composer require drupal/ixm_blocks:^1.1
drush cr
The Canvas folder reorganisation the post-update hooks performed is not undone by that, but it only affects how the palette is grouped, not what is placed on a page.