Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#1 2024-03-16 10:42:45

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 4,742
Website

How do I iterate over a (…)-separated list in a string [resolved]

Oleg posted the following teaser in this thread but I don’t think it ever made it into the core:

<txp:list data='<txp:custom_field />' breakby='???'>
    <txp:item />
</txp:list>

essentially replacing rah_repeat.

Is there a built-in way to do this?

EDIT: There is: it works with txp:variable exactly as shown below. I had the wrong variable name in my code 🤦.

My concrete question is I want to output a list of items stored as a string separated by #-- in a txp variable.

<txp:variable name="index_tag_cats" breakby="#--" wraptag="ul" break="li" class="index-list" />

but I get nothing, I suppose because txp:variable isn’t a tag that produces a list.

The background is I wanted to create an alphabetic index of interleaved categories and tags. I’ve output a category_list and an smd_tag_list into two variables, concatenated the two, used a tiny bit of php to sort them and return an alphabetically sorted string of <a href="…">tag/category</a> items separated by #-- to a variable. That works great and now I just want to iterate over it to display it.

(BTW: if I use a separator like ### or ???, I get the following error: Warning: preg_split(): Unknown modifier ‘?’ Issue detected. It doesn’t matter which separator I use. Why? It doesn’t happen with #--, for example)


TXP Builders – finely-crafted code, design and txp

Offline

#2 2024-03-16 10:46:19

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

Re: How do I iterate over a (…)-separated list in a string [resolved]

I think I can answer the second part. With a repeated string like that, it’s probably treating the outer two chars as start and end preg delimiters, so when it encounters the one in the middle, it thinks it’s a mistake to use the delimiter mid-expression.

Might be wrong but that’s my best guess.

Last edited by Bloke (2024-03-16 10:48:45)


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

Online

#3 2024-03-16 11:06:10

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 4,742
Website

Re: How do I iterate over a (…)-separated list in a string [resolved]

Bloke wrote #336927:

I think I can answer the second part. With a repeated string like that, it’s probably treating the outer two chars as start and end preg delimiters, so when it encounters the one in the middle, it thinks it’s a mistake to use the delimiter mid-expression.

Might be wrong but that’s my best guess.

You may be right there. With two characters there’s no error, but would that then also be interpreted as start and end regex delimiters with nothing between?


TXP Builders – finely-crafted code, design and txp

Offline

#4 2024-03-16 11:07:40

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

Re: How do I iterate over a (…)-separated list in a string [resolved]

jakob wrote #336928:

You may be right there. With two characters there’s no error, but would that then also be interpreted as start and end regex delimiters with nothing between?

Probably. If you’re doing that, you’re better off using multiple different characters, ensuring the start and end at the very least are different, or a single character.

Last edited by Bloke (2024-03-16 11:08:00)


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

Online

#5 2024-03-16 11:09:28

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 4,742
Website

Re: How do I iterate over a (…)-separated list in a string [resolved]

txp:variable seems to have worked with a similar construction in this post, so maybe I have an error in my setup?

EDIT: I did, it works with txp:variable after all.

Should I delete this entire thread, or is the breakby problem worth trapping in the core? I can imagine people tripping over that.


TXP Builders – finely-crafted code, design and txp

Offline

#6 2024-03-16 11:30:36

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

Re: How do I iterate over a (…)-separated list in a string [resolved]

Glad you got it working. It’s valuable to keep the thread in case people have similar issues, imo.


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

Online

#7 2024-03-16 18:11:17

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

Re: How do I iterate over a (…)-separated list in a string [resolved]

If you need to split by ### or similar, breakby="/###/" should work.

Offline

#8 2024-03-16 20:20:57

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

Re: How do I iterate over a (…)-separated list in a string [resolved]

jakob wrote #336928:

With two characters there’s no error, but would that then also be interpreted as start and end regex delimiters with nothing between?

No, for cutting between characters there is a simpler breakby="" syntax.

Offline

#9 2024-03-17 06:43:23

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 4,742
Website

Re: How do I iterate over a (…)-separated list in a string [resolved]

etc wrote #336932:

If you need to split by ### or similar, breakby="/###/" should work.

Thanks, that works and makes sense.

etc wrote #336934:

No, for cutting between characters there is a simpler breakby="" syntax.

With “two characters”, I actually meant using breakby="##" but that produced unusual results. But thanks for the reminder about breakby="". With limit="1" it gets you the first character.


TXP Builders – finely-crafted code, design and txp

Offline

#10 2024-03-17 07:10:41

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 4,742
Website

Re: How do I iterate over a (…)-separated list in a string [resolved]

FWIW, this is my current working solution. The principle is:

  • get list of available tags in the format {tag title in lowercase}@@@{html_code} and store in a comma-separated variable
  • get list of available categories in the format {category title in lowercase}@@@{html_code} and store in a comma-separated variable
  • concatenate the variables in a new combined variable
  • sort concatenated variable
  • strip out the preceding titles from the the first part to leave {html_code}
  • output as interleaved index of tags and categories

And this is the code for that (improvements welcome!):

<txp:variable name="all_tags" trim>
<txp:smd_tag_list type="article" showall="1" wraptag="" break="," class="" trim>
    <txp:smd_tag_name escape="lower" />@@@<a href="/tag/<txp:smd_tag_name title="0" />" class="tag" itemprop="name">#<txp:smd_tag_name  /></a>
</txp:smd_tag_list>
</txp:variable>

<txp:variable name="all_cats" trim>
<txp:category_list break="," trim>
        <txp:category title escape="lower" />@@@<a href="/<txp:text item="category" escape="url,lower" />/<txp:category />" class="category" itemprop="name"><txp:category title /></a>
    </txp:category_list>
</txp:variable>

<txp:variable name="all_index_items" trim>
    <txp:variable name="all_tags" />,<txp:variable name="all_cats" />
</txp:variable>

<txp:php>
    global $variable;
    $index_items = explode(",", $variable['all_index_items']);
    sort($index_items);

    $arr = array();
    foreach ($index_items as $item) {
        list($key, $value) = explode("@@@", $item);
        $arr[] = $value;
    }

    $variable['all_index_items'] = join("@@@", $arr);
</txp:php>

<txp:variable name="all_index_items" breakby="/@@@/" wraptag="ul" break="li" class="index-list" />

That works nicely so far and the category and tag items can be styled nicely. Perfectly fine for a site with a reasonable number of tags and categories.

A few things I’ve not (yet) worked on:

  • Adding alphabetic intermediary headings – A, B, C, … – to the list. Something with breakform and if_different perhaps with the list item (<+>?). I have, of course, buried the relevant Item name in the code so can’t get just the first letter.
  • Adding counts. <txp:smd_tag_count> offers an easy way to add counts to the html code, but I’m not sure how to do the same with <category_list />.
  • Omitting unassigned tags and categories.

TXP Builders – finely-crafted code, design and txp

Offline

Board footer

Powered by FluxBB