Month-overview filter

Hey,
so I want to create a macro that can output every tiddler which has fields corresponding to a given month. Right now I’m using filters that detect if a tiddler has the field month and year with the corresponding values. So if I’ve read a book in November 2024, the tiddler would have fields

month:nov 
year:2024

So then a tiddler called November can list all books I read that month. Only I have to use a different filter for each year.

However, let’s say I’ve read a book from November 2024 to January 2025. Now the filters are

month:nov,dec,jan
year:2024,2025

This breaks the filter, because it is impossible to determine whether the book was read in November 2024 or November 2025 based on the filters alone. So this system is essentially broken.

Another idea that I have is creating date ranges for tiddlers with a start-date and end-date. So now the book tiddler would have fields

start-date:20241101 
end-date:20250131

Format is yyyymmdd. However I don’t know how the filter could look like then. It would need to know, that the numbers one to four (yyyy) and five,six (mm) need to be excised individually to correctly attribute year and month. I tried to ask ChatGPT to create a macro that does just that, however it hasn’t been successful. Since I’m absolutely clueless about macros in general, I’m probably punching way above my weight here.

If necessary I can show examples of the current filter as well as the non-functioning macro. I’ve anybody has ideas I’m happy to hear them!

If you want this kind of per-month tagging, it might help you to start thinking of months in terms of month/year units and tagging based on that, instead of just looking at month names + year names across two tags.

Like Right now we are in Dec25; then next month will be Jan26, so on and so forth. That way each ‘month tag’ is explicitly disambiguated and then you are free to filter on those however you’d like.

There assuredly exists bolt-on filters and solutions to your current workflow; but in my experience if you cultivate your workflows to produce your desired outcomes it will be more elegant and extendable than trying to cram your outcomes through your existing workflows.

-Xyvir

To extract parts from a field value, you can define and invoke functions like this:

\function get.year(f)  [<tid>get<f>split[]first[4]join[]]
\function get.month(f) [<tid>get<f>split[]rest[4]first[2]join[]]

<$list filter="[has[start-date]has[end-date]]" variable=tid>
<$let startyear=<<get.year start-date>>
     startmonth=<<get.month start-date>>
        endyear=<<get.year end-date>>
       endmonth=<<get.month end-date>>>
TID=<<tid>>, START=<<startyear>> <<startmonth>>, END = <<endyear>> <<endmonth>>
</$let>
</$list>

Notes:

  • The \function definitions use filter syntax
    • The f parameter specifies field name you want to access
    • <tid>get<f> retrieves the value of the specified field from a tiddler whose name is stored in the tid variable
    • split[] breaks the field value into individual characters
    • first[4] gets the first four characters (i.e., the year)
    • rest[4]first[2] skips the first four characters and gets the next two (i.e., the month)
    • join[] re-assembles the individual characters into “yyyy” and “mm” strings respectively
  • To apply these functions, we set the tid variable using a $list widget to find the titles of all tiddlers that have non-blank start-date and end-date fields.
  • Then, for each individual tid value, we invoke the year and month functions and hold the results in separate variables: startyear, startmonth, endyear and endmonth
  • You can then reference those variables to produce your desired output

Note also that because your field values contain YYYYMMDD strings, you could use the format:date[...] filter syntax to directly extract the year and month without needing to use split[] and join[], like this:

\function get.year(f)  [<tid>get<f>format:date[YYYY]]
\function get.month(f) [<tid>get<f>format:date[0MM]]

Let me know how it goes…

enjoy,
-e

references:
https://tiddlywiki.com/#Functions
https://tiddlywiki.com/#format%20Operator
https://tiddlywiki.com/#DateFormat

3 Likes

Using this, we might write something like this:

title: view-templates/month
tags: $:/tags/ViewTemplate

<% if [<currentTiddler>tag[Month]] %>
<$let months="""{
  "January":  "01", "February": "02", "March": "03", "April": "04", "May": "05", "June": "06", 
  "July": "07", "August": "08", "September": "09", "October": "10", "November":  "11", "December": "12"
}""">
<$let 
  month={{{ [{!!title}split[ ]first[]] }}} 
  year={{{ [{!!title}split[ ]last[]] }}}
  month-nbr={{{ [<months>jsonget<month>] }}} 
  month-start={{{ [<month-nbr>addprefix<year>addsuffix[01]] }}}
  month-end={{{ [<month-nbr>addprefix<year>addsuffix[31]] }}}
>

!! Books Read
<<list-links filter:"[tag[Book]!is[draft]] :filter[get[start-date]compare:number:lteq<month-end>] :filter[get[end-date]compare:number:gteq<month-start>]" >>
</$let>
</$let>
<% endif %>

Then a tiddler such as November 2025 tagged Month would list the books that were started before or on the first day of the target month and concluded on or after the last day. (We use 31 for all months here, since it won’t break anything; we’d have to get more specific for other use-cases.)

You can test this by downloading the following and dragging the resulting file onto tiddlywiki.com (or wherever): BooksByMonth.json (2.2 KB) You will see a few of my favorite books, with start/end dates, and a few select months where at least one book was read.

The only slightly tricky thing in here was looking up month numbers from month names. We just included a JSON string for that, although there are many alternatives.

3 Likes

Here’s a way to get the 2-digit month number given a month name using TWCore $:/language tiddlers:

{{{ [all[shadows]prefix[$:/language/Date/Long/Month]text<month>split[/]last[]pad[2]] }}}

-e

2 Likes

Thank you. I didn’t realize this existed, but an independent implementation of that exact technique was one of the alternatives I did consider. Mine wouldn’t have been able to take advantage of the language tools, though.

Very useful!