Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#1 2020-04-06 11:40:05

david@druna.cz
Member
Registered: 2017-07-25
Posts: 41

Dynamic article sorting

Right now I have the articles getting sorted by a custom field like so <txp:article_custom sort=” CAST …/>. I would like to be able to sort the articles dynamically by an arbitrary logic, best defined in PHP. The sort attribute value is static and doesn’t get interpreted when I put in PHP nor a tag.

Use case: One article represents an ongoing class. Each class happens on a particlar time and day of the week. I need to sort the classes based on which one is currently the closest. For instance on Wednesday the Thursday class will be before the Monday one but on Sunday it will be reversed.

Solutions that came to my mind I would like to avoid:
1. I could have a database job updating the sorting custom fields periodically.
2. I could probably somehow run the txp:article_custom from PHP as many times as there are articles and each time take just one article to have them separated and then sort them.

Preferred solution:
Get the articles to PHP and be able able manipulate them and inspect them freely.

Last edited by david@druna.cz (2020-04-06 11:40:46)

Offline

#2 2020-04-06 14:52:49

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

Re: Dynamic article sorting

That’s an interesting conundrum. Choosing the article ‘closest’ to a given date/time is something I’d even struggle with in PHP so if you can find an answer, please let us know the solution as there might be something we can tweak in core to help out with the tags.

That said, you can run article/article_custom in PHP like this:

<txp:php>
echo article_custom(array('sort' => 'Posted desc', 'att2' => 'val2', ...));
</txp:php>

An approach I have used in the past is a two-stage system:

<txp:variable name="the_ids" escape="trim">
   <txp:article_custom sort="some custom sort" break=",">
      <txp:article_id />
   </txp:article_custom>
</txp:variable>

Doesn’t have to be article_custom there as the wrapper. Could be anything; PHP, plugins, and so on. That allows you to build a list of article IDs in a variable that you can then plug into a second <txp:article_custom />:

<txp:article_custom id='<txp:variable name="the_ids" />' wraptag="div" blah blah>
   ...article formatting tags here...
</txp:article_custom>

That’s handy if you’re manipulating search results, for example from plugins. I’ve used it with smd_featured and etc_query. You can use the first tag to grab the search result IDs from one or more plugins in the order you want them to appear (e.g. “Featured first”), construct a variable containing a comma-separated list of IDs in that order, then throw them at <txp:article_custom> to render them in that custom order.

Does that give you anything to go on?


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

#3 2020-04-06 16:19:04

david@druna.cz
Member
Registered: 2017-07-25
Posts: 41

Re: Dynamic article sorting

The computation is non trivial, that’s the reason the only place I can see it happening is in PHP. And we’re not even counting in that the class is happening only in a given range of dates and in that range it can have particular dates it’s not happening on. On top of that a class can happen on more than one days/times of the week.

For me all this information would be stored in a custom field of an article. I’m used to putting more configurations into a single custom textarea type field in a JSON format. That config would contain the date the classes start, the date when they end, the days of the week, the time it start and ends, dates when it doesn’t happen etc.

Now I can see two options:

1. Using your method of getting the ids first – For each of the ids I can get the config custom field with a subsequent <txp:article_custom> and another simple inline output rule to get just that. Then I parse the config, decide and possibly add the id to a list of the displayed ones in the computed order. Finally feed it all to a final <txp:article_custom>.

2. A way that I was planning before I read your post – I use <txp:article_custom> to get all articles in question and let it use a wrapper form that gets the config as well as the rendered article by calling the rendering form. The wrapper form then encodes the config and the rendered article into a JSON object. The set of those objects produced then get parsed by the PHP script, grabbing the pair of config and output for each article, computing based on the config and echoing the rendered output if appropriate.

Now I like the 1. more, there’s less encoding and parsing JSON. Thanks!

Right now I cannot see a way tags could make this easier. Being able to get articles as objects in PHP could be nice though. With name, body, custom field as properties. Rendering would be a matter of passing the object and the name of the rendering form to a function or calling a method on the object with the rendering form name as argument.

Last edited by david@druna.cz (2020-04-06 16:29:52)

Offline

Board footer

Powered by FluxBB