Tabs macro viewtemplate question

So, I’m working on a small side-goal I set for myself way back, where all tiddlers would automatically have tabs for specific content.

I’ve found a bit of time today to work on this and the end result is pretty close to what I was aiming for, but there’s a few things I haven’t managed to get to work yet.

Tiddler 1:

title: stylesheet
tags: $:/tags/Stylesheet
body: """ 
.tc-tiddler-body {display: none;} 
"""

Tiddler 2:

title: New Tiddler
tags: 
body: """
this text is shown in the only tab that appears in the ViewTemplate
"""

Tiddler 3:

title: Tabs template tiddler
tags: $:/tags/ViewTemplate
body: """
<<tabs "[<currentTiddler>] [!has[draft.of]tag<currentTiddler>tag[Section (Tiddler)]]">>
"""
list-before: $:/core/ui/ViewTemplate/body

My end goal is for every tiddler to have at least 2 tabs, one for all tiddlers tagged with the currentTiddler, listed in a bulleted list-links, the second tab being the body text of the tiddler, and any tabs after that are added if they are also tagged with the tag “Section (Tiddler)”

1. How can I set the tab showing the body of the currentTiddler to say “body” and set that to the default tab, but not using the caption field, so when it’s used as a tab for another tiddler it doesn’t show as ‘body’ there as well

2. is there a filter I can make where one of the tabs shown a tab that titled “all” and lists every tiddler tagged with the current tiddler? or do I just need to make a template tiddler for that specific tab?

Edit: I just made two more template tiddlers instead, but that does still leave me with the 3rd and 4th question.

  1. Is there a way I can select specific fields of a tiddler to turn into tabs and use the field content as the tab text? ie “[has[meta]meta[]]” where it shows the meta-notes if the tiddler has them

  2. Is there a way I can have the tabs collapse in place of the body text using the fold tiddler button?

The simplest way to do this, I think, is to use the cascade mechanism to specify that what’s should be in the “body” role (for tiddlers that meet the relevant condition) just IS the template you’re making with all these tabs. After all (if I understand correctly), the text field of the tiddler is getting displayed as one of those tabs, right?

As for the fields section, I don’t have much more time to reply now, and I also realize I’m not sure I understand your goal clearly. In particular, are there fields that should always have their contents show up as a tab (so that they might be globally tracked in some way across your wiki), or do you want to specify on a per-tiddler basis which fields should have their contents transcluded as tabs?

Yep, it’s always the second tab and the default tab.
I ended up just making another template tiddler that transcludes the body text and took the reveal widget from the default viewtemplate for the tiddler body field, and changed out the css class to “wiki-tabbed-tiddler-body”

Ah, I meant as one of the tabs in my viewtemplate, like the all tagged tab and the body tab.
for instance, I was aiming to have a tab show up only if a tiddler had a field of notes, if it didn’t, then the tab would not be included. the tab would be titled notes, and the contents of the tab would be the contents of the notes field of that specific tiddler.

Edit: Attached is what I have working so far. TabbedTiddlersViewTemplate.json (1.3 KB)

I plan on replacing the body template from {{!!text}} to using the transclude widget, because I want to find a way to include an emptyMessage for the body that says something along the lines of “Nothing here.”

Your tabs macro takes a filter for its list of tabs.

So, in your filter for the list of tabs, you build in a condition to display the tab only if the notes field has contents.

Have a notes-tab tiddler (or whatever you want to call it) with this content:

{{{ [<currentTiddler>get[notes]] }}}

And change your main view template ($:/wiki/ui/ViewTemplate/tabbed) to include that tab conditionally in the list of tabs:

<<tabs "[[$:/wiki/ui/ViewTemplate/tabbed/all-tagged]] [[$:/wiki/ui/ViewTemplate/tabbed/tiddler-body]] [!has[draft.of]tag<currentTiddler>tag[Section (Tiddler)]] [<currentTiddler>has[notes]then[notes-tab]]" default:"$:/wiki/ui/ViewTemplate/tabbed/tiddler-body">>
2 Likes

Ahh ok- awesome, thanks @Springer :grinning_face_with_smiling_eyes:

One other minor question I have though, is there a specific way I need to setup the body transclusion so that stylesheets and the like render with cody-body formatting?

One followup:

If your notes ever include any styling or other complexity, then you may be disappointed to see plain text in that tab.

Instead, make the notes-tab wikify the content, like so:

<$wikify name="ToWikify" text="""{{{ [<currentTiddler>get[notes]] }}}"""><<ToWikify>></$wikify>

@Springer covered nearly everything I was going to say, so I’ll just add that you could also write a more generic filter like this…

[<currentTiddler>fields[]filter<fields-as-tabs>addprefix[$:/wiki/ui/ViewTemplate/tabbed/]]

where fields-as-tabs defines the list of fields you want to include…

\define fields-as-tabs() [{!!title}] :intersection[enlist[field-1 field-2 another-field]]

1 Like

I’m afraid this is a level far beyond my understanding :sweat_smile:

Edit: Also, I’ve noticed a critial error with my tab viewtemplate that I don’t know how to fix…

When I drag a tiddler in to import, it shows in <code> rather than as the normal import page.

To make the body transclusion follow the cascade conditions (which is what makes code-body “yes” tiddlers show as code, etc.), change your tiddler-body tab so that instead of just {{!!text}} it has:

<$transclude field="text" tiddler={{{ [<currentTiddler>]  :cascade[all[shadows+tiddlers]tag[$:/tags/ViewTemplateBodyFilter]!is[draft]get[text]] :and[!is[blank]else[$:/core/ui/ViewTemplate/body/default]] }}} />

(Note, your current solution — in the form you attached as a json above — is employing a hide-body trick, and my tip here requires you not to change that. If you choose to have the tiddler-body tab display according to the cascade condition, you should not ALSO use the cascade condition to always show tiddler body as this set of tabs (which is something I suggested earlier in this thread). If you combined that earlier advice together with my recent follow-up tip (without further modifications), then you’d have a house-of-mirrors effect of having a set of tabs within a set of tabs, unto infinity, within the “body” tab of each tiddler ;))

I imagine you meant to quote my code, not @Springer’s, which is quite neat and self-explanatory, I think! Breaking it down:

  • fields[] retrieves all the existing fields of the input tiddler(s) - in this case, that’s <<currentTiddler>>
  • filter<> runs all the input values (here, the list of field names) through a secondary filter—here, that’s defined in the variable fields-as-tabs, which we’ll come back to! If the secondary filter produces any result for a given field name, that field name (not the result of the secondary filter) will be passed on to the next step of the original filter. (This is in contrast to subfilter, which passes on the result of the secondary filter.)
  • addprefix adds the prefix $:/wiki/ui/ViewTemplate/tabbed/ to each input value it receives.

And in filter<fields-as-tabs>

  • [{!!title}] = the input value - in this case, the name of each field on <<currentTiddler>>
  • :intersection finds the values that appear in both the filter run it precedes and the previous one - that is, only the field names that appear in the list field-1 field-2 another-field

So if you used this filter on a tiddler with fields field-a, field-1, and another-field

  • [<currentTiddler>fields[]... gives field-a field-1 another-field
  • filter<fields-as-tabs> gives field-1 another-field. field-a is excluded because it doesn’t appear in [enlist[field-1 field-2 another-field]].
  • addprefix[$:/wiki/ui/ViewTemplate/tabbed/] gives $:/wiki/ui/ViewTemplate/tabbed/field-1 $:/wiki/ui/ViewTemplate/tabbed/another-field — which are, hopefully, tab templates for displaying the contents of field-1 and another-field respectively.

So when you refer to the hide-body trick, are you referring to the data-tags display:none or the reveal widget? Just asking so I know which one to change in order to not have that infinite tab bug happen (again lol) because it crashed my wiki last time :sweat_smile:

Also, will the cascase above also resolve the issue with the $:/import tiddler?

I’m referring to your stylesheet trick: .tc-tiddler-body {display: none;}

which is what makes it non-redundant to put your tiddler’s text field into a tab in your custom view template…

I’m not seeing any import bug when I set your json combination up at tiddlywiki.com (though you probably have made changes that I’m not tracking completely).

So I’m not sure what to suggest, except that you can troubleshoot by dragging any subset of tiddlers there (to tiddlywiki.com), and seeing whether things behave ok when you try an import. If so, then the problem is something other than that particular set of tiddlers.

Since @Justin_H responded with a :thinking: emoji, and since I like the basic idea here, I just tossed @etardiff’s suggestions into a demo here:

https://quick-demo.tiddlyhost.com/#tabbyView%20demo:[[tabbyView%20demo]]%20%24%3A%2Fwiki%2Fstylesheets%2FViewTemplate%2Ftabbed

All of the tiddlers involved in this solution are tagged with tabbyView. So if you drag that tag pill to your wiki, they should all come over and behave well together, and you can deconstruct them to see how they work, change which fields get included, etc.

(For what it’s worth, I’m still not seeing any problem with how the import tiddler displays.)

Enjoy!

2 Likes

Ah, ok- thanks for clarifying on that!

Alrighty, just got home, lemme see if I can recreate the import issue I was running into, and I will explain what I find.

Edit: Ok! so, to recreate the issue, drag n drop this json package of tiddlers into tiddlywiki.com/empty, then from another tiddlywiki, drag any tiddler into the tiddlywiki.com/empty wiki, and it will show the $:/import tiddler as json, not the normal view.

tiddlers.json (1.9 KB)

I like your thinking here @Justin_H and will look at your idea further, a few quick notes;

  • As discussed here RFC: Conditional UI elements Tabs/buttons and more and illustrated here https://conditional-elements.tiddlyhost.com/ I have recently poroposed extending the tabs macro and others UI elements to allow an optional condition field in tabs.
    • Just drag the $:/core/macros/tabs to your wiki (Be backup safe),
    • Thus your notes tab would have a condition of [all[current]has[notes]] and it would be displayed if the current tiddler has the notes field and it is “not blank”.
  • I recomend you always have some kind of condition or indicator to show tiddlers that will have these tabs, it is importiant to be able to enable or disable it (any additional feature) on a given tiddler, because there will inevitably be tiddlers on which you need to.

One thing I realised is what you are doing is not dissimilar to the tabs in the info button drop down.

  • So I was thinking what if your tabs (with conditions) had the tag $:/tags/TiddlerInfo then they would be available in the info dropdown. I know this is not yet what you are after, but then consider;
  • What if we then had a tool info dropdown to select any one or more of these tabs on the tiddler itself, as you are doing?
  • They will be available in the info drop down and you can add them to the tiddler selectivly.
    • To achive this we would have a list field eg; tabs-here containing the tiddler titles of all selected tabs (also a filter), that can be reordered and other methods could be used to add tabs to this list. eg [tags[standard-tabs]]

If you are interested in this idea, let me know and I will work on it sooner rather than later.

[Edited] and we would leverage the body cascade as @Springer suggests.

I have found this is a good mechanisium to implement many of my solutions so are going ahead now.

1 Like

Justin, the version of the body tab that you’ve got in that uploaded json doesn’t use the cascade condition that I suggested above (and which I implemented in my demo). See the implementation for the body tab here.

1 Like

Huh, that’s an interesting idea, i would imagine you could do this by checkboxes, where unchecked is $:/tags/TiddlerInfo and checked is $:/tags/TiddlerTab(or other tag name?)

not neccesarily something I would use at the moment but I’m sure it has it’s utility for others.

@Springer oops, you’re right, I missed that, thank you- the issue doesn’t occur with yours at all :grinning_face_with_smiling_eyes:

Actually I have some other mechanisms. I have implemented the initial design here https://conditional-elements.tiddlyhost.com/

  • The home tiddler has had tabs set, you can see where to adjust it via the info button.
  • For your requirements you would simply tag a tiddler you want to appear as a tab in the tiddler (give it a caption) and tag with $:/tags/TiddlerInfo.
  • Then click on the info tab, select the first tab and select your tiddler to appear as a tab. If you want the standard body as a tab also select content as well.
    • You can also drag and drop reorder below that.

Thought I would return with a new question regarding the tabbed layout.

Is there a way to use a filter for when it’s applied to tiddlers, like how you can with $:/tags/StoryTiddlerTemplateFilter with a filter like [!is[system]then[$:/wiki/ui/ViewTemplate/tabbed]] or [tag[Topic (Tiddler)]then[$:/wiki/ui/ViewTemplate/tabbed]] ?

Yes, you can use cascades with the View Template Body as well. Make a new tiddler with your chosen filter, tag it $:/tags/ViewTemplateBodyFilter, and make sure that it appears above $:/config/ViewTemplateBodyFilters/default in the tag dropdown.

You can access any of the template cascades via the Control Panel → Info → Advanced → Cascades, BTW!

1 Like