Unless you need some very specific logic, I wouldn't use preprocessing, but use Drupal's template suggestions and Twig instead.
I always use Slick over CDN, adjust for your own needs if necessary. All filenames are relative to the base directory of your theme or module. Replace UPPERCASE_WORDS with corresponding machine names.
Create a library for your carousel:
MYTHEME.libaries.yml
carousel:
version: 1.0.0
js:
https://cdn.jsdelivr.net/npm/[email protected]/slick/slick.min.js: {type: external, minified: true, defer: true, async: true}
js/my_carousel.js: {}
css:
layout:
https://cdn.jsdelivr.net/npm/[email protected]/slick/slick-theme.min.css: {type: external, minified: true}
css/my_carousel.css: {}
js/my_carousel.js
behaviors
are the drupalesque counterpart to jQuery's .ready()
handler (e.g. even if your carousel is loaded inside a view with ajaxified paging, it will still trigger .slick()
after every paging).
(function ($, Drupal) {
Drupal.behaviors.myCarousel = {
attach: function (context, settings) {
$('[data-slick]', context).once('myCarousel').slick();
}
};
}(jQuery, Drupal));
templates/paragraph--CAROUSELCONTAINER.twig.html
The container template would be the place where you alter your slick options, e.g. if you have a integer field "Autoplay speed" on your container paragraph, you could add to my_carousel_options
using paragraph.field_autoplay_speed.0.value
{% set my_carousel_options = '"autoplay": true' %}
{{ attach_library('MYTHEME/carousel') }}
<div{{attributes}} data-slick="{{ my_carousel_options }}">
{{ content.FIELD_CONTAINING_SLIDES }}
</div>
templates/paragraph--CAROUSELSLIDE.twig.html
Here you can decide what to render on each individual slide
{# maybe you also need an additional wrapper <div> around each invidiual slide #}
<a href="{{ paragraph.MY_LINK_FIELD.0.url }}">
{{ content.MY_IMAGE_FIELD }}
{{ content.MY_TITLE_FIELD }}
{{ content.MY_DESCRIPTION_FIELD }}
</a>
If necessary you can further adjust the HTML markup of your slide subfields using something like templates/field--paragraph--MY-DESCRIPTION-FIELD.html.twig
Optional:
If you want to get rid of some container <div>
s around fields automatically rendered by Drupal, create a wrapper-less field template. E.g. I wanted to remove ALL <div>
s and field labels rendered by any paragraph host field:
(this is global for every paragraph host field, change it to a template suggestion matching only your carousel if you don't want this)
field--entity-reference-revisions.html.twig
{% for item in items %}
{{ item.content }}
{% endfor %}
Finally create your own CSS styles for your carousel in css/my_carousel.css
and rebuild the cache so Drupal discovers your new template files.
This basically is how I'm creating carousels on every of my projects. Not tested with Bootstrap theme though, this is some sort of general purpose tutorial.