PHPackages                             oliverthiele/ot-gallery - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. oliverthiele/ot-gallery

ActiveTypo3-cms-extension[Utility &amp; Helpers](/categories/utility)

oliverthiele/ot-gallery
=======================

Gallery - Gallery extension with pre-processing, srcset, lightbox, metadata and pagination for TYPO3 v13 and v14.

v1.2.0(2mo ago)020GPL-2.0-or-laterPHPPHP &gt;=8.3.0

Since Mar 13Pushed 4d agoCompare

[ Source](https://github.com/oliverthiele/ot-gallery)[ Packagist](https://packagist.org/packages/oliverthiele/ot-gallery)[ Docs](https://github.com/oliverthiele/ot-gallery)[ RSS](/packages/oliverthiele-ot-gallery/feed)WikiDiscussions main Synced 3w ago

READMEChangelogDependencies (6)Versions (5)Used By (0)

OT Gallery — TYPO3 Gallery Extension
====================================

[](#ot-gallery--typo3-gallery-extension)

A gallery extension for TYPO3 v13 and v14 built around one core idea: **image sizes are calculated mathematically from your Bootstrap grid configuration**, and all variants are pre-generated via CLI — so the first page load after a cache clear is just as fast as every subsequent one.

[![TYPO3](https://camo.githubusercontent.com/ff624ed071afbc7085dcd4f99f2358379f8284ba14ae6891eab075f69c55929f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5459504f332d31332e342d6f72616e67652e737667)](https://typo3.org/)[![Packagist Version](https://camo.githubusercontent.com/e5e0d30468f80dcf5a553e575feff79cd931a047f11c1f28cad5e3f0db08d14f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6f6c69766572746869656c652f6f742d67616c6c6572792e737667)](https://packagist.org/packages/oliverthiele/ot-gallery)[![PHP](https://camo.githubusercontent.com/a88667e16cf25979c8940c47fc8098ddd8635a928c536cb6378a5c6625f71c3e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646570656e64656e63792d762f6f6c69766572746869656c652f6f742d67616c6c6572792f7068702e737667)](https://php.net/)[![License](https://camo.githubusercontent.com/4c6dbf12a99f0abf06e61c3d1d560c47de32f544d8ce3e732fe797a3cfcee3a4/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6f6c69766572746869656c652f6f742d67616c6c6572792e737667)](LICENSE)[![Changelog](https://camo.githubusercontent.com/6bc02a7bc61afc1cb3faaa53420df6d904b9940d7f3e2e11a463e1fdbb3cd52d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4368616e67656c6f672d4348414e47454c4f472e6d642d626c75652e737667)](CHANGELOG.md)

---

Why another gallery extension?
------------------------------

[](#why-another-gallery-extension)

Most TYPO3 gallery extensions generate processed images on the first frontend request — which means a slow, blocking page load whenever the TYPO3 cache is cleared. They also require you to manually specify image widths that match your grid, or they produce srcset values that don't match the actual rendered size.

OT Gallery takes a different approach:

- **Sizes are derived from your grid, not guessed.** You configure your Bootstrap 5 container widths, gutters and column counts once in the SiteSet. The extension calculates exact pixel widths for every breakpoint — including HiDPI variants — and generates a mathematically correct `sizes` attribute.
- **A CLI command pre-generates every variant before deployment.** `gallery:process` uses the same internal processing pipeline as the frontend renderer, so the browser's first request hits the file system cache directly. No cold-start penalty, no server spike on cache clear.
- **SiteSet configuration** — TypoScript is provided as a TYPO3 v13 SiteSet; no manual TypoScript includes required, just add the extension as a SiteSet dependency.
- **Minimal JavaScript.** The gallery itself requires only Bootstrap 5 (which you likely already have) and optionally Fancybox 5 for the lightbox. No custom gallery framework, no jQuery.
- **Server-side pagination** means the gallery works correctly with hundreds of images and remains SEO-friendly — no JavaScript rendering required for content that search engines need to index.

---

Features
--------

[](#features)

- **Responsive images** — `` with WebP format, calculated from container widths, gutter and column configuration
- **Lightbox** — Fancybox, enable/disable per content element via checkbox; caption fields (title/description/copyright) configurable via SiteSet
- **Two image sources** — FAL file selection or folder (including recursive subfolders, multiple folders)
- **Three layout modes** — Grid, Masonry (CSS columns, no CLS), Justified (planned)
- **Aspect ratio + rendering** — Free, 1:1, 4:3, 3:2, 16:9 with cover/contain/fill per content element
- **Server-side pagination** — Cached, SEO-friendly URLs via TYPO3 Route Enhancer
- **FAL metadata** — Figcaption (title/description/copyright, optional `visually-hidden`) and three-dot context menu ( title/description/copyright) — each field toggled independently per content element
- **Per-image download** — Optional download button in three-dot context menu
- **CLI pre-processing** — Pre-generate all image variants to avoid server load on cache clear; uses `ImageService` to guarantee identical cache keys with the frontend
- **SiteSet configuration** — All defaults configurable via TYPO3 v13 SiteSets (no TypoScript)
- **Bootstrap 5** — Grid, pagination, dropdown components
- **Accessible** — ARIA labels, keyboard navigation, `visually-hidden` screen reader text

---

Requirements
------------

[](#requirements)

RequirementVersionTYPO313.4+PHP8.3+Bootstrap5.xFancybox5.x (if lightbox enabled)---

Installation
------------

[](#installation)

```
composer require oliverthiele/ot-gallery
```

Then run the TYPO3 setup:

```
vendor/bin/typo3 extension:setup -e ot_gallery
# or via DDEV:
ddev typo3 extension:setup -e ot_gallery
```

---

Configuration
-------------

[](#configuration)

### 1. Add SiteSet

[](#1-add-siteset)

Include the SiteSet in your site configuration (`config/sites/yoursite/config.yaml`):

```
dependencies:
    - oliverthiele/ot-gallery
```

### 2. Add Routing

[](#2-add-routing)

Include the pagination route enhancer to get SEO-friendly pagination URLs (`?tx_otgallery_page=2` → `/page-2`):

```
imports:
    - { resource: 'EXT:ot_gallery/Configuration/Routes/Default.yaml' }
```

### 3. Add SCSS

[](#3-add-scss)

Copy or import the example stylesheet into your project build:

```
@use 'path/to/EXT:ot_gallery/Resources/Private/Scss/Example' as gallery;
```

Or copy `Resources/Private/Scss/Example.scss` into your project and adapt as needed.

### 4. Initialize Bootstrap JavaScript

[](#4-initialize-bootstrap-javascript)

The three-dot context menu (description, copyright, download) uses Bootstrap Dropdown. Ensure Bootstrap JS is initialized on your page:

```
// If not using bootstrap.bundle.js (which auto-initializes):
document.querySelectorAll('[data-bs-toggle="dropdown"]').forEach(el => {
    new bootstrap.Dropdown(el);
});
```

### 5. Include Fancybox

[](#5-include-fancybox)

If you use the lightbox feature, include Fancybox 5 in your project:

```

```

Then initialize:

```
Fancybox.bind('[data-fancybox]');
```

---

SiteSet Settings
----------------

[](#siteset-settings)

All settings can be configured in your site's SiteSet or overridden per content element via FlexForm.

### Grid &amp; Breakpoints

[](#grid--breakpoints)

SettingDefaultDescription`otGallery.grid.columns.xs``1`Columns on xs screens`otGallery.grid.columns.sm``2`Columns on sm screens`otGallery.grid.columns.md``3`Columns on md screens`otGallery.grid.columns.lg``4`Columns on lg screens`otGallery.grid.columns.xl``5`Columns on xl screens`otGallery.grid.columns.xxl``6`Columns on xxl screens`otGallery.grid.gutter``24`Gutter width in px`otGallery.grid.container.padding``12`Container padding in px (one side)`otGallery.grid.container.sm.maxWidth``540`Container max-width at sm in px`otGallery.grid.container.md.maxWidth``720`Container max-width at md in px`otGallery.grid.container.lg.maxWidth``960`Container max-width at lg in px`otGallery.grid.container.xl.maxWidth``1140`Container max-width at xl in px`otGallery.grid.container.xxl.maxWidth``1320`Container max-width at xxl in px### Thumbnail Defaults

[](#thumbnail-defaults)

SettingDefaultDescription`otGallery.thumbnail.aspectRatio``free`Default aspect ratio (`free`, `1:1`, `4:3`, `3:2`, `16:9`)`otGallery.thumbnail.rendering``cover`Object-fit mode (`cover`, `contain`, `fill`)### Lightbox

[](#lightbox)

SettingDefaultDescription`otGallery.lightbox.captionFields``title,description,copyright`Comma-separated fields shown in lightbox caption`otGallery.lightbox.dataAttribute``data-fancybox`HTML data attribute used to trigger the lightbox### Pagination

[](#pagination)

SettingDefaultDescription`otGallery.pagination.itemsPerPage``48`Images per page (0 = unlimited)### Processing (CLI)

[](#processing-cli)

SettingDefaultDescription`otGallery.processing.hiDpi``true`Generate 2x variants for retina displays`otGallery.processing.webp.quality``82`WebP quality (1–100)`otGallery.processing.jpeg.quality``85`JPEG quality (1–100)---

FlexForm Options (per content element)
--------------------------------------

[](#flexform-options-per-content-element)

### Layout tab

[](#layout-tab)

- **Layout** — Grid / Masonry
- **Aspect ratio** — Free / 1:1 / 4:3 / 3:2 / 16:9
- **Rendering** — Cover / Contain / Fill (visible only when aspect ratio is not free)
- **Column override** — Override default columns per breakpoint

### Sort tab

[](#sort-tab)

- **Sort field** — By filename / date / custom (FAL sort order)
- **Sort direction** — Ascending / Descending
- **Items per page** — Override SiteSet default (0 = use SiteSet default)

### Features tab

[](#features-tab)

- **Enable lightbox** — Checkbox; activates Fancybox for all images in this element
- **Figcaption group** — Show title / description / copyright below each image; optionally `visually-hidden` (screen readers only)
- **Menu group** — Show title / description / copyright in the three-dot context menu per image
- **Enable download** — Per-image download button in the three-dot context menu

---

CLI: Image Pre-Processing
-------------------------

[](#cli-image-pre-processing)

Pre-process all gallery images to avoid server load when caches are cleared:

```
# Process all galleries
vendor/bin/typo3 gallery:process

# Process a specific content element
vendor/bin/typo3 gallery:process --content-uid=42

# Only process galleries where configuration has changed
vendor/bin/typo3 gallery:process --unprocessed-only

# Dry run (show what would be processed)
vendor/bin/typo3 gallery:process --dry-run

# Verbose output (show widths and column info per breakpoint)
vendor/bin/typo3 gallery:process -v
```

The command uses a configuration hash (`MD5`) stored per content element to detect when image dimensions need to be recalculated (e.g. after changing column counts or SiteSet grid settings).

The CLI uses `ImageService::applyProcessingInstructions()` — identical to the frontend ViewHelpers — so the pre-generated files produce exact cache hits on the first page load. No images are re-processed by the frontend.

---

Template Customization
----------------------

[](#template-customization)

The extension follows TYPO3's template override convention. Override paths in your TypoScript:

```
tt_content.ot_gallery {
    templateRootPaths.20 = EXT:your_sitepackage/Resources/Private/Templates/
    partialRootPaths.20 = EXT:your_sitepackage/Resources/Private/Partials/
    layoutRootPaths.20 = EXT:your_sitepackage/Resources/Private/Layouts/
}

```

### Available template variables

[](#available-template-variables)

VariableTypeDescription`{gallery.images}``FileInterface[]`Images on current page`{gallery.allImages}``FileInterface[]`All images (all pages)`{gallery.totalCount}``int`Total image count`{gallery.paginator}``ArrayPaginator`TYPO3 paginator object`{gallery.pagination}``SimplePagination`TYPO3 pagination object`{gallery.sizesAttribute}``string`Calculated `sizes` attribute string`{gallery.imageWidths}``array`Calculated widths per breakpoint (incl. `@2x` keys)`{gallery.rowColsClasses}``string`Bootstrap `row-cols-*` class string`{gallery.aspectRatioCss}``string`CSS-formatted ratio (`4/3`) or empty string`{gallery.effectiveLayout}``string`Active layout name (`grid`, `masonry`, …)`{gallery.flex}``array`All FlexForm settings`{gallery.lightboxCaptionFields}``array`Map of `title/description/copyright => bool` for lightbox captions`{gallery.source}``string``files` or `folder`### ViewHelpers

[](#viewhelpers)

ViewHelperDescription`ot:gallerySrcset`Generates `srcset` attribute string for all unique widths`ot:galleryImageSrc`Returns processed image URL for a single width (use for `src` fallback)`ot:lightboxCaption`Assembles lightbox caption string from image metadata fields---

SiteKit Integration (optional)
------------------------------

[](#sitekit-integration-optional)

If your project uses [OT SiteKit Base](https://github.com/oliverthiele/ot-sitekit-base), the extension ships with a `Configuration/SiteKit.yaml` that registers `ot_gallery` with the SiteKit grid system:

```
elements:
    -   ctype: ot_gallery
        groups: [ group_content_wide ]
        grid: { minCols: 6, requiresFullWidth: false }
```

This tells SiteKit that the gallery requires at least 6 grid columns and does not need to span the full width. Without SiteKit installed, this file is simply ignored.

---

Planned Features
----------------

[](#planned-features)

- **Fancybox across pagination pages** — Show all images in lightbox slideshow regardless of current page
- **Subfolder galleries** — Subfolders as nested gallery entries with cover image
- **Folder/image sidecar files** — `gallery.json` per folder, `image.jpg.json` per image for metadata without EXIF
- **ZIP download** — Pre-generated ZIP via CLI, served by middleware
- **EXIF display** — Camera, aperture, shutter speed, ISO, date in metadata overlay
- **Search / Filter** — Server-side via middleware or Extbase plugin (client-side not feasible with server-side pagination)

---

License
-------

[](#license)

GPL-2.0-or-later — see [LICENSE](LICENSE)

Author
------

[](#author)

Oliver Thiele — [oliver-thiele.de](https://www.oliver-thiele.de)

###  Health Score

42

—

FairBetter than 89% of packages

Maintenance94

Actively maintained with recent releases

Popularity8

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~22 days

Total

3

Last Release

62d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/5030298?v=4)[Oliver Thiele](/maintainers/oliverthiele)[@oliverthiele](https://github.com/oliverthiele)

---

Top Contributors

[![oliverthiele](https://avatars.githubusercontent.com/u/5030298?v=4)](https://github.com/oliverthiele "oliverthiele (30 commits)")

### Embed Badge

![Health badge](/badges/oliverthiele-ot-gallery/health.svg)

```
[![Health](https://phpackages.com/badges/oliverthiele-ot-gallery/health.svg)](https://phpackages.com/packages/oliverthiele-ot-gallery)
```

###  Alternatives

[friendsoftypo3/content-blocks

TYPO3 CMS Content Blocks - Content Types API | Define reusable components via YAML

101466.4k45](/packages/friendsoftypo3-content-blocks)[wazum/sluggi

TYPO3 extension for URL slug management with inline editing, auto-sync, locking, access control, and redirects

41515.2k](/packages/wazum-sluggi)[praetorius/vite-asset-collector

Use AssetCollector to embed frontend assets generated by vite

54299.7k1](/packages/praetorius-vite-asset-collector)[typo3/cms-redirects

TYPO3 CMS Redirects - Create manual redirects, list existing redirects and automatically createredirects on slug changes.

167.3M74](/packages/typo3-cms-redirects)[typo3/cms-sys-note

TYPO3 CMS System Notes - Records with messages which can be placed on any page and contain instructions or other information related to a page or section.

116.2M37](/packages/typo3-cms-sys-note)[b13/assetcollector

Asset collector - Add CSS and SVG files and strings as inline style tag/inline svg to the html code.

10123.2k](/packages/b13-assetcollector)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
