Textpattern CMS support forum
You are not logged in. Register | Login | Help
- Topics: Active | Unanswered
Simulate a FOR...EACH loop
I’ve used Twitter’s Bootstrap to rebuild my personal site. One of the elements I want to use is the image carousel to feature particular photos on the homepage, building it dynamically from images in the category of “carousel”. This means that I don’t know the number of images to use might change each time.
Here’s the demo coding for the carousel:
<div id="myCarousel" class="carousel slide">
<ol class="carousel-indicators">
<!-- Carousel indicators -->
<li data-target="#myCarousel" data-slide-to="0" class="active"></li>
<li data-target="#myCarousel" data-slide-to="1"></li>
<li data-target="#myCarousel" data-slide-to="2"></li>
</ol>
<!-- Carousel items -->
<div class="carousel-inner">
<div class="active item"><img src="..."></div>
<div class="item"><img src="..."></div>
<div class="item"><img src="..."></div>
</div>
<!-- Carousel nav -->
<a class="carousel-control left" href="#myCarousel" data-slide="prev">‹</a>
<a class="carousel-control right" href="#myCarousel" data-slide="next">›</a>
</div>
</div>
You can see that there are two places where loops are required – firstly, to create the correct number of carousel indicators and the secondly to display each individual image ‘item’.
The second loop to build the ‘slide’ for each image is easier using the available <txp:images>
tag or <txp:smd_query>
but I’m having trouble figuring out how to do the first one:
- I can find out the total number of images in the correct category using
<typ:smd_query>
, - I can manipulate a counter using
<txp:adi_calc>
, - but I don’t know how to stop the counter when it reaches the maximum. It feels like a job for
<txp:smd_each>
, but I think<txp:smd_each>
needs the full set of variables before processing (which I don’t know how to do!).
Note that this has to be two loops, because they reside in completely separate blocks.
If was going to use pseudo-code, it would be something like:
$n=[number of images]
$counter=1
while $counter <= $n
[output my code]
$counter++
endwhile
It feels like the answer is close, but each time I think I have the solution it just slips away and I’m stuck in a dead-end.
Offline
Re: Simulate a FOR...EACH loop
etc_query is really good at this kind of thing (obtaining datasets and reformatting them).
Offline
Re: Simulate a FOR...EACH loop
mrdale wrote:
etc_query is really good at this kind of thing (obtaining datasets and reformatting them).
I agree. :) First extract your images using the format you need, and store them in some <txp:variable name="images" />
:
<txp:variable name="images">
<txp:images wraptag="div" break="" class="carousel-inner">
<div class="item"><img src="<txp:image_url />"></div>
</txp:images>
</txp:variable>
Now pass it to etc_query
to construct the first block:
<div id="myCarousel" class="carousel slide">
<!-- Carousel indicators -->
<txp:etc_query data='<txp:variable name="images" />' query="div/div" wraptag="ol" class="carousel-indicators">
<li data-target="#myCarousel" data-slide-to="{#ind}"></li>
</txp:etc_query>
<!-- Carousel items -->
<txp:variable name="images" />
<!-- Carousel nav -->
<a class="carousel-control left" href="#myCarousel" data-slide="prev">‹</a>
<a class="carousel-control right" href="#myCarousel" data-slide="next">›</a>
</div>
</div>
But I guess your carousel will use js, so jQuery might suit your needs better.
Offline
Re: Simulate a FOR...EACH loop
OK, I’ve just been reading through the etc_query
documentation – it look very flexible, but it also looks like I have a steep learning curve ahead of me! But I like the idea of just getting all of my data, including the output HTML, into a single variable once (I was thinking along the lines of multiple passes). I didn’t realise that we could traverse a single Textpattern variable like that and just pull out the interesting bits.
I’m not much of a programmer any more, but I’m happy to try out the example and test it out. The total number of images will be limited (say, no more than 4) but I want to pull out 4 random images out of the total.
Thanks for your help, this gives me a great starting point to start testing later this afternoon.
Offline
Re: Simulate a FOR...EACH loop
Variables are very cute. Actually, there is an “almost” core solution, you need a plugin only to increment some <txp:variable name="counter" />
. I use <txp:etc_query data="{?counter|0|+1}" />
here, but I guess one can go with adi_calc
:
<txp:variable name="images">
<txp:images wraptag="div" break="" class="carousel-inner">
<div class="item"><img src="<txp:image_url />"></div>
<!-- increment counter variable by 1 or initialize it if not defined -->
<txp:etc_query name="counter" data="{?counter|0|+1}" globals="variable" />
<txp:variable name="indicators">
<txp:variable name="indicators" />
<li data-target="#myCarousel" data-slide-to='<txp:variable name="counter" />'></li>
</txp:variable>
</txp:images>
</txp:variable>
<div id="myCarousel" class="carousel slide">
<ol class="carousel-indicators">
<!-- Carousel indicators -->
<txp:variable name="indicators" />
</ol>
<!-- Carousel items -->
<txp:variable name="images" />
<!-- Carousel nav -->
<a class="carousel-control left" href="#myCarousel" data-slide="prev">‹</a>
<a class="carousel-control right" href="#myCarousel" data-slide="next">›</a>
</div>
Offline
Re: Simulate a FOR...EACH loop
etc wrote:
{#ind}
dumbest question yet
…is there an exhaustive list and explanation of the stuff you can put inside the curly braces?
for example, I know what the # does but what does ind do? does it echo “ind” or does it have some special reseved function?
Last edited by mrdale (2013-06-25 17:50:48)
Offline
Offline
Re: Simulate a FOR...EACH loop
Oh, duh. thanks
Last edited by mrdale (2013-06-25 17:57:59)
Offline
Re: Simulate a FOR...EACH loop
Thanks for your help- Oleg’s solution worked perfectly (well, so far – only 2 images). The only modification I had to make was to test for the first image, so that it could get the “active” class. I used <txp:smd_if>
for this purpose.
If you’re interested in what it looks like, my website is here. Note that the Twitter feed broke, so I need to incorporate the suggested changes to <txp:arc_twitter>
. And actually add some fresh content. And fix the contact form. And a few other things …
Offline
Re: Simulate a FOR...EACH loop
aslsw66 wrote:
The only modification I had to make was to test for the first image, so that it could get the “active” class. I used
<txp:smd_if>
for this purpose.
I guess you could use <txp:if_variable name="counter" value="0" />
to detect the first image.
That makes me think that some kind of <txp:counter />
and <txp:if_counter />
tags could be useful inside loop structures, and would partially replace <txp:if_first_... />
tags.
Offline
Re: Simulate a FOR...EACH loop
Stef has seduced me in to believing he has the answer for everything. It’s hard to remmeber that Textpattern can actually function without one of his plugins.
Offline
Offline