Cascade-like mechanism with centralized logic

I’m still working on my Periodic Table wiki, and I’m wondering about whether what I want to do is straightforward in wikitext. I can do it with JS, and will if I have to. But is there a way in TW to do something similar to the cascade mechanism, but with the logic centralized in a single tiddler rather than scattered with one tiddler per case?

If you look at an element, say Copper, you will see that the footer shows the values of most of the fields of this data tiddler. I actually want to add formatting to many of these, to display units or add links or some such. I’d like to get output something like this:

element: [[Copper]]
atomic-mass: Ar°(Cu) = 63.546
atomic-number: 29
atomic-radius: 1.6 pm
boiling-point: 2835 °K
density: 8.96 g/cm3
discoverer: Prehistoric
electronegativity: Pauling scale: 1.9
element-type: [[Transition Metal]]
first-ionization: 7.7264 kJ/mol
group: [[11|https://en.wikipedia.org/wiki/Group_11_element]]
melting-point: 1357.75 °K
metal: yes
metalloid: no
natural: yes
non-metal: no
number-of-electrons: 29
number-of-isotopes: 11
number-of-neutrons: 35
number-of-protons: 29
number-of-shells: 4
number-of-valence:
period: [[4|https://en.wikipedia.org/wiki/Period_4_element]]
phase: solid
radioactive: no
specific-heat: 0.385 J⋅kg−1⋅K−1
symbol: Cu
year: Prehistoric

But I don’t want to change the underlying data to add these units (especially because I think some of them may be wrong; I’m not a chemist!)

I’m imagining a macro, which I would call with something like

<!-- optional second parameter of tiddler, defaulted to current tiddler -->
<<display-field "melting-point">>

(although the field name in this case would likely be a variable, not hard-coded.)

I can do this in JavaScript with code like this:

const displayField = ((handlers = {
  'atomic-mass': (v, e) => `A<sub>r</sub><sup>°</sup>(${e.symbol}) = ${v}`,
  'boiling-point': (v, e) => `${v} °K`,
  'density': (v, e) => `${v} g/cm<sup>3</sup>`,
  'atomic-radius': (v, e) => `${v} pm`,
  'electronegativity': (v, e) => `Pauling scale: ${v}`,
  'element-type': (v, e) => `[[${v}]]`,
  'first-ionization': (v, e) => `${v} kJ/mol`,
  'group': (v, e) => v ? `[[${v}|https://en.wikipedia.org/wiki/Group_${v}_element]]` : ``,
  'melting-point': (v, e) => `${v} °K`,
  'metal': (v, e) => v || 'no',
  'metalloid': (v, e) => v || 'no',
  'natural': (v, e) => v || 'no',
  'non-metal': (v, e) => v || 'no',
  'period': (v, e) => v ? `[[${v}|https://en.wikipedia.org/wiki/Period_${v}_element]]`: ``,
  'radioactive': (v, e) => v || 'no',
  'specific-heat': (v, e) => `${v} J⋅kg<sup>−1</sup>⋅K<sup>−1</sup>`,
  'year': (v, e) => v || e.discoverer,  // interesting hack
}) => (field, element) => 
  (handlers [field] || ((v) => v)) (element [field] || '',  element)
) ()

(In each of these functions, v is the field value, and e the element, a data tiddler. If it’s in the way, I can choose to lose the second parameters; it’s only used in two places, and they’re inessential.)

I can easily convert these individual functions to wikitext, but I don’t know of a good way to convert the overall mechanism. I’m quite sure I can do this with the cascade. But that would mean having a separate tiddler for each of those functions. In one sense, I know that this is the TiddlyWiki way. I understand, and mostly agree with the Philosophy of Tiddlers, but I have a competing concern: the current goal of this wiki is for users to make their own copy and hack away at customizing for their own study, annotation, or other use of chemical information. These users will not likely be sophisticated TW users. But the parts should still be hackable. If they want to add a new field and they want it to get something more than the default formatting (just show the text), then I think it would be much easier to explain that they have to edit this tiddler than to explain the cascade to them.

I’m more than willing to be convinced otherwise: that this is a perfect use-case for cascade. So feel free to explain what I’m missing.

But I’m most interested in how to write in wikitext something similar to a switch statement or a if-elseif-elseif chain. Is this possible? Can it be done in a way that casual users can easily figure out how to extend it?

Regarding the :cascade filter run prefix, it just expects a list of filters to execute. You can determine where the filters are defined.

For example, defined in a single tiddler where the title of that tiddler is in the variable configTiddler, each on a new line:
<input-title> :cascade[<configTiddler>get[text]split[\n]]

I often prefer to exclude lines starting with \\ to allow for comments:
<input-title> :cascade[<configTiddler>get[text]split[\n]!prefix[\\]]

1 Like

Oh, of course. I had only seen this done with separate tiddlers. This makes perfect sense. Off to go read the cascade docs.

Just out of curiosity, do you often use back-slashes for comments? I’ve seen forward-slashes (//) often, but never backslashes.

We don’t have a standard for comments within filter expressions as of yet and I have settled on \\ primarily just because // puts me personally in the frame of mind of writing JavaScript and all of a sudden I will find ES6 style string interpretation in my filters, which of course doesn’t work. :slight_smile:

1 Like

I seem to be struggling with the syntax here. Do you happen to have a live example of this I could look at?

  • Do do otherwise would be foolish :nerd_face:

Personally I have not yet made use of the “Cascade Filter Run Prefix” outside of the UI cascades.

  • To me its value is when it is evaluated to return a list of filters

In a similar situations I write a macro eg display-fieldname you call with <$marocall $name=display-fieldname fieldname=<<fieldname>>/> then that macro;

  • Either hard codes the format for each filename
  • Or looks up a template in a field or tiddler by fieldname eg $:/fields/fieldname
    • In this case we would lookup the units field or a display format

For example, at a high level, given number-of-neutrons obtain the value on the current tiddler and then display something like this

Number of neutrons: value unit

  • With the fieldname
    • Replace - for space
    • Apply sentence case and append “:”
    • Display the value
    • Append the units obtained from $:/fields/fieldname!!units (if any)

Using this approach if you need to change the units or some other aspect of a field just open the appropriate fields tiddler eg number-of-neutrons appropriate unit field. You need not return to the more complex code in the macro.

  • The lookup Operator can be useful but for some reason I usually end up not using it.
  • I mostly write my macros to act on current tiddler if possible

I can share more details just ask.

This is great in the simple cases, but if you look at my list of my various formats, I need something more. I really need a format per field. (with some possible sharing between basic ones.) Here are the different types of outputs I’ve already come up with:

Unadorned field values:

atomic-number: 29
discoverer: Prehistoric
number-of-electrons: 29
number-of-isotopes: 11
number-of-neutrons: 35
number-of-protons: 29
number-of-shells: 4
number-of-valence:
symbol: Cu

Simply appended units:

atomic-radius: 1.6 pm
boiling-point: 2835 °K
density: 8.96 g/cm3
specific-heat: 0.385 J⋅kg−1⋅K−1
first-ionization: 7.7264 kJ/mol
melting-point: 1357.75 °K

Prepended units:

electronegativity: Pauling scale: 1.9

Values linking to tiddlers or sites:

element: [[Copper]]
element-type: [[Transition Metal]]
group: [[11|https://en.wikipedia.org/wiki/Group_11_element]]
period: [[4|https://en.wikipedia.org/wiki/Period_4_element]]

Booleans defaulting to no if not defined:

metal: yes
metalloid: no
natural: yes
non-metal: no
phase: solid
radioactive: no

Oddities using multiple fields from the data tiddler:

atomic-mass: Ar°(Cu) = 63.546
year: Prehistoric

That very last one is a bit of a hack, but it’s useful. The elements that have no year value have for discoverer either Prehistoric or Early historic times. It makes sense to me to show these values for the year when it’s not defined. But if it will make my life easier, I would skip both of the last two, since then I only need access to the current field value.

It’s this variety of display formats that prompted the question. The JS code I wrote is relatively simple. I’m hoping to find similarly simple way to do this in wikitext. The suggestion from @saqimtiaz looks as though it will let me do this. But I’m having one of my periodic run-ins with syntax, and haven’t yet gotten it to work.

But I’m off on a short vacation starting tomorrow, and maybe on my return next week my brain will be refreshed. I may or may not see responses while I’m gone, and may or may not be able to implement changes while I’m away.

Understood,

  • If you cant simplify it use the field definition model.
  • Further you can introduce a field type ie a field has a field-type also defined, so more than one field can have the same field type.
    • Re-use a field-type as need, perhaps turn units into a value recorded in the field definition and pass it to the field-type
    • Once you have a set of field definitions and field-types when a new one comes along it is a simple matter of cloning a similar one and making slight changes to get a new one.
  • It is such a virtuose circle I feel we should have a packaged solution that could be used as a defacto standard, and people can just write their field definitions and field types or reuse existing ones.
  • The think is if the template used to display the field value is transcluded you can introduce any wiki text you want that applies the correct formatting
  • If it starts to get too complex to set the display formatting in a single field we just make global macros to simplify it.
  • I would even give you the structure and high level design if you are not in a hurry.

I am sure wikitext can handle any possible display format and logic, and can share from a host of methods but to do so we need the specific requirement for each.

What I found in the past is with a structured wikitext based solution each challenge, once solved with a wikitext snippet is almost always reusable in another context.

  • For example years ago I made a menuing system, before the menu bar plugin existed, and I found the code used to iterate the menu items, or perform an action on click of the menu item if written in wiki text almost always was also suitable for;
    • Use in listing items
    • Rendering forms
    • Sidebar tabs
  • and a lot more. Meaning the Native Wikitext/macro and widget solution was always much more reusable.

Yes, I think this might simplify things. I will look at it again at some point, although quite possibly not until after vacation.

Thank you very much for your feedback.