Problem point ^children()^ to the right template


(Brian Crane) #1

Hi all. I’m having trouble getting a bit of export code to pull data from the correct note’s attribute.

The code I had initially was this:

^children(^value($PostListTemplate)^, 10)^

This wasn’t doing what I wanted: it exported the first 10 children but using the regular template assigned by their prototypes and not by the special templates I’d named in the attribute. Eventually I realized that the code was pulling the $PostListTemplate data from the note holding the code (i.e. the parent) and not the children.

So I then tried:

^children(^value($PostListTemplate(child))^, 10)^

This worked correctly for the first child: it pulled the template name from its attribute and used it to export the child note. But then it seemed to use that same template for all of the subsequent children even when different templates were named in their attributes.

Next I tried ^children(^value($PostListTemplate(children))^, 10)^ but this just seemed to default to the prototype defined templates, and now I’m fully stumped.

So does anyone know how to point this export code to each child note’s own $PostListTemplate value?


(eastgate) #2

The syntax is

^children( template )

^children always exports the children of this note. Perhaps you want to ^include( note,template) instead?


(Paul Walters) #3

child is the same as child(0), which is the first child of this note. That’s why you get that first child’s $PostListTemplate for all children.

Your export code would need to grab
^value($PostListTemplate(child)…
and then next grab
^value($PostListTemplate(child(1))…
and then
^value($PostListTemplate(child(2))…
and so on. If this is even possible.

Or use an agent or a stamp or some other technique, as export pre-processing, to setup those child notes with the correct template.


(Brian Crane) #4

Yes, this is what I was trying to do:

I may be going about this the wrong way though.

Here’s the context. I have built all the export templates for a web site and everything is working as planned. I have decided though that I would like a blog-style page of most recent notes. These notes already have an export template set by their various prototypes that ^include()^ the various pieces of their exported page (headers, sidebars, etc.). For the new page of recent posts all the sidebars, headers, etc. should appear just once and should be provided by the listing page, not the items on the list, which means ^children^ on its own won’t work here. So my thought was to pull the contents that go inside an <article> tag on each note’s regular export page into a list of <article> containers on the recent notes page. (Each notes’ <article> contains a few <div> filled will info pulled from the notes’ $Name, $Text and a few other attributes.)

So I created secondary export templates for the various notes that strip away everything except this <article> export info and stored the secondary template name for each note in $PostListTemplate using the note’s prototype. The export code I posted sits on the “recent notes” agent’s export template and was my attempt to then use these secondary templates to compile the list I wanted.

I’m wondering now if I need to rejig everything so that the most basic <article> template is the default set in $HTMLexporttemplate so that intermediate steps can be used to add export code rather than remove it.

updated to make all those tags visible!


(Mark Anderson) #5

To expand, ^children^ includes the contents of each child note of the currently exporting note, using each child’s own export templates as currently set. In general use, all notes will just inherit a common export template so the nuance of the above is not clear. But, if you set different export templates for each child, the differences will show up as a different form of data will get included for each child note.

Perhaps we want to override the chidlrens current export template for this context and use another template which we’ve created and named ‘Test1’. The syntax is now:

^children("Test1")^

Note the template name must be unique. If it isn’t instead of the title you must cite the whole $Path of the template which is normally not quoted).

If we have stored ‘Test1’ as the value of $MyTemplateString, perhaps becausewe have other code changing the stored template value, then the code would be this:

^children(^value($MyTemplate String)^)^

Note, the ^value()^ expression must evaluate to the unique name or or full path to a valid export template. The parameter is not intended to accept ad hoc export code in lieu of a template:

Separately, we can ask for data for only the first N children. To get the first 10 items in each of the above cases:

^children(,10)^
^children("Test1",10)^
^children(^value($MyTemplate String)^,10)^

I think to get what you want, you do need include. To save typing a long essay to explain, I’ve made a demo file. See http://www.acrobatfaq.com/tbdemos/child-inclusion.zip

Interestingly, it seems that as at v7.0.3, ^include()^ does not accept group designators (like children) althuogh its first parameter is [item|group], so you need to use a find().


(Brian Crane) #6

Thanks @mwra for the test file. It made good sense and points me toward what I was looking for. Much appreciated.

On my end, I moved the expression from inside() to an agent so that I can fiddle with the list contents without having to fiddle with the export templates once they are up and running.

So what’s happening here is:

  • the inside() says roughly “things exist in this container”
  • the find() says roughly “oh, okay, well then here’s a list of those things” (in outline order?)
  • the include() then works through the list sequentially.

Is this more-or-less the case?


(Mark Anderson) #7

I assume this relates to the deme export template code (for those without the demo):

^include(^value(find(inside("Test cell")&$SiblingOrder<11))^, ^value($PostListTemplate)^)^

The syntax for ^include^ is: ^include( item|group[, template] )^

So…

First parameter: a list of one or more notes (either as $Name or $Path). It appears ^include^ doesn’t (currently) accept group designators, so to pass a group of notes we need one of:

  • a literal list e.g. “/animals/ant;/animals/bee;…etc”.
  • a find(query) that returns a list of paths (one or more items). N.B find does not de-dupe, so unlike an agent query you may need to filter out aliases.
  • a group designator (currently not supported for this operator)

Second parameter. An optional export template. If supplied, use the template to render contents from the list evaluated from the first parameter input. The template, is either

  • A literal string with an export template (unique) $Name or full path if not unique.
  • A string attribute storing an export template (unique) $Name or full path if not unique

A difference—and one only I spotted testing this issue—is that in the case of an attribute-stored template, for ^children($StringAttribute)^ the attribute is evaluated in the parent (calling) note whereas in ^include(find(query),$StringAttribute)^ the context of evaluation is each list item.

In the demo the find() method for the first parameter. Generally, simple queries return matches in $OutlineOrder, but this can’t be assumed - especially with more complex queries (e.g. a query looking at the contents of an agent). If sort order is important, I believe, you can sort a find() within a query input. Lightly tested, the following tested in my demo file seemed to work to give a reverse outline sort: find(inside("Test cell")&$SiblingOrder<11).sort.reverse.

The fact find() doesn’t de-dupe can mean inside() gives unexpected results. inside() doesn’t match only the actual notes found in that container but also any note with an alias in that container. I’ve found that it is often more sensible to test the $Name (or $Path if not unique of the parent of the original). An alias will never match - unless alias and original are in the same container.

So, yes, but with all the various wrinkles outlined above.

Last point, if doing more than the most trivial use of action export code, these are good stylistic rules:

  • Give prototype a consisten naming syle (a prefix character is best) ensuring they are never misteken for a normal content note. This aslo assumes the prototypes are not use as content, only patterns for such, and are best stored in the default /Prototypes container
  • Don’t re-use Titles, i.e. $Name must be unique. If necessary, store the non-unique name in an attribute and use it for $DisplayName but have a unique value for name so queries work correctly
  • The same goes for (export templates). If you use unique $Name then you can juse just the title and not clutter your code by using full paths. In current Tinderbox, you might was well add a built-in template to create the default /Templates container and attendant HTML page prototype.
  • Do not use a forward-slash ‘/’ or normal parentheses ‘(’ and ‘)’ in a $Name. Why? Because it tends to not get parsed properly either as a $Name or a container section of a $Path. This is especially troublesome when using action-code linking/unlinking codes. Use the same approach as above of having a ‘safe’ $Name and caching the real title in a string attribute which can then be used for display purposes. I hit this issue all the time when my notes are the title of academic papers.

Does that help?


(Brian Crane) #8

Thanks Mark.

In my case, (for good or for ill…time will tell), my “site” container is mostly agents collecting sets of notes from a workspace. I think this sorts out a lot of the complications involving originals and aliases with inside() that you point out.

So thanks again for the help. It’s much appreciated.