How to set a default prototype for new notes in a container?


(Anders Thoresson) #1

I want to have a default prototype for all new notes I add within a container. Is this done using a OnAdd-action in the Action pane of the Inspector?


(Anders Thoresson) #2

Nevermind: Found the solution in the Suggested Topics below my new post.

How can I delete this redundant topic?


(Mark Anderson) #3

Don’t worry, this is a useful question for new starters.

For later readers, Yes, the right approach is to use a container OnAdd action, which is stored in the container’s $OnAdd attribute. It can be set a number of ways, most convenient first:

  • Action Inspector, ‘Action’ tab. The code box here sets $OnAdd. Helpfully when setting a prototype, if you type $Prototype= the autocomplete pops up a list of currently defined prototypes. clicking one of those inserts the prototype’s name correctly quote enclosed.

Other methods:

  • Properties Inspector, Quickstamp tab. You can search for the $OnAdd attribute and set code here. Less use than above, not least because the input box doesn’t use the code auto-complete you get in the Action Inspector.
  • Get Info dialog, attributes tab, General Group, edit the $OnAdd attribute. Select the attribute and type in your code.
  • Via action code. Not a likely need for an OnAdd action, but mentioned for completeness sake. Any editable attribute can be set via action code. Remember though, that if setting the the attribute of a different note than currently selected you need to specify the offset, i.e. $OnAdd='$Prototype="Event";' vs. $OnAdd("another note")='$Prototype="Event";'

(Anders Thoresson) #4

A follow-up: If I not only want to set a prototype by default, for all notes created in a container, but also want to set a couple of Attributes, how do I do that?

For the container Quotes, I want to use the prototype Quote. But in the container there will be more containers, in a nested structure. For notes created in Quotes -> Magazines, I want the Quote prototype to be set, but also the attribute Type to be Magazine.


Automatically assigning prototypes to sub-folders?
(Mark Anderson) #5

In which case the OnAdd needs a way to figure out the context in which it is being run. Is the parent called “Magazines” or not. For instance, try:

$Prototype = "Quote"
if($Name(parent)=="Magazines"){
   $Type="Magazine";
}

You can put that in several container’s $OnAdd, e.g. via a prototype, but only thy a container called “Magazines” will set a value for type in children added to that container.

So far, so good, but I suspect there are other options not mentioned such as other sorts of quote containers that need to set a specific type. Rather than explicitly test for each type (if($Name(parent)==“Magazines”), if($Name(parent)==“Journals”), etc.) a bit of extra structure helps. As all notes/containers have a name we probably want a discrete attribute to hold there type, but not $Type so queries don’t mistakenly match containers of a certain type of quote note. Let’s make a $ContainerType, and in that, for container ‘Magazines’ we’ll store the value Magazine. For the “Journals” container, you’d store Journal, etc. For containers in the quotes hierarchy that don’t hold typed notes, leave $ContainerType blank. Now the general OnAdd is:

$Prototype = "Quote"
if($ContainerType(parent)){
   $Type=$ContainerType(parent);
}

Now, the same code can set different $Type values in different containers using the same code.

As a side note, if rolling out set of containers, do read up on how prototypes can ‘bequeath’ child notes/containers.


Automatically assigning prototypes to sub-folders?
(Anders Thoresson) #6

How can I make all notes and containers added to a top-level container use the same prototype? Can the OnAdd be inherited?


(Mark Anderson) #7

By top-level do you mean ‘root’, as in a note added directly to an empty document, or a note added as a child to an existing root-level note?

A document doesn’t have an $OnAdd as such (though perhaps it ought to if this sort of issue is common) but you can edit the default value of the doc’s $OnAdd via the System tab of the Document Inspector.

If you do that, all notes will inherit this default code. You can’t stop the inheritance, but you can at least constrain its effect to root-level items. For example:

if($OutlineDepth==1){$Color="red"}

Only notes added at root will turn red , and their children will be the normal default $Color.

The layout of a new doc is designed to just get you going, so it’s natural to use a root-level map. Personal experience over some years of Tinderbox means I avoid this for other than simple tests and experiments. For actual work and where I’ll be building in structure (e.g. OnAdd, Rule, etc.) I generally create a root-level folder and put all data as descendants of that container. This:

  • Gives me a controllable root-level container for OnAdd, rule, etc.
  • Makes it easier to move even my ‘top’ level of data (as it’s inside a container).
  • Makes it easier to put all back-of-hose stuff lies prototypes, templates, etc., out of scope of searches. For instance, if all content is in container at path /DATA, then descendedFrom("DATA") excludes all extraneous material.

So, I think it’s not always a good idea not a good idea to start a big project by throwing stuff into the default (root) map.


(Pat Maddox) #8

fwiw I usually have an Inbox note, which I keep open in its own tab. From there, some stuff gets moved automatically via agents, some gets moved via stamps, and others might be manual.


(Anders Thoresson) #9

On top level, I’ve got Sources as a container. In Sources, I’ve got a few more containers, like Books, Interviews etc.

One of the user attributes of the prototype that sources use is Type. For Books, I want this to be Books by default, for every new notes created. Etc.


(eastgate) #10

Why not have the OnAdd action for Books set the prototype of new notes?

Warning: It’s a bad idea to use a container as a prototype for its contents. First, the two things are different: a collection of books is not a book, and a book isn’t an instance of a library. Second, the default behavior for inheritances says that, when a note is assigned a prototype, it receives a clone of each of the prototype’s children; clearly, you wouldn’t want that! This behavior can be disabled by setting. $PrototypeBequeathesChildren to false.


(Mark Anderson) #11

I think this wasn’t directly answered, so ‘Yes’. If a prototype has an OnAdd, all notes using that prototype will inherit the same OnAdd action.


(James Fallows) #12

Via advice from long-time TB users and conjurers, led by Mark A and Mark B, I’ve ended up structuring just about all my TBX files with only two top-level containers. One I call System, and the other Content.

The System container is for all the plumbing and structure of the file. Within it I have a sub-container for Prototypes, another one for Agents (I prefer to keep them on this side of the divide), others for miscellaneous backstage business.

In the Content container, I have sub-containers for all the actual data I am trying to manage – research info, appointments, contacts, whatever the file is for. There are some on-add Actions for the whole Content container, for attributes I might want all substantive items to share. Then there are sub-containers with their own on-add actions (assigning prototypes, assigning rules, whatever.) The prototypes they’re referring to all are lodged somewhere within the System/Prototypes container, and they’re applied within the Content container structure some place. In many files I have an Inbox container within Content, as a storehouse for info that I am waiting to classify.

As with everything in Tinderbox, what works best for you will be slightly different from what anyone else does. But I did find it a help to hear from the TB masters (including Mark A, several entries up in this thread) about the value of using root-level containers for big structural classifications, and doing your detail work a level or two lower down in the hierarchy.


(Anders Thoresson) #13

And I was obviously stating the question so that it could be misunderstood. :slight_smile:

If I assign a prototype to a container, with sub-containers, will notes created in those sub-containers use the prototype of the parent container?


(Anders Thoresson) #14

I’m lost here. Perhaps in the terminology, perhaps in how TB works. I’ll try to explain what it is I want to achieve:

Per @JFallows advice above, I’ve now a top-level container called Content. In Content two more containers: Writing, for outlining my book, and Research, with all things related to research.

At the moment, I’m trying to find the best way to organize the Research container. In it, there are three more containers:

  • Sources – with Books, Magazines, Podcasts, Scientific papers, Interviews, Keynotes and other source types as subcontainers. These subcontainers will hold notes with meta-data about the individual sources I have.
  • Quotes – the quotes I plan to use from each of my sources. This container will hold notes for the start, but I will probably organize them using ornaments and containers as the list grows. Between the notes in Sources and the notes in Quotes I’ll create links. That way I can use the roadmap (if I’ve understood that feature correct) to see what Quotes are planned to be used from each Source. The notes in Quotes will probably be moved (or cloned) into the Writing container as I go along in my work and decide which quotes should be used in which chapter.
  • Topics – temporary notes for topics that are discussed in the Sources and which I plan to cover in my book.

For Sources, I plan to use these attributes:

  • Type – which is the same as the container name, Interviews, Books etc.
  • URL and Devonthink – with a link to either the internet or my Devonthink library where I can find the source.

For Quotes, I plan to use these attributes:

  • URL and Devonthink – with a link to either the internet or my Devonthink library where I can find the source.
  • Technology – what kind of tech the quotes cover (my book will be about technology and society, so this attribute is set to let me use the attribute browser to get an overview over what technologies and to what extent they are covered in my used quotes).
  • Context – what part of society the Technology discussed in the quote are having an effect on. Education, Private life etc are examples.
  • Sentiment – a numeric value from -2 to 2, grading wether the quote sees opportunities or risks with the Technology in the given Context.
  • Used – boolean attribute, checked when I’ve actually used the quote in my manuscript.

To keep manual work at a minimal, I want to use prototypes to assign these attributes to new notes created Sources and Quotes.

  • For the prototype to be used on the notes in the Sources hierarchy, could it be assigned to the Sources container and used on all notes in the sub-containers in such a way that the Type is set based on the name of the sub-container? So that when a note is created in Books, the Type attribute is set to Books?
  • When I drag’n’drop a note from Devonthink to one of the Quotes containers in Tinderbox, is there a way to have to note use the prototype I want the Quotes to use. And have the Devonthink link added to the Devonthink attribute instead of the URL attribute?
  • If I later on realize that my Quotes notes need more attributes, can I add them to the prototype and have the attribute added to each note using that prototype? Or are attributes only added when a new note using a prototype are created, meaning that all additional attributes that I want to add later on requires manual work?
  • Could an Agent be used to automatically create links between a note in Sources and all notes in Quotes that share the same URL in the Devonthink or URL attribute? For each note in Sources, select either the URL or Devonthink attribute (whichever is set) and search Quotes for notes where the URL or Devonthink match and create a link between the two, resulting in a 1 to many-relationship?

And, perhaps needed for you to have any advice on this, the reason I plan to organize my work in this way:

Over the years, I’ve built a large collection of text notes in Devonthink. These notes are quotes and my own thoughts on the topic of technology and society. Now it’s time to use them as building blocks in a book. To get things off the ground, my idea is to work through this quote-collection in Devonthink, adding all quotes I now find useful into Tinderbox. First in the Quotes hierarchy (when decided that a quote should be used), and later on into the Writing hierarchy (when decided where a quote should be used in my writing). The different attributes to be used on the Quotes notes is a way to let me use the attribute browser to get an overview of different aspects of the quotes, making sure they are somewhat balanced in terms of sentiment, technologies, context etc.

Of course, any input on this is welcome!


(Mark Anderson) #15

The short answr is ‘No’, unless you add logic so to do. One such method is to use a prototype whose $OnAdd attrbute sets any child note to use the same prototype. So, let’s image a prototype note ‘pBook’. We give it the $OnAdd:

$Prototype="pBook";

Now, any note using that prototype will have the same OnAdd action. Any child of such a note now automatically takes the same prototype and also inherits the same OnAdd (directly from prototype). You will see that neither parent nor child have set a local $OnAdd value but have in each case inherited a non-default OnAdd from the one set in ‘pBook’.

Are you asking because you’ve tried this method and it appeared not to work? It may be you have set local values (even null local values) and these are imeding inheritance. You might find it useful to read this tutorial on Tinderbox inheritance and then this one, more specifcally on prototypes and inheritance. Both were written using v6 but the UI and methods are unchanged in v7.


(Anders Thoresson) #16

Thanks! No, I had not tried what you are suggesting. I was rather expecting inheritance to be based on the position in the outline, which the first tutorial you are linking to explains is not how things work.


(Mark Anderson) #17

Good, glad that helped. The inheritance method is of course more obvious after you get it. I can see one might presume hierarchy had some effect. In fact, it doesn’t though you can draw some logical inference such as using ‘parent’ or ‘child’ designators in action and export code. Plus, in export, you can generate links based on hierarchy, e.g. ^childLinks()^.

BTW, here a page listing some more tutorials. The v6 ones should all still be pertinent, the v5 ones you may need to allow for a different UI. I’ve noted I proably need to update the page to show which don’t apply to v6+ at all/