Good Evening,
I’m working in Ignition 8.0 and attempting to use a dynamic binding on a template path. What I’d like to do is fall back to a default template if the dynamic one does not exist. Is there a decent way to do this in 8.0? I’ve found this link but that solution seems to only apply to version 7.9 and earlier. Should I be using system.gui.getQuality()? If so what propertyName should I check to see if the template exists?
1 Like
imo the best improvement of 8.0 is that resources are flat text files so I’d imagine you could do something like
def template_or_default(template_name):
import os.path
# or whatever the actual file location is
template_path = 'install_dir\data\projects\project_name\resources\' + template_name + '.json'
return template_name if os.path.isfile(template_path) else 'default_name'
template_or_default('foo')
I don’t have an Ignition instance handy to test right now so ymmv
You might have some success looking at the .loadedTemplate
property of the template component. You could pivot off of that when it goes to None
. Here is a visual example:
Note that, with this reactive approach, you will produce a warning in the log when the template component attempts to load a missing template. Unfortunately, there isn’t an equivalent for templates to system.gui.getWindowNames()
that would allow you to proactively (in an easy manner) determine whether the loading of a given template will succeed.
1 Like
Note that, with this reactive approach, you will produce a warning in the log when the template component attempts to load a missing template.
That's easy to fix--wrap the call to .loadedTemplate
in eval()
component = event.source.parent.getComponent('foo')
component.templatePath = 'foo'
# returns None or the name of the template
print eval("component.loadedTemplate")
That's a more elegant and portable solution than reading the filesystem but is there a way to hide the ugly "template doesn't exist" box? (edit: I know we'd be quickly defaulting to another template but I'd be surprised if it didn't flash)
It isn’t the reference to .loadedTemplate
that is broken and causing the warning, but that the loaded template is invalid (and thus legitimately None
); the use of eval is unneeded. EDIT: In other words, setting the templatePath
to something invalid is what actually generates the warning.
Thanks so much for the help, you two! I ended up going with the .loadedTemplate route. I’ve got a fallback/default template hidden behind the dynamically loaded one, then use a simple runScript expression on the dynamic template’s visibility, setting the visibility bound to:
!isNull(runscript('self.loadedTemplate', 1))
1 Like
Yeah, you’re right. I was looking at the log wrong.
So Vision.Components.TemplateHolder
is actually generating the error, so you’d have to load it from that end to catch that warning
The implementation of .getResourcesOfType
changed. This works for me on 8.0.16
def template_exists(template_name):
"""
Syntax: template_exists(template_name)
Parameter:
template_name: A string of the template's name. If in a directory prefix with the directory name: path/to/template
Return Type: This method returns a Boolean value of class bool. This method returns True if the template exists otherwise returns False.
"""
from com.inductiveautomation.factorypmi.application.model import TemplateManager
context = event.source.getAppContext()
project = context.getProject()
resources = project.getResourcesOfType(TemplateManager(context).RESOURCE_TYPE)
paths = [str(resource.getResourcePath()) for resource in resources]
if 'com.inductiveautomation.vision/templates/' + template_name in paths:
return True
return False
print template_exists('foo')
That’s a nice, concise solution @DaveRNeal. If you don’t see the bad template overlay then I think that’s definitely the way to go