Custom widget parameters values validation

Hi!

I’m working on a custom widget and I want to validate user input values for parameters. For example, the $default parameter should contain a default value for the widget when the target field is missing or blank, just like <$edit-text> widget’s default parameter.

I first tried to use a <$parameter> widget, but default value for parameters are only used when the widget attribute value is missing, so I can’t use it to validate any user-defined value.

So I ended up using this pattern:

\function init.default()
  =[<$default>!is[blank]]
  =[<now "YYYY0MM0DD">]
  :filter[<currentTiddler>format:date[YYYY0MM0DD]match<currentTiddler>]
  +[first[]]
\end

\widget $my.widget($default)
<$let
 myDefault=<<init.default>>
>

<!-- relevant code using <<myDefault>> here... -->

</$let>
\end $my.widget

My real widget has 6+ parameters, all of which must be validated, leading to a lot of code verbosity. Did any of you work on this kind of problems? Do you have alternative code patterns to showcase? Or enhancement suggestions?

Thanks in advance

Fred

I think in this case verbosity is your friend, because it will be easier to maintain in the future. The only one, which sees the verbosity is a developer. So that should not be a problem for your users.

I do not understand, why you have a $default attribute name. They are used by the GenesisWidget and there they are reserved for the core. So IMO you should not use it for custom widgets.

You could use _default if you need to.

1 Like

Thanks @pmario for your answer.

Well it’s an error! :sweat_smile: I wanted my widget interface to be like an <$edit-text> and until I checked docs to write this topic I really thought the parameter name was $default, not default! Oops! I’ll change it, thanks for the advice.

Fred

If you want to you can move the function inside and then you don’t need the let statement.
You can also simplify your validation logic a bit by re-structuring the filter since validating the date format will handle blanks too and ~ will only be processed if the previous filter hasn’t returned a result
eg.

\widget $my.widget(default)
  \function myDefault() [<default>format:date[YYYY0MM0DD]match<default>] ~[<now "YYYY0MM0DD">]

  <<myDefault>>

\end $my.widget

or for more verbose:

\widget $my.widget(default)
  \function myDefault()
    [<default>format:date[YYYY0MM0DD]match<default>]
    ~[<now "YYYY0MM0DD">]
  \end myDefault

  <<myDefault>>

\end $my.widget

Testing:

* <$my.widget/>
* <$my.widget default=""/>
* <$my.widget default="20250202" />
* <$my.widget default="Not a date" />
  • 20250310
  • 20250310
  • 20250202
  • 20250310
2 Likes