1

I have this slideshow implementing to entries, which works except Dot navigation.

A count of Dots in navigations depends on manually inputing attributes and assigning numbers from 0...∞ ascendingly like this.

<ul>
    <li data-uk-slideshow-item="0"><a href=""></a></li>
    <li data-uk-slideshow-item="1"><a href=""></a></li>
    <li data-uk-slideshow-item="2"><a href=""></a></li>
</ul>

Actually, I limit(3) count of entries, so I know that there will be a certain number of dots. However, If there aren't any entries defined or only 1 entry defined, than I always get all three dots appeared, which don't function. So there MUST to be the exact number of dots as entries.

  • 1 Entry: 1 Dot
  • 2 Entires: 2 Dots
  • 3 Entries: 3 Dots

So I'm thinking to go with if condition or loop through entries, but with my attribute output with number increased by 1.

So far, I've started with if, because no need to loop ... and I don't know, if this is right way.

{# Display navigation if the condition is true #}
{% if craft.entries.section('handle').lightswitchHandle('1') is defined %}

<ul>
{# This is where I end up ... some comparission filter maybe ? #}
{% if craft.entries.section('handle').lightswitchHandle('1') %}
  <li data-uk-slideshow-item="0">
      <a href=""></a>
  </li>    
{% elseif craft.entries.section('handle').lightswitchHandle('1') %}
  <li data-uk-slideshow-item="1">
      <a href=""></a>
  </li>    
{% endif %} 
</ul>
{% endif %}

Update

<div id="food-slideshow" class="uk-switcher">
<div data-uk-slideshow>
    <span><a href="" data-uk-slideshow-item="previous">p</a></span>
    <span><a href="" data-uk-slideshow-item="next">n</a></span>

    {# Get the slides, store in variable called "slides" #}
    {% set slides = craft.entries.section('food').news('1').limit(3) %}

    {% if slides %}
        <ul class="uk-slideshow">
        {# Output slides, using the same "slides" variable #}    
        {# Loop through "news" with lightswitch on #}
        {% for slide in slides %}
            {# Entry type - Article #}
            {% if slides.type == 'article' %}
                {% include '_includes/components/food/news-article' %}
            {# Entry type - Person #}   
            {% elseif slides.type == 'person' %}
                {% include '_includes/components/food/news-person' %}
            {# Entry type - Recipe #}
            {% elseif slides.type == 'recipe' %}
                {% include '_includes/components/food/news-recipe' %}
            {% endif %}
            {% else %}
                <p>Any Text</p>
        {% endfor %}

        </ul>
    {% endif %}

{% if craft.entries.section('food').news('1') is defined %}
{# Output navigation, check length of "slides" variable #}
<ul class="uk-dotnav uk-dotnav-contrast uk-position-bottom uk-text-center">
     {% for i in 1..slides | length %}
         <li data-uk-slideshow-item="{{ i }}">
            <a href=""></a>
         </li>
     {% endfor %}
</ul>
{% endif %}

</div>

3
  • 1
    The second if statement ({% if craft.entries.section('food').news('1') is defined %}) is redundant. If the first statement evaluates to true, the second one will, as well – just have the {% if slides %} statement wrap all the markup (as in my example below) down to just before the final </div> tag, alternatively replace the second statement with an additional check for {% if slides %}. Will save you a DB query. Mar 8 '15 at 20:45
  • Also, exactly what does the "news(1)" part of the query do? Mar 8 '15 at 20:47
  • It's the lightswitch handle. Mar 9 '15 at 8:43
4

First, store your slides in a variable when you fetch them using craft.entries. Then, you can use the length property of that variable (which will be equal to the number of slides) to output your dots/navigation.

Full example:

{# Get the slides, store in variable called "slides" #}
{% set slides = craft.entries.section( 'yourSlideSection' ).limit( 3 ) %}

{% if slides %}
<ul class="slideshow">

    {# Output slides, using the same "slides" variable #}
    {% for slide in slides %}
    <li class="slide">[Your slide content here]</li>
    {% endfor %}

    {% if craft.entries.section('handle').lightswitchHandle('1') is defined %}
    {# Output navigation, check length of "slides" variable #}
    <ul class="nav">
         {% for i in 0..slides | length - 1 %}
         <li data-uk-slideshow-item="{{ i }}">
              <a href=""></a>
         </li>
         {% endfor %}
    </ul>
    {% endif %}

</ul>
{% endif %}

What the inner navigation loop does here, is to increment the variable i by one, each time the loop runs, until i is equal to the number of slides (slides | length). This means you'll always have exactly the same number of dots as slides. Inside the loop, the variable i is also used for the data attribute.

More on the Twig loop function here

13
  • I updated my question with implementation I have. Without {% if slides.type == 'article %} {% include '_includes/components/food/news-article' %} and so on, It works. But with it I get empty slides. There is something I did wrong. Mar 8 '15 at 20:30
  • When you loop through the slides, you do a check for slides.type. Should that be slide.type? Is the "type" property set to each slide, or the slideshow as a whole? Mar 8 '15 at 20:36
  • Also, what happens inside the templates you include is obviously not arbitrary – if you want to print any data from the individual slide, you'd have to target the "slide" (singular) variable inside those templates. If they however use another variable to output the data, e.g. "entry.title", you can either modify the templates, or just do {% include 'yourTemplate' with { 'entry' : slide } %} Mar 8 '15 at 20:52
  • Those slides are entries with types. So I want each slide have any types of entry when the condition is met. One slide - one entry type. I'm thinking now, If I shouldn't filter them randomly, because If first condition will be true, than first entry type in first If statement will be print. And that may be quiet often. Hmmm. But anyway, I corrected from slides to slide, which I had that set previously and didn't work, because I skipped to update slide one {% include 'file' %} with. So from that reason I set it to slides. But It is working GREAT!! THANK YOU! Mar 9 '15 at 8:53
  • 1
    My pleasure. The potato variable is actually created within the for tag – which I guess can be a bit confusing, but it's very similar to how a PHP foreach loop works, i.e. foreach ( $potatoes as $potato ) {}. You'll notice that PHP uses the "as" keyword instead of "in", and that the position of the array variable ("potatoes") and the iterated value ("potato") is reversed compared to Twig – but its the exact same thing. Mar 9 '15 at 14:21
2

I came across this post while attempting to solve a similar problem myself. Here is my solution (I am sure it could be refactored some) using Bootstrap 4 Beta and a Matrix field. This includes the indicators and the next/prev button. I wanted to make sure if the client added more photos to the carousel, it would scale properly. I wouldn't suggest more than 5 slides, though.

{% if entry.carousel | length %}
<div class="container-fluid quotes p-0 hidden-sm-down">
  <div id="quotesCarousel" class="carousel slide" data-ride="carousel" data-interval="6000" >

  <div class="carousel-inner" role="listbox">
    {% set carousel_count = 0 %}
    {% for block in entry.carousel %}
      {% set loopIndex = loop.index %}
      {% switch block.type %}
        {% case 'carouselSegment' %}
          {% set carousel_count = loopIndex %}
          {% set image = block.image.first %}
            <div class="carousel-item {% if loopIndex == 1 %}active{% endif %}">
              <div class="carousel-caption d-none d-md-block align-items-center">
                <h3><em>{{block.mainContent}}</em></h3>
                <h2 class="py-3">{{block.subContent}}</h2>
                <h4>{{block.contentSource}}</h4>
              </div>
              <img class="d-block img-fluid" src="{{image.getUrl()}}" alt="{{image.title}}">
            </div>
      {% endswitch %}
    {% endfor %}
  </div>

  <ol class="carousel-indicators">
    {% for i in 1..carousel_count %}
    <li data-target="#quotesCarousel" data-slide-to="{{i}}" class="{% if i == 1 %}active{% endif %}"></li>
    {% endfor %}
  </ol>

  <a class="carousel-control-prev" href="#quotesCarousel" role="button" data-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="carousel-control-next" href="#quotesCarousel" role="button" data-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>

  </div>
</div>
{% endif %}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.