Is there a way to divide the timeline entries by each month instead of each day?

I am using a clone of the default timeline macro to produce a list of transcluded tiddlers with a given tag, organized by date. I can get the entries to be shown as 2022-04, but since the timeline has an eachday operator, I get multiple entries of 2022-04, one for each day I add tiddlers. I would prefer all entries from April to be under one heading of 2022-04, all May entries under 2022-05, etc. Any idea how I could do that?

@DaveGifford I had a look at the macro $:/core/macros/timeline and it is using both eachday and sameday operators.

I expect it is easier to write your own nested lists and replace these with an equivalent “each month” and “same month”. With month just being the first 6 characters of the date.

I will see what I can do.

@DaveGifford I managed to find the solution with a bit of fiddling. Perhaps others can see a better way?

\define each-month()
<h3><$text text={{{ [[$(year-month)$15]format:date[MMM YYYY]] }}}/></h3>
<$list filter="[all[tiddlers]!is[system]!sort[modified]] :filter[get[modified]prefix[$(year-month)$]]">
   <!-- Same Month -->
   <$text text={{{ [all[current]get[modified]format:date[DDth]] }}}/> <$link/><br>
</$list>
\end
<$list filter="[all[tiddlers]!is[system]!sort[modified]get[modified]format:date[YYYY0MM]unique[]limit[4]!sort[]]" variable="year-month">
   <<each-month>>
</$list>

Using the filter;

[all[tiddlers]!is[system]!sort[modified]get[modified]format:date[YYYY0MM]unique[]limit[4]!sort[]]

I get a list of the last 4 months (YYYY0MM) with any tiddler and call each month.

  • See how I only use a partial date YYYY0MM
  • Note that this generates multiple YYYY0MM items except by using the unique operator to remove duplicates. I then need to reverse sort them again.

Each month I display the title,

  • note the use of “15” along with the month “YYYYMM”

Then I list all modified tiddlers with the prefix of the current month YYYYMM

  • I had to use the “:filter” to select these tiddlers while still returning the tiddler title as current tiddler.

Feel free to remove the display of the day of the month “DDth”, or reformat.

1 Like

Thanks Tones! I will have to play with this a bit and get the hang of it.

Can you elaborate on the importance of the 15?

I think it could actually be any padded 2 digit number from 01 to 28, but 15 is a good average.

The problem I foresee with this code is the old UTC bug-a-boo. The year-month variable contains your local time. But it is used to filter against the UTC time, which will not always be the same. Which means some tiddlers from the last few hours of the past or current month might be skipped. You can test to see if my theory is correct. The fix is to add a format operator between the get operator and the prefix operator.

On the surface perhaps this fixes it?

I replaced the date formats with macros of a similar name but which include the [UTC] because it contains [ and ] and cant be entered directly in the filters.

\define MMM-YYYY() [UTC]MMM YYYY 
\define DDth() [UTC]DDth
\define YYYY0MM() [UTC]YYYY0MM
\define each-month()
<h3><$text text={{{ [[$(year-month)$15]format:date<MMM-YYYY>] }}}/></h3>
<$list filter="[all[tiddlers]!is[system]!sort[modified]] :filter[get[modified]prefix[$(year-month)$]]">
   <!-- Same Month -->
   <$text text={{{ [all[current]get[modified]format:date<DDth>] }}}/> <$link/><br>
</$list>
\end
<$list filter="[all[tiddlers]!is[system]!sort[modified]get[modified]format:date<YYYY0MM>unique[]limit[4]!sort[]]" variable="year-month">
   <<each-month>>
</$list>

I am not sure what test case would prove this.

I’m not sure that you want [UTC]. Unless you’re travelling a lot, you’ll probably prefer to see it using local time.

To test, you probably need to use “created” instead of modified, so you can hack the field without it changing to whatever the current time is. Or you can change the modified field of a tiddler using actionSetfield with $timestamp="no" .

A minor correction.
This gives me be a nice output

...
   <!-- Same Month -->
   <span style="display:inline-block; width:4ch"><$text text={{{ [all[current]get[modified]format:date<DDth>] }}}/></span> <$link/><br>

Change as you like…

Okay I deleted my previous post. Here is what I came up with, based on your snippets and what I need. The snippet below lists things correctly, but instead of showing April 2022, it shows January 0015. Can you tell me what I did wrong?

The snippet below is in a system tiddler with $:/tags/Macro, and I used <<each-month>> in a regular tiddler “Preaching” for which there are a number of tiddlers tagged “Preaching”). To repeat, the LIST looks perfect. It is the header with the date that is messed up.

\define MMM-YYYY() [UTC]MMM YYYY 
\define DDth() [UTC]DDth
\define YYYY0MM() [UTC]YYYY0MM
\define each-month()
<h3><$text text={{{ [[$(year-month)$15]format:date<MMM-YYYY>] }}}/></h3>
<ol><$list filter="[all[current]tagging[]!is[system]!sort[created]] :filter[get[created]prefix[$(year-month)$]]">
   <!-- Same Month -->
   <li><$transclude field="text" mode="block"/></li>
</$list></ol>
\end

<$list filter="[all[current]tagging[]!is[system]!sort[created]get[created]format:date<YYYY0MM>unique[]limit[4]!sort[]]" variable="year-month">
<<each-month>>
</$list>

Is it possible that one or more of your tiddlers was created without a ‘created’ field? This is possible if the tiddlers were created, for instance, with the setfield widget.

An advanced search, filter search, for [!has:field[created]] does not turn up any results

What about [!has[created]] ?

No results. Also, opening info for tiddlers that have January 0015 shows they have created fields.

Is it because there is no definition for ‘year-month’? I don’t think so, because in the original snippet there was no definition for it, either.

Hi Dave,

I could reproduce the behavior you describe.

The <<each-month>> macro won’t work outside its surrounding <$list> widget, because it’s the list that defines the year-month variable used by the macro.

Fred

Perhaps, in advanced search filter use [get[created]sort[]] then scan the list to see if any have invalid dates.

On the use of [UTC] is important perhaps to store and query dates using UTC see https://tiddlywiki.com/#Date%20Fields which says

To avoid problems arising from differences of time zone, TiddlyWiki always uses UTC.

Personally I feel we need to confirm the behaviour of UTC, the automatic handing of created and modified and document it better. For example;

<$text text={{!!created}}/> {{!!created}} <$view field=created format=date template="YYYY-0MM-0DD hh:mm"/>

Dave, please try this:

Paste this code in a new tiddler, tagged $:/tags/Macro

\define MMM-YYYY() [UTC]MMM YYYY 
\define DDth() [UTC]DDth
\define YYYY0MM() [UTC]YYYY0MM
\define each-month()
<h3><$text text={{{ [[$(year-month)$15]format:date<MMM-YYYY>] }}}/></h3>
<ol><$list filter="[all[current]tagging[]!is[system]!sort[created]] :filter[get[created]prefix[$(year-month)$]]">
   <!-- Same Month -->
   <li><$transclude field="text" mode="block"/></li>
</$list></ol>
\end

Then, in your “Preaching” tiddler, paste this:

<<each-month>>

You will see the [in]famous “January 0015”!

If you replace the macrocall by the code below it should work as expected:

<$list filter="[all[current]tagging[]!is[system]!sort[created]get[created]format:date<YYYY0MM>unique[]limit[4]!sort[]]" variable="year-month">
<<each-month>>
</$list>

Fred

Thanks Fred, that indeed does work! So the macro requires the list that wraps it. I will adjust my ‘new’ button so it contains that snippet. Thanks again!

@DaveGifford … It should also be possible to include the list inside the <<each-month>> macro. So you don’t need to copy the list wrapper into every tiddler you use the macro. … Just a thought. … I didn’t test the code.

1 Like