Equivalent of an array of objects

This is very rough (and doesn’t make use of a macro), but I just tested it in a new template tagged with $:/tags/ViewTemplate, and I believe it ought to generate the kind of table you’re describing.

<$list filter="[<currentTiddler>tags[]tag[Wizard]limit[1]]" variable="null">
<table>
<tr>
<td>Previous</td>
<td>Category</td>
<td>Next</td>
</tr>
<$list filter="[tag[Wizard]] :filter[<..currentTiddler>tag<currentTiddler>]" variable=category>
<tr>
<td>{{{ [tag<category>before<currentTiddler>] }}}</td>
<td><$link to=<<category>> /></td>
<td>{{{ [tag<category>after<currentTiddler>] }}}</td>
</tr>
</$list>
</table>
</$list>

A few notes:

  • The outer list is there to ensure that the table is only rendered on tiddlers with one or more tags that are themselves tagged Wizard.
  • I used a ViewTemplate because it’s the simplest way to automatically render the navigation table on all appropriately tagged tiddlers. If I were building this for myself, I’d probably use the View Template Body cascade mechanism to handle conditional display rather than nesting it all inside a list, but this is simpler to share.
  • If you replace [tag[Wizard]] with something like [tag{!!navigation-tag}] then users can set the specific uber-tag they want to use by adding it to a field called navigation-tag on the template tiddler. I’d probably go ahead and add the field with “Wizard” as its default contents.
  • I’m not sure if you’re interested in including links to jump to the first/last tiddler in a sequence, but if so, it should be pretty simple to add those columns.
1 Like

I guess the general answer would be to break it into multiple, easy-to-read macros. Then, if you want to change things, you change two macros. In the following, you can change the structure by changing the overall macro mytable and the individual rows in myrow. Each is very understandable on its own. And macro myrows – the one with the basic logic – doesn’t have to change at all. Sometimes it’s best to roll with the paradigms you’re given, rather than the twenty cents you thought you wanted.

\define mytable()
<table border=5>
  <tr> <th>prev</th> <th>title</th>  <th>next</th> </tr>
   <<myrows>>
</table>
\end
\define myrows()
<$list variable="tag" filter="[all[current]tags[]tag{$:/plugins/ScottSauyet/WizardNav/config/TagName}]">
<$vars 
  prev={{{[<tag>get[list]enlist-input[]allbefore<currentTiddler>last[]]:else[<currentTiddler>]}}}
  next={{{[<tag>get[list]enlist-input[]allafter<currentTiddler>first[]]:else[<currentTiddler>]}}}
>
<<myrow>>
</$vars>
</$list>
\end

\define myrow()  <tr> <td><<prev>></td> <td><<tag>></td>   <td><<next>></td> </tr>

<<mytable>>
1 Like

Well, I was assuming that the macro would be stored in a tiddler. If there is a way to create additional variables to be used in processing a tiddler, that would make it nicer still (no define ... end). But I don’t know how to do so. I assumed variables like currentTiddler were buried in the bowels of TW code. I see from your code that a simple transclusion seems to keep the variables alive. I will probably use that to clean up my code now that you point that out.

But I’m not sure that it offers anything for the larger problem of how to pass a list of lists or something similar (or now as you’ve pointed out, not pass them so much as store them in a variable the view could use). But I have a lot of reading to do, thanks to @TW_Tones.

Thank you very much for your help!

That might be best. But I’m learning a lot more about TW pursuing this than I would by sticking to the tried and true. I keep thinking that there’s an answer obvious to the more experienced, that I’m either too dense or too inexperienced to see. But it simply may not be.

I wouldn’t bother refactoring what I’ve got, though to a three-macro (or I guess just three-tiddler, per @drhayes) solution. I don’t think that gives enough benefit over the current just-override-the-view-template solution. But I haven’t tried.

And I have a separate objection, which is that the minute I do that, I’ll see some use for rules like: “If there are more than three rows, do X, otherwise do Y” or “Let me handle the odd rows differently than the even ones.” Sure, it’s easy enough to say that such is not supported, but the only reason to even try this refactoring would be to offer users a simple way to customize that output while I handle the logic.

I’ve been spending a lot of time in these discussions, and I seem to have brought in a lot of people with far greater TW knowledge than my own, so, while I haven’t tried everything yet suggested, I am starting to believe that what I want is either not possible or only possible with some arcane knowledge. But I have plenty still to read and try.

Thanks again for you input.

Thanks. My current solution is similar, although your version is written more cleanly. I’d love for the user’s override not to have to include this line:

<$list filter="[tag[Wizard]] :filter[<..currentTiddler>tag<currentTiddler>]" variable=category>

or [tag<category>before<currentTiddler>] and [tag<category>after<currentTiddler>], but rather for these to be supplied to them as usable variable or some such mechanism.

I have something similar in my yet-to-be-published version.

Thanks a lot, more to study! :stuck_out_tongue_winking_eye:

That’s already there in the published version.

For my own uses, I’m not interested, but if I ever manage to get this customization the way I want to, then it would make sense to include them too. I hadn’t even thought about it, though. But you’re right, that would make sense, and be easy to do atop everything else.

Thank you for the help! (And – maybe! – for the additional material to research.)

You could certainly define the filters as variables, but I believe it comes at some slight cost to performance. Saq has written quite extensively about good practice from a performance standpoint here, but the general recommendation is to avoid macro substitution when possible.

I do appreciate your effort to make your final product as user-friendly as possible! I’d like to gently suggest that it may be counterproductive to hide too much, though. If someone is interested in tweaking the display template, it’s likely that they’ve already gained some degree of familiarity with TW code, or if not, they’re at least considering dipping their toes in - and in this case, it can be more challenging to follow a structure across multiple macros and variable definitions than it would be to study it in situ.

As a personal example, while I have tremendous respect and appreciation for Mohammad’s wealth of out-of-the-box or otherwise beginner-friendly plugins, I found them very difficult to tweak as a low-intermediate user - mostly because he’s so very good at hiding his filters!

If you want to pretend that there are arrays, you could pack everything into strings. Here titlelists are packed into one string separated by &&& (you can use whatever unique token you need). Then they can be passed, reparsed, and used again. For testing, I used tags “HelloThere” and “BetaReleaseNotes” (limited to 3 tiddlers for the image below) :

image

\define firstpass()
<$list filter="[all[current]tags[]]" variable="tag"><$wikify name=passme text="""<$text text={{{ [tag<tag>]:reduce[format:titlelist[]addprefix[ ]addprefix<accumulator>] }}}/>""" ><$text text=<<passme>>/>&&&</$wikify></$list>
\end

<$wikify name=arrays text=<<firstpass>> >
<$list filter="[<arrays>split[&&&]!is[blank]]" variable="array" counter="count" >
Array <<count>> :
<$macrocall $name="list-links" filter="[enlist<array>]" />
</$list>
</$wikify>

Thank you, one more time. I did consider something like this, but believed that it was likely to be more complex than your demonstration.

With more and more comments, I’m getting the sense that what I really want is simply not possible. I’m not overly disappointed, as this was always at most a nice-to-have. I think the plugin is already convenient and easy to use.

Hmm, thought I replied to this earlier. Got distracted by that performance article, I guess.

If I don’t use so some technique to pass data from one place to another, there is no reason for this refactoring whatsoever. But I’m quickly coming to the conclusion that this is the best answer.

I don’t think of it as hiding information as much as of bundling it appropriately. As a developer/software architect, I write a fair bit of code intended for others’ code to interact with. As much as possible I try to simplify the users’ experience, writing libraries rather than frameworks, passing the right information to the user that they don’t have to keep calling back for more (outside volume concerns like pagination.) I was hoping to apply the same here.

But thank you for your gentle advice. It sounds like it probably will be best to drop this, at least until I have much better TW understanding.

1 Like

@Scott_Sauyet this reply is friendly content and does not demand any additional learning or work.

  • Sure, I suppose I am suggesting it is an alternate way to look at the same information - via the tag pills.
  • It think it important to recognise what you are trying to do is both helpful to your end users and a little difficult to wrap your head around, not so much the tag issues but the alternate mark-up views.
    • Your could just insist alternate views include the logic like your existing table, and simply switch between views.
  • In my example where the logic is calling conditional templates is the best answer I can come up with for now, there may be better ones but it is not trivial to solve this. The reason I know is I have built a commercial solution that had dozens of views and templates with alternate data sets.
  • A point I made earlier was to try and keep the presentation seperate from the logic. This is difficult in the template logic, but not when in comes to CSS - its easy to introduce this eg every 2nd row etc… via CSS but lets address that later.

Best of luck, you do now have a lot, if not too much advice, to consider but feel free to ask fresh questions as your go.

1 Like

G’day,

This may not be of any use to you, but I could not help but think of this, so I bring it up in case it can trigger helpful ideas for your efforts.

I’m a big believer that even the silliest of things, even if totally useless, can suddenly bring a light bulb moment (a great idea that seemingly has nothing at all in common with the silliest of things…)

Use Case for Session Storage: Fibonacci Series

Warning: yeah, I did unashamedly use some javascript for this. And I hope I never see, in my lifetime, TiddlyWiki core features added to handle this without javascript.

:smile:

I hope my joking tone about that came through. I appreciate everything people have been offering, and while I think I’ll probably set aside the attempt I was making, I am going to go through everything people have offered. Some of it offers clean-up or just alternate means of doing the same thing, good to know. But much of it looks to teach me a lot.

Yes, it is an interesting alternative. It’s not useful for my current project, where I want the resulting (read-only) wiki to be as familiar to navigate as possible for users. But I want it to have the wonderful cross-linking, and composition features of TW for users, and its editing facility for myself (and eventually other writers). Unless the users already know TW, they won’t even know that the site is implemented in it. Such users would likely see Tag Pills as merely decorative.

This is for me a large wiki. I expect at the end that I’ll have about 250 “pages”, tiddlers linked from the TOC, with 40,000 - 50,000 words of text, 50+ screenshots, and 200 code samples, consisting of perhaps 700 - 800 total tiddlers, many of them transcluded into multiple pages. I’m trying to take seriously Divio’s documentation breakdown, and as well as Reference, How-tos, and Explanations, I also have a handful of Tutorials of 5 - 10 pages each. It’s those, and those only, that will get this navigation treatment. Everything else will conform to TW’s non-linear philosophy. I will probably extract the shell of it to use for other documentation projects, both for work and for personal projects.

While I’m very happy with how it’s coming out, I’ve needed to reach more deeply into TW than I have before, and as I go, I learn just how much there is to learn.

It’s interesting that this is the sticking point. To me that was the simple part. I wrote this code because I wanted it myself on this project. I turned it into a plugin because:

  • I expect I would want it again on other projects
  • I thought others might possibly want to use it
  • it was a good way to learn more about Tiddlywiki

But I vacillated in writing the markup. I originally had three divs in a CSS grid. Something went wrong with that, and I temporarily switched to tables. Then I realized that there would occasionally be footers with multiple rows, and I kept the tables, even though I figured out what had been wrong with my first approach. (You know, in CSS “div” and “.div” mean very different things! D’oh!). But that vacillation made me think that a useful configuration possibility would be to allow the user to decide to override the footer markup. This was mostly a way to learn more about TW; I would love to get it into the plugin on my terms, but if I can’t, I’ve still learned a lot.

But I was stuck with the question that I’ve been asking in this thread; and I’m still mostly stuck, although I have three or four posts in this thread (including a recent one from you) to investigate. Perhaps a clean answer will eventually come through.

If that was what I was left with, I probably wouldn’t bother. The ViewTemplate is already its own tiddler. Anyone who had the TW skills to deal with the logic could simply override that tiddler in the first place. I’m not planning on offering additional views myself, only to offer that capability to others. I have what I need.

I haven’t looked at the implementation yet, but will soon. But after this long thread, I’m certainly coming to believe that this is not a solved problem.

Oh yes, if you look at the plugin, the HTML is simply structure and the CSS is used for all the design. I once considered myself quite good with CSS, but I haven’t kept up in the past decade. Still, those skills come back pretty easily.

Again, I have to thank you very much. This has all been very informative.

Ok, so that was random. I’m not quite sure what brought it to mind. But it was fun to look at.

Yeah, well now you’ve got me thinking, "How could I write a simpler Fibonnaci generator in wikitext. The only connection I can think of between TW and recursion is the potential error or recursive transclusion. Hmm…

Simulation of dynamic Array.

But I also have a couple of cognitive disorders going on, and everything is linked to everything. (And when I say everything, I mean everything there ever was, everything there is, and everything there ever will be. All intertwingled.)

Recursion in wikitext, no problem. Recursion that references the two previously generated values, that’s a challenge.

Recursion, fun. The rest of that problem: I had way more interesting, or more pressing, things to do.

That was a case of: this simple javascript that can be useful for a gazillion things, I much prefer put that javascript together, and then I can jump into those gazillion things right away. It was just about being able to quickly get to the fun-to-me stuff.

It’s not clear to me if it would make any difference to think of it as a single pair of values, equivalent to

const nFibs = (n, [a, b] = [0, 1], res = []) =>
  n < 1 
    ? res
    : nFibs (n - 1, [b, a + b], res .concat (a))

nFibs (10) => [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

Probably not, but I haven’t really thought the problem through yet, and it’s bedtime. But if you enjoy recursion and JS, you might like this:

And as I was in the process of making a snack I figured out exactly how to do the recursion thing with the two previously generated values without any javascript.

And now that I know how to do it, I’ve totally lost interest in actually doing it. The challenge isn’t there, so my interest is totally stifled.

That’s one of the effects of the cognitive disability: solve problems quickly, no ability to explain the solution, and lost interest when the solution is known. Everything is a shiny object, so many more interesting things to figure out.

Love recursion, loath javascript.

I will stare javascript in the eyeballs only if it solves more problems than it creates, and only if I can get it done and over with quickly.

But I do appreciate javascript for the good stuff people have done with it, and appreciate those who can stand working with it.

I use it mostly in an FP manner, and then its not bad at all.

Yeah, I wrote a popular FP library in JS to make it easier to do just that. So much JS you see in the wild is cringe-worthy.

I’d still love it if you’d be willing to share!

I wonder if I share this! :slight_smile: