Age (or "time since") macro/widget

I’m currently doing a fast, and instead of downloading a dedicated app to keep track of how many hours have passed, I wrote a small Javascript macro for my journaling tiddler where I write about how hungry and bored I am:

<<timesince "202207121800">> :arrow_right: “41 hours 47 minutes”

I couldn’t find something like this in @EricShulman’s It's About Time! — TiddlyTools: "Small Tools for Big Ideas!" (tm), but it’s so vast I probably missed it.

I realize now that this would be a nice way to keep track of the age of my pets as well, since I can’t remember how old they are when calling the vet. Maybe the kids as well, but I can usually recall their last birthday…

Another thought is, would this be better as a widget? It would be neat if there was some kind of update, so that the time can be “live”, but a macro only returns WikiText. Maybe a widget could include a script or at least a button to manually update the time?

If this has been done before, please let me know. :slight_smile: I will publish my macro code eventually, but it’s still very experimental.

Certainly this is useful.

Just today I made an “event tiddler” with an event-date, and a side bar to list all event tiddlers with their relative date (most recent first). Why? - I needed to know how long since I had covid for my next vaccine ! I will shortly add the ability to add an event-date as needed to any tiddler using a date picker.

Once again, no Javascript needed :nerd_face:

@cdaven I imagine your making use of the view widget “relativedate” format?

I think you may have a closer look at: It's About Time! — TiddlyTools: "Small Tools for Big Ideas!" (tm)

But its just
<$view field=date-field format=relativedate/>

Yes, we should be able to give it a variable but cannot so we use;

{{{ [[202207121800]format:relativedate[]] }}}
or
{{{ [<datevar>format:relativedate[]] }}}

Nice, thank you! Since I know Javascript way better than these filters and widgets, it’s much easier to write a JS macro than trying to find what is possible and how in the TiddlyWiki documentation (and then remember it until next time!). But I’m learning.

I suppose for some people, it’s the other way around; you can do stuff with WikiText that you have no idea how to do in Javascript. :slight_smile:

Since relativedate returns the timespan as “X ago”, maybe we need an age format that returns the timespan as “X” instead?

Now my cat tiddler looks like this: “Born 2013-09-10 (8 years ago)”, but I would like not to use the word “ago” here. Also, I would sometimes like months and even days as well.

I tried this to get rid of the “ago” suffix: {{{ [get[date-field]format:relativedate[]trim[ago]] }}}

It kind of works, but becomes a link to a tiddler called “8 years”… So I write a Javascript macro <<trim>> instead, but then I don’t know how to pass a widget as a parameter to a macro…

So I create a custom Javascript “formatfilteroperator” called “age”, that I can use here:

{{{ [get[date-field]format:age[]] }}}

But then I see that the word “ago” is actually coded into $:/language/RelativeDate/Past/Years as “<<period>> years ago”. If I want the word “years”, I’m also getting “ago”.

Also, the View widget has “hard-coded” formats, so my new “age” format won’t work unless I shadow the whole $:/core/modules/widgets/view.js and insert my format there.

I think I’m keeping my Javascript <<timesince>> macro… :smirk:

I plan to be here to help you, as are others. If anything the tiddlywiki community motto is “Just ask”.

More than you think. Although I have started straying into Javascript of late, to develop things that are definitely missing, and its being hard to persuade others it is needed.

I have made public before my intention to be a super user and avoid reverting to bespoke or Javascript solutions so as to have a much deeper understanding and be in a position to find the gaps not served. In part this is why I am so prolific in these forums, I try and be the voice of TiddlyWiki when tiddlywiki can do it. This approach also empowers those without the power of “black arts”.

As the saying goes;

“If the only tool you have is a hammer, it is tempting to treat everything as if it were a nail”

I think I will dedicate a Topic to this subject and explain both the advantages and disadvantages of choosing a less appropriate tool, although the fact is you can choose whatever tool you need.

The health of the community needs people with your skills holding back on re-implementing things that can already be done, and helping address the gaps.

  • For example one way I could read your current situation is perhaps we can extend the date format, or relative date, to one we can provide a template to is as well as common or garden date formats.
  • This approach solves it once, but also many times for all who come after.
  • In many cases the effort is similar for “filling the gap” as it is for “bespoke and possibly overlapping” solutions.
  • Perhaps you can add features not available in tiddlywiki, ask us to be sure, into your new macro that may one day be adopted into the core.
1 Like

As you have found, rendering the result of a filtered transclusion (the {{{ [...] }}} syntax) produces a tiddler link. To force the result to show as plain text, use the $text widget, like this:

<$text text={{{ [get[date-field]format:relativedate[]trim[ ago]] }}} />

-e

Sounds great! :+1:

Thank you!

However, [get[date-field]] actually gets the field value from all tiddlers… I had to add all[current] to get only this tiddler’s field value.

Now, this gets me thinking …

If you have to first transclude a filter and then pipe it through a widget, wouldn’t it be easier if there was something like a “textfilter” macro?

<<textfilter {{!!date-field}} "[format:relativedate[]trim[ago]]">>

That “filters” the input value and outputs the resulting text?

Something like this:

\define textfilter(text, filter)
<$text text={{{ [[$text$]$filter$] }}} />
\end

Then I notice that this syntax doesn’t work, as you claim it does, in How can I pass the value of the a field or text into a macro - #2 by EricShulman

<<MacroName {{!!FieldName}}>>

I tried this with a JS macro that logs the input values, and “{{!!FieldName}}” is passed as a literal string. Also doesn’t work with the <<color>> core macro when passing a field value.

The other, more convoluted, syntax works, however:

<$macrocall $name="MacroName" var1={{!!FieldName}} />

Is there something I’m missing here?

You can use <<MacroName fieldName>> then in the macro {{!!$fieldname$}} or in a filter [get[$fieldname$]]

  • Something changed recently so you can pass more in the macro call but I am not yet across it.
    • V5.2.0 mentions <<mymacro arg:"""nested <<macro>> call""">>
  • Also some substantial changes are coming in Tiddlywiki version 5.2.4+

Macros are just “text expanders”. They don’t parse their parameters. Thus, {{!!fieldname}} is just passed into the macro “as-is” and the parameter reference within the macro definition (i.e., $param$) is replaced with {{!!fieldname}}. Then, the resulting macro content is used to replace the original macro call. It is up to the context where the macro was called to determine if that content is “wikified” to produce the final rendered result.

For example, suppose you create a macro like this:

\define showtext(param) <$text text=$param$/>

and then call it like this:

<<showtext {{!!fieldname}}>>

the result is that the original macro call is replaced by

<$text text={{!!fieldname}}/>

which is parsed to display the actual value stored in the fieldname. However, in your example:

\define textfilter(text, filter) <$text text={{{ [[$text$]$filter$] }}} />

the parameter you passed in is inserted into filter syntax. Thus, passing in `{{!!fieldname}} produces the output:

<$text text={{{ [[{{!!fieldname}}]$filter$] }}} />

Take note that the parameter value contained inside the filter syntax is enclosed within [...] which causes it to be treated as a literal text string and prevents it from being parsed to get the actual value stored in the specified fieldname.

To achieve something like what you expected, you would need to write:

\define textfilter(text, filter) <$text text={{{ [$text$$filter$] }}} />

and then invoke it with:

<<textfilter "{!!fieldname}">>

which would produce the following macro output:

<$text text={{{ [{!!fieldname}] }}}/>

which, when parsed and rendered WILL display the value stored in the specified fieldname.

For your particular use case, it is probably more obvious if you define a macro like this:

\define showrelativedate(field)
<$text text={{{ [{!!$field$}format:relativedate[]trim[ ago]] }}}/>
\end

which you could then invoke via:

<<showrelativedate date-field>>

Also, take note that, when you use the $macrocall WIDGET to invoke the macro, as in your example:

<$macrocall $name="MacroName" var1={{!!FieldName}} />

the var1 widget parameter IS being parsed before being passed in. Thus, the macro expansion uses the text value contained within the specified fieldname, producing the rendered output you expected.

While this may all seem a bit convoluted and somewhat different from most other languages, TiddlyWiki filter syntax is actually very consistent, even if this is not readily apparent.

I realize that it may seem easier to retreat to your comfort zone by defining macros using Javascript code, but I encourage you to keep trying to use TiddlyWiki native syntax as much as possible. It will probably take some time, but once it “clicks”, it will become surprisingly easy to create filters that achieve some very sophisticated results.

When you get stuck, just ask questions here… we are a friendly group, and are always eager to help people find the solutions they need to make their use of TiddlyWiki successful.

-e

1 Like

@EricShulman: Whoa, this should be put up in the docs on TW5-com.

Have a nice day
Yaisog

maybe this plugin from @EricShulman might help to track your fasting times

That plugin is for TiddlyWiki Classic.

The equivalent for TiddlyWiki5 is here:
https://tiddlytools.com/timer.html#TiddlyTools%2FTime%2FTimers

1 Like