Loading...
 
Skip to main content

History: PageBanner

Source of version: 2 (current)

Copy to clipboard
            {HTML(wiki="0")}
<style>
#community-promotion-carousel {
  --promotion-control-width: 2.75rem;
}
#community-promotion-carousel .carousel-control-prev,
#community-promotion-carousel .carousel-control-next {
  width: var(--promotion-control-width);
}
#evoludata-promotion-panel {
  background-color: var(--bs-body-bg);
  color: var(--bs-body-color);
  border-color: var(--bs-border-color);
  box-sizing: border-box;
  padding: .75rem 3.25rem;
}
#evoludata-promotion-layout {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  width: 100%;
  min-width: 0;
}
#evoludata-promotion-logo {
  flex: 0 0 110px;
  width: 110px;
  height: 100px;
  padding: .5rem;
}
#evoludata-promotion-logo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
#evoludata-promotion-copy {
  min-width: 0;
}
#evoludata-promotion-title {
  margin: 0 0 .25rem;
  font-size: clamp(1.25rem, 2.2vw, 1.6rem);
  line-height: 1.1;
}
#evoludata-promotion-description {
  margin: 0 0 .25rem;
  font-size: .95rem;
  line-height: 1.2;
}
#evoludata-promotion-products {
  margin: 0 0 .35rem;
}
#evoludata-promotion-actions .btn {
  padding: .25rem .6rem;
}
@media (max-width: 575.98px) {
  #evoludata-promotion-panel {
    padding: .75rem 2.75rem;
  }
  #evoludata-promotion-layout {
    gap: .75rem;
  }
  #evoludata-promotion-logo {
    flex-basis: 72px;
    width: 72px;
    height: 72px;
    padding: .25rem;
  }
  #evoludata-promotion-title {
    font-size: 1.05rem;
  }
  #evoludata-promotion-description,
  #evoludata-promotion-products {
    font-size: .78rem;
    line-height: 1.15;
  }
  #evoludata-promotion-actions {
    gap: .3rem !important;
  }
  #evoludata-promotion-actions .btn {
    padding: .2rem .4rem;
    font-size: .72rem;
  }
}
@media (prefers-reduced-motion: reduce) {
  #community-promotion-carousel .carousel-item {
    transition: none !important;
  }
}
</style>

<div
  id="community-promotion-carousel"
  class="carousel slide mb-3"
  data-bs-ride="carousel"
  data-bs-interval="8000"
  data-bs-pause="hover"
  role="region"
  aria-roledescription="carousel"
  aria-label="Upcoming event and EvoluData promotion"
>
  <div class="carousel-inner" aria-live="polite">
    <div
      id="calendar-event-slide"
      class="carousel-item active"
      role="group"
      aria-roledescription="slide"
      aria-label="1 of 2"
    >
{HTML}

{rss url="https://tiki.org/tiki-calendars_rss.php" max="1" date="1" desc="1" author="1" showtitle="1" ticker="1" sortBy="publication_date" sortOrder="ASC" tplWiki="rss_gabarit" refresh="360"}

{HTML(wiki="0")}
    </div>

    <div
      id="evoludata-promotion-slide"
      class="carousel-item"
      role="group"
      aria-roledescription="slide"
      aria-label="2 of 2"
    >
      <section
        id="evoludata-promotion-panel"
        class="alert alert-light bg-white border overflow-hidden d-flex align-items-center"
        aria-labelledby="evoludata-promotion-title"
      >
        <div id="evoludata-promotion-layout">
          <a
            id="evoludata-promotion-logo"
            href="https://evoludata.com/?utm_source=dev-tiki&amp;utm_medium=carousel&amp;utm_campaign=open-source-sites"
            target="_blank"
            rel="noopener noreferrer"
            class="d-flex align-items-center justify-content-center rounded bg-light"
            aria-label="Visit EvoluData"
          >
            <img
              src="https://evoludata.com/display22"
              alt="EvoluData"
              width="110"
              height="100"
              decoding="async"
            >
          </a>

          <div
            id="evoludata-promotion-copy"
            class="flex-grow-1 text-start"
          >
            <h2
              id="evoludata-promotion-title"
              class="text-primary fw-bold"
            >
              Open Source solutions
            </h2>

            <p id="evoludata-promotion-description">
              Custom development, consulting, and reliable support for critical Open Source platforms
            </p>

            <p
              id="evoludata-promotion-products"
              class="fw-semibold"
            >
              TikiWiki &middot; Cypht &middot; Dolibarr
            </p>

            <div
              id="evoludata-promotion-actions"
              class="d-flex flex-wrap gap-2"
            >
              <a
                class="btn btn-primary"
                href="https://evoludata.com/en/Solutions?utm_source=dev-tiki&amp;utm_medium=carousel&amp;utm_campaign=open-source-sites&amp;utm_content=solutions"
                target="_blank"
                rel="noopener noreferrer"
              >
                Explore our solutions
              </a>

              <a
                class="btn btn-outline-primary"
                href="https://evoludata.com/en/Contact-Us?utm_source=dev-tiki&amp;utm_medium=carousel&amp;utm_campaign=open-source-sites&amp;utm_content=contact"
                target="_blank"
                rel="noopener noreferrer"
              >
                Contact us
              </a>
            </div>
          </div>
        </div>
      </section>
    </div>
  </div>

  <button
    class="carousel-control-prev"
    type="button"
    data-bs-target="#community-promotion-carousel"
    data-bs-slide="prev"
    aria-label="Previous slide"
  >
    <span
      class="carousel-control-prev-icon btn btn-dark"
      aria-hidden="true"
    ></span>
  </button>

  <button
    class="carousel-control-next "
    type="button"
    data-bs-target="#community-promotion-carousel"
    data-bs-slide="next"
    aria-label="Next slide"
  >
    <span
      class="carousel-control-next-icon btn btn-dark"
      aria-hidden="true"
    ></span>
  </button>
</div>
{HTML}

{JQ()}
var $scope = $('#calendar-event-slide').find(
    '.upcoming-event-banner, .rsslist'
);

function extractCalItemId(url) {
    if (!url) return null;

    try {
        url = decodeURIComponent(url);
    } catch (e) {}

    var match = url.match(
        /(?:^|[?&])calitemId=([^&#]+)/i
    );

    return match ? match[1] : null;
}

$scope.find('a:not([target="_blank"])').each(function () {
    var $link = $(this);
    var href = $link.attr('href');

    if (
        !href
        || /tiki-calendar_export_ical\.php/i.test(href)
    ) {
        return;
    }

    var id = extractCalItemId(href)
        || extractCalItemId(
            $link.attr('data-href')
        );

    if (id) {
        $link.attr(
            'href',
            'https://tiki.org/tiki-calendar_export_ical.php'
                + '?export=y&calendarItem='
                + encodeURIComponent(id)
        );
    }
});

$scope.find('a[target="_blank"]').each(function () {
    var $link = $(this);
    var href = $link.attr('href');

    if (
        !href
        || !/%3F|%3D|%26|%2F/i.test(href)
    ) {
        return;
    }

    try {
        $link.attr(
            'href',
            decodeURIComponent(href)
        );
    } catch (e) {}
});

var carousel = document.getElementById(
    'community-promotion-carousel'
);

var inner = carousel
    && carousel.querySelector('.carousel-inner');

var eventSlide = document.getElementById(
    'calendar-event-slide'
);

var promotionSlide = document.getElementById(
    'evoludata-promotion-slide'
);

var promotion = document.getElementById(
    'evoludata-promotion-panel'
);

var controls = carousel
    && carousel.querySelectorAll(
        '.carousel-control-prev, .carousel-control-next'
    );

var frame = 0;

function findEventCard(scope) {
    return scope.querySelector(
        '.upcoming-event-banner, .rsslist > .alert'
    ) || scope.firstElementChild;
}

function measureCard(card) {
    if (!card) return null;

    var height = Math.ceil(
        card.getBoundingClientRect().height
    );

    if (!height) return null;

    var style = window.getComputedStyle(card);

    return {
        card: height,
        total: height
            + parseFloat(style.marginTop || 0)
            + parseFloat(style.marginBottom || 0)
    };
}

function eventMeasurements() {
    var card = findEventCard(eventSlide);
    var measurements = measureCard(card);

    if (measurements) {
        return measurements;
    }

    var clone = eventSlide.cloneNode(true);

    clone.removeAttribute('id');
    clone.className = 'carousel-item active';
    clone.setAttribute('aria-hidden', 'true');

    $(clone).css({
        position: 'absolute',
        visibility: 'hidden',
        pointerEvents: 'none',
        display: 'block',
        width: inner.clientWidth + 'px',
        height: 'auto'
    });

    inner.appendChild(clone);

    card = findEventCard(clone);
    measurements = measureCard(card);

    clone.remove();

    return measurements;
}

function syncPromotionHeight() {
    cancelAnimationFrame(frame);

    frame = requestAnimationFrame(function () {
        var measurements = eventMeasurements();

        if (!measurements) {
            return;
        }

        promotion.style.height =
            measurements.card + 'px';

        inner.style.height =
            measurements.total + 'px';
    });
}

if (
    carousel
    && inner
    && eventSlide
    && promotionSlide
    && promotion
) {
    if (!eventSlide.querySelector('.rssitem')) {
        eventSlide.classList.remove('active');
        promotionSlide.classList.add('active');

        $(controls).addClass('d-none');

        carousel.removeAttribute(
            'data-bs-ride'
        );

        if (window.bootstrap) {
            bootstrap.Carousel.getOrCreateInstance(
                carousel,
                {interval: false}
            ).pause();
        }
    } else {
        $(window).on(
            'load resize',
            syncPromotionHeight
        );

        $(carousel).on(
            'slide.bs.carousel slid.bs.carousel',
            syncPromotionHeight
        );

        $(eventSlide).find('img').on(
            'load',
            syncPromotionHeight
        );

        if (window.ResizeObserver) {
            new ResizeObserver(
                syncPromotionHeight
            ).observe(
                findEventCard(eventSlide)
            );
        }

        if (
            document.fonts
            && document.fonts.ready
        ) {
            document.fonts.ready.then(
                syncPromotionHeight
            );
        }

        if (
            window.matchMedia(
                '(prefers-reduced-motion: reduce)'
            ).matches
            && window.bootstrap
        ) {
            bootstrap.Carousel.getOrCreateInstance(
                carousel,
                {interval: false}
            ).pause();
        }

        syncPromotionHeight();
    }
}
{JQ}