Is this particular note tracking project ongoing?

I am intrigued by the idea to automatically arrange notes by their creation day, organized by year, month, day, a journal of sort in an outline. (Not my idea :-)) This originated perhaps in the forum or meetups. Is it still being discussed?

Thank you.

There are several ways that you can do this. The easiest way, if you have a container or agent, is to press cmd+1 and open the inspector. Click on the “action inspector” icon (I call it the “Death Star”) and the cick the support tab. Form here you can perform a two-order sort by $CreationDate.

If you want something more intrigue, this can be done with action code and attributes.

Thank you Michael,

I can do what you show. However I want a solution (via action code) that copies the aliases of new notes automatically into an section of the outline with a result like this:

Already, possible solutions were perhaps given in the forum, meetups, or as a TB challenge. I cannot find where.

Hmm…the only way to “create an alias” is with an agent. What you’re asking for is theoretically doable, but before we go there I want to confirm that it is aliases that you’re looking to use for this type of structure and not the actual notes. Yes? I’m curious as to the use case around this. Why use aliases and not move the actual notes into the appropriate container in the outline? For instance, I could see that you’d want to create journal notes pretty much anywhere in your dock, and when you’re ready to “archive them” you could use action code to move them in to the Jounal container tree.

As for finding this on the forum, there are tons of daily journal strategies, but I’ve not seen someone try to do what you’re doing. We can do it, just need a bit more explanation. Once I understand more, I’ll whip a demo together for you.

Where do the original notes live. Wouldn’t it make more sense to simply make the notes in the correct container to start with. Thinking this through there’s a lot do do for small gain I presume the calendar folder doesn’t exist, so needs to be made?

The logging goes something like this:

  • agent find notes not descended from ‘Journal’. As alias does match descendedFrom() even if the original is elsewhere. But, negative queries are hard to construct so better might be to have a user Boolean $IsArchived. default, false but set true when an alias is moved. Now the query is [whatever defines notes to check ANd $IsArchived is false.
  • Check each matched note (alias)
    • Using $Created data, figure out the path from root to the intended container of the and create() it, noting that this creates that note and the whole path to it if needed or does nothing if the container already exists.
    • move the alias to the container and set $IsArchived to true. On the next agent update the alias will not be re-generated due to the altered $IsArchived value that is share by original note and alias.

So if a note has a $Created of 2 Feb 2023, you need to make a note (to be the container of an alias) at path /Journal/2023/February, 2023/February 2, 2023. To generate that use Date.format() and date format codes.

Figuring the path for new date related containers is locale dependent but looks to be (in order from root):

  • Journal
  • four-digit year. Format string y
  • full month + comma + space+ four digit year. Format string MM, y
  • full month + space + un-padded day +comma + space+ four digit year. Format string MM d, y

So in the agent action:

var:string vDatePath;
vDatePath = "/Journal";
vDatePath += "/" + $Created.format("y");
vDatePath += "/" + $Created.format("MM, y");
vDatePath += "/" + $Created.format("MM d, y");
create(vDatePath);
$Container = vDatePath;
$IsArchived=true;

[Edited: this code demo TBX (next post below) is correct but here I’d forgotten the / between the containers in the path, as I posted before I’d finished testing the TBX. Now fixed.]

Ok, here’s a demo TBX. Currently the agent looks for notes in /Notes that are not archived (user attribute $IsArchived is false). You may of course set a query better suited to your means.

The agent’s action (code in post above) does the heavy lift: if missing, it makes the necessary container(s) under /Journal, moves the alias to the correct container and marks the note archived (placing it out of scope of the agent query).

The prototype (also applied via the $OnAdd of /Notes) is simply there to set Displayed Attributes I wanted for texting.

To try, add a new note under the ‘notes’ container and watch what happens. If you want, turn off the agent, delete /Journal and contents, re-set $IsArchived in notes ‘d’ and ‘e’ and then re-start the agent.

Here’s the TBX: Journal maker.tbx (137.3 KB)

1 Like

Thank you. Yes, it occurred to me later that I should have specified aliases.

Trying to understand the code - are we not required to insert a forward slash at each appendment to the vDatePath variable?

Note that you can get close to your desired behaviour without any Agents or action code using the Attribute Browser (see for instance the screenshot an expanded version of @mwra’s notebook with two additional notes created today). You will see that the daily notes are duly organised by day/date.

Differences with respect to your requirements are:

  • AB does not create aliases. What you see are the original notes in the container of your choice. As a work around you could easily create an Agent for each month and then view the aliases in AB view.
  • AB view only shows one level of grouping (in this case the date with one category per day). There are to my knowledge no options for a second subgrouping. For you this means there is no month or year hierarchy and you would need to create yourself e.g via one agent per month or similar as mentioned above.

Journal maker.tbx (131.8 KB)

Ah, I did in the test doc after noticing the error from my first test , here in the TBX:

So the code example should read:

var:string vDatePath;
vDatePath = "/Journal";
vDatePath += "/" + $Created.format("y");
vDatePath += "/" + $Created.format("MM, y");
vDatePath += "/" + $Created.format("MM d, y");
create(vDatePath);
$Container = vDatePath;
$IsArchived=true;

I’ve only split the vDatePath creation out into lines as in a teach doc it’s easier for the reader to see the construction than it is in one long line.

Action code performance will not be affected by the few extra line breaks but in each user’s own work pick what you like. Coders may prefer the feeling of efficiency by reducing the number of code characters. For most I suspect legibility helps. We can also comment the code (again the granularity of what is described is personal taste, but for instance:

// make a variable to hold the path of the new container
var:string vDatePath;
// start the path
vDatePath = "/Journal";
// add each successive sub-container ...
vDatePath += "/" + $Created.format("y");
vDatePath += "/" + $Created.format("MM, y");
vDatePath += "/" + $Created.format("MM d, y");
// make the container note - if already present nothing happens
create(vDatePath);
// move the alias into that container
$Container = vDatePath;
// set the archival flag so the note does not match the agent query
$IsArchived=true;

I’ll amend the example above in my earlier post. sorry! :slight_smile:

1 Like

You are correct that AB view only categorises the selected attribute’s value to one level.

Of course, you can use the AB view to test for $Created being >= (after) and <= (before) dates giving you year or month scoped content in the main view.

OP asked for how to do, thus my answer. But, personally, if I was doing such date-based review, I’d use this method. I think some users find AB intimidating and the original method seems more ‘real’ as they can ‘see’ the calendar structure.

In other alternate method one could use an agent (possibly with extra dare-scoping query terms), sort the results on $Created (i.e. by date) and then view the agent contents in timeline view.

This reminds us there is no ‘one’ right way and that what if informative—in terms of display—is more subjective that we may assume. Helping hear in the forum brings that home to me. It’s a fine line guessing whether a question is asked because someone know no other (better?) way, or they know what they want but not how to achieve it.

So I modified the TBX further …

  • I’ve added a new agent that finds the Journal notes (prototype of 'pJournal)—you can amend that as you see fit.
  • I then opened the agent in a new tab. Doing so ‘hoists’ that container in the new tab. IOW the scope of of the tab is that container’s descendants.
  • I then switched the new tab to timeline view and opened the timeline properties (the ‘i’ button on the tab’s icon.
  • The then set the start attribute (setting $TimelineStartAttribute) to ‘Created’ and the start ($TimelineStart) to 1 Feb 2023 and the end ($TimelineEnd) to 28 Feb 2023.

So new we see 3 ways to do the review, the latter two of which don’t require building lots of date-based containers):

  • building a container-based date journal using aliases
  • using Attribute Browser view
  • using Timeline view

All works. Which is most informative is subjective. I’d suggest one might even use different ones for different tasks. this updated version now has all the above (method #2 kudos to @mdavidson): Journal maker2.tbx (197.4 KB)

After reading this thread, I harken back to my original point, quoted above. What I was alluding to is that it is helpful to understand your goal, the outcome you want from an effort and then you can choose from several paths, strategies, to get there. Sometimes the outcome is clear, e.g., a report, othertimes the outcome is not, e.g., what is going on with all these notes, what can a glean from, i.e., an exploration outcome. Nonetheless, both of these have a desired goal, and outcome. Also, it is often helpful to put a contraight (physical or emotional effort, budget, time, and priority) to help bound the effort.

As we see above, there are so many ways to traverse the field of knowledge with Tinderbox and its companion apps.

A big thanks to everybody for digging into this. The three different views are very interesting. It may sound imposing to ask as a followup:

  • can notes outside of the Notes container added to Journal in outline view? I tried e.g. descendedFrom(“/“) and other modifications. I ask because a small section of my TBX which will receive the Journal maker code looks on the top level like this:
    Screen Shot 2023-02-11 at 7.16.46 PM
    and so on. I could move all containers inside a new top-level Notes container, but I rather do not. (The scope can be chosen in the attribute browser.)
  • unchecking the IsArchived checkbox makes another alias. Wouldn’t it be better if the alias is deleted? This is only noticed in the outline view.
  • likely related to the above (a change of thought unfortunately), it is probably better to not add notes to Journal by default, but rather by manually checking the IsArchived box. Then only the notes that are considered worthy to be journaled will be evaluated.
    I realize now that the attribute browser is indeed very useful with the Created but also the Modified attribute.
    Journal maker-cz.tbx (281.1 KB)

There are a couple of ways to do this. You could expand the query to have it look at other notes. I also remember @eastgate or @mwra teaching me how to search from root, it has something to do with the “all” designator, but I really can’t remember now how it worked.

There is nothing magical about my use of a ‘Notes’ container. That approach was simply about ‘scoping’ the query. As docs get bigger searching every note in the doc all the time becomes more work so it pays to start by telling the app the part of the document or the type of note upon which you want to do the rest of the query.

You aren’t required to, but you make more scoped searching harder. As long as ‘rather not’ is a principled decision’ and not avoidance of ‘extra effort’ then that’s fine. If you need to do different, do different. The example wasn’t saying “do things only this way.”.

It depends. It was written that way because humans make mistakes. Unticking the box signals that this note needs re-assessing. Deleting the alias in the journal just deletes the alias (and that wasn’t something asked for.

The danger faced when looking at demos line this is to assume they were made specifically for us individually. In fact they are normally a best guess understanding of the process of the original questioner. So if their needs don’t match yours, you are now simply applying assumptions not in the demo.

If you want but that’s not what was asked for so not how the demo works. see my last answer above. Unless your process is the same as (as opposed to similar to) that in the demo you will need to revisit the starting assumptions and adjust code accordingly.

I believe you’re also misunderstanding the role of the boolean: it is informing the app whether a note (has been assessed for and) been archived. You’d need a second boolean to indicate which notes were to be archived: only to indicate ‘please archived’ and another to record that action had occurred. Otherwise you’ll be re-doing things you thought were already done.

Again, avoid being too literal in interpreting the examples given. My demo wasn’t saying $Created was the only attribute you can use. I expected people to interpret that as _$Created or any other date-type attribute). But the whole point of AB view is you can use any attribute. Thus the name. Unless the demo is written for one person and only shared with that person, most people will need to adjust the ideaas a bit when re-using them.

When looking at the demo, first look at the pattern of what is being done rather than the specific settings. the latter makes sense once you know what is going on and will have the context to know what oyu’ll chnage if re-using it for your own task.

All queries search from root, i.e. the whole document. This is the driving idea being scoping an agent query or find(query). By starting with an inside(), descendedFrom() or $Prototype== term you ca rapidly cut the number of items tested in the second term from possibly 000s (in the whole doc) to a few 0s or 00s. The ‘all’ designator is pertinent to scoped operators like collect(scope,expression).

But there is legacy history and growth here. Initially, codes like collect() could only use designators as their first argument. I think 'all first arrived in v2.4.0. Then in v5.6.0 find() arriveed allowing codes like collect() to use a non-designator based argument by using a query called via find(query) instead. The likelihood of needing all today is probably low.

I hope that helps … :slight_smile:

Thank you. All is well and helpful. I am a beginner.

My scope and reversible checking problems are because I don’t understand the Journal creation agent code.

vDatePath = “/”; does have the effect that nothing is found anywhere. What would collect do in this context?

When using a boolean attribute with an agent (agent Pinned in the example) the alias shows when checked and disappears when unchecked. How to set up a second boolean, I don’t know.

Journal maker-cz2.tbx (317.9 KB)

That’s not a problem, that is exactly, to me the point of the forum, to help explain :slight_smile:

OK, yes, that’s in ytyou code but the agent action where this occurs actually defines vDate over four lines. This is from your TBX and this:

vDatePath = "/";
vDatePath += "/" + $Created.format("y");
vDatePath += "/" + $Created.format("MM, y");
vDatePath += "/" + $Created.format("MM d, y");

could be re-written as:

vDatePath = "/"+"/"+$Created.format("y")+"/"+$Created.format("MM, y")+"/"+$Created.format("MM d, y");

So the vDatePath += part is simply a shorter way of writing vDatePath = vDatePath + . IOW we are a_adding_ more (test) to the value of vDate.

So your agent action, if a note’s $Created date is 5th February 2023, vDatePath is:

vDatePath = "/"+"/"+"2023"+"/"+"April, 2023"+"/"+"April 5, 2023";

i.e. a string result of "//2023/April, 2023/April 5, 2023"

One obvious error is an extra ‘/’ has sneaked in. But were you wanting:

"/2023/April, 2023/April 5, 2023"

or

"/Journal/2023/April, 2023/April 5, 2023"

or something else?

The ‘Pinned’ agent works as expected. So the next question is which notes are you trying to archive? I’ll take a guess you want to archive only pinned notes. To do that, the “Journal creation agent” agent query becomes this:

descendedFrom(/Notes) & $Pinned==true & $IsArchived==false

If you want to find pinned notes anywhere the query is:

$Pinned==true & $IsArchived==false

And the agent action becomes (assuming we’re still using the /Journal branch of the document for storing aliases:

var:string vDatePath;
vDatePath = "/Journal"; //altered code
vDatePath += "/" + $Created.format("y");
vDatePath += "/" + $Created.format("MM, y");
vDatePath += "/" + $Created.format("MM d, y");
create(vDatePath);
$Container = vDatePath;
$IsArchived=true;
$Pinned = false;  //new code

This TBX Journal maker-cz2ed.tbx (327.0 KB) uses the latter of the two amended agent queries and the revised action. Using it, the note ‘Another Note’ at outline root and when $Pinned is ticked is detected, archived and $Pinned switched to false (un-ticked).

Does this help?

Indeed it helps a lot :slight_smile: I will digest and perhaps harken back. Thank you!

1 Like

A late thank you! Below is what I happily ended up with. Because a TBX file is text, it was easy to change names using find/replace in BBedit.
Journal maker-cz.tbx (207.0 KB)

2 Likes