Is there a better way to add Templates to the UXML?

Hi,

Taken from the example in the docs:

<engine:UXML ...>
    <engine:Template src="/Assets/Portrait.uxml" name="Portrait"/>
    <engine:VisualElement name="players">
        <engine:Instance template="Portrait" name="player1"/>
        <engine:Instance template="Portrait" name="player2"/>
    </engine:VisualElement>
</engine:UXML>

My question pertains to the src attribute of the Template node. It’s very cumbersome having to write the full path of where the template may exist. For example, imagine if I have a UI library of templates for the organization/game ie. “/Assets/Scripts/UiToolKitSystem/Templates/Users/Portrait.uxml” and many others.

If I or any other person decides to refactor the path/folder structure, it would be very annoying to go through each of the uxmls and do a find/replace.

One solution is to have the ability to define and use global variables much like the USS custom properties that can be used in the UXML and automatically interpolated. For example:

<engine:UXML ...>
    <engine:Template src="<portrait_path>" name="Portrait"/>
    <engine:VisualElement name="players">
        <engine:Instance template="Portrait" name="player1"/>
        <engine:Instance template="Portrait" name="player2"/>
    </engine:VisualElement>
</engine:UXML>

In another file:
portrait_path = "/Assets/Scripts/UiToolKitSystem/Templates/Users/Portrait.uxml"

Something like this could be extended to work with i8n localization.

Let me know if anyone has come up with an elegant solution for this.

Perhaps this is something that the ThemeStyleSheet can be used for… or something like it.

I think the UI Builder’s way is a bit different than the docs, because it also includes fileID and GUID in the src.

<ui:Template name="SelectItem" src="project://database/Assets/UI/Templates/SelectItem.uxml?fileID=9197481963319205126&guid=3699d6f77680a410aa64fa0154908f3f&type=3#SelectItem" />

My test template file path is “/Assets/UI/Templates/SelectItem.uxml”

When I move it to “/Assets/UI/SelectItem.uxml” nothing changes in the UI builder (or in game scene). After I resave the root uxml document in UI Builder, it automatically changes to:

<ui:Template name="SelectItem" src="project://database/Assets/UI/SelectItem.uxml?fileID=9197481963319205126&guid=3699d6f77680a410aa64fa0154908f3f&type=3#SelectItem" />

It seems, it is enough to use just fileID and GUID like this:

<ui:Template name="SelectItem" src="?fileID=9197481963319205126&guid=3699d6f77680a410aa64fa0154908f3f&type=3#SelectItem" />

The documentation was written from the point of view of maintaining UXML files manually, before the UI Builder existed.
The most straightforward fix in this usage scenario is to use relative paths, so for example <Template src="Portrait.uxml" name="Portrait"/> would resolve relative to the current document file path. If both files are moved and this relative path is still valid, there is nothing to update.

For the UI Builder we added the ability to save GUID/FileID so that moving files around does not break existing USS/UXML files, while still maintaining partially human-readable text files. I would advise to always keep the path, not just the fileID/GUID because:
1- it makes more sense when looking at the UXML file inside a text editor, version control system, etc.
2- you would end up fighting the UI Builder which always saves path+guid/fileID

1 Like

What version has this ability? I’m currently on 1.0.0-preview.18 for both Builder and Toolkit, but every time I move a file everything breaks and I have to reassemble them. GUID and FileID are NOT written into the uxml when I use UI Builder:

<ui:Template name="Notification" src="Dialog/Notification.uxml" />
<ui:Instance template="Notification" name="Notification" />

It does use relative links but I’m still figuring out how I want to structure my folders, which means those slugs are likely to continue changing (if I can find a way to change them without breaking everything every time)

Hi,
What version of unity do you use? Do you have to use the UI Builder package since the UI Builder is now builtin.

Thanks for the response.

I’m in a bit of disagreement with the relative path fix. IMO, Templates are meant to be used in various scenarios. If I have a global library of widgets then they would likely be in a directory folder not nested underneath.

I suppose if you structure your folders by type rather than feature then this is less likely to be an issue. Ie. if I have a folder dedicated to all UXMLs in the project then it would be easier to do this. This doesn’t work well for projects structured by feature.

Sorry for dissappearing. My regular job had a demanding client project! I’m using 2020.3.25f1.1418. I grabbed it because it was an LTS but I guess I missed the memo that UI Builder is out of preview and fully incorporated into some of the newer Unity builds. Presumably, Toolkit is still in preview?

Is there any option that can disable rewriting src path in uxml files?

No this is not supported.