Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
How to offer both PhotoSwipe v5 and Lightbox2 in a Jekyll project

Offering both PhotoSwipe v5 and Lightbox2 in a static site

This documents an example of how to offer both PhotoSwipe v5 and Lightbox2 in one project.

Notes

PhotoSwipe

PhotoSwipe helps to make the photo clickable, and then it'll zoom for the user and create a gallery, you can call the photo _include:

PhotoSwipe Setup
<div class="photoswipe-gallery">
  {% include elements/photo.html
      url="/assets/images/picture-01.jpg"
      thumb_width="200" thumb_height="230
      full_width="400" full_height="200"
      caption="Caption will show when the photo is enlarged" alt="Alt shows if the photo cannot be shown"
  %}
</div>

To create a "nested" PhotoSwipe gallery (where one gallery sites inside a larger gallery), please view the examples below:

Nested PhotoSwipe Gallery Markdown Example
Here's the "surrounding" PhotoSwipe gallery with pictures of an alpaca, bobcat, chipmunk, dolphin, ermine, and fox:

<div class="photoswipe-gallery"> <!-- This is the start of the "surrounding" gallery -->
  <div class="text-center">
    {% include elements/photo.html
        url="https://i.imgur.com/Y3ibubf.jpg"
        thumb_height="225" caption="Alpaca"
        full_width="720" full_height="960"
    %}
    {% include elements/photo.html
        url="https://i.imgur.com/8K0L9VU.jpg"
        thumb_height="225" caption="Bobcat"
        full_width="1600" full_height="1200"
    %}
    {% include elements/photo.html
        url="https://i.imgur.com/Sd4hAvW.jpg"
        thumb_height="225" caption="Chipmunk"
        full_width="1280" full_height="852"
    %}
  </div>

Here's an "inner" PhotoSwipe gallery. The photos in the "inner" gallery _are not_ included in the "surrounding" gallery. And photos from the "surrounding" gallery _are not_ included in the "inner" gallery.

The pictures in the "inner" gallery include pictures of a zebu, yak, and xerus:

  <div class="text-center inner-photoswipe-gallery"> <!-- This is the start of the "inner" gallery -->
    {% include elements/photo.html
        url="https://i.imgur.com/WNa7Bxx.jpg"
        thumb_height="80" caption="Zebu"
        full_width="1180" full_height="520"
        child_selector_class="inner-photoswipe"
    %}
    {% include elements/photo.html
        url="https://i.imgur.com/nR8jJEM.jpeg"
        thumb_height="80" caption="Yak"
        full_width="5184" full_height="3456"
        child_selector_class="inner-photoswipe"
    %}
    {% include elements/photo.html
        url="https://live.staticflickr.com/65535/51222953803_bb61bb4368_b.jpg"
        thumb_height="80" caption="Xerus"
        full_width="1000" full_height="667"
        child_selector_class="inner-photoswipe"
    %}
  </div> <!-- This is the end of the "inner" gallery -->

And now we're back to the "surrounding" gallery:

  <div class="text-center">
    {% include elements/photo.html
        url="https://i.imgur.com/pk5308U.jpg"
        thumb_height="225" caption="Dolphin"
        full_width="530" full_height="765"
    %}
    {% include elements/photo.html
        url="https://i.imgur.com/wdg3S.jpg"
        thumb_height="225" caption="Ermine"
        full_width="316" full_height="474"
    %}
    {% include elements/photo.html
        url="https://i.imgur.com/1VkY1R4.jpg"
        thumb_height="225" caption="Fox"
        full_width="540" full_height="405"
    %}
  </div>
</div> <!-- This is the end of the "surrounding" gallery -->

<!-- Include the below script IN ADDITION to the surrounding gallery's script, so there should be two calls to the activation script total -->
<script
  src="/assets/js/activate_photoswipe.js"
  type="module"
  class="photoswipe-activation"
  gallery-selector=".inner-photoswipe-gallery"
  child-selector=".inner-photoswipe"
></script>
Nested PhotoSwipe Gallery HTML Example
<p>Here’s the “surrounding” PhotoSwipe gallery with pictures of an alpaca, bobcat, chipmunk, dolphin, ermine, and fox:</p>

<div class="photoswipe-gallery"> <!-- This is the start of the "surrounding" gallery -->
  <div class="text-center">
    <a class="photoswipe" href="https://i.imgur.com/Y3ibubf.jpg" target="_blank" data-pswp-width="720" data-pswp-height="960">
      <img class="image" src="https://i.imgur.com/Y3ibubf.jpg" width="170" alt="Alpaca">
      <div class="invisible caption">Alpaca</div>
    </a>
    <a class="photoswipe" href="https://i.imgur.com/8K0L9VU.jpg" target="_blank" data-pswp-width="1600" data-pswp-height="1200">
      <img class="image" src="https://i.imgur.com/8K0L9VU.jpg" width="300" alt="Bobcat">
      <div class="invisible caption">Bobcat</div>
    </a>
    <a class="photoswipe" href="https://i.imgur.com/Sd4hAvW.jpg" target="_blank" data-pswp-width="1280" data-pswp-height="852">
      <img class="image" src="https://i.imgur.com/Sd4hAvW.jpg" width="340" alt="Chipmunk">
      <div class="invisible caption">Chipmunk</div>
    </a>
  </div>

  <p>Here’s an “inner” PhotoSwipe gallery. The photos in the “inner” gallery <em>are not</em> included in the “surrounding” gallery. And photos from the “surrounding” gallery <em>are not</em> included in the “inner” gallery.</p>

  <p>The pictures in the “inner” gallery include pictures of a zebu, yak, and xerus:</p>

  <div class="text-center inner-photoswipe-gallery"> <!-- This is the start of the "inner" gallery -->
    <a class="inner-photoswipe" href="https://i.imgur.com/WNa7Bxx.jpg" target="_blank" data-pswp-width="1180" data-pswp-height="520">
      <img class="image" src="https://i.imgur.com/WNa7Bxx.jpg" width="150" alt="Zebu">
      <div class="invisible caption">Zebu</div>
    </a>
    <a class="inner-photoswipe" href="https://i.imgur.com/nR8jJEM.jpeg" target="_blank" data-pswp-width="5184" data-pswp-height="3456">
      <img class="image" src="https://i.imgur.com/nR8jJEM.jpeg" width="100" alt="Yak">
      <div class="invisible caption">Yak</div>
    </a>
    <a class="inner-photoswipe" href="https://live.staticflickr.com/65535/51222953803_bb61bb4368_b.jpg" target="_blank" data-pswp-width="1000" data-pswp-height="667">
      <img class="image" src="https://live.staticflickr.com/65535/51222953803_bb61bb4368_b.jpg" width="100" alt="Xerus">
      <div class="invisible caption">Xerus</div>
    </a>
  </div> <!-- This is the end of the "inner" gallery -->

  <p>And now we’re back to the “surrounding” gallery:</p>

  <div class="text-center">
    <a class="photoswipe" href="https://i.imgur.com/pk5308U.jpg" target="_blank" data-pswp-width="530" data-pswp-height="765">
      <img class="image" src="https://i.imgur.com/pk5308U.jpg" width="155" alt="Dolphin">
      <div class="invisible caption">Dolphin</div>
    </a>
    <a class="photoswipe" href="https://i.imgur.com/wdg3S.jpg" target="_blank" data-pswp-width="316" data-pswp-height="474">
      <img class="image" src="https://i.imgur.com/wdg3S.jpg" width="150" alt="Ermine">
      <div class="invisible caption">Ermine</div>
    </a>
    <a class="photoswipe" href="https://i.imgur.com/1VkY1R4.jpg" target="_blank" data-pswp-width="540" data-pswp-height="405">
      <img class="image" src="https://i.imgur.com/1VkY1R4.jpg" width="300" alt="Fox">
      <div class="invisible caption">Fox</div>
    </a>
  </div>
</div> <!-- This is the end of the "surrounding" gallery -->

<!-- Include the below script IN ADDITION to the surrounding gallery's script, so there should be two calls to the activation script total -->
<script
  src="/assets/js/activate_photoswipe.js"
  type="module"
  class="photoswipe-activation"
  gallery-selector=".inner-photoswipe-gallery"
  child-selector=".inner-photoswipe"
></script>

Lightbox2

Using Lightbox2 in order to make photos clickable is also an option, but this is not recommended (use PhotoSwipe instead).

Lightbox2 Setup
{% include elements/photo.html
    url="/assets/images/picture-01.jpg"
    thumb_width="200" thumb_height="230
    lightbox_gallery="Lightbox Gallery Name" type="lightbox2"
    caption="Caption will show when the photo is enlarged" alt="Alt shows if the photo cannot be shown"
%}

Lastly...

  • If a caption is given, but not an alt, then the caption is used as both a caption and an alt. If an alt is given, but no caption, then there is no caption present on the photo. And if nothing is given, then there's neither a caption nor an alt on the photo.
  • The full_width and full_height represent the pixel sizes of the original image. If neither a thumb_width or a thumb_height is provided, then the thumb photo will be the same size as the original photo. If both a thumb_width and thumb_height are provided, then the image will warp to fit both parameters.

Example Files

activate_photoswipe.js

This file is going to be called from the bottom of every HTML page that has any type of photoswipe photo on it.

import PhotoSwipeLightbox from './photoswipe_lightbox.esm.min.js'

const photoswipeActivations = document.getElementsByClassName('photoswipe-activation')

for (let activation = 0; activation < photoswipeActivations.length; activation++) {
  const gallerySelector = photoswipeActivations[activation].getAttribute('gallery-selector')
  const childSelector = photoswipeActivations[activation].getAttribute('child-selector')

  const options = {
    gallerySelector: gallerySelector,
    childSelector: childSelector,
    pswpModule: '/assets/js/photoswipe.esm.min.js'
  }

  const lightbox = new PhotoSwipeLightbox(options)

  lightbox.on('uiRegister', function () {
    lightbox.pswp.ui.registerElement({
      name: 'custom-caption',
      order: 9,
      isButton: false,
      appendTo: 'root',
      html: 'Caption Text',
      onInit: (el, pswp) => {
        lightbox.pswp.on('change', () => {
          const currentSlideElement = lightbox.pswp.currSlide.data.element
          const hiddenCaption = currentSlideElement.querySelector('.caption')
          const customCaptionElements = document.getElementsByClassName('pswp__custom-caption')
          let captionHTML = ''

          if (hiddenCaption === '' || hiddenCaption === null) {
            for (let counter = 0; counter < customCaptionElements.length; counter++) {
              customCaptionElements[counter].classList.add('invisible')
            }
          } else {
            for (let counter = 0; counter < customCaptionElements.length; counter++) {
              customCaptionElements[counter].classList.remove('invisible')
            }

            if (currentSlideElement) {
              captionHTML = hiddenCaption.innerHTML
            }
          }

          el.innerHTML = captionHTML
        })
      }
    })
  })

  lightbox.init()
}

photo.html

Below is the piece of HTML that should be added to the bottom of HTML pages to call the activate_photoswipe.js file.

<!-- Javascript scripts only... these go at the bottom of the HTML page -->
<script
  src="/assets/js/activate_photoswipe.js"
  type="module"
  class="photoswipe-activation"
  gallery-selector=".photoswipe-gallery"
  child-selector=".photoswipe"
></script>

_includes/photo.html

Here is the include file that Jekyll uses to determine whether to show a Lightbox photo or a PhotoSwipe photo.

With this, any final images that have the photoswipe class are turned into a photoswipe gallery. If a different selector is provided, then it becomes part of a separate gallery (so you can have multiple galleries on one page.

Any final images that have the lightbox2 class are turned into lightbox2 photos.

{% if include.caption %}
  {% if include.alt %}
    {% assign caption = include.caption %}
    {% assign alt = include.alt %}
  {% else %}
    {% assign caption = include.caption %}
    {% assign alt = include.caption %}
  {% endif %}
{% else %}
  {% if include.alt %}
    {% assign caption = "" %}
    {% assign alt = include.alt %}
  {% else %}
    {% assign caption = "" %}
    {% assign alt = "" %}
  {% endif %}
{% endif %}

{% if include.thumb_width %}
  {% assign thumb_width = 'width="' | append: include.thumb_width | append: '"' %}
{% else %}
  {% assign thumb_width = "" %}
{% endif %}

{% if include.thumb_height %}
  {% assign thumb_height = 'height="' | append: include.thumb_height | append: '"' %}
{% else %}
  {% assign thumb_height = "" %}
{% endif %}

{% if include.type == "lightbox2" %}

{% if caption == "" %}
<a class="lightbox2" href="{{ include.url }}" data-lightbox="{{ include.lightbox_gallery }}">
{% else %}
<a class="lightbox2" href="{{ include.url }}" data-lightbox="{{ include.lightbox_gallery }}" title="{{ caption }}">
{% endif %}

{% else %}

{% if include.child_selector_class %}
  {% assign child_selector_class = include.child_selector_class %}
{% else %}
  {% assign child_selector_class = "photoswipe" %}
{% endif %}

<a class="{{ child_selector_class }}" href="{{ include.url }}" target="_blank" data-pswp-width="{{ include.full_width }}" data-pswp-height="{{ include.full_height }}">

{% endif %}

{% if alt == "" %}
<img src="{{ include.url }}" {{ thumb_width }} {{ thumb_height }}>
{% else %}
<img src="{{ include.url }}" {{ thumb_width }} {{ thumb_height }} alt="{{ alt }}">
{% endif %}

{% unless include.type == "lightbox2" %}
  {% unless caption == "" %}
  <div class="invisible caption">{{ caption }}</div>
  {% endunless %}
{% endunless %}

</a>

assets/css/_site.scss

Here's any extra CSS that's required:

.invisible {
  display: none;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment