Display selected fields in a Tiddler but only those with values

The title says it all in a nutshell, but I cannot see how to do this in an elegant way.

I have a Tiddler with five fields: field1, field2, field3, field4, field5.

At the top of the Tiddler I want to display just field1, field3, field5 BUT only if the the fields are not empty (not NULL).

Thanks.

G’day,

There’s probably a shorter way of setting this up, but this lays things out well I find:

\define this_pattern() (?i)field[135]

<$list variable="this_field" filter="[<currentTiddler>fields[]regexp<this_pattern>]">
    <$list variable="this_value" filter="[<currentTiddler>get<this_field>]">
        <<this_field>>: <<this_value>><br>
    </$list>
</$list>

EDIT: ARG! Typo! I had flipped the positions of the “i” and the “?” in the macro. Fixed.

@myfta I am preparing a response with examples off line and there are two parts, I see something that tends to confuse people so I am developing a robust response.

  • If you explained your purpose a little more I may be able to give a more direct answer
  • That is your question is too general, Its hard to understand why you ask this, and can influence the best solution.

But incase it is all you need;

There is a little trick just out of view for newer TW enthusiast’s and that is the difference between has and has:field

  • the first asks if the tiddler has a field containing a value - this is the “Not empty” case [all[current]has[fieldname]]
  • The second asks if the tiddler has:field a field with a value or not? This is the “if field exists” case. [all[current]has:field[fieldname]]

If you are only interested in conditionally showing the value, you can use a ViewWidget.

<$view field=field1/><$view field=field3/><$view field=field5/>

If you want to conditionally display additional context or formatting then you can use a ListWidget.

<$list filter="[<currentTiddler>get[field1]]" variable=value>
''Label for field1:'' <<value>>
</$list>
1 Like

So far the best way I can find is to simply use a list to generate a fieldname; then choose what todo inside the list;

Literal fieldnames

<$list filter="field1 field2 field3 field4 field5" variable=fieldname>

</$list>

With variable and subfilter

\define field-list() field1 field2 field3 field4 field5
<$list filter="[subfilter<field-list>]" variable=fieldname>

</$list>

Found fields with prefix

<$list filter="[all[current]fields[]prefix[field]]" variable=fieldname>

</$list>

Then within this list you can do many things to <<fieldname>>s, Insert one or more of the following inside one of the above lists.

List fieldname only if it has a value

  <$list filter="[all[current]has<fieldname>then<fieldname>]">

  </$list>

List fieldname and value only if it has a value

  <$list filter="[all[current]get<fieldname>]" variable=field-value>
    <<fieldname>> <<field-value>><br>
  </$list>

List values if has value with get

  {{{ [all[current]get<fieldname>] }}}, 

And you can do any other thing you want to test or display, using the current tiddler and <<fieldname>> or <fieldname>.

Note:
Nested lists (one inside another) or a list containing a filtered transclusion {{{ filter }}} is an efficient way to do this despite peoples tendency not to do this. It allows you to name the variable using variable=fieldnameas an example allowing you to still access the current tiddler.

  • People seem to “want to write a single list and single filter”, but sometimes this means you need to do a lot of filter “gymnastics” to make it work, but this is totally unnecessary. Just nest lists.

The following is an example of combining one of the lists above with a way to display the result that most resembles the original request.

\define field-list() field1 field2 field3 field4 field5
<$list filter="[subfilter<field-list>]" variable=fieldname>
     {{{ [all[current]get<fieldname>] }}}, 
</$list>

I live in the +10 time zone so did not respond earlier thank @EricShulman

1 Like

I like your comprehensive solution, however. I can’t quite get the syntax to work in my Tiddler. It’s probably me but it does not like this line:

\define field-list() field1 field2 field3 field4 field5

This line I think is intended to have “field-value” defined, but I cannot see where that is happening:

<$list filter="[all[current]hasthen]">

Maybe there is some clever with your nesting trick that I don’t understand.

Thanks

Putting @TW_Tones pieces together:

\define field-list() field1 field3 field5
<$list filter="[subfilter<field-list>]" variable=fieldname>
  <$list filter="[all[current]get<fieldname>]" variable=field-value>
    <<fieldname>> = <<field-value>><br>
  </$list>
</$list>

note: re-edited to restore inner $list widget so that fields without a value are not displayed (thanks to @Ant for reporting this)

-e

Thanks @EricShulman
OK, that runs without an error, but it only displays the fieldname for the three fields on one line and no field-value.

So I get this:

field1 field3 field5

rather than what I was expecting:

field1 = Val1
field5 = Val5

field3 is empty so should not display.

Copy/paste the exact code I provided into a tiddler at https://tiddlywiki.com, and then add field1 with a value of “Val1” and field5 with a value of “Val5”. The output that appears is:

field1 = Val1
field5 = Val5

as intended. Note that \define field-list() field1 field3 field5 is a “single line macro”, and MUST be entered all on one line, and has no closing \end syntax.

If you put a newline following the \define field-list() syntax, then the macro has blank contents, and field1 field3 field5 “falls out” of the macro definition causing the tiddler to display

field1 field3 field5

as you described… and, since the definition of field-list is now blank, the <$list filter="[subfilter<field-list>]" variable=fieldname> widget no longer produces any output.

1 Like

I’m pausing working on this. I’m current having to work mobile on Android (in Tiddloid) and I have a suspicion my problems are because of the way that Android handles ends of lines.

Just to note that for me, at least, the previous code just displayed the field name and value only for fields with a value, while now the field name displays if it is present in the tiddler even when it doesn’t have a value. So something like:
field1 = Val1
field3 =
field5 = Val5

Is this intended?

Anthony

Just as a side note:

kookma Utility plugin has simple transclusion macros: Utility 2.1.7 — utility kit for authors and developers

For displaying code, code-link, content, fields, …

So,

<<fields myTiddler>> 

shows all fields with their values in nicely formatted table. Intentionally it displays empty fields.

To give a try online, open Utility 2.1.7 — utility kit for authors and developers, drag and drop this sample tiddler data_tid01.json (289 Bytes) and look at the examples.
edit data/tid01 and see how macros work.

I use Utility simple transclusion in TW-Script where I want to explain wikitext solutions.

oops… thanks for noticing this… I’ve reverted the code so it has the inner $list widget again. This prevents the display of fieldnames that have a blank value.

Yes, that was my original request.

The sample I gave, the first reply to this post, did anybody give it a try?

It worked out of the gate.

Are folk getting thrown off by the regexp?

@Charlie_Veniot

I tried it but for me it trips up at (i?), but as I have mentioned it might be Android problem.

I did wonder if the syntax was intended to be something like:

(i?)field[1,3,5]

Bad copy paste job in my original reply. Should be “(?i)”, and not “(i?)”.

Nope, that would be a negative.

In regular expressions, “[135]” means “in this one-character position, it has to be one of the characters inside the square brackets”, not separated by commas.

Using regexp is likely overkill for your purposes here, but I prefer the generic nature of the thing rather than typing in the actual names of many similarly named fields.

It is a pretty powerful operator, so I tend to use it in a lot of places just to maintain “usage memory.”

Ugh, I really ought to get through a cup of coffee before doing “investigations.”

Yeah: “(i?)” does nothing in a regular expression. That might be dyslexia kicking in. “(?i)” is the correct order of things.

OK, I’m back on dry land now and on a Windows PC, but I am still not getting this code working. It outputs:

field1 field3 field5

So here are my two Tiddlers

Have I missed something?

Thanks.

The code you have defines a single-line field-list() macro that contains just the list field1 field3 field5. As a result, when you use <<field-list>> in another tiddler, it only shows that list of fieldnames. The rest of the tiddler content is not actually part of the macro, and so it is only rendered when you show the “TiddlerFields” tiddler itself.

Do this instead:

\define field-list(names:"field1 field3 field5")
<$list filter="[enlist<__names__>]" variable=name>
  <$list filter="[all[current]get<name>]" variable=value>
    <<name>> = <<value>><br>
  </$list>
</$list>
\end
  • The above defines a multi-line macro with one parameter, “names” that has a default value of “field1 field3 field5”. Use <<field-list>> to show those three fields. You can show other fields by passing the list as a parameter, like this: <<field-list "foo bar baz">>

  • The first $list widget uses enlist<__names__> to convert the parameter value into separate items and iterate over those items, one name at a time.

  • You can change the line <<name>> = <<value>><br> to adjust the output as desired

enjoy,
-e