Filtering a query by day of week

I have a ACF field of type date_time called “day_time_start” on a custom post type called “program”
I would like to display a widget that display’s Today’s Programs.
The idea is to loop all programs and show the once where the day_time_start filed happens to be on today’s day of the week (Monday, Tuesday etc).
This is the query I have came up with. But I always get no items even though there should be programs showing:

<If loop exists type=program orderby_field=day_time_start order=asc custom_date_field=day_time_start format="l" custom_date_field_compare=equal custom_date_field_value=today >
    <Loop>
      <div class="single-program">
        <a href="{Field url}" class="title"><Field title /></a><br />
        <span class="times"><Field acf_date_time=day_time_start format="g:i a"/></span>
      </div>
    </Loop>  
   <Else />
      There are no programs scheduled for today.
  </If>

Anyone can see why this query is not working?
PS: I tried current for the custom_date_field_value and I tried to add formatting to get only the week of the day but I still get no items and I am not certain if the formatting of the current or of today does work either.
Thank you

Hi Atef,

Just to clarify, are you seeing “There are no programs scheduled for today.” or nothing at all?

Hey @atef, welcome to the forum! Great use of L&L there. I think the main issue here is that you’re using the query parameter format (which doesn’t exist) whereas I imagine you should be using custom_date_field_format according to the docs. Regarding the value of that parameter, I see you’ve written "l", but is that the actual format of your underlying ACF date_time field? The docs seem to suggest that the default format of that ACF field is "Y-m-d H:i:s":

custom_date_field_format - For custom date field query, specify the date format of the field value - Default is “Ymd”; For date-time field, set “Y-m-d H:i:s”.

Even if you only care about checking the day of the week, you’ve got to tell L&L the full format of the field so that it knows how to read the field’s value and compare it properly.

The only other thing I’m seeing is that you’ve written custom_date_field_value=today but the docs say:

custom_date_field_value - Filter by given custom date field value, or current

I wouldn’t be surprised if today also works, but I’d stick to what’s noted in the docs to be sure.

By the way @Birkeholm, thanks for jumping in here, I see you’ve been super helpful chiming in on threads here lately and it’s really nice to have you here. I’ve been handing off support work to my colleagues lately but it’s so great to see helpful capable L&Lers jumping in to help when people have issues. Keep up the amazing work :slight_smile:

1 Like

Thank you @benjamin and @Birkeholm. Yes I see the message "There are no programs scheduled for today.” instead of the programs scheduled for that day.
The data stored in the field day_time_start is in the format “l g:i a” As I just need to store the day of the week and the time of start. in the query I want all the programs that have Monday as day of week.
Is there a way to filter by just the day of the week portion of the data?

I’m pretty sure custom_date_field_value=current is always going to just use today’s date, not today’s day. So it makes sense that that wouldn’t work.

For testing purposes, maybe try custom_date_field_value=monday and see if that displays all your events that take place on a Monday. If it does, then you’ll need to dynamically render today’s day using the Date tag with something like custom_date_field_value="{Date format='l'}"

If that doesn’t work, you’ll want to try using the Loop tag’s attributes instead since those are more flexible (albeit somewhat less performant) compared to query parameters. These can accept the same Comparisons as the If tag so you might be looking at something like

<If loop exists post_type=program field=day_time_start field_compare=includes field_value="{Date format='l'}" sort_field=day_time_start sort_type=date sort_date_format="l g:i a" sort_order=asc>

You’ll also notice that I swapped out orderby_field for sort_field since I don’t think orderby_field is going to work right with a date field, although it’s worth a shot. If that still doesn’t work, you’ll need to break that down into its components to identify which part might be causing your issue.

Unfortunately none of those variations worked. Not even hardcoding the custome value to Monday as an example.
So I have to break the code into 2 loops and do the condition by comparing the 2 text values of day of the week.
Here is my code below.
Please note how I couldn’t find in the docs a way to read to total number of items in a list. So I had to make a counter variable so I can check if I have any items. Could you improve this code a bit?
Thank you

<Set name=num_programs>0</Set>
  <List name=todays_programs>
    <Loop type=program >
      <Set name=todays_date><Field acf_date_time=day_time_from format="l" /> </Set>
      <If variable=todays_date is value="{Date format='l'}">
        <Item><Field id /></Item>
        <Set name=num_programs><Math><Get name=num_programs />+1</Math></Set>
      </If>
    </Loop>  
  </List>
  

  <If variable=num_programs is_not value="0" >
    <Loop type=program id="{Get list=todays_programs}" orderby_field=day_time_from order=asc>
      DISPLAY MY INFORMATION HERE 
    </Loop>  
  <Else />
    <div class="no-programs">
      There are no programs scheduled for today.
    </div>
  </If>
</div>
1 Like

I don’t think compromising on performance with the list variable is necessary in this case, but I’ll address that in another post in a minute. For starters, a quick note about your list-based approach.

That’s a smart approach using the Math tag, but I don’t think you’d need to, since you could just check whether the loop exists with something like this:

<List name=todays_programs>
    <Loop type=program >
      <If check="{Field acf_date_time=day_time_from format='l'}" is value="{Date format='l'}">
        <Item><Field id /></Item>
      </If>
    </Loop>  
  </List>

<If list=test_list exists>
    <Loop type=program id="{Get list=todays_programs}" orderby_field=day_time_from order=asc>
      DISPLAY MY INFORMATION HERE 
    </Loop>  
  <Else />
    <div class="no-programs">
      There are no programs scheduled for today.
    </div>
  </If>

Just so you’re aware for future reference, if you did need to check the number of items in a list, you could use the various loop variables to get the number you’re looking for.

Back to the original issue in this thread, I think your first approach is a better way to go about this since you’re not looping through all your data twice. But you’re running into issues so we need to troubleshoot it to identify where the issue lies. I’ve realized that this thread is a great case study about how to troubleshoot things in L&L, so I’m going to walk through how I approach it. I’m going to do that in a separate post so that I can maybe link people to it if necessary in the future.

You’ve got all the right ideas, but once you’ve established that you’re not inventing any tags or attributes and you’re following the correct syntax described in the docs (as you are), the next step in troubleshooting an L&L template is to break it down into smaller and smaller pieces until you figure out exactly which part of the template isn’t working as you expected.

Here’s how I would do that in your case. As a reminder, this is the template we’re starting with that isn’t working.

<If loop exists post_type=program field=day_time_start field_compare=includes field_value="{Date format='l'}" sort_field=day_time_start sort_type=date sort_date_format="l g:i a" sort_order=asc>
    <Loop>
      <div class="single-program">
        <a href="{Field url}" class="title"><Field title /></a><br />
        <span class="times"><Field acf_date_time=day_time_start format="g:i a"/></span>
      </div>
    </Loop>  
   <Else />
      There are no programs scheduled for today.
  </If>

For starters, I tried removing the extra stuff that isn’t really necessary for what we’re testing: the divs, the custom field display, and the sorting options on our loop. I also changed the dynamic value {Date format='l'} to a simple static value of Monday for testing purposes. After all, the first thing we need to do is make sure that we’re getting the data in the first place, then we can worry about organizing and styling it. So when I strip all that away, I’m left with:

<If loop exists post_type=program field=day_time_start field_compare=includes field_value="Monday">
  <Loop><p><Field title /></p></Loop>
</If>

But no luck, that still didn’t work and it outputs nothing. So I decided to simply loop through all our posts and display our day_time_start field values to see what’s contained within them:

<Loop post_type=program>
  <p><Field day_time_start /></p>
</Loop>

This revealed something interesting: the output looked like this

2023-10-23 00:00:00

2023-09-04 00:00:00

2023-07-12 00:00:00

That’s not the format I expected. After all, I had set up the field to output its data in the format l g:i a in the ACF field settings:

My first reaction was that this might be a bug, so if I wasn’t in contact with the devs already, I might make a post on the forum and let our devs know that I think I’ve identified a bug. In this case, I’ve actually already spoken to a dev about a similar issue and they mentioned this:

the Field tag doesn’t handle such ACF features unless you use ACF-specific attributes starting with acf_* to specify the field. For example, this:

<Field editor_field_name />

Should be changed to this:

<Field acf_editor=editor_field_name />

In other words, if you use the general-purpose L&L tags and attributes, it works with the raw field value, which in this case for the date_time field is in the format 2023-07-12 00:00:00. Whereas in order for L&L to be able to support the features of a third-party plugin (like the custom display format of ACF fields in this case), we need to use the plugin-specific tags and attributes mentioned in the docs. When I switch my template to this:

<Loop post_type=program>
  <p><Field acf_date_time=day_time_start /></p>
</Loop>

It outputs the data in the format I was expecting:

Monday 12:00 am

Monday 12:00 am

Wednesday 12:00 am

So that’s a massive clue about how we need to approach this: we need to use the acf_date_time attribute if we want to work with our custom ACF format of data instead of the raw format of the data that are actually saved in the field value. The reason it wasn’t filtering our loop as expected is because we were trying to filter the raw value of our field which would never contain the value “Monday” since the data itself isn’t in our custom text format.

Now we’ve got to build back up to get the functionality we want. Whether we tried using query parameters like custom_field or attributes like field, in both cases we would need to feed it an actual field name, which means that we wouldn’t be able to use our acf_date_time attribute to make sure we were working with the data in the right format. So, as noted here, that means we’re going to need to use conditional logic to filter our loop instead.

<Loop post_type=program>
  <If check="{Field acf_date_time=day_time_start}" includes value="Monday">
    <p><Field title /></p>
  </If>
</Loop>

Hey, that works! So we’ve identified why our template wasn’t working and we’ve got a revised template that’s displaying the data we wanted. Now it’s just a matter of putting the functionality back in that we took out for testing.

The cool thing about our discovery here is that we now know that the actual raw field value of that ACF date field is in a format that looks like this: YYYY-MM-DD HH:MM:SS. The fun thing about that format: it can be sorted alphabetically (i.e. reading the numbers from left to right) without us having to do anything fancy!

So in the end, ordering our loop might look like this:

<Loop post_type=program orderby_field=day_time_start>
  <If check="{Field acf_date_time=day_time_start}" includes value="{Date format='l'}">
    <p><Field title /></p>
  </If>
</Loop>

Finally, we need to add our logic back in so that we can display something when there aren’t any results. At first, I thought you could do that by setting a variable inside your If tag, like this:

<Loop post_type=program orderby_field=day_time_start>
  <If check="{Field acf_date_time=day_time_start}" includes value="{Date format='l'}">
    <p><Field title /></p>
    <Set any_programs>true</Set>
  </If>
</Loop>

<If variable=any_programs not exists>
  There are no programs scheduled for today.
</If>

The only flaw I see there is that the variable gets set multiple times. I imagine there would be ways around that, but it would involve additional tinkering and testing. and I imagine this should work quite well. If you ever want to do some tinkering and compare multiple possible approaches, you can use the Timer tag to test which approach performs better.

Hope that’s helpful!

1 Like

Thank you so much for taking the time @benjamin. That solution works perfectly.

That would definitely be my approach as well. I just did not have enough knowledge of L&L.
But Getting used to it and I am liking it so far :slight_smile:

1 Like

Glad to hear you like the plugin! If you’re interested in helping encourage our team’s development and support efforts surrounding this free plugin, posting a review of L&L on the WordPress repo would go a long way.

Whether you feel like doing that or not, I’m happy to hear that you’re getting used to it and building some interesting templates with it. You seem to have figured things out quite quickly if this is the first hurdle that’s caused you to make a post on the forum! Keep on sharing about what you’re building with L&L and I’ll see you around :slight_smile:

1 Like