.. include:: /Includes.rst.txt
.. _examples-advanced-features:
=================
Advanced Features
=================
Examples for implementing lightbox functionality and lazy loading for performance optimization.
.. contents:: Table of Contents
:depth: 3
:local:
Lightbox Integration
====================
PhotoSwipe Lightbox
-------------------
**Objective**: Add lightbox functionality to images
Install PhotoSwipe
~~~~~~~~~~~~~~~~~~
.. code-block:: bash
npm install photoswipe
TypoScript Setup
~~~~~~~~~~~~~~~~
.. code-block:: typoscript
page {
includeJSFooterlibs {
photoswipe = EXT:my_site/Resources/Public/JavaScript/photoswipe.min.js
photoswipe_init = EXT:my_site/Resources/Public/JavaScript/lightbox-init.js
}
includeCSS {
photoswipe = EXT:my_site/Resources/Public/Css/photoswipe.css
}
}
lib.parseFunc_RTE {
tags.img = TEXT
tags.img {
current = 1
preUserFunc = MyVendor\MySite\UserFunc\LightboxImageRenderer->render
}
}
PHP Wrapper
~~~~~~~~~~~
.. code-block:: php
:caption: EXT:my_site/Classes/UserFunc/LightboxImageRenderer.php
namespace MyVendor\MySite\UserFunc;
use TYPO3\CMS\Core\Resource\FileRepository;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
class LightboxImageRenderer
{
public function render(
string $content,
array $conf,
ContentObjectRenderer $cObj
): string {
// Check if zoom enabled
if (strpos($content, 'data-htmlarea-zoom') === false) {
return $content;
}
// Extract file UID
if (!preg_match('/data-htmlarea-file-uid="(\d+)"/', $content, $match)) {
return $content;
}
$fileUid = (int)$match[1];
$fileRepository = GeneralUtility::makeInstance(FileRepository::class);
try {
$file = $fileRepository->findByUid($fileUid);
} catch (\Exception $e) {
return $content;
}
// Remove data attributes for frontend
$content = preg_replace('/\s*data-htmlarea-[^=]+="[^"]*"/', '', $content);
// Wrap in lightbox link
$lightboxLink = sprintf(
'%s',
$file->getPublicUrl(),
$file->getProperty('width'),
$file->getProperty('height'),
$content
);
return $lightboxLink;
}
}
JavaScript Initialization
~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: javascript
:caption: EXT:my_site/Resources/Public/JavaScript/lightbox-init.js
import PhotoSwipeLightbox from 'photoswipe/lightbox';
import 'photoswipe/style.css';
const lightbox = new PhotoSwipeLightbox({
gallery: '.ce-bodytext',
children: 'a[data-pswp-width]',
pswpModule: () => import('photoswipe'),
});
lightbox.init();
**Result**: Click-to-enlarge images with lightbox ✅
Lazy Loading
============
Native Lazy Loading
-------------------
**Objective**: Improve page load performance with native lazy loading
TypoScript Setup
~~~~~~~~~~~~~~~~
.. code-block:: typoscript
lib.parseFunc_RTE {
nonTypoTagStdWrap.HTMLparser.tags.img {
fixAttrib {
loading {
set = lazy
}
# Remove internal attributes
data-htmlarea-file-uid.unset = 1
data-htmlarea-file-table.unset = 1
data-htmlarea-zoom.unset = 1
}
}
}
Result HTML
~~~~~~~~~~~
.. code-block:: html
Intersection Observer Fallback
-------------------------------
**For older browsers**:
TypoScript
~~~~~~~~~~
.. code-block:: typoscript
page.includeJSFooterlibs.lazyload = EXT:my_site/Resources/Public/JavaScript/lazyload.js
lib.parseFunc_RTE {
nonTypoTagStdWrap.HTMLparser.tags.img {
fixAttrib {
class {
list = lazyload
}
data-src {
# Copy src to data-src
stdWrap.field = src
}
src {
# Set placeholder
set = data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 3 2'%3E%3C/svg%3E
}
}
}
}
JavaScript
~~~~~~~~~~
.. code-block:: javascript
:caption: EXT:my_site/Resources/Public/JavaScript/lazyload.js
document.addEventListener('DOMContentLoaded', function() {
const imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.classList.remove('lazyload');
imageObserver.unobserve(img);
}
});
});
document.querySelectorAll('img.lazyload').forEach(img => {
imageObserver.observe(img);
});
});
**Result**: Progressive image loading ✅
Related Documentation
=====================
- :ref:`examples-responsive-images` - Responsive image implementation
- :ref:`examples-custom-extensions` - Custom dialog and extensions
- :ref:`integration-configuration` - Configuration guide