Open Vision Template via script

Hello!
I am currently running a 8.1 version of ignition on my laptop and I am working on script to add additional required roles on components. I have written one for vision windows and it executes without issue. I ran couple tests and it adds the new role for all components. However I am not able to change the component permissions on the templates. It doesn't throw any exceptions and it returns the roles when I print them in the console.
I am not sure if I am required to open the templates and make changes similar to vision windows? I have not been able to find a way to open templates via scripts so I am not sure if its even possible?

code to change the permissions:

#import the template and the container class
from com.inductiveautomation.factorypmi.application.components import BasicContainer, template
from com.inductiveautomation.vision.api.client.components.model import VisionComponent
#import the permissions class
from com.inductiveautomation.vision.api.client.components.model.security import ComponentPermissions
#get the names of all windows
windowNames = system.gui.getWindowNames()
#initial a list to hold all the templates
fullListofTemplates = []

#get the role maps created in the table
tableMap = event.source.parent.getComponent('Table').data
#stores the column as a list
itemMaps = tableMap.getColumnAsList(0)
itemSrcs = tableMap.getColumnAsList(1)

#This script sets the permission to include the mapped roles
def setPermissions(container,isContainer):
	permissions = ComponentPermissions.get(container) #gets the component permissions of the component
	requiredRoles = permissions.getRequiredRoles()	#gets the exempt roles as a list for the component
	
	#We only want to run the permissions when the required roles are selected						
	if requiredRoles is not None:	
		#iterates through the input column
		for item in itemMaps:
			#checks if the exact string is present in the exempt roles list for the component
			if item in requiredRoles:
				itemIndex = itemMaps.index(item) #gets the index of the input column
				requiredRoles.append(itemSrcs[itemIndex]) #adds the desired role to the exempt roles list
					
		permissions.setRequiredRoles(requiredRoles) #sets the new exempt roles as a list as a component permission
		if isContainer == 1:
			container.putClientProperty(VisionComponent.COMPONENT_PERMISSIONS,permissions)
		else:
			container.putClientProperty(template.VisionTemplate.COMPONENT_PERMISSIONS,permissions)
#		ComponentPermissions.set(container,permissions) #sets the new component permissions to the component
		
#		print 'window name is: ' , window
#		print 'parent name is: ' , container.getParent()
#		print 'container name is: ', container
	return

#iterate through all the windows in the list
for window in windowNames:
	system.nav.openWindow(window) #opens the window, which allows the designer to view and edit its components
	rootContainer = system.gui.getWindow(window).getRootContainer() #gets the root container
	
	setPermissions(rootContainer,1) #calls the permissions function
			
	newComponentList = rootContainer.components	#adds all the components inside the root container as a list
	componentCheck = [newComponentList]	#adds the list to a dynamic check list of the components
	
	#iterates until the dynamic check list is empty
	while componentCheck != []:
		firstIndex = componentCheck[0] #gets the first item in the list
		componentCheck.pop(0) #removes the first item in the list
		#iterates through all the components in the first item
		for component in firstIndex:
			
			#checks if the class of the component is a group or container and adds it to the dynamic check list.
			#This allows us to check for components inside nested containers.
			if isinstance(component, BasicContainer): 
			
				setPermissions(component,1)	#sets the permissions of the container
				
				newComponentList = component.getComponents() #gets the components inside the container as a list of objects
				componentCheck.append(newComponentList) #adds the list to the dynamic check list
			
			#checks if the class of the component is a template. 
			#This allows us to check for components inside a template	
			elif isinstance(component, template.TemplateHolder):	
						
				setPermissions(component,0)	#sets the permissions of the template
												
				newTemplateComponents = component.getComponents() #gets the components inside the template as a list of objects
				
				#Only adds unique templates to the list, this significantly reduces the runtime of the script
				if fullListofTemplates == []:
					fullListofTemplates.append(newTemplateComponents) #adds the list to the dynamic template check list
				
				if str(newTemplateComponents[0]) not in str(fullListofTemplates[-1][0]): #checks if the name of the template already exists
					fullListofTemplates.append(newTemplateComponents) 

#				if not any(str(newTemplateComponents[0]) in str(fTemp[0]) for fTemp in fullListofTemplates): #checks if the name of the template already exists in the list
#					fullListofTemplates.append(newTemplateComponents) 
			
			else:	
					
				setPermissions(component,1)	#sets the permissions of the component	
				
	#same as the component check above
	while fullListofTemplates != []:
		index = fullListofTemplates[0]
		fullListofTemplates.pop(0)
		for component in index:
		
			if isinstance(component, BasicContainer):
				setPermissions(component,1)		
					
				newComponentList = component.getComponents()
				fullListofTemplates.append(newComponentList)
				
			else:
				setPermissions(component,1)	
						
	#closes all vision windows except for the changeRoles window
	if window != 'changeRoles/onComponent':
		system.nav.closeWindow(window)


Windows and templates are conceptually very similar objects. It wouldn't surprise me if you have to do something very similar to both.

Yup, but:

Precisely. No such thing, since Templates are cannot be opened "bare" in a client. Only the designer opens them by themselves.

2 Likes

Is it possible to open the templates just in the designer with a script? We are not planning on releasing this to client.

I don't know. There's no system.* function to do so. It might be possible going "under the hood" with SDK methods, but you would be blazing a trail for the rest of us.

1 Like

haha fair enough :slight_smile: I will see what I can achieve and share any success I find.
Thanks for your time!

I figured this one out. This script will open templates in the designer:

from com.inductiveautomation.factorypmi.designer.workspace import WindowWorkspace
from javax.swing import SwingUtilities
windowWorkspace = SwingUtilities.getAncestorOfClass(WindowWorkspace, event.source)
windowWorkspace.openTemplate('templatePath') #insert your template path here

When fired from an event script, it uses swing utilities to locate the WindowWorkSpace of the designer. It then uses the workspace's built in openTemplate method to open the specified template.

4 Likes

Well done!

1 Like

this is awesome! I had given up.

1 Like