Allow Dynamic Import; e.g. {import:{=myvar}}

The current {import:/mysnippet} command does not allow for variable import names such as {import:{=myvar}}. Working around this creates a lot of extra work in certain use cases, the code for which dramatically slows down TextBlaze's execution time.

For example, I have a long list of snippes with the shortcut names all prefixed with "yvfi" (e.g. "yvfiteeth", "yvfichoice", "yvfiprotein", etc.). I'd like to be able to use these in a mix-and-match fashion within the context of a repeat structure:

{note}
Total Number Of Responses: {formtext: name=responses; default=1; cols=3}
Person Being Quoted: {formtext: name=addressee; cols=50; default=You}
{endnote}{repeat: {=responses}}
{if:len(addressee)>0}{=addressee}: {endif}"{formtext: name=quote; cols=100}"

{note: trim=right}Import: {formmenu: name=mysnippet; default=choice; perfect; dairy}
{endnote}{if:{=mysnippet}=="choice"}{import:/yvfichoice}{elseif:{=mysnippet}=="perfect"}{import:/yvfiperfect}{elseif:{=mysnippet}=="dairy"}{import:/yvfidairy}{endif}


{endrepeat}

It would be much more convenient to be able to generate the import dynamically:

{note}
Total Number Of Responses: {formtext: name=responses; default=1; cols=3}
Person Being Quoted: {formtext: name=addressee; cols=50; default=You}
{endnote}{repeat: {=responses}}
{if:len(addressee)>0}{=addressee}: {endif}"{formtext: name=quote; cols=100}"

{note: trim=right}Import: {formmenu: name=mysnippet; default=choice; perfect; dairy}{mychoice="/yvfi{=mysnippet}"}{endnote}{import:{=mychoice}}


{endrepeat}

Of course, I can just enter all my imports in a long line of if/else statements. However, this causes a severe slow down in execution time, likely due to the if/then/elses being within a {repeat} structure. I'll initially have 32 choices I'll be included, but even at 15 the snippet becomes unusable due to how slow it runs. For example:

{note}
Total Number Of Responses: {formtext: name=responses; default=1; cols=3}
Person Being Quoted: {formtext: name=addressee; cols=50; default=You}
{endnote}{repeat: {=responses}}
{if:len(addressee)>0}{=addressee}: {endif}"{formtext: name=quote; cols=100}"

{note: trim=right}Import: {formmenu: name=mysnippet; default=choice; perfect; dairy; animals; foodchain; ancestors; plants; humane; honor; crops; teeth; natural; environment; iron; protein}{endnote}{if:{=mysnippet}=="choice"}{import:/yvfichoice}{elseif:{=mysnippet}=="perfect"}{import:/yvfiperfect}{elseif:{=mysnippet}=="dairy"}{import:/yvfidairy}{elseif:{=mysnippet}=="animals"}{import:/yvfianimals}{elseif:{=mysnippet}=="foodchain"}{import:/yvfifoodchain}{elseif:{=mysnippet}=="ancestors"}{import:/yvfiancestors}{elseif:{=mysnippet}=="plants"}{import:/yvfiplants}{elseif:{=mysnippet}=="humane"}{import:/yvfihumane}{elseif:{=mysnippet}=="honor"}{import:/yvfihonor}{elseif:{=mysnippet}=="crops"}{import:/yvficrops}{elseif:{=mysnippet}=="teeth"}{import:/yvfiteeth}{elseif:{=mysnippet}=="natural"}{import:/yvfinatural}{elseif:{=mysnippet}=="environment"}{import:/yvfienvironment}{elseif:{=mysnippet}=="iron"}{import:/yvfiiron}{elseif:{=mysnippet}=="protein"}{import:/yvfiprotein}{endif}


{endrepeat}

If I'm correct that the slowdown is coming from all the if statements being reevaluated, then a dynamic {import} should fix the problem in this use case.

Hi @Sean_P_O_MacCath-Mor,

I see what you mean. Unfortunately import doesn't currently support dynamic content. But there might be a workaround to using all those elseif statements.

Can you give me a few examples of the snippets you're trying to import? More importantly, do those snippets contain any dynamic content?

Here's my thinking. You could use keyed lists for this, assuming the snippets imported are simple ones.

{mainlist=["item 1"="content 1", "item 2"="content 2", "item 3"="content 3", "item 4"="content 4"]}

{formmenu: name=choice; values={=keys(mainlist)}}

{=mainlist[choice]}

Would something like that work for you?

Thank you, @Cedric_Debono_Blaze -- this is a really cool approach that almost works. Sadly, what I'm importing isn't quite simple enough, it seems. When I use something like this:

{mainlist=["choice"={import:/yvfichoice}, "perfect"={import:/yvfiperfect}, "dairy"={import:/yvfidairy}, "animals"={import:/yvfianimals}, "humane"={import:/yvfihumane}, "foodchain"={import:/yvfifoodchain}]}

... it generates an error; i.e. Unknown name "blaze_url" (which I'll explain below). However, even when I use simple text-only snippets to import the value assignments in the array (e.g. {mainlist=["first"={import:/shrug}], I get the error Invalid command in formula: {import:/shrug}. Have I misunderstood what you're proposing should work here?

To explain what appears to be the deeper issue with the import in this context though, here's a generic ipsum lipsum example based on the template that all the snippets I'm attempting to import use:

{import:/blaze_format} Nam at tortor in tellus interdum sagittis. Vivamus quis mi. Suspendisse enim turpis, dictum sed, iaculis a, condimentum nec, nisi. Fusce ac felis sit amet ligula pharetra condimentum.

Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut id nisl quis enim dignissim sagittis. Fusce egestas elit eget lorem. Sed fringilla mauris sit amet nibh.

For more on this, {repeat: 1}{blaze_url=["url"="http://yvfi.ca/carnivores/r", "title"="check out the resources on the 'Pellentesque Habitant Morbi' page", "variant"="colon"]}{import:/blaze_link}{endrepeat}{if: format <> "markup"}.{endif}

For context, the {import:/blaze_format} either allows to be set which format should be use (markdown, rtf, etc.), or autodects which to use based on the URL, and sets this value in a globally scoped variable to be used later:

{note}{if:{site:domain}=="www.reddit.com"}{format="reddit"}{elseif:{site:domain}=="www.facebook.com"}{format="markup"}{else}{formmenu: name=format;default=text;reddit;markup}{endif}{endnote: trim=yes}

While the {import:/blaze_link} snippet outputs a link that's formatted based on the "format" variable set from the previous snippet using the variables in the local scope of the {repeat} structure:

{isemail=testregex(blaze_url["url"], "([-!#-'+/-9=?A-Z^-~]+(\.[-!#-'+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@0-9A-Za-z?(\.0-9A-Za-z?)+", "i")}{bold={=catch(blaze_url["bold"], {="no" if format == "markup" else "yes"})}}{italic={=catch(blaze_url["italic"], "no")}}{variant={=catch({=blaze_url["variant"]}, "paren")}}{bracket={=catch({=blaze_url["bracket"]}, "paren")}}{suffix={=catch(concat(" ", blaze_url["suffix"]), "")}}{if: format == "text"}{if: isemail == "yes"}{=catch(concat(blaze_url["title"], ": "), "")}{=blaze_url["url"]}{else}{link: {=blaze_url["url"]}}{repeat: 1}{blaze_markup=["text"={=blaze_url["title"]}, "italic"={=italic}, "bold"={=bold}]}{import:/blaze_markup}{endrepeat}{endlink}{endif}{elseif: format == "reddit"}[{repeat: 1}{blaze_markup=["text"={=catch(blaze_url["title"], blaze_url["url"])}, "italic"={=italic}, "bold"={=bold}]}{import:/blaze_markup}{endrepeat}]({if: isemail == "yes"}mailto:{endif}{=blaze_url["url"]}){elseif: format == "markup"}{if: isemail == "yes"}{=catch(concat(blaze_url["title"], ": "), "")}{=blaze_url["url"]}{else}{if: variant=="colon"}{title=concat({=blaze_url["title"]}, {=suffix})}{suffix=""}{else}{title={=blaze_url["title"]}}{endif}{url_href={=extractregex(blaze_url["url"], "https?://w?w?w?[.]?(.+)")}}{repeat: 1}{blaze_markup=["text"={=title}, "italic"={=italic}, "bold"={=bold}]}{import:/blaze_markup}{endrepeat}{if: variant == "paren"} {if: bracket == "paren"}({else}[{endif}ref: {else}: {endif}{=url_href}{if: variant == "paren"}{if: bracket == "paren"}){else}]{endif}{endif}{endif}{endif}{=suffix}

Is there another way to get where I'm trying to go, do you think, ooor is it possible to put in a feature request to allow using imports with variables in something like the {import:{=myvar}} format, or is such a feature too far outside the capabilities of the blaze scripting language, do you think?

@Sean_P_O_MacCath-Mor - the list won't allow you to put import commands into it. But the value of a keyed list can also be a multiline text or even a variable.

What you could do is bring the sub-snippets into the main snippet, assign each one to a variable, and then put those variables into keyed lists. If there are commands involved, you'll need to use the ampersand to concatenate, so it's a rather involved process. But it should give you what you're looking for.

Let me know if anything is unclear and I'll try to come up with an example.

Here's an example:

{note: preview=no}
{list=["First choice"=option1, "Second choice"=option2]}

{option1="This is some text with "&text&" and a "&menu&"
And this is an additional line of text."}
{option2="This is the text for the second option with a formula for "&firstnumber&" + "&secondnumber&" which equals "&{=firstnumber + secondnumber}}
{endnote}
{note}
{formtext: name=text; default=dynamic text}
{formmenu: name=menu; choice 1; choice 2; choice 3}
{formtext: name=firstnumber; default=3; cols=5}
{formtext: name=secondnumber; default=5; cols=5}

{endnote: trim=right}

{formmenu: name=menuchoice; values={=keys(list)}}

{=list[menuchoice]}

It's not exactly an elegant solution, but it's a workaround until we can implement something more streamlined.

@Sean_P_O_MacCath-Mor

Also, can you give me a practical example of what you're trying to capture with the testregex command? I think it could be simplified considerably.

Could you post it in here please?

I'd like to keep that thread for regex-related scenarios :slight_smile:

Heyo - just wanted to let you know that I had a STUPID busy week last week at work, and have been travelling since saturday, and will be continuing to travel until Tuesday night, and will have a stupid busy rest of the week after that. However, once I get back from all that, I'll circle back around to this.

Thanks!

@Sean_P_O_MacCath-Mor - no worries at all :slight_smile:

Stay healthy and hit me up when you're good to go!

Upvoting because this is my most used case. I would like to clean up my existing snippets and avoid having multiple if statements.

This is an example of what I'm trying to achieve but spans across several snippets and imported-snippets:

{note}{formmenu: default=Option 1; Option 2; Option 3; name=choices}{endnote}
{mapping=["Option 1":{import:/snippet1},"Option 2":{import:/snippet2},"Option 3":{import:/snippet3}]}
{output=mapping[choices]}
{=output}

Snippet1:

Invoice Number: {formtext: name=invNum}
Product Code: {formtext: name=itemNum}
Freight Handling Code: {formtext: name=FH Code}
Total Credit: {formtext: name=credAmount}
Quantity Received Damaged: {formtext: name=Qty Damaged}
Lot Number Damaged: {formtext: name=Lot # Damaged}
Signed POD Available: {formtext: name=Y/N (Attach to email)}
Pictures of Damages Available: {formtext: name=Y/N}
Additional Comments: {formparagraph}

Link to original post that sent me here

2 Likes

hi @latetotheparty,

The approach with the keyed list unfortunately won't work with imported snippets with form fields.

We're working on add a Snippet Field to Data Blaze that could be a great way to solve this. It would allow you to store partial snippets in Data Blaze and then load them into your snippet with a query.

2 Likes