Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#1 2020-08-05 08:28:02

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,269
Website GitHub

Alternating category output

I have a list of testimonials from two groups of people. Each testimonial is an article in a pageless section, with body as the testimonial text, title as the person’s name/role, and category1 indicates the ‘type’ of testimonial; whether it’s from a customer or a company.

I’d like to pull out a random selection of 3 or 4 testimonials from either type but I’d like to make sure they are interleaved alternately. Viz:

customer->company->customer->company, or
company->customer->company->customer

Using a traditional rand() might pull out three company testimonials in a row then one customer testimonial. So the first issue is to get an even split based on the limit. Then I need to factor in interleaving them.

The reason for doing this is that the type is used as a class name which hooks into some CSS to colour them according to type. I’d like the list to appear ‘zebra striped’ by type.

It’s part of a shortcode, so there are boring bits like variables that are set based on yield and so forth. But here’s the pertinent part:

<txp:article_custom section="testimonials-text" category='<txp:variable name="type" />' wraptag="div" class="testimonials" limit='<txp:yield name="limit" default="4" />' sort="rand()">
<div class="<txp:category1 />">
<txp:body />
-- <txp:title />
</div>
</txp:article_custom>

That of course works but doesn’t give me the result I want.

The only way I can think of doing this is to do two <txp:article_custom> calls – one for each type – and stash them in variables. Then do a loop of some kind (how? PHP, presumably) and alternate over each tag in the loop body, incrementing the offset each time.

Sounds like a lot of faff so I wondered if anyone had any clever tips on how I might approach this using tags or evaluate magic.


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#2 2020-08-05 10:39:19

etc
Developer
Registered: 2010-11-11
Posts: 5,053
Website GitHub

Re: Alternating category output

I think you could register strtok function and use it along these lines:

<txp:variable name="company">
<txp:article_custom section="testimonials-text" category="company" limit='<txp:yield name="limit" default="4" />' sort="rand()" break="¤">
<div class="company">
<txp:body />-- <txp:title />
</div>
</txp:article_custom>
</txp:variable>

<txp:article_custom section="testimonials-text" category="customer" limit='<txp:yield name="limit" default="4" />' sort="rand()">
<txp:if_first_article>
<txp:evaluate query='string(strtok(<txp:variable name="company" escape="quote" />, "¤"))' />
<txp:else />
<txp:evaluate query='string(strtok("¤"))' />
</txp:if_first_article>
<div class="customer">
<txp:body />-- <txp:title />
</div>
</txp:article_custom>

Probably, CSS order could work too, but create a discrepancy between the visual and DOM orders.

Offline

#3 2020-08-06 15:41:50

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,269
Website GitHub

Re: Alternating category output

Oleg, thank you. I haven’t had a chance to test this out. It looks suitably ingenious and I have no clue from glancing at the code how it might work. I’ll give it a grilling later.

Just one further observation that came to light as I was trying something out in this shortcode. Here’s the slightly modified version of the shortcode.

<txp:article_custom section="testimonials-text" category='<txp:variable name="type" />' wraptag="div" class="testimonials" limit='<txp:yield name="limit" default="3" />' sort="rand()">
<blockquote class="<txp:category1 />">
<txp:body />
<footer>
— <cite><txp:title /></a></cite>
</footer>
</blockquote>
</txp:article_custom>

I’m using that in two ways:

  1. To output a random subset of testimonials on various pages.
  2. To output all testimonials – in separate groups so the interleaving isn’t of concern – on the actual /testimonials page.

Fair enough. On the /testimonials page I want them to display in a grid and I use a class to control that – grid. So I decided I wanted to add an attribute to my shortcode that would either add the grid class or not:

<txp::testimonials type="customer" limit="999" class="grid" />

I went ahead and added the <txp:yield> to my shortcode but made a mistake. Here’s what I added inside <txp:article_custom>’s attribute list:

class="testimonials <txp:yield name="class" default="" />"

See my error? I left the double quotes around the class attribute value. I didn’t spot it at first. When I hit refresh I of course expected the ‘grid’ class to appear in my page. Worst case, it wouldn’t work. What I got was a spinning ‘loading’ icon in the browser tab and then, a handful of seconds later:

Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 258048 bytes) in txplib_misc.php on line 3042

Baffling. It seems that wrapping double quotes around <txp:yield> inside any <txp:article_custom> attribute triggered this bizarre result. There aren’t that many testimonials – maybe 20 so far in total. Whether this is specific to the host or the situation I’m not sure. Just thought I’d mention it as it seems to be tripping the parser out.


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#4 2020-08-06 16:13:06

etc
Developer
Registered: 2010-11-11
Posts: 5,053
Website GitHub

Re: Alternating category output

Have you tested it in an article body? Then it’s possible that <txp:body /> of this article provokes an infinite loop when processing <txp::testimonials />. The loop depth should be limited (about 15 by default), but it still could eat much memory.

With <txp:body /> removed, double quotes per se just give me some tag mismatch warning and wrong article list. But with <txp:body /> the max execution time is reached. Weird

Offline

#5 2020-08-06 16:32:20

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,269
Website GitHub

Re: Alternating category output

etc wrote #325202:

Have you tested it in an article body?

Yes. The /testimonials page is a sticky landing page that pretty much has some fluffy text in its body and then the two calls to the <txp::testimonials> shortcode. So the shortcode is being called from a body tag in the sticky article, which is then calling in a bunch of (pageless) content via <txp:article_custom> and rendering their own body tags in its container.

Nothing special in the pageless body copy. It’s just text.

Weird indeed, as you say. Found it odd that it only exhibited this behaviour if I (incorrectly) used double quotes around parsable tag content.

Last edited by Bloke (2020-08-06 16:34:44)


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#6 2020-08-06 16:40:23

etc
Developer
Registered: 2010-11-11
Posts: 5,053
Website GitHub

Re: Alternating category output

It looks like the opening <txp:article_custom> tag is not detected (since it’s bad-formed) and the parser processes <txp:body /> in the embedding article context. Which results in recursive <txp::testimonials /> calls and things go west.

Offline

#7 2020-08-06 17:26:04

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,269
Website GitHub

Re: Alternating category output

etc wrote #325204:

It looks like the opening <txp:article_custom> tag is not detected (since it’s bad-formed) and the parser processes <txp:body /> in the embedding article context. Which results in recursive <txp::testimonials /> calls and things go west.

That would make sense. Nothing we can do about my stupidity!


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

Board footer

Powered by FluxBB