Create New Journal Tiddler with Predefined Content

I’m trying to make a daily journal with a dynamically generated chore list included on it. I’m using the Kara plugin for the checklist, which requires items to be formatted as:

@@.todo
[ ] Item 1
[ ] Item 2
@@

I’ve got 3 tiddlers:
“testChores” - contains the list of chores. It has extra linebreaks because of the various list and/or reveal widgets that dynamically generate the chore list. It also has some links. Content:

\whitespace trim
[ ] Take out trash
[ ] Wash dishes

[ ] [[Check email|https://mail.google.com]]
[ ] Make lunch

“testAction” - creates the new tiddler, adding the @@.todo and @@ required for the Kara plugin.
Content:

\define journalChores()
{{testChores}}
\end

<$wikify name="Chores" text=<<journalChores>>>
<$action-createtiddler text={{{ "@@.todo
" [<Chores>] "
@@" +[join[]] }}} />
</$wikify>

“testButton” - calls “testAction” when clicked
Content:

\define journalAction()
{{testAction}}
\end

\define journalButton()
<$button actions=<<journalAction>> >
Test Button
</$button>
\end
<<journalButton>>

This creates a new tiddler with the following content:

@@.todo
[ ] Take out trash
[ ] Wash dishes[ ]Check email[ ] Make lunch
@@

But it’s removed the links and linebreaks/spaces around links aren’t preserved. Any thoughts on how to get this working the way I want? The ideal output for this would be a new tiddler containing the text:

@@.todo
[ ] Take out trash
[ ] Wash dishes
[ ] [[Check email|https://mail.google.com]]
[ ] Make lunch
@@

Bonus points (but not mandatory) if we can remove the [ ] from “testChores” and dynamically add it to each line in “testAction”.

Thanks in advance for any help!

Hello @Devin_Baillie,
I’m not sure what is wrong wih your code.
As an alternative, may I suggest that you create an Automatic checklist as per Kara Tutorial.
Any tiddler with a specific tag, such as Journal or Project can transclude a template checklist.

Kara Tutorial example here

Automatic Checklist.json (365 Bytes)
template_checklist.json (280 Bytes)

Sunny

2 Likes

As @Sunny explained you can use templates. Automatic template can add a checklist to certain tiddlers. You can even use one checklist for all those tiddlers (like all tiddlers tagged with project). See Kara 0.9.5 — In tiddler plain checklist and interstitial journaling plugin

If you like to create a tiddler with pre-populated contents and tags including a checklist then see https://tiddlywiki.com/#ActionCreateTiddlerWidget.

A small sample code is attached, to show how the second approach works.

tiddler_with_checklist.json (591 Bytes)

To give a try, download above json and improt into Kara 0.9.5 — In tiddler plain checklist and interstitial journaling plugin using simple drag and drop, ipen TestButton tiddler and then click on the Test Button button.

Note that white spaces empty lines , … are allowed in a data block.

Thanks, but that still doesn’t work the way I was hoping.

I’m already using automatic checklists with a view-template on the newly created note, I’m having trouble getting it to pre-populate the way I want.

I guess I could have clarified better: the list of chores is dynamically generated, including weekly and monthly chores, using list widgets to determine what should be listed and what shouldn’t.

Here’s a version of “testChores” with a weekly chore:

\whitespace trim
[ ] Take out trash
[ ] Wash dishes

<$vars day=<<now DDD>> >
<$list filter="[<day>match[Sunday]]">
[ ] Grocery Shopping
</$list>
</$vars>

[ ] [[Check email|https://mail.google.com]]
[ ] Make lunch

With my original “testAction” this generates a new tiddler with the following content:

@@.todo
[ ] Take out trash
[ ] Wash dishes[ ] Grocery Shopping[ ]Check email[ ] Make lunch
@@

Bad: It loses the link, most of the line-breaks, and spacing around “Check email”
Good: It processes the vars and list widgets, only including the text “[ ] Grocery Shopping” in the newly created tiddler.

If I instead use $template instead of text in “testAction”:

<$action-createtiddler $template="testChores">
  <$action-navigate $to=<<createTiddler-title>> />
</$action-createtiddler>

and update “testChores” to include the @@s

@@.todo
[ ] Take out trash
[ ] Wash dishes

<$vars day=<<now DDD>> >
<$list filter="[<day>match[Sunday]]">
[ ] Grocery Shopping
</$list>
</$vars>

[ ] [[Check email|https://mail.google.com]]
[ ] Make lunch
@@

Then I get a new tiddler who’s content is the same as the template:

@@.todo
[ ] Take out trash
[ ] Wash dishes

<$vars day=<<now DDD>> >
<$list filter="[<day>match[Sunday]]">
[ ] Grocery Shopping
</$list>
</$vars>

[ ] [[Check email|https://mail.google.com]]
[ ] Make lunch
@@

Good: It keeps the link and linebreaks.
Bad: It doesn’t process the vars and list widgets, inserting them as literal strings in the newly created tiddler.

Hopefully this makes sense - let me know if it’s not clear what I’m trying to accomplish, and I’ll try to explain better.

Edit:
And if I try the original version without \whitespace trim the spacing around links is kept, but linebreaks are still sometimes lost, and links are still lost.

The example I provided, use a pre-popultaed template.

If I understand your explanation correctly, you possess a Dynamically Generated List of Chores that may vary on a weekly or monthly. The question now is how to implement a dynamic template effectively?

Am I right?

Yes, that’s correct. I mentioned it in my first post, but stupidly forgot to include it in the example. Sorry about that.

Is it possible to separate this into a static list of chores and a dynamic? If so, the dynamic portion can be extracted and either appended to the beginning or the end of the list.

Note: This query is unrelated to Kara. It pertains to TiddlyWiki and aims to generate output from a tiddler containing both static and dynamic content, which can then be injected into another tiddler.

I can break it up in any way that works, that’s no problem.

In my actual list, I’ve got things that are weekly on various days of the week, every nth week, monthly and every nth month on various days of the month (and days from the end of the month), and yearly on specified dates. Currently they’re all in one tiddler, with various let, var, and list widgets determining what shows up and what doesn’t, but I could just as easily move them into separate tiddlers - say one for each day of the week, for weekly tasks - and put the logic for the inclusion criteria into the “testAction” tiddler instead, if that would work better.

Not sure if it’s helpful, but if I remove the \whitespace trim and use my original “testAction”, then it works well enough as long as there are no links: I get extra blank lines from the logic widgets, but it doesn’t affect the functionality of the generated tiddler, I just have 1 blank line in the @@.todo block for each condition that doesn’t get included. But currently it loses all the links (I assume from the conversion to text in the $action-createtiddler).

Everything I’ve tried to preserve the links either ends up messing up formatting by losing linebreaks and/or spaces, including the content (including the widgets) as literal strings, or just a dynamic reference to the main chores tiddler (Edit: or losing the @@ block in a wikify widget).

If we have “testChores” (or multiple chores lists to separate out the logic) as some variant of:

[ ] Take out trash
[ ] Wash dishes

<$vars day=<<now DDD>> >
<$list filter="[<day>match[Monday]]">
[ ] Grocery Shopping
</$list>
</$vars>

[ ] [[Check email|https://mail.google.com]]
[ ] Make lunch

then I’d like the newly created tiddler to contain:

@@.todo
[ ] Take out trash
[ ] Wash dishes
[ ] Grocery Shopping
[ ] [[Check email|https://mail.google.com]]
[ ] Make lunch
@@

If it has extra blank lines, that’s not the end of the world as it doesn’t affect the functionality, but removing them keeps things cleaner whenever I need to edit the text of the tiddler.

The removal of line feeds and the disappearance of links in [[caption|link]] are the results of wikification using $wikify. For example, if useCheck email: https://mail.google.com your link will be still there.

Thanks, that’s a workaround that will work, but some of the links are fairly long (links to internal work resources) so it’s not the most ideal.

Is there any way you can think of to keep the links in [[caption|link]] form?

I would suggest to use checklistdemo — a demo of the Checklist plugin for TiddlyWiki5 from Tony Grosinger (the source code is tgrosinger/tw5-checklist: Simple checklist widget for TiddlyWiki5:.

It works on the wikified contents and so handles all your wikitext. Try in a TiddlyWiki 5.3.0+ as you use match, let, …

Hello @Devin_Baillie and @Mohammad
I have given some more thought to this problem and would like to suggest another solution.
It may be acceptable for someone if not for @Devin_Baillie’s needs.
I have put an example here
Example Tiddlers
tiddlers(34).json (4.9 KB)

Good solution! It likes Japanese Kanban!

1 Like

I can’t take the credit for this, the credit belongs to @Mark_S for this posting

I liked the solution and changed the tiddlers accordingly, just hope it works.

Sunny

Thanks for this. I don’t think it addresses what I need, but I think I’ve made some more progress, I just need some help with (hopefully) the last step.

If I use:

<$button>
<$action-setfield $tiddler="test1" text={{{ [{test1}addsuffix{test2}] }}} />
Append test2 to test1
</$button>

it successfully adds the contents of “test2” to “test1”.

I figured that i could use that with some logic to add the relevant chores if I stored them each in an appropriately named tiddler. So then I tried:

<$button>
<$vars day=<<now DDD>> >
<$vars tiddlerToAppend={{{ [<day>addprefix[test ]] }}} >
<$reveal type="nomatch" state=<<tiddlerToAppend>> text="">
<$action-setfield $tiddler="test1" text={{{ [{test1}addsuffix<tiddlerToAppend>] }}} />
</$reveal>
</$vars>
</$vars>
Append today's test tiddler (if it exists)
</$button>

where the intention was to check whether “test Tuesday” exists, and if so, add its contents to the end of test1. However currently it just adds the title “test Tuesday”, instead of adding the contents. Any thoughts on how to modify

<$action-setfield $tiddler="test1" text={{{ [{test1}addsuffix<tiddlerToAppend>] }}} />

to add the contents of “tiddlerToAppend” instead of the title?

Give this a try:

<$action-setfield $tiddler="test1"
   text={{{ [{test1}] [<tiddlerToAppend>get[text]] +[join[]] }}} />

Notes:

  • Instead of using addsuffix to append the tiddlerToAppend content to the test1 tiddler content, use separate filter runs to get the contents of each tiddler and then +[join[]] them together to construct the new text content.

Also, instead of using $vars, you can use $let, which permits you to reference variables that are created earlier in the same $let widget, like this:

<$let day=<<now DDD>> tiddlerToAppend={{{ [<day>addprefix[test ]] }}}>

In addition, it doesn’t appear that you actually need to define a separate day variable since it is only referenced that one time. Instead, you could just write:

<$let tiddlerToAppend={{{ [<now DDD>addprefix[test ]] }}}>

enjoy,
-e

This is perfect, thanks!

Turns out I don’t need the reveal either - adding an empty/nonexistent tiddler doesn’t change anything.

Now I can put tasks for various schedules in their own tiddlers, and as long as I name them in a consistent way based on the date/schedule, I can create the daily journal and then just add all the relevant ones, whether they exist or not.

I appreciate everyone’s help getting this working.

I spent way too much time on this, so in the hopes that this is helpful to someone in case anyone else wants to recreate something similar, here’s the entirety of what I came up with:

I store lists of tasks in tiddlers with a consistent naming convention, then create a new journal tiddler, and append all of the relevant tiddlers for that date. It allows arbitrary frequencies for tasks that happen every n (currently n goes from 1 to 11, but that can be increased if needed by changing the number in <$list filter=[range[1],[11]] variable=n>) days, weeks (on specified weekday), months (on specified day number or days from end of month), or years (on specified date). It also lets me offset them; so if I have two tasks repeating every second day, I can specify them on the same day or alternating days (this is the parameter m in the code below). Each tiddler stores a list of tasks, one per line. Additional blank lines can be used for clarity, as they will be discarded later. At some point, if they become clutter, I may move them to $:/dev/tasks/… and update the code below appropriately.

Task list naming scheme (n is for frequency, m runs from 0 to n-1):

Every n days on day m: every_n_days_m

  • So “every_1_days_0” is for tasks that occur every single day
  • “every_3_days_0” “every_3_days_1” and “every_3_days_2” are for tasks that occur every third day, with 0, 1, and 2 changing which day of the three-day cycle they appear on (day counting based on unix standard time)

Every n weeks (on week m) on a specified weekday: every_n_weeks_DDD_m

  • Similarly, “every_2_weeks_Wednesday_0” and “every_2_weeks_Wednesday_1” are for tasks that occur every second Wednesday, and the 0 or 1 determines which of the alternating weeks they occur on (week counting also based on unix standard time).
  • “every_n_months_22_m”

Every n months (on month m) on a specified date: every_n_months_DD_m
or
Every n months (on month m), a number of days from the end of the month: every_n_months_-DD_m

  • So “every_2_months_13_0” happens every second month on the 13th.
  • “every_1_months_-7_0” happens 7 days before the last of the month, every month
  • Monthly counting is based on year*12+month#

Every n years (on year m): every_n_years_MMM_DD_m

  • So “every_1_year_October_1_0” happens every October 1st.

The main workhorse is “$:/dev/newJournalAction” tagged with “$:/tags/StartupAction/PostRender” so it automatically runs at startup. If the journal already exists, it skips the creation part and just opens the journal. If the journal doesn’t exist, it is created with the initial text “@@.todo”, then generates all of the tiddler names relevant for the current date, and appends them (non-existent tiddlers don’t affect the text, and it even removes extra blank lines and then adds "[ ] " before each entry), then finally adds the trailing “@@” required for Kara. It uses the default new journal title and tags (from settings). There are probably many ways to make this more concise or efficient, but it works and I’ve already spent too much time on this so I probably won’t look at it again for a long time (sometime after I’ve forgotten everything that I learned through this process, so I end up having to relearn it all again).

Then I’ve got a button “$:/dev/NewJournalButton” tagged with “$:/tags/PageControls” so I can show it instead of the original new journal button on the sidebar. This basically just copies the existing new journal button, but calls my action instead.

Finally I’ve got a viewtemplate “$:/dev/templates/JournalView”, which applies to all tiddlers tagged with “Journal”.

“$:/dev/newJournalAction”:

<!--------
key:
  n - frequency, every nth day/week/etc. (can be 1 for daily/weekly/etc.)
  m - which nth day, runs from 0 to n-1
Daily: every_n_days_m
Weekly: every_n_weeks_DDD_m
Monthly: every_n_months_DD_m (DD -> negative for days from end of month)
Yearly: every_n_years_MMM_DD_m
-------->
\define journalChores()
{{templates/dailyChores}}
\end

\define get-tags() $(textFieldTags)$ $(tagsFieldTags)$

<$let lf="
"
taskPre="[ ] "
journalTitleTemplate={{$:/config/NewJournal/Title}} textFieldTags={{$:/config/NewJournal/Tags}} tagsFieldTags={{$:/config/NewJournal/Tags!!tags}}>
<$wikify name="journalTitle" text="<$macrocall $name='now' format=<<journalTitleTemplate>>/>">
<$reveal type="match" state=<<journalTitle>> text="">
<$action-createtiddler $basetitle=<<journalTitle>> tags=<<get-tags>> text=@@.todo >
<$let
dayOfWeek=<<now DDD>> 
dayOfMonth=<<now DD>>
month=<<now MMM>>
n_month=<<now MM>>
year=<<now YYYY>>
lastDayOfMonth={{{ [<year>remainder[4]match[0]then<n_month>match[2]then[29]]
~[[31 28 31 30 31 30 31 31 30 31 30 31]split[ ]nth<n_month>] }}}
dayFromEndOfMonth={{{ [<lastDayOfMonth>subtract<dayOfMonth>] }}}
intDay={{{ [<now YYYY0MM0DD000000000Z>format:date[TIMESTAMP]divide[86400000]] }}}
intWeek={{{ [<now YYYY0MM0DD000000000Z>format:date[TIMESTAMP]divide[86400000]add[4]divide[7]floor[]] }}}
intMonth={{{ [<now YYYY>multiply[12]add<now MM>] }}}
>
<$list filter=[range[1],[11]] variable=n>
<$let m={{{ [<intDay>remainder<n>] }}}
tiddlerToAppend={{{ every_ [<n>] _days_ [<m>] +[join[]] }}}
>
<$action-setfield $tiddler=<<createTiddler-title>>
   text={{{ [<createTiddler-title>get[text]] [<tiddlerToAppend>get[text]split<lf>!is[blank]addprefix<taskPre>] +[join<lf>] }}} />
</$let>
<$let m={{{ [<intWeek>remainder<n>] }}}
tiddlerToAppend={{{ every_ [<n>] _weeks_ [<dayOfWeek>] _ [<m>] +[join[]] }}}
>
<$action-setfield $tiddler=<<createTiddler-title>>
   text={{{ [<createTiddler-title>get[text]] [<tiddlerToAppend>get[text]split<lf>!is[blank]addprefix<taskPre>] +[join<lf>] }}} />
</$let>
<$let m={{{ [<intMonth>remainder<n>] }}}
tiddlerToAppend={{{ every_ =[<n>] _months_ =[<dayOfMonth>] _ =[<m>] +[join[]] }}}
>
<$action-setfield $tiddler=<<createTiddler-title>>
   text={{{ [<createTiddler-title>get[text]] [<tiddlerToAppend>get[text]split<lf>!is[blank]addprefix<taskPre>] +[join<lf>] }}} />
</$let>
<$let m={{{ [<intMonth>remainder<n>] }}}
tiddlerToAppend={{{ every_ =[<n>] _months_- =[<dayFromEndOfMonth>] _ =[<m>] +[join[]] }}}
>
<$action-setfield $tiddler=<<createTiddler-title>>
   text={{{ [<createTiddler-title>get[text]] [<tiddlerToAppend>get[text]split<lf>!is[blank]addprefix<taskPre>] +[join<lf>] }}} />
</$let>
<$let m={{{ [<year>remainder<n>] }}}
tiddlerToAppend={{{ every_ =[<n>] _years_ =[<month>] =_ =[<dayOfMonth>] =_ =[<m>] +[join[]] }}}
>
<$action-setfield $tiddler=<<createTiddler-title>>
   text={{{ [<createTiddler-title>get[text]] [<tiddlerToAppend>get[text]split<lf>!is[blank]addprefix<taskPre>] +[join<lf>] }}} />
</$let>
</$list>
</$let>
<$action-setfield $tiddler=<<createTiddler-title>>
   text={{{ [<createTiddler-title>get[text]] @@ +[join<lf>] }}} />
</$action-createtiddler>
</$reveal>
<$action-navigate $to=<<journalTitle>> />
</$wikify>
</$let>

“$:/dev/NewJournalButton”:

\define journalChores()
{{templates/dailyChores}}
\end

\define get-tags() $(textFieldTags)$ $(tagsFieldTags)$

\define journalAction()
{{$:/dev/newJournalAction}}
\end

\whitespace trim
\define journalButton()
\whitespace trim
<$button tooltip={{$:/language/Buttons/NewJournal/Hint}} aria-label={{$:/language/Buttons/NewJournal/Caption}} class=<<tv-config-toolbar-class>> actions=<<journalAction>> >
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
{{$:/core/images/new-journal-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text">
<$text text={{$:/language/Buttons/NewJournal/Caption}}/>
</span>
</$list>
</$button>
\end
<<journalButton>>

“$:/dev/templates/JournalView”:

<$list filter="[all[current]tag[Journal]]">
<<checklist>>
<<interstitial>>
</$list>

Edit: A caveat/caution/bug that I’m aware of but don’t care enough to fix: If you specify monthly tasks on the 29, 30, or 31, they will simply not occur on months that have fewer days (and similarly for days from the end of the month).

It wouldn’t surprise me if there’s some content you could add to the task lists that breaks things (though maybe not, as they’re treated as text?), but all I care about for now is simple links, which appear to work perfectly.

Edit 2: If you want any other standard content outside of the todo list on the daily journal, you could create a separate template with whatever content, and add on creation using template instead of text, and then append the @@.todo the same as we do everything else. Or if you just want it to show up without being in the content of each journal, you can add it to the JournalView.

Ok, I know I said I was done, but apparently I couldn’t leave it alone. I reduced the amount of repetitive code in “$:/dev/newJournalAction”

<!--------
key:
  n - frequency, every nth day/week/etc. (can be 1 for daily/weekly/etc.)
  m - which nth day, runs from 0 to n-1
Daily: every_n_days_m
Weekly: every_n_weeks_DDD_m
Monthly: every_n_months_DD_m (DD -> negative for days from end of month)
Yearly: every_n_years_MMM_DD_m
-------->

\define journalChores()
{{templates/dailyChores}}
\end

\define get-tags() $(textFieldTags)$ $(tagsFieldTags)$

<$let lf="
"
taskPre="[ ] "
sep="::::::::"
journalTitleTemplate={{$:/config/NewJournal/Title}} textFieldTags={{$:/config/NewJournal/Tags}} tagsFieldTags={{$:/config/NewJournal/Tags!!tags}}>
<$wikify name="journalTitle" text="<$macrocall $name='now' format=<<journalTitleTemplate>>/>">
<$reveal type="match" state=<<journalTitle>> text="">
<$action-createtiddler $basetitle=<<journalTitle>> tags=<<get-tags>> text=@@.todo >
<$let
dayOfWeek=<<now DDD>> 
dayOfMonth=<<now DD>>
month=<<now MMM>>
n_month=<<now MM>>
year=<<now YYYY>>
lastDayOfMonth={{{ [<year>remainder[4]match[0]then<n_month>match[2]then[29]]
~[[31 28 31 30 31 30 31 31 30 31 30 31]split[ ]nth<n_month>] }}}
dayFromEndOfMonth={{{ [<lastDayOfMonth>subtract<dayOfMonth>] }}}
intDay={{{ [<now YYYY0MM0DD000000000Z>format:date[TIMESTAMP]divide[86400000]] }}}
intWeek={{{ [<now YYYY0MM0DD000000000Z>format:date[TIMESTAMP]divide[86400000]add[4]divide[7]floor[]] }}}
intMonth={{{ [<now YYYY>multiply[12]add<now MM>] }}}
>
<$list filter=[range[1],[11]] variable=n>
<$list filter=
"=every_ =[<n>] =_days_ =[<intDay>remainder<n>] =[<sep>]
=every_ =[<n>] =_weeks_ =[<dayOfWeek>] =_ =[<intWeek>remainder<n>] =[<sep>]
=every_ =[<n>] =_months_ =[<dayOfMonth>] =_ =[<intMonth>remainder<n>] =[<sep>]
=every_ =[<n>] =_months_ =[<dayFromEndOfMonth>] =_ =[<intMonth>remainder<n>] =[<sep>]
=every_ =[<n>] =_years_ =[<month>] =_ =[<dayOfMonth>] =_ =[<year>remainder<n>]
+[join[]split<sep>]" variable=tiddlerToAppend>
<$action-setfield $tiddler=<<createTiddler-title>>
   text={{{ [<createTiddler-title>get[text]] [<tiddlerToAppend>get[text]split<lf>!is[blank]addprefix<taskPre>] +[join<lf>] }}} />
</$list>
</$list>
</$let>
<$action-setfield $tiddler=<<createTiddler-title>>
   text={{{ [<createTiddler-title>get[text]] @@ +[join<lf>] }}} />
</$action-createtiddler>
</$reveal>
<$action-navigate $to=<<journalTitle>> />
</$wikify>
</$let>