Tinderbox Forum

How to put the top level notes in alphabetical order

How does one put the top level notes in alphabetical order?

Thanks.

Bryan

Create a new root note, move the containers into it. Sort that temporary top level container. Then move them out.

As you’ve found, the root (top-level) notes don’t have a parent as such—well, it’s the actual document. So you can’t set $Sort for their parent container in the sort Inspector.

Well, you can, but only by using the System Attribute Inspector to to change $Sort. In doing so you are actually changing the default value of $Sort for the whole TBX. So if you set it to “Name” I suggest you let the root content sort then reset (i.e. delete the value of “Name” in the default box).

I think easier is to make a new root level note and demote your content to there and sort the container. Dang, had to take a call, only to see the latter’s already suggested by @PaulWalters. In which case, I agree and recommend his solution!

On a general point, for all but quick tests, I put the ‘content’—my notes etc.—into a root-level container leaving the root for templates, prototypes and other back-of-house stuff.

1 Like

Just as a follow-up for @mwra @PaulWalters and other adepts, would be interested in your advice on this approach, which I have used for a long time:

  • At the root level, in all files, I have two containers.
  • One container is “System,” which includes all “plumbing” for the file. Prototypes, agents, everything that we’d call “infrastructure” (as in that hallowed U.S. occasion of “Infrastructure Week”).
  • The other container is “Data.” All of the “info” in the file is within that container, either as items at the top level of that container, or (more typically) in a variety of sub-containers and folders.
  • Then I have nothing else at the root level–no other notes, no other containers.

AFAIK this approach has two advantages:

  • Since the only elements of the file that are at root level, are the two master containers ( System / Data), you avoid any of the oddities of root-level functionality for the rest of the file.
  • It makes it easier to target agents and queries and so forth – and, in most cases, to exclude everything that is descendedFrom("System") from agents, queries, etc.

Does this match Approved Practice?

1 Like

Makes sense to me @JFallows. I usually have a “data” top level container. Sometimes I have two, driven by the way I like to set up exports – i.e., an “exportable data” container and an “all other data” container. That’s just personal preference though.

I often keep several other containers at the top level — old drafts, experiments, TODOs, and a dashboard.

1 Like

I used to use a ‘system’ container type approach, but /Prototypes, /Templates and /Composites are created at root so I prefer to use those locations rather than elsewhere.

Quite what you put at root is moot and depends on the task. I think the key take away is don’t, except for ‘quick & dirty’ work, e.g. simple tests, put 'content, i.e. the real work, into root, use a root level container for all the content. It saves faffing around down the line. With one container all the non-work stuff - prototypes, templates, code notes, etc., is outside the ‘root’ of the single ancestor container holding all content.

Indeed, if there were a feature to allow me to open a customised blank file rather than the app default, I’d probably add the prototype & template containers and a ‘CONTENT’ folder and open the map inside content and the outline at root but with ‘CONTENT’ selected. It avoids the trap of starting work in the root and then having to migrate stuff later.

I’m quite sure others may differ, but that’s my experiential take on this.

HTH :slight_smile:

Perhaps this is the best splash screen when we launch Tinderbox.

image

1 Like

I didn’t expect quite such an interesting discussion to emerge from my daft question. Thanks. BH

1 Like

How does one stop an agent fetching items from certain locations, such as my “superseded” and “prototype” containers which not live at root level?

So, if my agent is $Prototype==“type_1” but I don’t want to find those “type_1” which are in the superseded container. What do I add to the agent?

Thanks.

BH

‘not’ queries can get a bit exotic. I’d add a user Boolean IsSuperseded and set my 'Superseded` container’s $OnAdd to:

$IsSuperseded = true;

If notes are sometime ‘un-superseded’ you can set the container’s $OnRemove to:

$IsSuperseded=;

So that removing the note resets the attribute to default. Now your agent query is much simpler:

$Prototype=="type_1" & $IsSuperseded==false

For superseded notes of the desired prototype, they will fail the query due to the second term. Remember to that we use = in actions to set an attribute value and in queries we use == to test eqality (i.e. does left equal the value of right), or != for inequlaity

Tip. For user Booleans, think whether the natural state is true or not. The default of a boolean is false and it’s easiest to only set the attribute to true for exceptions. I usually name my booleans with an Is or Has start word, e.g. $IsRetired, as that remiinds me—months later—that this is a boolean (and don’t overlook to fill in the ‘Description’ box provided in the user attribute Inspector). If, $IsRetired would be true in most cases, one approach is to name it $IsNotRetired, flipping the meaning and allowing most notes to hold the default false value. It may appear counter-intuitive but I find the apprach becomes quite natural. This is exactly the method used by the system attribute $HTMLDontExport and which explains the odd sounding naming of the attribute.

Hopefully the explains my choice of the boolean’s name. If you are trying to map the above to the short-form test of an attribute value, these are the same test:

$IsSuperseded==false
!($IsSuperseded)

Or the opposite:

$IsSuperseded==true
$IsSuperseded

I suggest using the first, longer syntax until you feel expert enough to use the latter without mistakes.

HTH

This is not to differ with any of the advice that @mwra has given, since he is literally the Person Who Wrote the (Reference) Book about Tinderbox syntax and commands. But – in keeping with the “It Depends!” spirit of the software, as set out by @PaulWalters – here are some other possibilities to bear in mind, any of which can get you to a similar destination.

  1. The “descendedFrom( )” approach. If the notes you want to exclude from the search are either immediate children of “Superseded,” or are “grandchildren” or further descendants, you could used the query term:
    & !(descendedFrom("Superseded")
    (or whatever the parent note/container’s name is)

  2. The “parent” or “grandparent” approach. Similarly:
    & !($Name(parent)=="Superseded")
    or
    & !($Name(grandparent)=="Superseded")

And, as always in Tinderbox, there are variations in how you could compose similar queries.

FWIW my practice, shaped by guidance by the viziers here over the years, usually follows what @mwra is saying about creating a new attribute to indicate the status of items that you’d like to exclude, or include. Then you base the query on that attribute – rather than on queries using descendedFrom or parent or grandparent. Ie, setting the $IsSuperseded value either manually, or by agents or rules or actions, and then having that be the basis for your query.

Good luck!

1 Like

Agree with all the last. It neatly side-steps this issue where the scope is to check only children of the target container. inside() is you command for that, but if using aliases of notes, be careful you don’t get false positives. Users generally assume the latter operator means ‘is the original of the note a child of the nominated container?’ but it’s a little more complex, so if going that route, do test first. The divergent behaviour is deliberate and for a reason, but too tangential to describe here).

IOW: trust, but verify!

That great. Please remind me how to create the $OnAdd. Is is an action, a rule or an edict? What should the instruction look like. BH

Open the inspector and look for this tab:

2020-10-04_07-27-22

If the note is a container, then the action you define here will be the $OnAdd action.

Dear Paul,

Don’t tease me. What should I type in the box into which your lowest arrow points?

Yours sincerely,

Bryan


Bryan Heaney

Not a tease. That’s the area where you type your on-add action code.

Some (minor) examples:

$NameColor="red";$Badge="camera";

Will set $NameColor and $Badge for every note added to the container when they are added (“on add”).

The action could be as simple or complex as you want. Use action code here just as you would in an agent.

Bryan - is there a specific case you wanted to achieve with and $OnAdd action beyond what’s discussed in the thread?

That a great help. There is nothing else I need to know (for now). Thanks. BH

Where do I put an $OnRemove command?

BH

Two tabs to the right of the tab I showed you above. I.e., “Remove”. Same deal. Add whatever action code you want to “Remove” and that becomes the $OnRemove action.

2020-10-04_07-27-22

See more about the Action Inspector