Is there a way to see if a template exists in the vision client?

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