How to create a field macro similar to the tag macro

One useful feature of tag macro is that we can drag and drop the tag pill to import the tiddlers of that particular tag. Is something similar possible for fields - a field macro ??
I use fields instead of tags for organizing the tiddlers into groups to avoid overusage of tags. This is the reason for asking this question - so that I can drag and drop the tag pill for the field macro to import tiddlers with that particular field

It can be done but first;

When you drag a tag pill the tiddlers moved are those titles with the same tag value in there tags field.

So will you have a field pill for all the values in that field or something else?

I think the best solution may be a button (you can make look like a tag pill) that allows you to drag a package of tiddlers according to a filter given to the button, then you can use it for any conceivable set of tiddler titles.

The $button widget has a dragFilter parameter that you can use to define a “draggable payload” of tiddler titles.

Try this:

<$button dragFilter={{{ [has:field[fieldname]format:titlelist[]join[ ]] }}}>
   drag to import tiddler with fieldname
</$button>
  • replace “fieldname” with your desired field name
  • format:titlelist[] adds doubled square brackets around titles that contain spaces
  • join[ ] combines all matching titles into a single space-separated text string (otherwise, the dragFilter param only gets the first matching title)

enjoy,
-e

7 Likes

Eric presumably the dragFilter parameter triggers the JSONification of all the filtered titles to enable the drag and drop between wikis, is there a way to leverage the existing core code to allow it to be;

  • Exported to a file as well?
  • Saved/Imported as a JSON to the current Wiki?

I know it can be done other ways but it is cognitively challenging, I would love to document other ways that are easy for everyone to use.

1 Like

Here’s a button that supports BOTH drag-and-drop AND click to download:

<$let filter="[tag[HelloThere]format:titlelist[]join[ ]]">
<$button dragFilter={{{ [subfilter<filter>] }}}> export tiddlers with fieldname
<$action-sendmessage $message="tm-download-file"
   $param="$:/core/templates/exporters/JsonFile"
   exportFilter={{{ [subfilter<filter>] }}}
   filename="tiddlers.json" />
</$button>
5 Likes

Why we need format:titlelist[]join[ ]?

I think we can use the below modification.

<$let filter="[tag[HelloThere]]">
<$button dragFilter=<<filter>> > export tiddlers with fieldname
<$action-sendmessage $message="tm-download-file"
   $param="$:/core/templates/exporters/JsonFile"
   exportFilter=<<filter>>
   filename="tiddlers.json" />
</$button>
2 Likes

You are correct. When I was initially writing my example code, I used something like this

<$let tids={{{ [tag[HelloThere]format:titlelist[]join[ ]] }}}>

to get the actual list of tiddlers to export. This was done so that I could quickly display and verify the tiddler titles when I was testing the code. However, both the $button “dragFilter” and tm-download-file “exportFilter” params can accept filter syntax, so it’s not necessary to “pre-compute” the filter results, and it is sufficient to simply pass the filter syntax as the parameter value.

3 Likes

Sorry for the late reply. I had gone for sleep after posting the question yesterday night.

Thank you @EricShulman @Mohammad @TW_Tones for the replies, suggestions and solutions you have shared.

Based on the abovementioned code by Eric and Mohammed, I made some modifications as shown below to also have a pop up with tiddler list and download option - See here

<$let filter="[field-name[field-value]]">
<$button dragFilter=<<filter>> class="myfield"  popup="$:/statefieldmacro">field-name:field-value
</$button>
<$reveal type="popup" state="$:/statefieldmacro">
<div class="tc-drop-down">
<$button> export
<$action-sendmessage $message="tm-download-file"
   $param="$:/core/templates/exporters/JsonFile"
   exportFilter=<<filter>>
   filename="tiddlers.json" /> 
</$button>
<<list-links "[field-name[field-value]]">>
</div>
</$reveal>
</$let>

I want this to be made into a macro so that I can easily use it anywhere instead of typing the whole code everytime I need it. I don’t know how to do it correctly. I need to define the variables (field-name and field-value) using let widget initially I guess . Can someone guide?

2 Likes

Here is a quick example of turning this into a macro, with minimal changes, place it in a tiddler tagged $:/tags/Macro And you can use either of the two forms of ways to call the macro in the below example.

\define macroname(field-name field-value)
<$let filter="[$field-name$[$field-value$]]">
<$button dragFilter=<<filter>> class="myfield"  popup="$:/statefieldmacro">$field-name$:$field-value$
</$button>
<$reveal type="popup" state="$:/statefieldmacro">
<div class="tc-drop-down">
<$button> export
<$action-sendmessage $message="tm-download-file"
   $param="$:/core/templates/exporters/JsonFile"
   exportFilter=<<filter>>
   filename="tiddlers.json" /> 
</$button>
<<list-links "[$field-name$[$field-value$]]">>
</div>
</$reveal>
</$let>
\end
<<macroname fieldname fieldvalue>>
<$macrocall $name=macroname field-name="fieldname" field-value="fieldvalue"/>
  • I will leave it for you to test.
  • It could be optimised I expect however it makes it easy to see what you needed to change to make a macro and use parameters
1 Like

@TW_Tones How to use this method discussed by telumire to get unique pop ups for this macro? You must have seen that discussion.

@TW_Tones where you able to check it ?
@telumire Any suggestions on how to get unique pop up for the field macro discussed above - here is an example tiddler where the pop up aren’t unique.

1 Like
  • No, its for you since you must have a wiki with the field-name="fieldname" field-value="fieldvalue" you are testing.
  • The button popup= and reveal state= needs to “generate a title” such that it is unique for each time such a button is displayed eg <<qualify $:/state/>> however if this is not unique, in the same tiddler, you need to "qualify the state tiddler title even more.
  • This is straying off the Original Topic
  • Look At the links provided in replies for the OT
  • Perhaps start a more appropriate topic for;

I had tested it and its working. But the pop ups are not unique. Thats why I asked because I had already posted about it two days back.

I had tried using qualify macro, but it was not working. I will upload a demo of my testing today.

I have been wanting to recreate the tag-pill macro to accept any arbitrary filter and have struggled adapting the built in macro. Thank you for the OP for the good question and the respondents for the example code. I have finally generated what I needed! See below:

\define filter-pill(pill_filter pill_label:"FilterPill Label" pillcolour:lightgrey textcolour:#333333)
<$button dragFilter="$pill_filter$" class="tc-tag-label tc-btn-invisible" style="background-color:$pillcolour$; color:$textcolour$;" popup="""$:/temp/state/$pill_label$""">$pill_label$
</$button>
<$reveal type="popup" state="""$:/temp/state/$pill_label$""">
<div class="tc-drop-down">
<$button> export
<$action-sendmessage $message="tm-download-file"
   $param="$:/core/templates/exporters/JsonFile"
   exportFilter="$pill_filter$"
   filename="tiddlers.json" /> 
</$button>
<hr>
{{{$pill_filter$}}}
</div>
</$reveal>
\end

<<filter-pill "[!is[system]search:title[Drop]]" """Non-system Tiddlers With "Drop" in the title""" "grey" "white" >>
4 Likes

Thanks @mwiktowy for doing something I have being intending to for some time, the result is somewhat simple compared to what I imagined. From here we can;

  • Add a tag to introduce new elements to the filter pill as with tag pills $:/tags/TagDropdown
  • Create an alternative tag pill that looks like the regular ones but that responds to a filter eg todo not done
  • Make pills look a little different from tag pills
    • Perhaps add icons
  • Field value pill with drag and drop reordering

Thanks for the inspiration at the beginning of my Wednesday.

@arunnbabu81 have you know got what you wanted in the original Post?

I saw the post, but didn’t get time to test it. Have been busy for the last few days. I will test it later today

I got what I asked for in the OP earlier itself,but the pop ups are not unique. If I press on one field-pill, all other filed-pills also will show the pop ups (even with solution by @mwiktowy)
Check this tiddler.
Will try to solve it later.

In the definition of filter-pill(), the popup uses """$:/temp/state/$pill_label$""" to construct the popup ID. Thus, all filter pills that use the exact same label text will be displayed at the same time.

I suggest doing TWO things:

  1. Change the popup ID to use <<qualify """$:/temp/state/$pill_label$""">>. This will ensure that filter-pill popups that occur in different tiddlers will have unique ID values, even if they share the same $pill_label$ text.
  2. Add an optional id param to the macro: \define filter-pill(pill_filter pill_label:"FilterPill Label" pillcolour:lightgrey textcolour:#333333 id), and use <<qualify """$:/temp/state/$pill_label$$id$""">> to construct the popupID. This will allow you to pass an extra id value to explicitly differentiate filter-pill popups that occur in the same tiddler, like this:
<<filter-pill "[!is[system]search:title[Drop]]"
   """Non-system Tiddlers With "Drop" in the title""" "grey" "white" 1>>
<<filter-pill "[ae-cycle[shadow]]"
   """Non-system Tiddlers With "Drop" in the title""" "grey" "white" 2>>
<<filter-pill "[leftbar[shadow]]"
   """Non-system Tiddlers With "Drop" in the title""" "grey" "white" 3>>
2 Likes