I'm building a simple view to show content of X type, filtered by date. I want this view to be available via URLs like:

  • /events/2012 - Show all content for this year only
  • /events/2012/11 - Show all content for this year and month only
  • /events/2012/11/28 - Show all content for this exact day only

These URLs form part of this section's hierarchy so the patterns are non-negotiable.

The date I'm filtering on is a date field provided by the Date module, and has an optional end date.

I've tried setting the path of the view to /events/%/%/%, and have added three contextual filters for the date field. The granularity for each of the filters is set correctly to the respective date part for that filter.

However, none of that works; I either get all event content, regardless of year, for the year filter, or no content at all if I include the other filters.

There are several related questions (none with answers as it happens):

But nothing that covers exactly what I'm looking to do.

How do I tame these contextual filters, without resorting to the PHP filter which is simply not an option? I can't believe that there's no way to do this just with the UI, it seems like one of the most obvious use-cases.


I tried using a filter with a granularity of month, and changed the argument to 2012-11...and it worked.

So I think the answer is simply that the date filter handlers don't work as I expected.

  • I have been able to get a view that works as you described. It was too easy to get it, and I wonder if there is something I am missing.
    – apaderno
    Commented Nov 28, 2012 at 13:44
  • @kiamlaluno Really? There's two of us working on this and we haven't got past the year yet :P I'd be very grateful if you could dump an export of the view somewhere that I could have a look
    – Clive
    Commented Nov 28, 2012 at 13:50
  • 2
    As I said, it was too easy to be true. ;)
    – apaderno
    Commented Nov 28, 2012 at 16:40
  • lol @kiamlaluno ;)
    – Clive
    Commented Nov 28, 2012 at 17:06

1 Answer 1


Here is the one approach,

  • First create a custom call back for /events
  • Remove the date contextual filters from your view
  • Add only one filter(not contextual filter) to your view for that date field, accept the default values and save the view
  • Then use the following code in your custom callback to execute the view

    function get_events($year = '', $month = '', $day = '')
      // Display ID of the view.
      $display_id = 'default';
      // get the view object.
      $view = views_get_view('events_views'); //Replace with your view name
      $filter = $view->get_item($display_id, 'filter', 'field_event_date_value');
      if ($year) {
        $filter['value']['value'] = $year;
        $filter['granularity'] = 'year';
      if ($year && $month) {
        $filter['value']['value'] = $year . '-' . $month;
        $filter['granularity'] = 'month';
      if ($year && $month && $day) {
        $filter['value']['value'] = $year . '-' . $month . '-' . $day;
        $filter['granularity'] = 'day';
      $view->set_item($display_id, 'filter', 'field_event_date_value', $filter);
      // If you have any other arguments read from the URL and pass it here as part of args array
      $result = $view->execute_display($display_id, $args);

    Hope you are aware of how to pass arguments to the view programatically. This is what we are using for complex date filters in views which lacks lot of support for date functionality, however we haven't tried with granularity. This is un tested and not optimized. Modify it according to your need.

  • Thanks, I actually did exactly this for another view with the same requirements yesterday, but I was convinced there must be a way to convince the UI to play nicely. I won't accept this just yet in case anyone else has some ideas, but thanks again
    – Clive
    Commented Nov 28, 2012 at 14:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.