# Upgrade notes

## Breakpoint-field consolidation (release/v14, May 2026)

Three families of per-breakpoint columns on `tt_content` were collapsed
into single JSON columns to reduce row-size pressure and to make the
breakpoint count flexible.

| Old (this extension)              | New                       | Type   |
| ---                               | ---                       | ---    |
| `tx_t3bs_col_xs..xxl` (6 × varchar) | `tx_t3bs_column_grid`     | json   |
| `tx_t3bs_cards_grid_xs..xxl` (6 × varchar) | `tx_t3bs_cards_grid` | json   |

A third migration in **t3bootstrap/core** collapses
`imagecols_xs..xxl` (6 × tinyint) into `imagecols_grid` (json). See
that extension's `UPGRADE.md`.

### Backend

The six selects per family are replaced with a single
`breakpointGrid` form element — one row of breakpoint-headed selects.
The provided `itemsProcFunc` (e.g.
`T3Bootstrap\ContainerBs5Templates\Form\ColumnWidthItems::getItems`)
keeps working unchanged.

### Frontend

The Fluid templates `Column.html` and `Cards.html` now read
`{data.tx_t3bs_column_grid.xs}` etc., not the flat per-breakpoint
fields. A `JsonFieldsProcessor` (registered in
`Configuration/Sets/ContainerBs5Templates/setup.typoscript` for
`t3bs_column` and `t3bs_cards`) decodes the JSON column to an
associative array before Fluid renders.

**If you have site-specific overrides of `Column.html` or
`Cards.html`**: update them to use the dot notation. Reading
`{data.tx_t3bs_col_xs}` will return nothing after the migration.

### Upgrade procedure

```bash
composer update t3bootstrap/core t3bootstrap/container-bs5-templates
vendor/bin/typo3 database:updateschema           # adds 3 new JSON columns
vendor/bin/typo3 upgrade:run t3bsMigrateColumnGridToJson
vendor/bin/typo3 upgrade:run t3bsMigrateCardsGridToJson
vendor/bin/typo3 upgrade:run t3bcoreMigrateImagecolsToJson
vendor/bin/typo3 database:updateschema 'field.prefix'
vendor/bin/typo3 database:updateschema 'field.drop'
```

If `field.drop` errors with `Row size too large`, the table is still
above the InnoDB 8126-byte limit during the schema-aware drop.
Workaround:

```sql
ALTER TABLE tt_content
    DROP COLUMN zzz_deleted_tx_t3bs_col_xs,
    DROP COLUMN zzz_deleted_tx_t3bs_col_sm,
    DROP COLUMN zzz_deleted_tx_t3bs_col_md,
    DROP COLUMN zzz_deleted_tx_t3bs_col_lg,
    DROP COLUMN zzz_deleted_tx_t3bs_col_xl,
    DROP COLUMN zzz_deleted_tx_t3bs_col_xxl,
    DROP COLUMN zzz_deleted_tx_t3bs_cards_grid_xs,
    DROP COLUMN zzz_deleted_tx_t3bs_cards_grid_sm,
    DROP COLUMN zzz_deleted_tx_t3bs_cards_grid_md,
    DROP COLUMN zzz_deleted_tx_t3bs_cards_grid_lg,
    DROP COLUMN zzz_deleted_tx_t3bs_cards_grid_xl,
    DROP COLUMN zzz_deleted_tx_t3bs_cards_grid_xxl,
    DROP COLUMN zzz_deleted_imagecols_xs,
    DROP COLUMN zzz_deleted_imagecols_sm,
    DROP COLUMN zzz_deleted_imagecols_md,
    DROP COLUMN zzz_deleted_imagecols_lg,
    DROP COLUMN zzz_deleted_imagecols_xl,
    DROP COLUMN zzz_deleted_imagecols_xxl,
    ALGORITHM=COPY, LOCK=SHARED;
```

The `ALGORITHM=COPY` rebuilds the table in one pass, sidestepping the
row-size check that kicks in on incremental in-place drops.

### Wizards

All three migration wizards are idempotent. They skip rows whose
target JSON column is already populated. The legacy migrations
`MigrateFluxBs5ToContainerBs5` and `MigrateWst3bootstrapToContainerBs5`
have been updated to write the new JSON column directly when migrating
from old flux templates.
