From 35cd4d87595836676ebf78acdc0e4d24d998e36f Mon Sep 17 00:00:00 2001 From: Karsten Hassel Date: Sun, 8 Mar 2026 10:34:14 +0100 Subject: [PATCH] weather: add possibility to override njk's and css (#4051) This is an approach for #2909 It adds 2 values to the config: ```js themeDir: "./", themeCustomScripts: [] ``` `themeDir` must be specified relative to the weather dir. Example config: ```js { module: "weather", position: "top_center", config: { weatherProvider: "openmeteo", type: "current", lat: 40.776676, lon: -73.971321, themeDir: "../../../modules/MyWeatherTemplate/", themeCustomScripts: [ "skycons.js", "weathertheme.js" ], } }, ``` The `themeDir` must contain the 4 files - current.njk - forecast.njk - hourly.njk - weather.css You can add more files (if needed) and add them to the `themeCustomScripts` so they are loaded as script. There are 2 methods inserted which are called if defined: - initWeatherTheme: For doing special things when starting the module - updateWeatherTheme: For doing special things before updating the dom I see this as a simple approach for overriding the default njk templates and css. I did already convert my [MMM-WeatherBridge](https://gitlab.com/khassel/MMM-WeatherBridge) into a template. --- defaultmodules/weather/weather.js | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/defaultmodules/weather/weather.js b/defaultmodules/weather/weather.js index fc06af37..ff870000 100644 --- a/defaultmodules/weather/weather.js +++ b/defaultmodules/weather/weather.js @@ -42,7 +42,9 @@ Module.register("weather", { colored: false, absoluteDates: false, forecastDateFormat: "ddd", // format for forecast date display, e.g., "ddd" = Mon, "dddd" = Monday, "D MMM" = 18 Oct - hourlyForecastIncrements: 1 + hourlyForecastIncrements: 1, + themeDir: "./", + themeCustomScripts: [] }, // Module properties (all providers run server-side) @@ -57,14 +59,18 @@ Module.register("weather", { // Define required scripts. getStyles () { - return ["font-awesome.css", "weather-icons.css", "weather.css"]; + return ["font-awesome.css", "weather-icons.css", `${this.config.themeDir}weather.css`]; }, // Return the scripts that are necessary for the weather module. getScripts () { // Only load client-side dependencies for rendering // All providers run server-side via node_helper - return ["moment.js", "weatherutils.js", "weatherobject.js", "suncalc.js"]; + const resArr = ["moment.js", "weatherutils.js", "weatherobject.js", "suncalc.js"]; + this.config.themeCustomScripts.forEach((element) => { + resArr.push(`${this.config.themeDir}${element}`); + }); + return resArr; }, // Override getHeader method. @@ -98,6 +104,8 @@ Module.register("weather", { // All providers run server-side: generate unique instance ID and initialize via node_helper this.instanceId = `${this.identifier}_${Date.now()}`; + if (window.initWeatherTheme) window.initWeatherTheme(this); + Log.log(`[weather] Initializing server-side provider with instance ID: ${this.instanceId}`); this.sendSocketNotification("INIT_WEATHER", { @@ -211,15 +219,15 @@ Module.register("weather", { getTemplate () { switch (this.config.type.toLowerCase()) { case "current": - return "current.njk"; + return `${this.config.themeDir}current.njk`; case "hourly": - return "hourly.njk"; + return `${this.config.themeDir}hourly.njk`; case "daily": case "forecast": - return "forecast.njk"; + return `${this.config.themeDir}forecast.njk`; //Make the invalid values use the "Loading..." from forecast default: - return "forecast.njk"; + return `${this.config.themeDir}forecast.njk`; } }, @@ -242,7 +250,11 @@ Module.register("weather", { // What to do when the weather provider has new information available? updateAvailable () { Log.log("[weather] New weather information available."); - this.updateDom(300); + if (window.updateWeatherTheme) { + window.updateWeatherTheme(this); + } else { + this.updateDom(300); + } const currentWeather = this.currentWeatherObject;