diff --git a/client/ayon_harmony/js/loaders/TemplateLoader.js b/client/ayon_harmony/js/loaders/TemplateLoader.js index 8b012a59..5f9e6ec8 100644 --- a/client/ayon_harmony/js/loaders/TemplateLoader.js +++ b/client/ayon_harmony/js/loaders/TemplateLoader.js @@ -23,10 +23,19 @@ var TemplateLoader = function() {}; /** * Load template as container. * @function - * @param {string} templatePath Path to tpl file. + * @param {array} args Array of arguments. * @return {string} Name of backdrop container. + * @example + * // arguments are in this order: + * var args = [ + * templatePath, // Path to tpl file + * overrideName // Override name of backdrop container + * ]; */ -TemplateLoader.prototype.loadContainer = function(templatePath) { +TemplateLoader.prototype.loadContainer = function(args) { + var templatePath = args[0]; + var overrideName = args[1] || ""; + // Copy from template file MessageLog.trace("loadContainer:: "); @@ -173,23 +182,14 @@ TemplateLoader.prototype.loadContainer = function(templatePath) { allBackdrops[idx].position.x += offsetX; allBackdrops[idx].position.y += offsetY; }); - Backdrop.setBackdrops("Top", allBackdrops); } - // Find main backdrop name - // The main backdrop is the one with the smallest x + y value (top left corner) - var selectedBackdrops = selection.selectedBackdrops(); - var mainBackdropName = selectedBackdrops[0].title.text; - var mainAnchorValue = selectedBackdrops[0].position.x + selectedBackdrops[0].position.y; - selectedBackdrops.slice(1).forEach(function(backdrop) { - var anchor = backdrop.position.x + backdrop.position.y; - if (mainAnchorValue > anchor) { - mainBackdropName = backdrop.title.text; - mainAnchorValue = anchor; - } - }); + // Override name if provided + if (overrideName) { + allBackdrops[0].title.text = overrideName; + } - var allBackdrops = Backdrop.backdrops("Top"); + // Count existing backdrops by base name var backdropCounts = {}; for (var i = 0; i < allBackdrops.length; i++) { var parsed = parseBackdropName(allBackdrops[i].title.text); @@ -203,18 +203,21 @@ TemplateLoader.prototype.loadContainer = function(templatePath) { } } + // Increment count of backdrop with the same base name + var mainBackdropName = allBackdrops[0].title.text; var mainBackdropParsed = parseBackdropName(mainBackdropName); var count = backdropCounts[mainBackdropParsed.baseName] !== undefined ? backdropCounts[mainBackdropParsed.baseName] : 1; - if (count > 1){ // count -1 to match imported nodes which start from _1 mainBackdropName = mainBackdropName + "_" + (count - 1); - - // new backdrop always at 0 - allBackdrops[0].title.text = mainBackdropName; - Backdrop.setBackdrops("Top", allBackdrops); } + // Set name of main backdrop (always at index 0) + allBackdrops[0].title.text = mainBackdropName; + + // Update backdrops in scene + Backdrop.setBackdrops("Top", allBackdrops); + return mainBackdropName; }; diff --git a/client/ayon_harmony/plugins/load/load_template.py b/client/ayon_harmony/plugins/load/load_template.py index 58dc9b79..9c5132d3 100644 --- a/client/ayon_harmony/plugins/load/load_template.py +++ b/client/ayon_harmony/plugins/load/load_template.py @@ -15,6 +15,7 @@ class TemplateLoader(harmony.BackdropBaseLoader): representations = {"tpl"} label = "Load Template" icon = "gift" + override_name = "" def load(self, context, name=None, namespace=None, data=None): """Plugin entry point. @@ -31,6 +32,11 @@ def load(self, context, name=None, namespace=None, data=None): temp_dir = tempfile.mkdtemp() zip_file = self.filepath_from_context(context) + # Override container name + override_name = "" + if self.override_name: + override_name = self.override_name.format(**context) + with zipfile.ZipFile(zip_file, "r") as zip_ref: zip_ref.extractall(temp_dir) @@ -39,7 +45,10 @@ def load(self, context, name=None, namespace=None, data=None): "function": f"AyonHarmony.Loaders.{self_name}.loadContainer", # Published tpl name is not consistent, use first found, # must be only one - "args": next(Path(temp_dir).glob("*.tpl")).as_posix(), + "args": [ + next(Path(temp_dir).glob("*.tpl")).as_posix(), + override_name + ], } )["result"] @@ -48,7 +57,7 @@ def load(self, context, name=None, namespace=None, data=None): # We must validate the group_node return harmony.containerise( - name, + backdrop_name, namespace, backdrop_name, context, diff --git a/server/settings/load_plugins.py b/server/settings/load_plugins.py new file mode 100644 index 00000000..7559d645 --- /dev/null +++ b/server/settings/load_plugins.py @@ -0,0 +1,22 @@ +from ayon_server.settings import BaseSettingsModel, SettingsField + + +class TemplateLoaderPluginModel(BaseSettingsModel): + enabled: bool = SettingsField(True, title="Enabled") + override_name: str = SettingsField( + "", + title="Override container name", + description=( + "Optional container name to override the default name.\n" + "Keys are available in the context of the loader plugin.\n" + "Example keys: project[name], folder[name], product[name]..." + ), + placeholder="{folder[name]}_{product[name]}", + ) + + +class HarmonyLoadPlugins(BaseSettingsModel): + TemplateLoader: TemplateLoaderPluginModel = SettingsField( + default_factory=TemplateLoaderPluginModel, + title="Template Loader", + ) diff --git a/server/settings/main.py b/server/settings/main.py index f90000b9..aabfbe8b 100644 --- a/server/settings/main.py +++ b/server/settings/main.py @@ -2,6 +2,7 @@ from .imageio import HarmonyImageIOModel from .creator_plugins import HarmonyCreatePlugins +from .load_plugins import HarmonyLoadPlugins from .publish_plugins import HarmonyPublishPlugins @@ -16,6 +17,10 @@ class HarmonySettings(BaseSettingsModel): default_factory=HarmonyCreatePlugins, title="Creator plugins" ) + load: HarmonyLoadPlugins = SettingsField( + default_factory=HarmonyLoadPlugins, + title="Loader plugins", + ) publish: HarmonyPublishPlugins = SettingsField( default_factory=HarmonyPublishPlugins, title="Publish plugins" @@ -84,6 +89,12 @@ class HarmonySettings(BaseSettingsModel): } } }, + "load": { + "TemplateLoader": { + "enabled": True, + "override_name": "" + } + }, "publish": { "CollectPalettes": { "allowed_tasks": [