Shortcode for bootstrap 4 carousel using page resources

Frontmatter:

resources:
    - src: carousel/slide1.jpg
      name: slide
      title: slide 1 
    - src: carousel/slide2.jpg
      name: slide 
      title: slide 2  
    - src: carousel/slide3.jpg
      name: slide 
      title: slide 3 

shortcode carousel.html:

{{ $slides := ( $.Page.Resources.Match "slide*" ) }}

<div class="section" id="carousel">
  <div class="container">
    {{ with .Get "title" }}
      <div class="title">
        <h4>{{ . }}</h4>
      </div>      
    {{ end }}
    <div class="row justify-content-center">
      <div class="col">
        <div id="carouselIndicators" class="carousel slide" data-ride="carousel">
          <ol class="carousel-indicators">
            {{ range $key, $value := $slides }}
              {{ $active := "" }}
              {{ if eq $key 0 }}
                {{ $active = "active" }}
              {{ end }}
              <li data-target="#carouselIndicators" data-slide-to="{{ $key }}" class="{{ $active }}"></li>
            {{ end }}
          </ol>
          <div class="carousel-inner" role="listbox">
          {{ range $key, $value := $slides }}
            {{ $active := "" }}
            {{ if eq $key 0 }}
              {{ $active = "active" }}
            {{ end }}
              <div class="carousel-item {{ $active}} ">
                  <img class="d-block" src="{{ .RelPermalink }}" alt="{{ .Name }}">
                <div class="carousel-caption d-none d-md-block">
                  <h5>{{ .Title }} </h5>
                </div>
              </div>
            {{ end }}
          </div>
          <a class="carousel-control-prev" href="#carouselIndicators" role="button" data-slide="prev">
            <i class="now-ui-icons arrows-1_minimal-left"></i>
          </a>
          <a class="carousel-control-next" href="#carouselIndicators" role="button" data-slide="next">
            <i class="now-ui-icons arrows-1_minimal-right"></i>
          </a>
        </div>
      </div>
    </div>
  </div>
</div>

Usage:

{{% carousel title="optional" %}}

Hope it helps :slight_smile:

7 Likes

Do you have example site to show this?

Given I have a folder with images 001.png, 002.png, …, 020.png.
How can I use this?

Sure, go to this page and search for carousel: https://brunoamaral.eu/page/elements/

May I ask you to adapt the Carousel with captions from https://getbootstrap.com/docs/4.5/components/carousel/?

The code above already uses the title of each slide as a caption.

I guess I don’t understand the difference between the title if the whole div (From {{ with .Get "title" }}) and <h5>{{ .Title }} </h5>.
Which one is the title of the short code and which is the title of the slide.

It makes sense the top is from he first and the 2nd for the image itself.

1 Like

The code doesn’t work on the current Hugo (Version 0.79.0).
It seems this code doesn’t generate the li elements:

<ol class="bootstrapiso carousel-indicators">
            {{ range $key, $value := $slides }}
              {{ $active := "" }}
              {{ if eq $key 0 }}
                {{ $active = "active" }}
              {{ end }}
              <li data-target="#carouselIndicators" data-slide-to="{{ $key }}" class="bootstrapiso {{ $active }}"></li>
            {{ end }}
          </ol>
          <div class="bootstrapiso carousel-inner" role="listbox">
          {{ range $key, $value := $slides }}
            {{ $active := "" }}
            {{ if eq $key 0 }}
              {{ $active = "active" }}
            {{ end }}
              <div class="bootstrapiso carousel-item {{ $active}} ">
                  <img class="bootstrapiso d-block" src="{{ .RelPermalink }}" alt="{{ .Name }}">
                <div class="bootstrapiso carousel-caption d-none d-md-block">
                  <h5>{{ .Title }} </h5>
                </div>
              </div>
            {{ end }}
          </div>

That’s odd, because it looks like the one I have running right now with 0.79.

{{ $slides := ( $.Page.Resources.Match "slide*" ) }}
		{{ with .Get "title" }}
				<h4>{{ . }}</h4>
		{{ end }}
		<div class="row justify-content-center">
			<div class="col">
				<div id="carouselIndicators" class="carousel slide" data-ride="false" data-interval="false" data-touch="true" data-pause="hover" >
					<ol class="carousel-indicators">
						{{ range $key, $value := $slides }}
							{{ $active := "" }}
							{{ if eq $key 0 }}
								{{ $active = "active" }}
							{{ end }}
							<li data-target="#carouselIndicators" data-slide-to="{{ $key }}" class="{{ $active }}"></li>
						{{ end }}
					</ol>
					<div class="carousel-inner" role="listbox">
					{{ range $key, $value := $slides }}
						{{ $active := "" }}
						{{ if eq $key 0 }}
							{{ $active = "active" }}
						{{ end }}
							<div class="carousel-item {{ $active}} ">
									<img class="d-block" src="{{ .RelPermalink }}" alt="{{ .Name }}" loading="lazy">
								<div class="carousel-caption d-none d-md-block">
									<h5>{{ .Title }} </h5>
								</div>
							</div>
						{{ end }}
					</div>
					<a class="carousel-control-prev" href="#carouselIndicators" role="button" data-slide="prev">
						<i class="now-ui-icons arrows-1_minimal-left"></i>
					</a>
					<a class="carousel-control-next" href="#carouselIndicators" role="button" data-slide="next">
						<i class="now-ui-icons arrows-1_minimal-right"></i>
					</a>
				</div>
			</div>
		</div>

Could it be something tricky with the Forty theme?
It just seems that generation of the elements is wrong.

yes it could be related to that. Do you have any code you can share?

Well,
The Forty theme doesn’t have Bootstrap built in.
Hence I added Isolated Bootstrap (See How to isolate bootstrap CSS and JavaScript to a part of the html page and How to Isolate Bootstrap 4.4.1 CSS to Avoid Conflicts).

Then I just used your code inside a shortcode.
The output wasn’t as expected.

If you want more code let me know how to contact you.
I’d be happy to see how it could be solved!

That is the problem.

I glanced over the two links you showed and it looks like they create a new css class where bootstrap gets “hosted”.

You can try to change my code to include that new class, it might work. With such a big change to the initial structure it’s no wonder you are facing issues. And I would be worried that this might just be the tip of the iceberg in terms of conflicts.

My suggestion, try to find a standalone slideshow, that does not need bootstrap, and adapt the html i used to see if it works.

I did add the bootstrapiso class to your code.
It shows the slides, yet the nav controls and the indicators are not aligned with the slide itself.
Something about the positioning doesn’t work well.

Unfortunately I haven’t find a standalone slider with the nav controls, indicators and captions as in the Bootstrap carousel.

take a look at https://splidejs.com/

you may have to make some compromises in terms of what you need and what can be achieved with just the time and development you have at hand.

2 Likes