Views Carousel for Radix and Bootstrap 5

Created on 22 December 2023, 5 months ago
Updated 10 January 2024, 5 months ago

Add a Views Carousel that Rotates through Teasers

Bootstrap 5 provides JS to run a carousel that rotates through content with next, previous and indicator buttons. The WebWash tutorials have been really helpful and Ivan Zugec has produced a tutorial for a Radix and Boostrap carousel that works with paragraphs. I wanted to have a views carousel that rotated through teasers, and I built a carousel component to do that.

WebWash Bootstrap Carousel.

Proposed resolution

  1. Add a carousel component directory
  2. Create a view block of the content teasers you want to rotate through
  3. Create a carousel twig file to loop through the view rows and a small SCSS file for the buttons and indicators
  4. Add the component SCSS file to your main SCSS file.
  5. Perhaps create a node--my_content_type--teaser.html.twig file to rearrange the teaser fields layouts for the slides (e.g. remove body text)
  6. Place the views block on the page where you want the carousel.

The Carousel ID is automatically built from the View and Views Block IDs (view.storage.id and view.current_display), so the carousel will automatically work with the carousel view and block.

One subtle or tricky element is that when twig loops through the views rows, it counts 1,2,3... But, JS counts 0,1,2... So, there is a non-obvious arithmetic statement in the code: "data-bs-slide-to="{{ loop.index-1 }}" (You don't want to spend a couple hours like I did trying to figure out why the bootstrap carousel doesn't loop - it just runs once and stops at the end).

Files are attached. You may need to adjust field names for your content types. Here is my twig.html override code that wraps my slide logos with a link to an external partner.

<article{{ attributes.addClass(classes) }}>

  {% block content %}
    <a href="{{ content.field_website_link.0['#url'] }}" target="_blank">
    <div{{ content_attributes }}>
      <h3{{ title_attributes }} class="text-center">
        {{ label }}
       </h3>
      {{ content|without('field_website_link') }}
    </div>
    </a>
  {% endblock %}
</article>

Remaining tasks

I can't claim that I've correctly added all the Aria tags for proper accessibility.

Aria Carousel Accessibility

πŸ“Œ Task
Status

Needs work

Version

5.0

Component

Documentation

Created by

πŸ‡ΊπŸ‡ΈUnited States tstermitz

Live updates comments and jobs are added and updated live.
  • views

    Involves, uses, or integrates with views. In Drupal 8 core, use the β€œVDC” tag instead.

Sign in to follow issues

Comments & Activities

  • Issue created by @tstermitz
  • πŸ‡ΊπŸ‡ΈUnited States tstermitz
  • πŸ‡ΊπŸ‡ΈUnited States tstermitz
  • πŸ‡ΊπŸ‡ΈUnited States tstermitz
  • πŸ‡ΊπŸ‡ΈUnited States tstermitz
  • Great work Tom, seems like it still needs a bit of a cleanup, that aside, not sure if we should ship with a SCSS file, but rather use Bootstrap classes and the style that Bootstrap does it: https://getbootstrap.com/docs/5.3/components/carousel/

    I've been working on a Carousel component for the 6.x version, I can share it soon and we can work together to possibly merge your work and backport the 6.x into 5.x

    Could you possibly provide a MR after some cleanups? thanks

  • Status changed to Needs work 5 months ago
  • πŸ‡ΊπŸ‡ΈUnited States tstermitz

    Thanks Sohail. I'm pretty good with SCSS, but don't claim to be a good twig programmer.

    Also, although I maintain my own websites with git, I confess I've never sent a merge request to Drupal... maybe you could pm me or help educate me on that.

    I pulled the carousel.scss file out to my own styles as you suggested. The BS default white makes it impossible to see the indicators and arrows, so most people will need their own colors and styles

    I cleaned up the view-carousel.twig file a little taking out the debugging code. I don't know all the Drupal coding standards so I'd appreciate any other suggestions. The Aria stuff gets pretty complicated to do correctly; or else just leave it as Bootstrap defaults.

    I did forget to mention how the Views Carousel gets invoked.... It needs a template over-ride file which merely imports the component:

    File: templates/views/views-view-unformatted--carousel.html.twig
    Contents: {% include "@tangodxrdx/carousel/view-carousel.twig" %}
    

    Here's the carousel code:

    <div id="carousel--{{ view.storage.id }}-{{ view.current_display }}" class="carousel slide" data-bs-ride="carousel" data-bs-wrap="true">
    
      <div class="carousel-indicators">
    {% for item in rows %}
        <button type="button"
          data-bs-target="#carousel--{{ view.storage.id }}-{{ view.current_display }}"
          data-bs-slide-to="{{ loop.index-1 }}"
          aria-label="arialabel-{{ item.content['#node'].label }}"
          {{ loop.first ? 'class="active"'}} {{ loop.first ? 'aria-current="true"' }}>
          </button>
    {% endfor %}
      </div>
    
      <div class="carousel-inner">
        {% for item in rows %}
          <div class="carousel-item {{ loop.first ? 'active' }} carousel--{{ view.storage.id }}-{{ view.current_display }}" data-bs-interval="5000" >
            {% block views_row %}
              {{ item.content }}
            {% endblock %}
          </div>
        {% endfor %}
      </div>
    
      <button class="carousel-control-prev" type="button"
      data-bs-target="#carousel--{{ view.storage.id }}-{{ view.current_display }}"
      data-bs-slide="prev" style="cursor:pointer">
        <span class="carousel-control-prev-icon"></span>
      </button>
      <button class="carousel-control-next" type="button"
      data-bs-target="#carousel--{{ view.storage.id }}-{{ view.current_display }}"
      data-bs-slide="next" style="cursor:pointer">
        <span class="carousel-control-next-icon"></span>
      </button>
    </div>
    
  • πŸ‡ΊπŸ‡ΈUnited States tstermitz
  • πŸ‡ΊπŸ‡ΈUnited States Amstercad

    I'm willing to help you, but I can't go ahead and learn 5.x code, (with Components, uggh, ...too old skool.), because I'm so focused on 6.x with SDC. SDC is the future.

    I cannot imagine my answer is immediately useful for you, however if you can get to Radix 6.x (ultra-special SDC Edition) I think I can be more helpful for you. For what it is worth, SDC is the future of Drupal front end theming, so go for it. If you want to ask why, I'll try to give you an answer, but until then, https://idiazroncero.com/en/certainties/component-based-design-using-sin...

  • πŸ‡ΊπŸ‡ΈUnited States tstermitz

    Thanks Amstercad. Your article is very interesting and explains the situation well.

    I guess my Radix 5 issue is useful as documentation or an example of how to do a carousel with views. It probably isn't necessary to add it to the Radix theme.

Production build 0.69.0 2024