Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#1 2021-05-12 09:40:49

demoncleaner
Plugin Author
From: Germany
Registered: 2008-06-29
Posts: 168
Website

Sort articles based on multiple dates defined in one custom_field

I am having difficulties constructing a schedule page and I hope somebody could point me in the right direction.
I have a couple of events (articles) that each hold an unlimited number of dates in ONE custom field.

The schedule page is shown on a per month basis.
I managed to display the articles only if they match the current month.
So the only problem right now is the day.

I am using rah_repeat to do some splitting jobs and it gives me the different days on which each event is happening.

Let´s say I have an event “A” that has the following days (dates)

05, 09

And another event “B” that has

05, 12

At the moment in my <txp:article_custom> I am obviously getting this:

Day 05 Title of event A
Day 09 Title of event A
Day 05 Title of event B
Day 12 Title of event B

Because it will always go through one article (and its dates) and then the next one.
But what I want is this:

Day 05
Title of event A
Title of event B
Day 09
Title of event A
Day 12
Title of event B

For sure I need <txp:if_different> at a certain point but that alone would not do the trick I guess.
Is there a way to re-order the output afterwards by a variable?

I played around with smd_calendar in that context already but the problem is that I have many different dates and I am not reffering to the articles posted date at all. I also feel that I cannot feed the <txp:smd_article_event> with the different dates because they are not processed at that stage and they could not be unlimited.

Any idea on how that could be done would be highly appreciated.

Offline

#2 2021-05-12 11:20:39

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 10,358
Website GitHub

Re: Sort articles based on multiple dates defined in one custom_field

This is a hardcore conundrum.

I wondered at first if the new <txp:article_custom> aggregate fields attribute in recent Txp’s might help but that would probably GROUP BY, which is not what you want.

There may be some clever stuff you could employ with <txp:evaluate> inside a container or the global evaluate attribute. That could maybe evaluate the custom field and do something with it if certain conditions are met. Not quite sure how, though.

At the expense of a little more processing/computation, can you split it into a few phases?

Phase 1: use <txp:article_custom> to fetch a list of articles ordered by custom_n (your dates). In its container, append dates that have not been seen before and store the corresponding article ID. Also, perhaps make a note of the min and max date (so you have something to iterate over in a minute – might need to keep separate track of min/max year and the min/max month in that year separately).

Phase 2: iterate over dates from min to max (uhhh, somehow _ I thought rah_repeat’s range might help but I’m not sure how it can iterate over both months and years – it would need two nested tags, one for years, one for months) and supply the month value to another <txp:article_custom>. In that container, output the date as a heading, and lookup the date in your set of variables obtained in phase 1. Grab the corresponding article ID(s). Use a <txp:article_custom> to grab all the id values and then display the information from each article how you want.

It’s ugly and time-consuming and expensive. PHP might be neater.

The problem is compounded by the following issues:

  • Your date custom field has a list of dates, including performance start times. You need to strip off the times to get just the dates in phase 1.
  • Your article Posted dates – which Txp would normally use to build its list of articles over which to iterate (and where you could use <txp:if_different> etc) may not bear any relation to the performance dates in the custom field.

If you could guarantee that the article Posted date represented the date and time of the first performance and the custom field then listed additional dates, that might make things easier. That’s what smd_calendar assumes is the case for multiple/spanned events. But you still have the problem that an individual article might have an event in some future year/month that is outside the range of your other performances, and thus won’t be represented by the iterative article_custom tag.

I’m sure smd_calendar can help here but it’s been a while since I’ve used it. On your individual landing pages for an event, you can use <smd::article_event> to list the dates/extra dates etc. That’s all good.

On your page where you want to list events by date, the <smd::calendar> tag gives you the ability to iterate over all the days in a month. You don’t have to render the things as a traditional calendar table but use cellform to rewire the output into a ul / li list. In your cellform, the plugin knows what dates apply for each event (I think) and it should take dates from the nominated custom fields into account if you tell the tag to consider them. Maybe it doesn’t do that, but I thought that was the idea. I’ll have to refresh my memory.

The only downside is that the plugin can only iterate a month at a time. So if you want to display more than one month’s worth of events on a single page you need multiple <smd::calendar> tags – one for each month – and divert each tag to use the same form to render the list of events in each month. You probably want to do that anyway to split the page up into years/months with headings.

I’ll have a play on my test site and see if I can get something working.


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 2021-05-12 11:52:12

demoncleaner
Plugin Author
From: Germany
Registered: 2008-06-29
Posts: 168
Website

Re: Sort articles based on multiple dates defined in one custom_field

Don´t know what to say… Thank you so much on giving such a detailed answer to my problem.

It’s ugly and time-consuming and expensive. PHP might be neater.

I absolutely agree. When you say PHP would be neater, you mean you would just solve this inside your page template with <txp:php> or in other ways?

The only downside is that the plugin can only iterate a month at a time.

Not a problem in my case. I am using a GET variable “month” in the URL when calling the schedule page. It will then only show articles that run in the given month. If no month was given it shows the current month. That´s already working fine.

If you could guarantee that the article Posted date represented the date and time of the first performance and the custom field then listed additional dates, that might make things easier.

I theoretically could. But I am also stumbeling over the fact that smd_calender can only take a limited amount (2) of extra dates. At least that´s how I understand the help text of the plugin.

Another idea would be to use the date and time picker from glz_custom_fields. The input of data would be a bit more intuitive but the problem with this is, that I would have to predefined the number of total dates. Which I also could live with if thats much easier. I would then maybe hide the extra fields with some javascript in the backend until they are needed. Most of the events will not hold more than 3 dates anyway.

But I guess that would not make any difference to the problems I am facing here.

Offline

#4 2021-05-12 11:56:44

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 10,358
Website GitHub

Re: Sort articles based on multiple dates defined in one custom_field

Just tried it. smd_calendar and smd_article_event does all this for free on your behalf. No need to overcomplicate it or try to use core <txp:article_custom> tags or <txp:php> etc.

Since I don’t think the delimiter can be modified (I haven’t tried that yet) if the sticking point is that you want people to be able to list dates like this:

2021-05-14 18:00
2021-06-03 12:00
2021-06-22 12:00

instead of:

2021-05-14 18:00, 2021-06-03 12:00, 2021-06-22 12:00

Then you have some options:

Compromise

Tell people to enter dates like this:

2021-05-14 18:00,
2021-06-03 12:00,
2021-06-22 12:00

and then trim="," off commas just in case they add a trailing one (which would break <smd::article_event> as it would think there’s an extra date following then find a blank one).

Intervene

Write a tiny plugin that intercepts the save process and adds commas between each date when an event is saved (if they’re missing). Or use a glz_custom_fields macro that does likewise. Not sure if they operate at point of save or point of access, I can’t remember.

That way, people can enter the extra dates with or without commas, each on a newline or not, and your plugin/macro formats it how the plugin needs on save or when used.

Then you can use the power of the plugin to slice and dice the dates however you want.

EDIT: the only size limit is due to Txp’s internal maximum of 255 chars per custom field. If you’re using glz_custom_fields as a textarea, there’s only a theoretical limit to the number of dates you can list).

Last edited by Bloke (2021-05-12 12:00:59)


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

#5 2021-05-12 12:03:13

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 10,358
Website GitHub

Re: Sort articles based on multiple dates defined in one custom_field

I have hit a plugin issue with it throwing: ‘A non well formed numeric value encountered’ error in debugging mode. I’ll need to track that down. Might be my usage of the plugin during testing (I did it really quickly) or it could be a bug. Doesn’t seem to affect the output too much but I don’t like warnings like that!


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 2021-05-12 12:04:39

demoncleaner
Plugin Author
From: Germany
Registered: 2008-06-29
Posts: 168
Website

Re: Sort articles based on multiple dates defined in one custom_field

Thanks. I overcame all the problems with how people can input the dates and delimiters and seperators etc. already. I am pretty sure that this is not a problem.
I can easily generate an output of the custom_field like this:

2021-05-14 18:00,
2021-06-03 12:00,
2021-06-22 12:00

I might have misinterpreted the datefields attribute. Let me have another Go on this.

Offline

#7 2021-05-12 12:10:41

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 10,358
Website GitHub

Re: Sort articles based on multiple dates defined in one custom_field

demoncleaner wrote #330117:

I am also stumbeling over the fact that smd_calender can only take a limited amount (2) of extra dates.

Nope. Use extrafield="custom_7" (or whatever) to specify a list of arbitrary dates in that field. The plugin has the concepts of:

  • stepfield for regular recurring events on a schedule.
  • multi-day events that run for a range of days (e.g. an exhibition). This is denoted using Posted and Expiry of an event (article). Or datefields if you prefer.
  • skipfield if you want to cancel or otherwise omit any dates in a range or recurring pattern (e.g. due to illness or meteor strike).
  • holidays for national holidays that auto-skip events if they fall on those days.
  • extrafield for allowing you to list arbitrary dates. This could be rescheduled events after a closure or because they were skipped, or you could just use it to list the actual set of dates on which the event occurs.
  • datefields if you want to override the article’s posted and expiry dates. This is handy if you want to retain usage of the article’s posted and expiry for other purposes but want people to be able to enter the first/last date (or range) of the event in a pair of custom fields.

Hope that helps demystify things a bit. Sorry the plugin help is a little.. dense :)

Last edited by Bloke (2021-05-12 12:15:21)


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

#8 2021-05-12 12:11:42

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 10,358
Website GitHub

Re: Sort articles based on multiple dates defined in one custom_field

demoncleaner wrote #330120:

I might have misinterpreted the datefields attribute.

Ah yes. See my previous post. datefields has a specific meaning. You want to use extrafield.


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

#9 2021-05-12 13:08:04

demoncleaner
Plugin Author
From: Germany
Registered: 2008-06-29
Posts: 168
Website

Re: Sort articles based on multiple dates defined in one custom_field

Great! Sorting works perfect like this.
Nice feature that you can then access via <txp:posted/> the “faked” posted date(s).

People in Germany will not want to enter dates like 2021-05-14. So I thought how I could overcome this issue? But I just realized that smd_calendar seems to understand both formats.
If I put the dates in my custom_field like dd-mm-yyyy it still works fine. A bit surprising but great! =)

The only problem left is that in my custom_field I wated to hold not just the dates but also some extra info (like a unique ticket link) that needs to come with each date.

Maybe I need a second custom-field as a textarea that also holds per line that extra info and then I need to do some counting (if that even works) to give the right extra info depending on the iterated date. Not such a nice solution though. I cannot see any better option right now. =(

Offline

#10 2021-05-12 13:21:46

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 10,358
Website GitHub

Re: Sort articles based on multiple dates defined in one custom_field

Yes dates will work any way round if they are parsable by PHP (which means they need to be in English if using day names and next or last etc). However, is 3/5/21 3rd May or 5th March? That’s the only good thing about year first: it’s unambiguously interpreted.

As to assigning a unique code to each date, that is indeed tricky. If you’re going to do that I’d recommend wrapping it in a delimiter so it’s easy to filter out before you pass the date list to smd_calendar. E.g.

2021-05-14 18:00 {ab16da0f472b},
2021-06-03 12:00 {8419de8a55},
2021-06-22 12:00 {9b064721aa7}

Not ideal. But easier than faffing with matching values across fields. And less prone to mistakes.


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

#11 2021-05-12 13:36:24

demoncleaner
Plugin Author
From: Germany
Registered: 2008-06-29
Posts: 168
Website

Re: Sort articles based on multiple dates defined in one custom_field

I need to take a walk and think about how to solve this.
It would be a shame if I could not use smd_calendar because it solves so many things already out of the box. Just the last bit is tricky.

One little thing I just saw:
When using English date format I still seem to not get the Weekday with
<txp:posted format="%D"/>

Whereas b,m,d are all working fine.

Offline

#12 2021-05-12 14:11:27

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 10,358
Website GitHub

Re: Sort articles based on multiple dates defined in one custom_field

demoncleaner wrote #330125:

It would be a shame if I could not use smd_calendar because it solves so many things already out of the box. Just the last bit is tricky.

There has to be a solution. Who is the custodian of the ticket link and ‘extra info’ that is date specific? Do you have any control over what these links are, or is it handled by a third-party ticketing service? Can the extra info be derived somehow from the date? Can it be looked up? e.g. defined by some administrative task when a show is scheduled?

For example, they decide to show The Amazing Adventures of Demoncleaner at the venue. Somebody somewhere has to get hold of these links and additional info (presumably the price is the same, but maybe matinee performances attract a different price to other times) because they’ll need to be put into Txp somewhere.

So can the data be fetched/put somewhere else at this point? Maybe:

  • The Excerpt or a dedicated custom field of the event’s article.
  • A special variable, like in adi_variables perhaps.
  • A hidden snippet article in a pageless section.
  • A database table via a small back-end dashboard plugin.
  • Obtained from an API somehow: like something returned in a JSON format that is parsable by Txp when an event article is created (or whatever).

Effectively, if this can be a one-off exercise per show, you’re asking administrators to make up a mapping of date => other info in some location in a standard format. So that when a date is clicked you can look it up, match it to the show name (or article ID or whatever) and thus retrieve the additional info.

The right solution will depend on where the data is coming from, how much influence you have over it, and how savvy the people are who are compiling the info.

When using English date format I still seem to not get the Weekday with
<txp:posted format="%D"/>

%A is the weekday, isn’t it?

Also, according to the PHP strftime() docs which is the function that smd_calendar piggybacks:

Not all conversion specifiers may be supported by your C library, in which case they will not be supported by PHP’s strftime(). Additionally, not all platforms support negative timestamps, so your date range may be limited to no earlier than the Unix epoch. This means that %e, %T, %R and, %D (and possibly others) – as well as dates prior to Jan 1, 1970 – will not work on Windows, some Linux distributions, and a few other operating systems.


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